package staking_test import ( "math/big" stakingprecompile "github.com/0glabs/0g-chain/precompiles/staking" sdk "github.com/cosmos/cosmos-sdk/types" query "github.com/cosmos/cosmos-sdk/types/query" "github.com/ethereum/go-ethereum/common" ) func (s *StakingTestSuite) TestValidators() { method := stakingprecompile.StakingFunctionValidators testCases := []struct { name string malleate func() []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func() []byte { input, err := s.abi.Pack( method, "", query.PageRequest{ Limit: 10, CountTotal: true, }, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") validators := out[0].([]stakingprecompile.Validator) paginationResult := out[1].(stakingprecompile.PageResponse) s.Assert().EqualValues(3, len(validators)) s.Assert().EqualValues(3, paginationResult.Total) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() s.AddDelegation(s.signerOne.HexAddr, s.signerTwo.HexAddr, sdk.NewIntFromUint64(1000000)) bz, err := s.runTx(tc.malleate(), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestValidator() { method := stakingprecompile.StakingFunctionValidator testCases := []struct { name string malleate func(operatorAddress common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(operatorAddress common.Address) []byte { input, err := s.abi.Pack( method, operatorAddress, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) validator := out[0].(stakingprecompile.Validator) s.Require().EqualValues(validator.OperatorAddress, common.BytesToAddress(operatorAddress.Bytes())) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(operatorAddress.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestValidatorDelegations() { method := stakingprecompile.StakingFunctionValidatorDelegations testCases := []struct { name string malleate func(operatorAddress common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(operatorAddress common.Address) []byte { input, err := s.abi.Pack( method, operatorAddress, query.PageRequest{ Limit: 10, CountTotal: true, }, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) delegations := out[0].([]stakingprecompile.DelegationResponse) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) s.Require().EqualValues(len(delegations), len(d)) // jsonData, _ := json.MarshalIndent(delegations, "", " ") // fmt.Printf("delegations: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(operatorAddress.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestValidatorUnbondingDelegations() { method := stakingprecompile.StakingFunctionValidatorUnbondingDelegations testCases := []struct { name string malleate func(operatorAddress common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(operatorAddress common.Address) []byte { input, err := s.abi.Pack( method, operatorAddress, query.PageRequest{ Limit: 10, CountTotal: true, }, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") unbonding := out[0].([]stakingprecompile.UnbondingDelegation) s.Require().EqualValues(len(unbonding), 1) // jsonData, _ := json.MarshalIndent(unbonding, "", " ") // fmt.Printf("delegations: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress) s.Require().NoError(err) _, err = s.stakingKeeper.Undelegate(s.Ctx, delAddr, operatorAddress, sdk.NewDec(1)) s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(operatorAddress.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestDelegation() { method := stakingprecompile.StakingFunctionDelegation testCases := []struct { name string malleate func(delAddr, valAddr common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(delAddr, valAddr common.Address) []byte { input, err := s.abi.Pack( method, delAddr, valAddr, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") d := out[0].(stakingprecompile.Delegation) b := out[1].(*big.Int) _ = d _ = b /* jsonData, _ := json.MarshalIndent(d, "", " ") fmt.Printf("delegation: %s\n", string(jsonData)) fmt.Printf("balance: %v\n", b) */ }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress) s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(delAddr.Bytes()), common.Address(operatorAddress.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestUnbondingDelegation() { method := stakingprecompile.StakingFunctionUnbondingDelegation testCases := []struct { name string malleate func(delAddr, valAddr common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(delAddr, valAddr common.Address) []byte { input, err := s.abi.Pack( method, delAddr, valAddr, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") u := out[0].(stakingprecompile.UnbondingDelegation) _ = u // jsonData, _ := json.MarshalIndent(u, "", " ") // fmt.Printf("delegation: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress) s.Require().NoError(err) _, err = s.stakingKeeper.Undelegate(s.Ctx, delAddr, operatorAddress, sdk.NewDec(1)) s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(delAddr.Bytes()), common.Address(operatorAddress.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestDelegatorDelegations() { method := stakingprecompile.StakingFunctionDelegatorDelegations testCases := []struct { name string malleate func(delAddr common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(delAddr common.Address) []byte { input, err := s.abi.Pack( method, delAddr, query.PageRequest{ Limit: 10, CountTotal: true, }, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") d := out[0].([]stakingprecompile.DelegationResponse) paginationResult := out[1].(stakingprecompile.PageResponse) s.Assert().EqualValues(1, len(d)) s.Assert().EqualValues(1, paginationResult.Total) // jsonData, _ := json.MarshalIndent(d, "", " ") // fmt.Printf("delegation: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress) s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(delAddr.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestDelegatorUnbondingDelegations() { method := stakingprecompile.StakingFunctionDelegatorUnbondingDelegations testCases := []struct { name string malleate func(delAddr common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(delAddr common.Address) []byte { input, err := s.abi.Pack( method, delAddr, query.PageRequest{ Limit: 10, CountTotal: true, }, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") d := out[0].([]stakingprecompile.UnbondingDelegation) paginationResult := out[1].(stakingprecompile.PageResponse) s.Assert().EqualValues(1, len(d)) s.Assert().EqualValues(1, paginationResult.Total) // jsonData, _ := json.MarshalIndent(d, "", " ") // fmt.Printf("delegation: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress) s.Require().NoError(err) _, err = s.stakingKeeper.Undelegate(s.Ctx, delAddr, operatorAddress, sdk.NewDec(1)) s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(delAddr.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestRedelegations() { method := stakingprecompile.StakingFunctionRedelegations testCases := []struct { name string malleate func(delAddr, srcValAddr, dstValAddr common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(delAddr, srcValAddr, dstValAddr common.Address) []byte { input, err := s.abi.Pack( method, delAddr, srcValAddr, dstValAddr, query.PageRequest{ Limit: 10, CountTotal: true, }, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") d := out[0].([]stakingprecompile.RedelegationResponse) paginationResult := out[1].(stakingprecompile.PageResponse) s.Assert().EqualValues(1, len(d)) s.Assert().EqualValues(1, paginationResult.Total) // jsonData, _ := json.MarshalIndent(d, "", " ") // fmt.Printf("redelegations: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress) s.Require().NoError(err) // setup redelegations s.setupValidator(s.signerOne) _, err = s.stakingKeeper.BeginRedelegation(s.Ctx, delAddr, operatorAddress, s.signerOne.ValAddr, sdk.NewDec(1)) s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(delAddr.Bytes()), common.Address(operatorAddress.Bytes()), common.Address(s.signerOne.ValAddr.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestDelegatorValidators() { method := stakingprecompile.StakingFunctionDelegatorValidators testCases := []struct { name string malleate func(delAddr common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(delAddr common.Address) []byte { input, err := s.abi.Pack( method, delAddr, query.PageRequest{ Limit: 10, CountTotal: true, }, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") v := out[0].([]stakingprecompile.Validator) paginationResult := out[1].(stakingprecompile.PageResponse) s.Assert().EqualValues(1, len(v)) s.Assert().EqualValues(1, paginationResult.Total) // jsonData, _ := json.MarshalIndent(v, "", " ") // fmt.Printf("validators: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress) s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(delAddr.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestDelegatorValidator() { method := stakingprecompile.StakingFunctionDelegatorValidator testCases := []struct { name string malleate func(delAddr, valAddr common.Address) []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func(delAddr, valAddr common.Address) []byte { input, err := s.abi.Pack( method, delAddr, valAddr, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") v := out[0].(stakingprecompile.Validator) _ = v // jsonData, _ := json.MarshalIndent(v, "", " ") // fmt.Printf("validators: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() operatorAddress, err := s.firstBondedValidator() s.Require().NoError(err) d := s.stakingKeeper.GetValidatorDelegations(s.Ctx, operatorAddress) delAddr, err := sdk.AccAddressFromBech32(d[0].DelegatorAddress) s.Require().NoError(err) bz, err := s.runTx(tc.malleate(common.Address(delAddr.Bytes()), common.Address(operatorAddress.Bytes())), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestPool() { method := stakingprecompile.StakingFunctionPool testCases := []struct { name string malleate func() []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func() []byte { input, err := s.abi.Pack( method, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") bonded := out[0].(*big.Int) unbonded := out[0].(*big.Int) s.Assert().Equal(bonded.Int64(), int64(0)) s.Assert().Equal(unbonded.Int64(), int64(0)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() bz, err := s.runTx(tc.malleate(), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } } func (s *StakingTestSuite) TestParams() { method := stakingprecompile.StakingFunctionParams testCases := []struct { name string malleate func() []byte postCheck func(bz []byte) gas uint64 expErr bool errContains string }{ { "success", func() []byte { input, err := s.abi.Pack( method, ) s.Assert().NoError(err) return input }, func(data []byte) { out, err := s.abi.Methods[method].Outputs.Unpack(data) s.Require().NoError(err, "failed to unpack output") params := out[0].(stakingprecompile.Params) _ = params // jsonData, _ := json.MarshalIndent(params, "", " ") // fmt.Printf("params: %s\n", string(jsonData)) }, 100000, false, "", }, } for _, tc := range testCases { s.Run(tc.name, func() { s.SetupTest() bz, err := s.runTx(tc.malleate(), s.signerOne, 10000000) if tc.expErr { s.Require().Error(err) s.Require().Contains(err.Error(), tc.errContains) } else { s.Require().NoError(err) s.Require().NotNil(bz) tc.postCheck(bz) } }) } }