From d94f78849256a443c06a7950c60fb6e8a6025008 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Wed, 14 Aug 2024 18:46:38 +0200 Subject: [PATCH 01/33] feat: add test precompiled contract --- app/app.go | 8 +- precompile/precompiles.go | 27 ++++ precompile/regular/regular.go | 241 ++++++++++++++++++++++++++++++++++ precompile/types/errors.go | 17 +++ precompile/types/types.go | 39 ++++++ 5 files changed, 331 insertions(+), 1 deletion(-) create mode 100644 precompile/precompiles.go create mode 100644 precompile/regular/regular.go create mode 100644 precompile/types/errors.go create mode 100644 precompile/types/types.go diff --git a/app/app.go b/app/app.go index 4c74dee89b..be58612782 100644 --- a/app/app.go +++ b/app/app.go @@ -92,6 +92,7 @@ import ( "github.com/zeta-chain/zetacore/app/ante" "github.com/zeta-chain/zetacore/docs/openapi" zetamempool "github.com/zeta-chain/zetacore/pkg/mempool" + precompiles "github.com/zeta-chain/zetacore/precompile" srvflags "github.com/zeta-chain/zetacore/server/flags" authoritymodule "github.com/zeta-chain/zetacore/x/authority" authoritykeeper "github.com/zeta-chain/zetacore/x/authority/keeper" @@ -555,6 +556,7 @@ func New( ) evmSs := app.GetSubspace(evmtypes.ModuleName) + gasConfig := storetypes.TransientGasConfig() app.EvmKeeper = evmkeeper.NewKeeper( appCodec, keys[evmtypes.StoreKey], @@ -566,7 +568,11 @@ func New( &app.FeeMarketKeeper, tracer, evmSs, - []evmkeeper.CustomContractFn{}, + precompiles.PrecompiledContracts( + app.FungibleKeeper, + appCodec, + gasConfig, + ), app.ConsensusParamsKeeper, aggregateAllKeys(keys, tKeys, memKeys), ) diff --git a/precompile/precompiles.go b/precompile/precompiles.go new file mode 100644 index 0000000000..00bacbdf06 --- /dev/null +++ b/precompile/precompiles.go @@ -0,0 +1,27 @@ +package precompiles + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/core/vm" + ethparams "github.com/ethereum/go-ethereum/params" + evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" + "github.com/zeta-chain/zetacore/precompile/regular" + "github.com/zeta-chain/zetacore/x/fungible/keeper" +) + +func PrecompiledContracts(fungibleKeeper keeper.Keeper, cdc codec.Codec, gasConfig storetypes.GasConfig) []evmkeeper.CustomContractFn { + // Initialize at 0 the custom compiled contracts. + precompiledContracts := make([]evmkeeper.CustomContractFn, 0) + + // Define the regular contract function. + regularContract := func(ctx sdktypes.Context, rules ethparams.Rules) vm.PrecompiledContract { + return regular.NewRegularContract(fungibleKeeper, cdc, gasConfig) + } + + // Append all the precompiled contracts to the precompiledContracts slice. + precompiledContracts = append(precompiledContracts, regularContract) + + return precompiledContracts +} \ No newline at end of file diff --git a/precompile/regular/regular.go b/precompile/regular/regular.go new file mode 100644 index 0000000000..cceddd335c --- /dev/null +++ b/precompile/regular/regular.go @@ -0,0 +1,241 @@ +package regular + +import ( + "errors" + "fmt" + "math/big" + "strings" + + "github.com/zeta-chain/zetacore/testutil/contracts" + fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + ptypes "github.com/zeta-chain/zetacore/precompile/types" +) + +const ( + RegularCallMethodName = "regularCall" + Bech32ToHexAddrMethodName = "bech32ToHexAddr" + Bech32ifyMethodName = "bech32ify" +) + +var ( + ABI abi.ABI + ContractAddress = common.BytesToAddress([]byte{101}) + GasRequiredByMethod = map[[4]byte]uint64{} + ExampleABI *abi.ABI +) + +func init() { + ABI, GasRequiredByMethod = initABI() + ExampleABI, _ = contracts.ExampleMetaData.GetAbi() +} + +var RegularModuleMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"name\":\"bech32ToHexAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"prefix\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"bech32ify\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"regularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +func initABI() (abi abi.ABI, gasRequiredByMethod map[[4]byte]uint64) { + gasRequiredByMethod = map[[4]byte]uint64{} + if err := abi.UnmarshalJSON([]byte(RegularModuleMetaData.ABI)); err != nil { + panic(err) + } + for methodName := range abi.Methods { + var methodID [4]byte + copy(methodID[:], abi.Methods[methodName].ID[:4]) + switch methodName { + case RegularCallMethodName: + gasRequiredByMethod[methodID] = 10 + case Bech32ToHexAddrMethodName: + gasRequiredByMethod[methodID] = 0 + case Bech32ifyMethodName: + gasRequiredByMethod[methodID] = 0 + default: + gasRequiredByMethod[methodID] = 0 + } + } + return abi, gasRequiredByMethod +} + +type RegularContract struct { + ptypes.BaseContract + + FungibleKeeper fungiblekeeper.Keeper + cdc codec.Codec + kvGasConfig storetypes.GasConfig +} + +// NewRegularContract creates the precompiled contract to manage native tokens +func NewRegularContract(fungibleKeeper fungiblekeeper.Keeper, cdc codec.Codec, kvGasConfig storetypes.GasConfig) *RegularContract { + return &RegularContract{ + BaseContract: ptypes.NewBaseContract(ContractAddress), + FungibleKeeper: fungibleKeeper, + cdc: cdc, + kvGasConfig: kvGasConfig, + } +} + +func (rc *RegularContract) Address() common.Address { + return ContractAddress +} + +func (rc *RegularContract) Abi() abi.ABI { + return ABI +} + +// RequiredGas calculates the contract gas use +func (rc *RegularContract) RequiredGas(input []byte) uint64 { + // base cost to prevent large input size + baseCost := uint64(len(input)) * rc.kvGasConfig.WriteCostPerByte + var methodID [4]byte + copy(methodID[:], input[:4]) + requiredGas, ok := GasRequiredByMethod[methodID] + if ok { + return requiredGas + baseCost + } + return baseCost +} + +func (rc *RegularContract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { + if len(args) != 1 { + return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 1, len(args)) + } + + address, ok := args[0].(string) + if !ok || address == "" { + return nil, fmt.Errorf("invalid bech32 address: %v", args[0]) + } + + bech32Prefix := strings.SplitN(address, "1", 2)[0] + if bech32Prefix == address { + return nil, fmt.Errorf("invalid bech32 address: %s", address) + } + + addressBz, err := sdk.GetFromBech32(address, bech32Prefix) + if err != nil { + return nil, err + } + + if err := sdk.VerifyAddressFormat(addressBz); err != nil { + return nil, err + } + + return method.Outputs.Pack(common.BytesToAddress(addressBz)) +} +func (rc *RegularContract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, error) { + if len(args) != 2 { + return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 2, len(args)) + } + + cfg := sdk.GetConfig() + prefix, _ := args[0].(string) + if strings.TrimSpace(prefix) == "" { + return nil, fmt.Errorf( + "invalid bech32 human readable prefix (HRP). Please provide a either an account, validator or consensus address prefix (eg: %s, %s, %s)", + cfg.GetBech32AccountAddrPrefix(), cfg.GetBech32ValidatorAddrPrefix(), cfg.GetBech32ConsensusAddrPrefix(), + ) + } + + address, ok := args[1].(common.Address) + if !ok { + return nil, fmt.Errorf("invalid hex address") + } + + // NOTE: safety check, should not happen given that the address is is 20 bytes. + if err := sdk.VerifyAddressFormat(address.Bytes()); err != nil { + return nil, err + } + + bech32Str, err := sdk.Bech32ifyAddressBytes(prefix, address.Bytes()) + addressBz, err := sdk.GetFromBech32(bech32Str, "zeta") + if err != nil { + return nil, err + } + + if err := sdk.VerifyAddressFormat(addressBz); err != nil { + return nil, err + } + + if err != nil { + return nil, err + } + + return method.Outputs.Pack(bech32Str) +} + +func (rc *RegularContract) RegularCall(ctx sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) { + if len(args) != 2 { + return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 2, len(args)) + } + callingMethod, ok := args[0].(string) + if !ok { + return nil, fmt.Errorf(ptypes.ErrInvalidMethod, args[0]) + } + callingContract, ok := args[1].(common.Address) + if !ok { + return nil, fmt.Errorf(ptypes.ErrInvalidAddr, args[1]) + } + + res, err := rc.FungibleKeeper.CallEVM( + ctx, + *ExampleABI, + fungibletypes.ModuleAddressEVM, + callingContract, + big.NewInt(0), + nil, + true, + false, + callingMethod, + ) + if err != nil { + return nil, err + } + + return method.Outputs.Pack( + ptypes.BytesToBigInt(res.Ret), + ) +} + +func (rc *RegularContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([]byte, error) { + // parse input + methodID := contract.Input[:4] + method, err := ABI.MethodById(methodID) + if err != nil { + return nil, err + } + args, err := method.Inputs.Unpack(contract.Input[4:]) + if err != nil { + return nil, errors.New("fail to unpack input arguments") + } + + stateDB := evm.StateDB.(ptypes.ExtStateDB) + + switch method.Name { + case RegularCallMethodName: + var res []byte + if execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { + res, err = rc.RegularCall(ctx, method, args) + return err + }); execErr != nil { + return nil, err + } else { + return res, nil + } + + case Bech32ToHexAddrMethodName: + return rc.Bech32ToHexAddr(method, args) + case Bech32ifyMethodName: + return rc.Bech32ify(method, args) + // case OtherMethods: + // .. + default: + return nil, errors.New("unknown method") + } +} \ No newline at end of file diff --git a/precompile/types/errors.go b/precompile/types/errors.go new file mode 100644 index 0000000000..82f968468b --- /dev/null +++ b/precompile/types/errors.go @@ -0,0 +1,17 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package types + +const ( + // ErrDifferentOrigin is raised when an approval is set but the origin address is not the same as the spender. + ErrDifferentOrigin = "tx origin address %s does not match the delegator address %s" + // ErrInvalidAddr is raised when the origin address is invalid + ErrInvalidAddr = "invalid addr: %s" + // ErrInvalidDelegator is raised when the delegator address is not valid. + ErrInvalidDelegator = "invalid delegator address: %s" + // ErrInvalidNumberOfArgs is raised when the number of arguments is not what is expected. + ErrInvalidNumberOfArgs = "invalid number of arguments; expected %d; got: %d" + // ErrInvalidMethod is raised when the method is invalid. + ErrInvalidMethod = "unknown method: %s" +) \ No newline at end of file diff --git a/precompile/types/types.go b/precompile/types/types.go new file mode 100644 index 0000000000..a40b8c70fc --- /dev/null +++ b/precompile/types/types.go @@ -0,0 +1,39 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/zeta-chain/ethermint/x/evm/statedb" +) + +// ExtStateDB defines extra methods of statedb to support stateful precompiled contracts. +// It's used to persist changes into the store. +type ExtStateDB interface { + vm.StateDB + ExecuteNativeAction(contract common.Address, converter statedb.EventConverter, action func(ctx sdk.Context) error) error + CacheContext() sdk.Context +} + +type Registrable interface { + RegistryKey() common.Address +} + +type BaseContract interface { + Registrable +} + +// A baseContract implements Registrable and BaseContract interfaces. +type baseContract struct { + address common.Address +} + +func NewBaseContract(address common.Address) BaseContract { + return &baseContract{ + address: address, + } +} + +func (c *baseContract) RegistryKey() common.Address { + return c.address +} \ No newline at end of file From b9878a601e845d57740807fa457eafb2b7ebf94c Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Wed, 14 Aug 2024 20:44:26 +0200 Subject: [PATCH 02/33] feat: add test stateful contract --- app/app.go | 16 +++++-- {precompile => precompiles}/precompiles.go | 23 +++++++--- .../regular/regular.go | 46 +++++++++++-------- precompiles/regular/src/IRegular.abi | 1 + precompiles/regular/src/IRegular.sol | 35 ++++++++++++++ {precompile => precompiles}/types/errors.go | 2 +- {precompile => precompiles}/types/types.go | 14 +++++- 7 files changed, 104 insertions(+), 33 deletions(-) rename {precompile => precompiles}/precompiles.go (50%) rename {precompile => precompiles}/regular/regular.go (87%) create mode 100644 precompiles/regular/src/IRegular.abi create mode 100644 precompiles/regular/src/IRegular.sol rename {precompile => precompiles}/types/errors.go (99%) rename {precompile => precompiles}/types/types.go (77%) diff --git a/app/app.go b/app/app.go index be58612782..2f06d5b59e 100644 --- a/app/app.go +++ b/app/app.go @@ -92,7 +92,7 @@ import ( "github.com/zeta-chain/zetacore/app/ante" "github.com/zeta-chain/zetacore/docs/openapi" zetamempool "github.com/zeta-chain/zetacore/pkg/mempool" - precompiles "github.com/zeta-chain/zetacore/precompile" + "github.com/zeta-chain/zetacore/precompiles" srvflags "github.com/zeta-chain/zetacore/server/flags" authoritymodule "github.com/zeta-chain/zetacore/x/authority" authoritykeeper "github.com/zeta-chain/zetacore/x/authority/keeper" @@ -556,7 +556,9 @@ func New( ) evmSs := app.GetSubspace(evmtypes.ModuleName) + // Get gas config for stateful contracts. gasConfig := storetypes.TransientGasConfig() + app.EvmKeeper = evmkeeper.NewKeeper( appCodec, keys[evmtypes.StoreKey], @@ -568,9 +570,9 @@ func New( &app.FeeMarketKeeper, tracer, evmSs, - precompiles.PrecompiledContracts( - app.FungibleKeeper, - appCodec, + precompiles.StatefulContracts( + app.FungibleKeeper, + appCodec, gasConfig, ), app.ConsensusParamsKeeper, @@ -1055,10 +1057,16 @@ func (app *App) SimulationManager() *module.SimulationManager { func (app *App) BlockedAddrs() map[string]bool { blockList := make(map[string]bool) + for k, v := range blockedReceivingModAcc { addr := authtypes.NewModuleAddress(k) blockList[addr.String()] = v } + + for addr, enabled := range precompiles.EnabledStatefulContracts { + blockList[addr.String()] = enabled + } + return blockList } diff --git a/precompile/precompiles.go b/precompiles/precompiles.go similarity index 50% rename from precompile/precompiles.go rename to precompiles/precompiles.go index 00bacbdf06..6c86c6e8a1 100644 --- a/precompile/precompiles.go +++ b/precompiles/precompiles.go @@ -4,19 +4,30 @@ import ( "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" ethparams "github.com/ethereum/go-ethereum/params" evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" - "github.com/zeta-chain/zetacore/precompile/regular" + + "github.com/zeta-chain/zetacore/precompiles/regular" "github.com/zeta-chain/zetacore/x/fungible/keeper" ) -func PrecompiledContracts(fungibleKeeper keeper.Keeper, cdc codec.Codec, gasConfig storetypes.GasConfig) []evmkeeper.CustomContractFn { - // Initialize at 0 the custom compiled contracts. - precompiledContracts := make([]evmkeeper.CustomContractFn, 0) +var EnabledStatefulContracts = map[common.Address]bool{ + regular.ContractAddress: true, +} + +// StatefulContracts returns all the registered precompiled contracts. +func StatefulContracts( + fungibleKeeper keeper.Keeper, + cdc codec.Codec, + gasConfig storetypes.GasConfig, +) (precompiledContracts []evmkeeper.CustomContractFn) { + // Initialize at 0 the custom compiled contracts and the addresses. + precompiledContracts = make([]evmkeeper.CustomContractFn, 0) // Define the regular contract function. - regularContract := func(ctx sdktypes.Context, rules ethparams.Rules) vm.PrecompiledContract { + regularContract := func(_ sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { return regular.NewRegularContract(fungibleKeeper, cdc, gasConfig) } @@ -24,4 +35,4 @@ func PrecompiledContracts(fungibleKeeper keeper.Keeper, cdc codec.Codec, gasConf precompiledContracts = append(precompiledContracts, regularContract) return precompiledContracts -} \ No newline at end of file +} diff --git a/precompile/regular/regular.go b/precompiles/regular/regular.go similarity index 87% rename from precompile/regular/regular.go rename to precompiles/regular/regular.go index cceddd335c..ece46b6b43 100644 --- a/precompile/regular/regular.go +++ b/precompiles/regular/regular.go @@ -6,10 +6,6 @@ import ( "math/big" "strings" - "github.com/zeta-chain/zetacore/testutil/contracts" - fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" - fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" - "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -17,7 +13,11 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" - ptypes "github.com/zeta-chain/zetacore/precompile/types" + + ptypes "github.com/zeta-chain/zetacore/precompiles/types" + "github.com/zeta-chain/zetacore/testutil/contracts" + fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" ) const ( @@ -64,7 +64,7 @@ func initABI() (abi abi.ABI, gasRequiredByMethod map[[4]byte]uint64) { return abi, gasRequiredByMethod } -type RegularContract struct { +type Contract struct { ptypes.BaseContract FungibleKeeper fungiblekeeper.Keeper @@ -73,8 +73,12 @@ type RegularContract struct { } // NewRegularContract creates the precompiled contract to manage native tokens -func NewRegularContract(fungibleKeeper fungiblekeeper.Keeper, cdc codec.Codec, kvGasConfig storetypes.GasConfig) *RegularContract { - return &RegularContract{ +func NewRegularContract( + fungibleKeeper fungiblekeeper.Keeper, + cdc codec.Codec, + kvGasConfig storetypes.GasConfig, +) *Contract { + return &Contract{ BaseContract: ptypes.NewBaseContract(ContractAddress), FungibleKeeper: fungibleKeeper, cdc: cdc, @@ -82,16 +86,16 @@ func NewRegularContract(fungibleKeeper fungiblekeeper.Keeper, cdc codec.Codec, k } } -func (rc *RegularContract) Address() common.Address { +func (rc *Contract) Address() common.Address { return ContractAddress } -func (rc *RegularContract) Abi() abi.ABI { +func (rc *Contract) Abi() abi.ABI { return ABI } // RequiredGas calculates the contract gas use -func (rc *RegularContract) RequiredGas(input []byte) uint64 { +func (rc *Contract) RequiredGas(input []byte) uint64 { // base cost to prevent large input size baseCost := uint64(len(input)) * rc.kvGasConfig.WriteCostPerByte var methodID [4]byte @@ -103,7 +107,7 @@ func (rc *RegularContract) RequiredGas(input []byte) uint64 { return baseCost } -func (rc *RegularContract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { +func (rc *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 1 { return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 1, len(args)) } @@ -129,7 +133,7 @@ func (rc *RegularContract) Bech32ToHexAddr(method *abi.Method, args []interface{ return method.Outputs.Pack(common.BytesToAddress(addressBz)) } -func (rc *RegularContract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, error) { +func (rc *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 2 { return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 2, len(args)) } @@ -139,7 +143,9 @@ func (rc *RegularContract) Bech32ify(method *abi.Method, args []interface{}) ([] if strings.TrimSpace(prefix) == "" { return nil, fmt.Errorf( "invalid bech32 human readable prefix (HRP). Please provide a either an account, validator or consensus address prefix (eg: %s, %s, %s)", - cfg.GetBech32AccountAddrPrefix(), cfg.GetBech32ValidatorAddrPrefix(), cfg.GetBech32ConsensusAddrPrefix(), + cfg.GetBech32AccountAddrPrefix(), + cfg.GetBech32ValidatorAddrPrefix(), + cfg.GetBech32ConsensusAddrPrefix(), ) } @@ -154,23 +160,23 @@ func (rc *RegularContract) Bech32ify(method *abi.Method, args []interface{}) ([] } bech32Str, err := sdk.Bech32ifyAddressBytes(prefix, address.Bytes()) - addressBz, err := sdk.GetFromBech32(bech32Str, "zeta") if err != nil { return nil, err } - if err := sdk.VerifyAddressFormat(addressBz); err != nil { + addressBz, err := sdk.GetFromBech32(bech32Str, "zeta") + if err != nil { return nil, err } - if err != nil { + if err := sdk.VerifyAddressFormat(addressBz); err != nil { return nil, err } return method.Outputs.Pack(bech32Str) } -func (rc *RegularContract) RegularCall(ctx sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) { +func (rc *Contract) RegularCall(ctx sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 2 { return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 2, len(args)) } @@ -203,7 +209,7 @@ func (rc *RegularContract) RegularCall(ctx sdk.Context, method *abi.Method, args ) } -func (rc *RegularContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([]byte, error) { +func (rc *Contract) Run(evm *vm.EVM, contract *vm.Contract, _ bool) ([]byte, error) { // parse input methodID := contract.Input[:4] method, err := ABI.MethodById(methodID) @@ -238,4 +244,4 @@ func (rc *RegularContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool default: return nil, errors.New("unknown method") } -} \ No newline at end of file +} diff --git a/precompiles/regular/src/IRegular.abi b/precompiles/regular/src/IRegular.abi new file mode 100644 index 0000000000..a2c527ee60 --- /dev/null +++ b/precompiles/regular/src/IRegular.abi @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"bech32","type":"string"}],"name":"bech32ToHexAddr","outputs":[{"internalType":"address","name":"addr","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"prefix","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"bech32ify","outputs":[{"internalType":"string","name":"bech32","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"method","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"regularCall","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/precompiles/regular/src/IRegular.sol b/precompiles/regular/src/IRegular.sol new file mode 100644 index 0000000000..66296cb0a4 --- /dev/null +++ b/precompiles/regular/src/IRegular.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity ^0.8.7; + +/// @dev The IRegular contract's address. +address constant IREGULAR_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000065; // 101 + +/// @dev The IRegular contract's instance. +IRegular constant IREGULAR_CONTRACT = IRegular(IREGULAR_PRECOMPILE_ADDRESS); + +interface IRegular { + /// @dev converting a bech32 address to hexadecimal address. + /// @param bech32 The bech32 address. + /// @return addr The hexadecimal address. + function bech32ToHexAddr( + string memory bech32 + ) external view returns (address addr); + + /// @dev converting a hex address to bech32 address. + /// @param prefix of the bech32, e.g. zeta. + /// @param addr The hex address + /// @return bech32 The bech32 address. + function bech32ify( + string memory prefix, + address addr + ) external view returns (string memory bech32); + + /// @dev Function to verify calling regular contact through precompiled contact + /// @param method to call, e.g. bar. + /// @param addr of deployed regular contract. + /// @return result of the call. + function regularCall( + string memory method, + address addr + ) external returns (uint256 result); +} diff --git a/precompile/types/errors.go b/precompiles/types/errors.go similarity index 99% rename from precompile/types/errors.go rename to precompiles/types/errors.go index 82f968468b..b7619f81a8 100644 --- a/precompile/types/errors.go +++ b/precompiles/types/errors.go @@ -14,4 +14,4 @@ const ( ErrInvalidNumberOfArgs = "invalid number of arguments; expected %d; got: %d" // ErrInvalidMethod is raised when the method is invalid. ErrInvalidMethod = "unknown method: %s" -) \ No newline at end of file +) diff --git a/precompile/types/types.go b/precompiles/types/types.go similarity index 77% rename from precompile/types/types.go rename to precompiles/types/types.go index a40b8c70fc..579e138d37 100644 --- a/precompile/types/types.go +++ b/precompiles/types/types.go @@ -1,6 +1,8 @@ package types import ( + "math/big" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" @@ -11,7 +13,11 @@ import ( // It's used to persist changes into the store. type ExtStateDB interface { vm.StateDB - ExecuteNativeAction(contract common.Address, converter statedb.EventConverter, action func(ctx sdk.Context) error) error + ExecuteNativeAction( + contract common.Address, + converter statedb.EventConverter, + action func(ctx sdk.Context) error, + ) error CacheContext() sdk.Context } @@ -36,4 +42,8 @@ func NewBaseContract(address common.Address) BaseContract { func (c *baseContract) RegistryKey() common.Address { return c.address -} \ No newline at end of file +} + +func BytesToBigInt(data []byte) *big.Int { + return big.NewInt(0).SetBytes(data[:]) +} From 40ff210aa29939af8b3e8e7e893fb72add4f9a27 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Wed, 14 Aug 2024 21:08:17 +0200 Subject: [PATCH 03/33] feat: enable contracts granularly --- app/app.go | 4 +++- precompiles/precompiles.go | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/app.go b/app/app.go index 2f06d5b59e..577f325f47 100644 --- a/app/app.go +++ b/app/app.go @@ -1064,7 +1064,9 @@ func (app *App) BlockedAddrs() map[string]bool { } for addr, enabled := range precompiles.EnabledStatefulContracts { - blockList[addr.String()] = enabled + if enabled { + blockList[addr.String()] = enabled + } } return blockList diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go index 6c86c6e8a1..d7ab83997e 100644 --- a/precompiles/precompiles.go +++ b/precompiles/precompiles.go @@ -27,12 +27,14 @@ func StatefulContracts( precompiledContracts = make([]evmkeeper.CustomContractFn, 0) // Define the regular contract function. - regularContract := func(_ sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { - return regular.NewRegularContract(fungibleKeeper, cdc, gasConfig) - } + if EnabledStatefulContracts[regular.ContractAddress] { + regularContract := func(_ sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { + return regular.NewRegularContract(fungibleKeeper, cdc, gasConfig) + } - // Append all the precompiled contracts to the precompiledContracts slice. - precompiledContracts = append(precompiledContracts, regularContract) + // Append the regular contract to the precompiledContracts slice. + precompiledContracts = append(precompiledContracts, regularContract) + } return precompiledContracts } From 83457fc6862b6066a179348b0cc307a547114a29 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Wed, 14 Aug 2024 21:15:13 +0200 Subject: [PATCH 04/33] feat: allow passing the app ctx to contracts --- app/app.go | 2 ++ precompiles/precompiles.go | 1 + 2 files changed, 3 insertions(+) diff --git a/app/app.go b/app/app.go index 577f325f47..2648afe07d 100644 --- a/app/app.go +++ b/app/app.go @@ -89,6 +89,7 @@ import ( feemarketkeeper "github.com/zeta-chain/ethermint/x/feemarket/keeper" feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/zeta-chain/zetacore/app/ante" "github.com/zeta-chain/zetacore/docs/openapi" zetamempool "github.com/zeta-chain/zetacore/pkg/mempool" @@ -571,6 +572,7 @@ func New( tracer, evmSs, precompiles.StatefulContracts( + app.NewContext(true, tmproto.Header{}), app.FungibleKeeper, appCodec, gasConfig, diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go index d7ab83997e..1d12a20b80 100644 --- a/precompiles/precompiles.go +++ b/precompiles/precompiles.go @@ -19,6 +19,7 @@ var EnabledStatefulContracts = map[common.Address]bool{ // StatefulContracts returns all the registered precompiled contracts. func StatefulContracts( + _ sdktypes.Context, fungibleKeeper keeper.Keeper, cdc codec.Codec, gasConfig storetypes.GasConfig, From d13079ac1a15b599340b92a2adf6807a6951cd40 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Wed, 14 Aug 2024 21:23:53 +0200 Subject: [PATCH 05/33] revert ctx changes --- app/app.go | 2 -- precompiles/precompiles.go | 1 - 2 files changed, 3 deletions(-) diff --git a/app/app.go b/app/app.go index 2648afe07d..577f325f47 100644 --- a/app/app.go +++ b/app/app.go @@ -89,7 +89,6 @@ import ( feemarketkeeper "github.com/zeta-chain/ethermint/x/feemarket/keeper" feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/zeta-chain/zetacore/app/ante" "github.com/zeta-chain/zetacore/docs/openapi" zetamempool "github.com/zeta-chain/zetacore/pkg/mempool" @@ -572,7 +571,6 @@ func New( tracer, evmSs, precompiles.StatefulContracts( - app.NewContext(true, tmproto.Header{}), app.FungibleKeeper, appCodec, gasConfig, diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go index 1d12a20b80..d7ab83997e 100644 --- a/precompiles/precompiles.go +++ b/precompiles/precompiles.go @@ -19,7 +19,6 @@ var EnabledStatefulContracts = map[common.Address]bool{ // StatefulContracts returns all the registered precompiled contracts. func StatefulContracts( - _ sdktypes.Context, fungibleKeeper keeper.Keeper, cdc codec.Codec, gasConfig storetypes.GasConfig, From e58c78386d09631d3fcf2dfeacdb46dd2699dd8a Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Wed, 14 Aug 2024 21:26:31 +0200 Subject: [PATCH 06/33] format ABI --- precompiles/regular/src/IRegular.abi | 1 - precompiles/regular/src/IRegularABI.json | 37 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) delete mode 100644 precompiles/regular/src/IRegular.abi create mode 100644 precompiles/regular/src/IRegularABI.json diff --git a/precompiles/regular/src/IRegular.abi b/precompiles/regular/src/IRegular.abi deleted file mode 100644 index a2c527ee60..0000000000 --- a/precompiles/regular/src/IRegular.abi +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"string","name":"bech32","type":"string"}],"name":"bech32ToHexAddr","outputs":[{"internalType":"address","name":"addr","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"prefix","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"bech32ify","outputs":[{"internalType":"string","name":"bech32","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"method","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"regularCall","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/precompiles/regular/src/IRegularABI.json b/precompiles/regular/src/IRegularABI.json new file mode 100644 index 0000000000..3804046ec6 --- /dev/null +++ b/precompiles/regular/src/IRegularABI.json @@ -0,0 +1,37 @@ +[ + { + "inputs": [ + { "internalType": "string", "name": "bech32", "type": "string" } + ], + "name": "bech32ToHexAddr", + "outputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "prefix", "type": "string" }, + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "bech32ify", + "outputs": [ + { "internalType": "string", "name": "bech32", "type": "string" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "method", "type": "string" }, + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "regularCall", + "outputs": [ + { "internalType": "uint256", "name": "result", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] From eaac523fa59be1b7b967c43f58408eed7140fb63 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Thu, 15 Aug 2024 14:09:26 +0200 Subject: [PATCH 07/33] add first e2e test --- app/app.go | 5 +- changelog.md | 3 +- cmd/zetae2e/config/clients.go | 3 +- cmd/zetae2e/local/local.go | 1 + e2e/e2etests/e2etests.go | 7 + e2e/e2etests/test_precompiles_regular.go | 27 ++ precompiles/regular/{src => }/IRegular.sol | 0 precompiles/regular/IRegularABI.go | 264 ++++++++++++++++++ .../regular/{src => }/IRegularABI.json | 0 precompiles/regular/regular.go | 9 +- precompiles/testutil/errors.go | 39 +++ precompiles/testutil/events.go | 34 +++ precompiles/testutil/logs.go | 121 ++++++++ 13 files changed, 503 insertions(+), 10 deletions(-) create mode 100644 e2e/e2etests/test_precompiles_regular.go rename precompiles/regular/{src => }/IRegular.sol (100%) create mode 100644 precompiles/regular/IRegularABI.go rename precompiles/regular/{src => }/IRegularABI.json (100%) create mode 100644 precompiles/testutil/errors.go create mode 100644 precompiles/testutil/events.go create mode 100644 precompiles/testutil/logs.go diff --git a/app/app.go b/app/app.go index 577f325f47..23c1727c71 100644 --- a/app/app.go +++ b/app/app.go @@ -556,9 +556,6 @@ func New( ) evmSs := app.GetSubspace(evmtypes.ModuleName) - // Get gas config for stateful contracts. - gasConfig := storetypes.TransientGasConfig() - app.EvmKeeper = evmkeeper.NewKeeper( appCodec, keys[evmtypes.StoreKey], @@ -573,7 +570,7 @@ func New( precompiles.StatefulContracts( app.FungibleKeeper, appCodec, - gasConfig, + storetypes.TransientGasConfig(), ), app.ConsensusParamsKeeper, aggregateAllKeys(keys, tKeys, memKeys), diff --git a/changelog.md b/changelog.md index bef780d4a2..7ef55517f7 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,7 @@ * [2634](https://github.com/zeta-chain/node/pull/2634) - add support for EIP-1559 gas fees * [2597](https://github.com/zeta-chain/node/pull/2597) - Add generic rpc metrics to zetaclient * [2538](https://github.com/zeta-chain/node/pull/2538) - add background worker routines to shutdown zetaclientd when needed for tss migration +* [2633](https://github.com/zeta-chain/node/pull/2633) - support for stateful precompiled contracts. ### Refactor @@ -57,7 +58,6 @@ * [2524](https://github.com/zeta-chain/node/pull/2524) - add inscription envelop parsing * [2560](https://github.com/zeta-chain/node/pull/2560) - add support for Solana SOL token withdraw * [2533](https://github.com/zeta-chain/node/pull/2533) - parse memo from both OP_RETURN and inscription -* [2633](https://github.com/zeta-chain/node/pull/2633) - support for stateful precompiled contracts. ### Refactor @@ -115,6 +115,7 @@ * [2415](https://github.com/zeta-chain/node/pull/2415) - add e2e test for upgrade and test admin functionalities * [2440](https://github.com/zeta-chain/node/pull/2440) - Add e2e test for TSS migration * [2473](https://github.com/zeta-chain/node/pull/2473) - add e2e tests for most used admin transactions +* [2703](https://github.com/zeta-chain/node/pull/2703) - add e2e tests for stateful precompiled contracts ### Fixes diff --git a/cmd/zetae2e/config/clients.go b/cmd/zetae2e/config/clients.go index e70f2c566a..ac4686fc23 100644 --- a/cmd/zetae2e/config/clients.go +++ b/cmd/zetae2e/config/clients.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/gagliardetto/solana-go/rpc" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/zeta-chain/zetacore/e2e/config" authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" @@ -156,7 +157,7 @@ func getZetaClients(rpc string) ( zetaChainClients, error, ) { - grpcConn, err := grpc.Dial(rpc, grpc.WithInsecure()) + grpcConn, err := grpc.Dial(rpc, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return zetaChainClients{}, err } diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index cb24096859..2732d8daf6 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -229,6 +229,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestERC20DepositRestrictedName, } zetaTests := []string{ + e2etests.TestZetaPrecompilesName, e2etests.TestZetaWithdrawName, e2etests.TestMessagePassingExternalChainsName, e2etests.TestMessagePassingRevertFailExternalChainsName, diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 402eed367e..2b44003a21 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -15,6 +15,7 @@ const ( TestZetaDepositRestrictedName = "zeta_deposit_restricted" TestZetaWithdrawName = "zeta_withdraw" TestZetaWithdrawBTCRevertName = "zeta_withdraw_btc_revert" // #nosec G101 - not a hardcoded password + TestZetaPrecompilesName = "zeta_precompiles" /* Message passing tests @@ -123,6 +124,12 @@ var AllE2ETests = []runner.E2ETest{ /* ZETA tests */ + runner.NewE2ETest( + TestZetaPrecompilesName, + "call Regular stateful precompiled contract", + []runner.ArgDefinition{}, + TestPrecompilesRegular, + ), runner.NewE2ETest( TestZetaDepositName, "deposit ZETA from Ethereum to ZEVM", diff --git a/e2e/e2etests/test_precompiles_regular.go b/e2e/e2etests/test_precompiles_regular.go new file mode 100644 index 0000000000..b31b3f5337 --- /dev/null +++ b/e2e/e2etests/test_precompiles_regular.go @@ -0,0 +1,27 @@ +package e2etests + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/zetacore/e2e/runner" + "github.com/zeta-chain/zetacore/precompiles/regular" +) + +func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { + require.Len(r, args, 0, "No arguments expected") + + dummyBech32Addr := "1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u" + + // Call the Regular contract in the static precompile address. + contract, err := regular.NewRegular(regular.ContractAddress, r.EVMClient) + require.NoError(r, err, "Failed to create Regular contract caller") + + addr, err := contract.Bech32ToHexAddr( + nil, + common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE").String(), + ) + require.NoError(r, err, "Failed to call Bech32ToHexAddr in Regular precompiled contract") + + require.Equal(r, dummyBech32Addr, addr.String(), "Expected address %s, got %s", dummyBech32Addr, addr.String()) +} diff --git a/precompiles/regular/src/IRegular.sol b/precompiles/regular/IRegular.sol similarity index 100% rename from precompiles/regular/src/IRegular.sol rename to precompiles/regular/IRegular.sol diff --git a/precompiles/regular/IRegularABI.go b/precompiles/regular/IRegularABI.go new file mode 100644 index 0000000000..582d9f6b83 --- /dev/null +++ b/precompiles/regular/IRegularABI.go @@ -0,0 +1,264 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package regular + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// RegularMetaData contains all meta data concerning the Regular contract. +var RegularMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"name\":\"bech32ToHexAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"prefix\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"bech32ify\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"regularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// RegularABI is the input ABI used to generate the binding from. +// Deprecated: Use RegularMetaData.ABI instead. +var RegularABI = RegularMetaData.ABI + +// Regular is an auto generated Go binding around an Ethereum contract. +type Regular struct { + RegularCaller // Read-only binding to the contract + RegularTransactor // Write-only binding to the contract + RegularFilterer // Log filterer for contract events +} + +// RegularCaller is an auto generated read-only Go binding around an Ethereum contract. +type RegularCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularTransactor is an auto generated write-only Go binding around an Ethereum contract. +type RegularTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type RegularFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type RegularSession struct { + Contract *Regular // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RegularCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type RegularCallerSession struct { + Contract *RegularCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// RegularTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type RegularTransactorSession struct { + Contract *RegularTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RegularRaw is an auto generated low-level Go binding around an Ethereum contract. +type RegularRaw struct { + Contract *Regular // Generic contract binding to access the raw methods on +} + +// RegularCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type RegularCallerRaw struct { + Contract *RegularCaller // Generic read-only contract binding to access the raw methods on +} + +// RegularTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type RegularTransactorRaw struct { + Contract *RegularTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewRegular creates a new instance of Regular, bound to a specific deployed contract. +func NewRegular(address common.Address, backend bind.ContractBackend) (*Regular, error) { + contract, err := bindRegular(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Regular{RegularCaller: RegularCaller{contract: contract}, RegularTransactor: RegularTransactor{contract: contract}, RegularFilterer: RegularFilterer{contract: contract}}, nil +} + +// NewRegularCaller creates a new read-only instance of Regular, bound to a specific deployed contract. +func NewRegularCaller(address common.Address, caller bind.ContractCaller) (*RegularCaller, error) { + contract, err := bindRegular(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RegularCaller{contract: contract}, nil +} + +// NewRegularTransactor creates a new write-only instance of Regular, bound to a specific deployed contract. +func NewRegularTransactor(address common.Address, transactor bind.ContractTransactor) (*RegularTransactor, error) { + contract, err := bindRegular(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RegularTransactor{contract: contract}, nil +} + +// NewRegularFilterer creates a new log filterer instance of Regular, bound to a specific deployed contract. +func NewRegularFilterer(address common.Address, filterer bind.ContractFilterer) (*RegularFilterer, error) { + contract, err := bindRegular(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RegularFilterer{contract: contract}, nil +} + +// bindRegular binds a generic wrapper to an already deployed contract. +func bindRegular(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RegularMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Regular *RegularRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Regular.Contract.RegularCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Regular *RegularRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Regular.Contract.RegularTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Regular *RegularRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Regular.Contract.RegularTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Regular *RegularCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Regular.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Regular *RegularTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Regular.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Regular *RegularTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Regular.Contract.contract.Transact(opts, method, params...) +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_Regular *RegularCaller) Bech32ToHexAddr(opts *bind.CallOpts, bech32 string) (common.Address, error) { + var out []interface{} + err := _Regular.contract.Call(opts, &out, "bech32ToHexAddr", bech32) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_Regular *RegularSession) Bech32ToHexAddr(bech32 string) (common.Address, error) { + return _Regular.Contract.Bech32ToHexAddr(&_Regular.CallOpts, bech32) +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_Regular *RegularCallerSession) Bech32ToHexAddr(bech32 string) (common.Address, error) { + return _Regular.Contract.Bech32ToHexAddr(&_Regular.CallOpts, bech32) +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_Regular *RegularCaller) Bech32ify(opts *bind.CallOpts, prefix string, addr common.Address) (string, error) { + var out []interface{} + err := _Regular.contract.Call(opts, &out, "bech32ify", prefix, addr) + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_Regular *RegularSession) Bech32ify(prefix string, addr common.Address) (string, error) { + return _Regular.Contract.Bech32ify(&_Regular.CallOpts, prefix, addr) +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_Regular *RegularCallerSession) Bech32ify(prefix string, addr common.Address) (string, error) { + return _Regular.Contract.Bech32ify(&_Regular.CallOpts, prefix, addr) +} + +// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// +// Solidity: function regularCall(string method, address addr) returns(uint256 result) +func (_Regular *RegularTransactor) RegularCall(opts *bind.TransactOpts, method string, addr common.Address) (*types.Transaction, error) { + return _Regular.contract.Transact(opts, "regularCall", method, addr) +} + +// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// +// Solidity: function regularCall(string method, address addr) returns(uint256 result) +func (_Regular *RegularSession) RegularCall(method string, addr common.Address) (*types.Transaction, error) { + return _Regular.Contract.RegularCall(&_Regular.TransactOpts, method, addr) +} + +// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// +// Solidity: function regularCall(string method, address addr) returns(uint256 result) +func (_Regular *RegularTransactorSession) RegularCall(method string, addr common.Address) (*types.Transaction, error) { + return _Regular.Contract.RegularCall(&_Regular.TransactOpts, method, addr) +} diff --git a/precompiles/regular/src/IRegularABI.json b/precompiles/regular/IRegularABI.json similarity index 100% rename from precompiles/regular/src/IRegularABI.json rename to precompiles/regular/IRegularABI.json diff --git a/precompiles/regular/regular.go b/precompiles/regular/regular.go index ece46b6b43..608ea03546 100644 --- a/precompiles/regular/regular.go +++ b/precompiles/regular/regular.go @@ -98,12 +98,15 @@ func (rc *Contract) Abi() abi.ABI { func (rc *Contract) RequiredGas(input []byte) uint64 { // base cost to prevent large input size baseCost := uint64(len(input)) * rc.kvGasConfig.WriteCostPerByte + + // get methodID (first 4 bytes) var methodID [4]byte copy(methodID[:], input[:4]) - requiredGas, ok := GasRequiredByMethod[methodID] - if ok { + + if requiredGas, ok := GasRequiredByMethod[methodID]; ok { return requiredGas + baseCost } + return baseCost } @@ -239,8 +242,6 @@ func (rc *Contract) Run(evm *vm.EVM, contract *vm.Contract, _ bool) ([]byte, err return rc.Bech32ToHexAddr(method, args) case Bech32ifyMethodName: return rc.Bech32ify(method, args) - // case OtherMethods: - // .. default: return nil, errors.New("unknown method") } diff --git a/precompiles/testutil/errors.go b/precompiles/testutil/errors.go new file mode 100644 index 0000000000..030f32276e --- /dev/null +++ b/precompiles/testutil/errors.go @@ -0,0 +1,39 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package testutil + +import ( + "fmt" + "strings" + + abci "github.com/cometbft/cometbft/abci/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" +) + +// CheckVMError is a helper function used to check if the transaction is reverted with the expected error message +// in the VmError field of the MsgEthereumResponse struct. +func CheckVMError(res abci.ResponseDeliverTx, expErrMsg string, args ...interface{}) error { + if !res.IsOK() { + return fmt.Errorf("code 0 was expected on response but got code %d", res.Code) + } + ethRes, err := evmtypes.DecodeTxResponse(res.Data) + if err != nil { + return fmt.Errorf("error occurred while decoding the TxResponse. %s", err) + } + expMsg := fmt.Sprintf(expErrMsg, args...) + if !strings.Contains(ethRes.VmError, expMsg) { + return fmt.Errorf( + "unexpected VmError on response. expected error to contain: %s, received: %s", + expMsg, + ethRes.VmError, + ) + } + return nil +} + +// CheckEthereumTxFailed checks if there is a VM error in the transaction response and returns the reason. +func CheckEthereumTxFailed(ethRes *evmtypes.MsgEthereumTxResponse) (string, bool) { + reason := ethRes.VmError + return reason, reason != "" +} diff --git a/precompiles/testutil/events.go b/precompiles/testutil/events.go new file mode 100644 index 0000000000..3689c55d0c --- /dev/null +++ b/precompiles/testutil/events.go @@ -0,0 +1,34 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package testutil + +import ( + "fmt" + "strings" + + //nolint:stylecheck,revive // it's common practice to use the global imports for Ginkgo and Gomega + "github.com/ethereum/go-ethereum/accounts/abi" +) + +// validateEvents checks if the provided event names are included as keys in the contract events. +func validateEvents(contractEvents map[string]abi.Event, events []string) ([]abi.Event, error) { + expEvents := make([]abi.Event, 0, len(events)) + for _, eventStr := range events { + event, found := contractEvents[eventStr] + if !found { + availableABIEvents := make([]string, 0, len(contractEvents)) + for event := range contractEvents { + availableABIEvents = append(availableABIEvents, event) + } + availableABIEventsStr := strings.Join(availableABIEvents, ", ") + return nil, fmt.Errorf( + "unknown event %q is not contained in given ABI events:\n%s", + eventStr, + availableABIEventsStr, + ) + } + expEvents = append(expEvents, event) + } + return expEvents, nil +} diff --git a/precompiles/testutil/logs.go b/precompiles/testutil/logs.go new file mode 100644 index 0000000000..fe16a64ed5 --- /dev/null +++ b/precompiles/testutil/logs.go @@ -0,0 +1,121 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package testutil + +import ( + "fmt" + + abci "github.com/cometbft/cometbft/abci/types" + "github.com/ethereum/go-ethereum/accounts/abi" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + "golang.org/x/exp/slices" +) + +// CheckLogs checks the logs for the given events and whether the transaction was successful or not. +func CheckLogs(logArgs LogCheckArgs) error { + if len(logArgs.ExpEvents) != 0 && len(logArgs.ABIEvents) == 0 { + return fmt.Errorf("no ABI events provided in log check arguments, but expected events are present") + } + + expABIEvents, err := validateEvents(logArgs.ABIEvents, logArgs.ExpEvents) + if err != nil { + return err + } + + ethRes, err := evmtypes.DecodeTxResponse(logArgs.Res.Data) + if err != nil { + return fmt.Errorf("error while decoding ethereum tx response: %v", err) + } + + reason, failed := CheckEthereumTxFailed(ethRes) + if failed != !logArgs.ExpPass { + return fmt.Errorf( + "expected vm error found to be %t; got: %t (reason: %s)\nGas usage: %d/%d (~%d %%)", + !logArgs.ExpPass, + failed, + reason, + logArgs.Res.GasUsed, + logArgs.Res.GasWanted, + int64(float64(logArgs.Res.GasUsed)/float64(logArgs.Res.GasWanted)*100), + ) + } + + if err := CheckVMError(logArgs.Res, logArgs.ErrContains); err != nil { + return err + } + + if len(ethRes.Logs) != len(logArgs.ExpEvents) { + return fmt.Errorf("expected %d events in Ethereum response; got: %d", len(logArgs.ExpEvents), len(ethRes.Logs)) + } + + // Check if expected events are present in Ethereum response + availableEventIDs := make([]string, 0, len(ethRes.Logs)) + for _, log := range ethRes.Logs { + availableEventIDs = append(availableEventIDs, log.Topics[0]) + } + + expEventIDs := make([]string, 0, len(expABIEvents)) + for _, event := range expABIEvents { + expEventIDs = append(expEventIDs, event.ID.String()) + } + + for _, eventID := range expEventIDs { + if !slices.Contains(availableEventIDs, eventID) { + return fmt.Errorf("expected event with ID %v not found in Ethereum response", eventID) + } + } + + return nil +} + +// LogCheckArgs is a struct that contains configuration for the log checking. +type LogCheckArgs struct { + // ABIEvents is a map of available abi.Event corresponding to the corresponding event names, + // which are available in the contract ABI. + ABIEvents map[string]abi.Event + // ErrContains is the error message that is expected to be contained in the transaction response. + ErrContains string + // ExpEvents are the events which are expected to be emitted. + ExpEvents []string + // ExpPass is whether the transaction is expected to pass or not. + ExpPass bool + // Res is the response of the transaction. + // + // NOTE: This does not have to be set when using contracts.CallContractAndCheckLogs. + Res abci.ResponseDeliverTx +} + +// WithABIEvents sets the ABIEvents field of LogCheckArgs. +func (l LogCheckArgs) WithABIEvents(abiEvents map[string]abi.Event) LogCheckArgs { + l.ABIEvents = abiEvents + return l +} + +// WithErrContains sets the ErrContains field of LogCheckArgs. +// If any printArgs are provided, they are used to format the error message. +func (l LogCheckArgs) WithErrContains(errContains string, printArgs ...interface{}) LogCheckArgs { + if len(printArgs) > 0 { + errContains = fmt.Sprintf(errContains, printArgs...) + } + l.ErrContains = errContains + return l +} + +// WithExpEvents sets the ExpEvents field of LogCheckArgs. +func (l LogCheckArgs) WithExpEvents(expEvents ...string) LogCheckArgs { + l.ExpEvents = expEvents + return l +} + +// WithExpPass sets the ExpPass field of LogCheckArgs. +func (l LogCheckArgs) WithExpPass(expPass bool) LogCheckArgs { + l.ExpPass = expPass + return l +} + +// WithRes sets the Res field of LogCheckArgs. +func (l LogCheckArgs) WithRes(res abci.ResponseDeliverTx) LogCheckArgs { + l.Res = res + return l +} From fadf37a0e4a2b119ceebea4a7288a5d46e30979e Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Thu, 15 Aug 2024 15:37:32 +0200 Subject: [PATCH 08/33] add RegularCaller contract to e2e --- e2e/e2etests/test_precompiles_regular.go | 24 +- .../regular/testutil/RegularCaller.abi | 52 ++++ .../regular/testutil/RegularCaller.bin | 1 + precompiles/regular/testutil/RegularCaller.go | 286 ++++++++++++++++++ .../regular/testutil/RegularCaller.json | 55 ++++ .../regular/testutil/RegularCaller.sol | 50 +++ 6 files changed, 457 insertions(+), 11 deletions(-) create mode 100644 precompiles/regular/testutil/RegularCaller.abi create mode 100644 precompiles/regular/testutil/RegularCaller.bin create mode 100644 precompiles/regular/testutil/RegularCaller.go create mode 100644 precompiles/regular/testutil/RegularCaller.json create mode 100644 precompiles/regular/testutil/RegularCaller.sol diff --git a/e2e/e2etests/test_precompiles_regular.go b/e2e/e2etests/test_precompiles_regular.go index b31b3f5337..d434dfa32b 100644 --- a/e2e/e2etests/test_precompiles_regular.go +++ b/e2e/e2etests/test_precompiles_regular.go @@ -1,27 +1,29 @@ package e2etests import ( - "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" - "github.com/zeta-chain/zetacore/precompiles/regular" + "github.com/zeta-chain/zetacore/e2e/utils" + regularcaller "github.com/zeta-chain/zetacore/precompiles/regular/testutil" ) func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { require.Len(r, args, 0, "No arguments expected") - dummyBech32Addr := "1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u" + _, tx, contract, err := regularcaller.DeployRegularCaller(&bind.TransactOpts{}, r.ZEVMClient) + require.NoError(r, err, "Failed to deploy RegularCaller contract") + + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + require.Equal(r, receipt.Status, 1, "Failed to deploy RegularCaller contract") // Call the Regular contract in the static precompile address. - contract, err := regular.NewRegular(regular.ContractAddress, r.EVMClient) + ok, err := contract.TestBech32ToHexAddr(&bind.CallOpts{}) require.NoError(r, err, "Failed to create Regular contract caller") + require.True(r, ok, "Failed to validate Bech32ToHexAddr function") - addr, err := contract.Bech32ToHexAddr( - nil, - common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE").String(), - ) - require.NoError(r, err, "Failed to call Bech32ToHexAddr in Regular precompiled contract") - - require.Equal(r, dummyBech32Addr, addr.String(), "Expected address %s, got %s", dummyBech32Addr, addr.String()) + ok, err = contract.TestBech32ify(&bind.CallOpts{}) + require.NoError(r, err, "Failed to create Regular contract caller") + require.True(r, ok, "Failed to validate Bech32ToHexAddr function") } diff --git a/precompiles/regular/testutil/RegularCaller.abi b/precompiles/regular/testutil/RegularCaller.abi new file mode 100644 index 0000000000..8f4eee8709 --- /dev/null +++ b/precompiles/regular/testutil/RegularCaller.abi @@ -0,0 +1,52 @@ +[ + { + "inputs": [], + "name": "testBech32ToHexAddr", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "testBech32ify", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "method", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "testRegularCall", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/precompiles/regular/testutil/RegularCaller.bin b/precompiles/regular/testutil/RegularCaller.bin new file mode 100644 index 0000000000..5b7447ab81 --- /dev/null +++ b/precompiles/regular/testutil/RegularCaller.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033 \ No newline at end of file diff --git a/precompiles/regular/testutil/RegularCaller.go b/precompiles/regular/testutil/RegularCaller.go new file mode 100644 index 0000000000..71b45e868a --- /dev/null +++ b/precompiles/regular/testutil/RegularCaller.go @@ -0,0 +1,286 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package testutils + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// RegularCallerMetaData contains all meta data concerning the RegularCaller contract. +var RegularCallerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"testBech32ToHexAddr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testBech32ify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"testRegularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033", +} + +// RegularCallerABI is the input ABI used to generate the binding from. +// Deprecated: Use RegularCallerMetaData.ABI instead. +var RegularCallerABI = RegularCallerMetaData.ABI + +// RegularCallerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use RegularCallerMetaData.Bin instead. +var RegularCallerBin = RegularCallerMetaData.Bin + +// DeployRegularCaller deploys a new Ethereum contract, binding an instance of RegularCaller to it. +func DeployRegularCaller(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *RegularCaller, error) { + parsed, err := RegularCallerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RegularCallerBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &RegularCaller{RegularCallerCaller: RegularCallerCaller{contract: contract}, RegularCallerTransactor: RegularCallerTransactor{contract: contract}, RegularCallerFilterer: RegularCallerFilterer{contract: contract}}, nil +} + +// RegularCaller is an auto generated Go binding around an Ethereum contract. +type RegularCaller struct { + RegularCallerCaller // Read-only binding to the contract + RegularCallerTransactor // Write-only binding to the contract + RegularCallerFilterer // Log filterer for contract events +} + +// RegularCallerCaller is an auto generated read-only Go binding around an Ethereum contract. +type RegularCallerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularCallerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type RegularCallerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularCallerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type RegularCallerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularCallerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type RegularCallerSession struct { + Contract *RegularCaller // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RegularCallerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type RegularCallerCallerSession struct { + Contract *RegularCallerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// RegularCallerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type RegularCallerTransactorSession struct { + Contract *RegularCallerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RegularCallerRaw is an auto generated low-level Go binding around an Ethereum contract. +type RegularCallerRaw struct { + Contract *RegularCaller // Generic contract binding to access the raw methods on +} + +// RegularCallerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type RegularCallerCallerRaw struct { + Contract *RegularCallerCaller // Generic read-only contract binding to access the raw methods on +} + +// RegularCallerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type RegularCallerTransactorRaw struct { + Contract *RegularCallerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewRegularCaller creates a new instance of RegularCaller, bound to a specific deployed contract. +func NewRegularCaller(address common.Address, backend bind.ContractBackend) (*RegularCaller, error) { + contract, err := bindRegularCaller(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &RegularCaller{RegularCallerCaller: RegularCallerCaller{contract: contract}, RegularCallerTransactor: RegularCallerTransactor{contract: contract}, RegularCallerFilterer: RegularCallerFilterer{contract: contract}}, nil +} + +// NewRegularCallerCaller creates a new read-only instance of RegularCaller, bound to a specific deployed contract. +func NewRegularCallerCaller(address common.Address, caller bind.ContractCaller) (*RegularCallerCaller, error) { + contract, err := bindRegularCaller(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RegularCallerCaller{contract: contract}, nil +} + +// NewRegularCallerTransactor creates a new write-only instance of RegularCaller, bound to a specific deployed contract. +func NewRegularCallerTransactor(address common.Address, transactor bind.ContractTransactor) (*RegularCallerTransactor, error) { + contract, err := bindRegularCaller(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RegularCallerTransactor{contract: contract}, nil +} + +// NewRegularCallerFilterer creates a new log filterer instance of RegularCaller, bound to a specific deployed contract. +func NewRegularCallerFilterer(address common.Address, filterer bind.ContractFilterer) (*RegularCallerFilterer, error) { + contract, err := bindRegularCaller(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RegularCallerFilterer{contract: contract}, nil +} + +// bindRegularCaller binds a generic wrapper to an already deployed contract. +func bindRegularCaller(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RegularCallerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_RegularCaller *RegularCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RegularCaller.Contract.RegularCallerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_RegularCaller *RegularCallerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RegularCaller.Contract.RegularCallerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_RegularCaller *RegularCallerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RegularCaller.Contract.RegularCallerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_RegularCaller *RegularCallerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RegularCaller.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_RegularCaller *RegularCallerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RegularCaller.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_RegularCaller *RegularCallerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RegularCaller.Contract.contract.Transact(opts, method, params...) +} + +// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. +// +// Solidity: function testBech32ToHexAddr() view returns(bool) +func (_RegularCaller *RegularCallerCaller) TestBech32ToHexAddr(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _RegularCaller.contract.Call(opts, &out, "testBech32ToHexAddr") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. +// +// Solidity: function testBech32ToHexAddr() view returns(bool) +func (_RegularCaller *RegularCallerSession) TestBech32ToHexAddr() (bool, error) { + return _RegularCaller.Contract.TestBech32ToHexAddr(&_RegularCaller.CallOpts) +} + +// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. +// +// Solidity: function testBech32ToHexAddr() view returns(bool) +func (_RegularCaller *RegularCallerCallerSession) TestBech32ToHexAddr() (bool, error) { + return _RegularCaller.Contract.TestBech32ToHexAddr(&_RegularCaller.CallOpts) +} + +// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. +// +// Solidity: function testBech32ify() view returns(bool) +func (_RegularCaller *RegularCallerCaller) TestBech32ify(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _RegularCaller.contract.Call(opts, &out, "testBech32ify") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. +// +// Solidity: function testBech32ify() view returns(bool) +func (_RegularCaller *RegularCallerSession) TestBech32ify() (bool, error) { + return _RegularCaller.Contract.TestBech32ify(&_RegularCaller.CallOpts) +} + +// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. +// +// Solidity: function testBech32ify() view returns(bool) +func (_RegularCaller *RegularCallerCallerSession) TestBech32ify() (bool, error) { + return _RegularCaller.Contract.TestBech32ify(&_RegularCaller.CallOpts) +} + +// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. +// +// Solidity: function testRegularCall(string method, address addr) returns(uint256) +func (_RegularCaller *RegularCallerTransactor) TestRegularCall(opts *bind.TransactOpts, method string, addr common.Address) (*types.Transaction, error) { + return _RegularCaller.contract.Transact(opts, "testRegularCall", method, addr) +} + +// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. +// +// Solidity: function testRegularCall(string method, address addr) returns(uint256) +func (_RegularCaller *RegularCallerSession) TestRegularCall(method string, addr common.Address) (*types.Transaction, error) { + return _RegularCaller.Contract.TestRegularCall(&_RegularCaller.TransactOpts, method, addr) +} + +// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. +// +// Solidity: function testRegularCall(string method, address addr) returns(uint256) +func (_RegularCaller *RegularCallerTransactorSession) TestRegularCall(method string, addr common.Address) (*types.Transaction, error) { + return _RegularCaller.Contract.TestRegularCall(&_RegularCaller.TransactOpts, method, addr) +} diff --git a/precompiles/regular/testutil/RegularCaller.json b/precompiles/regular/testutil/RegularCaller.json new file mode 100644 index 0000000000..f8187a2651 --- /dev/null +++ b/precompiles/regular/testutil/RegularCaller.json @@ -0,0 +1,55 @@ +{ + "abi": [ + { + "inputs": [], + "name": "testBech32ToHexAddr", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "testBech32ify", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "method", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "testRegularCall", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033" +} diff --git a/precompiles/regular/testutil/RegularCaller.sol b/precompiles/regular/testutil/RegularCaller.sol new file mode 100644 index 0000000000..2e9aa13ee0 --- /dev/null +++ b/precompiles/regular/testutil/RegularCaller.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity ^0.8.7; + +import "./IRegular.sol"; + +//IRegular constant IREGULAR_CONTRACT = IRegular(IREGULAR_PRECOMPILE_ADDRESS); +contract RegularCaller { + function testBech32ToHexAddr() public view returns (bool) { + // Test input and expected output + string + memory testBech32 = "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"; + address expectedHexAddr = 0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE; + + // Call the precompiled contract + address result = IREGULAR_CONTRACT.bech32ToHexAddr(testBech32); + + // Check if the result matches the expected output + return result == expectedHexAddr; + } + + function testBech32ify() public view returns (bool) { + // Test input and expected output + string memory testPrefix = "zeta"; + address testHexAddr = 0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE; + string + memory expectedBech32 = "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"; + + // Call the precompiled contract + string memory result = IREGULAR_CONTRACT.bech32ify( + testPrefix, + testHexAddr + ); + + // Check if the result matches the expected output + return + keccak256(abi.encodePacked(result)) == + keccak256(abi.encodePacked(expectedBech32)); + } + + function testRegularCall( + string memory method, + address addr + ) public returns (uint256) { + // Call the precompiled contract with the given method and address + uint256 result = IREGULAR_CONTRACT.regularCall(method, addr); + + // Return the result + return result; + } +} From 8ad612b5c6a98ee02bfb184244058a87cee20841 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Thu, 15 Aug 2024 15:46:55 +0200 Subject: [PATCH 09/33] add signer to deployment --- e2e/e2etests/test_precompiles_regular.go | 6 ++++-- precompiles/regular/regular.go | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/e2e/e2etests/test_precompiles_regular.go b/e2e/e2etests/test_precompiles_regular.go index d434dfa32b..ce999cc789 100644 --- a/e2e/e2etests/test_precompiles_regular.go +++ b/e2e/e2etests/test_precompiles_regular.go @@ -12,11 +12,13 @@ import ( func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { require.Len(r, args, 0, "No arguments expected") - _, tx, contract, err := regularcaller.DeployRegularCaller(&bind.TransactOpts{}, r.ZEVMClient) + _, tx, contract, err := regularcaller.DeployRegularCaller(r.ZEVMAuth, r.ZEVMClient) require.NoError(r, err, "Failed to deploy RegularCaller contract") + r.Logger.Info("Contract deployed") receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - require.Equal(r, receipt.Status, 1, "Failed to deploy RegularCaller contract") + require.Equal(r, receipt.Status, uint64(1), "Failed to deploy RegularCaller contract") + r.Logger.Info("Deploy transaction successful") // Call the Regular contract in the static precompile address. ok, err := contract.TestBech32ToHexAddr(&bind.CallOpts{}) diff --git a/precompiles/regular/regular.go b/precompiles/regular/regular.go index 608ea03546..1245e50c1b 100644 --- a/precompiles/regular/regular.go +++ b/precompiles/regular/regular.go @@ -28,7 +28,7 @@ const ( var ( ABI abi.ABI - ContractAddress = common.BytesToAddress([]byte{101}) + ContractAddress = common.HexToAddress("0x0000000000000000000000000000000000000065") GasRequiredByMethod = map[[4]byte]uint64{} ExampleABI *abi.ABI ) From a717f01bdce36cc29e091af37da9a5cdfb95e095 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Fri, 16 Aug 2024 12:11:19 +0200 Subject: [PATCH 10/33] fix e2e, use regular abi --- e2e/e2etests/test_precompiles_regular.go | 29 ++++++++++-------------- precompiles/regular/regular.go | 6 ++--- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/e2e/e2etests/test_precompiles_regular.go b/e2e/e2etests/test_precompiles_regular.go index ce999cc789..1d7b2db955 100644 --- a/e2e/e2etests/test_precompiles_regular.go +++ b/e2e/e2etests/test_precompiles_regular.go @@ -1,31 +1,26 @@ package e2etests import ( - "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" - "github.com/zeta-chain/zetacore/e2e/utils" - regularcaller "github.com/zeta-chain/zetacore/precompiles/regular/testutil" + + //regularcaller "github.com/zeta-chain/zetacore/precompiles/regular/testutil" + "github.com/zeta-chain/zetacore/precompiles/regular" ) func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { require.Len(r, args, 0, "No arguments expected") - _, tx, contract, err := regularcaller.DeployRegularCaller(r.ZEVMAuth, r.ZEVMClient) - require.NoError(r, err, "Failed to deploy RegularCaller contract") - r.Logger.Info("Contract deployed") - - receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - require.Equal(r, receipt.Status, uint64(1), "Failed to deploy RegularCaller contract") - r.Logger.Info("Deploy transaction successful") + caller, err := regular.NewRegularCaller(regular.ContractAddress, r.ZEVMClient) + require.NoError(r, err, "Failed to create RegularCaller") - // Call the Regular contract in the static precompile address. - ok, err := contract.TestBech32ToHexAddr(&bind.CallOpts{}) - require.NoError(r, err, "Failed to create Regular contract caller") - require.True(r, ok, "Failed to validate Bech32ToHexAddr function") + res, err := caller.Bech32ify(nil, "zeta", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) + require.NoError(r, err, "Error calling Bech32ify") + require.Equal(r, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", res, "Failed to validate Bech32ify function") - ok, err = contract.TestBech32ify(&bind.CallOpts{}) - require.NoError(r, err, "Failed to create Regular contract caller") - require.True(r, ok, "Failed to validate Bech32ToHexAddr function") + addr, err := caller.Bech32ToHexAddr(nil, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u") + require.NoError(r, err, "Error calling Bech32ToHexAddr") + require.Equal(r, "0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE", addr.String(), "Failed to validate Bech32ToHexAddr function") } diff --git a/precompiles/regular/regular.go b/precompiles/regular/regular.go index 1245e50c1b..8fea3bdcaf 100644 --- a/precompiles/regular/regular.go +++ b/precompiles/regular/regular.go @@ -52,11 +52,11 @@ func initABI() (abi abi.ABI, gasRequiredByMethod map[[4]byte]uint64) { copy(methodID[:], abi.Methods[methodName].ID[:4]) switch methodName { case RegularCallMethodName: - gasRequiredByMethod[methodID] = 10 + gasRequiredByMethod[methodID] = 200000 case Bech32ToHexAddrMethodName: - gasRequiredByMethod[methodID] = 0 + gasRequiredByMethod[methodID] = 10000 case Bech32ifyMethodName: - gasRequiredByMethod[methodID] = 0 + gasRequiredByMethod[methodID] = 10000 default: gasRequiredByMethod[methodID] = 0 } From 5c88cf196c9e0e993c2c1b05eae322d626dae2bb Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Fri, 16 Aug 2024 12:16:46 +0200 Subject: [PATCH 11/33] minor rewording --- e2e/e2etests/e2etests.go | 2 +- e2e/e2etests/test_precompiles_regular.go | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 2b44003a21..2991b28179 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -126,7 +126,7 @@ var AllE2ETests = []runner.E2ETest{ */ runner.NewE2ETest( TestZetaPrecompilesName, - "call Regular stateful precompiled contract", + "call stateful precompiled contract", []runner.ArgDefinition{}, TestPrecompilesRegular, ), diff --git a/e2e/e2etests/test_precompiles_regular.go b/e2e/e2etests/test_precompiles_regular.go index 1d7b2db955..44bd1ea72c 100644 --- a/e2e/e2etests/test_precompiles_regular.go +++ b/e2e/e2etests/test_precompiles_regular.go @@ -5,8 +5,6 @@ import ( "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" - - //regularcaller "github.com/zeta-chain/zetacore/precompiles/regular/testutil" "github.com/zeta-chain/zetacore/precompiles/regular" ) @@ -14,13 +12,18 @@ func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { require.Len(r, args, 0, "No arguments expected") caller, err := regular.NewRegularCaller(regular.ContractAddress, r.ZEVMClient) - require.NoError(r, err, "Failed to create RegularCaller") + require.NoError(r, err, "Failed to create precompiled contract caller") res, err := caller.Bech32ify(nil, "zeta", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) require.NoError(r, err, "Error calling Bech32ify") - require.Equal(r, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", res, "Failed to validate Bech32ify function") + require.Equal(r, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", res, "Failed to validate Bech32ify result") addr, err := caller.Bech32ToHexAddr(nil, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u") require.NoError(r, err, "Error calling Bech32ToHexAddr") - require.Equal(r, "0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE", addr.String(), "Failed to validate Bech32ToHexAddr function") + require.Equal( + r, + "0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE", + addr.String(), + "Failed to validate Bech32ToHexAddr result", + ) } From f32ff3294f6dbef1e59a3b86dfe552ce243ce45e Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Fri, 16 Aug 2024 13:31:07 +0200 Subject: [PATCH 12/33] use idiomatic errors --- precompiles/regular/regular.go | 24 +++++++++++++++----- precompiles/types/errors.go | 40 +++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/precompiles/regular/regular.go b/precompiles/regular/regular.go index 8fea3bdcaf..2c3478d6dc 100644 --- a/precompiles/regular/regular.go +++ b/precompiles/regular/regular.go @@ -112,7 +112,10 @@ func (rc *Contract) RequiredGas(input []byte) uint64 { func (rc *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 1 { - return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 1, len(args)) + return nil, &ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 1, + } } address, ok := args[0].(string) @@ -136,9 +139,13 @@ func (rc *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]b return method.Outputs.Pack(common.BytesToAddress(addressBz)) } + func (rc *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 2 { - return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 2, len(args)) + return nil, &ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 2, + } } cfg := sdk.GetConfig() @@ -181,15 +188,22 @@ func (rc *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, e func (rc *Contract) RegularCall(ctx sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 2 { - return nil, fmt.Errorf(ptypes.ErrInvalidNumberOfArgs, 2, len(args)) + return nil, &(ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 2, + }) } callingMethod, ok := args[0].(string) if !ok { - return nil, fmt.Errorf(ptypes.ErrInvalidMethod, args[0]) + return nil, &ptypes.ErrInvalidMethod{ + Method: callingMethod, + } } callingContract, ok := args[1].(common.Address) if !ok { - return nil, fmt.Errorf(ptypes.ErrInvalidAddr, args[1]) + return nil, ptypes.ErrInvalidAddr{ + Got: callingContract.String(), + } } res, err := rc.FungibleKeeper.CallEVM( diff --git a/precompiles/types/errors.go b/precompiles/types/errors.go index b7619f81a8..d8dc6a5dd8 100644 --- a/precompiles/types/errors.go +++ b/precompiles/types/errors.go @@ -1,17 +1,27 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - package types -const ( - // ErrDifferentOrigin is raised when an approval is set but the origin address is not the same as the spender. - ErrDifferentOrigin = "tx origin address %s does not match the delegator address %s" - // ErrInvalidAddr is raised when the origin address is invalid - ErrInvalidAddr = "invalid addr: %s" - // ErrInvalidDelegator is raised when the delegator address is not valid. - ErrInvalidDelegator = "invalid delegator address: %s" - // ErrInvalidNumberOfArgs is raised when the number of arguments is not what is expected. - ErrInvalidNumberOfArgs = "invalid number of arguments; expected %d; got: %d" - // ErrInvalidMethod is raised when the method is invalid. - ErrInvalidMethod = "unknown method: %s" -) +import "fmt" + +type ErrInvalidAddr struct { + Got string +} + +func (e ErrInvalidAddr) Error() string { + return fmt.Sprintf("invalid address %s", e.Got) +} + +type ErrInvalidNumberOfArgs struct { + Got, Expect int +} + +func (e ErrInvalidNumberOfArgs) Error() string { + return fmt.Sprintf("invalid number of arguments; expected %d; got: %d", e.Expect, e.Got) +} + +type ErrInvalidMethod struct { + Method string +} + +func (e ErrInvalidMethod) Error() string { + return fmt.Sprintf("unknown method: %ss", e.Method) +} From ddee0c5010dc159ef9f3c5cb41ea8ceecc734905 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Mon, 19 Aug 2024 15:02:29 +0200 Subject: [PATCH 13/33] remove unused files --- precompiles/testutil/errors.go | 39 ----------- precompiles/testutil/events.go | 34 --------- precompiles/testutil/logs.go | 121 --------------------------------- precompiles/types/errors.go | 2 +- 4 files changed, 1 insertion(+), 195 deletions(-) delete mode 100644 precompiles/testutil/errors.go delete mode 100644 precompiles/testutil/events.go delete mode 100644 precompiles/testutil/logs.go diff --git a/precompiles/testutil/errors.go b/precompiles/testutil/errors.go deleted file mode 100644 index 030f32276e..0000000000 --- a/precompiles/testutil/errors.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package testutil - -import ( - "fmt" - "strings" - - abci "github.com/cometbft/cometbft/abci/types" - evmtypes "github.com/zeta-chain/ethermint/x/evm/types" -) - -// CheckVMError is a helper function used to check if the transaction is reverted with the expected error message -// in the VmError field of the MsgEthereumResponse struct. -func CheckVMError(res abci.ResponseDeliverTx, expErrMsg string, args ...interface{}) error { - if !res.IsOK() { - return fmt.Errorf("code 0 was expected on response but got code %d", res.Code) - } - ethRes, err := evmtypes.DecodeTxResponse(res.Data) - if err != nil { - return fmt.Errorf("error occurred while decoding the TxResponse. %s", err) - } - expMsg := fmt.Sprintf(expErrMsg, args...) - if !strings.Contains(ethRes.VmError, expMsg) { - return fmt.Errorf( - "unexpected VmError on response. expected error to contain: %s, received: %s", - expMsg, - ethRes.VmError, - ) - } - return nil -} - -// CheckEthereumTxFailed checks if there is a VM error in the transaction response and returns the reason. -func CheckEthereumTxFailed(ethRes *evmtypes.MsgEthereumTxResponse) (string, bool) { - reason := ethRes.VmError - return reason, reason != "" -} diff --git a/precompiles/testutil/events.go b/precompiles/testutil/events.go deleted file mode 100644 index 3689c55d0c..0000000000 --- a/precompiles/testutil/events.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package testutil - -import ( - "fmt" - "strings" - - //nolint:stylecheck,revive // it's common practice to use the global imports for Ginkgo and Gomega - "github.com/ethereum/go-ethereum/accounts/abi" -) - -// validateEvents checks if the provided event names are included as keys in the contract events. -func validateEvents(contractEvents map[string]abi.Event, events []string) ([]abi.Event, error) { - expEvents := make([]abi.Event, 0, len(events)) - for _, eventStr := range events { - event, found := contractEvents[eventStr] - if !found { - availableABIEvents := make([]string, 0, len(contractEvents)) - for event := range contractEvents { - availableABIEvents = append(availableABIEvents, event) - } - availableABIEventsStr := strings.Join(availableABIEvents, ", ") - return nil, fmt.Errorf( - "unknown event %q is not contained in given ABI events:\n%s", - eventStr, - availableABIEventsStr, - ) - } - expEvents = append(expEvents, event) - } - return expEvents, nil -} diff --git a/precompiles/testutil/logs.go b/precompiles/testutil/logs.go deleted file mode 100644 index fe16a64ed5..0000000000 --- a/precompiles/testutil/logs.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package testutil - -import ( - "fmt" - - abci "github.com/cometbft/cometbft/abci/types" - "github.com/ethereum/go-ethereum/accounts/abi" - evmtypes "github.com/zeta-chain/ethermint/x/evm/types" - "golang.org/x/exp/slices" -) - -// CheckLogs checks the logs for the given events and whether the transaction was successful or not. -func CheckLogs(logArgs LogCheckArgs) error { - if len(logArgs.ExpEvents) != 0 && len(logArgs.ABIEvents) == 0 { - return fmt.Errorf("no ABI events provided in log check arguments, but expected events are present") - } - - expABIEvents, err := validateEvents(logArgs.ABIEvents, logArgs.ExpEvents) - if err != nil { - return err - } - - ethRes, err := evmtypes.DecodeTxResponse(logArgs.Res.Data) - if err != nil { - return fmt.Errorf("error while decoding ethereum tx response: %v", err) - } - - reason, failed := CheckEthereumTxFailed(ethRes) - if failed != !logArgs.ExpPass { - return fmt.Errorf( - "expected vm error found to be %t; got: %t (reason: %s)\nGas usage: %d/%d (~%d %%)", - !logArgs.ExpPass, - failed, - reason, - logArgs.Res.GasUsed, - logArgs.Res.GasWanted, - int64(float64(logArgs.Res.GasUsed)/float64(logArgs.Res.GasWanted)*100), - ) - } - - if err := CheckVMError(logArgs.Res, logArgs.ErrContains); err != nil { - return err - } - - if len(ethRes.Logs) != len(logArgs.ExpEvents) { - return fmt.Errorf("expected %d events in Ethereum response; got: %d", len(logArgs.ExpEvents), len(ethRes.Logs)) - } - - // Check if expected events are present in Ethereum response - availableEventIDs := make([]string, 0, len(ethRes.Logs)) - for _, log := range ethRes.Logs { - availableEventIDs = append(availableEventIDs, log.Topics[0]) - } - - expEventIDs := make([]string, 0, len(expABIEvents)) - for _, event := range expABIEvents { - expEventIDs = append(expEventIDs, event.ID.String()) - } - - for _, eventID := range expEventIDs { - if !slices.Contains(availableEventIDs, eventID) { - return fmt.Errorf("expected event with ID %v not found in Ethereum response", eventID) - } - } - - return nil -} - -// LogCheckArgs is a struct that contains configuration for the log checking. -type LogCheckArgs struct { - // ABIEvents is a map of available abi.Event corresponding to the corresponding event names, - // which are available in the contract ABI. - ABIEvents map[string]abi.Event - // ErrContains is the error message that is expected to be contained in the transaction response. - ErrContains string - // ExpEvents are the events which are expected to be emitted. - ExpEvents []string - // ExpPass is whether the transaction is expected to pass or not. - ExpPass bool - // Res is the response of the transaction. - // - // NOTE: This does not have to be set when using contracts.CallContractAndCheckLogs. - Res abci.ResponseDeliverTx -} - -// WithABIEvents sets the ABIEvents field of LogCheckArgs. -func (l LogCheckArgs) WithABIEvents(abiEvents map[string]abi.Event) LogCheckArgs { - l.ABIEvents = abiEvents - return l -} - -// WithErrContains sets the ErrContains field of LogCheckArgs. -// If any printArgs are provided, they are used to format the error message. -func (l LogCheckArgs) WithErrContains(errContains string, printArgs ...interface{}) LogCheckArgs { - if len(printArgs) > 0 { - errContains = fmt.Sprintf(errContains, printArgs...) - } - l.ErrContains = errContains - return l -} - -// WithExpEvents sets the ExpEvents field of LogCheckArgs. -func (l LogCheckArgs) WithExpEvents(expEvents ...string) LogCheckArgs { - l.ExpEvents = expEvents - return l -} - -// WithExpPass sets the ExpPass field of LogCheckArgs. -func (l LogCheckArgs) WithExpPass(expPass bool) LogCheckArgs { - l.ExpPass = expPass - return l -} - -// WithRes sets the Res field of LogCheckArgs. -func (l LogCheckArgs) WithRes(res abci.ResponseDeliverTx) LogCheckArgs { - l.Res = res - return l -} diff --git a/precompiles/types/errors.go b/precompiles/types/errors.go index d8dc6a5dd8..7794d75775 100644 --- a/precompiles/types/errors.go +++ b/precompiles/types/errors.go @@ -23,5 +23,5 @@ type ErrInvalidMethod struct { } func (e ErrInvalidMethod) Error() string { - return fmt.Sprintf("unknown method: %ss", e.Method) + return fmt.Sprintf("invalid method: %s", e.Method) } From c1d41e211130e728b723866f5c21d8c4a1ba0bcc Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Mon, 19 Aug 2024 15:39:29 +0200 Subject: [PATCH 14/33] rename and generate bindings automatically --- e2e/e2etests/test_precompiles_regular.go | 4 +- precompiles/precompiles.go | 8 +- precompiles/prototype/IPrototype.abi | 69 +++++ precompiles/prototype/IPrototype.go | 264 ++++++++++++++++ precompiles/prototype/IPrototype.json | 71 +++++ .../IRegular.sol => prototype/IPrototype.sol} | 10 +- precompiles/prototype/bindings.go | 7 + .../regular.go => prototype/prototype.go} | 2 +- precompiles/regular/IRegularABI.go | 264 ---------------- precompiles/regular/IRegularABI.json | 37 --- .../regular/testutil/RegularCaller.abi | 52 ---- .../regular/testutil/RegularCaller.bin | 1 - precompiles/regular/testutil/RegularCaller.go | 286 ------------------ .../regular/testutil/RegularCaller.json | 55 ---- .../regular/testutil/RegularCaller.sol | 50 --- 15 files changed, 424 insertions(+), 756 deletions(-) create mode 100644 precompiles/prototype/IPrototype.abi create mode 100644 precompiles/prototype/IPrototype.go create mode 100644 precompiles/prototype/IPrototype.json rename precompiles/{regular/IRegular.sol => prototype/IPrototype.sol} (81%) create mode 100644 precompiles/prototype/bindings.go rename precompiles/{regular/regular.go => prototype/prototype.go} (99%) delete mode 100644 precompiles/regular/IRegularABI.go delete mode 100644 precompiles/regular/IRegularABI.json delete mode 100644 precompiles/regular/testutil/RegularCaller.abi delete mode 100644 precompiles/regular/testutil/RegularCaller.bin delete mode 100644 precompiles/regular/testutil/RegularCaller.go delete mode 100644 precompiles/regular/testutil/RegularCaller.json delete mode 100644 precompiles/regular/testutil/RegularCaller.sol diff --git a/e2e/e2etests/test_precompiles_regular.go b/e2e/e2etests/test_precompiles_regular.go index 44bd1ea72c..01c863b230 100644 --- a/e2e/e2etests/test_precompiles_regular.go +++ b/e2e/e2etests/test_precompiles_regular.go @@ -5,13 +5,13 @@ import ( "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" - "github.com/zeta-chain/zetacore/precompiles/regular" + "github.com/zeta-chain/zetacore/precompiles/prototype" ) func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { require.Len(r, args, 0, "No arguments expected") - caller, err := regular.NewRegularCaller(regular.ContractAddress, r.ZEVMClient) + caller, err := prototype.NewIPrototypeCaller(prototype.ContractAddress, r.ZEVMClient) require.NoError(r, err, "Failed to create precompiled contract caller") res, err := caller.Bech32ify(nil, "zeta", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go index d7ab83997e..fbd2a763a5 100644 --- a/precompiles/precompiles.go +++ b/precompiles/precompiles.go @@ -9,12 +9,12 @@ import ( ethparams "github.com/ethereum/go-ethereum/params" evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" - "github.com/zeta-chain/zetacore/precompiles/regular" + "github.com/zeta-chain/zetacore/precompiles/prototype" "github.com/zeta-chain/zetacore/x/fungible/keeper" ) var EnabledStatefulContracts = map[common.Address]bool{ - regular.ContractAddress: true, + prototype.ContractAddress: true, } // StatefulContracts returns all the registered precompiled contracts. @@ -27,9 +27,9 @@ func StatefulContracts( precompiledContracts = make([]evmkeeper.CustomContractFn, 0) // Define the regular contract function. - if EnabledStatefulContracts[regular.ContractAddress] { + if EnabledStatefulContracts[prototype.ContractAddress] { regularContract := func(_ sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { - return regular.NewRegularContract(fungibleKeeper, cdc, gasConfig) + return prototype.NewRegularContract(fungibleKeeper, cdc, gasConfig) } // Append the regular contract to the precompiledContracts slice. diff --git a/precompiles/prototype/IPrototype.abi b/precompiles/prototype/IPrototype.abi new file mode 100644 index 0000000000..cdfab36d72 --- /dev/null +++ b/precompiles/prototype/IPrototype.abi @@ -0,0 +1,69 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "bech32", + "type": "string" + } + ], + "name": "bech32ToHexAddr", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "prefix", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "bech32ify", + "outputs": [ + { + "internalType": "string", + "name": "bech32", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "method", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "regularCall", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/precompiles/prototype/IPrototype.go b/precompiles/prototype/IPrototype.go new file mode 100644 index 0000000000..4e447224ce --- /dev/null +++ b/precompiles/prototype/IPrototype.go @@ -0,0 +1,264 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package prototype + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// IPrototypeMetaData contains all meta data concerning the IPrototype contract. +var IPrototypeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"name\":\"bech32ToHexAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"prefix\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"bech32ify\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"regularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// IPrototypeABI is the input ABI used to generate the binding from. +// Deprecated: Use IPrototypeMetaData.ABI instead. +var IPrototypeABI = IPrototypeMetaData.ABI + +// IPrototype is an auto generated Go binding around an Ethereum contract. +type IPrototype struct { + IPrototypeCaller // Read-only binding to the contract + IPrototypeTransactor // Write-only binding to the contract + IPrototypeFilterer // Log filterer for contract events +} + +// IPrototypeCaller is an auto generated read-only Go binding around an Ethereum contract. +type IPrototypeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPrototypeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type IPrototypeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPrototypeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IPrototypeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPrototypeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IPrototypeSession struct { + Contract *IPrototype // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IPrototypeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IPrototypeCallerSession struct { + Contract *IPrototypeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IPrototypeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IPrototypeTransactorSession struct { + Contract *IPrototypeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IPrototypeRaw is an auto generated low-level Go binding around an Ethereum contract. +type IPrototypeRaw struct { + Contract *IPrototype // Generic contract binding to access the raw methods on +} + +// IPrototypeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IPrototypeCallerRaw struct { + Contract *IPrototypeCaller // Generic read-only contract binding to access the raw methods on +} + +// IPrototypeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IPrototypeTransactorRaw struct { + Contract *IPrototypeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewIPrototype creates a new instance of IPrototype, bound to a specific deployed contract. +func NewIPrototype(address common.Address, backend bind.ContractBackend) (*IPrototype, error) { + contract, err := bindIPrototype(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IPrototype{IPrototypeCaller: IPrototypeCaller{contract: contract}, IPrototypeTransactor: IPrototypeTransactor{contract: contract}, IPrototypeFilterer: IPrototypeFilterer{contract: contract}}, nil +} + +// NewIPrototypeCaller creates a new read-only instance of IPrototype, bound to a specific deployed contract. +func NewIPrototypeCaller(address common.Address, caller bind.ContractCaller) (*IPrototypeCaller, error) { + contract, err := bindIPrototype(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IPrototypeCaller{contract: contract}, nil +} + +// NewIPrototypeTransactor creates a new write-only instance of IPrototype, bound to a specific deployed contract. +func NewIPrototypeTransactor(address common.Address, transactor bind.ContractTransactor) (*IPrototypeTransactor, error) { + contract, err := bindIPrototype(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IPrototypeTransactor{contract: contract}, nil +} + +// NewIPrototypeFilterer creates a new log filterer instance of IPrototype, bound to a specific deployed contract. +func NewIPrototypeFilterer(address common.Address, filterer bind.ContractFilterer) (*IPrototypeFilterer, error) { + contract, err := bindIPrototype(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IPrototypeFilterer{contract: contract}, nil +} + +// bindIPrototype binds a generic wrapper to an already deployed contract. +func bindIPrototype(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IPrototypeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IPrototype *IPrototypeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IPrototype.Contract.IPrototypeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IPrototype *IPrototypeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IPrototype.Contract.IPrototypeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IPrototype *IPrototypeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IPrototype.Contract.IPrototypeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IPrototype *IPrototypeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IPrototype.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IPrototype *IPrototypeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IPrototype.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IPrototype *IPrototypeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IPrototype.Contract.contract.Transact(opts, method, params...) +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_IPrototype *IPrototypeCaller) Bech32ToHexAddr(opts *bind.CallOpts, bech32 string) (common.Address, error) { + var out []interface{} + err := _IPrototype.contract.Call(opts, &out, "bech32ToHexAddr", bech32) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_IPrototype *IPrototypeSession) Bech32ToHexAddr(bech32 string) (common.Address, error) { + return _IPrototype.Contract.Bech32ToHexAddr(&_IPrototype.CallOpts, bech32) +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_IPrototype *IPrototypeCallerSession) Bech32ToHexAddr(bech32 string) (common.Address, error) { + return _IPrototype.Contract.Bech32ToHexAddr(&_IPrototype.CallOpts, bech32) +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_IPrototype *IPrototypeCaller) Bech32ify(opts *bind.CallOpts, prefix string, addr common.Address) (string, error) { + var out []interface{} + err := _IPrototype.contract.Call(opts, &out, "bech32ify", prefix, addr) + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_IPrototype *IPrototypeSession) Bech32ify(prefix string, addr common.Address) (string, error) { + return _IPrototype.Contract.Bech32ify(&_IPrototype.CallOpts, prefix, addr) +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_IPrototype *IPrototypeCallerSession) Bech32ify(prefix string, addr common.Address) (string, error) { + return _IPrototype.Contract.Bech32ify(&_IPrototype.CallOpts, prefix, addr) +} + +// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// +// Solidity: function regularCall(string method, address addr) returns(uint256 result) +func (_IPrototype *IPrototypeTransactor) RegularCall(opts *bind.TransactOpts, method string, addr common.Address) (*types.Transaction, error) { + return _IPrototype.contract.Transact(opts, "regularCall", method, addr) +} + +// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// +// Solidity: function regularCall(string method, address addr) returns(uint256 result) +func (_IPrototype *IPrototypeSession) RegularCall(method string, addr common.Address) (*types.Transaction, error) { + return _IPrototype.Contract.RegularCall(&_IPrototype.TransactOpts, method, addr) +} + +// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// +// Solidity: function regularCall(string method, address addr) returns(uint256 result) +func (_IPrototype *IPrototypeTransactorSession) RegularCall(method string, addr common.Address) (*types.Transaction, error) { + return _IPrototype.Contract.RegularCall(&_IPrototype.TransactOpts, method, addr) +} diff --git a/precompiles/prototype/IPrototype.json b/precompiles/prototype/IPrototype.json new file mode 100644 index 0000000000..95c5eb2105 --- /dev/null +++ b/precompiles/prototype/IPrototype.json @@ -0,0 +1,71 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "bech32", + "type": "string" + } + ], + "name": "bech32ToHexAddr", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "prefix", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "bech32ify", + "outputs": [ + { + "internalType": "string", + "name": "bech32", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "method", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "regularCall", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/precompiles/regular/IRegular.sol b/precompiles/prototype/IPrototype.sol similarity index 81% rename from precompiles/regular/IRegular.sol rename to precompiles/prototype/IPrototype.sol index 66296cb0a4..0695ca4017 100644 --- a/precompiles/regular/IRegular.sol +++ b/precompiles/prototype/IPrototype.sol @@ -1,13 +1,15 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.7; +pragma solidity ^0.8.26; /// @dev The IRegular contract's address. -address constant IREGULAR_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000065; // 101 +address constant IPROTOTYPE_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000065; // 101 /// @dev The IRegular contract's instance. -IRegular constant IREGULAR_CONTRACT = IRegular(IREGULAR_PRECOMPILE_ADDRESS); +IPrototype constant IREGULAR_CONTRACT = IPrototype( + IPROTOTYPE_PRECOMPILE_ADDRESS +); -interface IRegular { +interface IPrototype { /// @dev converting a bech32 address to hexadecimal address. /// @param bech32 The bech32 address. /// @return addr The hexadecimal address. diff --git a/precompiles/prototype/bindings.go b/precompiles/prototype/bindings.go new file mode 100644 index 0000000000..e4a31a5e56 --- /dev/null +++ b/precompiles/prototype/bindings.go @@ -0,0 +1,7 @@ +//go:generate sh -c "solc IPrototype.sol --combined-json abi | jq '.contracts.\"IPrototype.sol:IPrototype\"' > IPrototype.json" +//go:generate sh -c "cat IPrototype.json | jq .abi > IPrototype.abi" +//go:generate sh -c "abigen --abi IPrototype.abi --pkg prototype --type IPrototype --out IPrototype.go" + +package prototype + +var _ Contract diff --git a/precompiles/regular/regular.go b/precompiles/prototype/prototype.go similarity index 99% rename from precompiles/regular/regular.go rename to precompiles/prototype/prototype.go index 2c3478d6dc..a3be4e1c71 100644 --- a/precompiles/regular/regular.go +++ b/precompiles/prototype/prototype.go @@ -1,4 +1,4 @@ -package regular +package prototype import ( "errors" diff --git a/precompiles/regular/IRegularABI.go b/precompiles/regular/IRegularABI.go deleted file mode 100644 index 582d9f6b83..0000000000 --- a/precompiles/regular/IRegularABI.go +++ /dev/null @@ -1,264 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package regular - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// RegularMetaData contains all meta data concerning the Regular contract. -var RegularMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"name\":\"bech32ToHexAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"prefix\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"bech32ify\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"regularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", -} - -// RegularABI is the input ABI used to generate the binding from. -// Deprecated: Use RegularMetaData.ABI instead. -var RegularABI = RegularMetaData.ABI - -// Regular is an auto generated Go binding around an Ethereum contract. -type Regular struct { - RegularCaller // Read-only binding to the contract - RegularTransactor // Write-only binding to the contract - RegularFilterer // Log filterer for contract events -} - -// RegularCaller is an auto generated read-only Go binding around an Ethereum contract. -type RegularCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularTransactor is an auto generated write-only Go binding around an Ethereum contract. -type RegularTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type RegularFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type RegularSession struct { - Contract *Regular // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RegularCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type RegularCallerSession struct { - Contract *RegularCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// RegularTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type RegularTransactorSession struct { - Contract *RegularTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RegularRaw is an auto generated low-level Go binding around an Ethereum contract. -type RegularRaw struct { - Contract *Regular // Generic contract binding to access the raw methods on -} - -// RegularCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type RegularCallerRaw struct { - Contract *RegularCaller // Generic read-only contract binding to access the raw methods on -} - -// RegularTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type RegularTransactorRaw struct { - Contract *RegularTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewRegular creates a new instance of Regular, bound to a specific deployed contract. -func NewRegular(address common.Address, backend bind.ContractBackend) (*Regular, error) { - contract, err := bindRegular(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Regular{RegularCaller: RegularCaller{contract: contract}, RegularTransactor: RegularTransactor{contract: contract}, RegularFilterer: RegularFilterer{contract: contract}}, nil -} - -// NewRegularCaller creates a new read-only instance of Regular, bound to a specific deployed contract. -func NewRegularCaller(address common.Address, caller bind.ContractCaller) (*RegularCaller, error) { - contract, err := bindRegular(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &RegularCaller{contract: contract}, nil -} - -// NewRegularTransactor creates a new write-only instance of Regular, bound to a specific deployed contract. -func NewRegularTransactor(address common.Address, transactor bind.ContractTransactor) (*RegularTransactor, error) { - contract, err := bindRegular(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &RegularTransactor{contract: contract}, nil -} - -// NewRegularFilterer creates a new log filterer instance of Regular, bound to a specific deployed contract. -func NewRegularFilterer(address common.Address, filterer bind.ContractFilterer) (*RegularFilterer, error) { - contract, err := bindRegular(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &RegularFilterer{contract: contract}, nil -} - -// bindRegular binds a generic wrapper to an already deployed contract. -func bindRegular(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := RegularMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Regular *RegularRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Regular.Contract.RegularCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Regular *RegularRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Regular.Contract.RegularTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Regular *RegularRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Regular.Contract.RegularTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Regular *RegularCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Regular.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Regular *RegularTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Regular.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Regular *RegularTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Regular.Contract.contract.Transact(opts, method, params...) -} - -// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. -// -// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) -func (_Regular *RegularCaller) Bech32ToHexAddr(opts *bind.CallOpts, bech32 string) (common.Address, error) { - var out []interface{} - err := _Regular.contract.Call(opts, &out, "bech32ToHexAddr", bech32) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. -// -// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) -func (_Regular *RegularSession) Bech32ToHexAddr(bech32 string) (common.Address, error) { - return _Regular.Contract.Bech32ToHexAddr(&_Regular.CallOpts, bech32) -} - -// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. -// -// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) -func (_Regular *RegularCallerSession) Bech32ToHexAddr(bech32 string) (common.Address, error) { - return _Regular.Contract.Bech32ToHexAddr(&_Regular.CallOpts, bech32) -} - -// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. -// -// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) -func (_Regular *RegularCaller) Bech32ify(opts *bind.CallOpts, prefix string, addr common.Address) (string, error) { - var out []interface{} - err := _Regular.contract.Call(opts, &out, "bech32ify", prefix, addr) - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. -// -// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) -func (_Regular *RegularSession) Bech32ify(prefix string, addr common.Address) (string, error) { - return _Regular.Contract.Bech32ify(&_Regular.CallOpts, prefix, addr) -} - -// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. -// -// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) -func (_Regular *RegularCallerSession) Bech32ify(prefix string, addr common.Address) (string, error) { - return _Regular.Contract.Bech32ify(&_Regular.CallOpts, prefix, addr) -} - -// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. -// -// Solidity: function regularCall(string method, address addr) returns(uint256 result) -func (_Regular *RegularTransactor) RegularCall(opts *bind.TransactOpts, method string, addr common.Address) (*types.Transaction, error) { - return _Regular.contract.Transact(opts, "regularCall", method, addr) -} - -// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. -// -// Solidity: function regularCall(string method, address addr) returns(uint256 result) -func (_Regular *RegularSession) RegularCall(method string, addr common.Address) (*types.Transaction, error) { - return _Regular.Contract.RegularCall(&_Regular.TransactOpts, method, addr) -} - -// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. -// -// Solidity: function regularCall(string method, address addr) returns(uint256 result) -func (_Regular *RegularTransactorSession) RegularCall(method string, addr common.Address) (*types.Transaction, error) { - return _Regular.Contract.RegularCall(&_Regular.TransactOpts, method, addr) -} diff --git a/precompiles/regular/IRegularABI.json b/precompiles/regular/IRegularABI.json deleted file mode 100644 index 3804046ec6..0000000000 --- a/precompiles/regular/IRegularABI.json +++ /dev/null @@ -1,37 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "string", "name": "bech32", "type": "string" } - ], - "name": "bech32ToHexAddr", - "outputs": [ - { "internalType": "address", "name": "addr", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "string", "name": "prefix", "type": "string" }, - { "internalType": "address", "name": "addr", "type": "address" } - ], - "name": "bech32ify", - "outputs": [ - { "internalType": "string", "name": "bech32", "type": "string" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "string", "name": "method", "type": "string" }, - { "internalType": "address", "name": "addr", "type": "address" } - ], - "name": "regularCall", - "outputs": [ - { "internalType": "uint256", "name": "result", "type": "uint256" } - ], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/precompiles/regular/testutil/RegularCaller.abi b/precompiles/regular/testutil/RegularCaller.abi deleted file mode 100644 index 8f4eee8709..0000000000 --- a/precompiles/regular/testutil/RegularCaller.abi +++ /dev/null @@ -1,52 +0,0 @@ -[ - { - "inputs": [], - "name": "testBech32ToHexAddr", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "testBech32ify", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "method", - "type": "string" - }, - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "testRegularCall", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/precompiles/regular/testutil/RegularCaller.bin b/precompiles/regular/testutil/RegularCaller.bin deleted file mode 100644 index 5b7447ab81..0000000000 --- a/precompiles/regular/testutil/RegularCaller.bin +++ /dev/null @@ -1 +0,0 @@ -608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033 \ No newline at end of file diff --git a/precompiles/regular/testutil/RegularCaller.go b/precompiles/regular/testutil/RegularCaller.go deleted file mode 100644 index 71b45e868a..0000000000 --- a/precompiles/regular/testutil/RegularCaller.go +++ /dev/null @@ -1,286 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package testutils - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// RegularCallerMetaData contains all meta data concerning the RegularCaller contract. -var RegularCallerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"testBech32ToHexAddr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testBech32ify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"testRegularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033", -} - -// RegularCallerABI is the input ABI used to generate the binding from. -// Deprecated: Use RegularCallerMetaData.ABI instead. -var RegularCallerABI = RegularCallerMetaData.ABI - -// RegularCallerBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use RegularCallerMetaData.Bin instead. -var RegularCallerBin = RegularCallerMetaData.Bin - -// DeployRegularCaller deploys a new Ethereum contract, binding an instance of RegularCaller to it. -func DeployRegularCaller(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *RegularCaller, error) { - parsed, err := RegularCallerMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RegularCallerBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &RegularCaller{RegularCallerCaller: RegularCallerCaller{contract: contract}, RegularCallerTransactor: RegularCallerTransactor{contract: contract}, RegularCallerFilterer: RegularCallerFilterer{contract: contract}}, nil -} - -// RegularCaller is an auto generated Go binding around an Ethereum contract. -type RegularCaller struct { - RegularCallerCaller // Read-only binding to the contract - RegularCallerTransactor // Write-only binding to the contract - RegularCallerFilterer // Log filterer for contract events -} - -// RegularCallerCaller is an auto generated read-only Go binding around an Ethereum contract. -type RegularCallerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularCallerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type RegularCallerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularCallerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type RegularCallerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularCallerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type RegularCallerSession struct { - Contract *RegularCaller // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RegularCallerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type RegularCallerCallerSession struct { - Contract *RegularCallerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// RegularCallerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type RegularCallerTransactorSession struct { - Contract *RegularCallerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RegularCallerRaw is an auto generated low-level Go binding around an Ethereum contract. -type RegularCallerRaw struct { - Contract *RegularCaller // Generic contract binding to access the raw methods on -} - -// RegularCallerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type RegularCallerCallerRaw struct { - Contract *RegularCallerCaller // Generic read-only contract binding to access the raw methods on -} - -// RegularCallerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type RegularCallerTransactorRaw struct { - Contract *RegularCallerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewRegularCaller creates a new instance of RegularCaller, bound to a specific deployed contract. -func NewRegularCaller(address common.Address, backend bind.ContractBackend) (*RegularCaller, error) { - contract, err := bindRegularCaller(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &RegularCaller{RegularCallerCaller: RegularCallerCaller{contract: contract}, RegularCallerTransactor: RegularCallerTransactor{contract: contract}, RegularCallerFilterer: RegularCallerFilterer{contract: contract}}, nil -} - -// NewRegularCallerCaller creates a new read-only instance of RegularCaller, bound to a specific deployed contract. -func NewRegularCallerCaller(address common.Address, caller bind.ContractCaller) (*RegularCallerCaller, error) { - contract, err := bindRegularCaller(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &RegularCallerCaller{contract: contract}, nil -} - -// NewRegularCallerTransactor creates a new write-only instance of RegularCaller, bound to a specific deployed contract. -func NewRegularCallerTransactor(address common.Address, transactor bind.ContractTransactor) (*RegularCallerTransactor, error) { - contract, err := bindRegularCaller(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &RegularCallerTransactor{contract: contract}, nil -} - -// NewRegularCallerFilterer creates a new log filterer instance of RegularCaller, bound to a specific deployed contract. -func NewRegularCallerFilterer(address common.Address, filterer bind.ContractFilterer) (*RegularCallerFilterer, error) { - contract, err := bindRegularCaller(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &RegularCallerFilterer{contract: contract}, nil -} - -// bindRegularCaller binds a generic wrapper to an already deployed contract. -func bindRegularCaller(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := RegularCallerMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_RegularCaller *RegularCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _RegularCaller.Contract.RegularCallerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_RegularCaller *RegularCallerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _RegularCaller.Contract.RegularCallerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_RegularCaller *RegularCallerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _RegularCaller.Contract.RegularCallerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_RegularCaller *RegularCallerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _RegularCaller.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_RegularCaller *RegularCallerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _RegularCaller.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_RegularCaller *RegularCallerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _RegularCaller.Contract.contract.Transact(opts, method, params...) -} - -// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. -// -// Solidity: function testBech32ToHexAddr() view returns(bool) -func (_RegularCaller *RegularCallerCaller) TestBech32ToHexAddr(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _RegularCaller.contract.Call(opts, &out, "testBech32ToHexAddr") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. -// -// Solidity: function testBech32ToHexAddr() view returns(bool) -func (_RegularCaller *RegularCallerSession) TestBech32ToHexAddr() (bool, error) { - return _RegularCaller.Contract.TestBech32ToHexAddr(&_RegularCaller.CallOpts) -} - -// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. -// -// Solidity: function testBech32ToHexAddr() view returns(bool) -func (_RegularCaller *RegularCallerCallerSession) TestBech32ToHexAddr() (bool, error) { - return _RegularCaller.Contract.TestBech32ToHexAddr(&_RegularCaller.CallOpts) -} - -// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. -// -// Solidity: function testBech32ify() view returns(bool) -func (_RegularCaller *RegularCallerCaller) TestBech32ify(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _RegularCaller.contract.Call(opts, &out, "testBech32ify") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. -// -// Solidity: function testBech32ify() view returns(bool) -func (_RegularCaller *RegularCallerSession) TestBech32ify() (bool, error) { - return _RegularCaller.Contract.TestBech32ify(&_RegularCaller.CallOpts) -} - -// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. -// -// Solidity: function testBech32ify() view returns(bool) -func (_RegularCaller *RegularCallerCallerSession) TestBech32ify() (bool, error) { - return _RegularCaller.Contract.TestBech32ify(&_RegularCaller.CallOpts) -} - -// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. -// -// Solidity: function testRegularCall(string method, address addr) returns(uint256) -func (_RegularCaller *RegularCallerTransactor) TestRegularCall(opts *bind.TransactOpts, method string, addr common.Address) (*types.Transaction, error) { - return _RegularCaller.contract.Transact(opts, "testRegularCall", method, addr) -} - -// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. -// -// Solidity: function testRegularCall(string method, address addr) returns(uint256) -func (_RegularCaller *RegularCallerSession) TestRegularCall(method string, addr common.Address) (*types.Transaction, error) { - return _RegularCaller.Contract.TestRegularCall(&_RegularCaller.TransactOpts, method, addr) -} - -// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. -// -// Solidity: function testRegularCall(string method, address addr) returns(uint256) -func (_RegularCaller *RegularCallerTransactorSession) TestRegularCall(method string, addr common.Address) (*types.Transaction, error) { - return _RegularCaller.Contract.TestRegularCall(&_RegularCaller.TransactOpts, method, addr) -} diff --git a/precompiles/regular/testutil/RegularCaller.json b/precompiles/regular/testutil/RegularCaller.json deleted file mode 100644 index f8187a2651..0000000000 --- a/precompiles/regular/testutil/RegularCaller.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "name": "testBech32ToHexAddr", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "testBech32ify", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "method", - "type": "string" - }, - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "testRegularCall", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bin": "608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033" -} diff --git a/precompiles/regular/testutil/RegularCaller.sol b/precompiles/regular/testutil/RegularCaller.sol deleted file mode 100644 index 2e9aa13ee0..0000000000 --- a/precompiles/regular/testutil/RegularCaller.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.7; - -import "./IRegular.sol"; - -//IRegular constant IREGULAR_CONTRACT = IRegular(IREGULAR_PRECOMPILE_ADDRESS); -contract RegularCaller { - function testBech32ToHexAddr() public view returns (bool) { - // Test input and expected output - string - memory testBech32 = "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"; - address expectedHexAddr = 0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE; - - // Call the precompiled contract - address result = IREGULAR_CONTRACT.bech32ToHexAddr(testBech32); - - // Check if the result matches the expected output - return result == expectedHexAddr; - } - - function testBech32ify() public view returns (bool) { - // Test input and expected output - string memory testPrefix = "zeta"; - address testHexAddr = 0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE; - string - memory expectedBech32 = "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"; - - // Call the precompiled contract - string memory result = IREGULAR_CONTRACT.bech32ify( - testPrefix, - testHexAddr - ); - - // Check if the result matches the expected output - return - keccak256(abi.encodePacked(result)) == - keccak256(abi.encodePacked(expectedBech32)); - } - - function testRegularCall( - string memory method, - address addr - ) public returns (uint256) { - // Call the precompiled contract with the given method and address - uint256 result = IREGULAR_CONTRACT.regularCall(method, addr); - - // Return the result - return result; - } -} From 797dbc4363e66dfd8db3787c2272463d788c0923 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Mon, 19 Aug 2024 16:11:45 +0200 Subject: [PATCH 15/33] create a new e2e section for precompiles --- cmd/zetae2e/local/local.go | 5 +- cmd/zetae2e/local/precompiles.go | 56 +++++++++++++++++++ e2e/e2etests/e2etests.go | 21 ++++--- ...gular.go => test_precompiles_prototype.go} | 0 4 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 cmd/zetae2e/local/precompiles.go rename e2e/e2etests/{test_precompiles_regular.go => test_precompiles_prototype.go} (100%) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 2732d8daf6..ae7af95374 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -228,8 +228,10 @@ func localE2ETest(cmd *cobra.Command, _ []string) { erc20AdvancedTests := []string{ e2etests.TestERC20DepositRestrictedName, } + precompiledContractTests := []string{ + e2etests.TestZetaPrecompilesPrototypeName, + } zetaTests := []string{ - e2etests.TestZetaPrecompilesName, e2etests.TestZetaWithdrawName, e2etests.TestMessagePassingExternalChainsName, e2etests.TestMessagePassingRevertFailExternalChainsName, @@ -284,6 +286,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { ethereumTests = append(ethereumTests, ethereumAdvancedTests...) } + eg.Go(statefulPrecompilesTestRoutine(conf, deployerRunner, verbose, precompiledContractTests...)) eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) eg.Go(zetaTestRoutine(conf, deployerRunner, verbose, zetaTests...)) eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) diff --git a/cmd/zetae2e/local/precompiles.go b/cmd/zetae2e/local/precompiles.go new file mode 100644 index 0000000000..c76d587c3c --- /dev/null +++ b/cmd/zetae2e/local/precompiles.go @@ -0,0 +1,56 @@ +package local + +import ( + "fmt" + "time" + + "github.com/fatih/color" + + "github.com/zeta-chain/zetacore/e2e/config" + "github.com/zeta-chain/zetacore/e2e/e2etests" + "github.com/zeta-chain/zetacore/e2e/runner" +) + +// erc20TestRoutine runs erc20 related e2e tests +func statefulPrecompilesTestRoutine( + conf config.Config, + deployerRunner *runner.E2ERunner, + verbose bool, + testNames ...string, +) func() error { + return func() (err error) { + account := conf.AdditionalAccounts.UserERC20 + + // initialize runner for erc20 test + erc20Runner, err := initTestRunner( + "precompiles", + conf, + deployerRunner, + account, + runner.NewLogger(verbose, color.FgRed, "precompiles"), + ) + if err != nil { + return err + } + + erc20Runner.Logger.Print("🏃 starting stateful precompiled contracts tests") + startTime := time.Now() + + // run erc20 test + testsToRun, err := erc20Runner.GetE2ETestsToRunByName( + e2etests.AllE2ETests, + testNames..., + ) + if err != nil { + return fmt.Errorf("precompiled contracts tests failed: %v", err) + } + + if err := erc20Runner.RunE2ETests(testsToRun); err != nil { + return fmt.Errorf("precompiled contracts tests failed: %v", err) + } + + erc20Runner.Logger.Print("🍾 precompiled contracts tests completed in %s", time.Since(startTime).String()) + + return err + } +} diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 2991b28179..6e14d13aa7 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -15,7 +15,6 @@ const ( TestZetaDepositRestrictedName = "zeta_deposit_restricted" TestZetaWithdrawName = "zeta_withdraw" TestZetaWithdrawBTCRevertName = "zeta_withdraw_btc_revert" // #nosec G101 - not a hardcoded password - TestZetaPrecompilesName = "zeta_precompiles" /* Message passing tests @@ -117,6 +116,11 @@ const ( Not used to test functionalities but do various interactions with the netwoks */ TestDeploy = "deploy" + + /* + Stateful precompiled contracts tests + */ + TestZetaPrecompilesPrototypeName = "precompiles_contract_prototype" ) // AllE2ETests is an ordered list of all e2e tests @@ -124,12 +128,6 @@ var AllE2ETests = []runner.E2ETest{ /* ZETA tests */ - runner.NewE2ETest( - TestZetaPrecompilesName, - "call stateful precompiled contract", - []runner.ArgDefinition{}, - TestPrecompilesRegular, - ), runner.NewE2ETest( TestZetaDepositName, "deposit ZETA from Ethereum to ZEVM", @@ -596,4 +594,13 @@ var AllE2ETests = []runner.E2ETest{ []runner.ArgDefinition{}, TestMigrateTSS, ), + /* + Stateful precompiled contracts tests + */ + runner.NewE2ETest( + TestZetaPrecompilesPrototypeName, + "call stateful precompiled contract", + []runner.ArgDefinition{}, + TestPrecompilesRegular, + ), } diff --git a/e2e/e2etests/test_precompiles_regular.go b/e2e/e2etests/test_precompiles_prototype.go similarity index 100% rename from e2e/e2etests/test_precompiles_regular.go rename to e2e/e2etests/test_precompiles_prototype.go From bb69a613b00e33abfb14c0a7cd431e25e750ff61 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Mon, 19 Aug 2024 16:20:27 +0200 Subject: [PATCH 16/33] add bindings generator and makefile target --- Makefile | 7 ++++++- scripts/bindings-stateful-precompiles.sh | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100755 scripts/bindings-stateful-precompiles.sh diff --git a/Makefile b/Makefile index c8381d9538..6f0267ba32 100644 --- a/Makefile +++ b/Makefile @@ -202,8 +202,13 @@ mocks: @bash ./scripts/mocks-generate.sh .PHONY: mocks +precompiles: + @echo "--> Generating bindings for precompiled contracts" + @bash ./scripts/bindings-stateful-precompiles.sh +.PHONY: precompiles + # generate also includes Go code formatting -generate: proto-gen openapi specs typescript docs-zetacored mocks fmt +generate: proto-gen openapi specs typescript docs-zetacored mocks precompiles fmt .PHONY: generate diff --git a/scripts/bindings-stateful-precompiles.sh b/scripts/bindings-stateful-precompiles.sh new file mode 100755 index 0000000000..cd649ed24c --- /dev/null +++ b/scripts/bindings-stateful-precompiles.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# Generic function to generate bindings +function bindings() { + cd $1 + go generate > /dev/null 2>&1 + echo "Generated bindings for $1" +} + +# List of bindings to generate +bindings ./precompiles/prototype + From 53098a1e2d50c1c307021b91d00b7c7de9db92f7 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Mon, 19 Aug 2024 19:45:01 +0200 Subject: [PATCH 17/33] add GetGasStabilityPoolBalance as prototype contract function --- e2e/e2etests/test_precompiles_prototype.go | 12 +- precompiles/precompiles.go | 5 +- precompiles/prototype/IPrototype.abi | 15 +-- precompiles/prototype/IPrototype.go | 36 ++++-- precompiles/prototype/IPrototype.json | 15 +-- precompiles/prototype/IPrototype.sol | 12 +- precompiles/prototype/prototype.go | 139 ++++++++++----------- precompiles/types/errors.go | 17 +++ 8 files changed, 132 insertions(+), 119 deletions(-) diff --git a/e2e/e2etests/test_precompiles_prototype.go b/e2e/e2etests/test_precompiles_prototype.go index 01c863b230..c877bc0416 100644 --- a/e2e/e2etests/test_precompiles_prototype.go +++ b/e2e/e2etests/test_precompiles_prototype.go @@ -11,14 +11,14 @@ import ( func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { require.Len(r, args, 0, "No arguments expected") - caller, err := prototype.NewIPrototypeCaller(prototype.ContractAddress, r.ZEVMClient) - require.NoError(r, err, "Failed to create precompiled contract caller") + iPrototype, err := prototype.NewIPrototype(prototype.ContractAddress, r.ZEVMClient) + require.NoError(r, err, "Failed to create prototype contract caller") - res, err := caller.Bech32ify(nil, "zeta", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) + res, err := iPrototype.Bech32ify(nil, "zeta", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) require.NoError(r, err, "Error calling Bech32ify") require.Equal(r, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", res, "Failed to validate Bech32ify result") - addr, err := caller.Bech32ToHexAddr(nil, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u") + addr, err := iPrototype.Bech32ToHexAddr(nil, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u") require.NoError(r, err, "Error calling Bech32ToHexAddr") require.Equal( r, @@ -26,4 +26,8 @@ func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { addr.String(), "Failed to validate Bech32ToHexAddr result", ) + + balance, err := iPrototype.GetGasStabilityPoolBalance(nil, int64(101)) + require.NoError(r, err, err.Error()) + require.NotNil(r, balance, "GetGasStabilityPoolBalance returned balance is nil") } diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go index fbd2a763a5..c5883b1bbd 100644 --- a/precompiles/precompiles.go +++ b/precompiles/precompiles.go @@ -13,6 +13,9 @@ import ( "github.com/zeta-chain/zetacore/x/fungible/keeper" ) +// EnabledStatefulContracts contains the list of all enabled stateful precompiles. +// This is useful for listing and reading from other packages, such as BlockedAddrs() function. +// Setting to false a contract here will disable it, not being included in the blockchain. var EnabledStatefulContracts = map[common.Address]bool{ prototype.ContractAddress: true, } @@ -29,7 +32,7 @@ func StatefulContracts( // Define the regular contract function. if EnabledStatefulContracts[prototype.ContractAddress] { regularContract := func(_ sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { - return prototype.NewRegularContract(fungibleKeeper, cdc, gasConfig) + return prototype.NewIPrototypeContract(fungibleKeeper, cdc, gasConfig) } // Append the regular contract to the precompiledContracts slice. diff --git a/precompiles/prototype/IPrototype.abi b/precompiles/prototype/IPrototype.abi index cdfab36d72..d510aa3ec5 100644 --- a/precompiles/prototype/IPrototype.abi +++ b/precompiles/prototype/IPrototype.abi @@ -45,17 +45,12 @@ { "inputs": [ { - "internalType": "string", - "name": "method", - "type": "string" - }, - { - "internalType": "address", - "name": "addr", - "type": "address" + "internalType": "int64", + "name": "chainID", + "type": "int64" } ], - "name": "regularCall", + "name": "getGasStabilityPoolBalance", "outputs": [ { "internalType": "uint256", @@ -63,7 +58,7 @@ "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" } ] diff --git a/precompiles/prototype/IPrototype.go b/precompiles/prototype/IPrototype.go index 4e447224ce..ab97bd36fc 100644 --- a/precompiles/prototype/IPrototype.go +++ b/precompiles/prototype/IPrototype.go @@ -31,7 +31,7 @@ var ( // IPrototypeMetaData contains all meta data concerning the IPrototype contract. var IPrototypeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"name\":\"bech32ToHexAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"prefix\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"bech32ify\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"regularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"name\":\"bech32ToHexAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"prefix\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"bech32ify\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int64\",\"name\":\"chainID\",\"type\":\"int64\"}],\"name\":\"getGasStabilityPoolBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", } // IPrototypeABI is the input ABI used to generate the binding from. @@ -242,23 +242,33 @@ func (_IPrototype *IPrototypeCallerSession) Bech32ify(prefix string, addr common return _IPrototype.Contract.Bech32ify(&_IPrototype.CallOpts, prefix, addr) } -// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// GetGasStabilityPoolBalance is a free data retrieval call binding the contract method 0x3ee8d1a4. // -// Solidity: function regularCall(string method, address addr) returns(uint256 result) -func (_IPrototype *IPrototypeTransactor) RegularCall(opts *bind.TransactOpts, method string, addr common.Address) (*types.Transaction, error) { - return _IPrototype.contract.Transact(opts, "regularCall", method, addr) +// Solidity: function getGasStabilityPoolBalance(int64 chainID) view returns(uint256 result) +func (_IPrototype *IPrototypeCaller) GetGasStabilityPoolBalance(opts *bind.CallOpts, chainID int64) (*big.Int, error) { + var out []interface{} + err := _IPrototype.contract.Call(opts, &out, "getGasStabilityPoolBalance", chainID) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// GetGasStabilityPoolBalance is a free data retrieval call binding the contract method 0x3ee8d1a4. // -// Solidity: function regularCall(string method, address addr) returns(uint256 result) -func (_IPrototype *IPrototypeSession) RegularCall(method string, addr common.Address) (*types.Transaction, error) { - return _IPrototype.Contract.RegularCall(&_IPrototype.TransactOpts, method, addr) +// Solidity: function getGasStabilityPoolBalance(int64 chainID) view returns(uint256 result) +func (_IPrototype *IPrototypeSession) GetGasStabilityPoolBalance(chainID int64) (*big.Int, error) { + return _IPrototype.Contract.GetGasStabilityPoolBalance(&_IPrototype.CallOpts, chainID) } -// RegularCall is a paid mutator transaction binding the contract method 0x93e3663d. +// GetGasStabilityPoolBalance is a free data retrieval call binding the contract method 0x3ee8d1a4. // -// Solidity: function regularCall(string method, address addr) returns(uint256 result) -func (_IPrototype *IPrototypeTransactorSession) RegularCall(method string, addr common.Address) (*types.Transaction, error) { - return _IPrototype.Contract.RegularCall(&_IPrototype.TransactOpts, method, addr) +// Solidity: function getGasStabilityPoolBalance(int64 chainID) view returns(uint256 result) +func (_IPrototype *IPrototypeCallerSession) GetGasStabilityPoolBalance(chainID int64) (*big.Int, error) { + return _IPrototype.Contract.GetGasStabilityPoolBalance(&_IPrototype.CallOpts, chainID) } diff --git a/precompiles/prototype/IPrototype.json b/precompiles/prototype/IPrototype.json index 95c5eb2105..3b7c9ea8cb 100644 --- a/precompiles/prototype/IPrototype.json +++ b/precompiles/prototype/IPrototype.json @@ -46,17 +46,12 @@ { "inputs": [ { - "internalType": "string", - "name": "method", - "type": "string" - }, - { - "internalType": "address", - "name": "addr", - "type": "address" + "internalType": "int64", + "name": "chainID", + "type": "int64" } ], - "name": "regularCall", + "name": "getGasStabilityPoolBalance", "outputs": [ { "internalType": "uint256", @@ -64,7 +59,7 @@ "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" } ] diff --git a/precompiles/prototype/IPrototype.sol b/precompiles/prototype/IPrototype.sol index 0695ca4017..d65779cc5f 100644 --- a/precompiles/prototype/IPrototype.sol +++ b/precompiles/prototype/IPrototype.sol @@ -26,12 +26,10 @@ interface IPrototype { address addr ) external view returns (string memory bech32); - /// @dev Function to verify calling regular contact through precompiled contact - /// @param method to call, e.g. bar. - /// @param addr of deployed regular contract. + /// @dev returns the balance of the gas stability pool + /// @param chainID to query gas. /// @return result of the call. - function regularCall( - string memory method, - address addr - ) external returns (uint256 result); + function getGasStabilityPoolBalance( + int64 chainID + ) external view returns (uint256 result); } diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index a3be4e1c71..a3a8be41a9 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -1,9 +1,8 @@ package prototype import ( - "errors" + _ "embed" "fmt" - "math/big" "strings" "github.com/cosmos/cosmos-sdk/codec" @@ -15,53 +14,52 @@ import ( "github.com/ethereum/go-ethereum/core/vm" ptypes "github.com/zeta-chain/zetacore/precompiles/types" - "github.com/zeta-chain/zetacore/testutil/contracts" fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" - fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" ) const ( - RegularCallMethodName = "regularCall" - Bech32ToHexAddrMethodName = "bech32ToHexAddr" - Bech32ifyMethodName = "bech32ify" + Bech32ToHexAddrMethodName = "bech32ToHexAddr" + Bech32ifyMethodName = "bech32ify" + GetGasStabilityPoolBalanceName = "getGasStabilityPoolBalance" ) var ( ABI abi.ABI ContractAddress = common.HexToAddress("0x0000000000000000000000000000000000000065") GasRequiredByMethod = map[[4]byte]uint64{} - ExampleABI *abi.ABI + + //go:embed IPrototype.abi + prototypeABI string ) func init() { - ABI, GasRequiredByMethod = initABI() - ExampleABI, _ = contracts.ExampleMetaData.GetAbi() -} + if prototypeABI == "" { + panic("missing prototype ABI") + } -var RegularModuleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"name\":\"bech32ToHexAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"prefix\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"bech32ify\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"regularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", -} + var IPrototypeMetaData = &bind.MetaData{ + ABI: prototypeABI, + } -func initABI() (abi abi.ABI, gasRequiredByMethod map[[4]byte]uint64) { - gasRequiredByMethod = map[[4]byte]uint64{} - if err := abi.UnmarshalJSON([]byte(RegularModuleMetaData.ABI)); err != nil { + if err := ABI.UnmarshalJSON([]byte(IPrototypeMetaData.ABI)); err != nil { panic(err) } - for methodName := range abi.Methods { + + GasRequiredByMethod = map[[4]byte]uint64{} + for methodName := range ABI.Methods { var methodID [4]byte - copy(methodID[:], abi.Methods[methodName].ID[:4]) + copy(methodID[:], ABI.Methods[methodName].ID[:4]) switch methodName { - case RegularCallMethodName: - gasRequiredByMethod[methodID] = 200000 case Bech32ToHexAddrMethodName: - gasRequiredByMethod[methodID] = 10000 + GasRequiredByMethod[methodID] = 10000 case Bech32ifyMethodName: - gasRequiredByMethod[methodID] = 10000 + GasRequiredByMethod[methodID] = 10000 + case GetGasStabilityPoolBalanceName: + GasRequiredByMethod[methodID] = 10000 default: - gasRequiredByMethod[methodID] = 0 + GasRequiredByMethod[methodID] = 0 } } - return abi, gasRequiredByMethod } type Contract struct { @@ -72,8 +70,7 @@ type Contract struct { kvGasConfig storetypes.GasConfig } -// NewRegularContract creates the precompiled contract to manage native tokens -func NewRegularContract( +func NewIPrototypeContract( fungibleKeeper fungiblekeeper.Keeper, cdc codec.Codec, kvGasConfig storetypes.GasConfig, @@ -86,18 +83,21 @@ func NewRegularContract( } } -func (rc *Contract) Address() common.Address { +// Address() is required to implement the PrecompiledContract interface. +func (c *Contract) Address() common.Address { return ContractAddress } -func (rc *Contract) Abi() abi.ABI { +// Abi() is required to implement the PrecompiledContract interface. +func (c *Contract) Abi() abi.ABI { return ABI } -// RequiredGas calculates the contract gas use -func (rc *Contract) RequiredGas(input []byte) uint64 { +// RequiredGas is required to implement the PrecompiledContract interface. +// The gas has to be calculated deterministically based on the input. +func (c *Contract) RequiredGas(input []byte) uint64 { // base cost to prevent large input size - baseCost := uint64(len(input)) * rc.kvGasConfig.WriteCostPerByte + baseCost := uint64(len(input)) * c.kvGasConfig.WriteCostPerByte // get methodID (first 4 bytes) var methodID [4]byte @@ -110,7 +110,7 @@ func (rc *Contract) RequiredGas(input []byte) uint64 { return baseCost } -func (rc *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { +func (c *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 1 { return nil, &ptypes.ErrInvalidNumberOfArgs{ Got: len(args), @@ -140,7 +140,7 @@ func (rc *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]b return method.Outputs.Pack(common.BytesToAddress(addressBz)) } -func (rc *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, error) { +func (c *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 2 { return nil, &ptypes.ErrInvalidNumberOfArgs{ Got: len(args), @@ -186,77 +186,68 @@ func (rc *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, e return method.Outputs.Pack(bech32Str) } -func (rc *Contract) RegularCall(ctx sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) { - if len(args) != 2 { +func (c *Contract) GetGasStabilityPoolBalance( + ctx sdk.Context, + method *abi.Method, + args []interface{}, +) ([]byte, error) { + if len(args) != 1 { return nil, &(ptypes.ErrInvalidNumberOfArgs{ Got: len(args), - Expect: 2, + Expect: 1, }) } - callingMethod, ok := args[0].(string) - if !ok { - return nil, &ptypes.ErrInvalidMethod{ - Method: callingMethod, - } - } - callingContract, ok := args[1].(common.Address) + + // Unwrap arguments. The chainID is the first and unique argument. + chainID, ok := args[0].(int64) if !ok { - return nil, ptypes.ErrInvalidAddr{ - Got: callingContract.String(), + return nil, ptypes.ErrInvalidArgument{ + Got: chainID, } } - res, err := rc.FungibleKeeper.CallEVM( - ctx, - *ExampleABI, - fungibletypes.ModuleAddressEVM, - callingContract, - big.NewInt(0), - nil, - true, - false, - callingMethod, - ) + balance, err := c.FungibleKeeper.GetGasStabilityPoolBalance(ctx, chainID) if err != nil { return nil, err } - return method.Outputs.Pack( - ptypes.BytesToBigInt(res.Ret), - ) + return method.Outputs.Pack(balance) } -func (rc *Contract) Run(evm *vm.EVM, contract *vm.Contract, _ bool) ([]byte, error) { - // parse input - methodID := contract.Input[:4] - method, err := ABI.MethodById(methodID) +// Run is the entrypoint of the precompiled contract, it switches over the input method, +// and execute them accordingly. +func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, _ bool) ([]byte, error) { + method, err := ABI.MethodById(contract.Input[:4]) if err != nil { return nil, err } + args, err := method.Inputs.Unpack(contract.Input[4:]) if err != nil { - return nil, errors.New("fail to unpack input arguments") + return nil, err } stateDB := evm.StateDB.(ptypes.ExtStateDB) switch method.Name { - case RegularCallMethodName: + case GetGasStabilityPoolBalanceName: var res []byte - if execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { - res, err = rc.RegularCall(ctx, method, args) + execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { + res, err = c.GetGasStabilityPoolBalance(ctx, method, args) return err - }); execErr != nil { + }) + if execErr != nil { return nil, err - } else { - return res, nil } + return method.Outputs.Pack(res) case Bech32ToHexAddrMethodName: - return rc.Bech32ToHexAddr(method, args) + return c.Bech32ToHexAddr(method, args) case Bech32ifyMethodName: - return rc.Bech32ify(method, args) + return c.Bech32ify(method, args) default: - return nil, errors.New("unknown method") + return nil, ptypes.ErrInvalidMethod{ + Method: method.Name, + } } } diff --git a/precompiles/types/errors.go b/precompiles/types/errors.go index 7794d75775..0cc6928541 100644 --- a/precompiles/types/errors.go +++ b/precompiles/types/errors.go @@ -2,6 +2,9 @@ package types import "fmt" +/* +Address related errors +*/ type ErrInvalidAddr struct { Got string } @@ -10,6 +13,9 @@ func (e ErrInvalidAddr) Error() string { return fmt.Sprintf("invalid address %s", e.Got) } +/* +Argument related errors +*/ type ErrInvalidNumberOfArgs struct { Got, Expect int } @@ -18,6 +24,17 @@ func (e ErrInvalidNumberOfArgs) Error() string { return fmt.Sprintf("invalid number of arguments; expected %d; got: %d", e.Expect, e.Got) } +type ErrInvalidArgument struct { + Got any +} + +func (e ErrInvalidArgument) Error() string { + return fmt.Sprintf("invalid argument: %s", e.Got.(string)) +} + +/* +Method related errors +*/ type ErrInvalidMethod struct { Method string } From dbe971c2694cc2853e8d09d80b1c3b90dc0358b9 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 01:06:00 +0200 Subject: [PATCH 18/33] include getGasStabilityPoolBalance function --- app/app.go | 6 +----- e2e/e2etests/test_precompiles_prototype.go | 4 ++-- precompiles/precompiles.go | 8 ++++---- precompiles/prototype/prototype.go | 15 +++++++++++---- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/app.go b/app/app.go index 23c1727c71..71188d3eb7 100644 --- a/app/app.go +++ b/app/app.go @@ -567,11 +567,7 @@ func New( &app.FeeMarketKeeper, tracer, evmSs, - precompiles.StatefulContracts( - app.FungibleKeeper, - appCodec, - storetypes.TransientGasConfig(), - ), + precompiles.StatefulContracts(&app.FungibleKeeper, appCodec, storetypes.TransientGasConfig()), app.ConsensusParamsKeeper, aggregateAllKeys(keys, tKeys, memKeys), ) diff --git a/e2e/e2etests/test_precompiles_prototype.go b/e2e/e2etests/test_precompiles_prototype.go index c877bc0416..d881d434a7 100644 --- a/e2e/e2etests/test_precompiles_prototype.go +++ b/e2e/e2etests/test_precompiles_prototype.go @@ -27,7 +27,7 @@ func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { "Failed to validate Bech32ToHexAddr result", ) - balance, err := iPrototype.GetGasStabilityPoolBalance(nil, int64(101)) - require.NoError(r, err, err.Error()) + balance, err := iPrototype.GetGasStabilityPoolBalance(nil, int64(1337)) + require.NoError(r, err, "Error calling GetGasStabilityPoolBalance") require.NotNil(r, balance, "GetGasStabilityPoolBalance returned balance is nil") } diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go index c5883b1bbd..1e76a7c69e 100644 --- a/precompiles/precompiles.go +++ b/precompiles/precompiles.go @@ -22,7 +22,7 @@ var EnabledStatefulContracts = map[common.Address]bool{ // StatefulContracts returns all the registered precompiled contracts. func StatefulContracts( - fungibleKeeper keeper.Keeper, + fungibleKeeper *keeper.Keeper, cdc codec.Codec, gasConfig storetypes.GasConfig, ) (precompiledContracts []evmkeeper.CustomContractFn) { @@ -31,12 +31,12 @@ func StatefulContracts( // Define the regular contract function. if EnabledStatefulContracts[prototype.ContractAddress] { - regularContract := func(_ sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { - return prototype.NewIPrototypeContract(fungibleKeeper, cdc, gasConfig) + prototype := func(ctx sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { + return prototype.NewIPrototypeContract(ctx, fungibleKeeper, cdc, gasConfig) } // Append the regular contract to the precompiledContracts slice. - precompiledContracts = append(precompiledContracts, regularContract) + precompiledContracts = append(precompiledContracts, prototype) } return precompiledContracts diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index a3a8be41a9..ddfb8531f3 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -65,19 +65,22 @@ func init() { type Contract struct { ptypes.BaseContract + Ctx sdk.Context FungibleKeeper fungiblekeeper.Keeper cdc codec.Codec kvGasConfig storetypes.GasConfig } func NewIPrototypeContract( - fungibleKeeper fungiblekeeper.Keeper, + context sdk.Context, + fungibleKeeper *fungiblekeeper.Keeper, cdc codec.Codec, kvGasConfig storetypes.GasConfig, ) *Contract { return &Contract{ + Ctx: context, BaseContract: ptypes.NewBaseContract(ContractAddress), - FungibleKeeper: fungibleKeeper, + FungibleKeeper: *fungibleKeeper, cdc: cdc, kvGasConfig: kvGasConfig, } @@ -208,7 +211,11 @@ func (c *Contract) GetGasStabilityPoolBalance( balance, err := c.FungibleKeeper.GetGasStabilityPoolBalance(ctx, chainID) if err != nil { - return nil, err + return nil, fmt.Errorf("error calling fungible keeper: %s", err.Error()) + } + + if balance == nil { + return nil, fmt.Errorf("balance not found") } return method.Outputs.Pack(balance) @@ -239,7 +246,7 @@ func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, _ bool) ([]byte, erro if execErr != nil { return nil, err } - return method.Outputs.Pack(res) + return res, nil case Bech32ToHexAddrMethodName: return c.Bech32ToHexAddr(method, args) From 906c4385dc3889e23e314318e29432e95cce69cc Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 11:12:15 +0200 Subject: [PATCH 19/33] apply code review fixes --- app/app.go | 2 + changelog.md | 5 +- cmd/zetae2e/local/precompiles.go | 14 +++--- codecov.yml | 86 ++++++++++++++++---------------- e2e/config/config.go | 1 + e2e/e2etests/e2etests.go | 2 +- 6 files changed, 58 insertions(+), 52 deletions(-) diff --git a/app/app.go b/app/app.go index 71188d3eb7..32d85214eb 100644 --- a/app/app.go +++ b/app/app.go @@ -1056,6 +1056,8 @@ func (app *App) BlockedAddrs() map[string]bool { blockList[addr.String()] = v } + // Each enabled precompiled stateful contract should be added as a BlockedAddrs. + // That way it's marked as non payable by the bank keeper. for addr, enabled := range precompiles.EnabledStatefulContracts { if enabled { blockList[addr.String()] = enabled diff --git a/changelog.md b/changelog.md index 7ef55517f7..fcd82cffe7 100644 --- a/changelog.md +++ b/changelog.md @@ -18,6 +18,10 @@ * [2654](https://github.com/zeta-chain/node/pull/2654) - add validation for authorization list in when validating genesis state for authorization module +### Tests + +* [2703](https://github.com/zeta-chain/node/pull/2703) - add e2e tests for stateful precompiled contracts + ## v19.0.0 ### Breaking Changes @@ -115,7 +119,6 @@ * [2415](https://github.com/zeta-chain/node/pull/2415) - add e2e test for upgrade and test admin functionalities * [2440](https://github.com/zeta-chain/node/pull/2440) - Add e2e test for TSS migration * [2473](https://github.com/zeta-chain/node/pull/2473) - add e2e tests for most used admin transactions -* [2703](https://github.com/zeta-chain/node/pull/2703) - add e2e tests for stateful precompiled contracts ### Fixes diff --git a/cmd/zetae2e/local/precompiles.go b/cmd/zetae2e/local/precompiles.go index c76d587c3c..bf1fe25257 100644 --- a/cmd/zetae2e/local/precompiles.go +++ b/cmd/zetae2e/local/precompiles.go @@ -19,10 +19,9 @@ func statefulPrecompilesTestRoutine( testNames ...string, ) func() error { return func() (err error) { - account := conf.AdditionalAccounts.UserERC20 + account := conf.AdditionalAccounts.UserPrecompile - // initialize runner for erc20 test - erc20Runner, err := initTestRunner( + precompileRunner, err := initTestRunner( "precompiles", conf, deployerRunner, @@ -33,11 +32,10 @@ func statefulPrecompilesTestRoutine( return err } - erc20Runner.Logger.Print("🏃 starting stateful precompiled contracts tests") + precompileRunner.Logger.Print("🏃 starting stateful precompiled contracts tests") startTime := time.Now() - // run erc20 test - testsToRun, err := erc20Runner.GetE2ETestsToRunByName( + testsToRun, err := precompileRunner.GetE2ETestsToRunByName( e2etests.AllE2ETests, testNames..., ) @@ -45,11 +43,11 @@ func statefulPrecompilesTestRoutine( return fmt.Errorf("precompiled contracts tests failed: %v", err) } - if err := erc20Runner.RunE2ETests(testsToRun); err != nil { + if err := precompileRunner.RunE2ETests(testsToRun); err != nil { return fmt.Errorf("precompiled contracts tests failed: %v", err) } - erc20Runner.Logger.Print("🍾 precompiled contracts tests completed in %s", time.Since(startTime).String()) + precompileRunner.Logger.Print("🍾 precompiled contracts tests completed in %s", time.Since(startTime).String()) return err } diff --git a/codecov.yml b/codecov.yml index 45df0a7f87..fb59f7ad2a 100644 --- a/codecov.yml +++ b/codecov.yml @@ -22,57 +22,59 @@ coverage: - pkg comment: - layout: "reach, diff, files" + layout: 'reach, diff, files' behavior: default require_changes: true flags: zetacore: paths: - - "x/" + - 'x/' zetaclient: paths: - - "zetaclient/" + - 'zetaclient/' pkg: paths: - - "pkg/" + - 'pkg/' ignore: - - "x/**/client/**/*" - - "x/**/keeper/keeper.go" - - "x/**/keeper/msg_server.go" - - "x/**/keeper/grpc_query_params.go" - - "x/**/types/codec.go" - - "x/**/types/errors.go" - - "x/**/types/keys.go" - - "x/**/types/key_*.go" - - "x/**/types/types.go" - - "x/**/types/expected_keepers.go" - - "x/**/module.go" - - "x/**/events.go" - - "x/**/migrator.go" - - "x/**/module_simulation.go" - - "x/**/simulation/**/*" - - "**/*.proto" - - "**/*.md" - - "**/*.yml" - - "**/*.yaml" - - "**/*.pb.go" - - "**/*.pb.gw.go" - - "**/*_legacy.go" - - "**/*.json" - - "zetaclient/testdata/**/*" - - "zetaclient/testutils/**/*" - - ".github" - - "app" - - "cmd" - - "contrib" - - "docs" - - "e2e" - - "proto" - - "rpc" - - "scripts" - - "server" - - "testutil" - - "tool" - - "typescript/**/*" \ No newline at end of file + - 'x/**/client/**/*' + - 'x/**/keeper/keeper.go' + - 'x/**/keeper/msg_server.go' + - 'x/**/keeper/grpc_query_params.go' + - 'x/**/types/codec.go' + - 'x/**/types/errors.go' + - 'x/**/types/keys.go' + - 'x/**/types/key_*.go' + - 'x/**/types/types.go' + - 'x/**/types/expected_keepers.go' + - 'x/**/module.go' + - 'x/**/events.go' + - 'x/**/migrator.go' + - 'x/**/module_simulation.go' + - 'x/**/simulation/**/*' + - '**/*.proto' + - '**/*.md' + - '**/*.yml' + - '**/*.yaml' + - '**/*.pb.go' + - '**/*.pb.gw.go' + - '**/*_legacy.go' + - '**/*.json' + - 'zetaclient/testdata/**/*' + - 'zetaclient/testutils/**/*' + - '.github' + - 'app' + - 'cmd' + - 'contrib' + - 'docs' + - 'e2e' + - 'proto' + - 'rpc' + - 'scripts' + - 'server' + - 'testutil' + - 'tool' + - 'typescript/**/*' + - 'precompiles/**/bindings.go' + - 'precompiles/prototype/IPrototype.*' diff --git a/e2e/config/config.go b/e2e/config/config.go index 8e8006c042..ca1a372a02 100644 --- a/e2e/config/config.go +++ b/e2e/config/config.go @@ -68,6 +68,7 @@ type AdditionalAccounts struct { UserMisc Account `yaml:"user_misc"` UserAdmin Account `yaml:"user_admin"` UserMigration Account `yaml:"user_migration"` + UserPrecompile Account `yaml:"user_precompile"` } type PolicyAccounts struct { diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 6e14d13aa7..6a975bcc79 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -120,7 +120,7 @@ const ( /* Stateful precompiled contracts tests */ - TestZetaPrecompilesPrototypeName = "precompiles_contract_prototype" + TestZetaPrecompilesPrototypeName = "precompile_contracts_prototype" ) // AllE2ETests is an ordered list of all e2e tests From cefb8d28a134d3c9eeb939b21c9e6696aa1db19a Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 11:32:57 +0200 Subject: [PATCH 20/33] include tests for precompiles package --- precompiles/precompiles_test.go | 40 +++ .../prototype/testutil/RegularCaller.abi | 52 ++++ .../prototype/testutil/RegularCaller.bin | 1 + .../prototype/testutil/RegularCaller.go | 286 ++++++++++++++++++ .../prototype/testutil/RegularCaller.json | 55 ++++ .../prototype/testutil/RegularCaller.sol | 50 +++ 6 files changed, 484 insertions(+) create mode 100644 precompiles/precompiles_test.go create mode 100644 precompiles/prototype/testutil/RegularCaller.abi create mode 100644 precompiles/prototype/testutil/RegularCaller.bin create mode 100644 precompiles/prototype/testutil/RegularCaller.go create mode 100644 precompiles/prototype/testutil/RegularCaller.json create mode 100644 precompiles/prototype/testutil/RegularCaller.sol diff --git a/precompiles/precompiles_test.go b/precompiles/precompiles_test.go new file mode 100644 index 0000000000..a53988e3fc --- /dev/null +++ b/precompiles/precompiles_test.go @@ -0,0 +1,40 @@ +package precompiles_test + +import ( + "testing" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" + ethparams "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" + ethermint "github.com/zeta-chain/ethermint/types" + "github.com/zeta-chain/zetacore/precompiles" + "github.com/zeta-chain/zetacore/testutil/keeper" +) + +func Test_StatefulContracts(t *testing.T) { + k, ctx, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + + var expectedContracts int + for _, enabled := range precompiles.EnabledStatefulContracts { + if enabled { + expectedContracts++ + } + } + + // StatefulContracts() should return all the enabled contracts. + contracts := precompiles.StatefulContracts(k, appCodec, gasConfig) + require.NotNil(t, contracts, "StatefulContracts() should not return a nil slice") + require.Len(t, contracts, expectedContracts, "StatefulContracts() should return all the enabled contracts") + + // Extract the contract function from the first contract. + customContractFn := contracts[0] + contract := customContractFn(ctx, ethparams.Rules{}) + + // Check the contract function returns a valid address. + contractAddr := contract.Address() + require.NotNil(t, contractAddr, "The called contract should have a valid address") +} \ No newline at end of file diff --git a/precompiles/prototype/testutil/RegularCaller.abi b/precompiles/prototype/testutil/RegularCaller.abi new file mode 100644 index 0000000000..8f4eee8709 --- /dev/null +++ b/precompiles/prototype/testutil/RegularCaller.abi @@ -0,0 +1,52 @@ +[ + { + "inputs": [], + "name": "testBech32ToHexAddr", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "testBech32ify", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "method", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "testRegularCall", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/precompiles/prototype/testutil/RegularCaller.bin b/precompiles/prototype/testutil/RegularCaller.bin new file mode 100644 index 0000000000..5b7447ab81 --- /dev/null +++ b/precompiles/prototype/testutil/RegularCaller.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033 \ No newline at end of file diff --git a/precompiles/prototype/testutil/RegularCaller.go b/precompiles/prototype/testutil/RegularCaller.go new file mode 100644 index 0000000000..71b45e868a --- /dev/null +++ b/precompiles/prototype/testutil/RegularCaller.go @@ -0,0 +1,286 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package testutils + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// RegularCallerMetaData contains all meta data concerning the RegularCaller contract. +var RegularCallerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"testBech32ToHexAddr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testBech32ify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"testRegularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033", +} + +// RegularCallerABI is the input ABI used to generate the binding from. +// Deprecated: Use RegularCallerMetaData.ABI instead. +var RegularCallerABI = RegularCallerMetaData.ABI + +// RegularCallerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use RegularCallerMetaData.Bin instead. +var RegularCallerBin = RegularCallerMetaData.Bin + +// DeployRegularCaller deploys a new Ethereum contract, binding an instance of RegularCaller to it. +func DeployRegularCaller(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *RegularCaller, error) { + parsed, err := RegularCallerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RegularCallerBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &RegularCaller{RegularCallerCaller: RegularCallerCaller{contract: contract}, RegularCallerTransactor: RegularCallerTransactor{contract: contract}, RegularCallerFilterer: RegularCallerFilterer{contract: contract}}, nil +} + +// RegularCaller is an auto generated Go binding around an Ethereum contract. +type RegularCaller struct { + RegularCallerCaller // Read-only binding to the contract + RegularCallerTransactor // Write-only binding to the contract + RegularCallerFilterer // Log filterer for contract events +} + +// RegularCallerCaller is an auto generated read-only Go binding around an Ethereum contract. +type RegularCallerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularCallerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type RegularCallerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularCallerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type RegularCallerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RegularCallerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type RegularCallerSession struct { + Contract *RegularCaller // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RegularCallerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type RegularCallerCallerSession struct { + Contract *RegularCallerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// RegularCallerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type RegularCallerTransactorSession struct { + Contract *RegularCallerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RegularCallerRaw is an auto generated low-level Go binding around an Ethereum contract. +type RegularCallerRaw struct { + Contract *RegularCaller // Generic contract binding to access the raw methods on +} + +// RegularCallerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type RegularCallerCallerRaw struct { + Contract *RegularCallerCaller // Generic read-only contract binding to access the raw methods on +} + +// RegularCallerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type RegularCallerTransactorRaw struct { + Contract *RegularCallerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewRegularCaller creates a new instance of RegularCaller, bound to a specific deployed contract. +func NewRegularCaller(address common.Address, backend bind.ContractBackend) (*RegularCaller, error) { + contract, err := bindRegularCaller(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &RegularCaller{RegularCallerCaller: RegularCallerCaller{contract: contract}, RegularCallerTransactor: RegularCallerTransactor{contract: contract}, RegularCallerFilterer: RegularCallerFilterer{contract: contract}}, nil +} + +// NewRegularCallerCaller creates a new read-only instance of RegularCaller, bound to a specific deployed contract. +func NewRegularCallerCaller(address common.Address, caller bind.ContractCaller) (*RegularCallerCaller, error) { + contract, err := bindRegularCaller(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RegularCallerCaller{contract: contract}, nil +} + +// NewRegularCallerTransactor creates a new write-only instance of RegularCaller, bound to a specific deployed contract. +func NewRegularCallerTransactor(address common.Address, transactor bind.ContractTransactor) (*RegularCallerTransactor, error) { + contract, err := bindRegularCaller(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RegularCallerTransactor{contract: contract}, nil +} + +// NewRegularCallerFilterer creates a new log filterer instance of RegularCaller, bound to a specific deployed contract. +func NewRegularCallerFilterer(address common.Address, filterer bind.ContractFilterer) (*RegularCallerFilterer, error) { + contract, err := bindRegularCaller(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RegularCallerFilterer{contract: contract}, nil +} + +// bindRegularCaller binds a generic wrapper to an already deployed contract. +func bindRegularCaller(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RegularCallerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_RegularCaller *RegularCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RegularCaller.Contract.RegularCallerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_RegularCaller *RegularCallerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RegularCaller.Contract.RegularCallerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_RegularCaller *RegularCallerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RegularCaller.Contract.RegularCallerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_RegularCaller *RegularCallerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RegularCaller.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_RegularCaller *RegularCallerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RegularCaller.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_RegularCaller *RegularCallerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RegularCaller.Contract.contract.Transact(opts, method, params...) +} + +// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. +// +// Solidity: function testBech32ToHexAddr() view returns(bool) +func (_RegularCaller *RegularCallerCaller) TestBech32ToHexAddr(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _RegularCaller.contract.Call(opts, &out, "testBech32ToHexAddr") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. +// +// Solidity: function testBech32ToHexAddr() view returns(bool) +func (_RegularCaller *RegularCallerSession) TestBech32ToHexAddr() (bool, error) { + return _RegularCaller.Contract.TestBech32ToHexAddr(&_RegularCaller.CallOpts) +} + +// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. +// +// Solidity: function testBech32ToHexAddr() view returns(bool) +func (_RegularCaller *RegularCallerCallerSession) TestBech32ToHexAddr() (bool, error) { + return _RegularCaller.Contract.TestBech32ToHexAddr(&_RegularCaller.CallOpts) +} + +// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. +// +// Solidity: function testBech32ify() view returns(bool) +func (_RegularCaller *RegularCallerCaller) TestBech32ify(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _RegularCaller.contract.Call(opts, &out, "testBech32ify") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. +// +// Solidity: function testBech32ify() view returns(bool) +func (_RegularCaller *RegularCallerSession) TestBech32ify() (bool, error) { + return _RegularCaller.Contract.TestBech32ify(&_RegularCaller.CallOpts) +} + +// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. +// +// Solidity: function testBech32ify() view returns(bool) +func (_RegularCaller *RegularCallerCallerSession) TestBech32ify() (bool, error) { + return _RegularCaller.Contract.TestBech32ify(&_RegularCaller.CallOpts) +} + +// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. +// +// Solidity: function testRegularCall(string method, address addr) returns(uint256) +func (_RegularCaller *RegularCallerTransactor) TestRegularCall(opts *bind.TransactOpts, method string, addr common.Address) (*types.Transaction, error) { + return _RegularCaller.contract.Transact(opts, "testRegularCall", method, addr) +} + +// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. +// +// Solidity: function testRegularCall(string method, address addr) returns(uint256) +func (_RegularCaller *RegularCallerSession) TestRegularCall(method string, addr common.Address) (*types.Transaction, error) { + return _RegularCaller.Contract.TestRegularCall(&_RegularCaller.TransactOpts, method, addr) +} + +// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. +// +// Solidity: function testRegularCall(string method, address addr) returns(uint256) +func (_RegularCaller *RegularCallerTransactorSession) TestRegularCall(method string, addr common.Address) (*types.Transaction, error) { + return _RegularCaller.Contract.TestRegularCall(&_RegularCaller.TransactOpts, method, addr) +} diff --git a/precompiles/prototype/testutil/RegularCaller.json b/precompiles/prototype/testutil/RegularCaller.json new file mode 100644 index 0000000000..f8187a2651 --- /dev/null +++ b/precompiles/prototype/testutil/RegularCaller.json @@ -0,0 +1,55 @@ +{ + "abi": [ + { + "inputs": [], + "name": "testBech32ToHexAddr", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "testBech32ify", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "method", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "testRegularCall", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033" +} diff --git a/precompiles/prototype/testutil/RegularCaller.sol b/precompiles/prototype/testutil/RegularCaller.sol new file mode 100644 index 0000000000..2e9aa13ee0 --- /dev/null +++ b/precompiles/prototype/testutil/RegularCaller.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity ^0.8.7; + +import "./IRegular.sol"; + +//IRegular constant IREGULAR_CONTRACT = IRegular(IREGULAR_PRECOMPILE_ADDRESS); +contract RegularCaller { + function testBech32ToHexAddr() public view returns (bool) { + // Test input and expected output + string + memory testBech32 = "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"; + address expectedHexAddr = 0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE; + + // Call the precompiled contract + address result = IREGULAR_CONTRACT.bech32ToHexAddr(testBech32); + + // Check if the result matches the expected output + return result == expectedHexAddr; + } + + function testBech32ify() public view returns (bool) { + // Test input and expected output + string memory testPrefix = "zeta"; + address testHexAddr = 0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE; + string + memory expectedBech32 = "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"; + + // Call the precompiled contract + string memory result = IREGULAR_CONTRACT.bech32ify( + testPrefix, + testHexAddr + ); + + // Check if the result matches the expected output + return + keccak256(abi.encodePacked(result)) == + keccak256(abi.encodePacked(expectedBech32)); + } + + function testRegularCall( + string memory method, + address addr + ) public returns (uint256) { + // Call the precompiled contract with the given method and address + uint256 result = IREGULAR_CONTRACT.regularCall(method, addr); + + // Return the result + return result; + } +} From 175064426fe1a277058713f733aad5e99141bd32 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 11:47:13 +0200 Subject: [PATCH 21/33] delete regularcaller --- .../prototype/testutil/RegularCaller.abi | 52 ---- .../prototype/testutil/RegularCaller.bin | 1 - .../prototype/testutil/RegularCaller.go | 286 ------------------ .../prototype/testutil/RegularCaller.json | 55 ---- .../prototype/testutil/RegularCaller.sol | 50 --- 5 files changed, 444 deletions(-) delete mode 100644 precompiles/prototype/testutil/RegularCaller.abi delete mode 100644 precompiles/prototype/testutil/RegularCaller.bin delete mode 100644 precompiles/prototype/testutil/RegularCaller.go delete mode 100644 precompiles/prototype/testutil/RegularCaller.json delete mode 100644 precompiles/prototype/testutil/RegularCaller.sol diff --git a/precompiles/prototype/testutil/RegularCaller.abi b/precompiles/prototype/testutil/RegularCaller.abi deleted file mode 100644 index 8f4eee8709..0000000000 --- a/precompiles/prototype/testutil/RegularCaller.abi +++ /dev/null @@ -1,52 +0,0 @@ -[ - { - "inputs": [], - "name": "testBech32ToHexAddr", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "testBech32ify", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "method", - "type": "string" - }, - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "testRegularCall", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/precompiles/prototype/testutil/RegularCaller.bin b/precompiles/prototype/testutil/RegularCaller.bin deleted file mode 100644 index 5b7447ab81..0000000000 --- a/precompiles/prototype/testutil/RegularCaller.bin +++ /dev/null @@ -1 +0,0 @@ -608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033 \ No newline at end of file diff --git a/precompiles/prototype/testutil/RegularCaller.go b/precompiles/prototype/testutil/RegularCaller.go deleted file mode 100644 index 71b45e868a..0000000000 --- a/precompiles/prototype/testutil/RegularCaller.go +++ /dev/null @@ -1,286 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package testutils - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// RegularCallerMetaData contains all meta data concerning the RegularCaller contract. -var RegularCallerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"testBech32ToHexAddr\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testBech32ify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"testRegularCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033", -} - -// RegularCallerABI is the input ABI used to generate the binding from. -// Deprecated: Use RegularCallerMetaData.ABI instead. -var RegularCallerABI = RegularCallerMetaData.ABI - -// RegularCallerBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use RegularCallerMetaData.Bin instead. -var RegularCallerBin = RegularCallerMetaData.Bin - -// DeployRegularCaller deploys a new Ethereum contract, binding an instance of RegularCaller to it. -func DeployRegularCaller(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *RegularCaller, error) { - parsed, err := RegularCallerMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RegularCallerBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &RegularCaller{RegularCallerCaller: RegularCallerCaller{contract: contract}, RegularCallerTransactor: RegularCallerTransactor{contract: contract}, RegularCallerFilterer: RegularCallerFilterer{contract: contract}}, nil -} - -// RegularCaller is an auto generated Go binding around an Ethereum contract. -type RegularCaller struct { - RegularCallerCaller // Read-only binding to the contract - RegularCallerTransactor // Write-only binding to the contract - RegularCallerFilterer // Log filterer for contract events -} - -// RegularCallerCaller is an auto generated read-only Go binding around an Ethereum contract. -type RegularCallerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularCallerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type RegularCallerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularCallerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type RegularCallerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegularCallerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type RegularCallerSession struct { - Contract *RegularCaller // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RegularCallerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type RegularCallerCallerSession struct { - Contract *RegularCallerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// RegularCallerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type RegularCallerTransactorSession struct { - Contract *RegularCallerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RegularCallerRaw is an auto generated low-level Go binding around an Ethereum contract. -type RegularCallerRaw struct { - Contract *RegularCaller // Generic contract binding to access the raw methods on -} - -// RegularCallerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type RegularCallerCallerRaw struct { - Contract *RegularCallerCaller // Generic read-only contract binding to access the raw methods on -} - -// RegularCallerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type RegularCallerTransactorRaw struct { - Contract *RegularCallerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewRegularCaller creates a new instance of RegularCaller, bound to a specific deployed contract. -func NewRegularCaller(address common.Address, backend bind.ContractBackend) (*RegularCaller, error) { - contract, err := bindRegularCaller(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &RegularCaller{RegularCallerCaller: RegularCallerCaller{contract: contract}, RegularCallerTransactor: RegularCallerTransactor{contract: contract}, RegularCallerFilterer: RegularCallerFilterer{contract: contract}}, nil -} - -// NewRegularCallerCaller creates a new read-only instance of RegularCaller, bound to a specific deployed contract. -func NewRegularCallerCaller(address common.Address, caller bind.ContractCaller) (*RegularCallerCaller, error) { - contract, err := bindRegularCaller(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &RegularCallerCaller{contract: contract}, nil -} - -// NewRegularCallerTransactor creates a new write-only instance of RegularCaller, bound to a specific deployed contract. -func NewRegularCallerTransactor(address common.Address, transactor bind.ContractTransactor) (*RegularCallerTransactor, error) { - contract, err := bindRegularCaller(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &RegularCallerTransactor{contract: contract}, nil -} - -// NewRegularCallerFilterer creates a new log filterer instance of RegularCaller, bound to a specific deployed contract. -func NewRegularCallerFilterer(address common.Address, filterer bind.ContractFilterer) (*RegularCallerFilterer, error) { - contract, err := bindRegularCaller(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &RegularCallerFilterer{contract: contract}, nil -} - -// bindRegularCaller binds a generic wrapper to an already deployed contract. -func bindRegularCaller(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := RegularCallerMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_RegularCaller *RegularCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _RegularCaller.Contract.RegularCallerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_RegularCaller *RegularCallerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _RegularCaller.Contract.RegularCallerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_RegularCaller *RegularCallerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _RegularCaller.Contract.RegularCallerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_RegularCaller *RegularCallerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _RegularCaller.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_RegularCaller *RegularCallerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _RegularCaller.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_RegularCaller *RegularCallerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _RegularCaller.Contract.contract.Transact(opts, method, params...) -} - -// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. -// -// Solidity: function testBech32ToHexAddr() view returns(bool) -func (_RegularCaller *RegularCallerCaller) TestBech32ToHexAddr(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _RegularCaller.contract.Call(opts, &out, "testBech32ToHexAddr") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. -// -// Solidity: function testBech32ToHexAddr() view returns(bool) -func (_RegularCaller *RegularCallerSession) TestBech32ToHexAddr() (bool, error) { - return _RegularCaller.Contract.TestBech32ToHexAddr(&_RegularCaller.CallOpts) -} - -// TestBech32ToHexAddr is a free data retrieval call binding the contract method 0x42875b1d. -// -// Solidity: function testBech32ToHexAddr() view returns(bool) -func (_RegularCaller *RegularCallerCallerSession) TestBech32ToHexAddr() (bool, error) { - return _RegularCaller.Contract.TestBech32ToHexAddr(&_RegularCaller.CallOpts) -} - -// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. -// -// Solidity: function testBech32ify() view returns(bool) -func (_RegularCaller *RegularCallerCaller) TestBech32ify(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _RegularCaller.contract.Call(opts, &out, "testBech32ify") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. -// -// Solidity: function testBech32ify() view returns(bool) -func (_RegularCaller *RegularCallerSession) TestBech32ify() (bool, error) { - return _RegularCaller.Contract.TestBech32ify(&_RegularCaller.CallOpts) -} - -// TestBech32ify is a free data retrieval call binding the contract method 0xd7c9bd02. -// -// Solidity: function testBech32ify() view returns(bool) -func (_RegularCaller *RegularCallerCallerSession) TestBech32ify() (bool, error) { - return _RegularCaller.Contract.TestBech32ify(&_RegularCaller.CallOpts) -} - -// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. -// -// Solidity: function testRegularCall(string method, address addr) returns(uint256) -func (_RegularCaller *RegularCallerTransactor) TestRegularCall(opts *bind.TransactOpts, method string, addr common.Address) (*types.Transaction, error) { - return _RegularCaller.contract.Transact(opts, "testRegularCall", method, addr) -} - -// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. -// -// Solidity: function testRegularCall(string method, address addr) returns(uint256) -func (_RegularCaller *RegularCallerSession) TestRegularCall(method string, addr common.Address) (*types.Transaction, error) { - return _RegularCaller.Contract.TestRegularCall(&_RegularCaller.TransactOpts, method, addr) -} - -// TestRegularCall is a paid mutator transaction binding the contract method 0x48fc7db1. -// -// Solidity: function testRegularCall(string method, address addr) returns(uint256) -func (_RegularCaller *RegularCallerTransactorSession) TestRegularCall(method string, addr common.Address) (*types.Transaction, error) { - return _RegularCaller.Contract.TestRegularCall(&_RegularCaller.TransactOpts, method, addr) -} diff --git a/precompiles/prototype/testutil/RegularCaller.json b/precompiles/prototype/testutil/RegularCaller.json deleted file mode 100644 index f8187a2651..0000000000 --- a/precompiles/prototype/testutil/RegularCaller.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "name": "testBech32ToHexAddr", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "testBech32ify", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "method", - "type": "string" - }, - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "testRegularCall", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bin": "608060405234801561001057600080fd5b50610918806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806342875b1d1461004657806348fc7db114610064578063d7c9bd0214610094575b600080fd5b61004e6100b2565b60405161005b9190610675565b60405180910390f35b61007e6004803603810190610079919061053e565b6101ae565b60405161008b91906106e2565b60405180910390f35b61009c61024b565b6040516100a99190610675565b60405180910390f35b6000806040518060600160405280602b81526020016108b8602b91399050600073b9dbc229bf588a613c00bee8e662727ab8121cfe90506000606573ffffffffffffffffffffffffffffffffffffffff1663e4e2a4ec846040518263ffffffff1660e01b81526004016101259190610690565b60206040518083038186803b15801561013d57600080fd5b505afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906104c8565b90508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614935050505090565b600080606573ffffffffffffffffffffffffffffffffffffffff166393e3663d85856040518363ffffffff1660e01b81526004016101ed9291906106b2565b602060405180830381600087803b15801561020757600080fd5b505af115801561021b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023f919061059a565b90508091505092915050565b6000806040518060400160405280600481526020017f7a657461000000000000000000000000000000000000000000000000000000008152509050600073b9dbc229bf588a613c00bee8e662727ab8121cfe905060006040518060600160405280602b81526020016108b8602b913990506000606573ffffffffffffffffffffffffffffffffffffffff16630615b74e85856040518363ffffffff1660e01b81526004016102fa9291906106b2565b60006040518083038186803b15801561031257600080fd5b505afa158015610326573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061034f91906104f5565b905081604051602001610362919061065e565b6040516020818303038152906040528051906020012081604051602001610389919061065e565b604051602081830303815290604052805190602001201494505050505090565b60006103bc6103b784610722565b6106fd565b9050828152602081018484840111156103d8576103d7610869565b5b6103e38482856107c2565b509392505050565b60006103fe6103f984610722565b6106fd565b90508281526020810184848401111561041a57610419610869565b5b6104258482856107d1565b509392505050565b60008135905061043c81610889565b92915050565b60008151905061045181610889565b92915050565b600082601f83011261046c5761046b610864565b5b813561047c8482602086016103a9565b91505092915050565b600082601f83011261049a57610499610864565b5b81516104aa8482602086016103eb565b91505092915050565b6000815190506104c2816108a0565b92915050565b6000602082840312156104de576104dd610873565b5b60006104ec84828501610442565b91505092915050565b60006020828403121561050b5761050a610873565b5b600082015167ffffffffffffffff8111156105295761052861086e565b5b61053584828501610485565b91505092915050565b6000806040838503121561055557610554610873565b5b600083013567ffffffffffffffff8111156105735761057261086e565b5b61057f85828601610457565b92505060206105908582860161042d565b9150509250929050565b6000602082840312156105b0576105af610873565b5b60006105be848285016104b3565b91505092915050565b6105d08161077a565b82525050565b6105df8161078c565b82525050565b60006105f082610753565b6105fa818561075e565b935061060a8185602086016107d1565b61061381610878565b840191505092915050565b600061062982610753565b610633818561076f565b93506106438185602086016107d1565b80840191505092915050565b610658816107b8565b82525050565b600061066a828461061e565b915081905092915050565b600060208201905061068a60008301846105d6565b92915050565b600060208201905081810360008301526106aa81846105e5565b905092915050565b600060408201905081810360008301526106cc81856105e5565b90506106db60208301846105c7565b9392505050565b60006020820190506106f7600083018461064f565b92915050565b6000610707610718565b90506107138282610804565b919050565b6000604051905090565b600067ffffffffffffffff82111561073d5761073c610835565b5b61074682610878565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061078582610798565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156107ef5780820151818401526020810190506107d4565b838111156107fe576000848401525b50505050565b61080d82610878565b810181811067ffffffffffffffff8211171561082c5761082b610835565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6108928161077a565b811461089d57600080fd5b50565b6108a9816107b8565b81146108b457600080fd5b5056fe7a65746131683864757932646c747a39787a307171686d357776636e6a303275707938383766796e343375a26469706673582212205d1317177480909fff852a3871dc5d7fbdcb2fec3c47b91fc472fa775517c70264736f6c63430008070033" -} diff --git a/precompiles/prototype/testutil/RegularCaller.sol b/precompiles/prototype/testutil/RegularCaller.sol deleted file mode 100644 index 2e9aa13ee0..0000000000 --- a/precompiles/prototype/testutil/RegularCaller.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.7; - -import "./IRegular.sol"; - -//IRegular constant IREGULAR_CONTRACT = IRegular(IREGULAR_PRECOMPILE_ADDRESS); -contract RegularCaller { - function testBech32ToHexAddr() public view returns (bool) { - // Test input and expected output - string - memory testBech32 = "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"; - address expectedHexAddr = 0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE; - - // Call the precompiled contract - address result = IREGULAR_CONTRACT.bech32ToHexAddr(testBech32); - - // Check if the result matches the expected output - return result == expectedHexAddr; - } - - function testBech32ify() public view returns (bool) { - // Test input and expected output - string memory testPrefix = "zeta"; - address testHexAddr = 0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE; - string - memory expectedBech32 = "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"; - - // Call the precompiled contract - string memory result = IREGULAR_CONTRACT.bech32ify( - testPrefix, - testHexAddr - ); - - // Check if the result matches the expected output - return - keccak256(abi.encodePacked(result)) == - keccak256(abi.encodePacked(expectedBech32)); - } - - function testRegularCall( - string memory method, - address addr - ) public returns (uint256) { - // Call the precompiled contract with the given method and address - uint256 result = IREGULAR_CONTRACT.regularCall(method, addr); - - // Return the result - return result; - } -} From 0f0a517e2ff8246819f6ba83608aab4272088837 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 12:05:30 +0200 Subject: [PATCH 22/33] ignore bindings from codecov --- codecov.yml | 91 +++++++++++++++++++++++--------------------- e2e/config/config.go | 5 +++ 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/codecov.yml b/codecov.yml index fb59f7ad2a..474cfe97ee 100644 --- a/codecov.yml +++ b/codecov.yml @@ -22,59 +22,62 @@ coverage: - pkg comment: - layout: 'reach, diff, files' + layout: "reach, diff, files" behavior: default require_changes: true flags: zetacore: paths: - - 'x/' + - "x/" zetaclient: paths: - - 'zetaclient/' + - "zetaclient/" pkg: paths: - - 'pkg/' + - "pkg/" ignore: - - 'x/**/client/**/*' - - 'x/**/keeper/keeper.go' - - 'x/**/keeper/msg_server.go' - - 'x/**/keeper/grpc_query_params.go' - - 'x/**/types/codec.go' - - 'x/**/types/errors.go' - - 'x/**/types/keys.go' - - 'x/**/types/key_*.go' - - 'x/**/types/types.go' - - 'x/**/types/expected_keepers.go' - - 'x/**/module.go' - - 'x/**/events.go' - - 'x/**/migrator.go' - - 'x/**/module_simulation.go' - - 'x/**/simulation/**/*' - - '**/*.proto' - - '**/*.md' - - '**/*.yml' - - '**/*.yaml' - - '**/*.pb.go' - - '**/*.pb.gw.go' - - '**/*_legacy.go' - - '**/*.json' - - 'zetaclient/testdata/**/*' - - 'zetaclient/testutils/**/*' - - '.github' - - 'app' - - 'cmd' - - 'contrib' - - 'docs' - - 'e2e' - - 'proto' - - 'rpc' - - 'scripts' - - 'server' - - 'testutil' - - 'tool' - - 'typescript/**/*' - - 'precompiles/**/bindings.go' - - 'precompiles/prototype/IPrototype.*' + - "x/**/client/**/*" + - "x/**/keeper/keeper.go" + - "x/**/keeper/msg_server.go" + - "x/**/keeper/grpc_query_params.go" + - "x/**/types/codec.go" + - "x/**/types/errors.go" + - "x/**/types/keys.go" + - "x/**/types/key_*.go" + - "x/**/types/types.go" + - "x/**/types/expected_keepers.go" + - "x/**/module.go" + - "x/**/events.go" + - "x/**/migrator.go" + - "x/**/module_simulation.go" + - "x/**/simulation/**/*" + - "**/*.proto" + - "**/*.md" + - "**/*.yml" + - "**/*.yaml" + - "**/*.pb.go" + - "**/*.pb.gw.go" + - "**/*_legacy.go" + - "**/*.json" + - "zetaclient/testdata/**/*" + - "zetaclient/testutils/**/*" + - ".github" + - "app" + - "cmd" + - "contrib" + - "docs" + - "e2e" + - "proto" + - "rpc" + - "scripts" + - "server" + - "testutil" + - "tool" + - "typescript/**/*" + - "precompiles/**/bindings.go" + - "precompiles/**/*.abi" + - "precompiles/**/*.json" + - "precompiles/**/*.sol" + - "precompiles/prototype/IPrototype.go" diff --git a/e2e/config/config.go b/e2e/config/config.go index ca1a372a02..2be878b444 100644 --- a/e2e/config/config.go +++ b/e2e/config/config.go @@ -213,6 +213,7 @@ func (a AdditionalAccounts) AsSlice() []Account { a.UserMisc, a.UserAdmin, a.UserMigration, + a.UserPrecompile, } } @@ -305,6 +306,10 @@ func (c *Config) GenerateKeys() error { if err != nil { return err } + c.AdditionalAccounts.UserPrecompile, err = generateAccount() + if err != nil { + return err + } c.PolicyAccounts.EmergencyPolicyAccount, err = generateAccount() if err != nil { From ee52f661971c54d8236acb8798b93b94055cfd75 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 12:29:23 +0200 Subject: [PATCH 23/33] introduce more unit testing --- precompiles/precompiles_test.go | 9 +++--- precompiles/types/errors_test.go | 48 ++++++++++++++++++++++++++++++++ precompiles/types/types.go | 5 ++++ precompiles/types/types_test.go | 26 +++++++++++++++++ 4 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 precompiles/types/errors_test.go create mode 100644 precompiles/types/types_test.go diff --git a/precompiles/precompiles_test.go b/precompiles/precompiles_test.go index a53988e3fc..06c8ccb0bb 100644 --- a/precompiles/precompiles_test.go +++ b/precompiles/precompiles_test.go @@ -1,4 +1,4 @@ -package precompiles_test +package precompiles import ( "testing" @@ -7,7 +7,6 @@ import ( ethparams "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" ethermint "github.com/zeta-chain/ethermint/types" - "github.com/zeta-chain/zetacore/precompiles" "github.com/zeta-chain/zetacore/testutil/keeper" ) @@ -19,14 +18,14 @@ func Test_StatefulContracts(t *testing.T) { appCodec := encoding.Codec var expectedContracts int - for _, enabled := range precompiles.EnabledStatefulContracts { + for _, enabled := range EnabledStatefulContracts { if enabled { expectedContracts++ } } // StatefulContracts() should return all the enabled contracts. - contracts := precompiles.StatefulContracts(k, appCodec, gasConfig) + contracts := StatefulContracts(k, appCodec, gasConfig) require.NotNil(t, contracts, "StatefulContracts() should not return a nil slice") require.Len(t, contracts, expectedContracts, "StatefulContracts() should return all the enabled contracts") @@ -37,4 +36,4 @@ func Test_StatefulContracts(t *testing.T) { // Check the contract function returns a valid address. contractAddr := contract.Address() require.NotNil(t, contractAddr, "The called contract should have a valid address") -} \ No newline at end of file +} diff --git a/precompiles/types/errors_test.go b/precompiles/types/errors_test.go new file mode 100644 index 0000000000..809290268e --- /dev/null +++ b/precompiles/types/errors_test.go @@ -0,0 +1,48 @@ +package types + +import "testing" + +func Test_ErrInvalidAddr(t *testing.T) { + e := ErrInvalidAddr{ + Got: "foo", + } + got := e.Error() + expect := "invalid address foo" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } +} + +func Test_ErrInvalidNumberOfArgs(t *testing.T) { + e := ErrInvalidNumberOfArgs{ + Got: 1, + Expect: 2, + } + got := e.Error() + expect := "invalid number of arguments; expected 2; got: 1" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } +} + +func Test_ErrInvalidArgument(t *testing.T) { + e := ErrInvalidArgument{ + Got: "foo", + } + got := e.Error() + expect := "invalid argument: foo" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } +} + +func Test_ErrInvalidMethod(t *testing.T) { + e := ErrInvalidMethod{ + Method: "foo", + } + got := e.Error() + expect := "invalid method: foo" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } +} \ No newline at end of file diff --git a/precompiles/types/types.go b/precompiles/types/types.go index 579e138d37..92b5dc0c82 100644 --- a/precompiles/types/types.go +++ b/precompiles/types/types.go @@ -9,6 +9,11 @@ import ( "github.com/zeta-chain/ethermint/x/evm/statedb" ) +// Interface compliance +var _ ExtStateDB = (*statedb.StateDB)(nil) +var _ Registrable = (*baseContract)(nil) +var _ BaseContract = (*baseContract)(nil) + // ExtStateDB defines extra methods of statedb to support stateful precompiled contracts. // It's used to persist changes into the store. type ExtStateDB interface { diff --git a/precompiles/types/types_test.go b/precompiles/types/types_test.go new file mode 100644 index 0000000000..d0b76e916c --- /dev/null +++ b/precompiles/types/types_test.go @@ -0,0 +1,26 @@ +package types + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func Test_BaseContract(t *testing.T) { + addr := common.BytesToAddress([]byte{0x1}) + + contract := NewBaseContract(addr) + require.NotNil(t, contract) + + // By implementing RegistryKey() the baseContract struct implements Registrable. + // Registrable is the unique requisite to implement BaseContract as well. + require.Equal(t, addr, contract.RegistryKey()) +} + +func Test_BytesToBigInt(t *testing.T) { + data := []byte{0x1} + intData := BytesToBigInt(data) + require.NotNil(t, intData) + require.Equal(t, int64(1), intData.Int64()) +} \ No newline at end of file From 3fa0cab1b8728e04954c57b80c6b141a271859dd Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 14:11:06 +0200 Subject: [PATCH 24/33] add unit testing for prototype.go --- e2e/e2etests/e2etests.go | 2 +- precompiles/prototype/IPrototype.sol | 1 - precompiles/prototype/prototype.go | 8 +- precompiles/prototype/prototype_test.go | 137 ++++++++++++++++++++++++ precompiles/types/types.go | 2 +- 5 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 precompiles/prototype/prototype_test.go diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 6a975bcc79..b2e78ed380 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -599,7 +599,7 @@ var AllE2ETests = []runner.E2ETest{ */ runner.NewE2ETest( TestZetaPrecompilesPrototypeName, - "call stateful precompiled contract", + "test stateful precompiled contracts prototype", []runner.ArgDefinition{}, TestPrecompilesRegular, ), diff --git a/precompiles/prototype/IPrototype.sol b/precompiles/prototype/IPrototype.sol index d65779cc5f..34a8892e3c 100644 --- a/precompiles/prototype/IPrototype.sol +++ b/precompiles/prototype/IPrototype.sol @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.26; /// @dev The IRegular contract's address. diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index ddfb8531f3..6152601c3f 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -152,7 +152,11 @@ func (c *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, er } cfg := sdk.GetConfig() - prefix, _ := args[0].(string) + prefix, ok := args[0].(string) + if !ok { + return nil, fmt.Errorf("invalid bech32 human readable prefix (HRP): %v", args[0]) + } + if strings.TrimSpace(prefix) == "" { return nil, fmt.Errorf( "invalid bech32 human readable prefix (HRP). Please provide a either an account, validator or consensus address prefix (eg: %s, %s, %s)", @@ -167,7 +171,7 @@ func (c *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, er return nil, fmt.Errorf("invalid hex address") } - // NOTE: safety check, should not happen given that the address is is 20 bytes. + // NOTE: safety check, should not happen given that the address is 20 bytes. if err := sdk.VerifyAddressFormat(address.Bytes()); err != nil { return nil, err } diff --git a/precompiles/prototype/prototype_test.go b/precompiles/prototype/prototype_test.go new file mode 100644 index 0000000000..1519693e91 --- /dev/null +++ b/precompiles/prototype/prototype_test.go @@ -0,0 +1,137 @@ +package prototype + +import ( + "testing" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + ethermint "github.com/zeta-chain/ethermint/types" + "github.com/zeta-chain/zetacore/testutil/keeper" +) + +func Test_IPrototypeContract(t *testing.T) { + /* + Configuration + */ + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, ctx, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + /* + Contract and ABI tests + */ + + // Create a new IPrototypeContract instance and get Address and Abi. + contract := NewIPrototypeContract(ctx, k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + address := contract.Address() + require.Equal(t, ContractAddress, address, "contract address should match the precompiled address") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + // Check all methods are present in the ABI. + bech32ToHex := abi.Methods[Bech32ToHexAddrMethodName] + require.NotNil(t, bech32ToHex, "bech32ToHexAddr method should be present in the ABI") + + bech32ify := abi.Methods[Bech32ifyMethodName] + require.NotNil(t, bech32ify, "bech32ify method should be present in the ABI") + + getGasStabilityPoolBalance := abi.Methods[GetGasStabilityPoolBalanceName] + require.NotNil(t, getGasStabilityPoolBalance, "getGasStabilityPoolBalance method should be present in the ABI") + + /* + Gas tests + */ + + // Check all methods use the correct gas amount. + var method [4]byte + + gasBech32ToHex := contract.RequiredGas(bech32ToHex.ID) + copy(method[:], bech32ToHex.ID[:4]) + baseCost := uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method] + baseCost, + gasBech32ToHex, + "bech32ToHexAddr method should require %d gas, got %d", + GasRequiredByMethod[method] + baseCost, + gasBech32ToHex) + + gasBech32ify := contract.RequiredGas(bech32ify.ID) + copy(method[:], bech32ify.ID[:4]) + baseCost = uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method] + baseCost, + gasBech32ify, + "bech32ify method should require %d gas, got %d", + GasRequiredByMethod[method] + baseCost, + gasBech32ify) + + gasGetGasStabilityPoolBalance := contract.RequiredGas(getGasStabilityPoolBalance.ID) + copy(method[:], getGasStabilityPoolBalance.ID[:4]) + baseCost = uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method] + baseCost, + gasGetGasStabilityPoolBalance, + "getGasStabilityPoolBalance method should require %d gas, got %d", + GasRequiredByMethod[method] + baseCost, + gasGetGasStabilityPoolBalance) + + /* + Methods tests + */ + + // Test Bech32HexAddr method. + methodID := abi.Methods[Bech32ToHexAddrMethodName] + args := make([]interface{}, 0) + args = append(args, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u") + + rawBytes, err := contract.Bech32ToHexAddr(&methodID, args) + require.NoError(t, err, "Bech32ToHexAddr should not return an error") + + // Discard the first 12 bytes, the address is the last 20 bytes. + addr := common.BytesToAddress(rawBytes[12:]) + require.Equal( + t, + common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE"), + addr, + "Bech32ToHexAddr should return the correct address, got: %v", + addr, + ) + + // Test Bech32ify method. + methodID = abi.Methods[Bech32ifyMethodName] + args = make([]interface{}, 0) + args = append(args, "zeta") + args = append(args, common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) + + rawBytes, err = contract.Bech32ify(&methodID, args) + require.NoError(t, err, "Bech32ify should not return an error") + + // Manually extract the address from the raw bytes. + zetaAddr := string(rawBytes[64:107]) + require.Equal( + t, + "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", + string(zetaAddr), + "Bech32ify should return the correct address, got: %v", + zetaAddr, + ) + + // Test GetGasStabilityPoolBalance method. + // Only check the function is called correctly inside the contract, and it returns the expected error. + // Configuring a local environment for this contract would require deploying system contracts and gas pools. + // This method is tested thoroughly in the e2e tests. + methodID = abi.Methods[GetGasStabilityPoolBalanceName] + args = make([]interface{}, 0) + args = append(args, int64(1337)) + + rawBytes, err = contract.GetGasStabilityPoolBalance(ctx, &methodID, args) + require.Error(t, err, "error calling fungible keeper: failed to get system contract variable: state variable not found") +} diff --git a/precompiles/types/types.go b/precompiles/types/types.go index 92b5dc0c82..7bd4a57bfa 100644 --- a/precompiles/types/types.go +++ b/precompiles/types/types.go @@ -9,7 +9,7 @@ import ( "github.com/zeta-chain/ethermint/x/evm/statedb" ) -// Interface compliance +// Interface compliance. var _ ExtStateDB = (*statedb.StateDB)(nil) var _ Registrable = (*baseContract)(nil) var _ BaseContract = (*baseContract)(nil) From 3a31ddbfc185b509f80ed3be0164d0c4bdefd593 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 14:21:26 +0200 Subject: [PATCH 25/33] minor linting fixes --- precompiles/prototype/IPrototype.sol | 6 +-- precompiles/prototype/prototype_test.go | 50 +++++++++++++------------ precompiles/types/errors_test.go | 2 +- precompiles/types/types_test.go | 2 +- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/precompiles/prototype/IPrototype.sol b/precompiles/prototype/IPrototype.sol index 34a8892e3c..eb8f34d770 100644 --- a/precompiles/prototype/IPrototype.sol +++ b/precompiles/prototype/IPrototype.sol @@ -1,10 +1,10 @@ pragma solidity ^0.8.26; -/// @dev The IRegular contract's address. +/// @dev The IPrototype contract's address. address constant IPROTOTYPE_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000065; // 101 -/// @dev The IRegular contract's instance. -IPrototype constant IREGULAR_CONTRACT = IPrototype( +/// @dev The IPrototype contract's instance. +IPrototype constant IPROTOTYPE_CONTRACT = IPrototype( IPROTOTYPE_PRECOMPILE_ADDRESS ); diff --git a/precompiles/prototype/prototype_test.go b/precompiles/prototype/prototype_test.go index 1519693e91..c809c33789 100644 --- a/precompiles/prototype/prototype_test.go +++ b/precompiles/prototype/prototype_test.go @@ -54,33 +54,33 @@ func Test_IPrototypeContract(t *testing.T) { copy(method[:], bech32ToHex.ID[:4]) baseCost := uint64(len(method)) * gasConfig.WriteCostPerByte require.Equal( - t, - GasRequiredByMethod[method] + baseCost, - gasBech32ToHex, - "bech32ToHexAddr method should require %d gas, got %d", - GasRequiredByMethod[method] + baseCost, + t, + GasRequiredByMethod[method]+baseCost, + gasBech32ToHex, + "bech32ToHexAddr method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, gasBech32ToHex) gasBech32ify := contract.RequiredGas(bech32ify.ID) copy(method[:], bech32ify.ID[:4]) baseCost = uint64(len(method)) * gasConfig.WriteCostPerByte require.Equal( - t, - GasRequiredByMethod[method] + baseCost, + t, + GasRequiredByMethod[method]+baseCost, gasBech32ify, - "bech32ify method should require %d gas, got %d", - GasRequiredByMethod[method] + baseCost, + "bech32ify method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, gasBech32ify) gasGetGasStabilityPoolBalance := contract.RequiredGas(getGasStabilityPoolBalance.ID) copy(method[:], getGasStabilityPoolBalance.ID[:4]) baseCost = uint64(len(method)) * gasConfig.WriteCostPerByte require.Equal( - t, - GasRequiredByMethod[method] + baseCost, + t, + GasRequiredByMethod[method]+baseCost, gasGetGasStabilityPoolBalance, - "getGasStabilityPoolBalance method should require %d gas, got %d", - GasRequiredByMethod[method] + baseCost, + "getGasStabilityPoolBalance method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, gasGetGasStabilityPoolBalance) /* @@ -89,7 +89,7 @@ func Test_IPrototypeContract(t *testing.T) { // Test Bech32HexAddr method. methodID := abi.Methods[Bech32ToHexAddrMethodName] - args := make([]interface{}, 0) + args := make([]interface{}, 0) args = append(args, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u") rawBytes, err := contract.Bech32ToHexAddr(&methodID, args) @@ -98,10 +98,10 @@ func Test_IPrototypeContract(t *testing.T) { // Discard the first 12 bytes, the address is the last 20 bytes. addr := common.BytesToAddress(rawBytes[12:]) require.Equal( - t, - common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE"), - addr, - "Bech32ToHexAddr should return the correct address, got: %v", + t, + common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE"), + addr, + "Bech32ToHexAddr should return the correct address, got: %v", addr, ) @@ -117,10 +117,10 @@ func Test_IPrototypeContract(t *testing.T) { // Manually extract the address from the raw bytes. zetaAddr := string(rawBytes[64:107]) require.Equal( - t, - "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", - string(zetaAddr), - "Bech32ify should return the correct address, got: %v", + t, + "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", + string(zetaAddr), + "Bech32ify should return the correct address, got: %v", zetaAddr, ) @@ -133,5 +133,9 @@ func Test_IPrototypeContract(t *testing.T) { args = append(args, int64(1337)) rawBytes, err = contract.GetGasStabilityPoolBalance(ctx, &methodID, args) - require.Error(t, err, "error calling fungible keeper: failed to get system contract variable: state variable not found") + require.Error( + t, + err, + "error calling fungible keeper: failed to get system contract variable: state variable not found", + ) } diff --git a/precompiles/types/errors_test.go b/precompiles/types/errors_test.go index 809290268e..5693a450eb 100644 --- a/precompiles/types/errors_test.go +++ b/precompiles/types/errors_test.go @@ -45,4 +45,4 @@ func Test_ErrInvalidMethod(t *testing.T) { if got != expect { t.Errorf("Expected %v, got %v", expect, got) } -} \ No newline at end of file +} diff --git a/precompiles/types/types_test.go b/precompiles/types/types_test.go index d0b76e916c..1193b55426 100644 --- a/precompiles/types/types_test.go +++ b/precompiles/types/types_test.go @@ -23,4 +23,4 @@ func Test_BytesToBigInt(t *testing.T) { intData := BytesToBigInt(data) require.NotNil(t, intData) require.Equal(t, int64(1), intData.Int64()) -} \ No newline at end of file +} From fe78f693ddabc3078b87bef9e80eeee2680c71b1 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 16:11:07 +0200 Subject: [PATCH 26/33] remove ctx, keep fungible keeper private --- precompiles/precompiles.go | 4 ++-- precompiles/prototype/prototype.go | 9 +++------ precompiles/prototype/prototype_test.go | 3 ++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go index 1e76a7c69e..ad5eb55c50 100644 --- a/precompiles/precompiles.go +++ b/precompiles/precompiles.go @@ -31,8 +31,8 @@ func StatefulContracts( // Define the regular contract function. if EnabledStatefulContracts[prototype.ContractAddress] { - prototype := func(ctx sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { - return prototype.NewIPrototypeContract(ctx, fungibleKeeper, cdc, gasConfig) + prototype := func(_ sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { + return prototype.NewIPrototypeContract(fungibleKeeper, cdc, gasConfig) } // Append the regular contract to the precompiledContracts slice. diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index 6152601c3f..db3d920422 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -65,22 +65,19 @@ func init() { type Contract struct { ptypes.BaseContract - Ctx sdk.Context - FungibleKeeper fungiblekeeper.Keeper + fungibleKeeper fungiblekeeper.Keeper cdc codec.Codec kvGasConfig storetypes.GasConfig } func NewIPrototypeContract( - context sdk.Context, fungibleKeeper *fungiblekeeper.Keeper, cdc codec.Codec, kvGasConfig storetypes.GasConfig, ) *Contract { return &Contract{ - Ctx: context, BaseContract: ptypes.NewBaseContract(ContractAddress), - FungibleKeeper: *fungibleKeeper, + fungibleKeeper: *fungibleKeeper, cdc: cdc, kvGasConfig: kvGasConfig, } @@ -213,7 +210,7 @@ func (c *Contract) GetGasStabilityPoolBalance( } } - balance, err := c.FungibleKeeper.GetGasStabilityPoolBalance(ctx, chainID) + balance, err := c.fungibleKeeper.GetGasStabilityPoolBalance(ctx, chainID) if err != nil { return nil, fmt.Errorf("error calling fungible keeper: %s", err.Error()) } diff --git a/precompiles/prototype/prototype_test.go b/precompiles/prototype/prototype_test.go index c809c33789..f42de48234 100644 --- a/precompiles/prototype/prototype_test.go +++ b/precompiles/prototype/prototype_test.go @@ -14,6 +14,7 @@ func Test_IPrototypeContract(t *testing.T) { /* Configuration */ + var encoding ethermint.EncodingConfig appCodec := encoding.Codec k, ctx, _, _ := keeper.FungibleKeeper(t) @@ -24,7 +25,7 @@ func Test_IPrototypeContract(t *testing.T) { */ // Create a new IPrototypeContract instance and get Address and Abi. - contract := NewIPrototypeContract(ctx, k, appCodec, gasConfig) + contract := NewIPrototypeContract(k, appCodec, gasConfig) require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") address := contract.Address() From b62a99ecabd5edc1e169946f02b13fb3ece43289 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 17:40:07 +0200 Subject: [PATCH 27/33] increase unit tests coverage --- precompiles/prototype/prototype.go | 9 +- precompiles/prototype/prototype_test.go | 156 ++++++++++++++++++++++-- 2 files changed, 149 insertions(+), 16 deletions(-) diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index db3d920422..dde0711af8 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -56,8 +56,6 @@ func init() { GasRequiredByMethod[methodID] = 10000 case GetGasStabilityPoolBalanceName: GasRequiredByMethod[methodID] = 10000 - default: - GasRequiredByMethod[methodID] = 0 } } } @@ -107,7 +105,8 @@ func (c *Contract) RequiredGas(input []byte) uint64 { return requiredGas + baseCost } - return baseCost + // Can not happen, but return 0 if the method is not found. + return 0 } func (c *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { @@ -215,10 +214,6 @@ func (c *Contract) GetGasStabilityPoolBalance( return nil, fmt.Errorf("error calling fungible keeper: %s", err.Error()) } - if balance == nil { - return nil, fmt.Errorf("balance not found") - } - return method.Outputs.Pack(balance) } diff --git a/precompiles/prototype/prototype_test.go b/precompiles/prototype/prototype_test.go index f42de48234..4f5e2e735b 100644 --- a/precompiles/prototype/prototype_test.go +++ b/precompiles/prototype/prototype_test.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ethermint "github.com/zeta-chain/ethermint/types" + "github.com/zeta-chain/zetacore/precompiles/types" "github.com/zeta-chain/zetacore/testutil/keeper" ) @@ -17,7 +18,7 @@ func Test_IPrototypeContract(t *testing.T) { var encoding ethermint.EncodingConfig appCodec := encoding.Codec - k, ctx, _, _ := keeper.FungibleKeeper(t) + k, _, _, _ := keeper.FungibleKeeper(t) gasConfig := storetypes.TransientGasConfig() /* @@ -84,11 +85,38 @@ func Test_IPrototypeContract(t *testing.T) { GasRequiredByMethod[method]+baseCost, gasGetGasStabilityPoolBalance) + // Can not happen, but check the gas for an invalid method. + // At runtime if the method does not exist in the ABI, it returns an error. + invalidMethodBytes := []byte("invalidMethod") + gasInvalidMethod := contract.RequiredGas(invalidMethodBytes) + baseCost = uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + uint64(0), + gasInvalidMethod, + "invalid method should require %d gas, got %d", + uint64(0), + gasInvalidMethod) +} + +func Test_Bech32ToHexAddress(t *testing.T) { /* - Methods tests + Configuration */ - // Test Bech32HexAddr method. + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, _, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + // Create contract and get ABI. + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + // Test Bech32HexAddr method. Should succeed. methodID := abi.Methods[Bech32ToHexAddrMethodName] args := make([]interface{}, 0) args = append(args, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u") @@ -106,13 +134,43 @@ func Test_IPrototypeContract(t *testing.T) { addr, ) + // Test Bech32HexAddr method. Should fail with invalid number of arguments. + args = append(args, "second argument") + _, err = contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected invalid number of arguments; expected 1; got: 2") + require.IsType(t, &types.ErrInvalidNumberOfArgs{}, err, "expected error type: ErrInvalidNumberOfArgs, got: %T", err) + + // Test Bech32HexAddr method. Should fail with invalid address. + argsInvalid := make([]interface{}, 0) + argsInvalid = append(argsInvalid, "") + _, errInvalid := contract.Bech32ToHexAddr(&methodID, argsInvalid) + require.Error(t, errInvalid, "expected error invalid bech32 address: %v", argsInvalid[0]) +} + +func Test_Bech32ify(t *testing.T) { + /* + Configuration + */ + + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, _, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + // Create contract and get ABI. + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + // Test Bech32ify method. - methodID = abi.Methods[Bech32ifyMethodName] - args = make([]interface{}, 0) + methodID := abi.Methods[Bech32ifyMethodName] + args := make([]interface{}, 0) args = append(args, "zeta") args = append(args, common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) - rawBytes, err = contract.Bech32ify(&methodID, args) + rawBytes, err := contract.Bech32ify(&methodID, args) require.NoError(t, err, "Bech32ify should not return an error") // Manually extract the address from the raw bytes. @@ -125,18 +183,98 @@ func Test_IPrototypeContract(t *testing.T) { zetaAddr, ) + // Test for invalid number of arguments. + args = append(args, "third argument") + _, err = contract.Bech32ify(&methodID, args) + require.Error(t, err, "expected invalid number of arguments; expected 2; got: 3") + require.IsType(t, &types.ErrInvalidNumberOfArgs{}, err, "expected error type: ErrInvalidNumberOfArgs, got: %T", err) + + // Test for invalid bech32 human readable prefix. + argsInvalidBech32 := make([]interface{}, 0) + argsInvalidBech32 = append(argsInvalidBech32, 1337) + argsInvalidBech32 = append(argsInvalidBech32, common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) + _, errInvalidBech32 := contract.Bech32ify(&methodID, argsInvalidBech32) + require.Error(t, errInvalidBech32, "expected error invalid bech32 human readable prefix (HRP)") + + // Test for invalid hex address. + argsInvalidHexAddress := make([]interface{}, 0) + argsInvalidHexAddress = append(argsInvalidHexAddress, "zeta") + argsInvalidHexAddress = append(argsInvalidHexAddress, 1337) + _, errInvalidHexAddress := contract.Bech32ify(&methodID, argsInvalidHexAddress) + require.Error(t, errInvalidHexAddress, "expected error invalid hex address") + + // Test for invalid bech32 human readable prefix. + argsInvalidEmptyPrefix := make([]interface{}, 0) + argsInvalidEmptyPrefix = append(argsInvalidEmptyPrefix, "") + argsInvalidEmptyPrefix = append(argsInvalidEmptyPrefix, common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) + _, errInvalidEmptyPrefix := contract.Bech32ify(&methodID, argsInvalidEmptyPrefix) + require.Error(t, errInvalidEmptyPrefix, "expected error invalid bech32 human readable prefix (HRP). Please provide a either an account, validator or consensus address prefix (eg: cosmos, cosmosvaloper, cosmosvalcons)") +} + +func Test_GetGasStabilityPoolBalance(t *testing.T) { + /* + Configuration + */ + + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, ctx, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + // Create contract and get ABI. + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + // Test GetGasStabilityPoolBalance method. // Only check the function is called correctly inside the contract, and it returns the expected error. // Configuring a local environment for this contract would require deploying system contracts and gas pools. // This method is tested thoroughly in the e2e tests. - methodID = abi.Methods[GetGasStabilityPoolBalanceName] - args = make([]interface{}, 0) + methodID := abi.Methods[GetGasStabilityPoolBalanceName] + args := make([]interface{}, 0) args = append(args, int64(1337)) - rawBytes, err = contract.GetGasStabilityPoolBalance(ctx, &methodID, args) + _, err := contract.GetGasStabilityPoolBalance(ctx, &methodID, args) require.Error( t, err, "error calling fungible keeper: failed to get system contract variable: state variable not found", ) + + // Test for invalid number of arguments. + args = append(args, "second argument") + _, err = contract.GetGasStabilityPoolBalance(ctx, &methodID, args) + require.Error(t, err, "expected invalid number of arguments; expected 2; got: 3") + require.IsType(t, &types.ErrInvalidNumberOfArgs{}, err, "expected error type: ErrInvalidNumberOfArgs, got: %T", err) + + // Test for invalid chainID. + argsInvalid := make([]interface{}, 0) + argsInvalid = append(argsInvalid, "foobar") + _, errInvalid := contract.GetGasStabilityPoolBalance(ctx, &methodID, argsInvalid) + require.Error(t, errInvalid, "expected int64, got: %T", argsInvalid[0]) + require.IsType(t, types.ErrInvalidArgument{}, errInvalid, "expected error type: ErrInvalidArgument, got: %T", errInvalid) } + +func Test_InvalidMethod(t *testing.T) { + /* + Configuration + */ + + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, _, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + // Create contract and get ABI. + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + // Test for non existent method. + _, doNotExist := abi.Methods["invalidMethod"] + require.False(t, doNotExist, "invalidMethod should not be present in the ABI") +} \ No newline at end of file From d2bcc798bcec9b2beea9633dde2f6fe83cf8b46f Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 18:07:15 +0200 Subject: [PATCH 28/33] add keys for new user_precompile --- cmd/zetae2e/config/localnet.yml | 105 ++++++++++++++++---------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index eb6ba8fbb9..b77e112ef5 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -1,71 +1,74 @@ -zeta_chain_id: "athens_101-1" +zeta_chain_id: 'athens_101-1' default_account: - bech32_address: "zeta1uhznv7uzyjq84s3q056suc8pkme85lkvhrz3dd" - evm_address: "0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC" - private_key: "d87baf7bf6dc560a252596678c12e41f7d1682837f05b29d411bc3f78ae2c263" + bech32_address: 'zeta1uhznv7uzyjq84s3q056suc8pkme85lkvhrz3dd' + evm_address: '0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC' + private_key: 'd87baf7bf6dc560a252596678c12e41f7d1682837f05b29d411bc3f78ae2c263' additional_accounts: user_erc20: - bech32_address: "zeta1datate7xmwm4uk032f9rmcu0cwy7ch7kg6y6zv" - evm_address: "0x6F57D5E7c6DBb75e59F1524a3dE38Fc389ec5Fd6" - private_key: "fda3be1b1517bdf48615bdadacc1e6463d2865868dc8077d2cdcfa4709a16894" + bech32_address: 'zeta1datate7xmwm4uk032f9rmcu0cwy7ch7kg6y6zv' + evm_address: '0x6F57D5E7c6DBb75e59F1524a3dE38Fc389ec5Fd6' + private_key: 'fda3be1b1517bdf48615bdadacc1e6463d2865868dc8077d2cdcfa4709a16894' user_zeta_test: - bech32_address: "zeta1tnp0hvsq4y5mxuhrq9h3jfwulxywpq0ads0rer" - evm_address: "0x5cC2fBb200A929B372e3016F1925DcF988E081fd" - private_key: "729a6cdc5c925242e7df92fdeeb94dadbf2d0b9950d4db8f034ab27a3b114ba7" + bech32_address: 'zeta1tnp0hvsq4y5mxuhrq9h3jfwulxywpq0ads0rer' + evm_address: '0x5cC2fBb200A929B372e3016F1925DcF988E081fd' + private_key: '729a6cdc5c925242e7df92fdeeb94dadbf2d0b9950d4db8f034ab27a3b114ba7' user_zevm_mp_test: - bech32_address: "zeta13t3zjxvwec7g38q8mdjga37rpes9zkfvv7tkn2" - evm_address: "0x8Ae229198eCE3c889C07DB648Ec7C30E6051592c" - private_key: "105460aebf71b10bfdb710ef5aa6d2932ee6ff6fc317ac9c24e0979903b10a5d" + bech32_address: 'zeta13t3zjxvwec7g38q8mdjga37rpes9zkfvv7tkn2' + evm_address: '0x8Ae229198eCE3c889C07DB648Ec7C30E6051592c' + private_key: '105460aebf71b10bfdb710ef5aa6d2932ee6ff6fc317ac9c24e0979903b10a5d' user_bitcoin: - bech32_address: "zeta19q7czqysah6qg0n4y3l2a08gfzqxydla492v80" - evm_address: "0x283d810090EdF4043E75247eAeBcE848806237fD" - private_key: "7bb523963ee2c78570fb6113d886a4184d42565e8847f1cb639f5f5e2ef5b37a" + bech32_address: 'zeta19q7czqysah6qg0n4y3l2a08gfzqxydla492v80' + evm_address: '0x283d810090EdF4043E75247eAeBcE848806237fD' + private_key: '7bb523963ee2c78570fb6113d886a4184d42565e8847f1cb639f5f5e2ef5b37a' user_solana: - bech32_address: "zeta1zqlajgj0qr8rqylf2c572t0ux8vqt45d4zngpm" - evm_address: "0x103FD9224F00ce3013e95629e52DFc31D805D68d" - private_key: "dd53f191113d18e57bd4a5494a64a020ba7919c815d0a6d34a42ebb2839e9d95" - solana_private_key: "4yqSQxDeTBvn86BuxcN5jmZb2gaobFXrBqu8kiE9rZxNkVMe3LfXmFigRsU4sRp7vk4vVP1ZCFiejDKiXBNWvs2C" + bech32_address: 'zeta1zqlajgj0qr8rqylf2c572t0ux8vqt45d4zngpm' + evm_address: '0x103FD9224F00ce3013e95629e52DFc31D805D68d' + private_key: 'dd53f191113d18e57bd4a5494a64a020ba7919c815d0a6d34a42ebb2839e9d95' + solana_private_key: '4yqSQxDeTBvn86BuxcN5jmZb2gaobFXrBqu8kiE9rZxNkVMe3LfXmFigRsU4sRp7vk4vVP1ZCFiejDKiXBNWvs2C' user_ether: - bech32_address: "zeta134rakuus43xn63yucgxhn88ywj8ewcv6ezn2ga" - evm_address: "0x8D47Db7390AC4D3D449Cc20D799ce4748F97619A" - private_key: "098e74a1c2261fa3c1b8cfca8ef2b4ff96c73ce36710d208d1f6535aef42545d" + bech32_address: 'zeta134rakuus43xn63yucgxhn88ywj8ewcv6ezn2ga' + evm_address: '0x8D47Db7390AC4D3D449Cc20D799ce4748F97619A' + private_key: '098e74a1c2261fa3c1b8cfca8ef2b4ff96c73ce36710d208d1f6535aef42545d' user_misc: - bech32_address: "zeta1jqfx6qhyrj0t9ggvl3p64vaax3s9y0xldt020w" - evm_address: "0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf" - private_key: "853c0945b8035a501b1161df65a17a0a20fc848bda8975a8b4e9222cc6f84cd4" + bech32_address: 'zeta1jqfx6qhyrj0t9ggvl3p64vaax3s9y0xldt020w' + evm_address: '0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf' + private_key: '853c0945b8035a501b1161df65a17a0a20fc848bda8975a8b4e9222cc6f84cd4' user_admin: - bech32_address: "zeta17w0adeg64ky0daxwd2ugyuneellmjgnx4e483s" - evm_address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - private_key: "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + bech32_address: 'zeta17w0adeg64ky0daxwd2ugyuneellmjgnx4e483s' + evm_address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' + private_key: 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' user_migration: - bech32_address: "zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz" - evm_address: "0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD" - private_key: "0bcc2fa28b526f90e1d54648d612db901e860bf68248555593f91ea801c6b482" + bech32_address: 'zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz' + evm_address: '0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD' + private_key: '0bcc2fa28b526f90e1d54648d612db901e860bf68248555593f91ea801c6b482' + user_precompile: + bech32_address: 'zeta1k4f0l2e9qqjccxnstwj0uaarxvn44lj990she9' + evm_address: '0xb552FFAb2500258C1A705Ba4Fe77A333275AFE45' + private_key: 'bd6b74387f11b31d21e87c2ae7a23ec269aee08a355dad6c508a6fceb79d1f48' policy_accounts: emergency_policy_account: - bech32_address: "zeta16m2cnrdwtgweq4njc6t470vl325gw4kp6s7tap" - evm_address: "0xd6d5898dAE5A1D905672c6975F3d9f8aA88756C1" - private_key: "88BE93D11624B794F4BCC77BEA7385AF7EAD0B183B913485C74F0A803ABBC3F0" + bech32_address: 'zeta16m2cnrdwtgweq4njc6t470vl325gw4kp6s7tap' + evm_address: '0xd6d5898dAE5A1D905672c6975F3d9f8aA88756C1' + private_key: '88BE93D11624B794F4BCC77BEA7385AF7EAD0B183B913485C74F0A803ABBC3F0' operational_policy_account: - bech32_address: "zeta1pgx85vzx4fzh5zzyjqgs6a6cmaujd0xs8efrkc" - evm_address: "0x0A0c7a3046AA457A084490110d7758Df7926bcd0" - private_key: "59D1B982BD446545A1740ABD01F1ED9C162B72ACC1522B9B71B6DB5A9C37FA7D" + bech32_address: 'zeta1pgx85vzx4fzh5zzyjqgs6a6cmaujd0xs8efrkc' + evm_address: '0x0A0c7a3046AA457A084490110d7758Df7926bcd0' + private_key: '59D1B982BD446545A1740ABD01F1ED9C162B72ACC1522B9B71B6DB5A9C37FA7D' admin_policy_account: - bech32_address: "zeta142ds9x7raljv2qz9euys93e64gjmgdfnc47dwq" - evm_address: "0xAa9b029BC3EFe4c50045Cf0902c73aAa25b43533" - private_key: "0595CB0CD9BF5264A85A603EC8E43C30ADBB5FD2D9E2EF84C374EA4A65BB616C" + bech32_address: 'zeta142ds9x7raljv2qz9euys93e64gjmgdfnc47dwq' + evm_address: '0xAa9b029BC3EFe4c50045Cf0902c73aAa25b43533' + private_key: '0595CB0CD9BF5264A85A603EC8E43C30ADBB5FD2D9E2EF84C374EA4A65BB616C' rpcs: - zevm: "http://zetacore0:8545" - evm: "http://eth:8545" + zevm: 'http://zetacore0:8545' + evm: 'http://eth:8545' bitcoin: - host: "bitcoin:18443" - user: "smoketest" - pass: "123" + host: 'bitcoin:18443' + user: 'smoketest' + pass: '123' http_post_mode: true disable_tls: true params: regnet - solana: "http://solana:8899" - zetacore_grpc: "zetacore0:9090" - zetacore_rpc: "http://zetacore0:26657" - -# contracts will be populated on first run \ No newline at end of file + solana: 'http://solana:8899' + zetacore_grpc: 'zetacore0:9090' + zetacore_rpc: 'http://zetacore0:26657' +# contracts will be populated on first run From adbc0a64e07d3217f06dc6d3ed025e70810c4e69 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 18:34:37 +0200 Subject: [PATCH 29/33] add init unit test --- precompiles/prototype/prototype.go | 4 ++++ precompiles/prototype/prototype_test.go | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index dde0711af8..5a19e1373f 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -33,6 +33,10 @@ var ( ) func init() { + initABI() +} + +func initABI() { if prototypeABI == "" { panic("missing prototype ABI") } diff --git a/precompiles/prototype/prototype_test.go b/precompiles/prototype/prototype_test.go index 4f5e2e735b..a97fc01e3b 100644 --- a/precompiles/prototype/prototype_test.go +++ b/precompiles/prototype/prototype_test.go @@ -1,6 +1,7 @@ package prototype import ( + "encoding/json" "testing" storetypes "github.com/cosmos/cosmos-sdk/store/types" @@ -277,4 +278,26 @@ func Test_InvalidMethod(t *testing.T) { // Test for non existent method. _, doNotExist := abi.Methods["invalidMethod"] require.False(t, doNotExist, "invalidMethod should not be present in the ABI") +} + +func Test_MissingABI(t *testing.T) { + prototypeABI = "" + defer func() { + if r := recover(); r != nil { + require.Equal(t, "missing prototype ABI", r, "expected error: missing ABI, got: %v", r) + } + }() + + initABI() +} + +func Test_InvalidABI(t *testing.T) { + prototypeABI = "invalid json" + defer func() { + if r := recover(); r != nil { + require.IsType(t, &json.SyntaxError{}, r, "expected error type: json.SyntaxError, got: %T", r) + } + }() + + initABI() } \ No newline at end of file From de401aae7e69d40f72dbdba87a506dbd4029de3b Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 20:59:36 +0200 Subject: [PATCH 30/33] switch to double quotes --- cmd/zetae2e/config/localnet.yml | 104 ++++++++++++++++---------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index b77e112ef5..220fb15255 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -1,74 +1,74 @@ -zeta_chain_id: 'athens_101-1' +zeta_chain_id: "athens_101-1" default_account: - bech32_address: 'zeta1uhznv7uzyjq84s3q056suc8pkme85lkvhrz3dd' - evm_address: '0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC' - private_key: 'd87baf7bf6dc560a252596678c12e41f7d1682837f05b29d411bc3f78ae2c263' + bech32_address: "zeta1uhznv7uzyjq84s3q056suc8pkme85lkvhrz3dd" + evm_address: "0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC" + private_key: "d87baf7bf6dc560a252596678c12e41f7d1682837f05b29d411bc3f78ae2c263" additional_accounts: user_erc20: - bech32_address: 'zeta1datate7xmwm4uk032f9rmcu0cwy7ch7kg6y6zv' - evm_address: '0x6F57D5E7c6DBb75e59F1524a3dE38Fc389ec5Fd6' - private_key: 'fda3be1b1517bdf48615bdadacc1e6463d2865868dc8077d2cdcfa4709a16894' + bech32_address: "zeta1datate7xmwm4uk032f9rmcu0cwy7ch7kg6y6zv" + evm_address: "0x6F57D5E7c6DBb75e59F1524a3dE38Fc389ec5Fd6" + private_key: "fda3be1b1517bdf48615bdadacc1e6463d2865868dc8077d2cdcfa4709a16894" user_zeta_test: - bech32_address: 'zeta1tnp0hvsq4y5mxuhrq9h3jfwulxywpq0ads0rer' - evm_address: '0x5cC2fBb200A929B372e3016F1925DcF988E081fd' - private_key: '729a6cdc5c925242e7df92fdeeb94dadbf2d0b9950d4db8f034ab27a3b114ba7' + bech32_address: "zeta1tnp0hvsq4y5mxuhrq9h3jfwulxywpq0ads0rer" + evm_address: "0x5cC2fBb200A929B372e3016F1925DcF988E081fd" + private_key: "729a6cdc5c925242e7df92fdeeb94dadbf2d0b9950d4db8f034ab27a3b114ba7" user_zevm_mp_test: - bech32_address: 'zeta13t3zjxvwec7g38q8mdjga37rpes9zkfvv7tkn2' - evm_address: '0x8Ae229198eCE3c889C07DB648Ec7C30E6051592c' - private_key: '105460aebf71b10bfdb710ef5aa6d2932ee6ff6fc317ac9c24e0979903b10a5d' + bech32_address: "zeta13t3zjxvwec7g38q8mdjga37rpes9zkfvv7tkn2" + evm_address: "0x8Ae229198eCE3c889C07DB648Ec7C30E6051592c" + private_key: "105460aebf71b10bfdb710ef5aa6d2932ee6ff6fc317ac9c24e0979903b10a5d" user_bitcoin: - bech32_address: 'zeta19q7czqysah6qg0n4y3l2a08gfzqxydla492v80' - evm_address: '0x283d810090EdF4043E75247eAeBcE848806237fD' - private_key: '7bb523963ee2c78570fb6113d886a4184d42565e8847f1cb639f5f5e2ef5b37a' + bech32_address: "zeta19q7czqysah6qg0n4y3l2a08gfzqxydla492v80" + evm_address: "0x283d810090EdF4043E75247eAeBcE848806237fD" + private_key: "7bb523963ee2c78570fb6113d886a4184d42565e8847f1cb639f5f5e2ef5b37a" user_solana: - bech32_address: 'zeta1zqlajgj0qr8rqylf2c572t0ux8vqt45d4zngpm' - evm_address: '0x103FD9224F00ce3013e95629e52DFc31D805D68d' - private_key: 'dd53f191113d18e57bd4a5494a64a020ba7919c815d0a6d34a42ebb2839e9d95' - solana_private_key: '4yqSQxDeTBvn86BuxcN5jmZb2gaobFXrBqu8kiE9rZxNkVMe3LfXmFigRsU4sRp7vk4vVP1ZCFiejDKiXBNWvs2C' + bech32_address: "zeta1zqlajgj0qr8rqylf2c572t0ux8vqt45d4zngpm" + evm_address: "0x103FD9224F00ce3013e95629e52DFc31D805D68d" + private_key: "dd53f191113d18e57bd4a5494a64a020ba7919c815d0a6d34a42ebb2839e9d95" + solana_private_key: "4yqSQxDeTBvn86BuxcN5jmZb2gaobFXrBqu8kiE9rZxNkVMe3LfXmFigRsU4sRp7vk4vVP1ZCFiejDKiXBNWvs2C" user_ether: - bech32_address: 'zeta134rakuus43xn63yucgxhn88ywj8ewcv6ezn2ga' - evm_address: '0x8D47Db7390AC4D3D449Cc20D799ce4748F97619A' - private_key: '098e74a1c2261fa3c1b8cfca8ef2b4ff96c73ce36710d208d1f6535aef42545d' + bech32_address: "zeta134rakuus43xn63yucgxhn88ywj8ewcv6ezn2ga" + evm_address: "0x8D47Db7390AC4D3D449Cc20D799ce4748F97619A" + private_key: "098e74a1c2261fa3c1b8cfca8ef2b4ff96c73ce36710d208d1f6535aef42545d" user_misc: - bech32_address: 'zeta1jqfx6qhyrj0t9ggvl3p64vaax3s9y0xldt020w' - evm_address: '0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf' - private_key: '853c0945b8035a501b1161df65a17a0a20fc848bda8975a8b4e9222cc6f84cd4' + bech32_address: "zeta1jqfx6qhyrj0t9ggvl3p64vaax3s9y0xldt020w" + evm_address: "0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf" + private_key: "853c0945b8035a501b1161df65a17a0a20fc848bda8975a8b4e9222cc6f84cd4" user_admin: - bech32_address: 'zeta17w0adeg64ky0daxwd2ugyuneellmjgnx4e483s' - evm_address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' - private_key: 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' + bech32_address: "zeta17w0adeg64ky0daxwd2ugyuneellmjgnx4e483s" + evm_address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + private_key: "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" user_migration: - bech32_address: 'zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz' - evm_address: '0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD' - private_key: '0bcc2fa28b526f90e1d54648d612db901e860bf68248555593f91ea801c6b482' + bech32_address: "zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz" + evm_address: "0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD" + private_key: "0bcc2fa28b526f90e1d54648d612db901e860bf68248555593f91ea801c6b482" user_precompile: - bech32_address: 'zeta1k4f0l2e9qqjccxnstwj0uaarxvn44lj990she9' - evm_address: '0xb552FFAb2500258C1A705Ba4Fe77A333275AFE45' - private_key: 'bd6b74387f11b31d21e87c2ae7a23ec269aee08a355dad6c508a6fceb79d1f48' + bech32_address: "zeta1k4f0l2e9qqjccxnstwj0uaarxvn44lj990she9" + evm_address: "0xb552FFAb2500258C1A705Ba4Fe77A333275AFE45" + private_key: "bd6b74387f11b31d21e87c2ae7a23ec269aee08a355dad6c508a6fceb79d1f48" policy_accounts: emergency_policy_account: - bech32_address: 'zeta16m2cnrdwtgweq4njc6t470vl325gw4kp6s7tap' - evm_address: '0xd6d5898dAE5A1D905672c6975F3d9f8aA88756C1' - private_key: '88BE93D11624B794F4BCC77BEA7385AF7EAD0B183B913485C74F0A803ABBC3F0' + bech32_address: "zeta16m2cnrdwtgweq4njc6t470vl325gw4kp6s7tap" + evm_address: "0xd6d5898dAE5A1D905672c6975F3d9f8aA88756C1" + private_key: "88BE93D11624B794F4BCC77BEA7385AF7EAD0B183B913485C74F0A803ABBC3F0" operational_policy_account: - bech32_address: 'zeta1pgx85vzx4fzh5zzyjqgs6a6cmaujd0xs8efrkc' - evm_address: '0x0A0c7a3046AA457A084490110d7758Df7926bcd0' - private_key: '59D1B982BD446545A1740ABD01F1ED9C162B72ACC1522B9B71B6DB5A9C37FA7D' + bech32_address: "zeta1pgx85vzx4fzh5zzyjqgs6a6cmaujd0xs8efrkc" + evm_address: "0x0A0c7a3046AA457A084490110d7758Df7926bcd0" + private_key: "59D1B982BD446545A1740ABD01F1ED9C162B72ACC1522B9B71B6DB5A9C37FA7D" admin_policy_account: - bech32_address: 'zeta142ds9x7raljv2qz9euys93e64gjmgdfnc47dwq' - evm_address: '0xAa9b029BC3EFe4c50045Cf0902c73aAa25b43533' - private_key: '0595CB0CD9BF5264A85A603EC8E43C30ADBB5FD2D9E2EF84C374EA4A65BB616C' + bech32_address: "zeta142ds9x7raljv2qz9euys93e64gjmgdfnc47dwq" + evm_address: "0xAa9b029BC3EFe4c50045Cf0902c73aAa25b43533" + private_key: "0595CB0CD9BF5264A85A603EC8E43C30ADBB5FD2D9E2EF84C374EA4A65BB616C" rpcs: - zevm: 'http://zetacore0:8545' - evm: 'http://eth:8545' + zevm: "http://zetacore0:8545" + evm: "http://eth:8545" bitcoin: - host: 'bitcoin:18443' - user: 'smoketest' - pass: '123' + host: "bitcoin:18443" + user: "smoketest" + pass: "123" http_post_mode: true disable_tls: true params: regnet - solana: 'http://solana:8899' - zetacore_grpc: 'zetacore0:9090' - zetacore_rpc: 'http://zetacore0:26657' + solana: "http://solana:8899" + zetacore_grpc: "zetacore0:9090" + zetacore_rpc: "http://zetacore0:26657" # contracts will be populated on first run From f49ac43f44ff15cff9bd9bc4f3f7286f564380f2 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 21:22:45 +0200 Subject: [PATCH 31/33] avoid go:embed --- precompiles/prototype/prototype.go | 14 ++------------ precompiles/prototype/prototype_test.go | 15 ++------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index 5a19e1373f..801e6bde52 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -9,7 +9,6 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" @@ -27,9 +26,6 @@ var ( ABI abi.ABI ContractAddress = common.HexToAddress("0x0000000000000000000000000000000000000065") GasRequiredByMethod = map[[4]byte]uint64{} - - //go:embed IPrototype.abi - prototypeABI string ) func init() { @@ -37,14 +33,6 @@ func init() { } func initABI() { - if prototypeABI == "" { - panic("missing prototype ABI") - } - - var IPrototypeMetaData = &bind.MetaData{ - ABI: prototypeABI, - } - if err := ABI.UnmarshalJSON([]byte(IPrototypeMetaData.ABI)); err != nil { panic(err) } @@ -60,6 +48,8 @@ func initABI() { GasRequiredByMethod[methodID] = 10000 case GetGasStabilityPoolBalanceName: GasRequiredByMethod[methodID] = 10000 + default: + GasRequiredByMethod[methodID] = 0 } } } diff --git a/precompiles/prototype/prototype_test.go b/precompiles/prototype/prototype_test.go index a97fc01e3b..8b64562c80 100644 --- a/precompiles/prototype/prototype_test.go +++ b/precompiles/prototype/prototype_test.go @@ -280,19 +280,8 @@ func Test_InvalidMethod(t *testing.T) { require.False(t, doNotExist, "invalidMethod should not be present in the ABI") } -func Test_MissingABI(t *testing.T) { - prototypeABI = "" - defer func() { - if r := recover(); r != nil { - require.Equal(t, "missing prototype ABI", r, "expected error: missing ABI, got: %v", r) - } - }() - - initABI() -} - func Test_InvalidABI(t *testing.T) { - prototypeABI = "invalid json" + IPrototypeMetaData.ABI = "invalid json" defer func() { if r := recover(); r != nil { require.IsType(t, &json.SyntaxError{}, r, "expected error type: json.SyntaxError, got: %T", r) @@ -300,4 +289,4 @@ func Test_InvalidABI(t *testing.T) { }() initABI() -} \ No newline at end of file +} From ac48e294762b2c62573ba564b4b1cc8dc5656269 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Tue, 20 Aug 2024 22:34:01 +0200 Subject: [PATCH 32/33] fixes derived from code review --- cmd/zetae2e/local/precompiles.go | 2 +- e2e/e2etests/test_precompiles_prototype.go | 5 ++++- precompiles/prototype/prototype.go | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmd/zetae2e/local/precompiles.go b/cmd/zetae2e/local/precompiles.go index bf1fe25257..55372431e6 100644 --- a/cmd/zetae2e/local/precompiles.go +++ b/cmd/zetae2e/local/precompiles.go @@ -11,7 +11,7 @@ import ( "github.com/zeta-chain/zetacore/e2e/runner" ) -// erc20TestRoutine runs erc20 related e2e tests +// statefulPrecompilesTestRoutine runs steateful precompiles related e2e tests func statefulPrecompilesTestRoutine( conf config.Config, deployerRunner *runner.E2ERunner, diff --git a/e2e/e2etests/test_precompiles_prototype.go b/e2e/e2etests/test_precompiles_prototype.go index d881d434a7..a78a20385f 100644 --- a/e2e/e2etests/test_precompiles_prototype.go +++ b/e2e/e2etests/test_precompiles_prototype.go @@ -27,7 +27,10 @@ func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { "Failed to validate Bech32ToHexAddr result", ) - balance, err := iPrototype.GetGasStabilityPoolBalance(nil, int64(1337)) + chainID, err := r.EVMClient.ChainID(r.Ctx) + require.NoError(r, err, "Error retrieving ChainID") + + balance, err := iPrototype.GetGasStabilityPoolBalance(nil, chainID.Int64()) require.NoError(r, err, "Error calling GetGasStabilityPoolBalance") require.NotNil(r, balance, "GetGasStabilityPoolBalance returned balance is nil") } diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index 801e6bde52..a0747631e1 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -1,7 +1,6 @@ package prototype import ( - _ "embed" "fmt" "strings" From 9cbc2749b940bb7d6c441a178cec64b67e7ce782 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Wed, 21 Aug 2024 12:30:18 +0200 Subject: [PATCH 33/33] refactor some parts of bech32 functions --- precompiles/prototype/prototype.go | 25 +++++++---- precompiles/prototype/prototype_test.go | 59 ++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 14 deletions(-) diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go index a0747631e1..930095f32f 100644 --- a/precompiles/prototype/prototype.go +++ b/precompiles/prototype/prototype.go @@ -102,6 +102,7 @@ func (c *Contract) RequiredGas(input []byte) uint64 { return 0 } +// Bech32ToHexAddr converts a bech32 address to a hex address. func (c *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 1 { return nil, &ptypes.ErrInvalidNumberOfArgs{ @@ -110,17 +111,24 @@ func (c *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]by } } - address, ok := args[0].(string) - if !ok || address == "" { - return nil, fmt.Errorf("invalid bech32 address: %v", args[0]) + bech32String, ok := args[0].(string) + if !ok { + return nil, fmt.Errorf("invalid argument, wanted a string, got: %T", args[0]) + } + + bech32String = strings.TrimSpace(bech32String) + if bech32String == "" { + return nil, fmt.Errorf("invalid bech32 address: %s", bech32String) } - bech32Prefix := strings.SplitN(address, "1", 2)[0] - if bech32Prefix == address { - return nil, fmt.Errorf("invalid bech32 address: %s", address) + // 1 is always the separator between the bech32 prefix and the bech32 data part. + // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 + bech32Prefix, bech32Data, found := strings.Cut(bech32String, "1") + if !found || bech32Data == "" || bech32Prefix == "" || bech32Prefix == bech32String { + return nil, fmt.Errorf("invalid bech32 address: %s", bech32String) } - addressBz, err := sdk.GetFromBech32(address, bech32Prefix) + addressBz, err := sdk.GetFromBech32(bech32String, bech32Prefix) if err != nil { return nil, err } @@ -132,6 +140,7 @@ func (c *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]by return method.Outputs.Pack(common.BytesToAddress(addressBz)) } +// Bech32ify converts a hex address to a bech32 address. func (c *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, error) { if len(args) != 2 { return nil, &ptypes.ErrInvalidNumberOfArgs{ @@ -170,7 +179,7 @@ func (c *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, er return nil, err } - addressBz, err := sdk.GetFromBech32(bech32Str, "zeta") + addressBz, err := sdk.GetFromBech32(bech32Str, prefix) if err != nil { return nil, err } diff --git a/precompiles/prototype/prototype_test.go b/precompiles/prototype/prototype_test.go index 8b64562c80..3c0d88b642 100644 --- a/precompiles/prototype/prototype_test.go +++ b/precompiles/prototype/prototype_test.go @@ -135,6 +135,26 @@ func Test_Bech32ToHexAddress(t *testing.T) { addr, ) + // Test Bech32HexAddr method. Should fail with invalid argument type.. + args[0] = 1 + rawBytes, err = contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected invalid argument; wanted string; got: %T", args[0]) + + // Test Bech32HexAddr method. Should fail because it's not a valid bech32 address. + args[0] = "foobar" + rawBytes, err = contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected error; invalid bech32 address") + + // Test Bech32HexAddr method. Should fail with invalid prefix. + args[0] = "foobar1" + rawBytes, err = contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected error; invalid bech32 addresss") + + // Test Bech32HexAddr method. Should fail with invalid prefix. + args[0] = "foobar1foobar" + rawBytes, err = contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected error; decoding bech32 failed") + // Test Bech32HexAddr method. Should fail with invalid number of arguments. args = append(args, "second argument") _, err = contract.Bech32ToHexAddr(&methodID, args) @@ -165,14 +185,14 @@ func Test_Bech32ify(t *testing.T) { abi := contract.Abi() require.NotNil(t, abi, "contract ABI should not be nil") - // Test Bech32ify method. + // Test Bech32ify method with a zeta HRP. methodID := abi.Methods[Bech32ifyMethodName] args := make([]interface{}, 0) args = append(args, "zeta") args = append(args, common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) rawBytes, err := contract.Bech32ify(&methodID, args) - require.NoError(t, err, "Bech32ify should not return an error") + require.NoError(t, err, "Bech32ify prefix zeta should not return an error") // Manually extract the address from the raw bytes. zetaAddr := string(rawBytes[64:107]) @@ -180,7 +200,21 @@ func Test_Bech32ify(t *testing.T) { t, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", string(zetaAddr), - "Bech32ify should return the correct address, got: %v", + "Bech32ify prefix zeta should return the correct address, got: %v", + zetaAddr, + ) + + // Test Bech32ify method with a cosmos HRP. + args[0] = "cosmos" + rawBytes, err = contract.Bech32ify(&methodID, args) + require.NoError(t, err, "Bech32ify prefix cosmos should not return an error") + + zetaAddr = string(rawBytes[64:107]) + require.Equal( + t, + "cosmos1h8duy2dltz9xz0qqhm5wvcnj02upy887lqaq", + string(zetaAddr), + "Bech32ify prefix cosmos should return the correct address, got: %v", zetaAddr, ) @@ -207,9 +241,16 @@ func Test_Bech32ify(t *testing.T) { // Test for invalid bech32 human readable prefix. argsInvalidEmptyPrefix := make([]interface{}, 0) argsInvalidEmptyPrefix = append(argsInvalidEmptyPrefix, "") - argsInvalidEmptyPrefix = append(argsInvalidEmptyPrefix, common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) + argsInvalidEmptyPrefix = append( + argsInvalidEmptyPrefix, + common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE"), + ) _, errInvalidEmptyPrefix := contract.Bech32ify(&methodID, argsInvalidEmptyPrefix) - require.Error(t, errInvalidEmptyPrefix, "expected error invalid bech32 human readable prefix (HRP). Please provide a either an account, validator or consensus address prefix (eg: cosmos, cosmosvaloper, cosmosvalcons)") + require.Error( + t, + errInvalidEmptyPrefix, + "expected error invalid bech32 human readable prefix (HRP). Please provide a either an account, validator or consensus address prefix (eg: cosmos, cosmosvaloper, cosmosvalcons)", + ) } func Test_GetGasStabilityPoolBalance(t *testing.T) { @@ -255,7 +296,13 @@ func Test_GetGasStabilityPoolBalance(t *testing.T) { argsInvalid = append(argsInvalid, "foobar") _, errInvalid := contract.GetGasStabilityPoolBalance(ctx, &methodID, argsInvalid) require.Error(t, errInvalid, "expected int64, got: %T", argsInvalid[0]) - require.IsType(t, types.ErrInvalidArgument{}, errInvalid, "expected error type: ErrInvalidArgument, got: %T", errInvalid) + require.IsType( + t, + types.ErrInvalidArgument{}, + errInvalid, + "expected error type: ErrInvalidArgument, got: %T", + errInvalid, + ) } func Test_InvalidMethod(t *testing.T) {