Skip to content

Commit

Permalink
refactor: privatize staking contract addresses and ABI (#779)
Browse files Browse the repository at this point in the history
  • Loading branch information
zakir-code authored Oct 24, 2024
1 parent 73063a3 commit 0fb5334
Show file tree
Hide file tree
Showing 29 changed files with 286 additions and 353 deletions.
10 changes: 10 additions & 0 deletions contract/precompile.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
)

Expand All @@ -16,6 +17,15 @@ type PrecompileMethod interface {
Run(evm *vm.EVM, contract *vm.Contract) ([]byte, error)
}

func EmitEvent(evm *vm.EVM, address common.Address, data []byte, topics []common.Hash) {
evm.StateDB.AddLog(&ethtypes.Log{
Address: address,
Topics: topics,
Data: data,
BlockNumber: evm.Context.BlockNumber.Uint64(),
})
}

type ERC20Call struct {
ERC20ABI
evm *vm.EVM
Expand Down
22 changes: 10 additions & 12 deletions tests/staking_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ import (

type StakingSuite struct {
Erc20TestSuite
grantKey cryptotypes.PrivKey
grantKey cryptotypes.PrivKey
stakingContract common.Address
}

func NewStakingSuite(ts *TestSuite) StakingSuite {
key := helpers.NewEthPrivKey()
return StakingSuite{
Erc20TestSuite: NewErc20TestSuite(ts),
grantKey: key,
Erc20TestSuite: NewErc20TestSuite(ts),
grantKey: key,
stakingContract: common.HexToAddress(contract.StakingAddress),
}
}

Expand Down Expand Up @@ -102,11 +104,10 @@ func (suite *StakingSuite) SetWithdrawAddressWithResponse(privKey cryptotypes.Pr
}

func (suite *StakingSuite) send(privateKey cryptotypes.PrivKey, value *big.Int, data []byte) *ethtypes.Receipt {
stakingContract := stakingprecompile.GetAddress()
if value == nil {
value = big.NewInt(0)
}
transaction, err := client.BuildEthTransaction(suite.ctx, suite.EthClient(), privateKey, &stakingContract, value, data)
transaction, err := client.BuildEthTransaction(suite.ctx, suite.EthClient(), privateKey, &suite.stakingContract, value, data)
suite.Require().NoError(err)
return suite.SendTransaction(transaction)
}
Expand Down Expand Up @@ -157,23 +158,21 @@ func (suite *StakingSuite) WithdrawReward(privateKey cryptotypes.PrivKey, valAdd
}

func (suite *StakingSuite) Delegation(valAddr string, delAddr common.Address) (*big.Int, *big.Int) {
stakingContract := stakingprecompile.GetAddress()
method := stakingprecompile.NewDelegationMethod(nil)
pack, err := method.PackInput(fxstakingtypes.DelegationArgs{Validator: valAddr, Delegator: delAddr})
suite.Require().NoError(err)
output, err := suite.EthClient().CallContract(suite.ctx, ethereum.CallMsg{To: &stakingContract, Data: pack}, nil)
output, err := suite.EthClient().CallContract(suite.ctx, ethereum.CallMsg{To: &suite.stakingContract, Data: pack}, nil)
suite.Require().NoError(err)
shares, amount, err := method.UnpackOutput(output)
suite.Require().NoError(err)
return shares, amount
}

func (suite *StakingSuite) Rewards(valAddr string, delAddr common.Address) *big.Int {
stakingContract := stakingprecompile.GetAddress()
method := stakingprecompile.NewDelegationRewardsMethod(nil)
pack, err := method.PackInput(fxstakingtypes.DelegationRewardsArgs{Validator: valAddr, Delegator: delAddr})
suite.Require().NoError(err)
output, err := suite.EthClient().CallContract(suite.ctx, ethereum.CallMsg{To: &stakingContract, Data: pack}, nil)
output, err := suite.EthClient().CallContract(suite.ctx, ethereum.CallMsg{To: &suite.stakingContract, Data: pack}, nil)
suite.Require().NoError(err)
amount, err := method.UnpackOutput(output)
suite.Require().NoError(err)
Expand Down Expand Up @@ -236,11 +235,10 @@ func (suite *StakingSuite) ApproveShares(privateKey cryptotypes.PrivKey, valAddr
}

func (suite *StakingSuite) AllowanceShares(valAddr string, owner, spender common.Address) *big.Int {
stakingContract := stakingprecompile.GetAddress()
method := stakingprecompile.NewAllowanceSharesMethod(nil)
pack, err := method.PackInput(fxstakingtypes.AllowanceSharesArgs{Validator: valAddr, Owner: owner, Spender: spender})
suite.Require().NoError(err)
output, err := suite.EthClient().CallContract(suite.ctx, ethereum.CallMsg{To: &stakingContract, Data: pack}, nil)
output, err := suite.EthClient().CallContract(suite.ctx, ethereum.CallMsg{To: &suite.stakingContract, Data: pack}, nil)
suite.Require().NoError(err)
amount, err := method.UnpackOutput(output)
suite.Require().NoError(err)
Expand All @@ -250,7 +248,7 @@ func (suite *StakingSuite) AllowanceShares(valAddr string, owner, spender common
func (suite *StakingSuite) LogReward(logs []*ethtypes.Log, valAddr string, addr common.Address) *big.Int {
method := stakingprecompile.NewWithdrawMethod(nil)
for _, log := range logs {
if log.Address == stakingprecompile.GetAddress() &&
if log.Address == suite.stakingContract &&
log.Topics[0] == method.Event.ID &&
log.Topics[1] == addr.Hash() {
unpack, err := method.Event.Inputs.NonIndexed().Unpack(log.Data)
Expand Down
2 changes: 1 addition & 1 deletion tests/staking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (suite *IntegrationTest) StakingContractTest() {

withdrawMethod := stakingprecompile.NewWithdrawMethod(nil)
for _, log := range receipt.Logs {
if log.Address == stakingprecompile.GetAddress() && log.Topics[0] == withdrawMethod.Event.ID {
if log.Address == suite.staking.stakingContract && log.Topics[0] == withdrawMethod.Event.ID {
unpack, err := withdrawMethod.Event.Inputs.NonIndexed().Unpack(log.Data)
suite.Require().NoError(err)
reward := unpack[1].(*big.Int)
Expand Down
2 changes: 1 addition & 1 deletion x/staking/precompile/allowance_shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type AllowanceSharesMethod struct {
func NewAllowanceSharesMethod(keeper *Keeper) *AllowanceSharesMethod {
return &AllowanceSharesMethod{
Keeper: keeper,
Method: fxstakingtypes.GetABI().Methods["allowanceShares"],
Method: stakingABI.Methods["allowanceShares"],
}
}

Expand Down
13 changes: 4 additions & 9 deletions x/staking/precompile/allowance_shares_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/functionx/fx-core/v8/contract"
testscontract "github.com/functionx/fx-core/v8/tests/contract"
"github.com/functionx/fx-core/v8/testutil/helpers"
"github.com/functionx/fx-core/v8/x/staking/precompile"
"github.com/functionx/fx-core/v8/x/staking/types"
Expand All @@ -24,7 +22,6 @@ func TestStakingAllowanceSharesABI(t *testing.T) {
}

func (suite *PrecompileTestSuite) TestAllowanceShares() {
allowanceSharesMethod := precompile.NewAllowanceSharesMethod(nil)
testCases := []struct {
name string
malleate func(val sdk.ValAddress, owner, spender *helpers.Signer) (types.AllowanceSharesArgs, error)
Expand Down Expand Up @@ -116,21 +113,19 @@ func (suite *PrecompileTestSuite) TestAllowanceShares() {

args, errResult := tc.malleate(operator, owner, spender)

packData, err := allowanceSharesMethod.PackInput(args)
packData, err := suite.allowanceSharesMethod.PackInput(args)
suite.Require().NoError(err)
stakingContract := precompile.GetAddress()
stakingContract := suite.stakingAddr

if strings.HasPrefix(tc.name, "contract") {
stakingContract = suite.staking
packData, err = contract.MustABIJson(testscontract.StakingTestMetaData.ABI).Pack(TestAllowanceSharesName, args.Validator, args.Owner, args.Spender)
suite.Require().NoError(err)
stakingContract = suite.stakingTestAddr
}

res := suite.EthereumTx(owner, stakingContract, big.NewInt(0), packData)

if tc.result {
suite.Require().False(res.Failed(), res.VmError)
shares, err := allowanceSharesMethod.UnpackOutput(res.Ret)
shares, err := suite.allowanceSharesMethod.UnpackOutput(res.Ret)
suite.Require().NoError(err)
if shares.Cmp(big.NewInt(0)) != 0 {
suite.Require().Equal(allowanceAmt.BigInt(), shares)
Expand Down
6 changes: 3 additions & 3 deletions x/staking/precompile/approve_shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ type ApproveSharesMethod struct {
func NewApproveSharesMethod(keeper *Keeper) *ApproveSharesMethod {
return &ApproveSharesMethod{
Keeper: keeper,
Method: fxstakingtypes.GetABI().Methods["approveShares"],
Event: fxstakingtypes.GetABI().Events["ApproveShares"],
Method: stakingABI.Methods["approveShares"],
Event: stakingABI.Events["ApproveShares"],
}
}

Expand Down Expand Up @@ -56,7 +56,7 @@ func (m *ApproveSharesMethod) Run(evm *vm.EVM, contract *vm.Contract) ([]byte, e
if err != nil {
return err
}
EmitEvent(evm, data, topic)
fxcontract.EmitEvent(evm, stakingAddress, data, topic)

return nil
}); err != nil {
Expand Down
20 changes: 7 additions & 13 deletions x/staking/precompile/approve_shares_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/functionx/fx-core/v8/contract"
testscontract "github.com/functionx/fx-core/v8/tests/contract"
"github.com/functionx/fx-core/v8/testutil/helpers"
"github.com/functionx/fx-core/v8/x/staking/precompile"
fxstakingtypes "github.com/functionx/fx-core/v8/x/staking/types"
Expand All @@ -27,7 +25,6 @@ func TestStakingApproveSharesABI(t *testing.T) {
}

func (suite *PrecompileTestSuite) TestApproveShares() {
approveSharesMethod := precompile.NewApproveSharesMethod(nil)
testCases := []struct {
name string
malleate func(val sdk.ValAddress, spender *helpers.Signer, allowance sdkmath.Int) (fxstakingtypes.ApproveSharesArgs, error)
Expand Down Expand Up @@ -115,17 +112,14 @@ func (suite *PrecompileTestSuite) TestApproveShares() {

args, errResult := tc.malleate(operator, spender, allowanceAmt)

packData, err := approveSharesMethod.PackInput(args)
packData, err := suite.approveSharesMethod.PackInput(args)
suite.Require().NoError(err)
stakingContract := precompile.GetAddress()
stakingContract := suite.stakingAddr
sender := owner.Address()

if strings.HasPrefix(tc.name, "contract") {
packData, err = contract.MustABIJson(testscontract.StakingTestMetaData.ABI).Pack(TestApproveSharesName, args.Validator, args.Spender, args.Shares)
suite.Require().NoError(err)

stakingContract = suite.staking
sender = suite.staking
stakingContract = suite.stakingTestAddr
sender = suite.stakingTestAddr
}

allowance := suite.App.StakingKeeper.GetAllowance(suite.Ctx, operator, owner.AccAddress(), spender.AccAddress())
Expand All @@ -143,9 +137,9 @@ func (suite *PrecompileTestSuite) TestApproveShares() {

existLog := false
for _, log := range res.Logs {
if log.Topics[0] == approveSharesMethod.Event.ID.String() {
suite.Require().Equal(log.Address, precompile.GetAddress().String())
event, err := approveSharesMethod.UnpackEvent(log.ToEthereum())
if log.Topics[0] == suite.approveSharesMethod.Event.ID.String() {
suite.Require().Equal(log.Address, suite.stakingAddr.String())
event, err := suite.approveSharesMethod.UnpackEvent(log.ToEthereum())
suite.Require().NoError(err)
suite.Require().Equal(event.Owner, sender)
suite.Require().Equal(event.Spender, spender.Address())
Expand Down
33 changes: 11 additions & 22 deletions x/staking/precompile/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import (
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"

"github.com/functionx/fx-core/v8/contract"
evmtypes "github.com/functionx/fx-core/v8/x/evm/types"
fxstakingkeeper "github.com/functionx/fx-core/v8/x/staking/keeper"
fxstakingtypes "github.com/functionx/fx-core/v8/x/staking/types"
)

var (
stakingAddress = common.HexToAddress(contract.StakingAddress)
stakingABI = contract.MustABIJson(contract.IStakingMetaData.ABI)
)

type Contract struct {
Expand All @@ -39,11 +42,6 @@ func NewPrecompiledContract(
slashingKeeper: slashingKeeper,
}

delegateV2 := NewDelegateV2Method(keeper)
redelegateV2 := NewRedelegateV2Method(keeper)
undelegateV2 := NewUndelegateV2Method(keeper)
slashingInfo := NewSlashingInfoMethod(keeper)
validatorList := NewValidatorListMethod(keeper)
return &Contract{
methods: []contract.PrecompileMethod{
NewAllowanceSharesMethod(keeper),
Expand All @@ -55,19 +53,19 @@ func NewPrecompiledContract(
NewTransferFromSharesMethod(keeper),
NewWithdrawMethod(keeper),

delegateV2,
redelegateV2,
undelegateV2,
NewDelegateV2Method(keeper),
NewRedelegateV2Method(keeper),
NewUndelegateV2Method(keeper),

slashingInfo,
validatorList,
NewSlashingInfoMethod(keeper),
NewValidatorListMethod(keeper),
},
govKeeper: govKeeper,
}
}

func (c *Contract) Address() common.Address {
return fxstakingtypes.GetAddress()
return stakingAddress
}

func (c *Contract) IsStateful() bool {
Expand Down Expand Up @@ -111,12 +109,3 @@ func (c *Contract) Run(evm *vm.EVM, vmContract *vm.Contract, readonly bool) (ret
}
return contract.PackRetErrV2(errors.New("unknown method"))
}

func EmitEvent(evm *vm.EVM, data []byte, topics []common.Hash) {
evm.StateDB.AddLog(&ethtypes.Log{
Address: fxstakingtypes.GetAddress(),
Topics: topics,
Data: data,
BlockNumber: evm.Context.BlockNumber.Uint64(),
})
}
Loading

0 comments on commit 0fb5334

Please sign in to comment.