From 758c366def0670a96374e53fa539fcad5148657f Mon Sep 17 00:00:00 2001 From: kevinssgh <79858682+kevinssgh@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:10:37 -0400 Subject: [PATCH 1/8] fix: some data race warnings in zetaclient (#1100) * fixed some data race issues in zetaclient * refactored fix * cleanup extra spaces and comments. --- Makefile | 4 ++-- contrib/localnet/orchestrator/smoketest/main.go | 6 ++++-- zetaclient/broadcast.go | 10 ++++------ zetaclient/tss_signer.go | 1 + zetaclient/zetabridge.go | 6 +++++- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index ec328166c6..99f64d7951 100644 --- a/Makefile +++ b/Makefile @@ -82,8 +82,8 @@ build-testnet-ubuntu: go.sum install: go.sum @echo "--> Installing zetacored & zetaclientd" - @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetacored - @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetaclientd + @go install -race -mod=readonly $(BUILD_FLAGS) ./cmd/zetacored + @go install -race -mod=readonly $(BUILD_FLAGS) ./cmd/zetaclientd install-zetaclient: go.sum @echo "--> Installing zetaclientd" diff --git a/contrib/localnet/orchestrator/smoketest/main.go b/contrib/localnet/orchestrator/smoketest/main.go index 5608bfca90..c08b04d3ac 100644 --- a/contrib/localnet/orchestrator/smoketest/main.go +++ b/contrib/localnet/orchestrator/smoketest/main.go @@ -148,6 +148,9 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { bankClient := banktypes.NewQueryClient(grpcConn) observerClient := observertypes.NewQueryClient(grpcConn) + //Wait for Genesis + time.Sleep(20 * time.Second) + // initialize client to send messages to ZetaChain zetaTxServer, err := NewZetaTxServer( "http://zetacore0:26657", @@ -158,8 +161,7 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { panic(err) } - // Wait for Genesis and keygen to be completed. ~ height 30 - time.Sleep(20 * time.Second) + //Wait for keygen to be completed. ~ height 30 for { time.Sleep(5 * time.Second) response, err := cctxClient.LastZetaHeight(context.Background(), &crosschaintypes.QueryLastZetaHeightRequest{}) diff --git a/zetaclient/broadcast.go b/zetaclient/broadcast.go index a9c9c91b3c..70f1ce0739 100644 --- a/zetaclient/broadcast.go +++ b/zetaclient/broadcast.go @@ -13,7 +13,6 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" flag "github.com/spf13/pflag" rpchttp "github.com/tendermint/tendermint/rpc/client/http" - "github.com/zeta-chain/zetacore/app" ) // Broadcast Broadcasts tx to metachain. Returns txHash and error @@ -119,11 +118,10 @@ func (b *ZetaCoreBridge) GetContext() client.Context { ctx = ctx.WithFromAddress(addr) ctx = ctx.WithBroadcastMode("sync") - encodingConfig := app.MakeEncodingConfig() - ctx = ctx.WithCodec(encodingConfig.Codec) - ctx = ctx.WithInterfaceRegistry(encodingConfig.InterfaceRegistry) - ctx = ctx.WithTxConfig(encodingConfig.TxConfig) - ctx = ctx.WithLegacyAmino(encodingConfig.Amino) + ctx = ctx.WithCodec(b.encodingCfg.Codec) + ctx = ctx.WithInterfaceRegistry(b.encodingCfg.InterfaceRegistry) + ctx = ctx.WithTxConfig(b.encodingCfg.TxConfig) + ctx = ctx.WithLegacyAmino(b.encodingCfg.Amino) ctx = ctx.WithAccountRetriever(authtypes.AccountRetriever{}) remote := b.cfg.ChainRPC diff --git a/zetaclient/tss_signer.go b/zetaclient/tss_signer.go index d0e540017d..d171c74ff9 100644 --- a/zetaclient/tss_signer.go +++ b/zetaclient/tss_signer.go @@ -173,6 +173,7 @@ func (tss *TSS) SignBatch(digests [][]byte, height uint64, chain *common.Chain) digestBase64[i] = base64.StdEncoding.EncodeToString(digest) } keysignReq := keysign.NewRequest(tssPubkey, digestBase64, int64(height), nil, "0.14.0") + ksRes, err := tss.Server.KeySign(keysignReq) if err != nil { log.Warn().Err(err).Msg("keysign fail") diff --git a/zetaclient/zetabridge.go b/zetaclient/zetabridge.go index 64a7a565bd..6e4c625ec2 100644 --- a/zetaclient/zetabridge.go +++ b/zetaclient/zetabridge.go @@ -4,6 +4,8 @@ import ( "fmt" "time" + "github.com/cosmos/cosmos-sdk/simapp/params" + "github.com/zeta-chain/zetacore/common" "sync" @@ -32,6 +34,7 @@ import ( //"strconv" //"strings" + "github.com/zeta-chain/zetacore/app" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/config" @@ -46,6 +49,7 @@ type ZetaCoreBridge struct { grpcConn *grpc.ClientConn httpClient *retryablehttp.Client cfg config.ClientConfiguration + encodingCfg params.EncodingConfig keys *Keys broadcastLock *sync.RWMutex zetaChainID string @@ -92,6 +96,7 @@ func NewZetaCoreBridge(k *Keys, chainIP string, signerName string, chainID strin accountNumber: accountsMap, seqNumber: seqMap, cfg: cfg, + encodingCfg: app.MakeEncodingConfig(), keys: k, broadcastLock: &sync.RWMutex{}, lastOutTxReportTime: map[string]time.Time{}, @@ -194,7 +199,6 @@ func (b *ZetaCoreBridge) UpdateConfigFromCore(cfg *config.Config, init bool) err } cfg.UpdateCoreParams(keyGen, newChains, newEVMParams, newBTCParams, init, b.logger) - cfg.Keygen = *keyGen tss, err := b.GetCurrentTss() if err != nil { b.logger.Error().Err(err).Msg("Unable to fetch TSS from zetacore") From de85c7faa88d9ef49b4bf8336d2d0cf7fa25c30e Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Wed, 20 Sep 2023 16:58:55 +0200 Subject: [PATCH 2/8] fix(`rpc`): reduce Ethereum rpc API and improve websocket API (#1106) * disable debug and personal * disable eth not secure * goimports * set message limit * set limit to 32MB * Update rpc/websockets.go --------- Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> --- rpc/apis.go | 129 +++++++++--------- rpc/namespaces/ethereum/debug/api.go | 10 +- rpc/namespaces/ethereum/eth/api.go | 60 ++++---- rpc/namespaces/ethereum/eth/filters/api.go | 14 +- .../ethereum/eth/filters/filter_system.go | 16 +-- .../ethereum/eth/filters/filters.go | 12 +- rpc/namespaces/ethereum/miner/api.go | 3 - rpc/namespaces/ethereum/personal/api.go | 13 +- rpc/namespaces/ethereum/txpool/api.go | 4 +- rpc/namespaces/ethereum/web3/api.go | 3 +- rpc/websockets.go | 17 ++- 11 files changed, 127 insertions(+), 154 deletions(-) diff --git a/rpc/apis.go b/rpc/apis.go index 3256f42d77..da130ad0a1 100644 --- a/rpc/apis.go +++ b/rpc/apis.go @@ -20,21 +20,14 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server" - "github.com/ethereum/go-ethereum/rpc" - ethermint "github.com/evmos/ethermint/types" + rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" "github.com/zeta-chain/zetacore/rpc/backend" - "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/debug" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/eth" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/eth/filters" - "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/miner" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/net" - "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/personal" - "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/txpool" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/web3" - - rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" ) // RPC namespaces and API version @@ -47,8 +40,8 @@ const ( Web3Namespace = "web3" EthNamespace = "eth" - PersonalNamespace = "personal" NetNamespace = "net" + PersonalNamespace = "personal" TxPoolNamespace = "txpool" DebugNamespace = "debug" MinerNamespace = "miner" @@ -112,64 +105,66 @@ func init() { }, } }, - PersonalNamespace: func(ctx *server.Context, - clientCtx client.Context, - _ *rpcclient.WSClient, - allowUnprotectedTxs bool, - indexer ethermint.EVMTxIndexer, - ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) - return []rpc.API{ - { - Namespace: PersonalNamespace, - Version: apiVersion, - Service: personal.NewAPI(ctx.Logger, evmBackend), - Public: false, - }, - } - }, - TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { - return []rpc.API{ - { - Namespace: TxPoolNamespace, - Version: apiVersion, - Service: txpool.NewPublicAPI(ctx.Logger), - Public: true, - }, - } - }, - DebugNamespace: func(ctx *server.Context, - clientCtx client.Context, - _ *rpcclient.WSClient, - allowUnprotectedTxs bool, - indexer ethermint.EVMTxIndexer, - ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) - return []rpc.API{ - { - Namespace: DebugNamespace, - Version: apiVersion, - Service: debug.NewAPI(ctx, evmBackend), - Public: true, - }, - } - }, - MinerNamespace: func(ctx *server.Context, - clientCtx client.Context, - _ *rpcclient.WSClient, - allowUnprotectedTxs bool, - indexer ethermint.EVMTxIndexer, - ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) - return []rpc.API{ - { - Namespace: MinerNamespace, - Version: apiVersion, - Service: miner.NewPrivateAPI(ctx, evmBackend), - Public: false, - }, - } - }, + // Disabled + // NOTE: Public field of API is deprecated and defined only for compatibility. + //PersonalNamespace: func(ctx *server.Context, + // clientCtx client.Context, + // _ *rpcclient.WSClient, + // allowUnprotectedTxs bool, + // indexer ethermint.EVMTxIndexer, + //) []rpc.API { + // evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + // return []rpc.API{ + // { + // Namespace: PersonalNamespace, + // Version: apiVersion, + // Service: personal.NewAPI(ctx.Logger, evmBackend), + // Public: false, + // }, + // } + //}, + //TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { + // return []rpc.API{ + // { + // Namespace: TxPoolNamespace, + // Version: apiVersion, + // Service: txpool.NewPublicAPI(ctx.Logger), + // Public: true, + // }, + // } + //}, + //DebugNamespace: func(ctx *server.Context, + // clientCtx client.Context, + // _ *rpcclient.WSClient, + // allowUnprotectedTxs bool, + // indexer ethermint.EVMTxIndexer, + //) []rpc.API { + // evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + // return []rpc.API{ + // { + // Namespace: DebugNamespace, + // Version: apiVersion, + // Service: debug.NewAPI(ctx, evmBackend), + // Public: true, + // }, + // } + //}, + //MinerNamespace: func(ctx *server.Context, + // clientCtx client.Context, + // _ *rpcclient.WSClient, + // allowUnprotectedTxs bool, + // indexer ethermint.EVMTxIndexer, + //) []rpc.API { + // evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + // return []rpc.API{ + // { + // Namespace: MinerNamespace, + // Version: apiVersion, + // Service: miner.NewPrivateAPI(ctx, evmBackend), + // Public: false, + // }, + // } + //}, } } diff --git a/rpc/namespaces/ethereum/debug/api.go b/rpc/namespaces/ethereum/debug/api.go index 0620b67be0..94f771ab39 100644 --- a/rpc/namespaces/ethereum/debug/api.go +++ b/rpc/namespaces/ethereum/debug/api.go @@ -27,18 +27,14 @@ import ( "sync" "time" - "github.com/davecgh/go-spew/spew" - - evmtypes "github.com/evmos/ethermint/x/evm/types" - - stderrors "github.com/pkg/errors" - "github.com/cosmos/cosmos-sdk/server" - + "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/rlp" + evmtypes "github.com/evmos/ethermint/x/evm/types" + stderrors "github.com/pkg/errors" "github.com/tendermint/tendermint/libs/log" "github.com/zeta-chain/zetacore/rpc/backend" rpctypes "github.com/zeta-chain/zetacore/rpc/types" diff --git a/rpc/namespaces/ethereum/eth/api.go b/rpc/namespaces/ethereum/eth/api.go index d62ddbe18c..7d05848b91 100644 --- a/rpc/namespaces/ethereum/eth/api.go +++ b/rpc/namespaces/ethereum/eth/api.go @@ -18,20 +18,14 @@ package eth import ( "context" - "github.com/ethereum/go-ethereum/signer/core/apitypes" - - "github.com/ethereum/go-ethereum/rpc" - - "github.com/tendermint/tendermint/libs/log" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" - - "github.com/zeta-chain/zetacore/rpc/backend" - + "github.com/ethereum/go-ethereum/rpc" ethermint "github.com/evmos/ethermint/types" evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/tendermint/tendermint/libs/log" + "github.com/zeta-chain/zetacore/rpc/backend" rpctypes "github.com/zeta-chain/zetacore/rpc/types" ) @@ -67,7 +61,6 @@ type EthereumAPI interface { // Allows developers to both send ETH from one address to another, write data // on-chain, and interact with smart contracts. SendRawTransaction(data hexutil.Bytes) (common.Hash, error) - SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) // eth_sendPrivateTransaction // eth_cancel PrivateTransaction @@ -111,9 +104,7 @@ type EthereumAPI interface { // Other Syncing() (interface{}, error) Coinbase() (string, error) - Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) - SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) FillTransaction(args evmtypes.TransactionArgs) (*rpctypes.SignTransactionResult, error) Resend(ctx context.Context, args evmtypes.TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) @@ -125,6 +116,11 @@ type EthereumAPI interface { // eth_getWork (on Ethereum.org) // eth_submitWork (on Ethereum.org) // eth_submitHashrate (on Ethereum.org) + + // Disabled APIs for security reasons + //SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) + //Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) + //SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) } var _ EthereumAPI = (*PublicAPI)(nil) @@ -230,12 +226,6 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) return e.backend.SendRawTransaction(data) } -// SendTransaction sends an Ethereum transaction. -func (e *PublicAPI) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) { - e.logger.Debug("eth_sendTransaction", "args", args.String()) - return e.backend.SendTransaction(args) -} - /////////////////////////////////////////////////////////////////////////////// /// Account Information /// /////////////////////////////////////////////////////////////////////////////// @@ -416,12 +406,6 @@ func (e *PublicAPI) Coinbase() (string, error) { return ethAddr.Hex(), nil } -// Sign signs the provided data using the private key of address via Geth's signature standard. -func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { - e.logger.Debug("eth_sign", "address", address.Hex(), "data", common.Bytes2Hex(data)) - return e.backend.Sign(address, data) -} - // GetTransactionLogs returns the logs given a transaction hash. func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) { e.logger.Debug("eth_getTransactionLogs", "hash", txHash) @@ -448,12 +432,6 @@ func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, err return backend.TxLogsFromEvents(resBlockResult.TxsResults[res.TxIndex].Events, int(res.MsgIndex)) } -// SignTypedData signs EIP-712 conformant typed data -func (e *PublicAPI) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) { - e.logger.Debug("eth_signTypedData", "address", address.Hex(), "data", typedData) - return e.backend.SignTypedData(address, typedData) -} - // FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) // on a given unsigned transaction, and returns it to the caller for further // processing (signing + broadcast). @@ -527,3 +505,25 @@ func (e *PublicAPI) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) return result, nil } + +/////////////////////////////////////////////////////////////////////////////// +/// Disabled /// +/////////////////////////////////////////////////////////////////////////////// + +//// SendTransaction sends an Ethereum transaction. +//func (e *PublicAPI) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) { +// e.logger.Debug("eth_sendTransaction", "args", args.String()) +// return e.backend.SendTransaction(args) +//} +// +//// Sign signs the provided data using the private key of address via Geth's signature standard. +//func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { +// e.logger.Debug("eth_sign", "address", address.Hex(), "data", common.Bytes2Hex(data)) +// return e.backend.Sign(address, data) +//} +// +//// SignTypedData signs EIP-712 conformant typed data +//func (e *PublicAPI) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) { +// e.logger.Debug("eth_signTypedData", "address", address.Hex(), "data", typedData) +// return e.backend.SignTypedData(address, typedData) +//} diff --git a/rpc/namespaces/ethereum/eth/filters/api.go b/rpc/namespaces/ethereum/eth/filters/api.go index f6a9135a16..0268c7217d 100644 --- a/rpc/namespaces/ethereum/eth/filters/api.go +++ b/rpc/namespaces/ethereum/eth/filters/api.go @@ -22,20 +22,16 @@ import ( "time" "github.com/cosmos/cosmos-sdk/client" - "github.com/zeta-chain/zetacore/rpc/types" - - "github.com/tendermint/tendermint/libs/log" - - coretypes "github.com/tendermint/tendermint/rpc/core/types" - rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" - tmtypes "github.com/tendermint/tendermint/types" - "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/rpc" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/tendermint/tendermint/libs/log" + coretypes "github.com/tendermint/tendermint/rpc/core/types" + rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/zeta-chain/zetacore/rpc/types" ) // FilterAPI gathers diff --git a/rpc/namespaces/ethereum/eth/filters/filter_system.go b/rpc/namespaces/ethereum/eth/filters/filter_system.go index ac69cfc53d..ba203cf685 100644 --- a/rpc/namespaces/ethereum/eth/filters/filter_system.go +++ b/rpc/namespaces/ethereum/eth/filters/filter_system.go @@ -21,23 +21,19 @@ import ( "sync" "time" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/rpc" + evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" - tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/libs/log" tmquery "github.com/tendermint/tendermint/libs/pubsub/query" coretypes "github.com/tendermint/tendermint/rpc/core/types" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" tmtypes "github.com/tendermint/tendermint/types" - - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/filters" - "github.com/ethereum/go-ethereum/rpc" - - sdk "github.com/cosmos/cosmos-sdk/types" - - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/ethereum/pubsub" ) diff --git a/rpc/namespaces/ethereum/eth/filters/filters.go b/rpc/namespaces/ethereum/eth/filters/filters.go index 7bcb08fd75..4355182001 100644 --- a/rpc/namespaces/ethereum/eth/filters/filters.go +++ b/rpc/namespaces/ethereum/eth/filters/filters.go @@ -21,17 +21,15 @@ import ( "fmt" "math/big" - "github.com/zeta-chain/zetacore/rpc/backend" - "github.com/zeta-chain/zetacore/rpc/types" - - "github.com/pkg/errors" - "github.com/tendermint/tendermint/libs/log" - tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/filters" + "github.com/pkg/errors" + "github.com/tendermint/tendermint/libs/log" + tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/zeta-chain/zetacore/rpc/backend" + "github.com/zeta-chain/zetacore/rpc/types" ) // BloomIV represents the bit indexes and value inside the bloom filter that belong diff --git a/rpc/namespaces/ethereum/miner/api.go b/rpc/namespaces/ethereum/miner/api.go index 901c567a46..9d5e8fc556 100644 --- a/rpc/namespaces/ethereum/miner/api.go +++ b/rpc/namespaces/ethereum/miner/api.go @@ -17,12 +17,9 @@ package miner import ( "github.com/cosmos/cosmos-sdk/server" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/tendermint/tendermint/libs/log" - "github.com/zeta-chain/zetacore/rpc/backend" ) diff --git a/rpc/namespaces/ethereum/personal/api.go b/rpc/namespaces/ethereum/personal/api.go index 49b654c8dc..fa182c4759 100644 --- a/rpc/namespaces/ethereum/personal/api.go +++ b/rpc/namespaces/ethereum/personal/api.go @@ -21,22 +21,17 @@ import ( "os" "time" - "github.com/zeta-chain/zetacore/rpc/backend" - - "github.com/evmos/ethermint/crypto/hd" - ethermint "github.com/evmos/ethermint/types" - - "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" - + "github.com/evmos/ethermint/crypto/hd" + ethermint "github.com/evmos/ethermint/types" evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/tendermint/tendermint/libs/log" + "github.com/zeta-chain/zetacore/rpc/backend" ) // PrivateAccountAPI is the personal_ prefixed set of APIs in the Web3 JSON-RPC spec. diff --git a/rpc/namespaces/ethereum/txpool/api.go b/rpc/namespaces/ethereum/txpool/api.go index e8320b6655..89fb056bde 100644 --- a/rpc/namespaces/ethereum/txpool/api.go +++ b/rpc/namespaces/ethereum/txpool/api.go @@ -16,10 +16,8 @@ package txpool import ( - "github.com/tendermint/tendermint/libs/log" - "github.com/ethereum/go-ethereum/common/hexutil" - + "github.com/tendermint/tendermint/libs/log" "github.com/zeta-chain/zetacore/rpc/types" ) diff --git a/rpc/namespaces/ethereum/web3/api.go b/rpc/namespaces/ethereum/web3/api.go index 47f522785d..46e09d9637 100644 --- a/rpc/namespaces/ethereum/web3/api.go +++ b/rpc/namespaces/ethereum/web3/api.go @@ -19,10 +19,9 @@ import ( "fmt" "runtime" - "github.com/zeta-chain/zetacore/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" + "github.com/zeta-chain/zetacore/common" ) // PublicAPI is the web3_ prefixed set of APIs in the Web3 JSON-RPC spec. diff --git a/rpc/websockets.go b/rpc/websockets.go index c76a028ea3..ba0419efcc 100644 --- a/rpc/websockets.go +++ b/rpc/websockets.go @@ -27,27 +27,28 @@ import ( "sync" "github.com/cosmos/cosmos-sdk/client" - "github.com/gorilla/mux" - "github.com/gorilla/websocket" - "github.com/pkg/errors" - "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - + evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/gorilla/mux" + "github.com/gorilla/websocket" + "github.com/pkg/errors" "github.com/tendermint/tendermint/libs/log" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" tmtypes "github.com/tendermint/tendermint/types" - - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/ethereum/pubsub" rpcfilters "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/eth/filters" "github.com/zeta-chain/zetacore/rpc/types" "github.com/zeta-chain/zetacore/server/config" ) +const ( + messageSizeLimit = 32 * 1024 * 1024 // 32MB +) + type WebsocketsServer interface { Start() } @@ -139,6 +140,8 @@ func (s *websocketsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + conn.SetReadLimit(messageSizeLimit) + s.readLoop(&wsConn{ mux: new(sync.Mutex), conn: conn, From b896e3cb08ff3c88bede89149d3a28e1f866d2f8 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Wed, 20 Sep 2023 17:57:25 +0200 Subject: [PATCH 3/8] refactor: generic `Header` and `Proof` (#1145) * update proto * proto, remove pointers * add header type * fix zeta client * update message * move header to common * implement generic proof * refactor grpc * make mocks * fix zetaclient * goimports * fix lint * fix smoke test * change pointer proof --- common/common.pb.go | 990 ++++++++++++++++-- common/headers.go | 68 ++ common/proof.go | 61 ++ common/proof_test.go | 15 + .../smoketest/test_deposit_eth.go | 2 +- docs/openapi/openapi.swagger.yaml | 57 +- docs/spec/crosschain/messages.md | 13 +- docs/spec/observer/messages.md | 6 +- proto/common/common.proto | 23 +- proto/crosschain/tx.proto | 4 +- proto/observer/headers.proto | 15 - proto/observer/query.proto | 12 +- proto/observer/tx.proto | 5 +- testutil/keeper/mocks/crosschain/account.go | 2 +- testutil/keeper/mocks/crosschain/bank.go | 2 +- testutil/keeper/mocks/crosschain/fungible.go | 2 +- testutil/keeper/mocks/crosschain/observer.go | 12 +- testutil/keeper/mocks/crosschain/staking.go | 2 +- testutil/keeper/mocks/fungible/account.go | 2 +- testutil/keeper/mocks/fungible/bank.go | 2 +- testutil/keeper/mocks/fungible/evm.go | 2 +- testutil/keeper/mocks/fungible/observer.go | 2 +- x/crosschain/keeper/keeper_out_tx_tracker.go | 40 +- x/crosschain/types/expected_keepers.go | 2 +- .../types/message_add_to_out_tx_tracker.go | 12 +- x/crosschain/types/tx.pb.go | 193 ++-- ...keeper_block_header.go => block_header.go} | 22 +- x/observer/keeper/grpc_query_prove.go | 14 +- .../keeper/msg_server_add_block_header.go | 35 +- x/observer/types/errors.go | 41 +- x/observer/types/headers.pb.go | 500 --------- x/observer/types/messages_add_block_header.go | 60 +- x/observer/types/query.pb.go | 270 +++-- x/observer/types/tx.pb.go | 188 ++-- zetaclient/evm_client.go | 8 +- zetaclient/query.go | 3 +- zetaclient/tx.go | 6 +- 37 files changed, 1583 insertions(+), 1110 deletions(-) create mode 100644 common/headers.go create mode 100644 common/proof.go create mode 100644 common/proof_test.go delete mode 100644 proto/observer/headers.proto rename x/observer/keeper/{keeper_block_header.go => block_header.go} (80%) delete mode 100644 x/observer/types/headers.pb.go diff --git a/common/common.pb.go b/common/common.pb.go index 683a844041..4277cc8dc6 100644 --- a/common/common.pb.go +++ b/common/common.pb.go @@ -11,6 +11,7 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/gogo/protobuf/proto" + ethereum "github.com/zeta-chain/zetacore/common/ethereum" ) // Reference imports to suppress errors if they are not otherwise used. @@ -255,48 +256,284 @@ func (m *Chain) GetChainId() int64 { return 0 } +type BlockHeader struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` + Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + ParentHash []byte `protobuf:"bytes,3,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"` + ChainId int64 `protobuf:"varint,4,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // chain specific header + Header HeaderData `protobuf:"bytes,5,opt,name=header,proto3" json:"header"` +} + +func (m *BlockHeader) Reset() { *m = BlockHeader{} } +func (m *BlockHeader) String() string { return proto.CompactTextString(m) } +func (*BlockHeader) ProtoMessage() {} +func (*BlockHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_8f954d82c0b891f6, []int{2} +} +func (m *BlockHeader) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BlockHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BlockHeader.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *BlockHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockHeader.Merge(m, src) +} +func (m *BlockHeader) XXX_Size() int { + return m.Size() +} +func (m *BlockHeader) XXX_DiscardUnknown() { + xxx_messageInfo_BlockHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockHeader proto.InternalMessageInfo + +func (m *BlockHeader) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *BlockHeader) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +func (m *BlockHeader) GetParentHash() []byte { + if m != nil { + return m.ParentHash + } + return nil +} + +func (m *BlockHeader) GetChainId() int64 { + if m != nil { + return m.ChainId + } + return 0 +} + +func (m *BlockHeader) GetHeader() HeaderData { + if m != nil { + return m.Header + } + return HeaderData{} +} + +type HeaderData struct { + // Types that are valid to be assigned to Data: + // + // *HeaderData_EthereumHeader + Data isHeaderData_Data `protobuf_oneof:"data"` +} + +func (m *HeaderData) Reset() { *m = HeaderData{} } +func (m *HeaderData) String() string { return proto.CompactTextString(m) } +func (*HeaderData) ProtoMessage() {} +func (*HeaderData) Descriptor() ([]byte, []int) { + return fileDescriptor_8f954d82c0b891f6, []int{3} +} +func (m *HeaderData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeaderData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeaderData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HeaderData) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeaderData.Merge(m, src) +} +func (m *HeaderData) XXX_Size() int { + return m.Size() +} +func (m *HeaderData) XXX_DiscardUnknown() { + xxx_messageInfo_HeaderData.DiscardUnknown(m) +} + +var xxx_messageInfo_HeaderData proto.InternalMessageInfo + +type isHeaderData_Data interface { + isHeaderData_Data() + MarshalTo([]byte) (int, error) + Size() int +} + +type HeaderData_EthereumHeader struct { + EthereumHeader []byte `protobuf:"bytes,1,opt,name=ethereum_header,json=ethereumHeader,proto3,oneof" json:"ethereum_header,omitempty"` +} + +func (*HeaderData_EthereumHeader) isHeaderData_Data() {} + +func (m *HeaderData) GetData() isHeaderData_Data { + if m != nil { + return m.Data + } + return nil +} + +func (m *HeaderData) GetEthereumHeader() []byte { + if x, ok := m.GetData().(*HeaderData_EthereumHeader); ok { + return x.EthereumHeader + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*HeaderData) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*HeaderData_EthereumHeader)(nil), + } +} + +type Proof struct { + // Types that are valid to be assigned to Proof: + // + // *Proof_EthereumProof + Proof isProof_Proof `protobuf_oneof:"proof"` +} + +func (m *Proof) Reset() { *m = Proof{} } +func (m *Proof) String() string { return proto.CompactTextString(m) } +func (*Proof) ProtoMessage() {} +func (*Proof) Descriptor() ([]byte, []int) { + return fileDescriptor_8f954d82c0b891f6, []int{4} +} +func (m *Proof) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Proof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Proof.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Proof) XXX_Merge(src proto.Message) { + xxx_messageInfo_Proof.Merge(m, src) +} +func (m *Proof) XXX_Size() int { + return m.Size() +} +func (m *Proof) XXX_DiscardUnknown() { + xxx_messageInfo_Proof.DiscardUnknown(m) +} + +var xxx_messageInfo_Proof proto.InternalMessageInfo + +type isProof_Proof interface { + isProof_Proof() + MarshalTo([]byte) (int, error) + Size() int +} + +type Proof_EthereumProof struct { + EthereumProof *ethereum.Proof `protobuf:"bytes,1,opt,name=ethereum_proof,json=ethereumProof,proto3,oneof" json:"ethereum_proof,omitempty"` +} + +func (*Proof_EthereumProof) isProof_Proof() {} + +func (m *Proof) GetProof() isProof_Proof { + if m != nil { + return m.Proof + } + return nil +} + +func (m *Proof) GetEthereumProof() *ethereum.Proof { + if x, ok := m.GetProof().(*Proof_EthereumProof); ok { + return x.EthereumProof + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Proof) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Proof_EthereumProof)(nil), + } +} + func init() { proto.RegisterEnum("common.ReceiveStatus", ReceiveStatus_name, ReceiveStatus_value) proto.RegisterEnum("common.CoinType", CoinType_name, CoinType_value) proto.RegisterEnum("common.ChainName", ChainName_name, ChainName_value) proto.RegisterType((*PubKeySet)(nil), "common.PubKeySet") proto.RegisterType((*Chain)(nil), "common.Chain") + proto.RegisterType((*BlockHeader)(nil), "common.BlockHeader") + proto.RegisterType((*HeaderData)(nil), "common.HeaderData") + proto.RegisterType((*Proof)(nil), "common.Proof") } func init() { proto.RegisterFile("common/common.proto", fileDescriptor_8f954d82c0b891f6) } var fileDescriptor_8f954d82c0b891f6 = []byte{ - // 476 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x92, 0x41, 0x8b, 0xd3, 0x40, - 0x14, 0xc7, 0x93, 0x76, 0x9b, 0x34, 0xaf, 0x6b, 0x3b, 0xce, 0x0a, 0xae, 0x7b, 0xc8, 0xca, 0xa2, - 0x20, 0x0b, 0x6e, 0x77, 0x2b, 0x55, 0xc4, 0x83, 0xb0, 0x41, 0x45, 0x04, 0x91, 0x74, 0x4f, 0x7b, - 0x29, 0x93, 0xc9, 0x23, 0x09, 0x26, 0x99, 0x90, 0x4c, 0x84, 0xfa, 0x29, 0xfc, 0x0a, 0x82, 0x07, - 0x3f, 0x8a, 0xc7, 0x3d, 0x7a, 0x5a, 0xa4, 0xfd, 0x16, 0x9e, 0x64, 0x26, 0x4d, 0xea, 0x29, 0x6f, - 0x7e, 0xf3, 0x7b, 0xf3, 0xfe, 0x64, 0x06, 0x0e, 0xb8, 0xc8, 0x32, 0x91, 0x4f, 0x9b, 0xcf, 0x59, - 0x51, 0x0a, 0x29, 0xa8, 0xd5, 0xac, 0x8e, 0xee, 0x45, 0x22, 0x12, 0x1a, 0x4d, 0x55, 0xd5, 0xec, - 0x9e, 0xc4, 0xe0, 0x7c, 0xaa, 0x83, 0x0f, 0xb8, 0x5a, 0xa0, 0xa4, 0x73, 0x70, 0x2a, 0xe4, 0xc5, - 0x6c, 0xfe, 0xfc, 0xf3, 0xc5, 0xa1, 0xf9, 0xd0, 0x7c, 0xe2, 0x5c, 0xde, 0x5f, 0xdf, 0x1e, 0x3b, - 0x8b, 0x16, 0xfe, 0xbd, 0x3d, 0xb6, 0x1a, 0xdd, 0xdf, 0x99, 0xf4, 0x11, 0xd8, 0x18, 0xce, 0xe6, - 0xf3, 0x8b, 0x97, 0x87, 0x3d, 0xdd, 0x04, 0xff, 0x79, 0xed, 0xd6, 0xc9, 0x15, 0x0c, 0xbc, 0x98, - 0x25, 0x39, 0x3d, 0x07, 0xe0, 0xaa, 0x58, 0xe6, 0x2c, 0x43, 0x3d, 0x66, 0x3c, 0xbb, 0x7b, 0xb6, - 0xcd, 0xac, 0x95, 0x8f, 0x2c, 0x43, 0xdf, 0xe1, 0x6d, 0x49, 0x1f, 0xc0, 0xb0, 0xe9, 0x48, 0x42, - 0x3d, 0xa1, 0xef, 0xdb, 0x7a, 0xfd, 0x3e, 0x3c, 0x7d, 0x05, 0x77, 0x7c, 0xe4, 0x98, 0x7c, 0xc1, - 0x85, 0x64, 0xb2, 0xae, 0xe8, 0x08, 0x6c, 0xaf, 0x44, 0x26, 0x31, 0x24, 0x86, 0x5a, 0x2c, 0x6a, - 0xce, 0xb1, 0xaa, 0x88, 0x49, 0x01, 0xac, 0xb7, 0x2c, 0x49, 0x31, 0x24, 0xbd, 0xa3, 0xbd, 0x9f, - 0x3f, 0x5c, 0xf3, 0xf4, 0x05, 0x0c, 0x3d, 0x91, 0xe4, 0x57, 0xab, 0x02, 0xe9, 0x10, 0xf6, 0xae, - 0x51, 0x32, 0x62, 0x50, 0x1b, 0xfa, 0xef, 0x98, 0x6a, 0x70, 0x60, 0xf0, 0xc6, 0xf7, 0x66, 0xe7, - 0xa4, 0xa7, 0x98, 0x97, 0x85, 0xa4, 0xbf, 0x6d, 0xfc, 0xde, 0x03, 0xa7, 0x4b, 0xaa, 0x3c, 0xcc, - 0x0a, 0xb9, 0x22, 0x06, 0x9d, 0xc0, 0x08, 0x65, 0xbc, 0xcc, 0x58, 0x92, 0xe7, 0x28, 0x89, 0x49, - 0x09, 0xec, 0x7f, 0x45, 0xc9, 0x3a, 0xd2, 0x53, 0x4a, 0x20, 0x79, 0x07, 0xfa, 0xf4, 0x00, 0x26, - 0x85, 0x48, 0x57, 0x91, 0xc8, 0x3b, 0xb8, 0xa7, 0xad, 0x6a, 0x67, 0x0d, 0x28, 0x85, 0x71, 0x24, - 0xb0, 0x4c, 0x93, 0xa5, 0xc4, 0x4a, 0x2a, 0x66, 0x29, 0x96, 0xd5, 0x59, 0xc0, 0x76, 0xcc, 0x56, - 0xa7, 0x45, 0x2c, 0x67, 0x3c, 0xc6, 0x0e, 0x0e, 0x95, 0x18, 0x30, 0x11, 0xb0, 0xa0, 0x63, 0x4e, - 0x3b, 0xa1, 0x05, 0xd0, 0x45, 0x6d, 0xc9, 0xa8, 0x8d, 0xda, 0x82, 0x7d, 0x7d, 0x78, 0x13, 0x22, - 0x15, 0x9c, 0xa5, 0x0a, 0x8e, 0x5b, 0xab, 0xc4, 0x48, 0x89, 0x64, 0xd2, 0xfc, 0xa3, 0xcb, 0xd7, - 0xbf, 0xd6, 0xae, 0x79, 0xb3, 0x76, 0xcd, 0x3f, 0x6b, 0xd7, 0xfc, 0xb6, 0x71, 0x8d, 0x9b, 0x8d, - 0x6b, 0xfc, 0xde, 0xb8, 0xc6, 0xf5, 0xe3, 0x28, 0x91, 0x71, 0x1d, 0xa8, 0x2b, 0x9f, 0xaa, 0x89, - 0x4f, 0xf5, 0x65, 0xea, 0x92, 0x8b, 0x12, 0xb7, 0xcf, 0x37, 0xb0, 0xf4, 0x0b, 0x7d, 0xf6, 0x2f, - 0x00, 0x00, 0xff, 0xff, 0xba, 0x90, 0x73, 0x66, 0xd6, 0x02, 0x00, 0x00, + // 639 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x94, 0xcb, 0x6a, 0xdb, 0x4c, + 0x14, 0x80, 0x25, 0x5f, 0x64, 0xeb, 0xc8, 0xb1, 0xf5, 0x4f, 0x7e, 0xfe, 0x3f, 0xcd, 0x42, 0x0e, + 0xa6, 0x85, 0x34, 0xd0, 0x5c, 0x5c, 0xdc, 0x0b, 0x5d, 0x04, 0xec, 0x5e, 0xdc, 0x16, 0x4a, 0x90, + 0xb3, 0xca, 0xc6, 0x8c, 0xa4, 0x53, 0x49, 0xc4, 0xd2, 0x08, 0x69, 0x5c, 0x70, 0x9f, 0xa2, 0xaf, + 0x50, 0x28, 0xb4, 0x8f, 0x92, 0x65, 0x96, 0x5d, 0x85, 0xe2, 0xbc, 0x45, 0x57, 0x65, 0x46, 0x17, + 0xa7, 0x2b, 0x9f, 0xf9, 0xce, 0x77, 0x2e, 0xf2, 0xc8, 0x86, 0x6d, 0x97, 0x45, 0x11, 0x8b, 0x8f, + 0xf2, 0x8f, 0xc3, 0x24, 0x65, 0x9c, 0x11, 0x2d, 0x3f, 0xed, 0x5a, 0x45, 0x12, 0x79, 0x80, 0x29, + 0x2e, 0xa3, 0x2a, 0xc8, 0xbd, 0xdd, 0x7f, 0x7d, 0xe6, 0x33, 0x19, 0x1e, 0x89, 0x28, 0xa7, 0x83, + 0x00, 0xf4, 0xb3, 0xa5, 0xf3, 0x1e, 0x57, 0x33, 0xe4, 0x64, 0x04, 0x7a, 0x86, 0x6e, 0x32, 0x1c, + 0x3d, 0xb9, 0x3c, 0xd9, 0x51, 0xf7, 0xd4, 0x7d, 0x7d, 0xfc, 0xff, 0xfa, 0xa6, 0xaf, 0xcf, 0x4a, + 0xf8, 0xfb, 0xa6, 0xaf, 0xe5, 0xba, 0xbd, 0x31, 0xc9, 0x7d, 0x68, 0xa1, 0x37, 0x1c, 0x8d, 0x4e, + 0x9e, 0xef, 0xd4, 0x64, 0x11, 0xdc, 0xf1, 0xca, 0xd4, 0xe0, 0x1c, 0x9a, 0x93, 0x80, 0x86, 0x31, + 0x39, 0x06, 0x70, 0x45, 0x30, 0x8f, 0x69, 0x84, 0x72, 0x4c, 0x77, 0xf8, 0xcf, 0x61, 0xf1, 0x4c, + 0x52, 0xf9, 0x40, 0x23, 0xb4, 0x75, 0xb7, 0x0c, 0xc9, 0x3d, 0x68, 0xe7, 0x15, 0xa1, 0x27, 0x27, + 0xd4, 0xed, 0x96, 0x3c, 0xbf, 0xf5, 0x06, 0xdf, 0x55, 0x30, 0xc6, 0x0b, 0xe6, 0x5e, 0x4e, 0x91, + 0x7a, 0x98, 0x92, 0xff, 0x40, 0x0b, 0x30, 0xf4, 0x03, 0x2e, 0x1b, 0xd7, 0xed, 0xe2, 0x44, 0x08, + 0x34, 0x02, 0x9a, 0x05, 0xb2, 0xbc, 0x63, 0xcb, 0x98, 0xf4, 0xc1, 0x48, 0x68, 0x8a, 0x31, 0x9f, + 0xcb, 0x54, 0x5d, 0xa6, 0x20, 0x47, 0x53, 0x21, 0xdc, 0x9d, 0xdb, 0xf8, 0x6b, 0x2e, 0x39, 0x16, + 0x73, 0xc4, 0xc4, 0x9d, 0xe6, 0x9e, 0xba, 0x6f, 0x0c, 0x49, 0xf9, 0x00, 0xf9, 0x1e, 0x2f, 0x29, + 0xa7, 0xe3, 0xc6, 0xd5, 0x4d, 0x5f, 0xb1, 0x0b, 0x6f, 0x70, 0x0a, 0xb0, 0xc9, 0x91, 0x87, 0xd0, + 0x2b, 0xef, 0x67, 0x5e, 0x34, 0x12, 0x0b, 0x77, 0xa6, 0x8a, 0xdd, 0x2d, 0x13, 0xb9, 0x3e, 0xd6, + 0xa0, 0xe1, 0x51, 0x4e, 0x07, 0xef, 0xa0, 0x79, 0x96, 0x32, 0xf6, 0x91, 0x3c, 0x83, 0x4a, 0x99, + 0x27, 0x82, 0xc8, 0x52, 0x63, 0xd8, 0x3b, 0xac, 0xae, 0x5c, 0x8a, 0x53, 0xc5, 0xde, 0x2a, 0x89, + 0x04, 0xe3, 0x16, 0x34, 0x65, 0xc1, 0xc1, 0x0b, 0xd8, 0xb2, 0xd1, 0xc5, 0xf0, 0x13, 0xce, 0x38, + 0xe5, 0xcb, 0x8c, 0x18, 0xd0, 0x9a, 0xa4, 0x48, 0x39, 0x7a, 0xa6, 0x22, 0x0e, 0xb3, 0xa5, 0xeb, + 0x62, 0x96, 0x99, 0x2a, 0x01, 0xd0, 0x5e, 0xd3, 0x70, 0x81, 0x9e, 0x59, 0xdb, 0x6d, 0xfc, 0xf8, + 0x66, 0xa9, 0x07, 0x4f, 0xa1, 0x3d, 0x61, 0x61, 0x7c, 0xbe, 0x4a, 0x90, 0xb4, 0xa1, 0x71, 0x81, + 0x9c, 0x9a, 0x0a, 0x69, 0x41, 0xfd, 0x0d, 0x15, 0x05, 0x3a, 0x34, 0x5f, 0xd9, 0x93, 0xe1, 0xb1, + 0x59, 0x13, 0x6c, 0x12, 0x79, 0x66, 0xbd, 0x28, 0xfc, 0x5a, 0x03, 0xbd, 0xba, 0x60, 0xe1, 0x61, + 0x94, 0xf0, 0x95, 0xa9, 0x90, 0x1e, 0x18, 0xc8, 0x83, 0x79, 0x44, 0xc3, 0x38, 0x46, 0x6e, 0xaa, + 0xc4, 0x84, 0xce, 0x67, 0xe4, 0xb4, 0x22, 0x35, 0xa1, 0x38, 0xdc, 0xad, 0x40, 0x9d, 0x6c, 0x43, + 0x2f, 0x61, 0x8b, 0x95, 0xcf, 0xe2, 0x0a, 0x36, 0xa4, 0x95, 0x6d, 0xac, 0x26, 0x21, 0xd0, 0xf5, + 0x19, 0xa6, 0x8b, 0x70, 0xce, 0x31, 0xe3, 0x82, 0x69, 0x82, 0x45, 0xcb, 0xc8, 0xa1, 0x1b, 0xd6, + 0x12, 0xdd, 0x7c, 0x1a, 0x53, 0x37, 0xc0, 0x0a, 0xb6, 0x85, 0xe8, 0x50, 0xe6, 0x50, 0xa7, 0x62, + 0x7a, 0x39, 0xa1, 0x04, 0x50, 0xad, 0x5a, 0x12, 0xa3, 0x5c, 0xb5, 0x04, 0x1d, 0xd9, 0x3c, 0x5f, + 0x62, 0xc1, 0x5c, 0xba, 0x10, 0xb0, 0x5b, 0x5a, 0x29, 0xfa, 0x42, 0x34, 0x7b, 0xf9, 0x77, 0x34, + 0x3e, 0xbd, 0x5a, 0x5b, 0xea, 0xf5, 0xda, 0x52, 0x7f, 0xad, 0x2d, 0xf5, 0xcb, 0xad, 0xa5, 0x5c, + 0xdf, 0x5a, 0xca, 0xcf, 0x5b, 0x4b, 0xb9, 0x78, 0xe0, 0x87, 0x3c, 0x58, 0x3a, 0xe2, 0x45, 0x3b, + 0x12, 0x13, 0x1f, 0xc9, 0x77, 0x51, 0x86, 0x2e, 0x4b, 0xb1, 0xf8, 0x57, 0x70, 0x34, 0xf9, 0xc3, + 0x7e, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x3c, 0x8a, 0x97, 0x2d, 0x04, 0x00, 0x00, } func (m *PubKeySet) Marshal() (dAtA []byte, err error) { @@ -369,6 +606,164 @@ func (m *Chain) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *BlockHeader) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlockHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlockHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if m.ChainId != 0 { + i = encodeVarintCommon(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x20 + } + if len(m.ParentHash) > 0 { + i -= len(m.ParentHash) + copy(dAtA[i:], m.ParentHash) + i = encodeVarintCommon(dAtA, i, uint64(len(m.ParentHash))) + i-- + dAtA[i] = 0x1a + } + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintCommon(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0x12 + } + if m.Height != 0 { + i = encodeVarintCommon(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *HeaderData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HeaderData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeaderData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Data != nil { + { + size := m.Data.Size() + i -= size + if _, err := m.Data.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *HeaderData_EthereumHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeaderData_EthereumHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.EthereumHeader != nil { + i -= len(m.EthereumHeader) + copy(dAtA[i:], m.EthereumHeader) + i = encodeVarintCommon(dAtA, i, uint64(len(m.EthereumHeader))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *Proof) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Proof) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Proof) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Proof != nil { + { + size := m.Proof.Size() + i -= size + if _, err := m.Proof.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *Proof_EthereumProof) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Proof_EthereumProof) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.EthereumProof != nil { + { + size, err := m.EthereumProof.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} func encodeVarintCommon(dAtA []byte, offset int, v uint64) int { offset -= sovCommon(v) base := offset @@ -394,31 +789,307 @@ func (m *PubKeySet) Size() (n int) { if l > 0 { n += 1 + l + sovCommon(uint64(l)) } - return n -} + return n +} + +func (m *Chain) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChainName != 0 { + n += 1 + sovCommon(uint64(m.ChainName)) + } + if m.ChainId != 0 { + n += 1 + sovCommon(uint64(m.ChainId)) + } + return n +} + +func (m *BlockHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovCommon(uint64(m.Height)) + } + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + l = len(m.ParentHash) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + if m.ChainId != 0 { + n += 1 + sovCommon(uint64(m.ChainId)) + } + l = m.Header.Size() + n += 1 + l + sovCommon(uint64(l)) + return n +} + +func (m *HeaderData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Data != nil { + n += m.Data.Size() + } + return n +} + +func (m *HeaderData_EthereumHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EthereumHeader != nil { + l = len(m.EthereumHeader) + n += 1 + l + sovCommon(uint64(l)) + } + return n +} +func (m *Proof) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Proof != nil { + n += m.Proof.Size() + } + return n +} + +func (m *Proof_EthereumProof) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EthereumProof != nil { + l = m.EthereumProof.Size() + n += 1 + l + sovCommon(uint64(l)) + } + return n +} + +func sovCommon(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozCommon(x uint64) (n int) { + return sovCommon(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PubKeySet) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PubKeySet: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubKeySet: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Secp256k1", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Secp256k1 = PubKey(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ed25519", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ed25519 = PubKey(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Chain) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Chain: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Chain: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainName", wireType) + } + m.ChainName = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainName |= ChainName(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + m.ChainId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } -func (m *Chain) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ChainName != 0 { - n += 1 + sovCommon(uint64(m.ChainName)) - } - if m.ChainId != 0 { - n += 1 + sovCommon(uint64(m.ChainId)) + if iNdEx > l { + return io.ErrUnexpectedEOF } - return n -} - -func sovCommon(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozCommon(x uint64) (n int) { - return sovCommon(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + return nil } -func (m *PubKeySet) Unmarshal(dAtA []byte) error { +func (m *BlockHeader) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -441,17 +1112,36 @@ func (m *PubKeySet) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PubKeySet: wiretype end group for non-group") + return fmt.Errorf("proto: BlockHeader: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PubKeySet: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BlockHeader: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Secp256k1", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommon @@ -461,29 +1151,31 @@ func (m *PubKeySet) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthCommon } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthCommon } if postIndex > l { return io.ErrUnexpectedEOF } - m.Secp256k1 = PubKey(dAtA[iNdEx:postIndex]) + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ed25519", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ParentHash", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommon @@ -493,23 +1185,77 @@ func (m *PubKeySet) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthCommon } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthCommon } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ed25519 = PubKey(dAtA[iNdEx:postIndex]) + m.ParentHash = append(m.ParentHash[:0], dAtA[iNdEx:postIndex]...) + if m.ParentHash == nil { + m.ParentHash = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + m.ChainId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -532,7 +1278,7 @@ func (m *PubKeySet) Unmarshal(dAtA []byte) error { } return nil } -func (m *Chain) Unmarshal(dAtA []byte) error { +func (m *HeaderData) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -555,17 +1301,17 @@ func (m *Chain) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Chain: wiretype end group for non-group") + return fmt.Errorf("proto: HeaderData: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Chain: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HeaderData: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainName", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EthereumHeader", wireType) } - m.ChainName = 0 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommon @@ -575,16 +1321,80 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ChainName |= ChainName(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + if byteLen < 0 { + return ErrInvalidLengthCommon } - m.ChainId = 0 + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.Data = &HeaderData_EthereumHeader{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Proof) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Proof: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Proof: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EthereumProof", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommon @@ -594,11 +1404,27 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ChainId |= int64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := ðereum.Proof{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Proof = &Proof_EthereumProof{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommon(dAtA[iNdEx:]) diff --git a/common/headers.go b/common/headers.go new file mode 100644 index 0000000000..e05a3f0c18 --- /dev/null +++ b/common/headers.go @@ -0,0 +1,68 @@ +package common + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// NewEthereumHeader returns a new HeaderData containing an Ethereum header +func NewEthereumHeader(header []byte) HeaderData { + return HeaderData{ + Data: &HeaderData_EthereumHeader{ + EthereumHeader: header, + }, + } +} + +// ParentHash extracts the parent hash from the header +func (h HeaderData) ParentHash() ([]byte, error) { + switch data := h.Data.(type) { + case *HeaderData_EthereumHeader: + var header ethtypes.Header + if err := rlp.DecodeBytes(data.EthereumHeader, &header); err != nil { + return nil, err + } + return header.ParentHash.Bytes(), nil + default: + return nil, errors.New("unrecognized header type") + } +} + +// Validate performs a basic validation of the HeaderData +func (h HeaderData) Validate(blockHash []byte, height int64) error { + switch data := h.Data.(type) { + case *HeaderData_EthereumHeader: + return validateEthereumHeader(data.EthereumHeader, blockHash, height) + default: + return errors.New("unrecognized header type") + } +} + +// validateEthereumHeader performs a basic validation of the Ethereum header +func validateEthereumHeader(headerBytes []byte, blockHash []byte, height int64) error { + // on ethereum the block header is ~538 bytes in RLP encoding + if len(headerBytes) > 1024 { + return fmt.Errorf("header too long (%d)", len(headerBytes)) + } + + // RLP encoded block header + var header ethtypes.Header + if err := rlp.DecodeBytes(headerBytes, &header); err != nil { + return fmt.Errorf("cannot decode RLP (%s)", err) + } + if err := header.SanityCheck(); err != nil { + return fmt.Errorf("sanity check failed (%s)", err) + } + if bytes.Compare(blockHash, header.Hash().Bytes()) != 0 { + return fmt.Errorf("tx hash mismatch (%s) vs (%s)", hex.EncodeToString(blockHash), header.Hash().Hex()) + } + if height != header.Number.Int64() { + return fmt.Errorf("height mismatch (%d) vs (%d)", height, header.Number.Int64()) + } + return nil +} diff --git a/common/proof.go b/common/proof.go new file mode 100644 index 0000000000..615c39b1f5 --- /dev/null +++ b/common/proof.go @@ -0,0 +1,61 @@ +package common + +import ( + "errors" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/zeta-chain/zetacore/common/ethereum" +) + +// ErrInvalidProof is a error type for invalid proofs embedding the underlying error +type ErrInvalidProof struct { + Err error +} + +func NewErrInvalidProof(err error) ErrInvalidProof { + return ErrInvalidProof{ + Err: err, + } +} + +func (e ErrInvalidProof) Error() string { + return e.Err.Error() +} + +// IsErrorInvalidProof returns true if the error is an ErrInvalidProof +func IsErrorInvalidProof(err error) bool { + return errors.As(err, &ErrInvalidProof{}) +} + +// NewEthereumProof returns a new Proof containing an Ethereum proof +func NewEthereumProof(proof *ethereum.Proof) *Proof { + return &Proof{ + Proof: &Proof_EthereumProof{ + EthereumProof: proof, + }, + } +} + +// Verify verifies the proof against the header +func (p Proof) Verify(headerData HeaderData, txIndex int) ([]byte, error) { + switch proof := p.Proof.(type) { + case *Proof_EthereumProof: + ethHeaderBytes := headerData.GetEthereumHeader() + if ethHeaderBytes == nil { + return nil, errors.New("can't verify ethereum proof against non-ethereum header") + } + var ethHeader ethtypes.Header + err := rlp.DecodeBytes(ethHeaderBytes, ðHeader) + if err != nil { + return nil, err + } + val, err := proof.EthereumProof.Verify(ethHeader.TxHash, txIndex) + if err != nil { + return nil, NewErrInvalidProof(err) + } + return val, nil + default: + return nil, errors.New("unrecognized proof type") + } +} diff --git a/common/proof_test.go b/common/proof_test.go new file mode 100644 index 0000000000..0615407684 --- /dev/null +++ b/common/proof_test.go @@ -0,0 +1,15 @@ +package common_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" +) + +func Test_IsErrorInvalidProof(t *testing.T) { + require.False(t, common.IsErrorInvalidProof(nil)) + require.False(t, common.IsErrorInvalidProof(errors.New("foo"))) + require.True(t, common.IsErrorInvalidProof(common.NewErrInvalidProof(errors.New("foo")))) +} diff --git a/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go b/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go index e79b23feb5..cea789d273 100644 --- a/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go +++ b/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go @@ -123,7 +123,7 @@ func (sm *SmokeTest) TestDepositEtherIntoZRC20() { BlockHash: blockHash.Hex(), TxIndex: int64(txIndex), TxHash: txHash.Hex(), - Proof: txProof, + Proof: common.NewEthereumProof(txProof), ChainId: 0, }) if err != nil { diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 3294b7827a..50af221fae 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -27590,7 +27590,7 @@ paths: in: query required: false type: string - - name: proof.keys + - name: proof.ethereum_proof.keys in: query required: false type: array @@ -27598,7 +27598,7 @@ paths: type: string format: byte collectionFormat: multi - - name: proof.values + - name: proof.ethereum_proof.values in: query required: false type: array @@ -50182,6 +50182,24 @@ definitions: - VOTE_OPTION_ABSTAIN: VOTE_OPTION_ABSTAIN defines an abstain vote option. - VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option. - VOTE_OPTION_NO_WITH_VETO: VOTE_OPTION_NO_WITH_VETO defines a no with veto vote option. + commonBlockHeader: + type: object + properties: + height: + type: string + format: int64 + hash: + type: string + format: byte + parent_hash: + type: string + format: byte + chain_id: + type: string + format: int64 + header: + $ref: '#/definitions/commonHeaderData' + title: chain specific header commonChain: type: object properties: @@ -50227,6 +50245,18 @@ definitions: - Gas: Ether, BNB, Matic, Klay, BTC, etc - ERC20: ERC20 token - Cmd: not a real coin, rather a command + commonHeaderData: + type: object + properties: + ethereum_header: + type: string + format: byte + title: binary encoded headers; RLP for ethereum + commonProof: + type: object + properties: + ethereum_proof: + $ref: '#/definitions/ethereumProof' commonPubKeySet: type: object properties: @@ -50824,25 +50854,6 @@ definitions: items: type: object $ref: '#/definitions/observerNode' - observerBlockHeader: - type: object - properties: - header: - type: string - format: byte - title: binary encoded headers; RLP for ethereum - height: - type: string - format: int64 - hash: - type: string - format: byte - parentHash: - type: string - format: byte - chain_id: - type: string - format: int64 observerCoreParams: type: object properties: @@ -51022,7 +51033,7 @@ definitions: type: array items: type: object - $ref: '#/definitions/observerBlockHeader' + $ref: '#/definitions/commonBlockHeader' pagination: $ref: '#/definitions/v1beta1PageResponse' observerQueryAllNodeAccountResponse: @@ -51066,7 +51077,7 @@ definitions: type: object properties: block_header: - $ref: '#/definitions/observerBlockHeader' + $ref: '#/definitions/commonBlockHeader' observerQueryGetCoreParamsForChainResponse: type: object properties: diff --git a/docs/spec/crosschain/messages.md b/docs/spec/crosschain/messages.md index 21a3916c8d..a64c725032 100644 --- a/docs/spec/crosschain/messages.md +++ b/docs/spec/crosschain/messages.md @@ -2,10 +2,8 @@ ## MsgAddToOutTxTracker -Adds a new record to the outbound transaction tracker. - -Only the admin policy account and the observer validators are authorized to -broadcast this message. +AddToOutTxTracker adds a new record to the outbound transaction tracker. +only the admin policy account and the observer validators are authorized to broadcast this message. ```proto message MsgAddToOutTxTracker { @@ -13,7 +11,7 @@ message MsgAddToOutTxTracker { int64 chain_id = 2; uint64 nonce = 3; string tx_hash = 4; - ethereum.Proof proof = 5; + common.Proof proof = 5; string block_hash = 6; int64 tx_index = 7; } @@ -21,9 +19,8 @@ message MsgAddToOutTxTracker { ## MsgRemoveFromOutTxTracker -Removes a record from the outbound transaction tracker by chain ID and nonce. - -Only the admin policy account is authorized to broadcast this message. +RemoveFromOutTxTracker removes a record from the outbound transaction tracker by chain ID and nonce. +only the admin policy account is authorized to broadcast this message. ```proto message MsgRemoveFromOutTxTracker { diff --git a/docs/spec/observer/messages.md b/docs/spec/observer/messages.md index 4a34d7779b..2ae574f73a 100644 --- a/docs/spec/observer/messages.md +++ b/docs/spec/observer/messages.md @@ -72,15 +72,15 @@ message MsgUpdateKeygen { ## MsgAddBlockHeader -MsgAddBlockHeader handles adding a block header to the store, through majority voting of observers +AddBlockHeader handles adding a block header to the store, through majority voting of observers ```proto message MsgAddBlockHeader { string creator = 1; int64 chain_id = 2; bytes block_hash = 3; - bytes block_header = 4; - int64 height = 5; + int64 height = 4; + common.HeaderData header = 5; } ``` diff --git a/proto/common/common.proto b/proto/common/common.proto index 936d542bba..161f533034 100644 --- a/proto/common/common.proto +++ b/proto/common/common.proto @@ -1,10 +1,10 @@ syntax = "proto3"; package common; +import "common/ethereum/ethereum.proto"; //option (gogoproto.goproto_stringer_all) = false; //option (gogoproto.stringer_all) = false; //option (gogoproto.goproto_getters_all) = false; - import "gogoproto/gogo.proto"; option go_package = "github.com/zeta-chain/zetacore/common"; @@ -62,3 +62,24 @@ message Chain { ChainName chain_name = 1; int64 chain_id = 2; } + +message BlockHeader { + int64 height = 1; + bytes hash = 2; + bytes parent_hash = 3; + int64 chain_id = 4; + // chain specific header + HeaderData header = 5 [(gogoproto.nullable) = false]; +} + +message HeaderData { + oneof data { + bytes ethereum_header = 1; // binary encoded headers; RLP for ethereum + } +} + +message Proof { + oneof proof { + ethereum.Proof ethereum_proof = 1; + } +} diff --git a/proto/crosschain/tx.proto b/proto/crosschain/tx.proto index 033d2d83cd..417b899787 100644 --- a/proto/crosschain/tx.proto +++ b/proto/crosschain/tx.proto @@ -2,7 +2,6 @@ syntax = "proto3"; package zetachain.zetacore.crosschain; import "common/common.proto"; -import "common/ethereum/ethereum.proto"; import "gogoproto/gogo.proto"; option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types"; @@ -27,6 +26,7 @@ message MsgUpdateTssAddress { } message MsgUpdateTssAddressResponse {} + message MsgWhitelistERC20 { string creator = 1; string erc20_address = 2; @@ -44,7 +44,7 @@ message MsgAddToOutTxTracker { int64 chain_id = 2; uint64 nonce = 3; string tx_hash = 4; - ethereum.Proof proof = 5; + common.Proof proof = 5; string block_hash = 6; int64 tx_index = 7; } diff --git a/proto/observer/headers.proto b/proto/observer/headers.proto deleted file mode 100644 index af1544c4f7..0000000000 --- a/proto/observer/headers.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; -package zetachain.zetacore.observer; - -import "gogoproto/gogo.proto"; -import "observer/observer.proto"; - -option go_package = "github.com/zeta-chain/zetacore/x/observer/types"; - -message BlockHeader { - bytes header = 1; // binary encoded headers; RLP for ethereum - int64 height = 2; - bytes hash = 3; - bytes parentHash = 4; - int64 chain_id = 5; -} diff --git a/proto/observer/query.proto b/proto/observer/query.proto index a989c2c2a5..f210f5e84c 100644 --- a/proto/observer/query.proto +++ b/proto/observer/query.proto @@ -2,13 +2,11 @@ syntax = "proto3"; package zetachain.zetacore.observer; import "common/common.proto"; -import "common/ethereum/ethereum.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; import "observer/ballot.proto"; import "observer/blame.proto"; -import "observer/headers.proto"; import "observer/keygen.proto"; import "observer/node_account.proto"; import "observer/observer.proto"; @@ -99,9 +97,9 @@ service Query { message QueryProveRequest { uint64 chain_id = 1; string tx_hash = 2; - ethereum.Proof proof = 5; - string block_hash = 6; - int64 tx_index = 7; + common.Proof proof = 3; + string block_hash = 4; + int64 tx_index = 5; } message QueryProveResponse { @@ -218,7 +216,7 @@ message QueryAllBlockHeaderRequest { } message QueryAllBlockHeaderResponse { - repeated BlockHeader block_headers = 1; + repeated common.BlockHeader block_headers = 1; cosmos.base.query.v1beta1.PageResponse pagination = 2; } @@ -227,5 +225,5 @@ message QueryGetBlockHeaderByHashRequest { } message QueryGetBlockHeaderByHashResponse { - BlockHeader block_header = 1; + common.BlockHeader block_header = 1; } diff --git a/proto/observer/tx.proto b/proto/observer/tx.proto index 589030dc74..368af443b5 100644 --- a/proto/observer/tx.proto +++ b/proto/observer/tx.proto @@ -4,7 +4,6 @@ package zetachain.zetacore.observer; import "common/common.proto"; import "gogoproto/gogo.proto"; import "observer/blame.proto"; -import "observer/headers.proto"; import "observer/observer.proto"; import "observer/params.proto"; @@ -24,8 +23,8 @@ message MsgAddBlockHeader { string creator = 1; int64 chain_id = 2; bytes block_hash = 3; - bytes block_header = 4; - int64 height = 5; + int64 height = 4; + common.HeaderData header = 5 [(gogoproto.nullable) = false]; } message MsgAddBlockHeaderResponse {} diff --git a/testutil/keeper/mocks/crosschain/account.go b/testutil/keeper/mocks/crosschain/account.go index 9044c1009c..626900da83 100644 --- a/testutil/keeper/mocks/crosschain/account.go +++ b/testutil/keeper/mocks/crosschain/account.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/crosschain/bank.go b/testutil/keeper/mocks/crosschain/bank.go index 8fef8170d5..cdf1e371ef 100644 --- a/testutil/keeper/mocks/crosschain/bank.go +++ b/testutil/keeper/mocks/crosschain/bank.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/crosschain/fungible.go b/testutil/keeper/mocks/crosschain/fungible.go index 7b8b6884a3..ccd55ffa06 100644 --- a/testutil/keeper/mocks/crosschain/fungible.go +++ b/testutil/keeper/mocks/crosschain/fungible.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/crosschain/observer.go b/testutil/keeper/mocks/crosschain/observer.go index 252c36e1cf..5811d9ba4d 100644 --- a/testutil/keeper/mocks/crosschain/observer.go +++ b/testutil/keeper/mocks/crosschain/observer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -173,18 +173,18 @@ func (_m *CrosschainObserverKeeper) GetBallot(ctx types.Context, index string) ( } // GetBlockHeader provides a mock function with given fields: ctx, hash -func (_m *CrosschainObserverKeeper) GetBlockHeader(ctx types.Context, hash []byte) (observertypes.BlockHeader, bool) { +func (_m *CrosschainObserverKeeper) GetBlockHeader(ctx types.Context, hash []byte) (common.BlockHeader, bool) { ret := _m.Called(ctx, hash) - var r0 observertypes.BlockHeader + var r0 common.BlockHeader var r1 bool - if rf, ok := ret.Get(0).(func(types.Context, []byte) (observertypes.BlockHeader, bool)); ok { + if rf, ok := ret.Get(0).(func(types.Context, []byte) (common.BlockHeader, bool)); ok { return rf(ctx, hash) } - if rf, ok := ret.Get(0).(func(types.Context, []byte) observertypes.BlockHeader); ok { + if rf, ok := ret.Get(0).(func(types.Context, []byte) common.BlockHeader); ok { r0 = rf(ctx, hash) } else { - r0 = ret.Get(0).(observertypes.BlockHeader) + r0 = ret.Get(0).(common.BlockHeader) } if rf, ok := ret.Get(1).(func(types.Context, []byte) bool); ok { diff --git a/testutil/keeper/mocks/crosschain/staking.go b/testutil/keeper/mocks/crosschain/staking.go index f35ad1190d..3027f516b1 100644 --- a/testutil/keeper/mocks/crosschain/staking.go +++ b/testutil/keeper/mocks/crosschain/staking.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/fungible/account.go b/testutil/keeper/mocks/fungible/account.go index d94cae3a4f..8ca9535cad 100644 --- a/testutil/keeper/mocks/fungible/account.go +++ b/testutil/keeper/mocks/fungible/account.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/fungible/bank.go b/testutil/keeper/mocks/fungible/bank.go index 3d78731354..a061b091f4 100644 --- a/testutil/keeper/mocks/fungible/bank.go +++ b/testutil/keeper/mocks/fungible/bank.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/fungible/evm.go b/testutil/keeper/mocks/fungible/evm.go index 42e3917ec1..8f6884d536 100644 --- a/testutil/keeper/mocks/fungible/evm.go +++ b/testutil/keeper/mocks/fungible/evm.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/fungible/observer.go b/testutil/keeper/mocks/fungible/observer.go index 3dee529922..13f419d80a 100644 --- a/testutil/keeper/mocks/fungible/observer.go +++ b/testutil/keeper/mocks/fungible/observer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.2. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/x/crosschain/keeper/keeper_out_tx_tracker.go b/x/crosschain/keeper/keeper_out_tx_tracker.go index 75b6e9cd1d..f0ed81f469 100644 --- a/x/crosschain/keeper/keeper_out_tx_tracker.go +++ b/x/crosschain/keeper/keeper_out_tx_tracker.go @@ -5,15 +5,16 @@ import ( "fmt" "strings" + cosmoserrors "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" eth "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" + "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/crosschain/types" - zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -159,29 +160,27 @@ func (k Keeper) OutTxTracker(c context.Context, req *types.QueryGetOutTxTrackerR // Messages -// Adds a new record to the outbound transaction tracker. -// -// Only the admin policy account and the observer validators are authorized to -// broadcast this message. +// AddToOutTxTracker adds a new record to the outbound transaction tracker. +// only the admin policy account and the observer validators are authorized to broadcast this message. func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToOutTxTracker) (*types.MsgAddToOutTxTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.ChainId) if chain == nil { - return nil, zetaObserverTypes.ErrSupportedChains + return nil, observertypes.ErrSupportedChains } if msg.Proof == nil { // without proof, only certain accounts can send this message - adminPolicyAccount := k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_out_tx_tracker) + adminPolicyAccount := k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_out_tx_tracker) isAdmin := msg.Creator == adminPolicyAccount isObserver, err := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, chain) if err != nil { ctx.Logger().Error("Error while checking if the account is an observer", err) - return nil, sdkerrors.Wrap(zetaObserverTypes.ErrNotAuthorized, fmt.Sprintf("error IsAuthorized %s", msg.Creator)) + return nil, cosmoserrors.Wrap(observertypes.ErrNotAuthorized, fmt.Sprintf("error IsAuthorized %s", msg.Creator)) } // Sender needs to be either the admin policy account or an observer if !(isAdmin || isObserver) { - return nil, sdkerrors.Wrap(zetaObserverTypes.ErrNotAuthorized, fmt.Sprintf("Creator %s", msg.Creator)) + return nil, cosmoserrors.Wrap(observertypes.ErrNotAuthorized, fmt.Sprintf("Creator %s", msg.Creator)) } } @@ -190,14 +189,14 @@ func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToO blockHash := eth.HexToHash(msg.BlockHash) res, found := k.zetaObserverKeeper.GetBlockHeader(ctx, blockHash.Bytes()) if !found { - return nil, sdkerrors.Wrap(zetaObserverTypes.ErrBlockHeaderNotFound, fmt.Sprintf("block header not found %s", msg.BlockHash)) + return nil, cosmoserrors.Wrap(observertypes.ErrBlockHeaderNotFound, fmt.Sprintf("block header not found %s", msg.BlockHash)) } - var header ethtypes.Header - err := rlp.DecodeBytes(res.Header, &header) - if err != nil { + + // verify and process the proof + val, err := msg.Proof.Verify(res.Header, int(msg.TxIndex)) + if err != nil && !common.IsErrorInvalidProof(err) { return nil, err } - val, err := msg.Proof.Verify(header.TxHash, int(msg.TxIndex)) if err == nil { var txx ethtypes.Transaction err = txx.UnmarshalBinary(val) @@ -272,13 +271,12 @@ func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToO return &types.MsgAddToOutTxTrackerResponse{}, nil } -// Removes a record from the outbound transaction tracker by chain ID and nonce. -// -// Only the admin policy account is authorized to broadcast this message. +// RemoveFromOutTxTracker removes a record from the outbound transaction tracker by chain ID and nonce. +// only the admin policy account is authorized to broadcast this message. func (k msgServer) RemoveFromOutTxTracker(goCtx context.Context, msg *types.MsgRemoveFromOutTxTracker) (*types.MsgRemoveFromOutTxTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if msg.Creator != k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_out_tx_tracker) { - return &types.MsgRemoveFromOutTxTrackerResponse{}, zetaObserverTypes.ErrNotAuthorizedPolicy + if msg.Creator != k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_out_tx_tracker) { + return &types.MsgRemoveFromOutTxTrackerResponse{}, observertypes.ErrNotAuthorizedPolicy } k.RemoveOutTxTracker(ctx, msg.ChainId, msg.Nonce) diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index 53a540c927..f6f31365b2 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -66,7 +66,7 @@ type ZetaObserverKeeper interface { IsAuthorized(ctx sdk.Context, address string, chain *common.Chain) (bool, error) FindBallot(ctx sdk.Context, index string, chain *common.Chain, observationType zetaObserverTypes.ObservationType) (ballot zetaObserverTypes.Ballot, isNew bool, err error) AddBallotToList(ctx sdk.Context, ballot zetaObserverTypes.Ballot) - GetBlockHeader(ctx sdk.Context, hash []byte) (val zetaObserverTypes.BlockHeader, found bool) + GetBlockHeader(ctx sdk.Context, hash []byte) (val common.BlockHeader, found bool) } type FungibleKeeper interface { diff --git a/x/crosschain/types/message_add_to_out_tx_tracker.go b/x/crosschain/types/message_add_to_out_tx_tracker.go index dffccbb32b..06716762a1 100644 --- a/x/crosschain/types/message_add_to_out_tx_tracker.go +++ b/x/crosschain/types/message_add_to_out_tx_tracker.go @@ -3,14 +3,22 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/zeta-chain/zetacore/common/ethereum" + "github.com/zeta-chain/zetacore/common" ) const TypeMsgAddToOutTxTracker = "AddToTracker" var _ sdk.Msg = &MsgAddToOutTxTracker{} -func NewMsgAddToOutTxTracker(creator string, chain int64, nonce uint64, txHash string, proof *ethereum.Proof, blockHash string, txIndex int64) *MsgAddToOutTxTracker { +func NewMsgAddToOutTxTracker( + creator string, + chain int64, + nonce uint64, + txHash string, + proof *common.Proof, + blockHash string, + txIndex int64, +) *MsgAddToOutTxTracker { return &MsgAddToOutTxTracker{ Creator: creator, ChainId: chain, diff --git a/x/crosschain/types/tx.pb.go b/x/crosschain/types/tx.pb.go index a27cf5db9f..f255d88bc9 100644 --- a/x/crosschain/types/tx.pb.go +++ b/x/crosschain/types/tx.pb.go @@ -15,7 +15,6 @@ import ( grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" common "github.com/zeta-chain/zetacore/common" - ethereum "github.com/zeta-chain/zetacore/common/ethereum" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -249,13 +248,13 @@ func (m *MsgWhitelistERC20Response) XXX_DiscardUnknown() { var xxx_messageInfo_MsgWhitelistERC20Response proto.InternalMessageInfo type MsgAddToOutTxTracker struct { - Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` - ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - Nonce uint64 `protobuf:"varint,3,opt,name=nonce,proto3" json:"nonce,omitempty"` - TxHash string `protobuf:"bytes,4,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` - Proof *ethereum.Proof `protobuf:"bytes,5,opt,name=proof,proto3" json:"proof,omitempty"` - BlockHash string `protobuf:"bytes,6,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` - TxIndex int64 `protobuf:"varint,7,opt,name=tx_index,json=txIndex,proto3" json:"tx_index,omitempty"` + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + Nonce uint64 `protobuf:"varint,3,opt,name=nonce,proto3" json:"nonce,omitempty"` + TxHash string `protobuf:"bytes,4,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` + Proof *common.Proof `protobuf:"bytes,5,opt,name=proof,proto3" json:"proof,omitempty"` + BlockHash string `protobuf:"bytes,6,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + TxIndex int64 `protobuf:"varint,7,opt,name=tx_index,json=txIndex,proto3" json:"tx_index,omitempty"` } func (m *MsgAddToOutTxTracker) Reset() { *m = MsgAddToOutTxTracker{} } @@ -319,7 +318,7 @@ func (m *MsgAddToOutTxTracker) GetTxHash() string { return "" } -func (m *MsgAddToOutTxTracker) GetProof() *ethereum.Proof { +func (m *MsgAddToOutTxTracker) GetProof() *common.Proof { if m != nil { return m.Proof } @@ -1231,93 +1230,93 @@ func init() { func init() { proto.RegisterFile("crosschain/tx.proto", fileDescriptor_81d6d611190b7635) } var fileDescriptor_81d6d611190b7635 = []byte{ - // 1375 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xcf, 0x36, 0x89, 0x63, 0xbf, 0xc4, 0x69, 0x32, 0x49, 0x9b, 0xed, 0xa6, 0x75, 0xda, 0x2d, - 0x2d, 0x15, 0x6a, 0xec, 0xe2, 0x82, 0x28, 0x85, 0x03, 0x4d, 0x54, 0xd2, 0x50, 0x9c, 0x44, 0x1b, - 0x17, 0xa4, 0x5e, 0xac, 0xf5, 0xee, 0x64, 0xbd, 0x8a, 0x77, 0xc7, 0xda, 0x19, 0x47, 0x76, 0xc5, - 0x09, 0x89, 0x03, 0x37, 0x0e, 0x48, 0x20, 0xbe, 0x00, 0x5f, 0xa5, 0xdc, 0x2a, 0x4e, 0xfc, 0x91, - 0x2a, 0x68, 0xbe, 0x01, 0x9f, 0x00, 0xcd, 0x9f, 0xdd, 0x78, 0x9d, 0xd8, 0x4e, 0x82, 0x38, 0x79, - 0xde, 0x9b, 0xf7, 0xe7, 0xf7, 0xe6, 0xbd, 0x37, 0xf3, 0xd6, 0xb0, 0xe0, 0x44, 0x84, 0x52, 0xa7, - 0x61, 0xfb, 0x61, 0x89, 0x75, 0x8a, 0xad, 0x88, 0x30, 0x82, 0xae, 0xbd, 0xc0, 0xcc, 0x16, 0xbc, - 0xa2, 0x58, 0x91, 0x08, 0x17, 0x8f, 0xe4, 0x8c, 0x05, 0x87, 0x04, 0x01, 0x09, 0x4b, 0xf2, 0x47, - 0xea, 0x18, 0x05, 0xc5, 0xc4, 0xac, 0x81, 0x23, 0xdc, 0x0e, 0x92, 0x85, 0xda, 0x5f, 0xf4, 0x88, - 0x47, 0xc4, 0xb2, 0xc4, 0x57, 0x92, 0x6b, 0x6e, 0xc1, 0x42, 0x85, 0x7a, 0xcf, 0x5a, 0xae, 0xcd, - 0x70, 0x95, 0xd2, 0x47, 0xae, 0x1b, 0x61, 0x4a, 0x91, 0x0e, 0x53, 0x4e, 0x84, 0x6d, 0x46, 0x22, - 0x5d, 0xbb, 0xae, 0xdd, 0xc9, 0x59, 0x31, 0x89, 0xae, 0x01, 0x30, 0x4a, 0x6b, 0xad, 0x76, 0x7d, - 0x1f, 0x77, 0xf5, 0x0b, 0x62, 0x33, 0xc7, 0x28, 0xdd, 0x11, 0x0c, 0xf3, 0x1a, 0x2c, 0x9f, 0x60, - 0xcf, 0xc2, 0xb4, 0x45, 0x42, 0x8a, 0xcd, 0x5f, 0x35, 0x98, 0xaf, 0x50, 0xef, 0xcb, 0x86, 0xcf, - 0x70, 0xd3, 0xa7, 0xec, 0xb1, 0xb5, 0x5e, 0xbe, 0x37, 0xc4, 0xdb, 0x4d, 0xc8, 0xe3, 0xc8, 0x29, - 0xdf, 0xab, 0xd9, 0xd2, 0x90, 0x72, 0x38, 0x23, 0x98, 0x31, 0xd8, 0x2b, 0x90, 0x15, 0xe7, 0x52, - 0xf3, 0x5d, 0x7d, 0xfc, 0xba, 0x76, 0x67, 0xdc, 0x9a, 0x12, 0xf4, 0xa6, 0x8b, 0x10, 0x4c, 0x84, - 0x76, 0x80, 0xf5, 0x09, 0xa1, 0x26, 0xd6, 0xe8, 0x32, 0x64, 0x68, 0x37, 0xa8, 0x93, 0xa6, 0x3e, - 0x29, 0xb8, 0x8a, 0x42, 0x06, 0x64, 0x5d, 0xec, 0xf8, 0x81, 0xdd, 0xa4, 0x7a, 0xe6, 0xba, 0x76, - 0x27, 0x6f, 0x25, 0x34, 0x5a, 0x86, 0x9c, 0x67, 0xd3, 0x5a, 0xd3, 0x0f, 0x7c, 0xa6, 0x4f, 0x09, - 0x1f, 0x59, 0xcf, 0xa6, 0x9f, 0x73, 0xda, 0x5c, 0x86, 0x2b, 0xc7, 0x62, 0x4a, 0x22, 0xfe, 0x53, - 0x83, 0xc5, 0x0a, 0xf5, 0x1e, 0xb9, 0x6e, 0x95, 0x6c, 0xb7, 0x59, 0xb5, 0x53, 0x8d, 0x6c, 0x67, - 0x1f, 0x47, 0x43, 0x82, 0xee, 0x8d, 0xe7, 0x42, 0x3a, 0x9e, 0x45, 0x98, 0x0c, 0x49, 0xe8, 0x60, - 0x11, 0xe7, 0x84, 0x25, 0x09, 0xb4, 0x04, 0x53, 0xac, 0x53, 0x6b, 0xd8, 0xb4, 0xa1, 0x02, 0xcd, - 0xb0, 0xce, 0x13, 0x9b, 0x36, 0xd0, 0x2d, 0x98, 0x6c, 0x45, 0x84, 0xec, 0x89, 0x48, 0xa7, 0xcb, - 0x17, 0x8b, 0x49, 0x4d, 0xec, 0x70, 0xb6, 0x25, 0x77, 0x79, 0x4e, 0xeb, 0x4d, 0xe2, 0xec, 0x4b, - 0x13, 0x19, 0x99, 0x53, 0xc1, 0x11, 0x56, 0xae, 0x40, 0x96, 0x75, 0x6a, 0x7e, 0xe8, 0xe2, 0x8e, - 0x8a, 0x7d, 0x8a, 0x75, 0x36, 0x39, 0x69, 0x16, 0xe0, 0xea, 0x49, 0xc1, 0x25, 0xd1, 0xef, 0x89, - 0xa3, 0xb1, 0x70, 0x40, 0x0e, 0xf0, 0xa7, 0x11, 0x09, 0xfe, 0xa7, 0x13, 0x30, 0x6f, 0xc2, 0x8d, - 0x81, 0x7e, 0x12, 0x30, 0x3f, 0xcb, 0xe2, 0x5b, 0xe7, 0x4e, 0x70, 0x75, 0x77, 0xf7, 0x0b, 0xc2, - 0x86, 0xa2, 0x18, 0x5e, 0xea, 0xe8, 0x1d, 0x98, 0xdb, 0xc7, 0xdd, 0x0d, 0x1c, 0x3e, 0xc7, 0xcc, - 0x7e, 0x82, 0x7d, 0xaf, 0xc1, 0x54, 0xf9, 0x1d, 0xe3, 0xa3, 0x55, 0xc8, 0x50, 0x66, 0xb3, 0x36, - 0x15, 0x09, 0x9a, 0x2d, 0x5f, 0x2a, 0xaa, 0xde, 0xb5, 0xb0, 0x83, 0xfd, 0x03, 0xbc, 0x2b, 0x36, - 0x2d, 0x25, 0xa4, 0x2a, 0x2a, 0x0d, 0x34, 0x09, 0xe3, 0x47, 0x0d, 0xe6, 0x2a, 0xd4, 0xdb, 0xb0, - 0xe9, 0x4e, 0xe4, 0x3b, 0x78, 0x54, 0x14, 0xc3, 0xcf, 0xb2, 0xc5, 0x4d, 0xc4, 0x67, 0x29, 0x08, - 0x74, 0x03, 0x66, 0x64, 0x35, 0x84, 0xed, 0xa0, 0x8e, 0x23, 0x81, 0x78, 0xc2, 0x9a, 0x16, 0xbc, - 0x2d, 0xc1, 0x12, 0x2d, 0xd4, 0x6e, 0xb5, 0x9a, 0xdd, 0xa4, 0x85, 0x04, 0x65, 0x1a, 0xa0, 0xf7, - 0x23, 0x4b, 0x60, 0x3f, 0x87, 0x7c, 0x85, 0x7a, 0x5b, 0x3c, 0x5d, 0xff, 0x0d, 0xf2, 0x09, 0xe9, - 0x5f, 0x82, 0x4b, 0x29, 0xdb, 0x89, 0xd3, 0xdf, 0x27, 0xc5, 0x7d, 0xc4, 0x99, 0xdb, 0xe1, 0x76, - 0x9d, 0xe2, 0xe8, 0x00, 0xbb, 0xdb, 0x6d, 0x56, 0x27, 0xed, 0xd0, 0xad, 0x76, 0x86, 0x60, 0x58, - 0x86, 0x9c, 0xe3, 0xc4, 0x5d, 0x25, 0x73, 0x9f, 0xe5, 0x0c, 0xd1, 0x11, 0x45, 0x58, 0x20, 0xca, - 0x58, 0x8d, 0xf0, 0x52, 0x93, 0x62, 0xe3, 0x42, 0x6c, 0x9e, 0x1c, 0xf9, 0xa9, 0x4a, 0xf9, 0x8f, - 0xc1, 0xe8, 0x93, 0x97, 0xdd, 0x25, 0x8b, 0x46, 0x1e, 0xb0, 0x9e, 0x52, 0x5b, 0x3b, 0xda, 0x47, - 0xef, 0xc3, 0x52, 0x9f, 0x36, 0xbf, 0x8b, 0xda, 0x14, 0xbb, 0x3a, 0x08, 0xd5, 0xc5, 0x94, 0xea, - 0x86, 0x4d, 0x9f, 0x51, 0xec, 0xa2, 0x17, 0x60, 0xf6, 0xa9, 0xe1, 0xbd, 0x3d, 0xec, 0x30, 0xff, - 0x00, 0x0b, 0x03, 0x32, 0xf5, 0xd3, 0x1c, 0xf3, 0x5a, 0xf1, 0xe5, 0xeb, 0x95, 0xb1, 0x3f, 0x5e, - 0xaf, 0xdc, 0xf6, 0x7c, 0xd6, 0x68, 0xd7, 0x79, 0x75, 0x96, 0x1c, 0x42, 0x03, 0x42, 0xd5, 0xcf, - 0x2a, 0x75, 0xf7, 0x4b, 0xac, 0xdb, 0xc2, 0xb4, 0xb8, 0x19, 0x32, 0xab, 0x90, 0xf2, 0xf8, 0x38, - 0xb6, 0x1b, 0x67, 0x1e, 0x7d, 0x36, 0xc2, 0xb7, 0xbc, 0x48, 0x67, 0x04, 0xfa, 0xc1, 0xb6, 0xc4, - 0xf5, 0x8a, 0x08, 0xcc, 0x1e, 0xd8, 0xcd, 0x36, 0xae, 0x45, 0xb2, 0x57, 0x5c, 0x59, 0x74, 0x6b, - 0x4f, 0x14, 0xe6, 0xb7, 0x4f, 0x81, 0xf9, 0x99, 0x1f, 0xb2, 0x7f, 0x5e, 0xaf, 0x5c, 0xea, 0xda, - 0x41, 0xf3, 0xa1, 0x99, 0x36, 0x67, 0x5a, 0x79, 0xc1, 0x50, 0xad, 0xe8, 0xf6, 0x34, 0x6b, 0xe6, - 0x14, 0xcd, 0x8a, 0x56, 0x60, 0x5a, 0x86, 0x28, 0x6a, 0x54, 0xdd, 0x90, 0x20, 0x58, 0xeb, 0x9c, - 0x83, 0x6e, 0xc3, 0x45, 0x29, 0xc0, 0x6f, 0x13, 0x59, 0xbd, 0x59, 0x11, 0x79, 0x5e, 0xb0, 0xab, - 0x94, 0x8a, 0xca, 0x45, 0xab, 0x90, 0x73, 0x88, 0x1f, 0xd6, 0x38, 0x64, 0x3d, 0x27, 0x5c, 0xcf, - 0xc5, 0xae, 0xd7, 0x89, 0x1f, 0x56, 0xbb, 0x2d, 0x6c, 0x65, 0x1d, 0xb5, 0x32, 0x6f, 0xc1, 0xcd, - 0x21, 0xa5, 0x9d, 0xb4, 0xc0, 0xdf, 0xe3, 0x60, 0x1c, 0x93, 0xdb, 0x0c, 0x47, 0x77, 0x00, 0x6f, - 0x72, 0x1c, 0xba, 0x38, 0x52, 0xe5, 0xaf, 0x28, 0x1e, 0x8e, 0x5c, 0xd5, 0xfa, 0x5e, 0xdd, 0xbc, - 0x64, 0xaf, 0xab, 0x56, 0x35, 0x20, 0xab, 0x8e, 0x38, 0x52, 0xcf, 0x52, 0x42, 0xa3, 0x5b, 0x30, - 0x1b, 0xaf, 0xd5, 0xb1, 0x4d, 0x4a, 0x13, 0x31, 0x57, 0x9e, 0xdc, 0x06, 0x64, 0xec, 0x80, 0xb4, - 0x43, 0x26, 0x1f, 0xa5, 0xb5, 0xd2, 0x19, 0x53, 0x6e, 0x29, 0x75, 0x1e, 0x65, 0x80, 0x29, 0xb5, - 0x3d, 0x79, 0xf4, 0x39, 0x2b, 0x26, 0xd1, 0x55, 0x00, 0x7e, 0xe4, 0xaa, 0x83, 0x73, 0x12, 0xa7, - 0x1f, 0xaa, 0xc6, 0xbd, 0x0d, 0x17, 0xfd, 0xb0, 0xa6, 0x1e, 0x47, 0xd9, 0xad, 0xb2, 0xe5, 0xf2, - 0x7e, 0xd8, 0xdb, 0xa2, 0xa9, 0xf9, 0x60, 0x5a, 0x48, 0x24, 0xf3, 0x41, 0x3a, 0xaf, 0x33, 0xa3, - 0xf2, 0xca, 0x6d, 0xb1, 0x4e, 0x8d, 0x44, 0xbe, 0xe7, 0x87, 0x7a, 0x5e, 0x02, 0x62, 0x9d, 0x6d, - 0x41, 0xf3, 0xfb, 0xcf, 0xa6, 0x14, 0x33, 0x7d, 0x56, 0x6c, 0x48, 0xc2, 0x7c, 0x0b, 0xcc, 0xc1, - 0x29, 0x4e, 0x2a, 0xe1, 0x5b, 0x0d, 0x66, 0x2b, 0xd4, 0xdb, 0xc5, 0x6c, 0x8b, 0xb8, 0xf8, 0x29, - 0xee, 0x0e, 0x9b, 0xf3, 0x4a, 0x90, 0x93, 0x0f, 0xdf, 0x2e, 0x66, 0xa2, 0x00, 0xa6, 0xcb, 0xf3, - 0x31, 0xe8, 0x9d, 0x76, 0xfd, 0xa9, 0xd8, 0xb0, 0x8e, 0x64, 0xd0, 0x5d, 0x40, 0xbc, 0xbe, 0xa9, - 0xef, 0x85, 0x38, 0xaa, 0xa9, 0xd9, 0x4c, 0x5d, 0x89, 0x73, 0x8c, 0xd2, 0x5d, 0xb1, 0xa1, 0xf8, - 0xa6, 0x0e, 0x97, 0xd3, 0x50, 0x62, 0x94, 0xe5, 0x5f, 0x72, 0x30, 0x5e, 0xa1, 0x1e, 0xfa, 0x46, - 0x83, 0xf9, 0xe3, 0x53, 0xd3, 0xfd, 0xe2, 0xd0, 0xd1, 0xb8, 0x78, 0xd2, 0x34, 0x62, 0x7c, 0x74, - 0x0e, 0xa5, 0x18, 0x0f, 0xfa, 0x5e, 0x83, 0xcb, 0x03, 0x06, 0x98, 0x07, 0xa3, 0xed, 0x9e, 0xac, - 0x69, 0x7c, 0x72, 0x5e, 0xcd, 0x04, 0xd6, 0x57, 0x30, 0xdb, 0x37, 0xc8, 0xdc, 0x1b, 0x6d, 0x33, - 0xad, 0x61, 0x3c, 0x38, 0xab, 0x46, 0xe2, 0xbd, 0x0b, 0xf9, 0xf4, 0xfc, 0x51, 0x1a, 0x6d, 0x2a, - 0xa5, 0x60, 0x7c, 0x70, 0x46, 0x85, 0xc4, 0x75, 0x0b, 0xa0, 0x67, 0x88, 0xb8, 0x3b, 0xda, 0xcc, - 0x91, 0xb4, 0xf1, 0xde, 0x59, 0xa4, 0x13, 0x8f, 0x3f, 0x69, 0xa0, 0x0f, 0x9c, 0x20, 0x1e, 0x8e, - 0x36, 0x39, 0x48, 0xd7, 0x58, 0x3b, 0xbf, 0x6e, 0x02, 0xee, 0x07, 0x0d, 0x96, 0x06, 0xdd, 0xed, - 0x1f, 0x9e, 0xd5, 0x7e, 0xa2, 0x6a, 0x3c, 0x3a, 0xb7, 0x6a, 0x6f, 0x85, 0xf6, 0x7d, 0xe7, 0x9d, - 0xa2, 0x42, 0xd3, 0x1a, 0xa7, 0xa9, 0xd0, 0x93, 0xbf, 0xbb, 0xd0, 0xd7, 0x1a, 0xcc, 0x1d, 0xfb, - 0xac, 0x2d, 0x8f, 0x36, 0xd7, 0xaf, 0x63, 0x3c, 0x3c, 0xbb, 0x4e, 0x0c, 0x62, 0xed, 0xe9, 0xcb, - 0x37, 0x05, 0xed, 0xd5, 0x9b, 0x82, 0xf6, 0xd7, 0x9b, 0x82, 0xf6, 0xdd, 0x61, 0x61, 0xec, 0xd5, - 0x61, 0x61, 0xec, 0xb7, 0xc3, 0xc2, 0xd8, 0xf3, 0x77, 0x7b, 0x5e, 0x30, 0x6e, 0x75, 0x55, 0xfe, - 0x03, 0x10, 0x3b, 0x28, 0x75, 0x4a, 0xbd, 0xff, 0x0b, 0xf0, 0x07, 0xad, 0x9e, 0x11, 0x5f, 0xec, - 0xf7, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xc9, 0xb3, 0x25, 0xb5, 0x32, 0x10, 0x00, 0x00, + // 1361 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xcd, 0x6e, 0xdb, 0xc6, + 0x13, 0x37, 0x63, 0x5b, 0x96, 0xc6, 0x96, 0x63, 0xaf, 0x9d, 0x98, 0xa1, 0x13, 0x39, 0xa1, 0xff, + 0xc9, 0x3f, 0x28, 0x62, 0x29, 0x75, 0x5a, 0x34, 0x4d, 0x7b, 0x68, 0x6c, 0xa4, 0x8e, 0x9b, 0xca, + 0x0e, 0x68, 0xa5, 0x05, 0x72, 0x21, 0x28, 0x72, 0x4d, 0x11, 0x16, 0xb9, 0x02, 0x77, 0x65, 0x48, + 0x41, 0x4f, 0x05, 0x7a, 0xe8, 0xad, 0x87, 0x02, 0x2d, 0xfa, 0x02, 0x7d, 0x95, 0xf4, 0x16, 0xf4, + 0xd4, 0xf6, 0x10, 0xb4, 0xc9, 0x1b, 0xf4, 0x09, 0x8a, 0xfd, 0x20, 0x2d, 0xca, 0x96, 0x64, 0xbb, + 0xe8, 0x89, 0x3b, 0xb3, 0xf3, 0xf1, 0x9b, 0x9d, 0x99, 0xdd, 0x21, 0x2c, 0xb8, 0x31, 0xa1, 0xd4, + 0x6d, 0x38, 0x41, 0x54, 0x61, 0x9d, 0x72, 0x2b, 0x26, 0x8c, 0xa0, 0x6b, 0x2f, 0x30, 0x73, 0x04, + 0xaf, 0x2c, 0x56, 0x24, 0xc6, 0xe5, 0x23, 0x39, 0x63, 0xc1, 0x25, 0x61, 0x48, 0xa2, 0x8a, 0xfc, + 0x48, 0x1d, 0x63, 0xd1, 0x27, 0x3e, 0x11, 0xcb, 0x0a, 0x5f, 0x49, 0xae, 0xb9, 0x03, 0x0b, 0x55, + 0xea, 0x3f, 0x6b, 0x79, 0x0e, 0xc3, 0x35, 0x4a, 0x1f, 0x7a, 0x5e, 0x8c, 0x29, 0x45, 0x3a, 0x4c, + 0xb9, 0x31, 0x76, 0x18, 0x89, 0x75, 0xed, 0xba, 0x76, 0xbb, 0x60, 0x25, 0x24, 0xba, 0x06, 0xc0, + 0x28, 0xb5, 0x5b, 0xed, 0xfa, 0x01, 0xee, 0xea, 0x17, 0xc4, 0x66, 0x81, 0x51, 0xfa, 0x54, 0x30, + 0xcc, 0x6b, 0xb0, 0x7c, 0x82, 0x3d, 0x0b, 0xd3, 0x16, 0x89, 0x28, 0x36, 0x7f, 0xd5, 0x60, 0xbe, + 0x4a, 0xfd, 0x2f, 0x1b, 0x01, 0xc3, 0xcd, 0x80, 0xb2, 0x47, 0xd6, 0xe6, 0xfa, 0xdd, 0x21, 0xde, + 0x56, 0xa1, 0x88, 0x63, 0x77, 0xfd, 0xae, 0xed, 0x48, 0x43, 0xca, 0xe1, 0x8c, 0x60, 0x26, 0x60, + 0xaf, 0x40, 0x5e, 0xc4, 0x6d, 0x07, 0x9e, 0x3e, 0x7e, 0x5d, 0xbb, 0x3d, 0x6e, 0x4d, 0x09, 0x7a, + 0xdb, 0x43, 0x08, 0x26, 0x22, 0x27, 0xc4, 0xfa, 0x84, 0x50, 0x13, 0x6b, 0x74, 0x19, 0x72, 0xb4, + 0x1b, 0xd6, 0x49, 0x53, 0x9f, 0x14, 0x5c, 0x45, 0x21, 0x03, 0xf2, 0x1e, 0x76, 0x83, 0xd0, 0x69, + 0x52, 0x3d, 0x77, 0x5d, 0xbb, 0x5d, 0xb4, 0x52, 0x1a, 0x2d, 0x43, 0xc1, 0x77, 0xa8, 0xdd, 0x0c, + 0xc2, 0x80, 0xe9, 0x53, 0xc2, 0x47, 0xde, 0x77, 0xe8, 0xe7, 0x9c, 0x36, 0x97, 0xe1, 0xca, 0xb1, + 0x98, 0xd2, 0x88, 0x7f, 0xd7, 0x60, 0xb1, 0x4a, 0xfd, 0x87, 0x9e, 0x57, 0x23, 0xbb, 0x6d, 0x56, + 0xeb, 0xd4, 0x62, 0xc7, 0x3d, 0xc0, 0xf1, 0x90, 0xa0, 0x7b, 0xe3, 0xb9, 0x90, 0x8d, 0x67, 0x11, + 0x26, 0x23, 0x12, 0xb9, 0x58, 0xc4, 0x39, 0x61, 0x49, 0x02, 0x2d, 0xc1, 0x14, 0xeb, 0xd8, 0x0d, + 0x87, 0x36, 0x54, 0xa0, 0x39, 0xd6, 0x79, 0xec, 0xd0, 0x06, 0x5a, 0x85, 0xc9, 0x56, 0x4c, 0xc8, + 0xbe, 0x88, 0x74, 0x7a, 0xbd, 0x58, 0x56, 0x15, 0xf1, 0x94, 0x33, 0x2d, 0xb9, 0xc7, 0x33, 0x5a, + 0x6f, 0x12, 0xf7, 0x40, 0x1a, 0xc8, 0xc9, 0x8c, 0x0a, 0x8e, 0xb0, 0x71, 0x05, 0xf2, 0xac, 0x63, + 0x07, 0x91, 0x87, 0x3b, 0x2a, 0xf2, 0x29, 0xd6, 0xd9, 0xe6, 0xa4, 0x59, 0x82, 0xab, 0x27, 0x85, + 0x96, 0xc6, 0xbe, 0x2f, 0x0e, 0xc6, 0xc2, 0x21, 0x39, 0xc4, 0x9f, 0xc6, 0x24, 0xfc, 0x8f, 0xe2, + 0x37, 0x57, 0xe1, 0xc6, 0x40, 0x3f, 0x29, 0x98, 0x9f, 0x65, 0xe9, 0x6d, 0x72, 0x27, 0xb8, 0xb6, + 0xb7, 0xf7, 0x05, 0x61, 0x43, 0x51, 0x0c, 0x2f, 0x74, 0xf4, 0x0e, 0xcc, 0x1d, 0xe0, 0xee, 0x16, + 0x8e, 0x9e, 0x63, 0xe6, 0x3c, 0xc6, 0x81, 0xdf, 0x60, 0xaa, 0xf8, 0x8e, 0xf1, 0xd1, 0x1a, 0xe4, + 0x28, 0x73, 0x58, 0x9b, 0x8a, 0xf4, 0xcc, 0xae, 0x5f, 0x4a, 0xf2, 0x60, 0x61, 0x17, 0x07, 0x87, + 0x78, 0x4f, 0x6c, 0x5a, 0x4a, 0x48, 0xd5, 0x53, 0x16, 0x68, 0x1a, 0xc6, 0x8f, 0x1a, 0xcc, 0x55, + 0xa9, 0xbf, 0xe5, 0xd0, 0xa7, 0x71, 0xe0, 0xe2, 0x51, 0x51, 0x0c, 0x3f, 0xcb, 0x16, 0x37, 0x91, + 0x9c, 0xa5, 0x20, 0xd0, 0x0d, 0x98, 0x91, 0xd5, 0x10, 0xb5, 0xc3, 0x3a, 0x8e, 0x05, 0xe2, 0x09, + 0x6b, 0x5a, 0xf0, 0x76, 0x04, 0x4b, 0x34, 0x50, 0xbb, 0xd5, 0x6a, 0x76, 0xd3, 0x06, 0x12, 0x94, + 0x69, 0x80, 0xde, 0x8f, 0x2c, 0x85, 0xfd, 0x1c, 0x8a, 0x55, 0xea, 0xef, 0xf0, 0x74, 0xfd, 0x3b, + 0xc8, 0x27, 0xa4, 0x7f, 0x09, 0x2e, 0x65, 0x6c, 0x1f, 0xf5, 0xde, 0xa4, 0xb8, 0x8d, 0x38, 0x73, + 0x37, 0xda, 0xad, 0x53, 0x1c, 0x1f, 0x62, 0x6f, 0xb7, 0xcd, 0xea, 0xa4, 0x1d, 0x79, 0xb5, 0xce, + 0x10, 0x0c, 0xcb, 0x50, 0x70, 0xdd, 0xa4, 0xa7, 0x64, 0xee, 0xf3, 0x9c, 0x21, 0x3a, 0xa2, 0x0c, + 0x0b, 0x44, 0x19, 0xb3, 0x09, 0x2f, 0x35, 0x29, 0x36, 0x2e, 0xc4, 0xe6, 0xc9, 0x91, 0x9f, 0x9a, + 0x94, 0xff, 0x18, 0x8c, 0x3e, 0x79, 0xd9, 0x5d, 0xb2, 0x68, 0xe4, 0x01, 0xeb, 0x19, 0xb5, 0x8d, + 0xa3, 0x7d, 0xf4, 0x3e, 0x2c, 0xf5, 0x69, 0xf3, 0x9b, 0xa8, 0x4d, 0xb1, 0xa7, 0x83, 0x50, 0x5d, + 0xcc, 0xa8, 0x6e, 0x39, 0xf4, 0x19, 0xc5, 0x1e, 0x7a, 0x01, 0x66, 0x9f, 0x1a, 0xde, 0xdf, 0xc7, + 0x2e, 0x0b, 0x0e, 0xb1, 0x30, 0x20, 0x53, 0x3f, 0xcd, 0x31, 0x6f, 0x94, 0x5f, 0xbe, 0x5e, 0x19, + 0xfb, 0xe3, 0xf5, 0xca, 0x2d, 0x3f, 0x60, 0x8d, 0x76, 0x9d, 0x57, 0x67, 0xc5, 0x25, 0x34, 0x24, + 0x54, 0x7d, 0xd6, 0xa8, 0x77, 0x50, 0x61, 0xdd, 0x16, 0xa6, 0xe5, 0xed, 0x88, 0x59, 0xa5, 0x8c, + 0xc7, 0x47, 0x89, 0xdd, 0x24, 0xf3, 0xe8, 0xb3, 0x11, 0xbe, 0xe5, 0x35, 0x3a, 0x23, 0xd0, 0x0f, + 0xb6, 0x25, 0x2e, 0x57, 0x44, 0x60, 0xf6, 0xd0, 0x69, 0xb6, 0xb1, 0x1d, 0xcb, 0x5e, 0xf1, 0x64, + 0xd1, 0x6d, 0x3c, 0x56, 0x98, 0xff, 0x7f, 0x0a, 0xcc, 0xcf, 0x82, 0x88, 0xfd, 0xfd, 0x7a, 0xe5, + 0x52, 0xd7, 0x09, 0x9b, 0x0f, 0xcc, 0xac, 0x39, 0xd3, 0x2a, 0x0a, 0x86, 0x6a, 0x45, 0xaf, 0xa7, + 0x59, 0x73, 0xa7, 0x68, 0x56, 0xb4, 0x02, 0xd3, 0x32, 0x44, 0x51, 0xa3, 0xea, 0x86, 0x04, 0xc1, + 0xda, 0xe4, 0x1c, 0x74, 0x0b, 0x2e, 0x4a, 0x01, 0x7e, 0x9b, 0xc8, 0xea, 0xcd, 0x8b, 0xc8, 0x8b, + 0x82, 0x5d, 0xa3, 0x54, 0x54, 0x2e, 0x5a, 0x83, 0x82, 0x4b, 0x82, 0xc8, 0xe6, 0x90, 0xf5, 0x82, + 0x70, 0x3d, 0x97, 0xb8, 0xde, 0x24, 0x41, 0x54, 0xeb, 0xb6, 0xb0, 0x95, 0x77, 0xd5, 0xca, 0xbc, + 0x09, 0xab, 0x43, 0x4a, 0x3b, 0x6d, 0x81, 0xbf, 0xc6, 0xc1, 0x38, 0x26, 0xb7, 0x1d, 0x8d, 0xee, + 0x00, 0xde, 0xe4, 0x38, 0xf2, 0x70, 0xac, 0xca, 0x5f, 0x51, 0x3c, 0x1c, 0xb9, 0xb2, 0xfb, 0xde, + 0xdc, 0xa2, 0x64, 0x6f, 0xaa, 0x56, 0x35, 0x20, 0xaf, 0x8e, 0x38, 0x56, 0x8f, 0x52, 0x4a, 0xa3, + 0x9b, 0x30, 0x9b, 0xac, 0xd5, 0xb1, 0x4d, 0x4a, 0x13, 0x09, 0x57, 0x9e, 0xdc, 0x16, 0xe4, 0x9c, + 0x90, 0xb4, 0x23, 0x26, 0x1f, 0xa5, 0x8d, 0xca, 0x19, 0x53, 0x6e, 0x29, 0x75, 0x1e, 0x65, 0x88, + 0x29, 0x75, 0x7c, 0x79, 0xf4, 0x05, 0x2b, 0x21, 0xd1, 0x55, 0x00, 0x7e, 0xe4, 0xaa, 0x83, 0x0b, + 0x12, 0x67, 0x10, 0xa9, 0xc6, 0xbd, 0x05, 0x17, 0x83, 0xc8, 0x56, 0x8f, 0xa3, 0xec, 0x56, 0xd9, + 0x72, 0xc5, 0x20, 0xea, 0x6d, 0xd1, 0xcc, 0x74, 0x30, 0x2d, 0x24, 0xd2, 0xe9, 0x20, 0x9b, 0xd7, + 0x99, 0x51, 0x79, 0xe5, 0xb6, 0x58, 0xc7, 0x26, 0x71, 0xe0, 0x07, 0x91, 0x5e, 0x94, 0x80, 0x58, + 0x67, 0x57, 0xd0, 0xfc, 0xfe, 0x73, 0x28, 0xc5, 0x4c, 0x9f, 0x15, 0x1b, 0x92, 0x30, 0xff, 0x07, + 0xe6, 0xe0, 0x14, 0xa7, 0x95, 0xf0, 0xad, 0x06, 0xb3, 0x55, 0xea, 0xef, 0x61, 0xb6, 0x43, 0x3c, + 0xfc, 0x04, 0x77, 0x87, 0x4d, 0x79, 0x15, 0x28, 0xc8, 0x87, 0x6f, 0x0f, 0x33, 0x51, 0x00, 0xd3, + 0xeb, 0xf3, 0xe9, 0xf0, 0xd0, 0xae, 0x3f, 0x11, 0x1b, 0xd6, 0x91, 0x0c, 0xba, 0x03, 0x88, 0xd7, + 0x37, 0x0d, 0xfc, 0x08, 0xc7, 0xb6, 0x9a, 0xcc, 0xd4, 0x95, 0x38, 0xc7, 0x28, 0xdd, 0x13, 0x1b, + 0x8a, 0x6f, 0xea, 0x70, 0x39, 0x0b, 0x25, 0x41, 0xb9, 0xfe, 0x4b, 0x01, 0xc6, 0xab, 0xd4, 0x47, + 0xdf, 0x68, 0x30, 0x7f, 0x7c, 0x66, 0xba, 0x57, 0x1e, 0x3a, 0xf8, 0x96, 0x4f, 0x9a, 0x46, 0x8c, + 0x8f, 0xce, 0xa1, 0x94, 0xe0, 0x41, 0xdf, 0x6b, 0x70, 0x79, 0xc0, 0x00, 0x73, 0x7f, 0xb4, 0xdd, + 0x93, 0x35, 0x8d, 0x4f, 0xce, 0xab, 0x99, 0xc2, 0xfa, 0x0a, 0x66, 0xfb, 0x06, 0x99, 0xbb, 0xa3, + 0x6d, 0x66, 0x35, 0x8c, 0xfb, 0x67, 0xd5, 0x48, 0xbd, 0x77, 0xa1, 0x98, 0x9d, 0x3f, 0x2a, 0xa3, + 0x4d, 0x65, 0x14, 0x8c, 0x0f, 0xce, 0xa8, 0x90, 0xba, 0x6e, 0x01, 0xf4, 0x0c, 0x11, 0x77, 0x46, + 0x9b, 0x39, 0x92, 0x36, 0xde, 0x3b, 0x8b, 0x74, 0xea, 0xf1, 0x27, 0x0d, 0xf4, 0x81, 0x13, 0xc4, + 0x83, 0xd1, 0x26, 0x07, 0xe9, 0x1a, 0x1b, 0xe7, 0xd7, 0x4d, 0xc1, 0xfd, 0xa0, 0xc1, 0xd2, 0xa0, + 0xbb, 0xfd, 0xc3, 0xb3, 0xda, 0x4f, 0x55, 0x8d, 0x87, 0xe7, 0x56, 0xed, 0xad, 0xd0, 0xbe, 0xbf, + 0xbc, 0x53, 0x54, 0x68, 0x56, 0xe3, 0x34, 0x15, 0x7a, 0xf2, 0x5f, 0x17, 0xfa, 0x5a, 0x83, 0xb9, + 0x63, 0x3f, 0xb5, 0xeb, 0xa3, 0xcd, 0xf5, 0xeb, 0x18, 0x0f, 0xce, 0xae, 0x93, 0x80, 0xd8, 0x78, + 0xf2, 0xf2, 0x4d, 0x49, 0x7b, 0xf5, 0xa6, 0xa4, 0xfd, 0xf9, 0xa6, 0xa4, 0x7d, 0xf7, 0xb6, 0x34, + 0xf6, 0xea, 0x6d, 0x69, 0xec, 0xb7, 0xb7, 0xa5, 0xb1, 0xe7, 0xef, 0xf6, 0xbc, 0x60, 0xdc, 0xea, + 0x9a, 0xfc, 0xbf, 0x4f, 0x1c, 0x54, 0x3a, 0x95, 0xde, 0xbf, 0x7e, 0xfe, 0xa0, 0xd5, 0x73, 0xe2, + 0x7f, 0xfd, 0xde, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x41, 0x25, 0x03, 0x10, 0x10, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3536,7 +3535,7 @@ func (m *MsgAddToOutTxTracker) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Proof == nil { - m.Proof = ðereum.Proof{} + m.Proof = &common.Proof{} } if err := m.Proof.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/observer/keeper/keeper_block_header.go b/x/observer/keeper/block_header.go similarity index 80% rename from x/observer/keeper/keeper_block_header.go rename to x/observer/keeper/block_header.go index 36fba2ff14..6bd64b34e4 100644 --- a/x/observer/keeper/keeper_block_header.go +++ b/x/observer/keeper/block_header.go @@ -6,20 +6,21 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" + "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -// SetNodeAccount set a specific nodeAccount in the store from its index -func (k Keeper) SetBlockHeader(ctx sdk.Context, header types.BlockHeader) { +// SetBlockHeader set a specific block header in the store from its index +func (k Keeper) SetBlockHeader(ctx sdk.Context, header common.BlockHeader) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BlockHeaderKey)) b := k.cdc.MustMarshal(&header) store.Set(header.Hash, b) } -// GetNodeAccount returns a nodeAccount from its index -func (k Keeper) GetBlockHeader(ctx sdk.Context, hash []byte) (val types.BlockHeader, found bool) { +// GetBlockHeader returns a block header from its hash +func (k Keeper) GetBlockHeader(ctx sdk.Context, hash []byte) (val common.BlockHeader, found bool) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BlockHeaderKey)) b := store.Get(hash) @@ -31,13 +32,13 @@ func (k Keeper) GetBlockHeader(ctx sdk.Context, hash []byte) (val types.BlockHea return val, true } -// RemoveNodeAccount removes a nodeAccount from the store +// RemoveBlockHeader removes a block header from the store func (k Keeper) RemoveBlockHeader(ctx sdk.Context, hash []byte) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BlockHeaderKey)) store.Delete(hash) } -// GRPC querier for block header +// GetAllBlockHeaders queries all for block header func (k Keeper) GetAllBlockHeaders(c context.Context, req *types.QueryAllBlockHeaderRequest) (*types.QueryAllBlockHeaderResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") @@ -46,9 +47,9 @@ func (k Keeper) GetAllBlockHeaders(c context.Context, req *types.QueryAllBlockHe store := ctx.KVStore(k.storeKey) blockHeaderStore := prefix.NewStore(store, types.KeyPrefix(types.BlockHeaderKey)) - var blockHeaders []*types.BlockHeader + var blockHeaders []*common.BlockHeader pageRes, err := query.Paginate(blockHeaderStore, req.Pagination, func(key []byte, value []byte) error { - var blockHeader types.BlockHeader + var blockHeader common.BlockHeader if err := k.cdc.Unmarshal(value, &blockHeader); err != nil { return err } @@ -62,15 +63,12 @@ func (k Keeper) GetAllBlockHeaders(c context.Context, req *types.QueryAllBlockHe return &types.QueryAllBlockHeaderResponse{BlockHeaders: blockHeaders, Pagination: pageRes}, nil } +// GetBlockHeaderByHash queries block header by hash func (k Keeper) GetBlockHeaderByHash(c context.Context, req *types.QueryGetBlockHeaderByHashRequest) (*types.QueryGetBlockHeaderByHashResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - if len(req.BlockHash) != 32 { - return nil, status.Error(codes.InvalidArgument, "invalid hash") - } - header, found := k.GetBlockHeader(sdk.UnwrapSDKContext(c), req.BlockHash) if !found { return nil, status.Error(codes.NotFound, "not found") diff --git a/x/observer/keeper/grpc_query_prove.go b/x/observer/keeper/grpc_query_prove.go index 99db2ae44a..e4880f4c2e 100644 --- a/x/observer/keeper/grpc_query_prove.go +++ b/x/observer/keeper/grpc_query_prove.go @@ -4,10 +4,11 @@ import ( "context" "fmt" + "github.com/zeta-chain/zetacore/common" + sdk "github.com/cosmos/cosmos-sdk/types" eth "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -24,14 +25,13 @@ func (k Keeper) Prove(c context.Context, req *types.QueryProveRequest) (*types.Q if !found { return nil, status.Error(codes.NotFound, "block header not found") } - var header ethtypes.Header - err := rlp.DecodeBytes(res.Header, &header) - if err != nil { - return nil, status.Error(codes.Internal, fmt.Sprintf("failed to decode header: %s", err)) - } + proven := false - val, err := req.Proof.Verify(header.TxHash, int(req.TxIndex)) + val, err := req.Proof.Verify(res.Header, int(req.TxIndex)) + if err != nil && !common.IsErrorInvalidProof(err) { + return nil, status.Error(codes.Internal, err.Error()) + } if err == nil { var txx ethtypes.Transaction err = txx.UnmarshalBinary(val) diff --git a/x/observer/keeper/msg_server_add_block_header.go b/x/observer/keeper/msg_server_add_block_header.go index caf53cffe6..8ee4ffa5cd 100644 --- a/x/observer/keeper/msg_server_add_block_header.go +++ b/x/observer/keeper/msg_server_add_block_header.go @@ -2,57 +2,64 @@ package keeper import ( "context" - "fmt" + "encoding/hex" + + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/observer/types" ) -// MsgAddBlockHeader handles adding a block header to the store, through majority voting of observers +// AddBlockHeader handles adding a block header to the store, through majority voting of observers func (k msgServer) AddBlockHeader(goCtx context.Context, msg *types.MsgAddBlockHeader) (*types.MsgAddBlockHeaderResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - observationType := types.ObservationType_InBoundTx + + // check authorization for this chain chain := common.GetChainFromChainID(msg.ChainId) ok, err := k.IsAuthorized(ctx, msg.Creator, chain) if !ok { - return nil, err + return nil, cosmoserrors.Wrap(types.ErrNotAuthorizedPolicy, err.Error()) } - ballot, _, err := k.FindBallot(ctx, msg.Digest(), chain, observationType) + // add vote to ballot + ballot, _, err := k.FindBallot(ctx, msg.Digest(), chain, types.ObservationType_InBoundTx) if err != nil { - return nil, sdkerrors.Wrap(err, "failed to find ballot") + return nil, cosmoserrors.Wrap(err, "failed to find ballot") } ballot, err = k.AddVoteToBallot(ctx, ballot, msg.Creator, types.VoteType_SuccessObservation) if err != nil { - return nil, sdkerrors.Wrap(err, "failed to add vote to ballot") + return nil, cosmoserrors.Wrap(err, "failed to add vote to ballot") } _, isFinalized := k.CheckIfFinalizingVote(ctx, ballot) if !isFinalized { return &types.MsgAddBlockHeaderResponse{}, nil } + /** + * Vote finalized, add block header to store + */ _, found := k.GetBlockHeader(ctx, msg.BlockHash) if found { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("block header with hash %s already exists", msg.BlockHeader)) + return nil, cosmoserrors.Wrap(types.ErrBlockAlreadyExist, hex.EncodeToString(msg.BlockHash)) } - pHash, err := msg.ParentHash() // error is checked in BasicValidation in msg; check again for extra caution + // NOTE: error is checked in BasicValidation in msg; check again for extra caution + pHash, err := msg.Header.ParentHash() if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("failed to get parent hash: %s", err.Error())) + return nil, cosmoserrors.Wrap(types.ErrNoParentHash, err.Error()) } // TODO: add check for parent block header's existence here https://github.com/zeta-chain/node/issues/1133 - bh := types.BlockHeader{ - Header: msg.BlockHeader, + bh := common.BlockHeader{ + Header: msg.Header, Height: msg.Height, Hash: msg.BlockHash, ParentHash: pHash, ChainId: msg.ChainId, } - k.SetBlockHeader(ctx, bh) + return &types.MsgAddBlockHeaderResponse{}, nil } diff --git a/x/observer/types/errors.go b/x/observer/types/errors.go index 5df4dab889..afe8422699 100644 --- a/x/observer/types/errors.go +++ b/x/observer/types/errors.go @@ -7,25 +7,26 @@ import ( ) var ( - ErrUnableToAddVote = errorsmod.Register(ModuleName, 1100, "Unable to add vote ") - ErrParamsThreshold = errorsmod.Register(ModuleName, 1101, "Threshold cannot be more than 1") - ErrSupportedChains = errorsmod.Register(ModuleName, 1102, "Err chain not supported") - ErrInvalidStatus = errorsmod.Register(ModuleName, 1103, "Invalid Voting Status") + ErrUnableToAddVote = errorsmod.Register(ModuleName, 1100, "unable to add vote ") + ErrParamsThreshold = errorsmod.Register(ModuleName, 1101, "threshold cannot be more than 1") + ErrSupportedChains = errorsmod.Register(ModuleName, 1102, "chain not supported") + ErrInvalidStatus = errorsmod.Register(ModuleName, 1103, "invalid Voting Status") - ErrObserverNotPresent = errorsmod.Register(ModuleName, 1105, "Observer for type and observation does not exist") - ErrNotValidator = errorsmod.Register(ModuleName, 1106, "User needs to be a validator before applying to become an observer") - ErrValidatorStatus = errorsmod.Register(ModuleName, 1107, "Corresponding validator needs to be bonded and not jailerd") - ErrInvalidAddress = errorsmod.Register(ModuleName, 1108, "Invalid Address") - ErrSelfDelegation = errorsmod.Register(ModuleName, 1109, "Self Delegation for operator not found") - ErrCheckObserverDelegation = errorsmod.Register(ModuleName, 1110, "Observer delegation not sufficient") - ErrNotAuthorizedPolicy = errorsmod.Register(ModuleName, 1111, "Msg Sender is not the authorized policy") - ErrCoreParamsNotSet = errorsmod.Register(ModuleName, 1112, "Core params has not been set") - ErrKeygenNotFound = errorsmod.Register(ModuleName, 1113, "Err Keygen not found, Keygen block can only be updated,New keygen cannot be set") - ErrKeygenBlockTooLow = errorsmod.Register(ModuleName, 1114, "Please set a block number at-least 10 blocks higher than the current block number") - ErrKeygenCompleted = errorsmod.Register(ModuleName, 1115, "Keygen already completed") - ErrNotAuthorized = errorsmod.Register(ModuleName, 1116, "Err not authorized") - ErrInvalidCoinType = errorsmod.Register(ModuleName, 1117, "Invalid coin type") - ErrObserverCountNegative = errorsmod.Register(ModuleName, 1118, "Observer count cannot be negative") - ErrInvalidPubKey = errorsmod.Register(ModuleName, 1119, "Invalid PubKey") - ErrBlockHeaderNotFound = errorsmod.Register(ModuleName, 1120, "Block header not found") + ErrObserverNotPresent = errorsmod.Register(ModuleName, 1105, "observer for type and observation does not exist") + ErrNotValidator = errorsmod.Register(ModuleName, 1106, "user needs to be a validator before applying to become an observer") + ErrValidatorStatus = errorsmod.Register(ModuleName, 1107, "corresponding validator needs to be bonded and not jailerd") + ErrInvalidAddress = errorsmod.Register(ModuleName, 1108, "invalid Address") + ErrSelfDelegation = errorsmod.Register(ModuleName, 1109, "self Delegation for operator not found") + ErrCheckObserverDelegation = errorsmod.Register(ModuleName, 1110, "observer delegation not sufficient") + ErrNotAuthorizedPolicy = errorsmod.Register(ModuleName, 1111, "msg Sender is not the authorized policy") + ErrCoreParamsNotSet = errorsmod.Register(ModuleName, 1112, "core params has not been set") + ErrKeygenNotFound = errorsmod.Register(ModuleName, 1113, "Keygen not found, Keygen block can only be updated,New keygen cannot be set") + ErrKeygenBlockTooLow = errorsmod.Register(ModuleName, 1114, "please set a block number at-least 10 blocks higher than the current block number") + ErrKeygenCompleted = errorsmod.Register(ModuleName, 1115, "keygen already completed") + ErrNotAuthorized = errorsmod.Register(ModuleName, 1116, "not authorized") + + ErrBlockHeaderNotFound = errorsmod.Register(ModuleName, 1117, "block header not found") + ErrUnrecognizedBlockHeader = errorsmod.Register(ModuleName, 1118, "unrecognized block header") + ErrBlockAlreadyExist = errorsmod.Register(ModuleName, 1119, "block already exists") + ErrNoParentHash = errorsmod.Register(ModuleName, 1120, "no parent hash") ) diff --git a/x/observer/types/headers.pb.go b/x/observer/types/headers.pb.go deleted file mode 100644 index 63acd00960..0000000000 --- a/x/observer/types/headers.pb.go +++ /dev/null @@ -1,500 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: observer/headers.proto - -package types - -import ( - fmt "fmt" - io "io" - math "math" - math_bits "math/bits" - - _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/gogo/protobuf/proto" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type BlockHeader struct { - Header []byte `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` - Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` - Hash []byte `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"` - ParentHash []byte `protobuf:"bytes,4,opt,name=parentHash,proto3" json:"parentHash,omitempty"` - ChainId int64 `protobuf:"varint,5,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` -} - -func (m *BlockHeader) Reset() { *m = BlockHeader{} } -func (m *BlockHeader) String() string { return proto.CompactTextString(m) } -func (*BlockHeader) ProtoMessage() {} -func (*BlockHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_2b67bad3a61a5de9, []int{0} -} -func (m *BlockHeader) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *BlockHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_BlockHeader.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *BlockHeader) XXX_Merge(src proto.Message) { - xxx_messageInfo_BlockHeader.Merge(m, src) -} -func (m *BlockHeader) XXX_Size() int { - return m.Size() -} -func (m *BlockHeader) XXX_DiscardUnknown() { - xxx_messageInfo_BlockHeader.DiscardUnknown(m) -} - -var xxx_messageInfo_BlockHeader proto.InternalMessageInfo - -func (m *BlockHeader) GetHeader() []byte { - if m != nil { - return m.Header - } - return nil -} - -func (m *BlockHeader) GetHeight() int64 { - if m != nil { - return m.Height - } - return 0 -} - -func (m *BlockHeader) GetHash() []byte { - if m != nil { - return m.Hash - } - return nil -} - -func (m *BlockHeader) GetParentHash() []byte { - if m != nil { - return m.ParentHash - } - return nil -} - -func (m *BlockHeader) GetChainId() int64 { - if m != nil { - return m.ChainId - } - return 0 -} - -func init() { - proto.RegisterType((*BlockHeader)(nil), "zetachain.zetacore.observer.BlockHeader") -} - -func init() { proto.RegisterFile("observer/headers.proto", fileDescriptor_2b67bad3a61a5de9) } - -var fileDescriptor_2b67bad3a61a5de9 = []byte{ - // 245 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcb, 0x4f, 0x2a, 0x4e, - 0x2d, 0x2a, 0x4b, 0x2d, 0xd2, 0xcf, 0x48, 0x4d, 0x4c, 0x49, 0x2d, 0x2a, 0xd6, 0x2b, 0x28, 0xca, - 0x2f, 0xc9, 0x17, 0x92, 0xae, 0x4a, 0x2d, 0x49, 0x4c, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x03, 0xb3, - 0xf2, 0x8b, 0x52, 0xf5, 0x60, 0x4a, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0xea, 0xf4, 0x41, - 0x2c, 0x88, 0x16, 0x29, 0x71, 0xb8, 0x51, 0x30, 0x06, 0x44, 0x42, 0xa9, 0x87, 0x91, 0x8b, 0xdb, - 0x29, 0x27, 0x3f, 0x39, 0xdb, 0x03, 0x6c, 0x85, 0x90, 0x18, 0x17, 0x1b, 0xc4, 0x32, 0x09, 0x46, - 0x05, 0x46, 0x0d, 0x9e, 0x20, 0x28, 0x0f, 0x22, 0x9e, 0x99, 0x9e, 0x51, 0x22, 0xc1, 0xa4, 0xc0, - 0xa8, 0xc1, 0x1c, 0x04, 0xe5, 0x09, 0x09, 0x71, 0xb1, 0x64, 0x24, 0x16, 0x67, 0x48, 0x30, 0x83, - 0x55, 0x83, 0xd9, 0x42, 0x72, 0x5c, 0x5c, 0x05, 0x89, 0x45, 0xa9, 0x79, 0x25, 0x1e, 0x20, 0x19, - 0x16, 0xb0, 0x0c, 0x92, 0x88, 0x90, 0x24, 0x17, 0x07, 0xd8, 0xf5, 0xf1, 0x99, 0x29, 0x12, 0xac, - 0x60, 0xd3, 0xd8, 0xc1, 0x7c, 0xcf, 0x14, 0x27, 0xcf, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, - 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, - 0x96, 0x63, 0x88, 0xd2, 0x4f, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x07, - 0xf9, 0x5a, 0x17, 0xac, 0x45, 0x1f, 0x16, 0x00, 0xfa, 0x15, 0x70, 0x9f, 0xe9, 0x97, 0x54, 0x16, - 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x3d, 0x68, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xba, 0x02, 0xb5, - 0x91, 0x46, 0x01, 0x00, 0x00, -} - -func (m *BlockHeader) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *BlockHeader) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *BlockHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ChainId != 0 { - i = encodeVarintHeaders(dAtA, i, uint64(m.ChainId)) - i-- - dAtA[i] = 0x28 - } - if len(m.ParentHash) > 0 { - i -= len(m.ParentHash) - copy(dAtA[i:], m.ParentHash) - i = encodeVarintHeaders(dAtA, i, uint64(len(m.ParentHash))) - i-- - dAtA[i] = 0x22 - } - if len(m.Hash) > 0 { - i -= len(m.Hash) - copy(dAtA[i:], m.Hash) - i = encodeVarintHeaders(dAtA, i, uint64(len(m.Hash))) - i-- - dAtA[i] = 0x1a - } - if m.Height != 0 { - i = encodeVarintHeaders(dAtA, i, uint64(m.Height)) - i-- - dAtA[i] = 0x10 - } - if len(m.Header) > 0 { - i -= len(m.Header) - copy(dAtA[i:], m.Header) - i = encodeVarintHeaders(dAtA, i, uint64(len(m.Header))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintHeaders(dAtA []byte, offset int, v uint64) int { - offset -= sovHeaders(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *BlockHeader) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Header) - if l > 0 { - n += 1 + l + sovHeaders(uint64(l)) - } - if m.Height != 0 { - n += 1 + sovHeaders(uint64(m.Height)) - } - l = len(m.Hash) - if l > 0 { - n += 1 + l + sovHeaders(uint64(l)) - } - l = len(m.ParentHash) - if l > 0 { - n += 1 + l + sovHeaders(uint64(l)) - } - if m.ChainId != 0 { - n += 1 + sovHeaders(uint64(m.ChainId)) - } - return n -} - -func sovHeaders(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozHeaders(x uint64) (n int) { - return sovHeaders(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *BlockHeader) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHeaders - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: BlockHeader: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: BlockHeader: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHeaders - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthHeaders - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthHeaders - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Header = append(m.Header[:0], dAtA[iNdEx:postIndex]...) - if m.Header == nil { - m.Header = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) - } - m.Height = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHeaders - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Height |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHeaders - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthHeaders - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthHeaders - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) - if m.Hash == nil { - m.Hash = []byte{} - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ParentHash", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHeaders - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthHeaders - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthHeaders - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ParentHash = append(m.ParentHash[:0], dAtA[iNdEx:postIndex]...) - if m.ParentHash == nil { - m.ParentHash = []byte{} - } - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) - } - m.ChainId = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHeaders - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ChainId |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipHeaders(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthHeaders - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipHeaders(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowHeaders - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowHeaders - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowHeaders - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthHeaders - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupHeaders - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthHeaders - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthHeaders = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowHeaders = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupHeaders = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/observer/types/messages_add_block_header.go b/x/observer/types/messages_add_block_header.go index d216494393..8db4410195 100644 --- a/x/observer/types/messages_add_block_header.go +++ b/x/observer/types/messages_add_block_header.go @@ -1,13 +1,11 @@ package types import ( - "bytes" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" "github.com/zeta-chain/zetacore/common" ) @@ -17,13 +15,13 @@ const ( TypeMsgAddBlockHeader = "add_block_header" ) -func NewMsgAddBlockHeader(creator string, chainID int64, blockHash []byte, height int64, header []byte) *MsgAddBlockHeader { +func NewMsgAddBlockHeader(creator string, chainID int64, blockHash []byte, height int64, header common.HeaderData) *MsgAddBlockHeader { return &MsgAddBlockHeader{ - Creator: creator, - ChainId: chainID, - BlockHash: blockHash, - Height: height, - BlockHeader: header, + Creator: creator, + ChainId: chainID, + BlockHash: blockHash, + Height: height, + Header: header, } } @@ -51,33 +49,23 @@ func (msg *MsgAddBlockHeader) GetSignBytes() []byte { func (msg *MsgAddBlockHeader) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, err.Error()) } - if len(msg.BlockHash) > 32 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid msg.txhash; too long (%d)", len(msg.BlockHash)) - } - if len(msg.BlockHeader) > 1024 { // on ethereum the block header is ~538 bytes in RLP encoding - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid msg.blockheader; too long (%d)", len(msg.BlockHeader)) - } if common.IsEthereum(msg.ChainId) { - // RLP encoded block header - var header types.Header - err = rlp.DecodeBytes(msg.BlockHeader, &header) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid block header; cannot decode RLP (%s)", err) - } - if err = header.SanityCheck(); err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid block header; sanity check failed (%s)", err) - } - if bytes.Compare(msg.BlockHash, header.Hash().Bytes()) != 0 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid block header; tx hash mismatch") - } - if msg.Height != header.Number.Int64() { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid block header; height mismatch") + if len(msg.BlockHash) > 32 { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid msg.txhash; too long (%d)", len(msg.BlockHash)) } } else { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid chain id (%d)", msg.ChainId) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid chain id (%d)", msg.ChainId) + } + + if err := msg.Header.Validate(msg.BlockHash, msg.Height); err != nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid block header (%s)", err) + } + + if _, err := msg.Header.ParentHash(); err != nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "can't get parent hash (%s)", err) } return nil @@ -89,13 +77,3 @@ func (msg *MsgAddBlockHeader) Digest() string { hash := crypto.Keccak256Hash([]byte(m.String())) return hash.Hex() } - -func (msg *MsgAddBlockHeader) ParentHash() ([]byte, error) { - var header types.Header - err := rlp.DecodeBytes(msg.BlockHeader, &header) - if err != nil { - return nil, err - } - - return header.ParentHash.Bytes(), nil -} diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index 91ff1026cf..d1e116394d 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -15,7 +15,6 @@ import ( grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" common "github.com/zeta-chain/zetacore/common" - ethereum "github.com/zeta-chain/zetacore/common/ethereum" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -34,11 +33,11 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type QueryProveRequest struct { - ChainId uint64 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - TxHash string `protobuf:"bytes,2,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` - Proof *ethereum.Proof `protobuf:"bytes,5,opt,name=proof,proto3" json:"proof,omitempty"` - BlockHash string `protobuf:"bytes,6,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` - TxIndex int64 `protobuf:"varint,7,opt,name=tx_index,json=txIndex,proto3" json:"tx_index,omitempty"` + ChainId uint64 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + TxHash string `protobuf:"bytes,2,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` + Proof *common.Proof `protobuf:"bytes,3,opt,name=proof,proto3" json:"proof,omitempty"` + BlockHash string `protobuf:"bytes,4,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + TxIndex int64 `protobuf:"varint,5,opt,name=tx_index,json=txIndex,proto3" json:"tx_index,omitempty"` } func (m *QueryProveRequest) Reset() { *m = QueryProveRequest{} } @@ -88,7 +87,7 @@ func (m *QueryProveRequest) GetTxHash() string { return "" } -func (m *QueryProveRequest) GetProof() *ethereum.Proof { +func (m *QueryProveRequest) GetProof() *common.Proof { if m != nil { return m.Proof } @@ -1452,8 +1451,8 @@ func (m *QueryAllBlockHeaderRequest) GetPagination() *query.PageRequest { } type QueryAllBlockHeaderResponse struct { - BlockHeaders []*BlockHeader `protobuf:"bytes,1,rep,name=block_headers,json=blockHeaders,proto3" json:"block_headers,omitempty"` - Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + BlockHeaders []*common.BlockHeader `protobuf:"bytes,1,rep,name=block_headers,json=blockHeaders,proto3" json:"block_headers,omitempty"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryAllBlockHeaderResponse) Reset() { *m = QueryAllBlockHeaderResponse{} } @@ -1489,7 +1488,7 @@ func (m *QueryAllBlockHeaderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryAllBlockHeaderResponse proto.InternalMessageInfo -func (m *QueryAllBlockHeaderResponse) GetBlockHeaders() []*BlockHeader { +func (m *QueryAllBlockHeaderResponse) GetBlockHeaders() []*common.BlockHeader { if m != nil { return m.BlockHeaders } @@ -1548,7 +1547,7 @@ func (m *QueryGetBlockHeaderByHashRequest) GetBlockHash() []byte { } type QueryGetBlockHeaderByHashResponse struct { - BlockHeader *BlockHeader `protobuf:"bytes,1,opt,name=block_header,json=blockHeader,proto3" json:"block_header,omitempty"` + BlockHeader *common.BlockHeader `protobuf:"bytes,1,opt,name=block_header,json=blockHeader,proto3" json:"block_header,omitempty"` } func (m *QueryGetBlockHeaderByHashResponse) Reset() { *m = QueryGetBlockHeaderByHashResponse{} } @@ -1584,7 +1583,7 @@ func (m *QueryGetBlockHeaderByHashResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryGetBlockHeaderByHashResponse proto.InternalMessageInfo -func (m *QueryGetBlockHeaderByHashResponse) GetBlockHeader() *BlockHeader { +func (m *QueryGetBlockHeaderByHashResponse) GetBlockHeader() *common.BlockHeader { if m != nil { return m.BlockHeader } @@ -1632,121 +1631,120 @@ func init() { func init() { proto.RegisterFile("observer/query.proto", fileDescriptor_dcb801e455adaee4) } var fileDescriptor_dcb801e455adaee4 = []byte{ - // 1823 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcd, 0x4f, 0x1b, 0x49, - 0x16, 0xa7, 0x21, 0x18, 0x78, 0x86, 0x00, 0x15, 0x92, 0x80, 0x01, 0xe3, 0xad, 0x2c, 0x89, 0x03, - 0x89, 0x1d, 0x1c, 0x69, 0xf3, 0x41, 0x20, 0xc2, 0x28, 0x21, 0xe4, 0x93, 0x75, 0x76, 0xb3, 0xab, - 0x95, 0x76, 0xad, 0xb6, 0x5d, 0xd8, 0x4e, 0xda, 0x5d, 0x4e, 0x77, 0x43, 0xf0, 0x46, 0x48, 0xab, - 0x3d, 0xef, 0x4a, 0x91, 0x56, 0xda, 0xbf, 0x61, 0x2e, 0x33, 0x87, 0x48, 0xa3, 0x39, 0x44, 0x73, - 0x99, 0xcb, 0xe4, 0x34, 0xca, 0x68, 0xa4, 0xd1, 0xcc, 0x61, 0x46, 0xa3, 0x64, 0xfe, 0x90, 0x51, - 0x57, 0x55, 0xb7, 0xcb, 0xed, 0x6e, 0xbb, 0x8d, 0x72, 0xa2, 0xeb, 0xe3, 0xbd, 0xf7, 0xfb, 0xbd, - 0xaa, 0x7a, 0xf5, 0x2b, 0x0c, 0x53, 0xb4, 0x60, 0x12, 0x63, 0x9f, 0x18, 0xe9, 0xe7, 0x7b, 0xc4, - 0x68, 0xa4, 0xea, 0x06, 0xb5, 0x28, 0x9a, 0xfd, 0x27, 0xb1, 0xd4, 0x62, 0x45, 0xad, 0xea, 0x29, - 0xf6, 0x45, 0x0d, 0x92, 0x72, 0x26, 0xc6, 0x4e, 0x14, 0x69, 0xad, 0x46, 0xf5, 0x34, 0xff, 0xc3, - 0x2d, 0x62, 0x71, 0xd1, 0x49, 0xac, 0x0a, 0x31, 0xc8, 0x5e, 0xcd, 0xfd, 0x10, 0xe3, 0x4b, 0x45, - 0x6a, 0xd6, 0xa8, 0x99, 0x2e, 0xa8, 0x26, 0xe1, 0xa1, 0xd2, 0xfb, 0x2b, 0x05, 0x62, 0xa9, 0x2b, - 0xe9, 0xba, 0x5a, 0xae, 0xea, 0xaa, 0x55, 0x75, 0x7d, 0x4d, 0x95, 0x69, 0x99, 0xb2, 0xcf, 0xb4, - 0xfd, 0x25, 0x7a, 0xe7, 0xca, 0x94, 0x96, 0x35, 0x92, 0x56, 0xeb, 0xd5, 0xb4, 0xaa, 0xeb, 0xd4, - 0x62, 0x26, 0xa6, 0x18, 0x3d, 0xe9, 0xf2, 0x28, 0xa8, 0x9a, 0x46, 0x2d, 0xc7, 0x55, 0xb3, 0x5b, - 0x53, 0x6b, 0x44, 0xf4, 0x9e, 0x72, 0x7b, 0x2b, 0x44, 0x2d, 0x11, 0xa3, 0xdd, 0xc9, 0x33, 0xd2, - 0x28, 0x13, 0x07, 0xcf, 0xac, 0xdb, 0xad, 0xd3, 0x12, 0xc9, 0xab, 0xc5, 0x22, 0xdd, 0xd3, 0x9d, - 0x08, 0xa7, 0xdd, 0x41, 0xe7, 0xa3, 0xcd, 0x59, 0x5d, 0x35, 0xd4, 0x9a, 0x13, 0x63, 0xa1, 0xd9, - 0x4d, 0x8c, 0x5a, 0xd5, 0x34, 0xab, 0x54, 0xcf, 0xef, 0x6a, 0x6a, 0x59, 0x4c, 0xc0, 0x9f, 0x28, - 0x30, 0xf9, 0x47, 0x3b, 0x41, 0x3b, 0x06, 0xdd, 0x27, 0x39, 0xf2, 0x7c, 0x8f, 0x98, 0x16, 0x9a, - 0x81, 0x61, 0xb6, 0x1e, 0xf9, 0x6a, 0x69, 0x5a, 0x49, 0x28, 0xc9, 0x63, 0xb9, 0x21, 0xd6, 0xde, - 0x2e, 0xa1, 0xd3, 0x30, 0x64, 0x1d, 0xe4, 0x2b, 0xaa, 0x59, 0x99, 0xee, 0x4f, 0x28, 0xc9, 0x91, - 0x5c, 0xc4, 0x3a, 0xb8, 0xa3, 0x9a, 0x15, 0xb4, 0x08, 0x83, 0x75, 0x83, 0xd2, 0xdd, 0xe9, 0xc1, - 0x84, 0x92, 0x8c, 0x66, 0xc6, 0x53, 0xee, 0x9a, 0xec, 0xd8, 0xdd, 0x39, 0x3e, 0x8a, 0xe6, 0x01, - 0x0a, 0x1a, 0x2d, 0x3e, 0xe3, 0x2e, 0x22, 0xcc, 0xc5, 0x08, 0xeb, 0x61, 0x5e, 0x66, 0x60, 0xd8, - 0x3a, 0xc8, 0x57, 0xf5, 0x12, 0x39, 0x98, 0x1e, 0x4a, 0x28, 0xc9, 0x81, 0xdc, 0x90, 0x75, 0xb0, - 0x6d, 0x37, 0xf1, 0x12, 0x20, 0x19, 0xa9, 0x59, 0xa7, 0xba, 0x49, 0xd0, 0x14, 0x0c, 0xee, 0xab, - 0x9a, 0xc0, 0x39, 0x9c, 0xe3, 0x0d, 0x3c, 0xe5, 0xcc, 0x65, 0xc9, 0x10, 0xb4, 0xf0, 0x5f, 0xe1, - 0x44, 0x4b, 0xaf, 0x70, 0xb1, 0x01, 0x11, 0x9e, 0x34, 0xe6, 0x23, 0x9a, 0x39, 0x93, 0xea, 0xb0, - 0x21, 0x53, 0xdc, 0x38, 0x7b, 0xec, 0xed, 0xcf, 0x0b, 0x7d, 0x39, 0x61, 0x88, 0x1f, 0x40, 0x9c, - 0x79, 0xce, 0xb2, 0xed, 0x90, 0x6d, 0x6c, 0x97, 0x88, 0x6e, 0x55, 0x77, 0xab, 0xc4, 0x70, 0x52, - 0xba, 0x0c, 0x93, 0x7c, 0xaf, 0xe4, 0xab, 0xee, 0x18, 0x8b, 0x37, 0x92, 0x9b, 0xe0, 0x03, 0x4d, - 0x1b, 0x6c, 0xc1, 0xc8, 0x13, 0x6a, 0x11, 0xe3, 0x7e, 0xd5, 0xb4, 0xd0, 0x19, 0x18, 0xdb, 0xb7, - 0x1b, 0x79, 0xb5, 0x54, 0x32, 0x88, 0x69, 0x0a, 0xab, 0x51, 0xd6, 0xb9, 0xc1, 0xfb, 0x50, 0x16, - 0x46, 0xec, 0x76, 0xde, 0x6a, 0xd4, 0x09, 0x5b, 0x98, 0xe3, 0x99, 0xc5, 0x8e, 0x34, 0x6c, 0xff, - 0x7f, 0x6a, 0xd4, 0x49, 0x6e, 0x78, 0x5f, 0x7c, 0xe1, 0x2f, 0xfa, 0x61, 0x21, 0x90, 0x85, 0xc8, - 0x55, 0x2f, 0x34, 0xd0, 0x3a, 0x44, 0x18, 0x48, 0x73, 0xba, 0x3f, 0x31, 0x90, 0x8c, 0x66, 0xce, - 0x76, 0x45, 0xc4, 0x18, 0xe7, 0x84, 0x15, 0xfa, 0x0b, 0x4c, 0xf0, 0x51, 0x76, 0xf8, 0x38, 0xb7, - 0x01, 0xc6, 0xed, 0x42, 0x47, 0x4f, 0x8f, 0x9a, 0x46, 0x8c, 0xe2, 0x38, 0x6d, 0xed, 0x40, 0x0f, - 0x61, 0x4c, 0xb0, 0x30, 0x2d, 0xd5, 0xda, 0x33, 0xa7, 0x8f, 0x31, 0xaf, 0xe7, 0x3b, 0x7a, 0xe5, - 0x59, 0x79, 0xcc, 0x0c, 0x72, 0xa3, 0x05, 0xa9, 0x85, 0xef, 0xc1, 0x1c, 0x4b, 0xdc, 0x23, 0x31, - 0xd7, 0xcc, 0x36, 0x36, 0x6d, 0x2f, 0xd2, 0xe2, 0xcb, 0x44, 0x58, 0x04, 0x27, 0x6b, 0xd2, 0x00, - 0xb3, 0xc1, 0x6b, 0x30, 0x1f, 0xe0, 0x4c, 0xac, 0xc1, 0x1c, 0x8c, 0x38, 0xa0, 0xec, 0xcd, 0x30, - 0x60, 0x9f, 0x20, 0xb7, 0x03, 0x27, 0xc4, 0x56, 0xdc, 0xd0, 0x34, 0xc7, 0xc3, 0x03, 0xb5, 0x5e, - 0x27, 0x86, 0x7b, 0x0c, 0x1a, 0x62, 0x99, 0xfd, 0x66, 0x88, 0x10, 0x4f, 0x9c, 0xcc, 0x13, 0x23, - 0x5f, 0xe3, 0x63, 0x2c, 0x52, 0x34, 0xb3, 0x1c, 0x22, 0xf3, 0x8e, 0x3f, 0x27, 0xf1, 0xae, 0x7f, - 0x7c, 0x0a, 0xa6, 0x58, 0xe8, 0xc7, 0x7b, 0xf5, 0x3a, 0x35, 0x2c, 0x52, 0x62, 0xcc, 0x4c, 0x7c, - 0x4b, 0x24, 0xd0, 0xd3, 0xef, 0xe2, 0x59, 0x84, 0x08, 0x0b, 0xe9, 0xa0, 0x18, 0x4b, 0x89, 0xfb, - 0x80, 0x67, 0x46, 0x0c, 0xe2, 0x75, 0xf8, 0x1d, 0x73, 0xb3, 0x45, 0xac, 0x4d, 0x6a, 0x10, 0x7e, - 0x54, 0x6f, 0x53, 0xa3, 0x65, 0x31, 0xbc, 0xc5, 0x6d, 0xc0, 0x2d, 0x6e, 0x58, 0x07, 0xdc, 0xc9, - 0x5e, 0x80, 0xb9, 0x03, 0x51, 0x9b, 0x75, 0xbe, 0xa5, 0x68, 0x9c, 0xeb, 0x98, 0x97, 0xa6, 0xb7, - 0x1c, 0x14, 0xdd, 0x6f, 0x3c, 0x0b, 0x33, 0xed, 0xf1, 0x9c, 0x65, 0x7a, 0x0a, 0x31, 0xbf, 0x41, - 0x01, 0xe2, 0xbe, 0x1f, 0x88, 0xe5, 0x90, 0x20, 0xd8, 0x29, 0x93, 0x81, 0x64, 0x9a, 0xb1, 0x1e, - 0xd2, 0x12, 0xd9, 0xe0, 0x97, 0x8e, 0x93, 0xb1, 0x29, 0x18, 0xe4, 0x15, 0x99, 0x6f, 0x59, 0xde, - 0xc0, 0x4f, 0x61, 0xd6, 0xd7, 0x46, 0x00, 0xbc, 0x07, 0xa3, 0xf2, 0x05, 0x26, 0x10, 0x26, 0x3b, - 0x22, 0x94, 0xfd, 0x44, 0xf5, 0x66, 0x03, 0x97, 0x04, 0xbe, 0x0d, 0x4d, 0xf3, 0xc1, 0x77, 0x1b, - 0xa0, 0x79, 0xad, 0x8b, 0x40, 0x67, 0x53, 0x5c, 0x03, 0xa4, 0x6c, 0x0d, 0x90, 0xe2, 0x72, 0x43, - 0x68, 0x80, 0xd4, 0x8e, 0x5a, 0x76, 0xae, 0xba, 0x9c, 0x64, 0x89, 0x5f, 0x2b, 0x82, 0x92, 0x37, - 0x8c, 0xa0, 0x74, 0x17, 0xa2, 0x52, 0xb7, 0xd8, 0x8a, 0x3d, 0x30, 0x92, 0x1a, 0x68, 0xab, 0x05, - 0x73, 0xbf, 0xd8, 0x43, 0xdd, 0x30, 0x73, 0x20, 0x2d, 0xa0, 0x9d, 0xf3, 0xbe, 0x45, 0xac, 0x1d, - 0xf7, 0x8e, 0xbf, 0x6d, 0x5f, 0xf1, 0xce, 0x46, 0xfa, 0x97, 0x22, 0x0e, 0xbc, 0xdf, 0x14, 0x41, - 0xed, 0xef, 0x30, 0xe1, 0x55, 0x08, 0x22, 0x91, 0x9d, 0x4b, 0xad, 0xc7, 0x9f, 0xb8, 0x16, 0xc7, - 0xeb, 0xad, 0xdd, 0xf8, 0x34, 0x9c, 0x74, 0x10, 0xdc, 0x63, 0x62, 0xc7, 0xc1, 0xf6, 0x67, 0x38, - 0xe5, 0x1d, 0x10, 0x88, 0x56, 0x21, 0xc2, 0x75, 0x51, 0xa8, 0x5b, 0x59, 0x18, 0x0b, 0x13, 0xbc, - 0x20, 0x6a, 0xe8, 0xe3, 0x0a, 0x7d, 0xe1, 0xd4, 0xa4, 0x4d, 0x69, 0xcb, 0xd8, 0x39, 0x89, 0x07, - 0xcd, 0x10, 0x00, 0xfe, 0x01, 0x27, 0x34, 0xd5, 0xb4, 0xf2, 0x6e, 0x21, 0x94, 0xf7, 0x71, 0xaa, - 0x23, 0x9a, 0xfb, 0xaa, 0x69, 0xb5, 0x3a, 0x9d, 0xd4, 0xbc, 0x5d, 0xf8, 0xae, 0xc0, 0x98, 0xb5, - 0xb5, 0xa2, 0x9f, 0x64, 0x38, 0x0f, 0x13, 0x4c, 0x47, 0xb6, 0x5f, 0xb5, 0xe3, 0xac, 0x5f, 0x12, - 0x0c, 0x45, 0x47, 0x7f, 0xb4, 0xfb, 0x72, 0x45, 0x0e, 0x08, 0x67, 0xfa, 0x2e, 0x15, 0x24, 0x70, - 0xe7, 0xfb, 0xce, 0x9e, 0x6e, 0x6b, 0x33, 0x3b, 0x94, 0xbe, 0x4b, 0xf1, 0x7c, 0xf3, 0x74, 0xf0, - 0x31, 0x52, 0xa4, 0x46, 0xc9, 0xdd, 0x66, 0xaa, 0xa8, 0xe1, 0x6d, 0xc3, 0x01, 0x08, 0x06, 0x7a, - 0x47, 0x20, 0x95, 0x81, 0x2c, 0x93, 0x8c, 0x4c, 0x50, 0x7f, 0xec, 0x32, 0xf0, 0xb9, 0x22, 0x13, - 0x95, 0xc2, 0x08, 0x22, 0x0f, 0x60, 0x4c, 0x48, 0x58, 0xae, 0xe7, 0x43, 0x15, 0x02, 0xd9, 0xd1, - 0x68, 0xa1, 0xd9, 0x30, 0x3f, 0x5e, 0x25, 0xd8, 0x80, 0x84, 0x73, 0x96, 0xa4, 0x68, 0xd9, 0x86, - 0x2d, 0xac, 0x9d, 0x1c, 0xb5, 0xca, 0x6f, 0x3b, 0x47, 0xa3, 0x92, 0xfc, 0xc6, 0xf5, 0xe6, 0x05, - 0xea, 0xe3, 0xa2, 0x59, 0xd9, 0x65, 0xfe, 0xa1, 0x2a, 0xbb, 0x4c, 0x3f, 0x2a, 0xd1, 0xcf, 0xfc, - 0x77, 0x06, 0x06, 0x59, 0x48, 0xf4, 0x4a, 0x81, 0x08, 0xbf, 0x8e, 0x50, 0xba, 0xa3, 0xaf, 0x76, - 0x65, 0x1f, 0xbb, 0x14, 0xde, 0x80, 0x93, 0xc0, 0x67, 0xfe, 0xfd, 0xdd, 0xaf, 0xff, 0xeb, 0x9f, - 0x47, 0xb3, 0x69, 0x7b, 0xfe, 0x45, 0x66, 0x9a, 0xf6, 0x3c, 0xa2, 0xd0, 0xf7, 0x0a, 0xa0, 0x76, - 0x31, 0x8c, 0x56, 0xbb, 0x47, 0x0b, 0x7c, 0x08, 0xc4, 0x6e, 0x1c, 0xcd, 0x58, 0xc0, 0xbe, 0xc5, - 0x60, 0xdf, 0x44, 0x6b, 0xbe, 0xb0, 0x85, 0xa8, 0x2d, 0x34, 0xa4, 0x92, 0x91, 0x7e, 0xd9, 0x26, - 0xd8, 0x0f, 0xd1, 0x37, 0x0a, 0x4c, 0x78, 0xf5, 0x25, 0xba, 0xd6, 0x1d, 0x59, 0x80, 0xc0, 0x8d, - 0x5d, 0x3f, 0x8a, 0xa9, 0xa0, 0xb4, 0xc9, 0x28, 0xad, 0xa1, 0x55, 0x5f, 0x4a, 0xae, 0xb0, 0xb5, - 0x59, 0xf1, 0xb1, 0x97, 0x6d, 0x5a, 0xfa, 0x10, 0x7d, 0xa5, 0x00, 0x6a, 0xd7, 0xb3, 0x61, 0x56, - 0x2a, 0x50, 0x27, 0x87, 0x59, 0xa9, 0x60, 0x09, 0x8d, 0x57, 0x18, 0xad, 0x65, 0x74, 0xde, 0x97, - 0x96, 0xaa, 0x69, 0x79, 0xaf, 0xc2, 0x46, 0x9f, 0x2a, 0x30, 0xee, 0x51, 0xc0, 0x68, 0xa5, 0x3b, - 0x08, 0x8f, 0x49, 0xec, 0x5a, 0xcf, 0x26, 0x2e, 0xe8, 0x0b, 0x0c, 0xf4, 0x59, 0xf4, 0x7b, 0x5f, - 0xd0, 0xa6, 0x07, 0xdb, 0x4f, 0x0a, 0x9c, 0xf4, 0x95, 0xca, 0x68, 0xbd, 0x3b, 0x84, 0x4e, 0x1a, - 0x3d, 0x76, 0xf3, 0xc8, 0xf6, 0xa1, 0x36, 0x55, 0x99, 0x58, 0xf9, 0xa2, 0x56, 0x25, 0xba, 0x25, - 0xf4, 0x73, 0x7e, 0x97, 0x1a, 0xce, 0xee, 0x72, 0x1e, 0x07, 0x87, 0xe8, 0x33, 0x05, 0xc6, 0x5a, - 0xc2, 0xa0, 0x3f, 0xf4, 0x88, 0xcb, 0xe1, 0x73, 0xa5, 0x67, 0xbb, 0x50, 0x0b, 0xc2, 0x78, 0x34, - 0x5f, 0x01, 0xe8, 0xb5, 0xd2, 0xa2, 0x50, 0x51, 0xb8, 0xb0, 0xed, 0x8a, 0x3a, 0x76, 0xb5, 0x77, - 0x43, 0x01, 0xf8, 0x12, 0x03, 0xbc, 0x84, 0x92, 0xbe, 0x80, 0x25, 0x4d, 0x9f, 0x7e, 0xc9, 0x9e, - 0x11, 0x87, 0xf6, 0xae, 0x3f, 0x2e, 0x79, 0xda, 0xd0, 0xb4, 0x30, 0xb8, 0x7d, 0x5f, 0x02, 0x61, - 0x70, 0xfb, 0x6b, 0x7b, 0x9c, 0x64, 0xb8, 0x31, 0x4a, 0x74, 0xc3, 0x8d, 0xde, 0x28, 0x30, 0xee, - 0x91, 0xbd, 0x61, 0xea, 0x4c, 0xa0, 0x3e, 0x0f, 0x53, 0x67, 0x82, 0x95, 0x3b, 0xbe, 0xc8, 0x80, - 0x9f, 0x43, 0x8b, 0xfe, 0x17, 0x99, 0x47, 0xd4, 0xa3, 0xff, 0x2b, 0x10, 0xe1, 0x62, 0x19, 0x65, - 0x42, 0xc5, 0x6d, 0xd1, 0xeb, 0xb1, 0xcb, 0x3d, 0xd9, 0x84, 0xba, 0x6b, 0xb9, 0x64, 0x47, 0x5f, - 0x2b, 0x30, 0xd9, 0x26, 0xc6, 0x51, 0x88, 0x8b, 0x25, 0x48, 0xe3, 0xc7, 0x56, 0x8f, 0x64, 0x2b, - 0x30, 0x5f, 0x63, 0x98, 0x2f, 0xa3, 0x15, 0x19, 0xb3, 0xe3, 0x45, 0x2a, 0x89, 0x15, 0xfa, 0xc2, - 0xf3, 0x42, 0x40, 0xdf, 0x2a, 0x30, 0xd9, 0x26, 0xc4, 0xc3, 0x30, 0x09, 0x7a, 0x09, 0x84, 0x61, - 0x12, 0xa8, 0xfc, 0xbb, 0x94, 0x42, 0x2e, 0xc9, 0xbd, 0x8a, 0xc1, 0xf3, 0xec, 0x38, 0x44, 0x5f, - 0x2a, 0x80, 0xb6, 0x88, 0xe5, 0xd1, 0xf6, 0x28, 0xdc, 0x79, 0xf3, 0x79, 0x2d, 0x84, 0xb9, 0xa4, - 0x02, 0x1e, 0x12, 0x38, 0xc3, 0x08, 0x5d, 0x40, 0x4b, 0x81, 0x35, 0xd1, 0xbe, 0x5d, 0x39, 0x07, - 0x43, 0x00, 0x7d, 0x23, 0xe1, 0x97, 0xb4, 0xf7, 0x95, 0x90, 0x28, 0xbc, 0x6f, 0x8d, 0xd8, 0xd5, - 0xde, 0x0d, 0x7b, 0x44, 0x2f, 0x3d, 0x30, 0xd0, 0x8f, 0x0a, 0x4c, 0xf9, 0x49, 0x72, 0xb4, 0x16, - 0xea, 0x38, 0x06, 0xbd, 0x06, 0x62, 0xeb, 0x47, 0x35, 0x17, 0x5c, 0xb2, 0x8c, 0xcb, 0x0d, 0x74, - 0x3d, 0x90, 0x8b, 0xcc, 0xc3, 0xde, 0x65, 0xf6, 0xb3, 0xc3, 0xde, 0x5f, 0xce, 0x13, 0xe4, 0x10, - 0xfd, 0x47, 0x81, 0x41, 0xf6, 0x2f, 0x7d, 0x94, 0x0a, 0x21, 0xe2, 0xa5, 0x5f, 0x29, 0x62, 0xe9, - 0xd0, 0xf3, 0x05, 0x5c, 0xcc, 0xe0, 0xce, 0xa1, 0x98, 0x7f, 0xa9, 0xb4, 0xe7, 0x66, 0xb7, 0xdf, - 0xbe, 0x8f, 0x2b, 0xef, 0xde, 0xc7, 0x95, 0x5f, 0xde, 0xc7, 0x95, 0x57, 0x1f, 0xe2, 0x7d, 0xef, - 0x3e, 0xc4, 0xfb, 0x7e, 0xf8, 0x10, 0xef, 0xfb, 0x5b, 0xba, 0x5c, 0xb5, 0x2a, 0x7b, 0x85, 0x54, - 0x91, 0xd6, 0x7c, 0x6b, 0xc2, 0x41, 0xd3, 0x95, 0xd5, 0xa8, 0x13, 0xb3, 0x10, 0x61, 0x3f, 0xb1, - 0x5c, 0xfe, 0x2d, 0x00, 0x00, 0xff, 0xff, 0xc6, 0x48, 0x99, 0x25, 0xf6, 0x1a, 0x00, 0x00, + // 1800 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcd, 0x4f, 0x1b, 0xcf, + 0x19, 0x66, 0x21, 0x38, 0xf0, 0x1a, 0x02, 0x0c, 0xe4, 0x17, 0x30, 0x60, 0xdc, 0xa1, 0x49, 0x1c, + 0x48, 0xec, 0xe0, 0x48, 0xf9, 0x22, 0x10, 0x61, 0x94, 0x10, 0xf2, 0x49, 0x9d, 0x36, 0xad, 0x5a, + 0xb5, 0xd6, 0xda, 0x1e, 0x8c, 0x93, 0x65, 0xc7, 0xd9, 0x5d, 0x08, 0x6e, 0x84, 0x54, 0xf5, 0xdc, + 0x4a, 0x91, 0x2a, 0xf5, 0xdc, 0x53, 0x6f, 0xed, 0x21, 0x97, 0x1e, 0xa2, 0x5e, 0x7a, 0x69, 0x4e, + 0x55, 0xaa, 0x4a, 0x55, 0x7b, 0x68, 0x55, 0x25, 0xfd, 0x43, 0x7e, 0xda, 0xf9, 0x58, 0x8f, 0xd7, + 0xbb, 0xf6, 0x1a, 0xe5, 0xc4, 0xce, 0xc7, 0xfb, 0xce, 0xf3, 0xbc, 0x33, 0xf3, 0xbe, 0xcf, 0x60, + 0x98, 0xa2, 0x25, 0x9b, 0x58, 0x87, 0xc4, 0xca, 0xbe, 0x3e, 0x20, 0x56, 0x23, 0x53, 0xb7, 0xa8, + 0x43, 0xd1, 0xec, 0xcf, 0x89, 0xa3, 0x97, 0xf7, 0xf4, 0x9a, 0x99, 0x61, 0x5f, 0xd4, 0x22, 0x19, + 0x39, 0x31, 0x31, 0x59, 0xa6, 0xfb, 0xfb, 0xd4, 0xcc, 0xf2, 0x3f, 0xdc, 0x22, 0xb1, 0x54, 0xa6, + 0xf6, 0x3e, 0xb5, 0xb3, 0x25, 0xdd, 0x26, 0xdc, 0x55, 0xf6, 0x70, 0xa5, 0x44, 0x1c, 0x7d, 0x25, + 0x5b, 0xd7, 0xab, 0x35, 0x53, 0x77, 0x6a, 0xde, 0xdc, 0xa9, 0x2a, 0xad, 0x52, 0xf6, 0x99, 0x75, + 0xbf, 0x44, 0xef, 0x5c, 0x95, 0xd2, 0xaa, 0x41, 0xb2, 0x7a, 0xbd, 0x96, 0xd5, 0x4d, 0x93, 0x3a, + 0xcc, 0xc4, 0x16, 0xa3, 0x67, 0x3d, 0x9c, 0x25, 0xdd, 0x30, 0xa8, 0x23, 0x5d, 0x35, 0xbb, 0x0d, + 0x7d, 0x9f, 0xb4, 0x4d, 0x7e, 0x45, 0x1a, 0x55, 0x22, 0xd7, 0x9d, 0xf5, 0xba, 0x4d, 0x5a, 0x21, + 0x45, 0xbd, 0x5c, 0xa6, 0x07, 0xa6, 0xf4, 0x74, 0xce, 0x1b, 0x94, 0x1f, 0x6d, 0xce, 0xea, 0xba, + 0xa5, 0xef, 0x4b, 0x40, 0x0b, 0xcd, 0x6e, 0x62, 0xed, 0xd7, 0x6c, 0xbb, 0x46, 0xcd, 0xe2, 0xae, + 0xa1, 0x57, 0xc5, 0x04, 0xfc, 0x7b, 0x0d, 0x26, 0xbe, 0xe7, 0x06, 0x62, 0xc7, 0xa2, 0x87, 0xa4, + 0x40, 0x5e, 0x1f, 0x10, 0xdb, 0x41, 0x33, 0x30, 0xc4, 0xe2, 0x5a, 0xac, 0x55, 0xa6, 0xb5, 0x94, + 0x96, 0x3e, 0x55, 0x38, 0xcd, 0xda, 0xdb, 0x15, 0x74, 0x0e, 0x4e, 0x3b, 0x47, 0xc5, 0x3d, 0xdd, + 0xde, 0x9b, 0xee, 0x4f, 0x69, 0xe9, 0xe1, 0x42, 0xcc, 0x39, 0x7a, 0xa0, 0xdb, 0x7b, 0x68, 0x11, + 0x06, 0xeb, 0x16, 0xa5, 0xbb, 0xd3, 0x03, 0x29, 0x2d, 0x1d, 0xcf, 0x8d, 0x66, 0x44, 0xe4, 0x77, + 0xdc, 0xce, 0x02, 0x1f, 0x43, 0xf3, 0x00, 0x25, 0x83, 0x96, 0x5f, 0x71, 0x07, 0xa7, 0x98, 0x83, + 0x61, 0xd6, 0xc3, 0x7c, 0xcc, 0xc0, 0x90, 0x73, 0x54, 0xac, 0x99, 0x15, 0x72, 0x34, 0x3d, 0x98, + 0xd2, 0xd2, 0x03, 0x85, 0xd3, 0xce, 0xd1, 0xb6, 0xdb, 0xc4, 0x4b, 0x80, 0x54, 0x9c, 0x76, 0x9d, + 0x9a, 0x36, 0x41, 0x53, 0x30, 0x78, 0xa8, 0x1b, 0x02, 0xe5, 0x50, 0x81, 0x37, 0xf0, 0x94, 0x9c, + 0xcb, 0x42, 0x21, 0x48, 0xe1, 0x1f, 0xc1, 0x64, 0x4b, 0xaf, 0x70, 0xb1, 0x01, 0x31, 0x1e, 0x32, + 0xe6, 0x23, 0x9e, 0x5b, 0xcc, 0x74, 0x38, 0x56, 0x19, 0x6e, 0x9c, 0x3f, 0xf5, 0xf1, 0xbf, 0x0b, + 0x7d, 0x05, 0x61, 0x88, 0x9f, 0x40, 0x92, 0x79, 0xce, 0xb3, 0x4d, 0xcf, 0x37, 0xb6, 0x2b, 0xc4, + 0x74, 0x6a, 0xbb, 0x35, 0x62, 0xc9, 0x80, 0x2e, 0xc3, 0x04, 0x3f, 0x11, 0xc5, 0x9a, 0x37, 0xc6, + 0xd6, 0x1b, 0x2e, 0x8c, 0xf3, 0x81, 0xa6, 0x0d, 0x76, 0x60, 0xf8, 0x05, 0x75, 0x88, 0xf5, 0xb8, + 0x66, 0x3b, 0x68, 0x11, 0x46, 0x0f, 0xdd, 0x46, 0x51, 0xaf, 0x54, 0x2c, 0x62, 0xdb, 0xc2, 0x6a, + 0x84, 0x75, 0x6e, 0xf0, 0x3e, 0x94, 0x87, 0x61, 0xb7, 0x5d, 0x74, 0x1a, 0x75, 0xc2, 0xb6, 0xe5, + 0x4c, 0xee, 0x7c, 0x47, 0x1a, 0xae, 0xff, 0xef, 0x37, 0xea, 0xa4, 0x30, 0x74, 0x28, 0xbe, 0xf0, + 0x9f, 0xfa, 0x61, 0x21, 0x94, 0x85, 0x88, 0x55, 0x2f, 0x34, 0xd0, 0x3a, 0xc4, 0x18, 0x48, 0x7b, + 0xba, 0x3f, 0x35, 0x90, 0x8e, 0xe7, 0x2e, 0x74, 0x45, 0xc4, 0x18, 0x17, 0x84, 0x15, 0xfa, 0x21, + 0x8c, 0xf3, 0x51, 0x76, 0xc5, 0x38, 0xb7, 0x01, 0xc6, 0xed, 0x72, 0x47, 0x4f, 0xcf, 0x9a, 0x46, + 0x8c, 0xe2, 0x18, 0x6d, 0xed, 0x40, 0x4f, 0x61, 0x54, 0xb0, 0xb0, 0x1d, 0xdd, 0x39, 0xb0, 0xd9, + 0x39, 0x3c, 0x93, 0xbb, 0xd4, 0xd1, 0x2b, 0x8f, 0xca, 0x73, 0x66, 0x50, 0x18, 0x29, 0x29, 0x2d, + 0xfc, 0x08, 0xe6, 0x58, 0xe0, 0x9e, 0x89, 0xb9, 0x76, 0xbe, 0xb1, 0xe9, 0x7a, 0x51, 0x36, 0x5f, + 0x25, 0xc2, 0x56, 0x90, 0x51, 0x53, 0x06, 0x98, 0x0d, 0x5e, 0x83, 0xf9, 0x10, 0x67, 0x62, 0x0f, + 0xe6, 0x60, 0x58, 0x82, 0x72, 0x0f, 0xc3, 0x80, 0x7b, 0x83, 0xbc, 0x0e, 0x9c, 0x12, 0x47, 0x71, + 0xc3, 0x30, 0xa4, 0x87, 0x27, 0x7a, 0xbd, 0x4e, 0x2c, 0xef, 0x1a, 0x34, 0xc4, 0x36, 0x07, 0xcd, + 0x10, 0x4b, 0xbc, 0x90, 0x91, 0x27, 0x56, 0x71, 0x9f, 0x8f, 0xb1, 0x95, 0xe2, 0xb9, 0xe5, 0x08, + 0x91, 0x97, 0xfe, 0x64, 0xe0, 0x3d, 0xff, 0xf8, 0x1b, 0x98, 0x62, 0x4b, 0x3f, 0x3f, 0xa8, 0xd7, + 0xa9, 0xe5, 0x90, 0x0a, 0x63, 0x66, 0xe3, 0x7b, 0x22, 0x80, 0xbe, 0x7e, 0x0f, 0xcf, 0x79, 0x88, + 0xb1, 0x25, 0x25, 0x0a, 0x2f, 0xb7, 0xf0, 0xc8, 0x88, 0x41, 0xbc, 0x0e, 0xdf, 0x61, 0x6e, 0xb6, + 0x88, 0xb3, 0x49, 0x2d, 0xc2, 0xaf, 0xea, 0x7d, 0x6a, 0xb5, 0x6c, 0x86, 0x3f, 0xb5, 0x0d, 0x78, + 0xa9, 0x0d, 0x9b, 0x80, 0x3b, 0xd9, 0x0b, 0x30, 0x0f, 0x20, 0xee, 0xb2, 0x2e, 0xb6, 0x24, 0x8d, + 0x8b, 0x1d, 0xe3, 0xd2, 0xf4, 0x56, 0x80, 0xb2, 0xf7, 0x8d, 0x67, 0x61, 0xa6, 0x7d, 0x3d, 0xb9, + 0x4d, 0x2f, 0x21, 0x11, 0x34, 0x28, 0x40, 0x3c, 0x0e, 0x02, 0xb1, 0x1c, 0x11, 0x04, 0xbb, 0x65, + 0x2a, 0x90, 0x5c, 0x73, 0xad, 0xa7, 0xb4, 0x42, 0x36, 0x78, 0xc9, 0x91, 0x11, 0x9b, 0x82, 0x41, + 0x9e, 0x91, 0xf9, 0x91, 0xe5, 0x0d, 0xfc, 0x12, 0x66, 0x03, 0x6d, 0x04, 0xc0, 0x47, 0x30, 0xa2, + 0x96, 0x2f, 0x81, 0x30, 0xdd, 0x11, 0xa1, 0xea, 0x27, 0x6e, 0x36, 0x1b, 0xb8, 0x22, 0xf0, 0x6d, + 0x18, 0x46, 0x00, 0xbe, 0xfb, 0x00, 0xcd, 0xe2, 0x2d, 0x16, 0xba, 0x90, 0xe1, 0x95, 0x3e, 0xe3, + 0x56, 0xfa, 0x0c, 0x17, 0x0d, 0xa2, 0xd2, 0x67, 0x76, 0xf4, 0xaa, 0x2c, 0x74, 0x05, 0xc5, 0x12, + 0xbf, 0xd7, 0x04, 0x25, 0xff, 0x32, 0x82, 0xd2, 0x43, 0x88, 0x2b, 0xdd, 0xe2, 0x28, 0xf6, 0xc0, + 0x48, 0x69, 0xa0, 0xad, 0x16, 0xcc, 0xfd, 0xe2, 0x0c, 0x75, 0xc3, 0xcc, 0x81, 0xb4, 0x80, 0x96, + 0xf7, 0x7d, 0x8b, 0x38, 0x3b, 0x5e, 0x85, 0xbf, 0xef, 0x16, 0x78, 0x79, 0x90, 0x7e, 0xa1, 0x89, + 0x0b, 0x1f, 0x34, 0x45, 0x50, 0xfb, 0x29, 0x8c, 0xfb, 0xf5, 0x81, 0x08, 0x64, 0xe7, 0x54, 0xeb, + 0xf3, 0x27, 0xca, 0xe2, 0x58, 0xbd, 0xb5, 0x1b, 0x9f, 0x83, 0xb3, 0x12, 0xc1, 0x23, 0x26, 0x75, + 0x24, 0xb6, 0x1f, 0xc0, 0x37, 0xfe, 0x01, 0x81, 0x68, 0x15, 0x62, 0x5c, 0x15, 0x45, 0xaa, 0xca, + 0xc2, 0x58, 0x98, 0xe0, 0x05, 0x91, 0x43, 0x9f, 0xef, 0xd1, 0x37, 0x32, 0x27, 0x6d, 0x2a, 0x47, + 0xc6, 0x8d, 0x49, 0x32, 0x6c, 0x86, 0x00, 0xf0, 0x33, 0x98, 0x34, 0x74, 0xdb, 0x29, 0x7a, 0x89, + 0x50, 0x3d, 0xc7, 0x99, 0x8e, 0x68, 0x1e, 0xeb, 0xb6, 0xd3, 0xea, 0x74, 0xc2, 0xf0, 0x77, 0xe1, + 0x87, 0x02, 0x63, 0xde, 0x55, 0x84, 0x41, 0x92, 0xe1, 0x12, 0x8c, 0x33, 0xb5, 0xd8, 0x5e, 0x6a, + 0xc7, 0x58, 0xbf, 0x22, 0x18, 0xca, 0x52, 0x7f, 0xb4, 0xfb, 0xf2, 0x44, 0x0e, 0x08, 0x67, 0xe6, + 0x2e, 0x15, 0x24, 0x70, 0xe7, 0x7a, 0xe7, 0x4e, 0x77, 0xb5, 0x99, 0xbb, 0x94, 0xb9, 0x4b, 0xf1, + 0x7c, 0xf3, 0x76, 0xf0, 0x31, 0x52, 0xa6, 0x56, 0xc5, 0x3b, 0x66, 0xba, 0xc8, 0xe1, 0x6d, 0xc3, + 0x21, 0x08, 0x06, 0x7a, 0x47, 0xa0, 0xa4, 0x81, 0x3c, 0x93, 0x8c, 0x44, 0xaf, 0x34, 0xe3, 0xf5, + 0xb5, 0xd2, 0xc0, 0xef, 0x34, 0x95, 0xa8, 0xb2, 0x8c, 0x20, 0x72, 0x13, 0x46, 0x85, 0x84, 0x65, + 0xfd, 0xb2, 0x26, 0x4d, 0xca, 0x9a, 0xa4, 0xda, 0x8c, 0x94, 0x9a, 0x0d, 0xfb, 0xeb, 0x5d, 0xfa, + 0x0d, 0x48, 0xc9, 0x6b, 0xa3, 0xac, 0x96, 0x6f, 0xb8, 0x1a, 0x5a, 0x86, 0xa3, 0x55, 0x69, 0xbb, + 0xe1, 0x18, 0x51, 0x94, 0x36, 0xfe, 0x49, 0xb3, 0x56, 0x06, 0xb8, 0x10, 0x54, 0xaf, 0xc3, 0x88, + 0x4a, 0x55, 0x04, 0x35, 0x90, 0x69, 0x5c, 0x61, 0x9a, 0xfb, 0xf5, 0x0c, 0x0c, 0x32, 0xef, 0xe8, + 0x9d, 0x06, 0x31, 0x5e, 0x64, 0x50, 0xb6, 0xe3, 0x66, 0xb7, 0xeb, 0xf5, 0xc4, 0xd5, 0xe8, 0x06, + 0x1c, 0x2f, 0x5e, 0xfc, 0xe5, 0x3f, 0xfe, 0xff, 0x9b, 0xfe, 0x79, 0x34, 0x9b, 0x75, 0xe7, 0x5f, + 0x61, 0xa6, 0x59, 0xdf, 0xc3, 0x08, 0xfd, 0x53, 0x03, 0xd4, 0x2e, 0x71, 0xd1, 0x6a, 0xf7, 0xd5, + 0x42, 0xe5, 0x7d, 0xe2, 0xce, 0xc9, 0x8c, 0x05, 0xec, 0x7b, 0x0c, 0xf6, 0x5d, 0xb4, 0x16, 0x08, + 0x5b, 0x48, 0xd5, 0x52, 0x43, 0x49, 0x04, 0xd9, 0xb7, 0x6d, 0x32, 0xfc, 0x18, 0xfd, 0x4d, 0x83, + 0x71, 0xbf, 0x6a, 0x44, 0xb7, 0xba, 0x23, 0x0b, 0x91, 0xad, 0x89, 0xdb, 0x27, 0x31, 0x15, 0x94, + 0x36, 0x19, 0xa5, 0x35, 0xb4, 0x1a, 0x48, 0xc9, 0x93, 0xab, 0x2e, 0x2b, 0x3e, 0xf6, 0xb6, 0x4d, + 0x21, 0x1f, 0xa3, 0xbf, 0x68, 0x80, 0xda, 0x55, 0x6a, 0x94, 0x9d, 0x0a, 0x55, 0xbf, 0x51, 0x76, + 0x2a, 0x5c, 0x18, 0xe3, 0x15, 0x46, 0x6b, 0x19, 0x5d, 0x0a, 0xa4, 0xa5, 0x1b, 0x46, 0xd1, 0xaf, + 0x9b, 0xd1, 0x1f, 0x34, 0x18, 0xf3, 0xe9, 0x5a, 0xb4, 0xd2, 0x1d, 0x84, 0xcf, 0x24, 0x71, 0xab, + 0x67, 0x13, 0x0f, 0xf4, 0x65, 0x06, 0xfa, 0x02, 0xfa, 0x6e, 0x20, 0x68, 0xdb, 0x87, 0xed, 0x3f, + 0x1a, 0x9c, 0x0d, 0x14, 0xc0, 0x68, 0xbd, 0x3b, 0x84, 0x4e, 0xca, 0x3b, 0x71, 0xf7, 0xc4, 0xf6, + 0x91, 0x0e, 0x55, 0x95, 0x38, 0xc5, 0xb2, 0x51, 0x23, 0xa6, 0x23, 0x54, 0x71, 0x71, 0x97, 0x5a, + 0xf2, 0x74, 0x49, 0xc9, 0x7f, 0x8c, 0xfe, 0xa8, 0xc1, 0x68, 0xcb, 0x32, 0xe8, 0x7a, 0x8f, 0xb8, + 0x24, 0x9f, 0x1b, 0x3d, 0xdb, 0x45, 0xda, 0x10, 0xc6, 0xa3, 0xa9, 0xed, 0xd1, 0x7b, 0xad, 0x45, + 0x77, 0xa2, 0x68, 0xcb, 0xb6, 0xeb, 0xe4, 0xc4, 0xcd, 0xde, 0x0d, 0x05, 0xe0, 0xab, 0x0c, 0xf0, + 0x12, 0x4a, 0x07, 0x02, 0x56, 0x94, 0x7a, 0xf6, 0x2d, 0x7b, 0x1c, 0x1c, 0xbb, 0xa7, 0xfe, 0x8c, + 0xe2, 0x69, 0xc3, 0x30, 0xa2, 0xe0, 0x0e, 0xd4, 0xf7, 0x51, 0x70, 0x07, 0x2b, 0x76, 0x9c, 0x66, + 0xb8, 0x31, 0x4a, 0x75, 0xc3, 0x8d, 0x3e, 0x68, 0x30, 0xe6, 0x13, 0xb3, 0x51, 0xf2, 0x4c, 0xa8, + 0xea, 0x8e, 0x92, 0x67, 0xc2, 0xf5, 0x38, 0xbe, 0xc2, 0x80, 0x5f, 0x44, 0xe7, 0x83, 0x0b, 0x99, + 0x4f, 0xaa, 0xa3, 0xdf, 0x6a, 0x10, 0xe3, 0x12, 0x18, 0xe5, 0x22, 0xad, 0xdb, 0xa2, 0xc2, 0x13, + 0xd7, 0x7a, 0xb2, 0x89, 0x54, 0x6b, 0xb9, 0x10, 0x47, 0x7f, 0xd5, 0x60, 0xa2, 0x4d, 0x62, 0xa3, + 0x08, 0x85, 0x25, 0x4c, 0xb9, 0x27, 0x56, 0x4f, 0x64, 0x2b, 0x30, 0xdf, 0x62, 0x98, 0xaf, 0xa1, + 0x15, 0x15, 0xb3, 0xf4, 0xa2, 0xa4, 0xc4, 0x3d, 0xfa, 0xc6, 0xa7, 0xfb, 0xd1, 0xdf, 0x35, 0x98, + 0x68, 0x93, 0xd7, 0x51, 0x98, 0x84, 0xe9, 0xfb, 0x28, 0x4c, 0x42, 0xf5, 0x7c, 0x97, 0x54, 0xc8, + 0x85, 0xb6, 0x5f, 0x31, 0xf8, 0x1e, 0x13, 0xc7, 0xe8, 0xcf, 0x1a, 0xa0, 0x2d, 0xe2, 0xf8, 0x14, + 0x3b, 0x8a, 0x76, 0xdf, 0x02, 0xde, 0x00, 0x51, 0x8a, 0x54, 0xc8, 0xf3, 0x00, 0xe7, 0x18, 0xa1, + 0xcb, 0x68, 0x29, 0x34, 0x27, 0xba, 0xd5, 0x95, 0x73, 0xb0, 0x04, 0xd0, 0x0f, 0x0a, 0x7e, 0x45, + 0x66, 0xdf, 0x88, 0x88, 0xc2, 0xff, 0x82, 0x48, 0xdc, 0xec, 0xdd, 0xb0, 0x47, 0xf4, 0xca, 0xb3, + 0x01, 0xfd, 0x5b, 0x83, 0xa9, 0x20, 0xf5, 0x8d, 0xd6, 0x22, 0x5d, 0xc7, 0x30, 0xe1, 0x9f, 0x58, + 0x3f, 0xa9, 0xb9, 0xe0, 0x92, 0x67, 0x5c, 0xee, 0xa0, 0xdb, 0xa1, 0x5c, 0x54, 0x1e, 0xee, 0x29, + 0x73, 0x5f, 0x18, 0xee, 0xf9, 0x92, 0xaf, 0x8d, 0x63, 0xf4, 0x2b, 0x0d, 0x06, 0xd9, 0x3f, 0xea, + 0x51, 0x26, 0x82, 0x88, 0x57, 0x7e, 0x79, 0x48, 0x64, 0x23, 0xcf, 0x17, 0x70, 0x31, 0x83, 0x3b, + 0x87, 0x12, 0xc1, 0xa9, 0xd2, 0x9d, 0x9b, 0xdf, 0xfe, 0xf8, 0x39, 0xa9, 0x7d, 0xfa, 0x9c, 0xd4, + 0xfe, 0xf7, 0x39, 0xa9, 0xbd, 0xfb, 0x92, 0xec, 0xfb, 0xf4, 0x25, 0xd9, 0xf7, 0xaf, 0x2f, 0xc9, + 0xbe, 0x1f, 0x67, 0xab, 0x35, 0x67, 0xef, 0xa0, 0xe4, 0xbe, 0x68, 0x02, 0x73, 0xc2, 0x51, 0xd3, + 0x95, 0xd3, 0xa8, 0x13, 0xbb, 0x14, 0x63, 0x3f, 0x9b, 0x5c, 0xfb, 0x36, 0x00, 0x00, 0xff, 0xff, + 0x2e, 0xac, 0xc8, 0xff, 0x92, 0x1a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2452,14 +2450,14 @@ func (m *QueryProveRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.TxIndex != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.TxIndex)) i-- - dAtA[i] = 0x38 + dAtA[i] = 0x28 } if len(m.BlockHash) > 0 { i -= len(m.BlockHash) copy(dAtA[i:], m.BlockHash) i = encodeVarintQuery(dAtA, i, uint64(len(m.BlockHash))) i-- - dAtA[i] = 0x32 + dAtA[i] = 0x22 } if m.Proof != nil { { @@ -2471,7 +2469,7 @@ func (m *QueryProveRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x1a } if len(m.TxHash) > 0 { i -= len(m.TxHash) @@ -4157,7 +4155,7 @@ func (m *QueryProveRequest) Unmarshal(dAtA []byte) error { } m.TxHash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) } @@ -4187,13 +4185,13 @@ func (m *QueryProveRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Proof == nil { - m.Proof = ðereum.Proof{} + m.Proof = &common.Proof{} } if err := m.Proof.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 6: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BlockHash", wireType) } @@ -4225,7 +4223,7 @@ func (m *QueryProveRequest) Unmarshal(dAtA []byte) error { } m.BlockHash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field TxIndex", wireType) } @@ -6753,7 +6751,7 @@ func (m *QueryAllBlockHeaderResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BlockHeaders = append(m.BlockHeaders, &BlockHeader{}) + m.BlockHeaders = append(m.BlockHeaders, &common.BlockHeader{}) if err := m.BlockHeaders[len(m.BlockHeaders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -6958,7 +6956,7 @@ func (m *QueryGetBlockHeaderByHashResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.BlockHeader == nil { - m.BlockHeader = &BlockHeader{} + m.BlockHeader = &common.BlockHeader{} } if err := m.BlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/observer/types/tx.pb.go b/x/observer/types/tx.pb.go index 8019e5dc5a..cb6f2df8f9 100644 --- a/x/observer/types/tx.pb.go +++ b/x/observer/types/tx.pb.go @@ -13,7 +13,7 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" - _ "github.com/zeta-chain/zetacore/common" + common "github.com/zeta-chain/zetacore/common" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -31,11 +31,11 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type MsgAddBlockHeader struct { - Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` - ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - BlockHash []byte `protobuf:"bytes,3,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` - BlockHeader []byte `protobuf:"bytes,4,opt,name=block_header,json=blockHeader,proto3" json:"block_header,omitempty"` - Height int64 `protobuf:"varint,5,opt,name=height,proto3" json:"height,omitempty"` + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + BlockHash []byte `protobuf:"bytes,3,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + Height int64 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"` + Header common.HeaderData `protobuf:"bytes,5,opt,name=header,proto3" json:"header"` } func (m *MsgAddBlockHeader) Reset() { *m = MsgAddBlockHeader{} } @@ -92,18 +92,18 @@ func (m *MsgAddBlockHeader) GetBlockHash() []byte { return nil } -func (m *MsgAddBlockHeader) GetBlockHeader() []byte { +func (m *MsgAddBlockHeader) GetHeight() int64 { if m != nil { - return m.BlockHeader + return m.Height } - return nil + return 0 } -func (m *MsgAddBlockHeader) GetHeight() int64 { +func (m *MsgAddBlockHeader) GetHeader() common.HeaderData { if m != nil { - return m.Height + return m.Header } - return 0 + return common.HeaderData{} } type MsgAddBlockHeaderResponse struct { @@ -632,53 +632,53 @@ func init() { func init() { proto.RegisterFile("observer/tx.proto", fileDescriptor_1bcd40fa296a2b1d) } var fileDescriptor_1bcd40fa296a2b1d = []byte{ - // 723 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xcb, 0x6e, 0xd3, 0x4c, - 0x14, 0xae, 0xff, 0xfe, 0xbd, 0xe4, 0xa4, 0xea, 0xc5, 0xbd, 0x39, 0xa9, 0x1a, 0x05, 0x6f, 0x28, - 0x50, 0x62, 0x68, 0x01, 0x21, 0x24, 0x16, 0x29, 0x82, 0x36, 0x42, 0xa5, 0x95, 0x25, 0x58, 0xb0, - 0xb1, 0xc6, 0x9e, 0x53, 0xdb, 0x6a, 0x3c, 0x13, 0x79, 0x1c, 0x94, 0xb0, 0x60, 0xcf, 0x02, 0xc4, - 0x33, 0xf0, 0x2c, 0x2c, 0x58, 0x76, 0xc9, 0x12, 0xb5, 0x1b, 0x1e, 0x03, 0x65, 0x7c, 0x69, 0x2e, - 0x25, 0x4d, 0xba, 0xf2, 0xcc, 0x39, 0xdf, 0xf9, 0xce, 0x77, 0x2e, 0xd6, 0xc0, 0x12, 0xb7, 0x05, - 0x86, 0x1f, 0x30, 0x34, 0xa2, 0x56, 0xa5, 0x11, 0xf2, 0x88, 0xab, 0x1b, 0x1f, 0x31, 0x22, 0x8e, - 0x47, 0x7c, 0x56, 0x91, 0x27, 0x1e, 0x62, 0x25, 0x45, 0x15, 0x97, 0x1d, 0x1e, 0x04, 0x9c, 0x19, - 0xf1, 0x27, 0x8e, 0x28, 0xae, 0xb8, 0xdc, 0xe5, 0xf2, 0x68, 0x74, 0x4e, 0xa9, 0x35, 0xa3, 0xb6, - 0xeb, 0x24, 0xc0, 0xc4, 0xba, 0x96, 0x59, 0x3d, 0x24, 0x14, 0x43, 0x91, 0xd8, 0xd7, 0x33, 0x7b, - 0x7a, 0x48, 0x1c, 0xab, 0x99, 0xa3, 0x41, 0x42, 0x12, 0x24, 0x78, 0xfd, 0xbb, 0x02, 0x4b, 0x87, - 0xc2, 0xad, 0x52, 0xba, 0x57, 0xe7, 0xce, 0xe9, 0x81, 0x24, 0x53, 0x35, 0x98, 0x71, 0x42, 0x24, - 0x11, 0x0f, 0x35, 0xa5, 0xac, 0x6c, 0xe5, 0xcc, 0xf4, 0xaa, 0x16, 0x60, 0x56, 0xd6, 0x64, 0xf9, - 0x54, 0xfb, 0xaf, 0xac, 0x6c, 0x4d, 0x9a, 0x33, 0xf2, 0x5e, 0xa3, 0xea, 0x26, 0x80, 0xdd, 0xe1, - 0xb0, 0x3c, 0x22, 0x3c, 0x6d, 0xb2, 0xac, 0x6c, 0xcd, 0x99, 0x39, 0x69, 0x39, 0x20, 0xc2, 0x53, - 0x6f, 0xc1, 0x5c, 0xe2, 0x96, 0x39, 0xb4, 0xff, 0x25, 0x20, 0x6f, 0x77, 0xa5, 0x5d, 0x83, 0x69, - 0x0f, 0x7d, 0xd7, 0x8b, 0xb4, 0x29, 0x49, 0x9d, 0xdc, 0xf4, 0x0d, 0x28, 0x0c, 0x68, 0x34, 0x51, - 0x34, 0x38, 0x13, 0xa8, 0xb7, 0x60, 0xf9, 0x50, 0xb8, 0x6f, 0x1b, 0x94, 0x44, 0xf8, 0x82, 0x87, - 0x78, 0x2c, 0xcb, 0x1b, 0x52, 0xc2, 0x3e, 0x80, 0x93, 0xe1, 0x64, 0x11, 0xf9, 0x9d, 0xdb, 0x95, - 0x21, 0xd3, 0xaa, 0x5c, 0xd2, 0x9a, 0x5d, 0xa1, 0xfa, 0x26, 0x6c, 0x5c, 0x91, 0x39, 0x13, 0xf6, - 0x43, 0x81, 0xf9, 0x58, 0xf6, 0x51, 0x42, 0x34, 0x44, 0xd4, 0x1d, 0x58, 0x4c, 0xd3, 0x59, 0x84, - 0xd2, 0x10, 0x45, 0x2c, 0x2d, 0x67, 0x2e, 0xa4, 0xf6, 0x6a, 0x6c, 0x56, 0x9f, 0x41, 0x41, 0x4a, - 0xac, 0xfb, 0xc8, 0x22, 0xcb, 0x0d, 0x09, 0x8b, 0x10, 0xad, 0x46, 0xd3, 0x3e, 0xc5, 0xb6, 0x6c, - 0x7b, 0xce, 0x5c, 0xbf, 0x04, 0xec, 0xc7, 0xfe, 0x63, 0xe9, 0x56, 0x1f, 0xc2, 0x2a, 0xa1, 0xd4, - 0x62, 0x9c, 0xa2, 0x45, 0x1c, 0x87, 0x37, 0x59, 0x64, 0x71, 0x56, 0x6f, 0xcb, 0x69, 0xcc, 0x9a, - 0x2a, 0xa1, 0xf4, 0x0d, 0xa7, 0x58, 0x8d, 0x5d, 0x47, 0xac, 0xde, 0xd6, 0x35, 0x58, 0xeb, 0xad, - 0x22, 0x2b, 0xf0, 0xb3, 0x02, 0x0b, 0xe9, 0x5c, 0x48, 0x80, 0xef, 0x78, 0x84, 0x37, 0xdb, 0x9c, - 0x6a, 0x67, 0x73, 0x48, 0x80, 0x96, 0xcf, 0x4e, 0xb8, 0x2c, 0x21, 0xbf, 0xa3, 0x0f, 0x9d, 0x88, - 0x4c, 0xd8, 0xd9, 0x2e, 0x12, 0x60, 0x8d, 0x9d, 0x70, 0xbd, 0x00, 0xeb, 0x7d, 0x52, 0x32, 0x99, - 0x5f, 0x15, 0xd0, 0xb2, 0x39, 0x1d, 0x63, 0x18, 0xf8, 0x42, 0xf8, 0x9c, 0xbd, 0xaa, 0x13, 0x77, - 0xd8, 0x9a, 0xdc, 0x85, 0x45, 0x5f, 0xd4, 0x98, 0xcd, 0x9b, 0x8c, 0xbe, 0x64, 0xc4, 0xae, 0x23, - 0x95, 0xd2, 0x66, 0xcd, 0x01, 0xbb, 0xba, 0x0d, 0x4b, 0xbe, 0x38, 0x6a, 0x46, 0x3d, 0xe0, 0xb8, - 0xa5, 0x83, 0x0e, 0x5d, 0x87, 0xf2, 0xbf, 0xf4, 0x64, 0xa2, 0xab, 0xb2, 0xb5, 0x31, 0xe6, 0x35, - 0xb6, 0x5d, 0x64, 0x43, 0xa4, 0xae, 0xc0, 0x94, 0xfc, 0x8d, 0x92, 0xbe, 0xc6, 0x97, 0xa4, 0x25, - 0xdd, 0x14, 0x29, 0xfb, 0xce, 0x9f, 0x29, 0x98, 0x3c, 0x14, 0xae, 0xca, 0x21, 0xdf, 0xbd, 0x9e, - 0xf7, 0x86, 0xf6, 0xbc, 0x77, 0x0b, 0x8a, 0xbb, 0x63, 0x80, 0xd3, 0xc4, 0xea, 0x27, 0x58, 0x1c, - 0xf8, 0x53, 0x1f, 0x5c, 0x47, 0xd4, 0x1f, 0x51, 0x7c, 0x3a, 0x6e, 0x44, 0x96, 0x3f, 0x84, 0xb9, - 0x9e, 0x75, 0xdd, 0x1e, 0xa1, 0x88, 0x0c, 0x5d, 0x7c, 0x34, 0x0e, 0x3a, 0xcb, 0xf9, 0x45, 0x81, - 0xd5, 0xab, 0x97, 0xef, 0xf1, 0x68, 0x75, 0xf4, 0x85, 0x15, 0x9f, 0xdf, 0x28, 0xac, 0xbb, 0x07, - 0x3d, 0x7b, 0xb5, 0x3d, 0x1a, 0x5d, 0x8c, 0xbe, 0xbe, 0x07, 0x57, 0x2d, 0x9c, 0xda, 0x82, 0xf9, - 0xbe, 0x27, 0xa6, 0x32, 0x52, 0x2f, 0x33, 0x7c, 0xf1, 0xc9, 0x78, 0xf8, 0x34, 0xf3, 0x5e, 0xed, - 0xe7, 0x79, 0x49, 0x39, 0x3b, 0x2f, 0x29, 0xbf, 0xcf, 0x4b, 0xca, 0xb7, 0x8b, 0xd2, 0xc4, 0xd9, - 0x45, 0x69, 0xe2, 0xd7, 0x45, 0x69, 0xe2, 0xbd, 0xe1, 0xfa, 0x91, 0xd7, 0xb4, 0x2b, 0x0e, 0x0f, - 0x8c, 0x0e, 0xe3, 0x7d, 0x49, 0x6e, 0xa4, 0xe4, 0x46, 0xcb, 0xb8, 0x7c, 0xd4, 0xdb, 0x0d, 0x14, - 0xf6, 0xb4, 0x7c, 0x32, 0x77, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x14, 0x0f, 0x4d, 0xed, - 0x07, 0x00, 0x00, + // 731 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x49, 0x6f, 0xd3, 0x40, + 0x14, 0x8e, 0xe9, 0x9a, 0x97, 0xaa, 0x8b, 0xbb, 0x39, 0xa9, 0x1a, 0x22, 0x5f, 0x08, 0x50, 0xe2, + 0x92, 0x02, 0x42, 0x48, 0x1c, 0x52, 0x96, 0x36, 0x42, 0xa5, 0x95, 0x25, 0x38, 0x70, 0xb1, 0xc6, + 0x99, 0x57, 0xc7, 0x6a, 0x3c, 0x13, 0xd9, 0x0e, 0x4a, 0x38, 0x70, 0xe7, 0x00, 0xe2, 0xaf, 0xf0, + 0x1f, 0x38, 0xf4, 0xd8, 0x23, 0x27, 0x84, 0xda, 0x0b, 0x3f, 0x03, 0x79, 0xbc, 0x34, 0x4b, 0x49, + 0x93, 0x9e, 0x3c, 0xf3, 0xde, 0xf7, 0xbe, 0xf7, 0xbd, 0xc5, 0x1a, 0x58, 0xe2, 0xa6, 0x87, 0xee, + 0x47, 0x74, 0x35, 0xbf, 0x5d, 0x6a, 0xba, 0xdc, 0xe7, 0xf2, 0xc6, 0x27, 0xf4, 0x49, 0xad, 0x4e, + 0x6c, 0x56, 0x12, 0x27, 0xee, 0x62, 0x29, 0x46, 0xe5, 0x96, 0x6b, 0xdc, 0x71, 0x38, 0xd3, 0xc2, + 0x4f, 0x18, 0x91, 0x5b, 0xb1, 0xb8, 0xc5, 0xc5, 0x51, 0x0b, 0x4e, 0xb1, 0x35, 0xa1, 0x36, 0x1b, + 0xc4, 0xc1, 0xc8, 0xba, 0x9e, 0x58, 0xe3, 0x43, 0xe4, 0x58, 0x4d, 0x1c, 0x4d, 0xe2, 0x12, 0xc7, + 0x0b, 0xcd, 0xea, 0x0f, 0x09, 0x96, 0x0e, 0x3c, 0xab, 0x42, 0xe9, 0x6e, 0x83, 0xd7, 0x4e, 0xf6, + 0x91, 0x50, 0x74, 0x65, 0x05, 0x66, 0x6a, 0x2e, 0x12, 0x9f, 0xbb, 0x8a, 0x54, 0x90, 0x8a, 0x69, + 0x3d, 0xbe, 0xca, 0x59, 0x98, 0x15, 0xda, 0x0d, 0x9b, 0x2a, 0xb7, 0x0a, 0x52, 0x71, 0x42, 0x9f, + 0x11, 0xf7, 0x2a, 0x95, 0x37, 0x01, 0xcc, 0x80, 0xc3, 0xa8, 0x13, 0xaf, 0xae, 0x4c, 0x14, 0xa4, + 0xe2, 0x9c, 0x9e, 0x16, 0x96, 0x7d, 0xe2, 0xd5, 0xe5, 0x35, 0x98, 0xae, 0xa3, 0x6d, 0xd5, 0x7d, + 0x65, 0x52, 0xc4, 0x45, 0x37, 0x79, 0x3b, 0xb0, 0x07, 0x59, 0x95, 0xa9, 0x82, 0x54, 0xcc, 0x94, + 0xe5, 0x52, 0x54, 0x7c, 0xa8, 0xe5, 0x25, 0xf1, 0xc9, 0xee, 0xe4, 0xe9, 0xef, 0xdb, 0x29, 0x3d, + 0xc2, 0xa9, 0x1b, 0x90, 0x1d, 0x90, 0xac, 0xa3, 0xd7, 0xe4, 0xcc, 0x43, 0xb5, 0x0d, 0xcb, 0x07, + 0x9e, 0xf5, 0xae, 0x49, 0x89, 0x8f, 0x2f, 0xb8, 0x8b, 0x47, 0xa2, 0xda, 0x21, 0x15, 0xed, 0x01, + 0xd4, 0x12, 0x9c, 0xa8, 0x29, 0x53, 0xbe, 0x53, 0x1a, 0x32, 0xa4, 0xd2, 0x25, 0xad, 0xde, 0x15, + 0xaa, 0x6e, 0xc2, 0xc6, 0x15, 0x99, 0x13, 0x61, 0x3f, 0x25, 0x98, 0x0f, 0x65, 0x1f, 0x46, 0x44, + 0x43, 0x44, 0xdd, 0x85, 0xc5, 0x38, 0x9d, 0x41, 0x28, 0x75, 0xd1, 0x0b, 0xa5, 0xa5, 0xf5, 0x85, + 0xd8, 0x5e, 0x09, 0xcd, 0xf2, 0x33, 0xc8, 0x0a, 0x89, 0x0d, 0x1b, 0x99, 0x6f, 0x58, 0x2e, 0x61, + 0x3e, 0xa2, 0xd1, 0x6c, 0x99, 0x27, 0xd8, 0x11, 0x53, 0x48, 0xeb, 0xeb, 0x97, 0x80, 0xbd, 0xd0, + 0x7f, 0x24, 0xdc, 0xf2, 0x43, 0x58, 0x25, 0x94, 0x1a, 0x8c, 0x53, 0x34, 0x48, 0xad, 0xc6, 0x5b, + 0xcc, 0x37, 0x38, 0x6b, 0x74, 0xc4, 0x88, 0x66, 0x75, 0x99, 0x50, 0xfa, 0x96, 0x53, 0xac, 0x84, + 0xae, 0x43, 0xd6, 0xe8, 0xa8, 0x0a, 0xac, 0xf5, 0x56, 0x91, 0x14, 0xf8, 0x45, 0x82, 0x85, 0x78, + 0x2e, 0xc4, 0xc1, 0xf7, 0xdc, 0xc7, 0x9b, 0x2d, 0x52, 0x25, 0x58, 0x24, 0xe2, 0xa0, 0x61, 0xb3, + 0x63, 0x2e, 0x4a, 0xc8, 0x94, 0xd5, 0xa1, 0x13, 0x11, 0x09, 0x83, 0x65, 0x23, 0x0e, 0x56, 0xd9, + 0x31, 0x57, 0xb3, 0xb0, 0xde, 0x27, 0x25, 0x91, 0xf9, 0x4d, 0x02, 0x25, 0x99, 0xd3, 0x11, 0xba, + 0x8e, 0xed, 0x79, 0x36, 0x67, 0xaf, 0x1b, 0xc4, 0x1a, 0xb6, 0x26, 0xf7, 0x60, 0xd1, 0xf6, 0xaa, + 0xcc, 0xe4, 0x2d, 0x46, 0x5f, 0x31, 0x62, 0x36, 0x90, 0x0a, 0x69, 0xb3, 0xfa, 0x80, 0x5d, 0xde, + 0x82, 0x25, 0xdb, 0x3b, 0x6c, 0xf9, 0x3d, 0xe0, 0xb0, 0xa5, 0x83, 0x0e, 0x55, 0x85, 0xc2, 0xff, + 0xf4, 0x24, 0xa2, 0x2b, 0xa2, 0xb5, 0x21, 0xe6, 0x0d, 0x76, 0x2c, 0x64, 0x43, 0xa4, 0xae, 0xc0, + 0x94, 0xf8, 0xed, 0xa2, 0xbe, 0x86, 0x97, 0xa8, 0x25, 0xdd, 0x14, 0x31, 0x7b, 0xf9, 0xef, 0x14, + 0x4c, 0x1c, 0x78, 0x96, 0xcc, 0x21, 0xd3, 0xbd, 0x9e, 0xf7, 0x87, 0xf6, 0xbc, 0x77, 0x0b, 0x72, + 0x3b, 0x63, 0x80, 0xe3, 0xc4, 0xf2, 0x67, 0x58, 0x1c, 0xf8, 0x53, 0xb7, 0xaf, 0x23, 0xea, 0x8f, + 0xc8, 0x3d, 0x1d, 0x37, 0x22, 0xc9, 0xef, 0xc2, 0x5c, 0xcf, 0xba, 0x6e, 0x8d, 0x50, 0x44, 0x82, + 0xce, 0x3d, 0x1a, 0x07, 0x9d, 0xe4, 0xfc, 0x2a, 0xc1, 0xea, 0xd5, 0xcb, 0xf7, 0x78, 0xb4, 0x3a, + 0xfa, 0xc2, 0x72, 0xcf, 0x6f, 0x14, 0xd6, 0xdd, 0x83, 0x9e, 0xbd, 0xda, 0x1a, 0x8d, 0x2e, 0x44, + 0x5f, 0xdf, 0x83, 0xab, 0x16, 0x4e, 0x6e, 0xc3, 0x7c, 0xdf, 0x8b, 0x53, 0x1a, 0xa9, 0x97, 0x09, + 0x3e, 0xf7, 0x64, 0x3c, 0x7c, 0x9c, 0x79, 0xb7, 0x7a, 0x7a, 0x9e, 0x97, 0xce, 0xce, 0xf3, 0xd2, + 0x9f, 0xf3, 0xbc, 0xf4, 0xfd, 0x22, 0x9f, 0x3a, 0xbb, 0xc8, 0xa7, 0x7e, 0x5d, 0xe4, 0x53, 0x1f, + 0x34, 0xcb, 0xf6, 0xeb, 0x2d, 0x33, 0x78, 0x7d, 0xb4, 0x80, 0xf1, 0x81, 0x20, 0xd7, 0x62, 0x72, + 0xad, 0xad, 0x5d, 0xbe, 0xe5, 0x9d, 0x26, 0x7a, 0xe6, 0xb4, 0x78, 0x41, 0x77, 0xfe, 0x05, 0x00, + 0x00, 0xff, 0xff, 0xf9, 0x62, 0xcd, 0x1c, 0xe4, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -961,17 +961,20 @@ func (m *MsgAddBlockHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a if m.Height != 0 { i = encodeVarintTx(dAtA, i, uint64(m.Height)) i-- - dAtA[i] = 0x28 - } - if len(m.BlockHeader) > 0 { - i -= len(m.BlockHeader) - copy(dAtA[i:], m.BlockHeader) - i = encodeVarintTx(dAtA, i, uint64(len(m.BlockHeader))) - i-- - dAtA[i] = 0x22 + dAtA[i] = 0x20 } if len(m.BlockHash) > 0 { i -= len(m.BlockHash) @@ -1389,13 +1392,11 @@ func (m *MsgAddBlockHeader) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.BlockHeader) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } if m.Height != 0 { n += 1 + sovTx(uint64(m.Height)) } + l = m.Header.Size() + n += 1 + l + sovTx(uint64(l)) return n } @@ -1670,10 +1671,10 @@ func (m *MsgAddBlockHeader) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockHeader", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } - var byteLen int + m.Height = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1683,31 +1684,16 @@ func (m *MsgAddBlockHeader) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + m.Height |= int64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BlockHeader = append(m.BlockHeader[:0], dAtA[iNdEx:postIndex]...) - if m.BlockHeader == nil { - m.BlockHeader = []byte{} - } - iNdEx = postIndex case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) } - m.Height = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1717,11 +1703,25 @@ func (m *MsgAddBlockHeader) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Height |= int64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 0e95cb3bea..1d77e6fb5a 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -830,7 +830,13 @@ func (ob *EVMChainClient) observeInTX() error { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("error encoding block header: %d", bn) continue } - _, err = ob.zetaClient.PostAddBlockHeader(ob.chain.ChainId, block.Hash().Bytes(), block.Number().Int64(), headerRLP) + + _, err = ob.zetaClient.PostAddBlockHeader( + ob.chain.ChainId, + block.Hash().Bytes(), + block.Number().Int64(), + common.NewEthereumHeader(headerRLP), + ) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("error posting block header: %d", bn) continue diff --git a/zetaclient/query.go b/zetaclient/query.go index a93c52c5e4..9e00acab4c 100644 --- a/zetaclient/query.go +++ b/zetaclient/query.go @@ -12,7 +12,6 @@ import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" tmtypes "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/zeta-chain/zetacore/common" - "github.com/zeta-chain/zetacore/common/ethereum" "github.com/zeta-chain/zetacore/x/crosschain/types" zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc" @@ -299,7 +298,7 @@ func (b *ZetaCoreBridge) GetPendingNonces() (*types.QueryAllPendingNoncesRespons return resp, nil } -func (b *ZetaCoreBridge) Prove(blockHash string, txHash string, txIndex int64, proof *ethereum.Proof, chainID uint64) (bool, error) { +func (b *ZetaCoreBridge) Prove(blockHash string, txHash string, txIndex int64, proof *common.Proof, chainID uint64) (bool, error) { client := zetaObserverTypes.NewQueryClient(b.grpcConn) resp, err := client.Prove(context.Background(), &zetaObserverTypes.QueryProveRequest{ BlockHash: blockHash, diff --git a/zetaclient/tx.go b/zetaclient/tx.go index 5b23ef5a73..4e0b0b150c 100644 --- a/zetaclient/tx.go +++ b/zetaclient/tx.go @@ -8,7 +8,6 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" - "github.com/zeta-chain/zetacore/common/ethereum" "github.com/zeta-chain/zetacore/zetaclient/config" "gitlab.com/thorchain/tss/go-tss/blame" @@ -55,7 +54,7 @@ func (b *ZetaCoreBridge) PostGasPrice(chain common.Chain, gasPrice uint64, suppl return "", fmt.Errorf("post gasprice failed after %d retries", DefaultRetryInterval) } -func (b *ZetaCoreBridge) AddTxHashToOutTxTracker(chainID int64, nonce uint64, txHash string, proof *ethereum.Proof, blockHash string, txIndex int64) (string, error) { +func (b *ZetaCoreBridge) AddTxHashToOutTxTracker(chainID int64, nonce uint64, txHash string, proof *common.Proof, blockHash string, txIndex int64) (string, error) { signerAddress := b.keys.GetOperatorAddress().String() msg := types.NewMsgAddToOutTxTracker(signerAddress, chainID, nonce, txHash, proof, blockHash, txIndex) authzMsg, authzSigner := b.WrapMessageWithAuthz(msg) @@ -192,10 +191,11 @@ func (b *ZetaCoreBridge) PostBlameData(blame *blame.Blame, chainID int64, index return "", fmt.Errorf("post blame data failed after %d retries", DefaultRetryCount) } -func (b *ZetaCoreBridge) PostAddBlockHeader(chainID int64, txhash []byte, height int64, header []byte) (string, error) { +func (b *ZetaCoreBridge) PostAddBlockHeader(chainID int64, txhash []byte, height int64, header common.HeaderData) (string, error) { signerAddress := b.keys.GetOperatorAddress().String() msg := observerTypes.NewMsgAddBlockHeader(signerAddress, chainID, txhash, height, header) authzMsg, authzSigner := b.WrapMessageWithAuthz(msg) + var gasLimit uint64 = DefaultGasLimit for i := 0; i < DefaultRetryCount; i++ { zetaTxHash, err := b.Broadcast(gasLimit, authzMsg, authzSigner) From ea49309746e1896cca84fcf9ad85317a42651972 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 20 Sep 2023 14:02:12 -0400 Subject: [PATCH 4/8] Move permission check to Event Processing rather from Process All logs (#1152) --- x/crosschain/keeper/evm_hooks.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index 5ef345e7c3..a87e0a041c 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -81,9 +81,6 @@ func (k Keeper) PostTxProcessing( // from registered ZRC20 contract, new CCTX will be created to trigger and track outbound // transaction. func (k Keeper) ProcessLogs(ctx sdk.Context, logs []*ethtypes.Log, emittingContract ethcommon.Address, txOrigin string) error { - if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { - return types.ErrNotEnoughPermissions - } system, found := k.fungibleKeeper.GetSystemContract(ctx) if !found { return fmt.Errorf("cannot find system contract") @@ -113,6 +110,9 @@ func (k Keeper) ProcessLogs(ctx sdk.Context, logs []*ethtypes.Log, emittingContr // ProcessZRC20WithdrawalEvent creates a new CCTX to process the withdrawal event // error indicates system error and non-recoverable; should abort func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20Withdrawal, emittingContract ethcommon.Address, txOrigin string) error { + if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { + return types.ErrNotEnoughPermissions + } ctx.Logger().Info("ZRC20 withdrawal to %s amount %d\n", hex.EncodeToString(event.To), event.Value) tss, found := k.GetTSS(ctx) if !found { @@ -164,6 +164,9 @@ func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20W } func (k Keeper) ProcessZetaSentEvent(ctx sdk.Context, event *connectorzevm.ZetaConnectorZEVMZetaSent, emittingContract ethcommon.Address, txOrigin string) error { + if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { + return types.ErrNotEnoughPermissions + } ctx.Logger().Info(fmt.Sprintf( "Zeta withdrawal to %s amount %d to chain with chainId %d", hex.EncodeToString(event.DestinationAddress), From a5d704b48d8274e0eca7ee1668eed5440f5e7f7d Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 20 Sep 2023 15:41:07 -0400 Subject: [PATCH 5/8] feat: add new query for pending nonces using chain id (#1131) --- docs/openapi/openapi.swagger.yaml | 25 + proto/crosschain/query.proto | 12 + x/crosschain/keeper/keeper_pending_nonces.go | 20 + x/crosschain/types/query.pb.go | 786 ++++++++++++++----- x/crosschain/types/query.pb.gw.go | 101 +++ 5 files changed, 734 insertions(+), 210 deletions(-) diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 50af221fae..025b70c325 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -27213,6 +27213,26 @@ paths: $ref: '#/definitions/googlerpcStatus' tags: - Query + /zeta-chain/crosschain/pendingNonces/{chain_id}: + get: + operationId: Query_PendingNoncesByChain + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/crosschainQueryPendingNoncesByChainResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: chain_id + in: path + required: true + type: string + format: uint64 + tags: + - Query /zeta-chain/crosschain/protocolFee: get: operationId: Query_ProtocolFee @@ -50660,6 +50680,11 @@ definitions: properties: feeInZeta: type: string + crosschainQueryPendingNoncesByChainResponse: + type: object + properties: + pending_nonces: + $ref: '#/definitions/crosschainPendingNonces' crosschainQueryTssHistoryResponse: type: object properties: diff --git a/proto/crosschain/query.proto b/proto/crosschain/query.proto index 600645508e..ca7ccb7f51 100644 --- a/proto/crosschain/query.proto +++ b/proto/crosschain/query.proto @@ -94,6 +94,10 @@ service Query { option (google.api.http).get = "/zeta-chain/crosschain/pendingNonces"; } + rpc PendingNoncesByChain(QueryPendingNoncesByChainRequest) returns (QueryPendingNoncesByChainResponse) { + option (google.api.http).get = "/zeta-chain/crosschain/pendingNonces/{chain_id}"; + } + // Queries a lastBlockHeight by index. rpc LastBlockHeight(QueryGetLastBlockHeightRequest) returns (QueryGetLastBlockHeightResponse) { option (google.api.http).get = "/zeta-chain/crosschain/lastBlockHeight/{index}"; @@ -253,6 +257,14 @@ message QueryAllPendingNoncesResponse { repeated PendingNonces pending_nonces = 1; } +message QueryPendingNoncesByChainRequest { + uint64 chain_id = 1; +} + +message QueryPendingNoncesByChainResponse { + PendingNonces pending_nonces = 1 [(gogoproto.nullable) = false]; +} + message QueryGetLastBlockHeightRequest { string index = 1; } diff --git a/x/crosschain/keeper/keeper_pending_nonces.go b/x/crosschain/keeper/keeper_pending_nonces.go index da1648b104..8808b6ec4b 100644 --- a/x/crosschain/keeper/keeper_pending_nonces.go +++ b/x/crosschain/keeper/keeper_pending_nonces.go @@ -93,3 +93,23 @@ func (k Keeper) PendingNoncesAll(c context.Context, req *types.QueryAllPendingNo PendingNonces: list, }, nil } + +func (k Keeper) PendingNoncesByChain(c context.Context, req *types.QueryPendingNoncesByChainRequest) (*types.QueryPendingNoncesByChainResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + tss, found := k.GetTSS(ctx) + if !found { + return nil, status.Error(codes.NotFound, "tss not found") + } + list, found := k.GetPendingNonces(ctx, tss.TssPubkey, req.ChainId) + if !found { + return nil, status.Error(codes.NotFound, fmt.Sprintf("pending nonces not found for chain id : %d", req.ChainId)) + } + + return &types.QueryPendingNoncesByChainResponse{ + PendingNonces: list, + }, nil +} diff --git a/x/crosschain/types/query.pb.go b/x/crosschain/types/query.pb.go index ab9aef612d..4a808fb004 100644 --- a/x/crosschain/types/query.pb.go +++ b/x/crosschain/types/query.pb.go @@ -1378,6 +1378,94 @@ func (m *QueryAllPendingNoncesResponse) GetPendingNonces() []*PendingNonces { return nil } +type QueryPendingNoncesByChainRequest struct { + ChainId uint64 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` +} + +func (m *QueryPendingNoncesByChainRequest) Reset() { *m = QueryPendingNoncesByChainRequest{} } +func (m *QueryPendingNoncesByChainRequest) String() string { return proto.CompactTextString(m) } +func (*QueryPendingNoncesByChainRequest) ProtoMessage() {} +func (*QueryPendingNoncesByChainRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_65a992045e92a606, []int{30} +} +func (m *QueryPendingNoncesByChainRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPendingNoncesByChainRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPendingNoncesByChainRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryPendingNoncesByChainRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPendingNoncesByChainRequest.Merge(m, src) +} +func (m *QueryPendingNoncesByChainRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryPendingNoncesByChainRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPendingNoncesByChainRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPendingNoncesByChainRequest proto.InternalMessageInfo + +func (m *QueryPendingNoncesByChainRequest) GetChainId() uint64 { + if m != nil { + return m.ChainId + } + return 0 +} + +type QueryPendingNoncesByChainResponse struct { + PendingNonces PendingNonces `protobuf:"bytes,1,opt,name=pending_nonces,json=pendingNonces,proto3" json:"pending_nonces"` +} + +func (m *QueryPendingNoncesByChainResponse) Reset() { *m = QueryPendingNoncesByChainResponse{} } +func (m *QueryPendingNoncesByChainResponse) String() string { return proto.CompactTextString(m) } +func (*QueryPendingNoncesByChainResponse) ProtoMessage() {} +func (*QueryPendingNoncesByChainResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_65a992045e92a606, []int{31} +} +func (m *QueryPendingNoncesByChainResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPendingNoncesByChainResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPendingNoncesByChainResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryPendingNoncesByChainResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPendingNoncesByChainResponse.Merge(m, src) +} +func (m *QueryPendingNoncesByChainResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryPendingNoncesByChainResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPendingNoncesByChainResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPendingNoncesByChainResponse proto.InternalMessageInfo + +func (m *QueryPendingNoncesByChainResponse) GetPendingNonces() PendingNonces { + if m != nil { + return m.PendingNonces + } + return PendingNonces{} +} + type QueryGetLastBlockHeightRequest struct { Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` } @@ -1386,7 +1474,7 @@ func (m *QueryGetLastBlockHeightRequest) Reset() { *m = QueryGetLastBloc func (m *QueryGetLastBlockHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetLastBlockHeightRequest) ProtoMessage() {} func (*QueryGetLastBlockHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{30} + return fileDescriptor_65a992045e92a606, []int{32} } func (m *QueryGetLastBlockHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1430,7 +1518,7 @@ func (m *QueryGetLastBlockHeightResponse) Reset() { *m = QueryGetLastBlo func (m *QueryGetLastBlockHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetLastBlockHeightResponse) ProtoMessage() {} func (*QueryGetLastBlockHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{31} + return fileDescriptor_65a992045e92a606, []int{33} } func (m *QueryGetLastBlockHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1474,7 +1562,7 @@ func (m *QueryAllLastBlockHeightRequest) Reset() { *m = QueryAllLastBloc func (m *QueryAllLastBlockHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllLastBlockHeightRequest) ProtoMessage() {} func (*QueryAllLastBlockHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{32} + return fileDescriptor_65a992045e92a606, []int{34} } func (m *QueryAllLastBlockHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1519,7 +1607,7 @@ func (m *QueryAllLastBlockHeightResponse) Reset() { *m = QueryAllLastBlo func (m *QueryAllLastBlockHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllLastBlockHeightResponse) ProtoMessage() {} func (*QueryAllLastBlockHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{33} + return fileDescriptor_65a992045e92a606, []int{35} } func (m *QueryAllLastBlockHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1570,7 +1658,7 @@ func (m *QueryGetCctxRequest) Reset() { *m = QueryGetCctxRequest{} } func (m *QueryGetCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxRequest) ProtoMessage() {} func (*QueryGetCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{34} + return fileDescriptor_65a992045e92a606, []int{36} } func (m *QueryGetCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1615,7 +1703,7 @@ func (m *QueryGetCctxByNonceRequest) Reset() { *m = QueryGetCctxByNonceR func (m *QueryGetCctxByNonceRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxByNonceRequest) ProtoMessage() {} func (*QueryGetCctxByNonceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{35} + return fileDescriptor_65a992045e92a606, []int{37} } func (m *QueryGetCctxByNonceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1666,7 +1754,7 @@ func (m *QueryGetCctxResponse) Reset() { *m = QueryGetCctxResponse{} } func (m *QueryGetCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxResponse) ProtoMessage() {} func (*QueryGetCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{36} + return fileDescriptor_65a992045e92a606, []int{38} } func (m *QueryGetCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1710,7 +1798,7 @@ func (m *QueryAllCctxRequest) Reset() { *m = QueryAllCctxRequest{} } func (m *QueryAllCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxRequest) ProtoMessage() {} func (*QueryAllCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{37} + return fileDescriptor_65a992045e92a606, []int{39} } func (m *QueryAllCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1755,7 +1843,7 @@ func (m *QueryAllCctxResponse) Reset() { *m = QueryAllCctxResponse{} } func (m *QueryAllCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxResponse) ProtoMessage() {} func (*QueryAllCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{38} + return fileDescriptor_65a992045e92a606, []int{40} } func (m *QueryAllCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1807,7 +1895,7 @@ func (m *QueryAllCctxPendingRequest) Reset() { *m = QueryAllCctxPendingR func (m *QueryAllCctxPendingRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxPendingRequest) ProtoMessage() {} func (*QueryAllCctxPendingRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{39} + return fileDescriptor_65a992045e92a606, []int{41} } func (m *QueryAllCctxPendingRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1859,7 +1947,7 @@ func (m *QueryAllCctxPendingResponse) Reset() { *m = QueryAllCctxPending func (m *QueryAllCctxPendingResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxPendingResponse) ProtoMessage() {} func (*QueryAllCctxPendingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{40} + return fileDescriptor_65a992045e92a606, []int{42} } func (m *QueryAllCctxPendingResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1909,7 +1997,7 @@ func (m *QueryLastZetaHeightRequest) Reset() { *m = QueryLastZetaHeightR func (m *QueryLastZetaHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryLastZetaHeightRequest) ProtoMessage() {} func (*QueryLastZetaHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{41} + return fileDescriptor_65a992045e92a606, []int{43} } func (m *QueryLastZetaHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1946,7 +2034,7 @@ func (m *QueryLastZetaHeightResponse) Reset() { *m = QueryLastZetaHeight func (m *QueryLastZetaHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryLastZetaHeightResponse) ProtoMessage() {} func (*QueryLastZetaHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{42} + return fileDescriptor_65a992045e92a606, []int{44} } func (m *QueryLastZetaHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1991,7 +2079,7 @@ func (m *QueryConvertGasToZetaRequest) Reset() { *m = QueryConvertGasToZ func (m *QueryConvertGasToZetaRequest) String() string { return proto.CompactTextString(m) } func (*QueryConvertGasToZetaRequest) ProtoMessage() {} func (*QueryConvertGasToZetaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{43} + return fileDescriptor_65a992045e92a606, []int{45} } func (m *QueryConvertGasToZetaRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2044,7 +2132,7 @@ func (m *QueryConvertGasToZetaResponse) Reset() { *m = QueryConvertGasTo func (m *QueryConvertGasToZetaResponse) String() string { return proto.CompactTextString(m) } func (*QueryConvertGasToZetaResponse) ProtoMessage() {} func (*QueryConvertGasToZetaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{44} + return fileDescriptor_65a992045e92a606, []int{46} } func (m *QueryConvertGasToZetaResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2101,7 +2189,7 @@ func (m *QueryMessagePassingProtocolFeeRequest) Reset() { *m = QueryMess func (m *QueryMessagePassingProtocolFeeRequest) String() string { return proto.CompactTextString(m) } func (*QueryMessagePassingProtocolFeeRequest) ProtoMessage() {} func (*QueryMessagePassingProtocolFeeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{45} + return fileDescriptor_65a992045e92a606, []int{47} } func (m *QueryMessagePassingProtocolFeeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2140,7 +2228,7 @@ func (m *QueryMessagePassingProtocolFeeResponse) Reset() { func (m *QueryMessagePassingProtocolFeeResponse) String() string { return proto.CompactTextString(m) } func (*QueryMessagePassingProtocolFeeResponse) ProtoMessage() {} func (*QueryMessagePassingProtocolFeeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{46} + return fileDescriptor_65a992045e92a606, []int{48} } func (m *QueryMessagePassingProtocolFeeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2184,7 +2272,7 @@ func (m *QueryZEVMGetTransactionReceiptRequest) Reset() { *m = QueryZEVM func (m *QueryZEVMGetTransactionReceiptRequest) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetTransactionReceiptRequest) ProtoMessage() {} func (*QueryZEVMGetTransactionReceiptRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{47} + return fileDescriptor_65a992045e92a606, []int{49} } func (m *QueryZEVMGetTransactionReceiptRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2241,7 +2329,7 @@ func (m *QueryZEVMGetTransactionReceiptResponse) Reset() { func (m *QueryZEVMGetTransactionReceiptResponse) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetTransactionReceiptResponse) ProtoMessage() {} func (*QueryZEVMGetTransactionReceiptResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{48} + return fileDescriptor_65a992045e92a606, []int{50} } func (m *QueryZEVMGetTransactionReceiptResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2371,7 +2459,7 @@ func (m *Log) Reset() { *m = Log{} } func (m *Log) String() string { return proto.CompactTextString(m) } func (*Log) ProtoMessage() {} func (*Log) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{49} + return fileDescriptor_65a992045e92a606, []int{51} } func (m *Log) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2471,7 +2559,7 @@ func (m *QueryZEVMGetTransactionRequest) Reset() { *m = QueryZEVMGetTran func (m *QueryZEVMGetTransactionRequest) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetTransactionRequest) ProtoMessage() {} func (*QueryZEVMGetTransactionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{50} + return fileDescriptor_65a992045e92a606, []int{52} } func (m *QueryZEVMGetTransactionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2531,7 +2619,7 @@ func (m *QueryZEVMGetTransactionResponse) Reset() { *m = QueryZEVMGetTra func (m *QueryZEVMGetTransactionResponse) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetTransactionResponse) ProtoMessage() {} func (*QueryZEVMGetTransactionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{51} + return fileDescriptor_65a992045e92a606, []int{53} } func (m *QueryZEVMGetTransactionResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2687,7 +2775,7 @@ func (m *QueryZEVMGetBlockByNumberRequest) Reset() { *m = QueryZEVMGetBl func (m *QueryZEVMGetBlockByNumberRequest) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetBlockByNumberRequest) ProtoMessage() {} func (*QueryZEVMGetBlockByNumberRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{52} + return fileDescriptor_65a992045e92a606, []int{54} } func (m *QueryZEVMGetBlockByNumberRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2751,7 +2839,7 @@ func (m *QueryZEVMGetBlockByNumberResponse) Reset() { *m = QueryZEVMGetB func (m *QueryZEVMGetBlockByNumberResponse) String() string { return proto.CompactTextString(m) } func (*QueryZEVMGetBlockByNumberResponse) ProtoMessage() {} func (*QueryZEVMGetBlockByNumberResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{53} + return fileDescriptor_65a992045e92a606, []int{55} } func (m *QueryZEVMGetBlockByNumberResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2958,6 +3046,8 @@ func init() { proto.RegisterType((*QueryAllChainNoncesResponse)(nil), "zetachain.zetacore.crosschain.QueryAllChainNoncesResponse") proto.RegisterType((*QueryAllPendingNoncesRequest)(nil), "zetachain.zetacore.crosschain.QueryAllPendingNoncesRequest") proto.RegisterType((*QueryAllPendingNoncesResponse)(nil), "zetachain.zetacore.crosschain.QueryAllPendingNoncesResponse") + proto.RegisterType((*QueryPendingNoncesByChainRequest)(nil), "zetachain.zetacore.crosschain.QueryPendingNoncesByChainRequest") + proto.RegisterType((*QueryPendingNoncesByChainResponse)(nil), "zetachain.zetacore.crosschain.QueryPendingNoncesByChainResponse") proto.RegisterType((*QueryGetLastBlockHeightRequest)(nil), "zetachain.zetacore.crosschain.QueryGetLastBlockHeightRequest") proto.RegisterType((*QueryGetLastBlockHeightResponse)(nil), "zetachain.zetacore.crosschain.QueryGetLastBlockHeightResponse") proto.RegisterType((*QueryAllLastBlockHeightRequest)(nil), "zetachain.zetacore.crosschain.QueryAllLastBlockHeightRequest") @@ -2987,192 +3077,196 @@ func init() { func init() { proto.RegisterFile("crosschain/query.proto", fileDescriptor_65a992045e92a606) } var fileDescriptor_65a992045e92a606 = []byte{ - // 2949 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0x5b, 0x6f, 0x1b, 0xc7, - 0xf5, 0xf7, 0x8a, 0x14, 0x25, 0x8d, 0xae, 0x1e, 0x2b, 0x0e, 0xc3, 0xd8, 0xa2, 0xb3, 0x8e, 0x2f, - 0xf1, 0x85, 0x8c, 0x15, 0xdb, 0x49, 0x6c, 0x27, 0xf8, 0x4b, 0x76, 0xac, 0x18, 0x51, 0x12, 0xfd, - 0x57, 0x4a, 0x5b, 0xb8, 0x68, 0x89, 0xd5, 0x72, 0x4c, 0x2d, 0xb2, 0xe4, 0x32, 0x3b, 0x43, 0x41, - 0x8a, 0xe1, 0x3e, 0xe4, 0x13, 0x04, 0x28, 0xd0, 0xbe, 0xf4, 0xb5, 0x97, 0x87, 0x3e, 0x14, 0x68, - 0xd0, 0x14, 0x28, 0x90, 0x3e, 0xb4, 0x4d, 0xf3, 0x18, 0xa0, 0x40, 0xd1, 0x22, 0x00, 0x51, 0xc4, - 0x7d, 0xe2, 0x37, 0x28, 0xd0, 0x87, 0x62, 0xce, 0x9e, 0xe5, 0xce, 0x92, 0xbb, 0xe2, 0x9a, 0x62, - 0x8b, 0xf6, 0x85, 0x3b, 0x73, 0x66, 0xce, 0x99, 0xdf, 0xb9, 0xcc, 0xcc, 0xd9, 0x3d, 0x24, 0xc7, - 0x2d, 0xcf, 0xe5, 0xdc, 0xda, 0x31, 0xed, 0x46, 0xf9, 0x83, 0x16, 0xf3, 0xf6, 0x4b, 0x4d, 0xcf, - 0x15, 0x2e, 0x3d, 0xf9, 0x21, 0x13, 0x26, 0x90, 0x4b, 0xd0, 0x72, 0x3d, 0x56, 0x0a, 0xa7, 0x16, - 0x2e, 0x58, 0x2e, 0xaf, 0xbb, 0xbc, 0xbc, 0x6d, 0x72, 0xe6, 0xf3, 0x95, 0x77, 0xaf, 0x6c, 0x33, - 0x61, 0x5e, 0x29, 0x37, 0xcd, 0x9a, 0xdd, 0x30, 0x85, 0xed, 0x36, 0x7c, 0x51, 0x85, 0x93, 0xca, - 0x12, 0xf0, 0x5b, 0x69, 0xb8, 0x0d, 0x8b, 0x71, 0x1c, 0x2e, 0xaa, 0xc3, 0xb2, 0x59, 0xf1, 0x27, - 0x89, 0x3d, 0x9c, 0x50, 0x50, 0x26, 0xd4, 0x4c, 0x5e, 0x69, 0x7a, 0xb6, 0xc5, 0x70, 0xec, 0xb4, - 0x32, 0x06, 0x3c, 0x95, 0x1d, 0x93, 0xef, 0x54, 0x84, 0x5b, 0xb1, 0xac, 0xae, 0x00, 0x5d, 0x99, - 0xe4, 0x98, 0x5c, 0x54, 0xb6, 0x1d, 0xd7, 0x7a, 0xbf, 0xb2, 0xc3, 0xec, 0xda, 0x8e, 0xc0, 0x39, - 0x4b, 0xca, 0x1c, 0x80, 0xd7, 0x23, 0x43, 0x45, 0xe9, 0xb6, 0x84, 0x5c, 0x49, 0x78, 0xa6, 0xf5, - 0x3e, 0xf3, 0x70, 0xc2, 0xd3, 0xca, 0x84, 0xa6, 0xe9, 0x99, 0xf5, 0x40, 0xbf, 0x45, 0x65, 0x40, - 0xf0, 0x2e, 0xb5, 0xe6, 0xd6, 0x5c, 0x68, 0x96, 0x65, 0x0b, 0xa9, 0x27, 0x6a, 0xae, 0x5b, 0x73, - 0x58, 0xd9, 0x6c, 0xda, 0x65, 0xb3, 0xd1, 0x70, 0x05, 0xd8, 0x11, 0x79, 0xf4, 0x3c, 0x39, 0xfe, - 0xff, 0xd2, 0xd4, 0x5b, 0x9c, 0xbf, 0x69, 0x73, 0xe1, 0x7a, 0xfb, 0x06, 0xfb, 0xa0, 0xc5, 0xb8, - 0xd0, 0xbf, 0x4b, 0x9e, 0xee, 0x1b, 0xe1, 0x4d, 0xb7, 0xc1, 0x19, 0xbd, 0x4d, 0x26, 0x05, 0xe7, - 0x15, 0xc7, 0xe6, 0x22, 0xaf, 0x9d, 0xca, 0x9c, 0x9f, 0x5e, 0xd6, 0x4b, 0x07, 0xfa, 0xb6, 0xb4, - 0xb5, 0xb9, 0xb9, 0x9a, 0xfd, 0xa2, 0x5d, 0x3c, 0x62, 0x4c, 0x08, 0xce, 0xd7, 0x6d, 0x2e, 0xf4, - 0x45, 0x42, 0x41, 0xfe, 0x06, 0x28, 0x16, 0xac, 0x7a, 0x9f, 0x1c, 0x8b, 0x50, 0xbb, 0x2b, 0xe6, - 0x7c, 0x03, 0xe4, 0xb5, 0x53, 0xda, 0xf9, 0xe9, 0xe5, 0x33, 0x03, 0xd6, 0xf3, 0xd9, 0x71, 0x49, - 0x64, 0xd5, 0xdf, 0x26, 0xcf, 0x82, 0xec, 0x35, 0x26, 0xde, 0x6d, 0x89, 0xad, 0xbd, 0x2d, 0xdf, - 0xd8, 0xb8, 0x34, 0xcd, 0x93, 0x09, 0x60, 0xbe, 0x77, 0x07, 0x16, 0xc9, 0x18, 0x41, 0x97, 0x2e, - 0x92, 0x71, 0xf0, 0x5f, 0x7e, 0xec, 0x94, 0x76, 0x3e, 0x6b, 0xf8, 0x1d, 0xbd, 0x45, 0x4e, 0xc4, - 0x8b, 0x43, 0xcc, 0xef, 0x91, 0x19, 0x57, 0xa1, 0x23, 0xf2, 0x8b, 0x03, 0x90, 0xab, 0xa2, 0x10, - 0x7f, 0x44, 0x8c, 0xce, 0x50, 0x8b, 0x15, 0xc7, 0x89, 0xd3, 0xe2, 0x2e, 0x21, 0xe1, 0x6e, 0xc1, - 0x35, 0xcf, 0x96, 0xfc, 0xad, 0x55, 0x92, 0x5b, 0xab, 0xe4, 0x6f, 0x49, 0xdc, 0x5a, 0xa5, 0x0d, - 0xb3, 0xc6, 0x90, 0xd7, 0x50, 0x38, 0xf5, 0xcf, 0x34, 0x54, 0xaf, 0x6f, 0x9d, 0x44, 0xf5, 0x32, - 0x23, 0x50, 0x8f, 0xae, 0x45, 0xf0, 0x8f, 0x01, 0xfe, 0x73, 0x03, 0xf1, 0xfb, 0x98, 0x22, 0x0a, - 0x7c, 0xa4, 0x11, 0x3d, 0x4e, 0x81, 0xd5, 0xfd, 0xdb, 0x12, 0x49, 0x60, 0xaf, 0x45, 0x32, 0x0e, - 0xc8, 0xd0, 0xe7, 0x7e, 0xa7, 0xc7, 0x8a, 0x63, 0x43, 0x5b, 0xf1, 0x0f, 0x1a, 0x39, 0x7d, 0x20, - 0x88, 0xff, 0x11, 0x63, 0xde, 0x24, 0x27, 0x83, 0x58, 0xbf, 0xd7, 0xd8, 0xda, 0x7b, 0xd3, 0xe4, - 0x3b, 0x5b, 0xee, 0x6d, 0x4b, 0xec, 0x05, 0x66, 0x2c, 0x90, 0x49, 0x1b, 0x07, 0xc0, 0x92, 0x53, - 0x46, 0xb7, 0xaf, 0x3f, 0x22, 0x4b, 0x49, 0xcc, 0xa8, 0xfe, 0xb7, 0xc9, 0x9c, 0x1d, 0x19, 0xc1, - 0xc0, 0xbd, 0x3c, 0xc0, 0x00, 0x51, 0x71, 0x68, 0x82, 0x1e, 0x51, 0xfa, 0x2d, 0x5c, 0x3e, 0x3a, - 0xf9, 0x8e, 0x29, 0xcc, 0x34, 0xe0, 0x3f, 0x24, 0xc5, 0x44, 0x6e, 0x44, 0xff, 0x4d, 0x32, 0x7b, - 0x5b, 0x62, 0x02, 0x97, 0x6e, 0xed, 0xf1, 0x94, 0xde, 0x53, 0x79, 0x10, 0x7a, 0x54, 0x8e, 0x5e, - 0x43, 0xab, 0xaf, 0x38, 0x4e, 0xbc, 0xd5, 0x47, 0xb5, 0xd9, 0x3f, 0xd7, 0xd0, 0x46, 0x31, 0x2b, - 0x1d, 0xe0, 0xa2, 0xcc, 0x88, 0x5c, 0x34, 0xba, 0x38, 0x7d, 0x96, 0x3c, 0x13, 0x84, 0xda, 0x16, - 0xe7, 0x2b, 0xd5, 0xaa, 0xc7, 0x78, 0xf7, 0x6e, 0xf9, 0x3f, 0x52, 0x88, 0x1b, 0x44, 0x05, 0x17, - 0x48, 0x86, 0x89, 0xc0, 0xff, 0xb2, 0x29, 0x29, 0xdb, 0xc2, 0x02, 0x38, 0x53, 0x86, 0x6c, 0x76, - 0xef, 0x2c, 0x29, 0x61, 0x73, 0x33, 0x90, 0xfb, 0x16, 0xde, 0x59, 0x01, 0x15, 0x05, 0x5e, 0x25, - 0x99, 0xad, 0xcd, 0x4d, 0xf4, 0x4a, 0x8a, 0x0b, 0xd2, 0x90, 0xd3, 0xf5, 0x32, 0x5e, 0xbb, 0x6b, - 0x4c, 0xac, 0x99, 0x7c, 0x43, 0xe6, 0x25, 0xca, 0x51, 0x65, 0x37, 0xaa, 0x6c, 0x0f, 0x31, 0xfa, - 0x1d, 0xbd, 0x42, 0xf2, 0xfd, 0x0c, 0xe1, 0x45, 0x1d, 0xd0, 0x10, 0xc7, 0xb9, 0x01, 0x38, 0xba, - 0x22, 0xba, 0x8c, 0xba, 0x89, 0x88, 0x56, 0x1c, 0xa7, 0x17, 0xd1, 0xa8, 0xe2, 0xef, 0x67, 0x1a, - 0x2a, 0x11, 0x59, 0x23, 0x56, 0x89, 0xcc, 0x50, 0x4a, 0x8c, 0x2e, 0xc2, 0x96, 0xc3, 0x20, 0x82, - 0x7d, 0xfa, 0x0e, 0xe4, 0x9d, 0x07, 0xbb, 0xe8, 0xfd, 0x30, 0xf1, 0x88, 0xf0, 0xa0, 0x82, 0xeb, - 0x64, 0x5a, 0x21, 0xa3, 0x19, 0x2f, 0x0c, 0x3a, 0x3d, 0x14, 0x41, 0x2a, 0xbb, 0x5e, 0x45, 0x80, - 0x2b, 0x8e, 0x13, 0x03, 0x70, 0x54, 0x1e, 0xfb, 0x44, 0x0b, 0xd3, 0x90, 0x54, 0x3a, 0x65, 0x0e, - 0xa1, 0xd3, 0xe8, 0xbc, 0xb7, 0x14, 0x26, 0x35, 0x1b, 0xac, 0x51, 0xb5, 0x1b, 0xb5, 0x88, 0x79, - 0x74, 0x11, 0x9e, 0xb8, 0x3d, 0xe3, 0xa8, 0xd7, 0x26, 0x99, 0x6b, 0xfa, 0x03, 0xf8, 0xc6, 0x81, - 0xaa, 0x5d, 0x1a, 0x94, 0x90, 0x46, 0xa4, 0xcd, 0x36, 0xd5, 0xae, 0x7e, 0x3d, 0xbc, 0x20, 0xd7, - 0x4d, 0x2e, 0x56, 0xe5, 0xab, 0xc4, 0x9b, 0xf0, 0x26, 0x71, 0x70, 0x5c, 0x3d, 0xc4, 0xbb, 0x29, - 0x8e, 0x0f, 0xf1, 0x7e, 0x8b, 0xcc, 0xf7, 0x0c, 0xa1, 0xd3, 0x4b, 0x03, 0x00, 0xf7, 0x0a, 0xec, - 0x15, 0xa3, 0xef, 0x84, 0x57, 0x46, 0x02, 0xe8, 0x51, 0xc5, 0xda, 0xef, 0x35, 0xd4, 0x33, 0x6e, - 0xa9, 0x83, 0xf4, 0xcc, 0x8c, 0x40, 0xcf, 0xd1, 0xc5, 0xde, 0xc5, 0xf0, 0x9a, 0x50, 0xef, 0xf0, - 0x78, 0xd7, 0xae, 0x2b, 0xc7, 0x8c, 0xbc, 0x37, 0xf7, 0x21, 0x54, 0x86, 0x7d, 0x55, 0xa9, 0x91, - 0xc5, 0xe8, 0xd2, 0x68, 0xb5, 0x77, 0xc9, 0x8c, 0x9a, 0x71, 0xa4, 0x7c, 0x45, 0x51, 0x59, 0x8c, - 0x88, 0x00, 0xfd, 0x3b, 0xa8, 0xa3, 0x3c, 0x15, 0xfe, 0x0d, 0x79, 0xca, 0x2f, 0x34, 0x54, 0xa4, - 0x2b, 0x3f, 0x51, 0x91, 0xcc, 0xa1, 0x14, 0x19, 0x9d, 0xd7, 0xbf, 0xa7, 0x1c, 0xc7, 0x96, 0xd8, - 0xc3, 0x73, 0xa0, 0xcf, 0x91, 0x55, 0xb0, 0x4a, 0x36, 0x70, 0x64, 0x75, 0x64, 0x6f, 0x20, 0x9f, - 0xaa, 0x07, 0xb5, 0x0a, 0xe0, 0xbf, 0xde, 0x72, 0x27, 0xd0, 0x72, 0x72, 0x43, 0xde, 0x67, 0xc2, - 0x8c, 0x1c, 0x2e, 0xfa, 0x35, 0x54, 0xab, 0x77, 0x14, 0xd5, 0x3a, 0x4e, 0x72, 0xca, 0x71, 0x97, - 0x31, 0xb0, 0xa7, 0x6f, 0xe1, 0x05, 0x70, 0xdb, 0x6d, 0xec, 0x32, 0x4f, 0x66, 0x4c, 0x5b, 0xae, - 0x64, 0x4f, 0x70, 0x48, 0x26, 0x74, 0x48, 0x81, 0x4c, 0xd6, 0x4c, 0xbe, 0x6e, 0xd7, 0x6d, 0x81, - 0x29, 0x61, 0xb7, 0xaf, 0xff, 0x58, 0xc3, 0x7b, 0xa3, 0x5f, 0x2c, 0xe2, 0xb9, 0x44, 0x8e, 0xba, - 0x2d, 0xb1, 0xed, 0xb6, 0x1a, 0xd5, 0x35, 0x93, 0xdf, 0x6b, 0xc8, 0x41, 0xdc, 0xf1, 0xfd, 0x03, - 0x72, 0x36, 0x7c, 0x9e, 0xb1, 0x5c, 0xe7, 0x2e, 0x63, 0x38, 0xdb, 0x5f, 0xb4, 0x7f, 0x80, 0x9e, - 0x27, 0xf3, 0xf2, 0xa9, 0x9e, 0x7d, 0x19, 0x08, 0xa6, 0x5e, 0xb2, 0x7e, 0x8e, 0x9c, 0x01, 0x98, - 0x6f, 0x33, 0xce, 0xcd, 0x1a, 0xdb, 0x30, 0x39, 0xb7, 0x1b, 0xb5, 0x8d, 0x50, 0x62, 0x60, 0xdd, - 0xbb, 0xe4, 0xec, 0xa0, 0x89, 0xa8, 0xd8, 0x09, 0x32, 0xf5, 0xa0, 0x0b, 0xd1, 0x57, 0x28, 0x24, - 0xe8, 0x37, 0x71, 0xc1, 0xfb, 0x6f, 0x7c, 0xe3, 0x6d, 0x99, 0x1e, 0x7b, 0x66, 0x83, 0x9b, 0x96, - 0x74, 0xaf, 0xc1, 0x2c, 0x66, 0x37, 0xbb, 0x77, 0x05, 0x25, 0xd9, 0x9d, 0xf0, 0xf5, 0x0b, 0xda, - 0xfa, 0x3f, 0xb3, 0x88, 0xe2, 0x00, 0xee, 0xae, 0x79, 0x09, 0x7e, 0x80, 0xeb, 0x0a, 0x59, 0x9d, - 0xed, 0xb4, 0x8b, 0x53, 0x40, 0x95, 0x6f, 0x1a, 0x46, 0xd8, 0xa4, 0xcb, 0x64, 0xc6, 0x9f, 0xdd, - 0x68, 0xd5, 0xb7, 0x99, 0xe7, 0x5b, 0x76, 0x75, 0xbe, 0xd3, 0x2e, 0x4e, 0x03, 0xfd, 0x1d, 0x20, - 0x1b, 0x6a, 0x87, 0xbe, 0x4e, 0x16, 0x2c, 0xb7, 0x21, 0x3c, 0xd3, 0x12, 0x15, 0xd3, 0x7f, 0x75, - 0x00, 0x2b, 0x4f, 0xad, 0x1e, 0xeb, 0xb4, 0x8b, 0xf3, 0xc1, 0x58, 0xf0, 0x56, 0xd1, 0x4b, 0xa0, - 0x6f, 0x90, 0x63, 0x56, 0xab, 0xde, 0x72, 0x4c, 0x61, 0xef, 0xb2, 0x4a, 0xcd, 0xe4, 0x95, 0x16, - 0x67, 0xd5, 0x7c, 0x16, 0x44, 0x3c, 0xd5, 0x69, 0x17, 0x8f, 0x86, 0xc3, 0x6b, 0x26, 0x7f, 0x8f, - 0xb3, 0xaa, 0xd1, 0x4f, 0xa2, 0x27, 0x48, 0xf6, 0x81, 0xe7, 0xd6, 0xf3, 0xe3, 0xc0, 0x37, 0xd9, - 0x69, 0x17, 0xa1, 0x6f, 0xc0, 0x2f, 0x3d, 0x0b, 0x31, 0xea, 0x4b, 0xce, 0xc1, 0x8c, 0xe9, 0x4e, - 0xbb, 0x38, 0x51, 0x43, 0x79, 0x41, 0x43, 0x9a, 0xcb, 0x71, 0x6b, 0xbc, 0xb2, 0xed, 0xb8, 0x6e, - 0x3d, 0x3f, 0x11, 0x9a, 0x4b, 0x52, 0x57, 0x25, 0xd1, 0x08, 0x9b, 0x54, 0x27, 0x39, 0x2e, 0x4c, - 0xd1, 0xe2, 0xf9, 0x49, 0x98, 0x49, 0x3a, 0xed, 0x22, 0x52, 0x0c, 0x7c, 0xd2, 0xe3, 0x64, 0x4c, - 0xb8, 0xf9, 0x29, 0x18, 0xcf, 0x75, 0xda, 0xc5, 0x31, 0xe1, 0x1a, 0x63, 0xc2, 0x95, 0x66, 0x13, - 0xa1, 0xdb, 0x7c, 0xf7, 0x90, 0xd0, 0x6c, 0xca, 0x18, 0x38, 0xa9, 0x97, 0x40, 0x57, 0xc8, 0x51, - 0x95, 0xdf, 0xbf, 0x29, 0xa7, 0x41, 0xc0, 0x62, 0xa7, 0x5d, 0x54, 0x85, 0xdf, 0x93, 0x63, 0x46, - 0x1f, 0x85, 0x5e, 0x27, 0x59, 0xa9, 0x4b, 0x7e, 0x26, 0xd5, 0x97, 0xca, 0x75, 0xb7, 0x66, 0xc0, - 0x7c, 0xfd, 0xa3, 0x0c, 0xc9, 0xac, 0xbb, 0x35, 0x79, 0x24, 0x04, 0x0e, 0xf7, 0xa3, 0x33, 0xe8, - 0xca, 0x43, 0x46, 0xb8, 0x4d, 0xdb, 0xe2, 0xf9, 0xb1, 0x53, 0x99, 0xf3, 0x53, 0x06, 0xf6, 0x64, - 0x30, 0x57, 0x4d, 0x61, 0xfa, 0xf1, 0x61, 0x40, 0xbb, 0x2f, 0xe6, 0xa4, 0xe3, 0xb3, 0x83, 0x63, - 0xae, 0xcf, 0x78, 0xe3, 0x87, 0x35, 0x5e, 0x0e, 0x16, 0x4e, 0x6b, 0xbc, 0xe8, 0xc6, 0x9a, 0x18, - 0xb0, 0xb1, 0x5e, 0x20, 0x32, 0x6c, 0x70, 0xa1, 0x49, 0x58, 0x68, 0xa6, 0xd3, 0x2e, 0x4e, 0x3a, - 0x6e, 0xcd, 0x5f, 0xa0, 0xdb, 0xa2, 0x67, 0xc8, 0x84, 0xc7, 0xea, 0xee, 0x2e, 0xab, 0x42, 0xd4, - 0x4c, 0xfa, 0x91, 0x8a, 0x24, 0x23, 0x68, 0xe8, 0x57, 0x31, 0xcb, 0x8c, 0x3b, 0x02, 0x92, 0x4f, - 0x8e, 0x7f, 0x64, 0x31, 0x63, 0x8c, 0x63, 0xfb, 0x8f, 0x1d, 0x19, 0xc1, 0x5e, 0xcd, 0xc4, 0xee, - 0xd5, 0x67, 0x48, 0xa6, 0x66, 0x72, 0x3c, 0x00, 0x26, 0x3a, 0xed, 0xa2, 0xec, 0x1a, 0xf2, 0x47, - 0x9a, 0xb1, 0x5b, 0x94, 0x40, 0x87, 0x83, 0x19, 0x6b, 0xdd, 0xf7, 0xda, 0xa0, 0x25, 0xd7, 0x00, - 0xfc, 0xb9, 0x70, 0x0d, 0xd9, 0xf7, 0xed, 0x40, 0x8b, 0x32, 0xb7, 0x6c, 0xb6, 0x04, 0x3a, 0x6e, - 0xaa, 0xd3, 0x2e, 0xfa, 0x04, 0xc3, 0x7f, 0xc8, 0x09, 0x7e, 0xba, 0x38, 0x19, 0x4e, 0x00, 0x02, - 0x66, 0x8e, 0x89, 0xfb, 0x3a, 0x36, 0xb4, 0xc8, 0x13, 0xed, 0xcb, 0x22, 0x19, 0xdf, 0x35, 0x9d, - 0x16, 0xc3, 0xed, 0x0c, 0x6b, 0x03, 0xc1, 0xf0, 0x1f, 0x52, 0x37, 0xb1, 0xdf, 0x64, 0xf9, 0x99, - 0x50, 0x37, 0xd9, 0x37, 0xe0, 0x97, 0x96, 0xc9, 0xb4, 0x69, 0x59, 0x2c, 0xa8, 0x43, 0xcc, 0xca, - 0x1d, 0xb8, 0x3a, 0xd7, 0x69, 0x17, 0x89, 0x4f, 0x5e, 0xb7, 0x65, 0x26, 0x14, 0xb6, 0xe5, 0xe1, - 0xe8, 0x57, 0x81, 0xec, 0x6a, 0x7e, 0x2e, 0x3c, 0x1c, 0xf1, 0x7e, 0x0f, 0x2f, 0xfa, 0x63, 0x44, - 0xdb, 0xcd, 0xcf, 0xc3, 0x84, 0xf1, 0x4e, 0xbb, 0xa8, 0xed, 0x1a, 0xda, 0xae, 0x24, 0x7a, 0xf9, - 0x85, 0x90, 0xe8, 0x19, 0x9a, 0x27, 0x89, 0x3c, 0x7f, 0x34, 0x24, 0x72, 0x43, 0xe3, 0xfa, 0x0d, - 0x72, 0x4a, 0x0d, 0x3d, 0xb8, 0x7e, 0x57, 0xf7, 0x31, 0x3e, 0x30, 0x66, 0x8f, 0x93, 0xdc, 0x4e, - 0x98, 0x9d, 0x64, 0x0d, 0xec, 0xe9, 0x7f, 0x9d, 0x20, 0xcf, 0x1d, 0xc0, 0x8c, 0x91, 0xab, 0x93, - 0x1c, 0x46, 0xa1, 0x16, 0x9e, 0xc7, 0x3e, 0xc5, 0xc0, 0x67, 0x37, 0x2e, 0xc6, 0x62, 0xe3, 0xa2, - 0x4c, 0xa6, 0x9b, 0xa6, 0xc7, 0x1a, 0xc2, 0x0f, 0x7e, 0x3f, 0x40, 0xc1, 0x76, 0x3e, 0x19, 0xa2, - 0x5f, 0x69, 0x87, 0x71, 0x92, 0x4d, 0x88, 0x93, 0x32, 0x99, 0xe6, 0x3b, 0xe6, 0x4b, 0x95, 0x56, - 0xc3, 0x72, 0x18, 0xc7, 0xa0, 0x05, 0x89, 0x92, 0xfc, 0x1e, 0x50, 0x0d, 0xa5, 0xdd, 0x73, 0x05, - 0xe5, 0x06, 0x5c, 0x41, 0xd1, 0x70, 0xe3, 0x15, 0xcf, 0x75, 0x83, 0xa0, 0xee, 0x0d, 0x37, 0x6e, - 0xb8, 0xae, 0x30, 0xfa, 0x28, 0x72, 0x41, 0x79, 0x57, 0x31, 0x9f, 0x77, 0x32, 0x5c, 0x10, 0xa8, - 0xc0, 0x14, 0x36, 0xe9, 0x35, 0x32, 0xeb, 0xf9, 0x39, 0x06, 0x2e, 0xe6, 0x6f, 0x81, 0x85, 0x4e, - 0xbb, 0x38, 0x13, 0x0c, 0x00, 0x4f, 0xa4, 0x27, 0xed, 0x54, 0xb7, 0x1b, 0xcc, 0xc3, 0xad, 0x00, - 0x76, 0x02, 0x82, 0xe1, 0x3f, 0x68, 0x89, 0x90, 0xaa, 0xfd, 0xe0, 0x81, 0x6d, 0xb5, 0x1c, 0xb1, - 0x8f, 0x91, 0x0f, 0x66, 0x0a, 0xa9, 0x86, 0xd2, 0x86, 0x2b, 0xc0, 0x15, 0xa6, 0x53, 0x51, 0xb8, - 0x66, 0x94, 0x2b, 0x40, 0x8e, 0xdd, 0x09, 0x59, 0x7b, 0x09, 0x52, 0x6b, 0xb6, 0x27, 0x3c, 0xb3, - 0x02, 0x17, 0xd2, 0x6c, 0xa8, 0x35, 0x50, 0xe1, 0x33, 0x76, 0xd8, 0x94, 0x51, 0xc3, 0xed, 0x0f, - 0x19, 0x6e, 0x0f, 0x88, 0x1a, 0xd9, 0x37, 0xe0, 0x37, 0x38, 0x96, 0x1c, 0x48, 0x81, 0xe7, 0x23, - 0xc7, 0x12, 0xa4, 0xc1, 0x61, 0x42, 0x1c, 0x49, 0x44, 0x16, 0x0e, 0x48, 0x44, 0x2e, 0x92, 0x29, - 0x61, 0xd7, 0x19, 0x17, 0x66, 0xbd, 0x89, 0x3b, 0x09, 0xd0, 0x75, 0x89, 0x46, 0xd8, 0xa4, 0x57, - 0xc9, 0x8c, 0xea, 0xd5, 0x3c, 0x85, 0x2d, 0x0f, 0x2e, 0x89, 0x78, 0x3b, 0xd2, 0x93, 0xbb, 0x05, - 0x83, 0xf2, 0x18, 0xcc, 0x87, 0xdd, 0xe2, 0x53, 0x0c, 0x7c, 0xd2, 0x1b, 0x64, 0x41, 0xbe, 0x99, - 0x54, 0x1e, 0x30, 0x56, 0x69, 0x32, 0x4f, 0xa6, 0x67, 0xf9, 0x45, 0x40, 0x73, 0xb4, 0xd3, 0x2e, - 0xce, 0xca, 0xb1, 0xbb, 0x8c, 0x6d, 0x30, 0x6f, 0xcd, 0xe4, 0x46, 0xb4, 0x2b, 0x55, 0xad, 0xdb, - 0x7e, 0x8d, 0x38, 0xff, 0x54, 0xa8, 0x6a, 0xdd, 0x86, 0x0f, 0xdc, 0x46, 0xd0, 0x58, 0xfe, 0x4a, - 0x27, 0xe3, 0xb0, 0xb7, 0xe9, 0x0f, 0x34, 0x92, 0xf3, 0x0b, 0x94, 0xf4, 0xca, 0x80, 0x6c, 0xa4, - 0xbf, 0x42, 0x5a, 0x58, 0x7e, 0x12, 0x16, 0xff, 0xc4, 0xd0, 0xcf, 0x7c, 0xf4, 0xa7, 0xbf, 0x7f, - 0x7f, 0xac, 0x48, 0x4f, 0x96, 0x25, 0xc7, 0x65, 0xa5, 0x30, 0xae, 0x16, 0x97, 0xe9, 0xe7, 0x1a, - 0x99, 0x51, 0x6b, 0x4a, 0xf4, 0x46, 0x9a, 0xb5, 0xe2, 0xcb, 0xa9, 0x85, 0x9b, 0x43, 0xf1, 0x22, - 0xe0, 0xd7, 0x00, 0xf0, 0xcb, 0xf4, 0x5a, 0x02, 0x60, 0xb5, 0xca, 0x55, 0x7e, 0x88, 0x1f, 0x3f, - 0x1e, 0x95, 0x1f, 0xc2, 0x61, 0xf4, 0x88, 0x7e, 0xaa, 0x91, 0x79, 0x55, 0xee, 0x8a, 0xe3, 0xa4, - 0xd3, 0x25, 0xbe, 0xa8, 0x9a, 0x4e, 0x97, 0x84, 0x42, 0xa9, 0x7e, 0x11, 0x74, 0x39, 0x43, 0x4f, - 0xa7, 0xd0, 0x85, 0x7e, 0xa5, 0x91, 0xe3, 0x3d, 0xc8, 0xb1, 0x56, 0x48, 0x57, 0x86, 0x00, 0x11, - 0x2d, 0x76, 0x16, 0x56, 0x0f, 0x23, 0x02, 0xd5, 0xb9, 0x01, 0xea, 0x5c, 0xa5, 0xcb, 0x29, 0xd4, - 0x41, 0x5e, 0xf4, 0xd0, 0x23, 0xfa, 0x47, 0x8d, 0xcc, 0x45, 0x0b, 0x42, 0xf4, 0x56, 0xca, 0x30, - 0x89, 0x2d, 0x80, 0x15, 0x5e, 0x1b, 0x92, 0x1b, 0x75, 0x79, 0x05, 0x74, 0x59, 0xa6, 0x2f, 0x26, - 0xe8, 0x12, 0x2d, 0x53, 0x95, 0x1f, 0x06, 0xfd, 0x47, 0xf4, 0xcf, 0x1a, 0xa1, 0xfd, 0x25, 0x41, - 0x9a, 0x0a, 0x4f, 0x62, 0x21, 0xb2, 0xf0, 0xfa, 0xb0, 0xec, 0xa8, 0xcf, 0x0a, 0xe8, 0x73, 0x93, - 0xbe, 0x9a, 0xa8, 0x4f, 0xef, 0xdf, 0x59, 0xe0, 0x5e, 0x50, 0x15, 0xfb, 0xad, 0x46, 0x8e, 0x46, - 0x57, 0x90, 0x9b, 0xe7, 0x56, 0xca, 0xc0, 0x39, 0x84, 0x97, 0x12, 0x4b, 0x8f, 0xfa, 0x65, 0xd0, - 0xea, 0x1c, 0x3d, 0x93, 0xca, 0x4b, 0xf4, 0x13, 0x8d, 0xcc, 0x46, 0x4a, 0x7c, 0xf4, 0x95, 0x94, - 0x51, 0xd2, 0x57, 0x32, 0x2c, 0xbc, 0x3a, 0x04, 0x27, 0xa2, 0x2e, 0x01, 0xea, 0xf3, 0xf4, 0x6c, - 0x02, 0xea, 0x1a, 0x13, 0x15, 0xc1, 0x79, 0xf0, 0x31, 0x81, 0x7e, 0xac, 0x41, 0xbd, 0x30, 0xdd, - 0x95, 0x10, 0x29, 0x40, 0xa6, 0xbb, 0x12, 0xa2, 0xd5, 0x49, 0x5d, 0x07, 0x78, 0x27, 0x68, 0x21, - 0x01, 0x9e, 0x84, 0xf2, 0x73, 0x2d, 0x2c, 0xbd, 0xd1, 0xeb, 0x29, 0x17, 0xe9, 0xa9, 0x11, 0x16, - 0x5e, 0x7e, 0x62, 0x3e, 0x44, 0x58, 0x06, 0x84, 0x2f, 0xd0, 0x73, 0x49, 0x06, 0x44, 0x06, 0x19, - 0xbd, 0x55, 0xb6, 0xf7, 0x88, 0xfe, 0x54, 0x23, 0xd3, 0x81, 0x14, 0x19, 0xb4, 0xd7, 0x53, 0x86, - 0xdd, 0x50, 0x88, 0x63, 0x2a, 0x95, 0xfa, 0x39, 0x40, 0xfc, 0x1c, 0x2d, 0x0e, 0x40, 0x4c, 0x3f, - 0xd3, 0xc8, 0x42, 0xef, 0xa7, 0x42, 0x9a, 0xea, 0x92, 0x49, 0xf8, 0x6e, 0x59, 0xb8, 0x35, 0x1c, - 0x73, 0x4a, 0x53, 0x5b, 0xbd, 0x58, 0x3f, 0xd7, 0xc8, 0xb4, 0xf2, 0x35, 0x90, 0xde, 0x49, 0xb3, - 0xfc, 0xa0, 0xaf, 0x8e, 0x85, 0x37, 0x0e, 0x29, 0x05, 0xb5, 0xb9, 0x00, 0xda, 0x3c, 0x4f, 0xf5, - 0xa4, 0x6c, 0x47, 0x01, 0xfe, 0x6b, 0x2d, 0x52, 0xa8, 0xa4, 0x69, 0x37, 0x7c, 0x7f, 0x69, 0xb5, - 0x70, 0x63, 0x18, 0x56, 0x84, 0xbc, 0x0c, 0x90, 0x2f, 0xd1, 0x0b, 0x49, 0x0e, 0x08, 0x79, 0xba, - 0xe1, 0xfe, 0x4b, 0x8d, 0xcc, 0x29, 0xb2, 0x64, 0xc4, 0xbf, 0x9a, 0x32, 0x72, 0x87, 0x45, 0x1f, - 0x5f, 0xec, 0x1d, 0x68, 0x70, 0x05, 0x3d, 0xfd, 0x8d, 0x46, 0x16, 0x22, 0xc5, 0x50, 0x89, 0x3b, - 0x6d, 0x7e, 0x15, 0x57, 0xb3, 0x2d, 0xdc, 0x1a, 0x8e, 0x19, 0xb1, 0x5f, 0x02, 0xec, 0x67, 0xe9, - 0xf3, 0x49, 0xc1, 0xa2, 0x72, 0xd1, 0x2f, 0xb4, 0xbe, 0x3a, 0x23, 0x4d, 0x9b, 0x83, 0xc4, 0x57, - 0x49, 0xd3, 0xdd, 0xf9, 0xc9, 0x15, 0x5e, 0xfd, 0x3a, 0x28, 0xf0, 0x22, 0x2d, 0x25, 0x28, 0xe0, - 0x44, 0xf9, 0xba, 0xe1, 0xf3, 0x3b, 0x8d, 0xd0, 0x1e, 0x99, 0xd2, 0x15, 0x69, 0xef, 0xea, 0xc3, - 0x68, 0x93, 0x5c, 0xc7, 0x1d, 0x78, 0x6b, 0xf6, 0x68, 0x43, 0x7f, 0xa4, 0x91, 0x2c, 0xdc, 0xfa, - 0x69, 0xef, 0x40, 0x35, 0x2f, 0x79, 0xe9, 0x89, 0x78, 0x52, 0xa6, 0xf3, 0x16, 0x66, 0x8a, 0x60, - 0xe4, 0x4f, 0xe4, 0xf1, 0x12, 0xd6, 0x6f, 0xd3, 0x1f, 0x2f, 0x7d, 0x35, 0xdf, 0xe1, 0xc0, 0x5e, - 0x03, 0xb0, 0x65, 0x7a, 0xf9, 0x40, 0xb0, 0x7d, 0xef, 0x4f, 0x3f, 0xd4, 0xc8, 0x44, 0x90, 0xfa, - 0x2d, 0xa7, 0x3d, 0x18, 0x9e, 0xd4, 0xb0, 0x3d, 0x35, 0x5c, 0xfd, 0x34, 0x60, 0x3d, 0x49, 0x9f, - 0x3d, 0x00, 0xab, 0x7f, 0xe8, 0xf9, 0xc8, 0x70, 0x3f, 0xa7, 0x3f, 0xf4, 0xfa, 0xca, 0xaf, 0xe9, - 0x0f, 0xbd, 0xfe, 0xc2, 0xe9, 0xe0, 0x43, 0x2f, 0xe4, 0xa1, 0xbf, 0xd2, 0xc8, 0x5c, 0xb4, 0x50, - 0x99, 0x0e, 0x75, 0x6c, 0xe9, 0x33, 0x1d, 0xea, 0xf8, 0xba, 0xe8, 0xc0, 0x5c, 0xda, 0x89, 0xa2, - 0xfc, 0x89, 0x46, 0x48, 0xf8, 0x07, 0x70, 0x7a, 0x2d, 0xcd, 0xca, 0x7d, 0x7f, 0x25, 0x2f, 0x5c, - 0x7f, 0x52, 0x36, 0x04, 0xfb, 0x02, 0x80, 0x3d, 0x4d, 0x9f, 0x4b, 0x00, 0x2b, 0xba, 0x2c, 0xab, - 0x6f, 0x7d, 0xf1, 0xf5, 0x92, 0xf6, 0xe5, 0xd7, 0x4b, 0xda, 0xdf, 0xbe, 0x5e, 0xd2, 0x3e, 0x7e, - 0xbc, 0x74, 0xe4, 0xcb, 0xc7, 0x4b, 0x47, 0xfe, 0xf2, 0x78, 0xe9, 0xc8, 0xfd, 0x2b, 0x35, 0x5b, - 0xec, 0xb4, 0xb6, 0x4b, 0x96, 0x5b, 0x57, 0xc5, 0x04, 0x38, 0xca, 0x7b, 0x11, 0x89, 0xfb, 0x4d, - 0xc6, 0xb7, 0x73, 0x90, 0x21, 0xbc, 0xf4, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x64, 0xbe, 0xfc, - 0x57, 0xc9, 0x30, 0x00, 0x00, + // 3021 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0xcd, 0x6f, 0x1b, 0xc7, + 0x15, 0xf7, 0x8a, 0xb4, 0x3e, 0x46, 0x9f, 0x1e, 0x2b, 0x0e, 0xc3, 0xd8, 0xa2, 0xb3, 0x8e, 0x3f, + 0xe2, 0x0f, 0x32, 0x56, 0x6c, 0x27, 0xb1, 0x9d, 0x34, 0x92, 0x1d, 0x2b, 0x46, 0x94, 0x44, 0x5d, + 0x29, 0xfd, 0x70, 0xd1, 0x12, 0xab, 0xe5, 0x98, 0x5a, 0x64, 0xc9, 0x65, 0x76, 0x86, 0x82, 0x14, + 0x43, 0x39, 0xe4, 0x2f, 0x08, 0x50, 0xa0, 0xbd, 0xf4, 0xda, 0x8f, 0x43, 0x0f, 0x01, 0x1a, 0x34, + 0x05, 0x0a, 0xa4, 0x87, 0xb6, 0x69, 0x8e, 0x41, 0x0b, 0x14, 0x2d, 0x0a, 0x10, 0x45, 0xd2, 0x13, + 0xff, 0x83, 0x02, 0x3d, 0x14, 0xf3, 0xf6, 0x2d, 0x77, 0x96, 0xdc, 0x15, 0x57, 0x14, 0x5b, 0xb4, + 0x17, 0x71, 0xe6, 0xcd, 0xbc, 0x37, 0xbf, 0xf7, 0x31, 0x33, 0x6f, 0xf6, 0x89, 0x9c, 0xb0, 0x3c, + 0x97, 0x73, 0x6b, 0xcb, 0xb4, 0xeb, 0xa5, 0x77, 0x9b, 0xcc, 0xdb, 0x2d, 0x36, 0x3c, 0x57, 0xb8, + 0xf4, 0xd4, 0x7b, 0x4c, 0x98, 0x40, 0x2e, 0x42, 0xcb, 0xf5, 0x58, 0x31, 0x9c, 0x9a, 0xbf, 0x68, + 0xb9, 0xbc, 0xe6, 0xf2, 0xd2, 0xa6, 0xc9, 0x99, 0xcf, 0x57, 0xda, 0xbe, 0xba, 0xc9, 0x84, 0x79, + 0xb5, 0xd4, 0x30, 0xab, 0x76, 0xdd, 0x14, 0xb6, 0x5b, 0xf7, 0x45, 0xe5, 0x4f, 0x29, 0x4b, 0xc0, + 0xdf, 0x72, 0xdd, 0xad, 0x5b, 0x8c, 0xe3, 0x70, 0x41, 0x1d, 0x96, 0xcd, 0xb2, 0x3f, 0x49, 0xec, + 0xe0, 0x84, 0xbc, 0x32, 0xa1, 0x6a, 0xf2, 0x72, 0xc3, 0xb3, 0x2d, 0x86, 0x63, 0x67, 0x94, 0x31, + 0xe0, 0x29, 0x6f, 0x99, 0x7c, 0xab, 0x2c, 0xdc, 0xb2, 0x65, 0x75, 0x04, 0xe8, 0xca, 0x24, 0xc7, + 0xe4, 0xa2, 0xbc, 0xe9, 0xb8, 0xd6, 0x3b, 0xe5, 0x2d, 0x66, 0x57, 0xb7, 0x04, 0xce, 0x59, 0x50, + 0xe6, 0x00, 0xbc, 0x2e, 0x19, 0x2a, 0x4a, 0xb7, 0x29, 0xe4, 0x4a, 0xc2, 0x33, 0xad, 0x77, 0x98, + 0x87, 0x13, 0x1e, 0x57, 0x26, 0x34, 0x4c, 0xcf, 0xac, 0x05, 0xfa, 0xcd, 0x2b, 0x03, 0x82, 0x77, + 0xa8, 0x55, 0xb7, 0xea, 0x42, 0xb3, 0x24, 0x5b, 0x48, 0x3d, 0x59, 0x75, 0xdd, 0xaa, 0xc3, 0x4a, + 0x66, 0xc3, 0x2e, 0x99, 0xf5, 0xba, 0x2b, 0xc0, 0x8e, 0xc8, 0xa3, 0xe7, 0xc8, 0x89, 0xaf, 0x4b, + 0x53, 0x6f, 0x70, 0xfe, 0x9a, 0xcd, 0x85, 0xeb, 0xed, 0x1a, 0xec, 0xdd, 0x26, 0xe3, 0x42, 0xff, + 0x1e, 0x79, 0xbc, 0x67, 0x84, 0x37, 0xdc, 0x3a, 0x67, 0xf4, 0x0e, 0x19, 0x17, 0x9c, 0x97, 0x1d, + 0x9b, 0x8b, 0x9c, 0x76, 0x3a, 0x73, 0x61, 0x72, 0x51, 0x2f, 0xee, 0xeb, 0xdb, 0xe2, 0xc6, 0xfa, + 0xfa, 0x72, 0xf6, 0xf3, 0x56, 0xe1, 0x88, 0x31, 0x26, 0x38, 0x5f, 0xb5, 0xb9, 0xd0, 0xe7, 0x09, + 0x05, 0xf9, 0x6b, 0xa0, 0x58, 0xb0, 0xea, 0x03, 0x72, 0x3c, 0x42, 0xed, 0xac, 0x38, 0xea, 0x1b, + 0x20, 0xa7, 0x9d, 0xd6, 0x2e, 0x4c, 0x2e, 0x9e, 0xed, 0xb3, 0x9e, 0xcf, 0x8e, 0x4b, 0x22, 0xab, + 0xfe, 0x06, 0x79, 0x12, 0x64, 0xaf, 0x30, 0xf1, 0x56, 0x53, 0x6c, 0xec, 0x6c, 0xf8, 0xc6, 0xc6, + 0xa5, 0x69, 0x8e, 0x8c, 0x01, 0xf3, 0xfd, 0xbb, 0xb0, 0x48, 0xc6, 0x08, 0xba, 0x74, 0x9e, 0x1c, + 0x05, 0xff, 0xe5, 0x46, 0x4e, 0x6b, 0x17, 0xb2, 0x86, 0xdf, 0xd1, 0x9b, 0xe4, 0x64, 0xbc, 0x38, + 0xc4, 0xfc, 0x36, 0x99, 0x72, 0x15, 0x3a, 0x22, 0xbf, 0xd4, 0x07, 0xb9, 0x2a, 0x0a, 0xf1, 0x47, + 0xc4, 0xe8, 0x0c, 0xb5, 0x58, 0x72, 0x9c, 0x38, 0x2d, 0xee, 0x11, 0x12, 0xee, 0x16, 0x5c, 0xf3, + 0x5c, 0xd1, 0xdf, 0x5a, 0x45, 0xb9, 0xb5, 0x8a, 0xfe, 0x96, 0xc4, 0xad, 0x55, 0x5c, 0x33, 0xab, + 0x0c, 0x79, 0x0d, 0x85, 0x53, 0xff, 0x54, 0x43, 0xf5, 0x7a, 0xd6, 0x49, 0x54, 0x2f, 0x33, 0x04, + 0xf5, 0xe8, 0x4a, 0x04, 0xff, 0x08, 0xe0, 0x3f, 0xdf, 0x17, 0xbf, 0x8f, 0x29, 0xa2, 0xc0, 0x07, + 0x1a, 0xd1, 0xe3, 0x14, 0x58, 0xde, 0xbd, 0x23, 0x91, 0x04, 0xf6, 0x9a, 0x27, 0x47, 0x01, 0x19, + 0xfa, 0xdc, 0xef, 0x74, 0x59, 0x71, 0x64, 0x60, 0x2b, 0xfe, 0x5e, 0x23, 0x67, 0xf6, 0x05, 0xf1, + 0x7f, 0x62, 0xcc, 0x5b, 0xe4, 0x54, 0x10, 0xeb, 0xf7, 0xeb, 0x1b, 0x3b, 0xaf, 0x99, 0x7c, 0x6b, + 0xc3, 0xbd, 0x63, 0x89, 0x9d, 0xc0, 0x8c, 0x79, 0x32, 0x6e, 0xe3, 0x00, 0x58, 0x72, 0xc2, 0xe8, + 0xf4, 0xf5, 0x3d, 0xb2, 0x90, 0xc4, 0x8c, 0xea, 0x7f, 0x87, 0xcc, 0xd8, 0x91, 0x11, 0x0c, 0xdc, + 0x2b, 0x7d, 0x0c, 0x10, 0x15, 0x87, 0x26, 0xe8, 0x12, 0xa5, 0xdf, 0xc6, 0xe5, 0xa3, 0x93, 0xef, + 0x9a, 0xc2, 0x4c, 0x03, 0xfe, 0x3d, 0x52, 0x48, 0xe4, 0x46, 0xf4, 0xdf, 0x24, 0xd3, 0x77, 0x24, + 0x26, 0x70, 0xe9, 0xc6, 0x0e, 0x4f, 0xe9, 0x3d, 0x95, 0x07, 0xa1, 0x47, 0xe5, 0xe8, 0x55, 0xb4, + 0xfa, 0x92, 0xe3, 0xc4, 0x5b, 0x7d, 0x58, 0x9b, 0xfd, 0x33, 0x0d, 0x6d, 0x14, 0xb3, 0xd2, 0x3e, + 0x2e, 0xca, 0x0c, 0xc9, 0x45, 0xc3, 0x8b, 0xd3, 0x27, 0xc9, 0x13, 0x41, 0xa8, 0x6d, 0x70, 0xbe, + 0x54, 0xa9, 0x78, 0x8c, 0x77, 0xee, 0x96, 0x57, 0x48, 0x3e, 0x6e, 0x10, 0x15, 0x9c, 0x23, 0x19, + 0x26, 0x02, 0xff, 0xcb, 0xa6, 0xa4, 0x6c, 0x0a, 0x0b, 0xe0, 0x4c, 0x18, 0xb2, 0xd9, 0xb9, 0xb3, + 0xa4, 0x84, 0xf5, 0xf5, 0x40, 0xee, 0xeb, 0x78, 0x67, 0x05, 0x54, 0x14, 0x78, 0x8d, 0x64, 0x36, + 0xd6, 0xd7, 0xd1, 0x2b, 0x29, 0x2e, 0x48, 0x43, 0x4e, 0xd7, 0x4b, 0x78, 0xed, 0xae, 0x30, 0xb1, + 0x62, 0xf2, 0x35, 0x99, 0x97, 0x28, 0x47, 0x95, 0x5d, 0xaf, 0xb0, 0x1d, 0xc4, 0xe8, 0x77, 0xf4, + 0x32, 0xc9, 0xf5, 0x32, 0x84, 0x17, 0x75, 0x40, 0x43, 0x1c, 0xe7, 0xfb, 0xe0, 0xe8, 0x88, 0xe8, + 0x30, 0xea, 0x26, 0x22, 0x5a, 0x72, 0x9c, 0x6e, 0x44, 0xc3, 0x8a, 0xbf, 0x9f, 0x69, 0xa8, 0x44, + 0x64, 0x8d, 0x58, 0x25, 0x32, 0x03, 0x29, 0x31, 0xbc, 0x08, 0x5b, 0x0c, 0x83, 0x08, 0xf6, 0xe9, + 0x9b, 0x90, 0x77, 0xee, 0xef, 0xa2, 0x77, 0xc2, 0xc4, 0x23, 0xc2, 0x83, 0x0a, 0xae, 0x92, 0x49, + 0x85, 0x8c, 0x66, 0xbc, 0xd8, 0xef, 0xf4, 0x50, 0x04, 0xa9, 0xec, 0x7a, 0x05, 0x01, 0x2e, 0x39, + 0x4e, 0x0c, 0xc0, 0x61, 0x79, 0xec, 0x63, 0x2d, 0x4c, 0x43, 0x52, 0xe9, 0x94, 0x39, 0x84, 0x4e, + 0xc3, 0xf3, 0xde, 0x42, 0x98, 0xd4, 0xac, 0xb1, 0x7a, 0xc5, 0xae, 0x57, 0x23, 0xe6, 0xd1, 0x45, + 0x78, 0xe2, 0x76, 0x8d, 0xa3, 0x5e, 0xeb, 0x64, 0xa6, 0xe1, 0x0f, 0xe0, 0x8b, 0x03, 0x55, 0xbb, + 0xdc, 0x2f, 0x21, 0x8d, 0x48, 0x9b, 0x6e, 0xa8, 0x5d, 0xfd, 0x25, 0x72, 0xda, 0x4f, 0x7a, 0x55, + 0x6a, 0x57, 0x9e, 0xf2, 0x04, 0x19, 0xf7, 0xdf, 0x30, 0x76, 0x05, 0xdc, 0x96, 0x0d, 0xd2, 0xd3, + 0x8a, 0xfe, 0x3e, 0x79, 0x6a, 0x1f, 0x76, 0x04, 0xfe, 0xed, 0x18, 0xe0, 0xda, 0x41, 0x81, 0x07, + 0xd7, 0x54, 0x14, 0xfe, 0x8d, 0xf0, 0x7e, 0x5f, 0x35, 0xb9, 0x58, 0x96, 0x2f, 0xa1, 0xd7, 0xe0, + 0x21, 0xb4, 0xff, 0xb6, 0x78, 0x84, 0x57, 0x6b, 0x1c, 0x1f, 0xa2, 0xfe, 0x16, 0x99, 0xed, 0x1a, + 0x42, 0xd8, 0xc5, 0x3e, 0xb0, 0xbb, 0x05, 0x76, 0x8b, 0xd1, 0xb7, 0xc2, 0x1b, 0x2f, 0x01, 0xf4, + 0xb0, 0xb6, 0xca, 0xef, 0x34, 0xd4, 0x33, 0x6e, 0xa9, 0xfd, 0xf4, 0xcc, 0x0c, 0x41, 0xcf, 0xe1, + 0x6d, 0x9d, 0x4b, 0xe1, 0x2d, 0xa7, 0xa6, 0x20, 0xf1, 0xae, 0x5d, 0x55, 0x4e, 0x49, 0x79, 0xed, + 0xef, 0x42, 0xa8, 0x0c, 0xfa, 0xd2, 0xaa, 0x92, 0xf9, 0xe8, 0xd2, 0x68, 0xb5, 0xb7, 0xc8, 0x94, + 0x9a, 0x30, 0xa5, 0x7c, 0x61, 0xa9, 0x2c, 0x46, 0x44, 0x80, 0xfe, 0x5d, 0xd4, 0x51, 0x1e, 0x6a, + 0xff, 0x81, 0x34, 0xeb, 0x23, 0x0d, 0x15, 0xe9, 0xc8, 0x4f, 0x54, 0x24, 0x73, 0x28, 0x45, 0x86, + 0xe7, 0xf5, 0xf7, 0x95, 0xdb, 0xc4, 0x12, 0x3b, 0x78, 0x1a, 0xf4, 0x38, 0xb2, 0xfb, 0x4c, 0x1a, + 0xda, 0x03, 0xea, 0x13, 0xf5, 0x9e, 0x51, 0x01, 0xfc, 0xcf, 0x5b, 0xee, 0x24, 0x5a, 0x4e, 0x6e, + 0xc8, 0x07, 0x4c, 0x98, 0x91, 0xc3, 0x45, 0xbf, 0x8e, 0x6a, 0x75, 0x8f, 0xa2, 0x5a, 0x27, 0xc8, + 0xa8, 0x72, 0xdc, 0x65, 0x0c, 0xec, 0xe9, 0x1b, 0x78, 0x7f, 0xdd, 0x71, 0xeb, 0xdb, 0xcc, 0x93, + 0x09, 0xdf, 0x86, 0x2b, 0xd9, 0x13, 0x1c, 0x92, 0x09, 0x1d, 0x92, 0x27, 0xe3, 0x55, 0x93, 0xaf, + 0xda, 0x35, 0x5b, 0x60, 0x46, 0xdb, 0xe9, 0xeb, 0x3f, 0xd6, 0xf0, 0xda, 0xeb, 0x15, 0x8b, 0x78, + 0x2e, 0x93, 0x63, 0x6e, 0x53, 0x6c, 0xba, 0xcd, 0x7a, 0x65, 0xc5, 0xe4, 0xf7, 0xeb, 0x72, 0x10, + 0x77, 0x7c, 0xef, 0x80, 0x9c, 0x0d, 0x5f, 0x97, 0x2c, 0xd7, 0xb9, 0xc7, 0x18, 0xce, 0xf6, 0x17, + 0xed, 0x1d, 0xa0, 0x17, 0xc8, 0xac, 0xfc, 0x55, 0xcf, 0xbe, 0x0c, 0x04, 0x53, 0x37, 0x59, 0x3f, + 0x4f, 0xce, 0x02, 0xcc, 0x37, 0x18, 0xe7, 0x66, 0x95, 0xad, 0x99, 0x9c, 0xdb, 0xf5, 0xea, 0x5a, + 0x28, 0x31, 0xb0, 0xee, 0x3d, 0x72, 0xae, 0xdf, 0x44, 0x54, 0xec, 0x24, 0x99, 0x78, 0xd8, 0x81, + 0xe8, 0x2b, 0x14, 0x12, 0xf4, 0x5b, 0xb8, 0xe0, 0x83, 0x57, 0xbf, 0xf1, 0x86, 0xcc, 0xee, 0x3d, + 0xb3, 0xce, 0x4d, 0x4b, 0xba, 0xd7, 0x60, 0x16, 0xb3, 0x1b, 0x9d, 0xbb, 0x82, 0x92, 0xec, 0x56, + 0xf8, 0x7a, 0x84, 0xb6, 0xfe, 0xaf, 0x2c, 0xa2, 0xd8, 0x87, 0xbb, 0x63, 0x5e, 0x82, 0xdf, 0x0f, + 0x3b, 0x42, 0x96, 0xa7, 0xdb, 0xad, 0xc2, 0x04, 0x50, 0xe5, 0x43, 0xc9, 0x08, 0x9b, 0x74, 0x91, + 0x4c, 0xf9, 0xb3, 0xeb, 0xcd, 0xda, 0x26, 0xf3, 0x7c, 0xcb, 0x2e, 0xcf, 0xb6, 0x5b, 0x85, 0x49, + 0xa0, 0xbf, 0x09, 0x64, 0x43, 0xed, 0xd0, 0x97, 0xc9, 0x9c, 0xe5, 0xd6, 0x85, 0x67, 0x5a, 0xa2, + 0x6c, 0xfa, 0x2f, 0x1f, 0xb0, 0xf2, 0xc4, 0xf2, 0xf1, 0x76, 0xab, 0x30, 0x1b, 0x8c, 0x05, 0x8f, + 0xa2, 0x6e, 0x02, 0x7d, 0x95, 0x1c, 0xb7, 0x9a, 0xb5, 0xa6, 0x63, 0x0a, 0x7b, 0x9b, 0x95, 0xab, + 0x26, 0x2f, 0x37, 0x39, 0xab, 0xe4, 0xb2, 0x20, 0xe2, 0xb1, 0x76, 0xab, 0x70, 0x2c, 0x1c, 0x5e, + 0x31, 0xf9, 0xdb, 0x9c, 0x55, 0x8c, 0x5e, 0x12, 0x3d, 0x49, 0xb2, 0x0f, 0x3d, 0xb7, 0x96, 0x3b, + 0x0a, 0x7c, 0xe3, 0xed, 0x56, 0x01, 0xfa, 0x06, 0xfc, 0xa5, 0xe7, 0x20, 0x46, 0x7d, 0xc9, 0xa3, + 0x30, 0x63, 0xb2, 0xdd, 0x2a, 0x8c, 0x55, 0x51, 0x5e, 0xd0, 0x90, 0xe6, 0x72, 0xdc, 0x2a, 0x2f, + 0x6f, 0x3a, 0xae, 0x5b, 0xcb, 0x8d, 0x85, 0xe6, 0x92, 0xd4, 0x65, 0x49, 0x34, 0xc2, 0x26, 0xd5, + 0xc9, 0x28, 0x17, 0xa6, 0x68, 0xf2, 0xdc, 0x38, 0xcc, 0x24, 0xed, 0x56, 0x01, 0x29, 0x06, 0xfe, + 0xd2, 0x13, 0x64, 0x44, 0xb8, 0xb9, 0x09, 0x18, 0x1f, 0x6d, 0xb7, 0x0a, 0x23, 0xc2, 0x35, 0x46, + 0x84, 0x2b, 0xcd, 0x26, 0x42, 0xb7, 0xf9, 0xee, 0x21, 0xa1, 0xd9, 0x94, 0x31, 0x70, 0x52, 0x37, + 0x81, 0x2e, 0x91, 0x63, 0x2a, 0xbf, 0x7f, 0x53, 0x4e, 0x82, 0x80, 0xf9, 0x76, 0xab, 0xa0, 0x0a, + 0xbf, 0x2f, 0xc7, 0x8c, 0x1e, 0x0a, 0xbd, 0x41, 0xb2, 0x52, 0x97, 0xdc, 0x54, 0xaa, 0x0f, 0xad, + 0xab, 0x6e, 0xd5, 0x80, 0xf9, 0xfa, 0x07, 0x19, 0x92, 0x59, 0x75, 0xab, 0xf2, 0x48, 0x08, 0x1c, + 0xee, 0x47, 0x67, 0xd0, 0x95, 0x87, 0x8c, 0x70, 0x1b, 0xb6, 0xc5, 0x73, 0x23, 0xa7, 0x33, 0x17, + 0x26, 0x0c, 0xec, 0xc9, 0x60, 0xae, 0x98, 0xc2, 0xf4, 0xe3, 0xc3, 0x80, 0x76, 0x4f, 0xcc, 0x49, + 0xc7, 0x67, 0xfb, 0xc7, 0x5c, 0x8f, 0xf1, 0x8e, 0x1e, 0xd6, 0x78, 0xa3, 0xb0, 0x70, 0x5a, 0xe3, + 0x45, 0x37, 0xd6, 0x58, 0x9f, 0x8d, 0xf5, 0x0c, 0x91, 0x61, 0x83, 0x0b, 0x8d, 0xc3, 0x42, 0x53, + 0xed, 0x56, 0x61, 0xdc, 0x71, 0xab, 0xfe, 0x02, 0x9d, 0x16, 0x3d, 0x4b, 0xc6, 0x3c, 0x56, 0x73, + 0xb7, 0x59, 0x05, 0xa2, 0x66, 0xdc, 0x8f, 0x54, 0x24, 0x19, 0x41, 0x43, 0xbf, 0x86, 0x59, 0x66, + 0xdc, 0x11, 0x90, 0x7c, 0x72, 0xfc, 0x33, 0x8b, 0x19, 0x63, 0x1c, 0xdb, 0x7f, 0xed, 0xc8, 0x08, + 0xf6, 0x6a, 0x26, 0x76, 0xaf, 0x3e, 0x41, 0x32, 0x55, 0x93, 0xe3, 0x01, 0x30, 0xd6, 0x6e, 0x15, + 0x64, 0xd7, 0x90, 0x7f, 0xa4, 0x19, 0x3b, 0x35, 0x15, 0x74, 0x38, 0x98, 0xb1, 0xda, 0x79, 0x96, + 0x07, 0x2d, 0xb9, 0x06, 0xe0, 0x1f, 0x0d, 0xd7, 0x90, 0x7d, 0xdf, 0x0e, 0xb4, 0x20, 0x73, 0xcb, + 0x46, 0x53, 0xa0, 0xe3, 0x26, 0xda, 0xad, 0x82, 0x4f, 0x30, 0xfc, 0x1f, 0x39, 0xc1, 0x4f, 0x17, + 0xc7, 0xc3, 0x09, 0x40, 0xc0, 0xcc, 0x31, 0x71, 0x5f, 0xc7, 0x86, 0x16, 0x39, 0xd0, 0xbe, 0x2c, + 0x90, 0xa3, 0xdb, 0xa6, 0xd3, 0x64, 0xb8, 0x9d, 0x61, 0x6d, 0x20, 0x18, 0xfe, 0x8f, 0xd4, 0x4d, + 0xec, 0x36, 0x58, 0x6e, 0x2a, 0xd4, 0x4d, 0xf6, 0x0d, 0xf8, 0x4b, 0x4b, 0x64, 0xd2, 0xb4, 0x2c, + 0x16, 0x94, 0x51, 0xa6, 0xe5, 0x0e, 0x5c, 0x9e, 0x69, 0xb7, 0x0a, 0xc4, 0x27, 0xaf, 0xda, 0x32, + 0x13, 0x0a, 0xdb, 0xf2, 0x70, 0xec, 0x3c, 0x00, 0x67, 0xc2, 0xc3, 0x11, 0xef, 0xf7, 0xf0, 0xa2, + 0x3f, 0x4e, 0xb4, 0xed, 0xdc, 0x2c, 0x4c, 0x38, 0xda, 0x6e, 0x15, 0xb4, 0x6d, 0x43, 0xdb, 0x96, + 0x44, 0x2f, 0x37, 0x17, 0x12, 0x3d, 0x43, 0xf3, 0x24, 0x91, 0xe7, 0x8e, 0x85, 0x44, 0x6e, 0x68, + 0x5c, 0xbf, 0x89, 0x6f, 0x51, 0x0c, 0x3d, 0xb8, 0x7e, 0x97, 0x77, 0x31, 0x3e, 0x30, 0x66, 0x4f, + 0x90, 0xd1, 0xad, 0x30, 0x3b, 0xc9, 0x1a, 0xd8, 0xd3, 0xff, 0x3a, 0x86, 0x2f, 0xd1, 0x78, 0x66, + 0x8c, 0x5c, 0x9d, 0x8c, 0x62, 0x14, 0x6a, 0xe1, 0x79, 0xec, 0x53, 0x0c, 0xfc, 0xed, 0xc4, 0xc5, + 0x48, 0x6c, 0x5c, 0x94, 0xc8, 0x64, 0xc3, 0xf4, 0x58, 0x5d, 0xf8, 0xc1, 0xef, 0x07, 0x28, 0xd8, + 0xce, 0x27, 0x43, 0xf4, 0x2b, 0xed, 0x30, 0x4e, 0xb2, 0x09, 0x71, 0x52, 0x22, 0x93, 0x7c, 0xcb, + 0x7c, 0xae, 0xdc, 0xac, 0x5b, 0x0e, 0xe3, 0x18, 0xb4, 0x20, 0x51, 0x92, 0xdf, 0x06, 0xaa, 0xa1, + 0xb4, 0xbb, 0xae, 0xa0, 0xd1, 0x3e, 0x57, 0x50, 0x34, 0xdc, 0x78, 0xd9, 0x73, 0xdd, 0x20, 0xa8, + 0xbb, 0xc3, 0x8d, 0x1b, 0xae, 0x2b, 0x8c, 0x1e, 0x8a, 0x5c, 0x50, 0xde, 0x55, 0xcc, 0xe7, 0x1d, + 0x0f, 0x17, 0x04, 0x2a, 0x30, 0x85, 0x4d, 0x7a, 0x9d, 0x4c, 0x7b, 0x7e, 0x8e, 0x81, 0x8b, 0xf9, + 0x5b, 0x60, 0xae, 0xdd, 0x2a, 0x4c, 0x05, 0x03, 0xc0, 0x13, 0xe9, 0x49, 0x3b, 0xd5, 0xec, 0x3a, + 0xf3, 0x70, 0x2b, 0x80, 0x9d, 0x80, 0x60, 0xf8, 0x3f, 0xb4, 0x48, 0x48, 0xc5, 0x7e, 0xf8, 0xd0, + 0xb6, 0x9a, 0x8e, 0xd8, 0xc5, 0xc8, 0x07, 0x33, 0x85, 0x54, 0x43, 0x69, 0xc3, 0x15, 0xe0, 0x0a, + 0xd3, 0x29, 0x2b, 0x5c, 0x53, 0xca, 0x15, 0x20, 0xc7, 0xee, 0x86, 0xac, 0xdd, 0x04, 0xa9, 0x35, + 0xdb, 0x11, 0x9e, 0x59, 0x86, 0x0b, 0x69, 0x3a, 0xd4, 0x1a, 0xa8, 0xf0, 0x15, 0x3e, 0x6c, 0xca, + 0xa8, 0xe1, 0xf6, 0x7b, 0x0c, 0xb7, 0x07, 0x44, 0x8d, 0xec, 0x1b, 0xf0, 0x37, 0x38, 0x96, 0x1c, + 0x48, 0x81, 0x67, 0x23, 0xc7, 0x12, 0xa4, 0xc1, 0x61, 0x42, 0x1c, 0x49, 0x44, 0xe6, 0xf6, 0x49, + 0x44, 0x2e, 0x91, 0x09, 0x61, 0xd7, 0x18, 0x17, 0x66, 0xad, 0x81, 0x3b, 0x09, 0xd0, 0x75, 0x88, + 0x46, 0xd8, 0xa4, 0xd7, 0xc8, 0x94, 0xea, 0xd5, 0x1c, 0x85, 0x2d, 0x0f, 0x2e, 0x89, 0x78, 0x3b, + 0xd2, 0x93, 0xbb, 0x05, 0x83, 0xf2, 0x38, 0xcc, 0x87, 0xdd, 0xe2, 0x53, 0x0c, 0xfc, 0xa5, 0x37, + 0xc9, 0x9c, 0x7c, 0x99, 0x94, 0x1f, 0x32, 0x56, 0x6e, 0x30, 0x4f, 0xa6, 0x67, 0xb9, 0x79, 0x40, + 0x73, 0xac, 0xdd, 0x2a, 0x4c, 0xcb, 0xb1, 0x7b, 0x8c, 0xad, 0x31, 0x6f, 0xc5, 0xe4, 0x46, 0xb4, + 0x2b, 0x55, 0xad, 0xd9, 0x7e, 0x89, 0x3b, 0xf7, 0x58, 0xa8, 0x6a, 0xcd, 0x86, 0xef, 0xf3, 0x46, + 0xd0, 0x58, 0xfc, 0xe8, 0x69, 0x72, 0x14, 0xf6, 0x36, 0xfd, 0x81, 0x46, 0x46, 0xfd, 0xfa, 0x2a, + 0xbd, 0xda, 0x27, 0x1b, 0xe9, 0x2d, 0xf0, 0xe6, 0x17, 0x0f, 0xc2, 0xe2, 0x9f, 0x18, 0xfa, 0xd9, + 0x0f, 0xfe, 0xf4, 0x8f, 0xef, 0x8f, 0x14, 0xe8, 0xa9, 0x92, 0xe4, 0xb8, 0xa2, 0xd4, 0xf5, 0xd5, + 0xda, 0x38, 0xfd, 0x4c, 0x23, 0x53, 0x6a, 0x49, 0x8c, 0xde, 0x4c, 0xb3, 0x56, 0x7c, 0x35, 0x38, + 0x7f, 0x6b, 0x20, 0x5e, 0x04, 0xfc, 0x12, 0x00, 0x7e, 0x9e, 0x5e, 0x4f, 0x00, 0xac, 0x16, 0xe9, + 0x4a, 0x8f, 0xf0, 0xe3, 0xc7, 0x5e, 0xe9, 0x11, 0x1c, 0x46, 0x7b, 0xf4, 0x13, 0x8d, 0xcc, 0xaa, + 0x72, 0x97, 0x1c, 0x27, 0x9d, 0x2e, 0xf1, 0x35, 0xe1, 0x74, 0xba, 0x24, 0xd4, 0x79, 0xf5, 0x4b, + 0xa0, 0xcb, 0x59, 0x7a, 0x26, 0x85, 0x2e, 0xf4, 0x6f, 0x1a, 0x39, 0xd1, 0x85, 0x1c, 0x3f, 0x44, + 0xd2, 0xa5, 0x01, 0x40, 0x44, 0xbf, 0x81, 0xe6, 0x97, 0x0f, 0x23, 0x02, 0xd5, 0xb9, 0x09, 0xea, + 0x5c, 0xa3, 0x8b, 0x29, 0xd4, 0x41, 0x5e, 0xf4, 0xd0, 0x1e, 0xfd, 0x83, 0x46, 0x66, 0xa2, 0xf5, + 0x2c, 0x7a, 0x3b, 0x65, 0x98, 0xc4, 0xd6, 0xef, 0xf2, 0x2f, 0x0d, 0xc8, 0x8d, 0xba, 0xbc, 0x00, + 0xba, 0x2c, 0xd2, 0x67, 0x13, 0x74, 0x89, 0x56, 0xd9, 0x4a, 0x8f, 0x82, 0xfe, 0x1e, 0xfd, 0xb3, + 0x46, 0x68, 0x6f, 0x45, 0x93, 0xa6, 0xc2, 0x93, 0x58, 0x47, 0xcd, 0xbf, 0x3c, 0x28, 0x3b, 0xea, + 0xb3, 0x04, 0xfa, 0xdc, 0xa2, 0x2f, 0x26, 0xea, 0xd3, 0xfd, 0xdf, 0x38, 0x70, 0x2f, 0xa8, 0x8a, + 0xfd, 0x46, 0x23, 0xc7, 0xa2, 0x2b, 0xc8, 0xcd, 0x73, 0x3b, 0x65, 0xe0, 0x1c, 0xc2, 0x4b, 0x89, + 0x95, 0x53, 0xfd, 0x0a, 0x68, 0x75, 0x9e, 0x9e, 0x4d, 0xe5, 0x25, 0xfa, 0xb1, 0x46, 0xa6, 0x23, + 0x15, 0x4a, 0xfa, 0x42, 0xca, 0x28, 0xe9, 0xa9, 0x78, 0xe6, 0x5f, 0x1c, 0x80, 0x13, 0x51, 0x17, + 0x01, 0xf5, 0x05, 0x7a, 0x2e, 0x01, 0x75, 0x95, 0x89, 0xb2, 0xe0, 0x3c, 0xf8, 0x98, 0x40, 0x3f, + 0xd4, 0xa0, 0xdc, 0x99, 0xee, 0x4a, 0x88, 0xd4, 0x4f, 0xd3, 0x5d, 0x09, 0xd1, 0xe2, 0xaa, 0xae, + 0x03, 0xbc, 0x93, 0x34, 0x9f, 0x00, 0x4f, 0x42, 0xf9, 0xb9, 0x16, 0x56, 0x0e, 0xe9, 0x8d, 0x94, + 0x8b, 0x74, 0x95, 0x38, 0xf3, 0xcf, 0x1f, 0x98, 0x0f, 0x11, 0x96, 0x00, 0xe1, 0x33, 0xf4, 0x7c, + 0x92, 0x01, 0x91, 0x41, 0x46, 0x6f, 0x85, 0xed, 0xec, 0xd1, 0x9f, 0x6a, 0x64, 0x32, 0x90, 0x22, + 0x83, 0xf6, 0x46, 0xca, 0xb0, 0x1b, 0x08, 0x71, 0x4c, 0xa1, 0x55, 0x3f, 0x0f, 0x88, 0x9f, 0xa2, + 0x85, 0x3e, 0x88, 0xe9, 0xa7, 0x1a, 0x99, 0xeb, 0xfe, 0x54, 0x48, 0x53, 0x5d, 0x32, 0x09, 0xdf, + 0x2d, 0xf3, 0xb7, 0x07, 0x63, 0x4e, 0x69, 0x6a, 0xab, 0x1b, 0xeb, 0x67, 0x1a, 0x99, 0x54, 0xbe, + 0x06, 0xd2, 0xbb, 0x69, 0x96, 0xef, 0xf7, 0xd5, 0x31, 0xff, 0xea, 0x21, 0xa5, 0xa0, 0x36, 0x17, + 0x41, 0x9b, 0xa7, 0xa9, 0x9e, 0x94, 0xed, 0x28, 0xc0, 0x7f, 0xa5, 0x45, 0xea, 0xac, 0x34, 0xed, + 0x86, 0xef, 0xad, 0x0c, 0xe7, 0x6f, 0x0e, 0xc2, 0x8a, 0x90, 0x17, 0x01, 0xf2, 0x65, 0x7a, 0x31, + 0xc9, 0x01, 0x21, 0x4f, 0x27, 0xdc, 0x7f, 0xa1, 0x91, 0x19, 0x45, 0x96, 0x8c, 0xf8, 0x17, 0x53, + 0x46, 0xee, 0xa0, 0xe8, 0xe3, 0x6b, 0xd5, 0x7d, 0x0d, 0xae, 0xa0, 0xa7, 0xbf, 0xd6, 0xc8, 0x5c, + 0xa4, 0x24, 0x2a, 0x71, 0xa7, 0xcd, 0xaf, 0xe2, 0x4a, 0xce, 0xf9, 0xdb, 0x83, 0x31, 0x23, 0xf6, + 0xcb, 0x80, 0xfd, 0x1c, 0x7d, 0x3a, 0x29, 0x58, 0x54, 0x2e, 0xfa, 0x47, 0x8d, 0xcc, 0xc7, 0x55, + 0x89, 0xe9, 0xd7, 0x52, 0x65, 0xe5, 0xc9, 0xe5, 0xe9, 0xfc, 0x2b, 0x83, 0x0b, 0x40, 0x4d, 0x9e, + 0x07, 0x4d, 0xae, 0xd2, 0x52, 0x1a, 0x4d, 0x30, 0x25, 0x2b, 0xdb, 0x95, 0x3d, 0xfa, 0xb9, 0xd6, + 0x53, 0x3c, 0xa5, 0x69, 0x13, 0xab, 0xf8, 0xd2, 0x6f, 0xba, 0x44, 0x26, 0xb9, 0x6c, 0xad, 0xdf, + 0x00, 0x5d, 0x9e, 0xa5, 0xc5, 0x04, 0x5d, 0x9c, 0x28, 0x5f, 0x67, 0x4f, 0xfc, 0x56, 0x23, 0xb4, + 0x4b, 0xa6, 0x8c, 0xaf, 0xb4, 0x09, 0xc8, 0x61, 0xb4, 0x49, 0x2e, 0x4e, 0xf7, 0x4d, 0x05, 0xba, + 0xb4, 0xa1, 0x3f, 0xd2, 0x48, 0x16, 0x52, 0x99, 0xb4, 0x17, 0xbb, 0x9a, 0x6c, 0x3d, 0x77, 0x20, + 0x9e, 0x94, 0x6f, 0x14, 0x0b, 0xd3, 0x5f, 0x30, 0xf2, 0xc7, 0xf2, 0xcc, 0x0c, 0x8b, 0xd2, 0xe9, + 0xcf, 0xcc, 0x9e, 0x42, 0xf6, 0x60, 0x60, 0xaf, 0x03, 0xd8, 0x12, 0xbd, 0xb2, 0x2f, 0xd8, 0x9e, + 0x47, 0xe1, 0x0f, 0x35, 0x32, 0x16, 0xe4, 0xb3, 0x8b, 0x69, 0x4f, 0xbb, 0x83, 0x1a, 0xb6, 0xab, + 0x30, 0xad, 0x9f, 0x01, 0xac, 0xa7, 0xe8, 0x93, 0xfb, 0x60, 0xf5, 0x4f, 0x72, 0x1f, 0x19, 0xee, + 0xf0, 0xf4, 0x27, 0x79, 0x4f, 0x4d, 0x39, 0xfd, 0x49, 0xde, 0x5b, 0x0d, 0xee, 0x7f, 0x92, 0x87, + 0x3c, 0xf4, 0x97, 0x1a, 0x99, 0x89, 0x56, 0x5f, 0xd3, 0xa1, 0x8e, 0xad, 0xe7, 0xa6, 0x43, 0x1d, + 0x5f, 0xec, 0xed, 0xfb, 0x40, 0x70, 0xa2, 0x28, 0x7f, 0xa2, 0x11, 0x12, 0xfe, 0x53, 0x3e, 0xbd, + 0x9e, 0x66, 0xe5, 0x9e, 0x7f, 0xef, 0xcf, 0xdf, 0x38, 0x28, 0x1b, 0x82, 0x7d, 0x06, 0xc0, 0x9e, + 0xa1, 0x4f, 0x25, 0x80, 0x15, 0x1d, 0x96, 0xe5, 0xd7, 0x3f, 0xff, 0x72, 0x41, 0xfb, 0xe2, 0xcb, + 0x05, 0xed, 0xef, 0x5f, 0x2e, 0x68, 0x1f, 0x7e, 0xb5, 0x70, 0xe4, 0x8b, 0xaf, 0x16, 0x8e, 0xfc, + 0xe5, 0xab, 0x85, 0x23, 0x0f, 0xae, 0x56, 0x6d, 0xb1, 0xd5, 0xdc, 0x2c, 0x5a, 0x6e, 0x4d, 0x15, + 0x13, 0xe0, 0x28, 0xed, 0x44, 0x24, 0xee, 0x36, 0x18, 0xdf, 0x1c, 0x85, 0xb4, 0xe7, 0xb9, 0x7f, + 0x07, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xf5, 0xed, 0x4b, 0x5d, 0x32, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3215,6 +3309,7 @@ type QueryClient interface { // Queries a list of chainNonces items. ChainNoncesAll(ctx context.Context, in *QueryAllChainNoncesRequest, opts ...grpc.CallOption) (*QueryAllChainNoncesResponse, error) PendingNoncesAll(ctx context.Context, in *QueryAllPendingNoncesRequest, opts ...grpc.CallOption) (*QueryAllPendingNoncesResponse, error) + PendingNoncesByChain(ctx context.Context, in *QueryPendingNoncesByChainRequest, opts ...grpc.CallOption) (*QueryPendingNoncesByChainResponse, error) // Queries a lastBlockHeight by index. LastBlockHeight(ctx context.Context, in *QueryGetLastBlockHeightRequest, opts ...grpc.CallOption) (*QueryGetLastBlockHeightResponse, error) // Queries a list of lastBlockHeight items. @@ -3384,6 +3479,15 @@ func (c *queryClient) PendingNoncesAll(ctx context.Context, in *QueryAllPendingN return out, nil } +func (c *queryClient) PendingNoncesByChain(ctx context.Context, in *QueryPendingNoncesByChainRequest, opts ...grpc.CallOption) (*QueryPendingNoncesByChainResponse, error) { + out := new(QueryPendingNoncesByChainResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Query/PendingNoncesByChain", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) LastBlockHeight(ctx context.Context, in *QueryGetLastBlockHeightRequest, opts ...grpc.CallOption) (*QueryGetLastBlockHeightResponse, error) { out := new(QueryGetLastBlockHeightResponse) err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Query/LastBlockHeight", in, out, opts...) @@ -3486,6 +3590,7 @@ type QueryServer interface { // Queries a list of chainNonces items. ChainNoncesAll(context.Context, *QueryAllChainNoncesRequest) (*QueryAllChainNoncesResponse, error) PendingNoncesAll(context.Context, *QueryAllPendingNoncesRequest) (*QueryAllPendingNoncesResponse, error) + PendingNoncesByChain(context.Context, *QueryPendingNoncesByChainRequest) (*QueryPendingNoncesByChainResponse, error) // Queries a lastBlockHeight by index. LastBlockHeight(context.Context, *QueryGetLastBlockHeightRequest) (*QueryGetLastBlockHeightResponse, error) // Queries a list of lastBlockHeight items. @@ -3555,6 +3660,9 @@ func (*UnimplementedQueryServer) ChainNoncesAll(ctx context.Context, req *QueryA func (*UnimplementedQueryServer) PendingNoncesAll(ctx context.Context, req *QueryAllPendingNoncesRequest) (*QueryAllPendingNoncesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method PendingNoncesAll not implemented") } +func (*UnimplementedQueryServer) PendingNoncesByChain(ctx context.Context, req *QueryPendingNoncesByChainRequest) (*QueryPendingNoncesByChainResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PendingNoncesByChain not implemented") +} func (*UnimplementedQueryServer) LastBlockHeight(ctx context.Context, req *QueryGetLastBlockHeightRequest) (*QueryGetLastBlockHeightResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method LastBlockHeight not implemented") } @@ -3872,6 +3980,24 @@ func _Query_PendingNoncesAll_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _Query_PendingNoncesByChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPendingNoncesByChainRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).PendingNoncesByChain(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.crosschain.Query/PendingNoncesByChain", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).PendingNoncesByChain(ctx, req.(*QueryPendingNoncesByChainRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_LastBlockHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryGetLastBlockHeightRequest) if err := dec(in); err != nil { @@ -4084,6 +4210,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "PendingNoncesAll", Handler: _Query_PendingNoncesAll_Handler, }, + { + MethodName: "PendingNoncesByChain", + Handler: _Query_PendingNoncesByChain_Handler, + }, { MethodName: "LastBlockHeight", Handler: _Query_LastBlockHeight_Handler, @@ -5166,6 +5296,67 @@ func (m *QueryAllPendingNoncesResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } +func (m *QueryPendingNoncesByChainRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryPendingNoncesByChainRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPendingNoncesByChainRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ChainId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryPendingNoncesByChainResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryPendingNoncesByChainResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPendingNoncesByChainResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.PendingNonces.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *QueryGetLastBlockHeightRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6808,6 +6999,29 @@ func (m *QueryAllPendingNoncesResponse) Size() (n int) { return n } +func (m *QueryPendingNoncesByChainRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChainId != 0 { + n += 1 + sovQuery(uint64(m.ChainId)) + } + return n +} + +func (m *QueryPendingNoncesByChainResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.PendingNonces.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func (m *QueryGetLastBlockHeightRequest) Size() (n int) { if m == nil { return 0 @@ -9963,6 +10177,158 @@ func (m *QueryAllPendingNoncesResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryPendingNoncesByChainRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryPendingNoncesByChainRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPendingNoncesByChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + m.ChainId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryPendingNoncesByChainResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryPendingNoncesByChainResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPendingNoncesByChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PendingNonces", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PendingNonces.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryGetLastBlockHeightRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/crosschain/types/query.pb.gw.go b/x/crosschain/types/query.pb.gw.go index 2b64d0ef9a..f8ea4ecbae 100644 --- a/x/crosschain/types/query.pb.gw.go +++ b/x/crosschain/types/query.pb.gw.go @@ -667,6 +667,60 @@ func local_request_Query_PendingNoncesAll_0(ctx context.Context, marshaler runti } +func request_Query_PendingNoncesByChain_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPendingNoncesByChainRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := client.PendingNoncesByChain(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_PendingNoncesByChain_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPendingNoncesByChainRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := server.PendingNoncesByChain(ctx, &protoReq) + return msg, metadata, err + +} + func request_Query_LastBlockHeight_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryGetLastBlockHeightRequest var metadata runtime.ServerMetadata @@ -1369,6 +1423,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_PendingNoncesByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_PendingNoncesByChain_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_PendingNoncesByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_LastBlockHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1914,6 +1991,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_PendingNoncesByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_PendingNoncesByChain_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_PendingNoncesByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_LastBlockHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -2110,6 +2207,8 @@ var ( pattern_Query_PendingNoncesAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "crosschain", "pendingNonces"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_PendingNoncesByChain_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "crosschain", "pendingNonces", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_LastBlockHeight_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "crosschain", "lastBlockHeight", "index"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_LastBlockHeightAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "crosschain", "lastBlockHeight"}, "", runtime.AssumeColonVerbOpt(false))) @@ -2160,6 +2259,8 @@ var ( forward_Query_PendingNoncesAll_0 = runtime.ForwardResponseMessage + forward_Query_PendingNoncesByChain_0 = runtime.ForwardResponseMessage + forward_Query_LastBlockHeight_0 = runtime.ForwardResponseMessage forward_Query_LastBlockHeightAll_0 = runtime.ForwardResponseMessage From 8e9c6724228e2c9d5f9f468eb4bfbe9261d053e1 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Thu, 21 Sep 2023 02:20:28 -0500 Subject: [PATCH 6/8] feat(`fungible`): add message to update contract bytecode (#995) * test zrc20 contract bytecode update * WIP * use existing contract bytecode * test change bytecode * imports * fix build * improve test * some cleanup * message type test * add authorization check * error test cases * add new bytecode hash in response * add testzrc20 * restrict to zrc20 and connector contract * update comment * make generate * fix test * initialize the smoketest * remove unnecessary lines * change address method * add upgrade bytecode smoke test * fix test --------- Co-authored-by: brewmaster012 <> Co-authored-by: lumtis --- .../contracts/testzrc20/TestZRC20.abi | 670 ++++++ .../contracts/testzrc20/TestZRC20.bin | 1 + .../contracts/testzrc20/TestZRC20.go | 1925 +++++++++++++++++ .../contracts/testzrc20/TestZRC20.json | 673 ++++++ .../contracts/testzrc20/TestZRC20.sol | 363 ++++ .../smoketest/contracts/testzrc20/bindings.go | 6 + .../localnet/orchestrator/smoketest/main.go | 3 + .../smoketest/test_update_bytecode.go | 189 ++ docs/openapi/openapi.swagger.yaml | 6 + docs/spec/fungible/messages.md | 15 + proto/fungible/tx.proto | 11 + testutil/keeper/mocks/fungible/evm.go | 34 + ...blocker_deploy_system_contracts_privnet.go | 1 + x/fungible/keeper/evm.go | 55 +- .../msg_server_update_contract_bytecode.go | 83 + ...sg_server_update_contract_bytecode_test.go | 374 ++++ ..._server_update_zrc20_paused_status_test.go | 13 - x/fungible/types/errors.go | 6 +- x/fungible/types/expected_keepers.go | 4 + .../types/message_update_contract_bytecode.go | 62 + .../message_update_contract_bytecode_test.go | 65 + x/fungible/types/tx.pb.go | 585 ++++- 22 files changed, 5078 insertions(+), 66 deletions(-) create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.abi create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.bin create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.go create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.json create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.sol create mode 100644 contrib/localnet/orchestrator/smoketest/contracts/testzrc20/bindings.go create mode 100644 contrib/localnet/orchestrator/smoketest/test_update_bytecode.go create mode 100644 x/fungible/keeper/msg_server_update_contract_bytecode.go create mode 100644 x/fungible/keeper/msg_server_update_contract_bytecode_test.go create mode 100644 x/fungible/types/message_update_contract_bytecode.go create mode 100644 x/fungible/types/message_update_contract_bytecode_test.go diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.abi b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.abi new file mode 100644 index 0000000000..ec8cc79f66 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.abi @@ -0,0 +1,670 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainid_", + "type": "uint256" + }, + { + "internalType": "enum CoinType", + "name": "coinType_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerIsNotFungibleModule", + "type": "error" + }, + { + "inputs": [], + "name": "GasFeeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSender", + "type": "error" + }, + { + "inputs": [], + "name": "LowAllowance", + "type": "error" + }, + { + "inputs": [], + "name": "LowBalance", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroGasCoin", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroGasPrice", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "from", + "type": "bytes" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "UpdatedGasLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "UpdatedProtocolFlatFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "systemContract", + "type": "address" + } + ], + "name": "UpdatedSystemContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gasfee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "CHAIN_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "COIN_TYPE", + "outputs": [ + { + "internalType": "enum CoinType", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FUNGIBLE_MODULE_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GAS_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROTOCOL_FLAT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SYSTEM_CONTRACT_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newField", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newPublicField", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "updateGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newField_", + "type": "uint256" + } + ], + "name": "updateNewField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "updateProtocolFlatFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "updateSystemContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawGasFee", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.bin b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.bin new file mode 100644 index 0000000000..9e74c2aaa3 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.bin @@ -0,0 +1 @@ +60c06040523480156200001157600080fd5b5060405162002566380380620025668339818101604052810190620000379190620000e1565b816080818152505080600281111562000055576200005462000128565b5b60a08160028111156200006d576200006c62000128565b5b81525050505062000157565b600080fd5b6000819050919050565b62000093816200007e565b81146200009f57600080fd5b50565b600081519050620000b38162000088565b92915050565b60038110620000c757600080fd5b50565b600081519050620000db81620000b9565b92915050565b60008060408385031215620000fb57620000fa62000079565b5b60006200010b85828601620000a2565b92505060206200011e85828601620000ca565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60805160a0516123db6200018b6000396000610aa40152600081816109ee01528181610f59015261107e01526123db6000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806385e1f4d0116100f9578063c701262611610097578063dd62ed3e11610071578063dd62ed3e146104ff578063eddeb1231461052f578063f2441b321461054b578063f687d12a14610569576101a9565b8063c701262614610494578063c835d7cc146104c4578063d9eeebed146104e0576101a9565b8063a457c2d7116100d3578063a457c2d7146103f8578063a7605f4514610428578063a9059cbb14610446578063b92894ba14610476576101a9565b806385e1f4d01461039e57806395d89b41146103bc578063a3413d03146103da576101a9565b8063395093511161016657806347e7ef241161014057806347e7ef24146103045780634d8943bb1461033457806370a0823114610352578063732bb0e414610382576101a9565b806339509351146102865780633ce4a5bc146102b657806342966c68146102d4576101a9565b806306fdde03146101ae578063091d2788146101cc578063095ea7b3146101ea57806318160ddd1461021a57806323b872dd14610238578063313ce56714610268575b600080fd5b6101b6610585565b6040516101c39190611b20565b60405180910390f35b6101d4610617565b6040516101e19190611b5b565b60405180910390f35b61020460048036038101906101ff9190611c14565b61061d565b6040516102119190611c6f565b60405180910390f35b61022261063b565b60405161022f9190611b5b565b60405180910390f35b610252600480360381019061024d9190611c8a565b610645565b60405161025f9190611c6f565b60405180910390f35b61027061073d565b60405161027d9190611cf9565b60405180910390f35b6102a0600480360381019061029b9190611c14565b610754565b6040516102ad9190611c6f565b60405180910390f35b6102be6107fa565b6040516102cb9190611d23565b60405180910390f35b6102ee60048036038101906102e99190611d3e565b610812565b6040516102fb9190611c6f565b60405180910390f35b61031e60048036038101906103199190611c14565b610827565b60405161032b9190611c6f565b60405180910390f35b61033c610993565b6040516103499190611b5b565b60405180910390f35b61036c60048036038101906103679190611d6b565b610999565b6040516103799190611b5b565b60405180910390f35b61039c60048036038101906103979190611d3e565b6109e2565b005b6103a66109ec565b6040516103b39190611b5b565b60405180910390f35b6103c4610a10565b6040516103d19190611b20565b60405180910390f35b6103e2610aa2565b6040516103ef9190611e0f565b60405180910390f35b610412600480360381019061040d9190611c14565b610ac6565b60405161041f9190611c6f565b60405180910390f35b610430610c29565b60405161043d9190611b5b565b60405180910390f35b610460600480360381019061045b9190611c14565b610c2f565b60405161046d9190611c6f565b60405180910390f35b61047e610c4d565b60405161048b9190611b20565b60405180910390f35b6104ae60048036038101906104a99190611f5f565b610cdb565b6040516104bb9190611c6f565b60405180910390f35b6104de60048036038101906104d99190611d6b565b610e22565b005b6104e8610f15565b6040516104f6929190611fbb565b60405180910390f35b61051960048036038101906105149190611fe4565b611162565b6040516105269190611b5b565b60405180910390f35b61054960048036038101906105449190611d3e565b6111e9565b005b6105536112a3565b6040516105609190611d23565b60405180910390f35b610583600480360381019061057e9190611d3e565b6112c7565b005b60606006805461059490612053565b80601f01602080910402602001604051908101604052809291908181526020018280546105c090612053565b801561060d5780601f106105e25761010080835404028352916020019161060d565b820191906000526020600020905b8154815290600101906020018083116105f057829003601f168201915b5050505050905090565b60015481565b600061063161062a611381565b8484611389565b6001905092915050565b6000600554905090565b6000610652848484611540565b6000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061069d611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610714576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073185610720611381565b858461072c91906120b3565b611389565b60019150509392505050565b6000600860009054906101000a900460ff16905090565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006107a0611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107e991906120e7565b925050819055506001905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab81565b600061081e338361179a565b60019050919050565b600073735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156108c5575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b156108fc576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109068383611951565b8273ffffffffffffffffffffffffffffffffffffffff167f67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab373735b14bb79463307aacbed86daf3322b1e6226ab6040516020016109639190612163565b604051602081830303815290604052846040516109819291906121d3565b60405180910390a26001905092915050565b60025481565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b8060098190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606060078054610a1f90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4b90612053565b8015610a985780601f10610a6d57610100808354040283529160200191610a98565b820191906000526020600020905b815481529060010190602001808311610a7b57829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610b12611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b85576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610bcf611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c1891906120b3565b925050819055506001905092915050565b60095481565b6000610c43610c3c611381565b8484611540565b6001905092915050565b600a8054610c5a90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8690612053565b8015610cd35780601f10610ca857610100808354040283529160200191610cd3565b820191906000526020600020905b815481529060010190602001808311610cb657829003601f168201915b505050505081565b6000806000610ce8610f15565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3373735b14bb79463307aacbed86daf3322b1e6226ab846040518463ffffffff1660e01b8152600401610d3d93929190612203565b6020604051808303816000875af1158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190612266565b610db6576040517f0a7cd6d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dc0338561179a565b3373ffffffffffffffffffffffffffffffffffffffff167f9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955868684600254604051610e0e9493929190612293565b60405180910390a260019250505092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9b576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae81604051610f0a9190611d23565b60405180910390a150565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630be155477f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610f949190611b5b565b602060405180830381865afa158015610fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd591906122f4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361103d576040517f78fff39600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d7fd7afb7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004016110b99190611b5b565b602060405180830381865afa1580156110d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fa9190612336565b905060008103611136576040517fe661aed000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600254600154836111499190612363565b61115391906120e7565b90508281945094505050509091565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611262576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806002819055507fef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f816040516112989190611b5b565b60405180910390a150565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611340576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001819055507fff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a816040516113769190611b5b565b60405180910390a150565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113ef576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611455576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516115339190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036115a6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361160c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561168a576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161169691906120b3565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172891906120e7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161178c9190611b5b565b60405180910390a350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611800576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561187e576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161188a91906120b3565b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008282546118df91906120b3565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119449190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119b7576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008282546119c991906120e7565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a1f91906120e7565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611a849190611b5b565b60405180910390a35050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611aca578082015181840152602081019050611aaf565b60008484015250505050565b6000601f19601f8301169050919050565b6000611af282611a90565b611afc8185611a9b565b9350611b0c818560208601611aac565b611b1581611ad6565b840191505092915050565b60006020820190508181036000830152611b3a8184611ae7565b905092915050565b6000819050919050565b611b5581611b42565b82525050565b6000602082019050611b706000830184611b4c565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611bb582611b8a565b9050919050565b611bc581611baa565b8114611bd057600080fd5b50565b600081359050611be281611bbc565b92915050565b611bf181611b42565b8114611bfc57600080fd5b50565b600081359050611c0e81611be8565b92915050565b60008060408385031215611c2b57611c2a611b80565b5b6000611c3985828601611bd3565b9250506020611c4a85828601611bff565b9150509250929050565b60008115159050919050565b611c6981611c54565b82525050565b6000602082019050611c846000830184611c60565b92915050565b600080600060608486031215611ca357611ca2611b80565b5b6000611cb186828701611bd3565b9350506020611cc286828701611bd3565b9250506040611cd386828701611bff565b9150509250925092565b600060ff82169050919050565b611cf381611cdd565b82525050565b6000602082019050611d0e6000830184611cea565b92915050565b611d1d81611baa565b82525050565b6000602082019050611d386000830184611d14565b92915050565b600060208284031215611d5457611d53611b80565b5b6000611d6284828501611bff565b91505092915050565b600060208284031215611d8157611d80611b80565b5b6000611d8f84828501611bd3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611dd857611dd7611d98565b5b50565b6000819050611de982611dc7565b919050565b6000611df982611ddb565b9050919050565b611e0981611dee565b82525050565b6000602082019050611e246000830184611e00565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611e6c82611ad6565b810181811067ffffffffffffffff82111715611e8b57611e8a611e34565b5b80604052505050565b6000611e9e611b76565b9050611eaa8282611e63565b919050565b600067ffffffffffffffff821115611eca57611ec9611e34565b5b611ed382611ad6565b9050602081019050919050565b82818337600083830152505050565b6000611f02611efd84611eaf565b611e94565b905082815260208101848484011115611f1e57611f1d611e2f565b5b611f29848285611ee0565b509392505050565b600082601f830112611f4657611f45611e2a565b5b8135611f56848260208601611eef565b91505092915050565b60008060408385031215611f7657611f75611b80565b5b600083013567ffffffffffffffff811115611f9457611f93611b85565b5b611fa085828601611f31565b9250506020611fb185828601611bff565b9150509250929050565b6000604082019050611fd06000830185611d14565b611fdd6020830184611b4c565b9392505050565b60008060408385031215611ffb57611ffa611b80565b5b600061200985828601611bd3565b925050602061201a85828601611bd3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061206b57607f821691505b60208210810361207e5761207d612024565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006120be82611b42565b91506120c983611b42565b92508282039050818111156120e1576120e0612084565b5b92915050565b60006120f282611b42565b91506120fd83611b42565b925082820190508082111561211557612114612084565b5b92915050565b60008160601b9050919050565b60006121338261211b565b9050919050565b600061214582612128565b9050919050565b61215d61215882611baa565b61213a565b82525050565b600061216f828461214c565b60148201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006121a58261217e565b6121af8185612189565b93506121bf818560208601611aac565b6121c881611ad6565b840191505092915050565b600060408201905081810360008301526121ed818561219a565b90506121fc6020830184611b4c565b9392505050565b60006060820190506122186000830186611d14565b6122256020830185611d14565b6122326040830184611b4c565b949350505050565b61224381611c54565b811461224e57600080fd5b50565b6000815190506122608161223a565b92915050565b60006020828403121561227c5761227b611b80565b5b600061228a84828501612251565b91505092915050565b600060808201905081810360008301526122ad818761219a565b90506122bc6020830186611b4c565b6122c96040830185611b4c565b6122d66060830184611b4c565b95945050505050565b6000815190506122ee81611bbc565b92915050565b60006020828403121561230a57612309611b80565b5b6000612318848285016122df565b91505092915050565b60008151905061233081611be8565b92915050565b60006020828403121561234c5761234b611b80565b5b600061235a84828501612321565b91505092915050565b600061236e82611b42565b915061237983611b42565b925082820261238781611b42565b9150828204841483151761239e5761239d612084565b5b509291505056fea264697066735822122011fda4fba218fc7f911b68b0418884c426f5ddb324eb1572e2e793fcb60edf6c64736f6c63430008150033 diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.go b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.go new file mode 100644 index 0000000000..aef95ec0d1 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.go @@ -0,0 +1,1925 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package testzrc20 + +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 +) + +// TestZRC20MetaData contains all meta data concerning the TestZRC20 contract. +var TestZRC20MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid_\",\"type\":\"uint256\"},{\"internalType\":\"enumCoinType\",\"name\":\"coinType_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerIsNotFungibleModule\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasFeeTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LowAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LowBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroGasCoin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroGasPrice\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"UpdatedGasLimit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedProtocolFlatFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"systemContract\",\"type\":\"address\"}],\"name\":\"UpdatedSystemContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasfee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CHAIN_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COIN_TYPE\",\"outputs\":[{\"internalType\":\"enumCoinType\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FUNGIBLE_MODULE_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GAS_LIMIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROTOCOL_FLAT_FEE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SYSTEM_CONTRACT_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"newField\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"newPublicField\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"updateGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newField_\",\"type\":\"uint256\"}],\"name\":\"updateNewField\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"updateProtocolFlatFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"updateSystemContractAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawGasFee\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162002566380380620025668339818101604052810190620000379190620000e1565b816080818152505080600281111562000055576200005462000128565b5b60a08160028111156200006d576200006c62000128565b5b81525050505062000157565b600080fd5b6000819050919050565b62000093816200007e565b81146200009f57600080fd5b50565b600081519050620000b38162000088565b92915050565b60038110620000c757600080fd5b50565b600081519050620000db81620000b9565b92915050565b60008060408385031215620000fb57620000fa62000079565b5b60006200010b85828601620000a2565b92505060206200011e85828601620000ca565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60805160a0516123db6200018b6000396000610aa40152600081816109ee01528181610f59015261107e01526123db6000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806385e1f4d0116100f9578063c701262611610097578063dd62ed3e11610071578063dd62ed3e146104ff578063eddeb1231461052f578063f2441b321461054b578063f687d12a14610569576101a9565b8063c701262614610494578063c835d7cc146104c4578063d9eeebed146104e0576101a9565b8063a457c2d7116100d3578063a457c2d7146103f8578063a7605f4514610428578063a9059cbb14610446578063b92894ba14610476576101a9565b806385e1f4d01461039e57806395d89b41146103bc578063a3413d03146103da576101a9565b8063395093511161016657806347e7ef241161014057806347e7ef24146103045780634d8943bb1461033457806370a0823114610352578063732bb0e414610382576101a9565b806339509351146102865780633ce4a5bc146102b657806342966c68146102d4576101a9565b806306fdde03146101ae578063091d2788146101cc578063095ea7b3146101ea57806318160ddd1461021a57806323b872dd14610238578063313ce56714610268575b600080fd5b6101b6610585565b6040516101c39190611b20565b60405180910390f35b6101d4610617565b6040516101e19190611b5b565b60405180910390f35b61020460048036038101906101ff9190611c14565b61061d565b6040516102119190611c6f565b60405180910390f35b61022261063b565b60405161022f9190611b5b565b60405180910390f35b610252600480360381019061024d9190611c8a565b610645565b60405161025f9190611c6f565b60405180910390f35b61027061073d565b60405161027d9190611cf9565b60405180910390f35b6102a0600480360381019061029b9190611c14565b610754565b6040516102ad9190611c6f565b60405180910390f35b6102be6107fa565b6040516102cb9190611d23565b60405180910390f35b6102ee60048036038101906102e99190611d3e565b610812565b6040516102fb9190611c6f565b60405180910390f35b61031e60048036038101906103199190611c14565b610827565b60405161032b9190611c6f565b60405180910390f35b61033c610993565b6040516103499190611b5b565b60405180910390f35b61036c60048036038101906103679190611d6b565b610999565b6040516103799190611b5b565b60405180910390f35b61039c60048036038101906103979190611d3e565b6109e2565b005b6103a66109ec565b6040516103b39190611b5b565b60405180910390f35b6103c4610a10565b6040516103d19190611b20565b60405180910390f35b6103e2610aa2565b6040516103ef9190611e0f565b60405180910390f35b610412600480360381019061040d9190611c14565b610ac6565b60405161041f9190611c6f565b60405180910390f35b610430610c29565b60405161043d9190611b5b565b60405180910390f35b610460600480360381019061045b9190611c14565b610c2f565b60405161046d9190611c6f565b60405180910390f35b61047e610c4d565b60405161048b9190611b20565b60405180910390f35b6104ae60048036038101906104a99190611f5f565b610cdb565b6040516104bb9190611c6f565b60405180910390f35b6104de60048036038101906104d99190611d6b565b610e22565b005b6104e8610f15565b6040516104f6929190611fbb565b60405180910390f35b61051960048036038101906105149190611fe4565b611162565b6040516105269190611b5b565b60405180910390f35b61054960048036038101906105449190611d3e565b6111e9565b005b6105536112a3565b6040516105609190611d23565b60405180910390f35b610583600480360381019061057e9190611d3e565b6112c7565b005b60606006805461059490612053565b80601f01602080910402602001604051908101604052809291908181526020018280546105c090612053565b801561060d5780601f106105e25761010080835404028352916020019161060d565b820191906000526020600020905b8154815290600101906020018083116105f057829003601f168201915b5050505050905090565b60015481565b600061063161062a611381565b8484611389565b6001905092915050565b6000600554905090565b6000610652848484611540565b6000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061069d611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610714576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073185610720611381565b858461072c91906120b3565b611389565b60019150509392505050565b6000600860009054906101000a900460ff16905090565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006107a0611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107e991906120e7565b925050819055506001905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab81565b600061081e338361179a565b60019050919050565b600073735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156108c5575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b156108fc576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109068383611951565b8273ffffffffffffffffffffffffffffffffffffffff167f67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab373735b14bb79463307aacbed86daf3322b1e6226ab6040516020016109639190612163565b604051602081830303815290604052846040516109819291906121d3565b60405180910390a26001905092915050565b60025481565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b8060098190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606060078054610a1f90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4b90612053565b8015610a985780601f10610a6d57610100808354040283529160200191610a98565b820191906000526020600020905b815481529060010190602001808311610a7b57829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610b12611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b85576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610bcf611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c1891906120b3565b925050819055506001905092915050565b60095481565b6000610c43610c3c611381565b8484611540565b6001905092915050565b600a8054610c5a90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8690612053565b8015610cd35780601f10610ca857610100808354040283529160200191610cd3565b820191906000526020600020905b815481529060010190602001808311610cb657829003601f168201915b505050505081565b6000806000610ce8610f15565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3373735b14bb79463307aacbed86daf3322b1e6226ab846040518463ffffffff1660e01b8152600401610d3d93929190612203565b6020604051808303816000875af1158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190612266565b610db6576040517f0a7cd6d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dc0338561179a565b3373ffffffffffffffffffffffffffffffffffffffff167f9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955868684600254604051610e0e9493929190612293565b60405180910390a260019250505092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9b576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae81604051610f0a9190611d23565b60405180910390a150565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630be155477f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610f949190611b5b565b602060405180830381865afa158015610fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd591906122f4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361103d576040517f78fff39600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d7fd7afb7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004016110b99190611b5b565b602060405180830381865afa1580156110d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fa9190612336565b905060008103611136576040517fe661aed000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600254600154836111499190612363565b61115391906120e7565b90508281945094505050509091565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611262576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806002819055507fef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f816040516112989190611b5b565b60405180910390a150565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611340576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001819055507fff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a816040516113769190611b5b565b60405180910390a150565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113ef576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611455576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516115339190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036115a6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361160c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561168a576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161169691906120b3565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172891906120e7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161178c9190611b5b565b60405180910390a350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611800576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561187e576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161188a91906120b3565b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008282546118df91906120b3565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119449190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119b7576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008282546119c991906120e7565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a1f91906120e7565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611a849190611b5b565b60405180910390a35050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611aca578082015181840152602081019050611aaf565b60008484015250505050565b6000601f19601f8301169050919050565b6000611af282611a90565b611afc8185611a9b565b9350611b0c818560208601611aac565b611b1581611ad6565b840191505092915050565b60006020820190508181036000830152611b3a8184611ae7565b905092915050565b6000819050919050565b611b5581611b42565b82525050565b6000602082019050611b706000830184611b4c565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611bb582611b8a565b9050919050565b611bc581611baa565b8114611bd057600080fd5b50565b600081359050611be281611bbc565b92915050565b611bf181611b42565b8114611bfc57600080fd5b50565b600081359050611c0e81611be8565b92915050565b60008060408385031215611c2b57611c2a611b80565b5b6000611c3985828601611bd3565b9250506020611c4a85828601611bff565b9150509250929050565b60008115159050919050565b611c6981611c54565b82525050565b6000602082019050611c846000830184611c60565b92915050565b600080600060608486031215611ca357611ca2611b80565b5b6000611cb186828701611bd3565b9350506020611cc286828701611bd3565b9250506040611cd386828701611bff565b9150509250925092565b600060ff82169050919050565b611cf381611cdd565b82525050565b6000602082019050611d0e6000830184611cea565b92915050565b611d1d81611baa565b82525050565b6000602082019050611d386000830184611d14565b92915050565b600060208284031215611d5457611d53611b80565b5b6000611d6284828501611bff565b91505092915050565b600060208284031215611d8157611d80611b80565b5b6000611d8f84828501611bd3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611dd857611dd7611d98565b5b50565b6000819050611de982611dc7565b919050565b6000611df982611ddb565b9050919050565b611e0981611dee565b82525050565b6000602082019050611e246000830184611e00565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611e6c82611ad6565b810181811067ffffffffffffffff82111715611e8b57611e8a611e34565b5b80604052505050565b6000611e9e611b76565b9050611eaa8282611e63565b919050565b600067ffffffffffffffff821115611eca57611ec9611e34565b5b611ed382611ad6565b9050602081019050919050565b82818337600083830152505050565b6000611f02611efd84611eaf565b611e94565b905082815260208101848484011115611f1e57611f1d611e2f565b5b611f29848285611ee0565b509392505050565b600082601f830112611f4657611f45611e2a565b5b8135611f56848260208601611eef565b91505092915050565b60008060408385031215611f7657611f75611b80565b5b600083013567ffffffffffffffff811115611f9457611f93611b85565b5b611fa085828601611f31565b9250506020611fb185828601611bff565b9150509250929050565b6000604082019050611fd06000830185611d14565b611fdd6020830184611b4c565b9392505050565b60008060408385031215611ffb57611ffa611b80565b5b600061200985828601611bd3565b925050602061201a85828601611bd3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061206b57607f821691505b60208210810361207e5761207d612024565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006120be82611b42565b91506120c983611b42565b92508282039050818111156120e1576120e0612084565b5b92915050565b60006120f282611b42565b91506120fd83611b42565b925082820190508082111561211557612114612084565b5b92915050565b60008160601b9050919050565b60006121338261211b565b9050919050565b600061214582612128565b9050919050565b61215d61215882611baa565b61213a565b82525050565b600061216f828461214c565b60148201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006121a58261217e565b6121af8185612189565b93506121bf818560208601611aac565b6121c881611ad6565b840191505092915050565b600060408201905081810360008301526121ed818561219a565b90506121fc6020830184611b4c565b9392505050565b60006060820190506122186000830186611d14565b6122256020830185611d14565b6122326040830184611b4c565b949350505050565b61224381611c54565b811461224e57600080fd5b50565b6000815190506122608161223a565b92915050565b60006020828403121561227c5761227b611b80565b5b600061228a84828501612251565b91505092915050565b600060808201905081810360008301526122ad818761219a565b90506122bc6020830186611b4c565b6122c96040830185611b4c565b6122d66060830184611b4c565b95945050505050565b6000815190506122ee81611bbc565b92915050565b60006020828403121561230a57612309611b80565b5b6000612318848285016122df565b91505092915050565b60008151905061233081611be8565b92915050565b60006020828403121561234c5761234b611b80565b5b600061235a84828501612321565b91505092915050565b600061236e82611b42565b915061237983611b42565b925082820261238781611b42565b9150828204841483151761239e5761239d612084565b5b509291505056fea264697066735822122011fda4fba218fc7f911b68b0418884c426f5ddb324eb1572e2e793fcb60edf6c64736f6c63430008150033", +} + +// TestZRC20ABI is the input ABI used to generate the binding from. +// Deprecated: Use TestZRC20MetaData.ABI instead. +var TestZRC20ABI = TestZRC20MetaData.ABI + +// TestZRC20Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TestZRC20MetaData.Bin instead. +var TestZRC20Bin = TestZRC20MetaData.Bin + +// DeployTestZRC20 deploys a new Ethereum contract, binding an instance of TestZRC20 to it. +func DeployTestZRC20(auth *bind.TransactOpts, backend bind.ContractBackend, chainid_ *big.Int, coinType_ uint8) (common.Address, *types.Transaction, *TestZRC20, error) { + parsed, err := TestZRC20MetaData.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(TestZRC20Bin), backend, chainid_, coinType_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TestZRC20{TestZRC20Caller: TestZRC20Caller{contract: contract}, TestZRC20Transactor: TestZRC20Transactor{contract: contract}, TestZRC20Filterer: TestZRC20Filterer{contract: contract}}, nil +} + +// TestZRC20 is an auto generated Go binding around an Ethereum contract. +type TestZRC20 struct { + TestZRC20Caller // Read-only binding to the contract + TestZRC20Transactor // Write-only binding to the contract + TestZRC20Filterer // Log filterer for contract events +} + +// TestZRC20Caller is an auto generated read-only Go binding around an Ethereum contract. +type TestZRC20Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestZRC20Transactor is an auto generated write-only Go binding around an Ethereum contract. +type TestZRC20Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestZRC20Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TestZRC20Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestZRC20Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TestZRC20Session struct { + Contract *TestZRC20 // 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 +} + +// TestZRC20CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TestZRC20CallerSession struct { + Contract *TestZRC20Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TestZRC20TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TestZRC20TransactorSession struct { + Contract *TestZRC20Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TestZRC20Raw is an auto generated low-level Go binding around an Ethereum contract. +type TestZRC20Raw struct { + Contract *TestZRC20 // Generic contract binding to access the raw methods on +} + +// TestZRC20CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TestZRC20CallerRaw struct { + Contract *TestZRC20Caller // Generic read-only contract binding to access the raw methods on +} + +// TestZRC20TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TestZRC20TransactorRaw struct { + Contract *TestZRC20Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewTestZRC20 creates a new instance of TestZRC20, bound to a specific deployed contract. +func NewTestZRC20(address common.Address, backend bind.ContractBackend) (*TestZRC20, error) { + contract, err := bindTestZRC20(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TestZRC20{TestZRC20Caller: TestZRC20Caller{contract: contract}, TestZRC20Transactor: TestZRC20Transactor{contract: contract}, TestZRC20Filterer: TestZRC20Filterer{contract: contract}}, nil +} + +// NewTestZRC20Caller creates a new read-only instance of TestZRC20, bound to a specific deployed contract. +func NewTestZRC20Caller(address common.Address, caller bind.ContractCaller) (*TestZRC20Caller, error) { + contract, err := bindTestZRC20(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TestZRC20Caller{contract: contract}, nil +} + +// NewTestZRC20Transactor creates a new write-only instance of TestZRC20, bound to a specific deployed contract. +func NewTestZRC20Transactor(address common.Address, transactor bind.ContractTransactor) (*TestZRC20Transactor, error) { + contract, err := bindTestZRC20(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TestZRC20Transactor{contract: contract}, nil +} + +// NewTestZRC20Filterer creates a new log filterer instance of TestZRC20, bound to a specific deployed contract. +func NewTestZRC20Filterer(address common.Address, filterer bind.ContractFilterer) (*TestZRC20Filterer, error) { + contract, err := bindTestZRC20(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TestZRC20Filterer{contract: contract}, nil +} + +// bindTestZRC20 binds a generic wrapper to an already deployed contract. +func bindTestZRC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TestZRC20MetaData.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 (_TestZRC20 *TestZRC20Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestZRC20.Contract.TestZRC20Caller.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 (_TestZRC20 *TestZRC20Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestZRC20.Contract.TestZRC20Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestZRC20 *TestZRC20Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestZRC20.Contract.TestZRC20Transactor.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 (_TestZRC20 *TestZRC20CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestZRC20.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 (_TestZRC20 *TestZRC20TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestZRC20.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestZRC20 *TestZRC20TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestZRC20.Contract.contract.Transact(opts, method, params...) +} + +// CHAINID is a free data retrieval call binding the contract method 0x85e1f4d0. +// +// Solidity: function CHAIN_ID() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) CHAINID(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "CHAIN_ID") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CHAINID is a free data retrieval call binding the contract method 0x85e1f4d0. +// +// Solidity: function CHAIN_ID() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) CHAINID() (*big.Int, error) { + return _TestZRC20.Contract.CHAINID(&_TestZRC20.CallOpts) +} + +// CHAINID is a free data retrieval call binding the contract method 0x85e1f4d0. +// +// Solidity: function CHAIN_ID() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) CHAINID() (*big.Int, error) { + return _TestZRC20.Contract.CHAINID(&_TestZRC20.CallOpts) +} + +// COINTYPE is a free data retrieval call binding the contract method 0xa3413d03. +// +// Solidity: function COIN_TYPE() view returns(uint8) +func (_TestZRC20 *TestZRC20Caller) COINTYPE(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "COIN_TYPE") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// COINTYPE is a free data retrieval call binding the contract method 0xa3413d03. +// +// Solidity: function COIN_TYPE() view returns(uint8) +func (_TestZRC20 *TestZRC20Session) COINTYPE() (uint8, error) { + return _TestZRC20.Contract.COINTYPE(&_TestZRC20.CallOpts) +} + +// COINTYPE is a free data retrieval call binding the contract method 0xa3413d03. +// +// Solidity: function COIN_TYPE() view returns(uint8) +func (_TestZRC20 *TestZRC20CallerSession) COINTYPE() (uint8, error) { + return _TestZRC20.Contract.COINTYPE(&_TestZRC20.CallOpts) +} + +// FUNGIBLEMODULEADDRESS is a free data retrieval call binding the contract method 0x3ce4a5bc. +// +// Solidity: function FUNGIBLE_MODULE_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20Caller) FUNGIBLEMODULEADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "FUNGIBLE_MODULE_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// FUNGIBLEMODULEADDRESS is a free data retrieval call binding the contract method 0x3ce4a5bc. +// +// Solidity: function FUNGIBLE_MODULE_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20Session) FUNGIBLEMODULEADDRESS() (common.Address, error) { + return _TestZRC20.Contract.FUNGIBLEMODULEADDRESS(&_TestZRC20.CallOpts) +} + +// FUNGIBLEMODULEADDRESS is a free data retrieval call binding the contract method 0x3ce4a5bc. +// +// Solidity: function FUNGIBLE_MODULE_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20CallerSession) FUNGIBLEMODULEADDRESS() (common.Address, error) { + return _TestZRC20.Contract.FUNGIBLEMODULEADDRESS(&_TestZRC20.CallOpts) +} + +// GASLIMIT is a free data retrieval call binding the contract method 0x091d2788. +// +// Solidity: function GAS_LIMIT() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) GASLIMIT(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "GAS_LIMIT") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GASLIMIT is a free data retrieval call binding the contract method 0x091d2788. +// +// Solidity: function GAS_LIMIT() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) GASLIMIT() (*big.Int, error) { + return _TestZRC20.Contract.GASLIMIT(&_TestZRC20.CallOpts) +} + +// GASLIMIT is a free data retrieval call binding the contract method 0x091d2788. +// +// Solidity: function GAS_LIMIT() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) GASLIMIT() (*big.Int, error) { + return _TestZRC20.Contract.GASLIMIT(&_TestZRC20.CallOpts) +} + +// PROTOCOLFLATFEE is a free data retrieval call binding the contract method 0x4d8943bb. +// +// Solidity: function PROTOCOL_FLAT_FEE() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) PROTOCOLFLATFEE(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "PROTOCOL_FLAT_FEE") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// PROTOCOLFLATFEE is a free data retrieval call binding the contract method 0x4d8943bb. +// +// Solidity: function PROTOCOL_FLAT_FEE() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) PROTOCOLFLATFEE() (*big.Int, error) { + return _TestZRC20.Contract.PROTOCOLFLATFEE(&_TestZRC20.CallOpts) +} + +// PROTOCOLFLATFEE is a free data retrieval call binding the contract method 0x4d8943bb. +// +// Solidity: function PROTOCOL_FLAT_FEE() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) PROTOCOLFLATFEE() (*big.Int, error) { + return _TestZRC20.Contract.PROTOCOLFLATFEE(&_TestZRC20.CallOpts) +} + +// SYSTEMCONTRACTADDRESS is a free data retrieval call binding the contract method 0xf2441b32. +// +// Solidity: function SYSTEM_CONTRACT_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20Caller) SYSTEMCONTRACTADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "SYSTEM_CONTRACT_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SYSTEMCONTRACTADDRESS is a free data retrieval call binding the contract method 0xf2441b32. +// +// Solidity: function SYSTEM_CONTRACT_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20Session) SYSTEMCONTRACTADDRESS() (common.Address, error) { + return _TestZRC20.Contract.SYSTEMCONTRACTADDRESS(&_TestZRC20.CallOpts) +} + +// SYSTEMCONTRACTADDRESS is a free data retrieval call binding the contract method 0xf2441b32. +// +// Solidity: function SYSTEM_CONTRACT_ADDRESS() view returns(address) +func (_TestZRC20 *TestZRC20CallerSession) SYSTEMCONTRACTADDRESS() (common.Address, error) { + return _TestZRC20.Contract.SYSTEMCONTRACTADDRESS(&_TestZRC20.CallOpts) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_TestZRC20 *TestZRC20Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _TestZRC20.Contract.Allowance(&_TestZRC20.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _TestZRC20.Contract.Allowance(&_TestZRC20.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_TestZRC20 *TestZRC20Session) BalanceOf(account common.Address) (*big.Int, error) { + return _TestZRC20.Contract.BalanceOf(&_TestZRC20.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _TestZRC20.Contract.BalanceOf(&_TestZRC20.CallOpts, account) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_TestZRC20 *TestZRC20Caller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_TestZRC20 *TestZRC20Session) Decimals() (uint8, error) { + return _TestZRC20.Contract.Decimals(&_TestZRC20.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_TestZRC20 *TestZRC20CallerSession) Decimals() (uint8, error) { + return _TestZRC20.Contract.Decimals(&_TestZRC20.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_TestZRC20 *TestZRC20Caller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_TestZRC20 *TestZRC20Session) Name() (string, error) { + return _TestZRC20.Contract.Name(&_TestZRC20.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_TestZRC20 *TestZRC20CallerSession) Name() (string, error) { + return _TestZRC20.Contract.Name(&_TestZRC20.CallOpts) +} + +// NewField is a free data retrieval call binding the contract method 0xa7605f45. +// +// Solidity: function newField() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) NewField(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "newField") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NewField is a free data retrieval call binding the contract method 0xa7605f45. +// +// Solidity: function newField() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) NewField() (*big.Int, error) { + return _TestZRC20.Contract.NewField(&_TestZRC20.CallOpts) +} + +// NewField is a free data retrieval call binding the contract method 0xa7605f45. +// +// Solidity: function newField() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) NewField() (*big.Int, error) { + return _TestZRC20.Contract.NewField(&_TestZRC20.CallOpts) +} + +// NewPublicField is a free data retrieval call binding the contract method 0xb92894ba. +// +// Solidity: function newPublicField() view returns(string) +func (_TestZRC20 *TestZRC20Caller) NewPublicField(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "newPublicField") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// NewPublicField is a free data retrieval call binding the contract method 0xb92894ba. +// +// Solidity: function newPublicField() view returns(string) +func (_TestZRC20 *TestZRC20Session) NewPublicField() (string, error) { + return _TestZRC20.Contract.NewPublicField(&_TestZRC20.CallOpts) +} + +// NewPublicField is a free data retrieval call binding the contract method 0xb92894ba. +// +// Solidity: function newPublicField() view returns(string) +func (_TestZRC20 *TestZRC20CallerSession) NewPublicField() (string, error) { + return _TestZRC20.Contract.NewPublicField(&_TestZRC20.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_TestZRC20 *TestZRC20Caller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_TestZRC20 *TestZRC20Session) Symbol() (string, error) { + return _TestZRC20.Contract.Symbol(&_TestZRC20.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_TestZRC20 *TestZRC20CallerSession) Symbol() (string, error) { + return _TestZRC20.Contract.Symbol(&_TestZRC20.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_TestZRC20 *TestZRC20Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_TestZRC20 *TestZRC20Session) TotalSupply() (*big.Int, error) { + return _TestZRC20.Contract.TotalSupply(&_TestZRC20.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_TestZRC20 *TestZRC20CallerSession) TotalSupply() (*big.Int, error) { + return _TestZRC20.Contract.TotalSupply(&_TestZRC20.CallOpts) +} + +// WithdrawGasFee is a free data retrieval call binding the contract method 0xd9eeebed. +// +// Solidity: function withdrawGasFee() view returns(address, uint256) +func (_TestZRC20 *TestZRC20Caller) WithdrawGasFee(opts *bind.CallOpts) (common.Address, *big.Int, error) { + var out []interface{} + err := _TestZRC20.contract.Call(opts, &out, "withdrawGasFee") + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +// WithdrawGasFee is a free data retrieval call binding the contract method 0xd9eeebed. +// +// Solidity: function withdrawGasFee() view returns(address, uint256) +func (_TestZRC20 *TestZRC20Session) WithdrawGasFee() (common.Address, *big.Int, error) { + return _TestZRC20.Contract.WithdrawGasFee(&_TestZRC20.CallOpts) +} + +// WithdrawGasFee is a free data retrieval call binding the contract method 0xd9eeebed. +// +// Solidity: function withdrawGasFee() view returns(address, uint256) +func (_TestZRC20 *TestZRC20CallerSession) WithdrawGasFee() (common.Address, *big.Int, error) { + return _TestZRC20.Contract.WithdrawGasFee(&_TestZRC20.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "approve", spender, amount) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Approve(&_TestZRC20.TransactOpts, spender, amount) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Approve(&_TestZRC20.TransactOpts, spender, amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Burn(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "burn", amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Burn(amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Burn(&_TestZRC20.TransactOpts, amount) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Burn(amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Burn(&_TestZRC20.TransactOpts, amount) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "decreaseAllowance", spender, amount) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) DecreaseAllowance(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.DecreaseAllowance(&_TestZRC20.TransactOpts, spender, amount) +} + +// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. +// +// Solidity: function decreaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) DecreaseAllowance(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.DecreaseAllowance(&_TestZRC20.TransactOpts, spender, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Deposit(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "deposit", to, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Deposit(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Deposit(&_TestZRC20.TransactOpts, to, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Deposit(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Deposit(&_TestZRC20.TransactOpts, to, amount) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "increaseAllowance", spender, amount) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) IncreaseAllowance(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.IncreaseAllowance(&_TestZRC20.TransactOpts, spender, amount) +} + +// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. +// +// Solidity: function increaseAllowance(address spender, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) IncreaseAllowance(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.IncreaseAllowance(&_TestZRC20.TransactOpts, spender, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Transfer(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "transfer", recipient, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Transfer(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Transfer(&_TestZRC20.TransactOpts, recipient, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Transfer(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Transfer(&_TestZRC20.TransactOpts, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) TransferFrom(opts *bind.TransactOpts, sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "transferFrom", sender, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) TransferFrom(sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.TransferFrom(&_TestZRC20.TransactOpts, sender, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) TransferFrom(sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.TransferFrom(&_TestZRC20.TransactOpts, sender, recipient, amount) +} + +// UpdateGasLimit is a paid mutator transaction binding the contract method 0xf687d12a. +// +// Solidity: function updateGasLimit(uint256 gasLimit) returns() +func (_TestZRC20 *TestZRC20Transactor) UpdateGasLimit(opts *bind.TransactOpts, gasLimit *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "updateGasLimit", gasLimit) +} + +// UpdateGasLimit is a paid mutator transaction binding the contract method 0xf687d12a. +// +// Solidity: function updateGasLimit(uint256 gasLimit) returns() +func (_TestZRC20 *TestZRC20Session) UpdateGasLimit(gasLimit *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateGasLimit(&_TestZRC20.TransactOpts, gasLimit) +} + +// UpdateGasLimit is a paid mutator transaction binding the contract method 0xf687d12a. +// +// Solidity: function updateGasLimit(uint256 gasLimit) returns() +func (_TestZRC20 *TestZRC20TransactorSession) UpdateGasLimit(gasLimit *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateGasLimit(&_TestZRC20.TransactOpts, gasLimit) +} + +// UpdateNewField is a paid mutator transaction binding the contract method 0x732bb0e4. +// +// Solidity: function updateNewField(uint256 newField_) returns() +func (_TestZRC20 *TestZRC20Transactor) UpdateNewField(opts *bind.TransactOpts, newField_ *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "updateNewField", newField_) +} + +// UpdateNewField is a paid mutator transaction binding the contract method 0x732bb0e4. +// +// Solidity: function updateNewField(uint256 newField_) returns() +func (_TestZRC20 *TestZRC20Session) UpdateNewField(newField_ *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateNewField(&_TestZRC20.TransactOpts, newField_) +} + +// UpdateNewField is a paid mutator transaction binding the contract method 0x732bb0e4. +// +// Solidity: function updateNewField(uint256 newField_) returns() +func (_TestZRC20 *TestZRC20TransactorSession) UpdateNewField(newField_ *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateNewField(&_TestZRC20.TransactOpts, newField_) +} + +// UpdateProtocolFlatFee is a paid mutator transaction binding the contract method 0xeddeb123. +// +// Solidity: function updateProtocolFlatFee(uint256 protocolFlatFee) returns() +func (_TestZRC20 *TestZRC20Transactor) UpdateProtocolFlatFee(opts *bind.TransactOpts, protocolFlatFee *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "updateProtocolFlatFee", protocolFlatFee) +} + +// UpdateProtocolFlatFee is a paid mutator transaction binding the contract method 0xeddeb123. +// +// Solidity: function updateProtocolFlatFee(uint256 protocolFlatFee) returns() +func (_TestZRC20 *TestZRC20Session) UpdateProtocolFlatFee(protocolFlatFee *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateProtocolFlatFee(&_TestZRC20.TransactOpts, protocolFlatFee) +} + +// UpdateProtocolFlatFee is a paid mutator transaction binding the contract method 0xeddeb123. +// +// Solidity: function updateProtocolFlatFee(uint256 protocolFlatFee) returns() +func (_TestZRC20 *TestZRC20TransactorSession) UpdateProtocolFlatFee(protocolFlatFee *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateProtocolFlatFee(&_TestZRC20.TransactOpts, protocolFlatFee) +} + +// UpdateSystemContractAddress is a paid mutator transaction binding the contract method 0xc835d7cc. +// +// Solidity: function updateSystemContractAddress(address addr) returns() +func (_TestZRC20 *TestZRC20Transactor) UpdateSystemContractAddress(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "updateSystemContractAddress", addr) +} + +// UpdateSystemContractAddress is a paid mutator transaction binding the contract method 0xc835d7cc. +// +// Solidity: function updateSystemContractAddress(address addr) returns() +func (_TestZRC20 *TestZRC20Session) UpdateSystemContractAddress(addr common.Address) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateSystemContractAddress(&_TestZRC20.TransactOpts, addr) +} + +// UpdateSystemContractAddress is a paid mutator transaction binding the contract method 0xc835d7cc. +// +// Solidity: function updateSystemContractAddress(address addr) returns() +func (_TestZRC20 *TestZRC20TransactorSession) UpdateSystemContractAddress(addr common.Address) (*types.Transaction, error) { + return _TestZRC20.Contract.UpdateSystemContractAddress(&_TestZRC20.TransactOpts, addr) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xc7012626. +// +// Solidity: function withdraw(bytes to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Transactor) Withdraw(opts *bind.TransactOpts, to []byte, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.contract.Transact(opts, "withdraw", to, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xc7012626. +// +// Solidity: function withdraw(bytes to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20Session) Withdraw(to []byte, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Withdraw(&_TestZRC20.TransactOpts, to, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xc7012626. +// +// Solidity: function withdraw(bytes to, uint256 amount) returns(bool) +func (_TestZRC20 *TestZRC20TransactorSession) Withdraw(to []byte, amount *big.Int) (*types.Transaction, error) { + return _TestZRC20.Contract.Withdraw(&_TestZRC20.TransactOpts, to, amount) +} + +// TestZRC20ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the TestZRC20 contract. +type TestZRC20ApprovalIterator struct { + Event *TestZRC20Approval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20ApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20ApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20Approval represents a Approval event raised by the TestZRC20 contract. +type TestZRC20Approval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*TestZRC20ApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &TestZRC20ApprovalIterator{contract: _TestZRC20.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *TestZRC20Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20Approval) + if err := _TestZRC20.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) ParseApproval(log types.Log) (*TestZRC20Approval, error) { + event := new(TestZRC20Approval) + if err := _TestZRC20.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20DepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the TestZRC20 contract. +type TestZRC20DepositIterator struct { + Event *TestZRC20Deposit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20DepositIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20Deposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20Deposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20DepositIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20DepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20Deposit represents a Deposit event raised by the TestZRC20 contract. +type TestZRC20Deposit struct { + From []byte + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDeposit is a free log retrieval operation binding the contract event 0x67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab3. +// +// Solidity: event Deposit(bytes from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) FilterDeposit(opts *bind.FilterOpts, to []common.Address) (*TestZRC20DepositIterator, error) { + + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "Deposit", toRule) + if err != nil { + return nil, err + } + return &TestZRC20DepositIterator{contract: _TestZRC20.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +// WatchDeposit is a free log subscription operation binding the contract event 0x67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab3. +// +// Solidity: event Deposit(bytes from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *TestZRC20Deposit, to []common.Address) (event.Subscription, error) { + + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "Deposit", toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20Deposit) + if err := _TestZRC20.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDeposit is a log parse operation binding the contract event 0x67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab3. +// +// Solidity: event Deposit(bytes from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) ParseDeposit(log types.Log) (*TestZRC20Deposit, error) { + event := new(TestZRC20Deposit) + if err := _TestZRC20.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the TestZRC20 contract. +type TestZRC20TransferIterator struct { + Event *TestZRC20Transfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20TransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20TransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20Transfer represents a Transfer event raised by the TestZRC20 contract. +type TestZRC20Transfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TestZRC20TransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &TestZRC20TransferIterator{contract: _TestZRC20.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *TestZRC20Transfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20Transfer) + if err := _TestZRC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_TestZRC20 *TestZRC20Filterer) ParseTransfer(log types.Log) (*TestZRC20Transfer, error) { + event := new(TestZRC20Transfer) + if err := _TestZRC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20UpdatedGasLimitIterator is returned from FilterUpdatedGasLimit and is used to iterate over the raw logs and unpacked data for UpdatedGasLimit events raised by the TestZRC20 contract. +type TestZRC20UpdatedGasLimitIterator struct { + Event *TestZRC20UpdatedGasLimit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20UpdatedGasLimitIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedGasLimit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedGasLimit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20UpdatedGasLimitIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20UpdatedGasLimitIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20UpdatedGasLimit represents a UpdatedGasLimit event raised by the TestZRC20 contract. +type TestZRC20UpdatedGasLimit struct { + GasLimit *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdatedGasLimit is a free log retrieval operation binding the contract event 0xff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a. +// +// Solidity: event UpdatedGasLimit(uint256 gasLimit) +func (_TestZRC20 *TestZRC20Filterer) FilterUpdatedGasLimit(opts *bind.FilterOpts) (*TestZRC20UpdatedGasLimitIterator, error) { + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "UpdatedGasLimit") + if err != nil { + return nil, err + } + return &TestZRC20UpdatedGasLimitIterator{contract: _TestZRC20.contract, event: "UpdatedGasLimit", logs: logs, sub: sub}, nil +} + +// WatchUpdatedGasLimit is a free log subscription operation binding the contract event 0xff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a. +// +// Solidity: event UpdatedGasLimit(uint256 gasLimit) +func (_TestZRC20 *TestZRC20Filterer) WatchUpdatedGasLimit(opts *bind.WatchOpts, sink chan<- *TestZRC20UpdatedGasLimit) (event.Subscription, error) { + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "UpdatedGasLimit") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20UpdatedGasLimit) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedGasLimit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdatedGasLimit is a log parse operation binding the contract event 0xff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a. +// +// Solidity: event UpdatedGasLimit(uint256 gasLimit) +func (_TestZRC20 *TestZRC20Filterer) ParseUpdatedGasLimit(log types.Log) (*TestZRC20UpdatedGasLimit, error) { + event := new(TestZRC20UpdatedGasLimit) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedGasLimit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20UpdatedProtocolFlatFeeIterator is returned from FilterUpdatedProtocolFlatFee and is used to iterate over the raw logs and unpacked data for UpdatedProtocolFlatFee events raised by the TestZRC20 contract. +type TestZRC20UpdatedProtocolFlatFeeIterator struct { + Event *TestZRC20UpdatedProtocolFlatFee // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20UpdatedProtocolFlatFeeIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedProtocolFlatFee) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedProtocolFlatFee) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20UpdatedProtocolFlatFeeIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20UpdatedProtocolFlatFeeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20UpdatedProtocolFlatFee represents a UpdatedProtocolFlatFee event raised by the TestZRC20 contract. +type TestZRC20UpdatedProtocolFlatFee struct { + ProtocolFlatFee *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdatedProtocolFlatFee is a free log retrieval operation binding the contract event 0xef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f. +// +// Solidity: event UpdatedProtocolFlatFee(uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) FilterUpdatedProtocolFlatFee(opts *bind.FilterOpts) (*TestZRC20UpdatedProtocolFlatFeeIterator, error) { + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "UpdatedProtocolFlatFee") + if err != nil { + return nil, err + } + return &TestZRC20UpdatedProtocolFlatFeeIterator{contract: _TestZRC20.contract, event: "UpdatedProtocolFlatFee", logs: logs, sub: sub}, nil +} + +// WatchUpdatedProtocolFlatFee is a free log subscription operation binding the contract event 0xef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f. +// +// Solidity: event UpdatedProtocolFlatFee(uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) WatchUpdatedProtocolFlatFee(opts *bind.WatchOpts, sink chan<- *TestZRC20UpdatedProtocolFlatFee) (event.Subscription, error) { + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "UpdatedProtocolFlatFee") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20UpdatedProtocolFlatFee) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedProtocolFlatFee", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdatedProtocolFlatFee is a log parse operation binding the contract event 0xef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f. +// +// Solidity: event UpdatedProtocolFlatFee(uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) ParseUpdatedProtocolFlatFee(log types.Log) (*TestZRC20UpdatedProtocolFlatFee, error) { + event := new(TestZRC20UpdatedProtocolFlatFee) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedProtocolFlatFee", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20UpdatedSystemContractIterator is returned from FilterUpdatedSystemContract and is used to iterate over the raw logs and unpacked data for UpdatedSystemContract events raised by the TestZRC20 contract. +type TestZRC20UpdatedSystemContractIterator struct { + Event *TestZRC20UpdatedSystemContract // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20UpdatedSystemContractIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedSystemContract) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20UpdatedSystemContract) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20UpdatedSystemContractIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20UpdatedSystemContractIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20UpdatedSystemContract represents a UpdatedSystemContract event raised by the TestZRC20 contract. +type TestZRC20UpdatedSystemContract struct { + SystemContract common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdatedSystemContract is a free log retrieval operation binding the contract event 0xd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae. +// +// Solidity: event UpdatedSystemContract(address systemContract) +func (_TestZRC20 *TestZRC20Filterer) FilterUpdatedSystemContract(opts *bind.FilterOpts) (*TestZRC20UpdatedSystemContractIterator, error) { + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "UpdatedSystemContract") + if err != nil { + return nil, err + } + return &TestZRC20UpdatedSystemContractIterator{contract: _TestZRC20.contract, event: "UpdatedSystemContract", logs: logs, sub: sub}, nil +} + +// WatchUpdatedSystemContract is a free log subscription operation binding the contract event 0xd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae. +// +// Solidity: event UpdatedSystemContract(address systemContract) +func (_TestZRC20 *TestZRC20Filterer) WatchUpdatedSystemContract(opts *bind.WatchOpts, sink chan<- *TestZRC20UpdatedSystemContract) (event.Subscription, error) { + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "UpdatedSystemContract") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20UpdatedSystemContract) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedSystemContract", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdatedSystemContract is a log parse operation binding the contract event 0xd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae. +// +// Solidity: event UpdatedSystemContract(address systemContract) +func (_TestZRC20 *TestZRC20Filterer) ParseUpdatedSystemContract(log types.Log) (*TestZRC20UpdatedSystemContract, error) { + event := new(TestZRC20UpdatedSystemContract) + if err := _TestZRC20.contract.UnpackLog(event, "UpdatedSystemContract", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestZRC20WithdrawalIterator is returned from FilterWithdrawal and is used to iterate over the raw logs and unpacked data for Withdrawal events raised by the TestZRC20 contract. +type TestZRC20WithdrawalIterator struct { + Event *TestZRC20Withdrawal // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestZRC20WithdrawalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestZRC20Withdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestZRC20Withdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestZRC20WithdrawalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestZRC20WithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestZRC20Withdrawal represents a Withdrawal event raised by the TestZRC20 contract. +type TestZRC20Withdrawal struct { + From common.Address + To []byte + Value *big.Int + Gasfee *big.Int + ProtocolFlatFee *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawal is a free log retrieval operation binding the contract event 0x9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955. +// +// Solidity: event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) FilterWithdrawal(opts *bind.FilterOpts, from []common.Address) (*TestZRC20WithdrawalIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _TestZRC20.contract.FilterLogs(opts, "Withdrawal", fromRule) + if err != nil { + return nil, err + } + return &TestZRC20WithdrawalIterator{contract: _TestZRC20.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +// WatchWithdrawal is a free log subscription operation binding the contract event 0x9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955. +// +// Solidity: event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *TestZRC20Withdrawal, from []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _TestZRC20.contract.WatchLogs(opts, "Withdrawal", fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestZRC20Withdrawal) + if err := _TestZRC20.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawal is a log parse operation binding the contract event 0x9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955. +// +// Solidity: event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee) +func (_TestZRC20 *TestZRC20Filterer) ParseWithdrawal(log types.Log) (*TestZRC20Withdrawal, error) { + event := new(TestZRC20Withdrawal) + if err := _TestZRC20.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.json b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.json new file mode 100644 index 0000000000..b4d7b68b26 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.json @@ -0,0 +1,673 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainid_", + "type": "uint256" + }, + { + "internalType": "enum CoinType", + "name": "coinType_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerIsNotFungibleModule", + "type": "error" + }, + { + "inputs": [], + "name": "GasFeeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSender", + "type": "error" + }, + { + "inputs": [], + "name": "LowAllowance", + "type": "error" + }, + { + "inputs": [], + "name": "LowBalance", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroGasCoin", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroGasPrice", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "from", + "type": "bytes" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "UpdatedGasLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "UpdatedProtocolFlatFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "systemContract", + "type": "address" + } + ], + "name": "UpdatedSystemContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gasfee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "CHAIN_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "COIN_TYPE", + "outputs": [ + { + "internalType": "enum CoinType", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FUNGIBLE_MODULE_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GAS_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROTOCOL_FLAT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SYSTEM_CONTRACT_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newField", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newPublicField", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "updateGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newField_", + "type": "uint256" + } + ], + "name": "updateNewField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "protocolFlatFee", + "type": "uint256" + } + ], + "name": "updateProtocolFlatFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "updateSystemContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawGasFee", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bin": "60c06040523480156200001157600080fd5b5060405162002566380380620025668339818101604052810190620000379190620000e1565b816080818152505080600281111562000055576200005462000128565b5b60a08160028111156200006d576200006c62000128565b5b81525050505062000157565b600080fd5b6000819050919050565b62000093816200007e565b81146200009f57600080fd5b50565b600081519050620000b38162000088565b92915050565b60038110620000c757600080fd5b50565b600081519050620000db81620000b9565b92915050565b60008060408385031215620000fb57620000fa62000079565b5b60006200010b85828601620000a2565b92505060206200011e85828601620000ca565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60805160a0516123db6200018b6000396000610aa40152600081816109ee01528181610f59015261107e01526123db6000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806385e1f4d0116100f9578063c701262611610097578063dd62ed3e11610071578063dd62ed3e146104ff578063eddeb1231461052f578063f2441b321461054b578063f687d12a14610569576101a9565b8063c701262614610494578063c835d7cc146104c4578063d9eeebed146104e0576101a9565b8063a457c2d7116100d3578063a457c2d7146103f8578063a7605f4514610428578063a9059cbb14610446578063b92894ba14610476576101a9565b806385e1f4d01461039e57806395d89b41146103bc578063a3413d03146103da576101a9565b8063395093511161016657806347e7ef241161014057806347e7ef24146103045780634d8943bb1461033457806370a0823114610352578063732bb0e414610382576101a9565b806339509351146102865780633ce4a5bc146102b657806342966c68146102d4576101a9565b806306fdde03146101ae578063091d2788146101cc578063095ea7b3146101ea57806318160ddd1461021a57806323b872dd14610238578063313ce56714610268575b600080fd5b6101b6610585565b6040516101c39190611b20565b60405180910390f35b6101d4610617565b6040516101e19190611b5b565b60405180910390f35b61020460048036038101906101ff9190611c14565b61061d565b6040516102119190611c6f565b60405180910390f35b61022261063b565b60405161022f9190611b5b565b60405180910390f35b610252600480360381019061024d9190611c8a565b610645565b60405161025f9190611c6f565b60405180910390f35b61027061073d565b60405161027d9190611cf9565b60405180910390f35b6102a0600480360381019061029b9190611c14565b610754565b6040516102ad9190611c6f565b60405180910390f35b6102be6107fa565b6040516102cb9190611d23565b60405180910390f35b6102ee60048036038101906102e99190611d3e565b610812565b6040516102fb9190611c6f565b60405180910390f35b61031e60048036038101906103199190611c14565b610827565b60405161032b9190611c6f565b60405180910390f35b61033c610993565b6040516103499190611b5b565b60405180910390f35b61036c60048036038101906103679190611d6b565b610999565b6040516103799190611b5b565b60405180910390f35b61039c60048036038101906103979190611d3e565b6109e2565b005b6103a66109ec565b6040516103b39190611b5b565b60405180910390f35b6103c4610a10565b6040516103d19190611b20565b60405180910390f35b6103e2610aa2565b6040516103ef9190611e0f565b60405180910390f35b610412600480360381019061040d9190611c14565b610ac6565b60405161041f9190611c6f565b60405180910390f35b610430610c29565b60405161043d9190611b5b565b60405180910390f35b610460600480360381019061045b9190611c14565b610c2f565b60405161046d9190611c6f565b60405180910390f35b61047e610c4d565b60405161048b9190611b20565b60405180910390f35b6104ae60048036038101906104a99190611f5f565b610cdb565b6040516104bb9190611c6f565b60405180910390f35b6104de60048036038101906104d99190611d6b565b610e22565b005b6104e8610f15565b6040516104f6929190611fbb565b60405180910390f35b61051960048036038101906105149190611fe4565b611162565b6040516105269190611b5b565b60405180910390f35b61054960048036038101906105449190611d3e565b6111e9565b005b6105536112a3565b6040516105609190611d23565b60405180910390f35b610583600480360381019061057e9190611d3e565b6112c7565b005b60606006805461059490612053565b80601f01602080910402602001604051908101604052809291908181526020018280546105c090612053565b801561060d5780601f106105e25761010080835404028352916020019161060d565b820191906000526020600020905b8154815290600101906020018083116105f057829003601f168201915b5050505050905090565b60015481565b600061063161062a611381565b8484611389565b6001905092915050565b6000600554905090565b6000610652848484611540565b6000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061069d611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610714576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073185610720611381565b858461072c91906120b3565b611389565b60019150509392505050565b6000600860009054906101000a900460ff16905090565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006107a0611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107e991906120e7565b925050819055506001905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab81565b600061081e338361179a565b60019050919050565b600073735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156108c5575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b156108fc576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109068383611951565b8273ffffffffffffffffffffffffffffffffffffffff167f67fc7bdaed5b0ec550d8706b87d60568ab70c6b781263c70101d54cd1564aab373735b14bb79463307aacbed86daf3322b1e6226ab6040516020016109639190612163565b604051602081830303815290604052846040516109819291906121d3565b60405180910390a26001905092915050565b60025481565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b8060098190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606060078054610a1f90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4b90612053565b8015610a985780601f10610a6d57610100808354040283529160200191610a98565b820191906000526020600020905b815481529060010190602001808311610a7b57829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610b12611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b85576040517f10bad14700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610bcf611381565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c1891906120b3565b925050819055506001905092915050565b60095481565b6000610c43610c3c611381565b8484611540565b6001905092915050565b600a8054610c5a90612053565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8690612053565b8015610cd35780601f10610ca857610100808354040283529160200191610cd3565b820191906000526020600020905b815481529060010190602001808311610cb657829003601f168201915b505050505081565b6000806000610ce8610f15565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3373735b14bb79463307aacbed86daf3322b1e6226ab846040518463ffffffff1660e01b8152600401610d3d93929190612203565b6020604051808303816000875af1158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190612266565b610db6576040517f0a7cd6d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dc0338561179a565b3373ffffffffffffffffffffffffffffffffffffffff167f9ffbffc04a397460ee1dbe8c9503e098090567d6b7f4b3c02a8617d800b6d955868684600254604051610e0e9493929190612293565b60405180910390a260019250505092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9b576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd55614e962c5fd6ece71614f6348d702468a997a394dd5e5c1677950226d97ae81604051610f0a9190611d23565b60405180910390a150565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630be155477f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610f949190611b5b565b602060405180830381865afa158015610fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd591906122f4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361103d576040517f78fff39600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d7fd7afb7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004016110b99190611b5b565b602060405180830381865afa1580156110d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fa9190612336565b905060008103611136576040517fe661aed000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600254600154836111499190612363565b61115391906120e7565b90508281945094505050509091565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611262576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806002819055507fef13af88e424b5d15f49c77758542c1938b08b8b95b91ed0751f98ba99000d8f816040516112989190611b5b565b60405180910390a150565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73735b14bb79463307aacbed86daf3322b1e6226ab73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611340576040517f2b2add3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001819055507fff5788270f43bfc1ca41c503606d2594aa3023a1a7547de403a3e2f146a4a80a816040516113769190611b5b565b60405180910390a150565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113ef576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611455576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516115339190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036115a6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361160c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561168a576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161169691906120b3565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172891906120e7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161178c9190611b5b565b60405180910390a350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611800576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561187e576040517ffe382aa700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818161188a91906120b3565b600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008282546118df91906120b3565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119449190611b5b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119b7576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008282546119c991906120e7565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a1f91906120e7565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611a849190611b5b565b60405180910390a35050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611aca578082015181840152602081019050611aaf565b60008484015250505050565b6000601f19601f8301169050919050565b6000611af282611a90565b611afc8185611a9b565b9350611b0c818560208601611aac565b611b1581611ad6565b840191505092915050565b60006020820190508181036000830152611b3a8184611ae7565b905092915050565b6000819050919050565b611b5581611b42565b82525050565b6000602082019050611b706000830184611b4c565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611bb582611b8a565b9050919050565b611bc581611baa565b8114611bd057600080fd5b50565b600081359050611be281611bbc565b92915050565b611bf181611b42565b8114611bfc57600080fd5b50565b600081359050611c0e81611be8565b92915050565b60008060408385031215611c2b57611c2a611b80565b5b6000611c3985828601611bd3565b9250506020611c4a85828601611bff565b9150509250929050565b60008115159050919050565b611c6981611c54565b82525050565b6000602082019050611c846000830184611c60565b92915050565b600080600060608486031215611ca357611ca2611b80565b5b6000611cb186828701611bd3565b9350506020611cc286828701611bd3565b9250506040611cd386828701611bff565b9150509250925092565b600060ff82169050919050565b611cf381611cdd565b82525050565b6000602082019050611d0e6000830184611cea565b92915050565b611d1d81611baa565b82525050565b6000602082019050611d386000830184611d14565b92915050565b600060208284031215611d5457611d53611b80565b5b6000611d6284828501611bff565b91505092915050565b600060208284031215611d8157611d80611b80565b5b6000611d8f84828501611bd3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611dd857611dd7611d98565b5b50565b6000819050611de982611dc7565b919050565b6000611df982611ddb565b9050919050565b611e0981611dee565b82525050565b6000602082019050611e246000830184611e00565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611e6c82611ad6565b810181811067ffffffffffffffff82111715611e8b57611e8a611e34565b5b80604052505050565b6000611e9e611b76565b9050611eaa8282611e63565b919050565b600067ffffffffffffffff821115611eca57611ec9611e34565b5b611ed382611ad6565b9050602081019050919050565b82818337600083830152505050565b6000611f02611efd84611eaf565b611e94565b905082815260208101848484011115611f1e57611f1d611e2f565b5b611f29848285611ee0565b509392505050565b600082601f830112611f4657611f45611e2a565b5b8135611f56848260208601611eef565b91505092915050565b60008060408385031215611f7657611f75611b80565b5b600083013567ffffffffffffffff811115611f9457611f93611b85565b5b611fa085828601611f31565b9250506020611fb185828601611bff565b9150509250929050565b6000604082019050611fd06000830185611d14565b611fdd6020830184611b4c565b9392505050565b60008060408385031215611ffb57611ffa611b80565b5b600061200985828601611bd3565b925050602061201a85828601611bd3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061206b57607f821691505b60208210810361207e5761207d612024565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006120be82611b42565b91506120c983611b42565b92508282039050818111156120e1576120e0612084565b5b92915050565b60006120f282611b42565b91506120fd83611b42565b925082820190508082111561211557612114612084565b5b92915050565b60008160601b9050919050565b60006121338261211b565b9050919050565b600061214582612128565b9050919050565b61215d61215882611baa565b61213a565b82525050565b600061216f828461214c565b60148201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006121a58261217e565b6121af8185612189565b93506121bf818560208601611aac565b6121c881611ad6565b840191505092915050565b600060408201905081810360008301526121ed818561219a565b90506121fc6020830184611b4c565b9392505050565b60006060820190506122186000830186611d14565b6122256020830185611d14565b6122326040830184611b4c565b949350505050565b61224381611c54565b811461224e57600080fd5b50565b6000815190506122608161223a565b92915050565b60006020828403121561227c5761227b611b80565b5b600061228a84828501612251565b91505092915050565b600060808201905081810360008301526122ad818761219a565b90506122bc6020830186611b4c565b6122c96040830185611b4c565b6122d66060830184611b4c565b95945050505050565b6000815190506122ee81611bbc565b92915050565b60006020828403121561230a57612309611b80565b5b6000612318848285016122df565b91505092915050565b60008151905061233081611be8565b92915050565b60006020828403121561234c5761234b611b80565b5b600061235a84828501612321565b91505092915050565b600061236e82611b42565b915061237983611b42565b925082820261238781611b42565b9150828204841483151761239e5761239d612084565b5b509291505056fea264697066735822122011fda4fba218fc7f911b68b0418884c426f5ddb324eb1572e2e793fcb60edf6c64736f6c63430008150033" +} diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.sol b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.sol new file mode 100644 index 0000000000..c31ccb4686 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/TestZRC20.sol @@ -0,0 +1,363 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + +/** + * @dev Custom errors for ZRC20 + */ +interface ZRC20Errors { + error CallerIsNotFungibleModule(); + error InvalidSender(); + error GasFeeTransferFailed(); + error ZeroGasCoin(); + error ZeroGasPrice(); + error LowAllowance(); + error LowBalance(); + error ZeroAddress(); +} + +/** + * @dev Interfaces of SystemContract and ZRC20 to make easier to import. + */ +interface ISystem { + function FUNGIBLE_MODULE_ADDRESS() external view returns (address); + function wZetaContractAddress() external view returns (address); + function uniswapv2FactoryAddress() external view returns (address); + function gasPriceByChainId(uint256 chainID) external view returns (uint256); + function gasCoinZRC20ByChainId(uint256 chainID) external view returns (address); + function gasZetaPoolByChainId(uint256 chainID) external view returns (address); +} + +interface IZRC20 { + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address recipient, uint256 amount) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + function deposit(address to, uint256 amount) external returns (bool); + function withdraw(bytes memory to, uint256 amount) external returns (bool); + function withdrawGasFee() external view returns (address, uint256); + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + event Deposit(bytes from, address indexed to, uint256 value); + event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee); + event UpdatedSystemContract(address systemContract); + event UpdatedGasLimit(uint256 gasLimit); + event UpdatedProtocolFlatFee(uint256 protocolFlatFee); +} + +interface IZRC20Metadata is IZRC20 { + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function decimals() external view returns (uint8); +} + +/// @dev Coin types for ZRC20. Zeta value should not be used. +enum CoinType { + Zeta, + Gas, + ERC20 +} + +/** + * @dev TestZRC20 is a test implementation of ZRC20 that extends the contract with new fields to test contract + bytecode upgrade + */ +contract TestZRC20 is IZRC20, IZRC20Metadata, ZRC20Errors { + /// @notice Fungible address is always the same, maintained at the protocol level + address public constant FUNGIBLE_MODULE_ADDRESS = 0x735b14BB79463307AAcBED86DAf3322B1e6226aB; + /// @notice Chain id.abi + uint256 public immutable CHAIN_ID; + /// @notice Coin type, checkout Interfaces.sol. + CoinType public immutable COIN_TYPE; + /// @notice System contract address. + address public SYSTEM_CONTRACT_ADDRESS; + /// @notice Gas limit. + uint256 public GAS_LIMIT; + /// @notice Protocol flat fee. + uint256 public PROTOCOL_FLAT_FEE; + + mapping(address => uint256) private _balances; + mapping(address => mapping(address => uint256)) private _allowances; + uint256 private _totalSupply; + string private _name; + string private _symbol; + uint8 private _decimals; + + /// @notice extend the contract with new fields to test contract bytecode upgrade + uint256 public newField; + string public newPublicField; + + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } + + /** + * @dev Only fungible module modifier. + */ + modifier onlyFungible() { + if (msg.sender != FUNGIBLE_MODULE_ADDRESS) revert CallerIsNotFungibleModule(); + _; + } + + /** + * @dev Constructor + */ + constructor( + uint256 chainid_, + CoinType coinType_ + ) { + CHAIN_ID = chainid_; + COIN_TYPE = coinType_; + } + + /** + * @dev ZRC20 name + * @return name as string + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev ZRC20 symbol. + * @return symbol as string. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev ZRC20 decimals. + * @return returns uint8 decimals. + */ + function decimals() public view virtual override returns (uint8) { + return _decimals; + } + + /** + * @dev ZRC20 total supply. + * @return returns uint256 total supply. + */ + function totalSupply() public view virtual override returns (uint256) { + return _totalSupply; + } + + /** + * @dev Returns ZRC20 balance of an account. + * @param account, account address for which balance is requested. + * @return uint256 account balance. + */ + function balanceOf(address account) public view virtual override returns (uint256) { + return _balances[account]; + } + + /** + * @dev Returns ZRC20 balance of an account. + * @param recipient, recipiuent address to which transfer is done. + * @return true/false if transfer succeeded/failed. + */ + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(_msgSender(), recipient, amount); + return true; + } + + /** + * @dev Returns token allowance from owner to spender. + * @param owner, owner address. + * @return uint256 allowance. + */ + function allowance(address owner, address spender) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev Approves amount transferFrom for spender. + * @param spender, spender address. + * @param amount, amount to approve. + * @return true/false if succeeded/failed. + */ + function approve(address spender, uint256 amount) public virtual override returns (bool) { + _approve(_msgSender(), spender, amount); + return true; + } + + /** + * @dev Increases allowance by amount for spender. + * @param spender, spender address. + * @param amount, amount by which to increase allownace. + * @return true/false if succeeded/failed. + */ + function increaseAllowance(address spender, uint256 amount) external virtual returns (bool) { + _allowances[spender][_msgSender()] += amount; + return true; + } + + /** + * @dev Decreases allowance by amount for spender. + * @param spender, spender address. + * @param amount, amount by which to decrease allownace. + * @return true/false if succeeded/failed. + */ + function decreaseAllowance(address spender, uint256 amount) external virtual returns (bool) { + if (_allowances[spender][_msgSender()] < amount) revert LowAllowance(); + _allowances[spender][_msgSender()] -= amount; + return true; + } + + /** + * @dev Transfers tokens from sender to recipient. + * @param sender, sender address. + * @param recipient, recipient address. + * @param amount, amount to transfer. + * @return true/false if succeeded/failed. + */ + function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(sender, recipient, amount); + + uint256 currentAllowance = _allowances[sender][_msgSender()]; + if (currentAllowance < amount) revert LowAllowance(); + + _approve(sender, _msgSender(), currentAllowance - amount); + + return true; + } + + /** + * @dev Burns an amount of tokens. + * @param amount, amount to burn. + * @return true/false if succeeded/failed. + */ + function burn(uint256 amount) external returns (bool) { + _burn(msg.sender, amount); + return true; + } + + function _transfer(address sender, address recipient, uint256 amount) internal virtual { + if (sender == address(0)) revert ZeroAddress(); + if (recipient == address(0)) revert ZeroAddress(); + + uint256 senderBalance = _balances[sender]; + if (senderBalance < amount) revert LowBalance(); + + _balances[sender] = senderBalance - amount; + _balances[recipient] += amount; + + emit Transfer(sender, recipient, amount); + } + + function _mint(address account, uint256 amount) internal virtual { + if (account == address(0)) revert ZeroAddress(); + + _totalSupply += amount; + _balances[account] += amount; + emit Transfer(address(0), account, amount); + } + + function _burn(address account, uint256 amount) internal virtual { + if (account == address(0)) revert ZeroAddress(); + + uint256 accountBalance = _balances[account]; + if (accountBalance < amount) revert LowBalance(); + + _balances[account] = accountBalance - amount; + _totalSupply -= amount; + + emit Transfer(account, address(0), amount); + } + + function _approve(address owner, address spender, uint256 amount) internal virtual { + if (owner == address(0)) revert ZeroAddress(); + if (spender == address(0)) revert ZeroAddress(); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Deposits corresponding tokens from external chain, only callable by Fungible module. + * @param to, recipient address. + * @param amount, amount to deposit. + * @return true/false if succeeded/failed. + */ + function deposit(address to, uint256 amount) external override returns (bool) { + if (msg.sender != FUNGIBLE_MODULE_ADDRESS && msg.sender != SYSTEM_CONTRACT_ADDRESS) revert InvalidSender(); + _mint(to, amount); + emit Deposit(abi.encodePacked(FUNGIBLE_MODULE_ADDRESS), to, amount); + return true; + } + + /** + * @dev Withdraws gas fees. + * @return returns the ZRC20 address for gas on the same chain of this ZRC20, and calculates the gas fee for withdraw() + */ + function withdrawGasFee() public view override returns (address, uint256) { + address gasZRC20 = ISystem(SYSTEM_CONTRACT_ADDRESS).gasCoinZRC20ByChainId(CHAIN_ID); + if (gasZRC20 == address(0)) { + revert ZeroGasCoin(); + } + uint256 gasPrice = ISystem(SYSTEM_CONTRACT_ADDRESS).gasPriceByChainId(CHAIN_ID); + if (gasPrice == 0) { + revert ZeroGasPrice(); + } + uint256 gasFee = gasPrice * GAS_LIMIT + PROTOCOL_FLAT_FEE; + return (gasZRC20, gasFee); + } + + /** + * @dev Withraws ZRC20 tokens to external chains, this function causes cctx module to send out outbound tx to the outbound chain + * this contract should be given enough allowance of the gas ZRC20 to pay for outbound tx gas fee. + * @param to, recipient address. + * @param amount, amount to deposit. + * @return true/false if succeeded/failed. + */ + function withdraw(bytes memory to, uint256 amount) external override returns (bool) { + (address gasZRC20, uint256 gasFee) = withdrawGasFee(); + if (!IZRC20(gasZRC20).transferFrom(msg.sender, FUNGIBLE_MODULE_ADDRESS, gasFee)) { + revert GasFeeTransferFailed(); + } + _burn(msg.sender, amount); + emit Withdrawal(msg.sender, to, amount, gasFee, PROTOCOL_FLAT_FEE); + return true; + } + + /** + * @dev Updates system contract address. Can only be updated by the fungible module. + * @param addr, new system contract address. + */ + function updateSystemContractAddress(address addr) external onlyFungible { + SYSTEM_CONTRACT_ADDRESS = addr; + emit UpdatedSystemContract(addr); + } + + /** + * @dev Updates gas limit. Can only be updated by the fungible module. + * @param gasLimit, new gas limit. + */ + function updateGasLimit(uint256 gasLimit) external onlyFungible { + GAS_LIMIT = gasLimit; + emit UpdatedGasLimit(gasLimit); + } + + /** + * @dev Updates protocol flat fee. Can only be updated by the fungible module. + * @param protocolFlatFee, new protocol flat fee. + */ + function updateProtocolFlatFee(uint256 protocolFlatFee) external onlyFungible { + PROTOCOL_FLAT_FEE = protocolFlatFee; + emit UpdatedProtocolFlatFee(protocolFlatFee); + } + + /** + * @dev Updates newField. Can only be updated by the fungible module. + * @param newField_, new newField. + */ + function updateNewField(uint256 newField_) external { + newField = newField_; + } +} diff --git a/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/bindings.go b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/bindings.go new file mode 100644 index 0000000000..dc615b9770 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/contracts/testzrc20/bindings.go @@ -0,0 +1,6 @@ +//go:generate sh -c "solc --evm-version paris TestZRC20.sol --combined-json abi,bin | jq '.contracts.\"TestZRC20.sol:TestZRC20\"' > TestZRC20.json" +//go:generate sh -c "cat TestZRC20.json | jq .abi > TestZRC20.abi" +//go:generate sh -c "cat TestZRC20.json | jq .bin | tr -d '\"' > TestZRC20.bin" +//go:generate sh -c "abigen --abi TestZRC20.abi --bin TestZRC20.bin --pkg testzrc20 --type TestZRC20 --out TestZRC20.go" + +package testzrc20 diff --git a/contrib/localnet/orchestrator/smoketest/main.go b/contrib/localnet/orchestrator/smoketest/main.go index c08b04d3ac..09f307de7c 100644 --- a/contrib/localnet/orchestrator/smoketest/main.go +++ b/contrib/localnet/orchestrator/smoketest/main.go @@ -300,6 +300,9 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { smokeTest.TestPauseZRC20() smokeTest.CheckZRC20ReserveAndSupply() + smokeTest.TestUpdateBytecode() + smokeTest.CheckZRC20ReserveAndSupply() + // add your dev test here smokeTest.TestMyTest() diff --git a/contrib/localnet/orchestrator/smoketest/test_update_bytecode.go b/contrib/localnet/orchestrator/smoketest/test_update_bytecode.go new file mode 100644 index 0000000000..f8350b9a12 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/test_update_bytecode.go @@ -0,0 +1,189 @@ +//go:build PRIVNET +// +build PRIVNET + +package main + +import ( + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/testzrc20" + "github.com/zeta-chain/zetacore/testutil/sample" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" +) + +// TestUpdateBytecode tests updating the bytecode of a zrc20 and interact with it +func (sm *SmokeTest) TestUpdateBytecode() { + startTime := time.Now() + defer func() { + fmt.Printf("test finishes in %s\n", time.Since(startTime)) + }() + LoudPrintf("Testing updating ZRC20 bytecode swap...\n") + + // Random approval + approved := sample.EthAddress() + tx, err := sm.ETHZRC20.Approve(sm.zevmAuth, approved, big.NewInt(1e10)) + if err != nil { + panic(err) + } + receipt := MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status != 1 { + panic("approval failed") + } + + // Deploy the TestZRC20 contract + fmt.Println("Deploying contract with new bytecode") + newZRC20Address, _, newZRC20Contract, err := testzrc20.DeployTestZRC20(sm.zevmAuth, sm.zevmClient, big.NewInt(5), uint8(common.CoinType_Gas)) + if err != nil { + panic(err) + } + + // Get current info of the ZRC20 + name, err := sm.ETHZRC20.Name(&bind.CallOpts{}) + if err != nil { + panic(err) + } + symbol, err := sm.ETHZRC20.Symbol(&bind.CallOpts{}) + if err != nil { + panic(err) + } + decimals, err := sm.ETHZRC20.Decimals(&bind.CallOpts{}) + if err != nil { + panic(err) + } + totalSupply, err := sm.ETHZRC20.TotalSupply(&bind.CallOpts{}) + if err != nil { + panic(err) + } + balance, err := sm.ETHZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + approval, err := sm.ETHZRC20.Allowance(&bind.CallOpts{}, DeployerAddress, approved) + if err != nil { + panic(err) + } + + fmt.Println("Updating the bytecode of the ZRC20") + msg := fungibletypes.NewMsgUpdateContractBytecode( + FungibleAdminAddress, + sm.ETHZRC20Addr, + newZRC20Address, + ) + res, err := sm.zetaTxServer.BroadcastTx(FungibleAdminName, msg) + if err != nil { + panic(err) + } + fmt.Printf("Update zrc20 bytecode tx hash: %s\n", res.TxHash) + + // Get new info of the ZRC20 + fmt.Println("Checking the state of the ZRC20 remains the same") + newName, err := sm.ETHZRC20.Name(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if name != newName { + panic("name shouldn't change upon bytecode update") + } + newSymbol, err := sm.ETHZRC20.Symbol(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if symbol != newSymbol { + panic("symbol shouldn't change upon bytecode update") + } + newDecimals, err := sm.ETHZRC20.Decimals(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if decimals != newDecimals { + panic("decimals shouldn't change upon bytecode update") + } + newTotalSupply, err := sm.ETHZRC20.TotalSupply(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if totalSupply.Cmp(newTotalSupply) != 0 { + panic("total supply shouldn't change upon bytecode update") + } + newBalance, err := sm.ETHZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + if balance.Cmp(newBalance) != 0 { + panic("balance shouldn't change upon bytecode update") + } + newApproval, err := sm.ETHZRC20.Allowance(&bind.CallOpts{}, DeployerAddress, approved) + if err != nil { + panic(err) + } + if approval.Cmp(newApproval) != 0 { + panic("approval shouldn't change upon bytecode update") + } + + fmt.Println("Can interact with the new code of the contract") + testZRC20Contract, err := testzrc20.NewTestZRC20(sm.ETHZRC20Addr, sm.zevmClient) + if err != nil { + panic(err) + } + tx, err = testZRC20Contract.UpdateNewField(sm.zevmAuth, big.NewInt(1e10)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status != 1 { + panic("update new field failed") + } + newField, err := testZRC20Contract.NewField(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if newField.Cmp(big.NewInt(1e10)) != 0 { + panic("new field value mismatch") + } + + fmt.Println("Interacting with the bytecode contract doesn't disrupt the zrc20 contract") + tx, err = newZRC20Contract.UpdateNewField(sm.zevmAuth, big.NewInt(1e5)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status != 1 { + panic("update new field failed") + } + newField, err = newZRC20Contract.NewField(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if newField.Cmp(big.NewInt(1e5)) != 0 { + panic("new field value mismatch on bytecode contract") + } + newField, err = testZRC20Contract.NewField(&bind.CallOpts{}) + if err != nil { + panic(err) + } + if newField.Cmp(big.NewInt(1e10)) != 0 { + panic("new field value mismatch on zrc20 contract") + } + + // can continue to operate the ZRC20 + fmt.Println("Checking the ZRC20 can continue to operate after state change") + tx, err = sm.ETHZRC20.Transfer(sm.zevmAuth, approved, big.NewInt(1e14)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status != 1 { + panic("transfer failed") + } + newBalance, err = sm.ETHZRC20.BalanceOf(&bind.CallOpts{}, approved) + if err != nil { + panic(err) + } + if newBalance.Cmp(big.NewInt(1e14)) != 0 { + panic("balance not updated") + } +} diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 025b70c325..b6e222894a 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -50787,6 +50787,12 @@ definitions: type: object fungibleMsgRemoveForeignCoinResponse: type: object + fungibleMsgUpdateContractBytecodeResponse: + type: object + properties: + new_bytecode_hash: + type: string + format: byte fungibleMsgUpdateSystemContractResponse: type: object fungibleMsgUpdateZRC20PausedStatusResponse: diff --git a/docs/spec/fungible/messages.md b/docs/spec/fungible/messages.md index 5e67f9131b..9f86674b5b 100644 --- a/docs/spec/fungible/messages.md +++ b/docs/spec/fungible/messages.md @@ -66,6 +66,21 @@ message MsgUpdateZRC20WithdrawFee { } ``` +## MsgUpdateContractBytecode + +UpdateContractBytecode updates the bytecode of a contract from the bytecode of an existing contract +Only a ZRC20 contract or the WZeta connector contract can be updated +IMPORTANT: the new contract bytecode must have the same storage layout as the old contract bytecode +the new contract can add new variable but cannot remove any existing variable + +```proto +message MsgUpdateContractBytecode { + string creator = 1; + string contract_address = 2; + string new_bytecode_address = 3; +} +``` + ## MsgUpdateZRC20PausedStatus UpdateZRC20PausedStatus updates the paused status of a ZRC20 diff --git a/proto/fungible/tx.proto b/proto/fungible/tx.proto index c26e0adea2..5e2b7d5299 100644 --- a/proto/fungible/tx.proto +++ b/proto/fungible/tx.proto @@ -12,6 +12,7 @@ service Msg { rpc RemoveForeignCoin(MsgRemoveForeignCoin) returns (MsgRemoveForeignCoinResponse); rpc UpdateSystemContract(MsgUpdateSystemContract) returns (MsgUpdateSystemContractResponse); rpc UpdateZRC20WithdrawFee(MsgUpdateZRC20WithdrawFee) returns (MsgUpdateZRC20WithdrawFeeResponse); + rpc UpdateContractBytecode(MsgUpdateContractBytecode) returns (MsgUpdateContractBytecodeResponse); rpc UpdateZRC20PausedStatus(MsgUpdateZRC20PausedStatus) returns (MsgUpdateZRC20PausedStatusResponse); } @@ -53,6 +54,16 @@ message MsgRemoveForeignCoin { message MsgRemoveForeignCoinResponse {} +message MsgUpdateContractBytecode { + string creator = 1; + string contract_address = 2; + string new_bytecode_address = 3; +} + +message MsgUpdateContractBytecodeResponse { + bytes new_bytecode_hash = 1; +} + enum UpdatePausedStatusAction { PAUSE = 0; UNPAUSE = 1; diff --git a/testutil/keeper/mocks/fungible/evm.go b/testutil/keeper/mocks/fungible/evm.go index 8f6884d536..81653bd4a4 100644 --- a/testutil/keeper/mocks/fungible/evm.go +++ b/testutil/keeper/mocks/fungible/evm.go @@ -6,12 +6,16 @@ import ( context "context" big "math/big" + common "github.com/ethereum/go-ethereum/common" + core "github.com/ethereum/go-ethereum/core" evmtypes "github.com/evmos/ethermint/x/evm/types" mock "github.com/stretchr/testify/mock" + statedb "github.com/evmos/ethermint/x/evm/statedb" + types "github.com/cosmos/cosmos-sdk/types" vm "github.com/ethereum/go-ethereum/core/vm" @@ -90,6 +94,22 @@ func (_m *FungibleEVMKeeper) EstimateGas(c context.Context, req *evmtypes.EthCal return r0, r1 } +// GetAccount provides a mock function with given fields: ctx, addr +func (_m *FungibleEVMKeeper) GetAccount(ctx types.Context, addr common.Address) *statedb.Account { + ret := _m.Called(ctx, addr) + + var r0 *statedb.Account + if rf, ok := ret.Get(0).(func(types.Context, common.Address) *statedb.Account); ok { + r0 = rf(ctx, addr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*statedb.Account) + } + } + + return r0 +} + // GetBlockBloomTransient provides a mock function with given fields: ctx func (_m *FungibleEVMKeeper) GetBlockBloomTransient(ctx types.Context) *big.Int { ret := _m.Called(ctx) @@ -120,6 +140,20 @@ func (_m *FungibleEVMKeeper) GetLogSizeTransient(ctx types.Context) uint64 { return r0 } +// SetAccount provides a mock function with given fields: ctx, addr, account +func (_m *FungibleEVMKeeper) SetAccount(ctx types.Context, addr common.Address, account statedb.Account) error { + ret := _m.Called(ctx, addr, account) + + var r0 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address, statedb.Account) error); ok { + r0 = rf(ctx, addr, account) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // SetBlockBloomTransient provides a mock function with given fields: ctx, bloom func (_m *FungibleEVMKeeper) SetBlockBloomTransient(ctx types.Context, bloom *big.Int) { _m.Called(ctx, bloom) diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go index 21a04c7f64..19db995327 100644 --- a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go @@ -133,6 +133,7 @@ func (k Keeper) TestUpdateSystemContractAddress(goCtx context.Context) error { creator := k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_deploy_fungible_coin) msg := types.NewMessageUpdateSystemContract(creator, SystemContractAddress.Hex()) _, err = k.UpdateSystemContract(ctx, msg) + k.Logger(ctx).Info("System contract updated", "new address", SystemContractAddress.String()) return err } diff --git a/x/fungible/keeper/evm.go b/x/fungible/keeper/evm.go index 9911c81adf..0f0e240ca5 100644 --- a/x/fungible/keeper/evm.go +++ b/x/fungible/keeper/evm.go @@ -195,7 +195,6 @@ func (k Keeper) DepositZRC20( to common.Address, amount *big.Int, ) (*evmtypes.MsgEthereumTxResponse, error) { - //abi, err := zrc20.ZRC4MetaData.GetAbi() abi, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return nil, err @@ -338,6 +337,60 @@ func (k Keeper) BalanceOfZRC4( return balance, nil } +// TotalSupplyZRC4 queries the total supply of a given ZRC4 contract +func (k Keeper) TotalSupplyZRC4( + ctx sdk.Context, + contract common.Address, +) (*big.Int, error) { + abi, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) + } + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "totalSupply") + if err != nil { + return nil, err + } + + unpacked, err := abi.Unpack("totalSupply", res.Ret) + if err != nil || len(unpacked) == 0 { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) + } + + totalSupply, ok := unpacked[0].(*big.Int) + if !ok { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack total supply") + } + + return totalSupply, nil +} + +// QueryChainIDFromContract returns the chain id of the chain +func (k Keeper) QueryChainIDFromContract( + ctx sdk.Context, + contract common.Address, +) (*big.Int, error) { + abi, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) + } + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "CHAIN_ID") + if err != nil { + return nil, err + } + + unpacked, err := abi.Unpack("CHAIN_ID", res.Ret) + if err != nil || len(unpacked) == 0 { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) + } + + chainID, ok := unpacked[0].(*big.Int) + if !ok { + return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack chain ID") + } + + return chainID, nil +} + // CallEVM performs a smart contract method call using given args // returns (msg,err) the EVM execution result if there is any, even if error is non-nil due to contract reverts // Furthermore, err!=nil && msg!=nil && msg.Failed() means the contract call reverted. diff --git a/x/fungible/keeper/msg_server_update_contract_bytecode.go b/x/fungible/keeper/msg_server_update_contract_bytecode.go new file mode 100644 index 0000000000..ed66882fe4 --- /dev/null +++ b/x/fungible/keeper/msg_server_update_contract_bytecode.go @@ -0,0 +1,83 @@ +package keeper + +import ( + "context" + + cosmoserror "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// UpdateContractBytecode updates the bytecode of a contract from the bytecode of an existing contract +// Only a ZRC20 contract or the WZeta connector contract can be updated +// IMPORTANT: the new contract bytecode must have the same storage layout as the old contract bytecode +// the new contract can add new variable but cannot remove any existing variable +func (k Keeper) UpdateContractBytecode(goCtx context.Context, msg *types.MsgUpdateContractBytecode) (*types.MsgUpdateContractBytecodeResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // check authorization + if msg.Creator != k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_deploy_fungible_coin) { + return nil, cosmoserror.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") + } + + // fetch account to update + if !ethcommon.IsHexAddress(msg.ContractAddress) { + return nil, cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", msg.ContractAddress) + } + contractAddress := ethcommon.HexToAddress(msg.ContractAddress) + acct := k.evmKeeper.GetAccount(ctx, contractAddress) + if acct == nil { + return nil, cosmoserror.Wrapf(types.ErrContractNotFound, "contract (%s) not found", contractAddress.Hex()) + } + + // check the contract is a zrc20 + _, found := k.GetForeignCoins(ctx, msg.ContractAddress) + if !found { + // check contract is wzeta connector contract + systemContract, found := k.GetSystemContract(ctx) + if !found { + return nil, types.ErrSystemContractNotFound + } + if msg.ContractAddress != systemContract.ConnectorZevm { + // not a zrc20 or wzeta connector contract, can't be updated + return nil, cosmoserror.Wrapf(types.ErrInvalidContract, "contract (%s) is neither a zrc20 nor wzeta connector", msg.ContractAddress) + } + } + + // fetch the account of the new bytecode + if !ethcommon.IsHexAddress(msg.NewBytecodeAddress) { + return nil, cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", msg.NewBytecodeAddress) + } + newBytecodeAddress := ethcommon.HexToAddress(msg.NewBytecodeAddress) + newBytecodeAcct := k.evmKeeper.GetAccount(ctx, newBytecodeAddress) + if newBytecodeAcct == nil { + return nil, cosmoserror.Wrapf(types.ErrContractNotFound, "contract (%s) not found", newBytecodeAddress.Hex()) + } + + // set the new CodeHash to the account + previousCodeHash := acct.CodeHash + acct.CodeHash = newBytecodeAcct.CodeHash + err := k.evmKeeper.SetAccount(ctx, contractAddress, *acct) + if err != nil { + return nil, cosmoserror.Wrapf( + types.ErrSetBytecode, + "failed to update contract (%s) bytecode (%s)", + contractAddress.Hex(), + err.Error(), + ) + } + k.Logger(ctx).Info( + "updated contract bytecode", + "contract", contractAddress.Hex(), + "oldCodeHash", string(previousCodeHash), + "newCodeHash", string(acct.CodeHash), + ) + + return &types.MsgUpdateContractBytecodeResponse{ + NewBytecodeHash: acct.CodeHash, + }, nil +} diff --git a/x/fungible/keeper/msg_server_update_contract_bytecode_test.go b/x/fungible/keeper/msg_server_update_contract_bytecode_test.go new file mode 100644 index 0000000000..8db3f53bdf --- /dev/null +++ b/x/fungible/keeper/msg_server_update_contract_bytecode_test.go @@ -0,0 +1,374 @@ +package keeper_test + +import ( + "errors" + "math/big" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/evmos/ethermint/x/evm/statedb" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + zetacommon "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +func setAdminDeployFungibleCoin(ctx sdk.Context, zk keepertest.ZetaKeepers, admin string) { + zk.ObserverKeeper.SetParams(ctx, observertypes.Params{ + AdminPolicy: []*observertypes.Admin_Policy{ + { + PolicyType: observertypes.Policy_Type_deploy_fungible_coin, + Address: admin, + }, + }, + }) +} + +func TestKeeper_UpdateContractBytecode(t *testing.T) { + t.Run("can update the bytecode from another contract", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + + // set admin policy + setAdminDeployFungibleCoin(ctx, zk, admin) + + // sample chainIDs and addresses + chainList := zetacommon.DefaultChainsList() + require.True(t, len(chainList) > 1) + require.NotNil(t, chainList[0]) + require.NotNil(t, chainList[1]) + require.NotEqual(t, chainList[0].ChainId, chainList[1].ChainId) + chainID1 := chainList[0].ChainId + chainID2 := chainList[1].ChainId + + addr1 := sample.EthAddress() + addr2 := sample.EthAddress() + + // deploy the system contract and a ZRC20 contract + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID1, "alpha", "alpha") + + // do some operation to populate the state + _, err := k.DepositZRC20(ctx, zrc20, addr1, big.NewInt(100)) + require.NoError(t, err) + _, err = k.DepositZRC20(ctx, zrc20, addr2, big.NewInt(200)) + require.NoError(t, err) + + // check the state + checkState := func() { + // state that should not change + balance, err := k.BalanceOfZRC4(ctx, zrc20, addr1) + require.NoError(t, err) + require.Equal(t, int64(100), balance.Int64()) + balance, err = k.BalanceOfZRC4(ctx, zrc20, addr2) + require.NoError(t, err) + require.Equal(t, int64(200), balance.Int64()) + totalSupply, err := k.TotalSupplyZRC4(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, int64(10000300), totalSupply.Int64()) // 10000000 minted on deploy + } + + checkState() + chainID, err := k.QueryChainIDFromContract(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, chainID1, chainID.Int64()) + + // deploy new zrc20 + newCodeAddress, err := k.DeployZRC20Contract( + ctx, + "beta", + "BETA", + 18, + chainID2, + zetacommon.CoinType_ERC20, + "beta", + big.NewInt(90_000), + ) + require.NoError(t, err) + + // update the bytecode + res, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + zrc20, + newCodeAddress, + )) + require.NoError(t, err) + + // check the returned new bytecode hash matches the one in the account + acct := sdkk.EvmKeeper.GetAccount(ctx, zrc20) + require.Equal(t, acct.CodeHash, res.NewBytecodeHash) + + // check the state + // balances and total supply should remain + // BYTECODE value is immutable and therefore part of the code, this value should change + checkState() + chainID, err = k.QueryChainIDFromContract(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, chainID2, chainID.Int64()) + + // can continue to interact with the contract + _, err = k.DepositZRC20(ctx, zrc20, addr1, big.NewInt(1000)) + require.NoError(t, err) + balance, err := k.BalanceOfZRC4(ctx, zrc20, addr1) + require.NoError(t, err) + require.Equal(t, int64(1100), balance.Int64()) + totalSupply, err := k.TotalSupplyZRC4(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, int64(10001300), totalSupply.Int64()) + + // can change again bytecode + newCodeAddress, err = k.DeployZRC20Contract( + ctx, + "gamma", + "GAMMA", + 18, + chainID1, + zetacommon.CoinType_ERC20, + "gamma", + big.NewInt(90_000), + ) + require.NoError(t, err) + _, err = k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + zrc20, + newCodeAddress, + )) + require.NoError(t, err) + balance, err = k.BalanceOfZRC4(ctx, zrc20, addr1) + require.NoError(t, err) + require.Equal(t, int64(1100), balance.Int64()) + totalSupply, err = k.TotalSupplyZRC4(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, int64(10001300), totalSupply.Int64()) + chainID, err = k.QueryChainIDFromContract(ctx, zrc20) + require.NoError(t, err) + require.Equal(t, chainID1, chainID.Int64()) + }) + + t.Run("can update the bytecode of the wzeta connector contract", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + + // deploy a connector + setAdminDeployFungibleCoin(ctx, zk, admin) + wzeta, _, _, oldConnector, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // deploy a new connector that will become official connector + newConnector, err := k.DeployConnectorZEVM(ctx, wzeta) + require.NoError(t, err) + require.NotEmpty(t, newConnector) + assertContractDeployment(t, sdkk.EvmKeeper, ctx, newConnector) + + // can update the bytecode of the new connector with the old connector contract + _, err = k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + newConnector, + oldConnector, + )) + require.NoError(t, err) + }) + + t.Run("should fail if unauthorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + sample.AccAddress(), + sample.EthAddress(), + sample.EthAddress(), + )) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should fail invalid contract address", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeper(t) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + _, err := k.UpdateContractBytecode(ctx, &types.MsgUpdateContractBytecode{ + Creator: admin, + ContractAddress: "invalid", + NewBytecodeAddress: sample.EthAddress().Hex(), + }) + require.ErrorIs(t, err, sdkerrors.ErrInvalidAddress) + }) + + t.Run("should fail if can't get contract account", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + contractAddr := sample.EthAddress() + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + contractAddr, + ).Return(nil) + + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + contractAddr, + sample.EthAddress(), + )) + require.ErrorIs(t, err, types.ErrContractNotFound) + + mockEVMKeeper.AssertExpectations(t) + }) + + t.Run("should fail neither a zrc20 nor wzeta connector", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + + setAdminDeployFungibleCoin(ctx, zk, admin) + wzeta, _, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // can't update the bytecode of the wzeta contract + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + wzeta, + sample.EthAddress(), + )) + require.ErrorIs(t, err, types.ErrInvalidContract) + }) + + t.Run("should fail if system contract not found", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + + setAdminDeployFungibleCoin(ctx, zk, admin) + _, _, _, connector, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // remove system contract + k.RemoveSystemContract(ctx) + + // can't update the bytecode of the wzeta contract + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + connector, + sample.EthAddress(), + )) + require.ErrorIs(t, err, types.ErrSystemContractNotFound) + }) + + t.Run("should fail if invalid bytecode address", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // set the contract as the connector + contract := sample.EthAddress() + k.SetSystemContract(ctx, types.SystemContract{ + ConnectorZevm: contract.Hex(), + }) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + mock.Anything, + ).Return(&statedb.Account{}) + + _, err := k.UpdateContractBytecode(ctx, &types.MsgUpdateContractBytecode{ + Creator: admin, + ContractAddress: contract.Hex(), + NewBytecodeAddress: "invalid", + }) + + require.ErrorIs(t, err, sdkerrors.ErrInvalidAddress) + + mockEVMKeeper.AssertExpectations(t) + }) + + t.Run("should fail if can't get new bytecode account", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + contractAddr := sample.EthAddress() + newBytecodeAddr := sample.EthAddress() + + // set the contract as the connector + k.SetSystemContract(ctx, types.SystemContract{ + ConnectorZevm: contractAddr.String(), + }) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + contractAddr, + ).Return(&statedb.Account{}) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + newBytecodeAddr, + ).Return(nil) + + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + contractAddr, + newBytecodeAddr, + )) + require.ErrorIs(t, err, types.ErrContractNotFound) + + mockEVMKeeper.AssertExpectations(t) + }) + + t.Run("should fail if can't set account with new bytecode", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + contractAddr := sample.EthAddress() + newBytecodeAddr := sample.EthAddress() + + // set the contract as the connector + k.SetSystemContract(ctx, types.SystemContract{ + ConnectorZevm: contractAddr.String(), + }) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + contractAddr, + ).Return(&statedb.Account{}) + + mockEVMKeeper.On( + "GetAccount", + mock.Anything, + newBytecodeAddr, + ).Return(&statedb.Account{}) + + mockEVMKeeper.On( + "SetAccount", + mock.Anything, + mock.Anything, + mock.Anything, + ).Return(errors.New("can't set account")) + + _, err := k.UpdateContractBytecode(ctx, types.NewMsgUpdateContractBytecode( + admin, + contractAddr, + newBytecodeAddr, + )) + require.ErrorIs(t, err, types.ErrSetBytecode) + + mockEVMKeeper.AssertExpectations(t) + }) +} diff --git a/x/fungible/keeper/msg_server_update_zrc20_paused_status_test.go b/x/fungible/keeper/msg_server_update_zrc20_paused_status_test.go index a6b452747c..cdf27ed943 100644 --- a/x/fungible/keeper/msg_server_update_zrc20_paused_status_test.go +++ b/x/fungible/keeper/msg_server_update_zrc20_paused_status_test.go @@ -3,26 +3,13 @@ package keeper_test import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/require" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/fungible/types" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -func setAdminDeployFungibleCoin(ctx sdk.Context, zk keepertest.ZetaKeepers, admin string) { - zk.ObserverKeeper.SetParams(ctx, observertypes.Params{ - AdminPolicy: []*observertypes.Admin_Policy{ - { - PolicyType: observertypes.Policy_Type_deploy_fungible_coin, - Address: admin, - }, - }, - }) -} - func TestKeeper_UpdateZRC20PausedStatus(t *testing.T) { t.Run("can update the paused status of zrc20", func(t *testing.T) { k, ctx, _, zk := keepertest.FungibleKeeper(t) diff --git a/x/fungible/types/errors.go b/x/fungible/types/errors.go index 64e770b547..5b63632114 100644 --- a/x/fungible/types/errors.go +++ b/x/fungible/types/errors.go @@ -27,6 +27,8 @@ var ( ErrGasPriceNotFound = sdkerrors.Register(ModuleName, 1116, "gas price not found") ErrUpdateNonce = sdkerrors.Register(ModuleName, 1117, "update nonce error") ErrInvalidGasLimit = sdkerrors.Register(ModuleName, 1118, "invalid gas limit") - ErrPausedZRC20 = sdkerrors.Register(ModuleName, 1120, "ZRC20 is paused") - ErrForeignCoinNotFound = sdkerrors.Register(ModuleName, 1121, "foreign coin not found") + ErrSetBytecode = sdkerrors.Register(ModuleName, 1119, "set bytecode error") + ErrInvalidContract = sdkerrors.Register(ModuleName, 1120, "invalid contract") + ErrPausedZRC20 = sdkerrors.Register(ModuleName, 1121, "ZRC20 is paused") + ErrForeignCoinNotFound = sdkerrors.Register(ModuleName, 1122, "foreign coin not found") ) diff --git a/x/fungible/types/expected_keepers.go b/x/fungible/types/expected_keepers.go index fd3b5505f5..46450aab09 100644 --- a/x/fungible/types/expected_keepers.go +++ b/x/fungible/types/expected_keepers.go @@ -7,8 +7,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" + "github.com/evmos/ethermint/x/evm/statedb" evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/common" @@ -63,4 +65,6 @@ type EVMKeeper interface { tracer vm.EVMLogger, commit bool, ) (*evmtypes.MsgEthereumTxResponse, error) + GetAccount(ctx sdk.Context, addr ethcommon.Address) *statedb.Account + SetAccount(ctx sdk.Context, addr ethcommon.Address, account statedb.Account) error } diff --git a/x/fungible/types/message_update_contract_bytecode.go b/x/fungible/types/message_update_contract_bytecode.go new file mode 100644 index 0000000000..a8a10cb5bd --- /dev/null +++ b/x/fungible/types/message_update_contract_bytecode.go @@ -0,0 +1,62 @@ +package types + +import ( + cosmoserror "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ethcommon "github.com/ethereum/go-ethereum/common" +) + +const TypeMsgUpdateContractBytecode = "update_contract_bytecode" + +var _ sdk.Msg = &MsgUpdateContractBytecode{} + +func NewMsgUpdateContractBytecode( + creator string, contractAddress ethcommon.Address, newBytecodeAddress ethcommon.Address, +) *MsgUpdateContractBytecode { + return &MsgUpdateContractBytecode{ + Creator: creator, + ContractAddress: contractAddress.Hex(), + NewBytecodeAddress: newBytecodeAddress.Hex(), + } +} + +func (msg *MsgUpdateContractBytecode) Route() string { + return RouterKey +} + +func (msg *MsgUpdateContractBytecode) Type() string { + return TypeMsgUpdateContractBytecode +} + +func (msg *MsgUpdateContractBytecode) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgUpdateContractBytecode) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgUpdateContractBytecode) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Creator); err != nil { + return cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + // check if the contract address is valid + if !ethcommon.IsHexAddress(msg.ContractAddress) { + return cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", msg.ContractAddress) + } + + // check if the bytecode contract address is valid + if !ethcommon.IsHexAddress(msg.NewBytecodeAddress) { + return cosmoserror.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", msg.ContractAddress) + } + + return nil +} diff --git a/x/fungible/types/message_update_contract_bytecode_test.go b/x/fungible/types/message_update_contract_bytecode_test.go new file mode 100644 index 0000000000..23a1ee2d97 --- /dev/null +++ b/x/fungible/types/message_update_contract_bytecode_test.go @@ -0,0 +1,65 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestMsgUpdateContractBytecode_ValidateBasic(t *testing.T) { + tt := []struct { + name string + msg types.MsgUpdateContractBytecode + wantError bool + }{ + { + name: "valid", + msg: types.MsgUpdateContractBytecode{ + Creator: sample.AccAddress(), + ContractAddress: sample.EthAddress().Hex(), + NewBytecodeAddress: sample.EthAddress().Hex(), + }, + wantError: false, + }, + { + name: "invalid creator", + msg: types.MsgUpdateContractBytecode{ + Creator: "invalid", + ContractAddress: sample.EthAddress().Hex(), + NewBytecodeAddress: sample.EthAddress().Hex(), + }, + wantError: true, + }, + { + name: "invalid contract address", + msg: types.MsgUpdateContractBytecode{ + Creator: sample.AccAddress(), + ContractAddress: "invalid", + NewBytecodeAddress: sample.EthAddress().Hex(), + }, + wantError: true, + }, + { + name: "invalid bytecode address", + msg: types.MsgUpdateContractBytecode{ + Creator: sample.AccAddress(), + ContractAddress: sample.EthAddress().Hex(), + NewBytecodeAddress: "invalid", + }, + wantError: true, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/fungible/types/tx.pb.go b/x/fungible/types/tx.pb.go index c1df08fe31..eafc374a03 100644 --- a/x/fungible/types/tx.pb.go +++ b/x/fungible/types/tx.pb.go @@ -457,6 +457,110 @@ func (m *MsgRemoveForeignCoinResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgRemoveForeignCoinResponse proto.InternalMessageInfo +type MsgUpdateContractBytecode struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + NewBytecodeAddress string `protobuf:"bytes,3,opt,name=new_bytecode_address,json=newBytecodeAddress,proto3" json:"new_bytecode_address,omitempty"` +} + +func (m *MsgUpdateContractBytecode) Reset() { *m = MsgUpdateContractBytecode{} } +func (m *MsgUpdateContractBytecode) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateContractBytecode) ProtoMessage() {} +func (*MsgUpdateContractBytecode) Descriptor() ([]byte, []int) { + return fileDescriptor_197fdedece277fa0, []int{8} +} +func (m *MsgUpdateContractBytecode) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateContractBytecode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateContractBytecode.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateContractBytecode) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateContractBytecode.Merge(m, src) +} +func (m *MsgUpdateContractBytecode) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateContractBytecode) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateContractBytecode.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateContractBytecode proto.InternalMessageInfo + +func (m *MsgUpdateContractBytecode) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgUpdateContractBytecode) GetContractAddress() string { + if m != nil { + return m.ContractAddress + } + return "" +} + +func (m *MsgUpdateContractBytecode) GetNewBytecodeAddress() string { + if m != nil { + return m.NewBytecodeAddress + } + return "" +} + +type MsgUpdateContractBytecodeResponse struct { + NewBytecodeHash []byte `protobuf:"bytes,1,opt,name=new_bytecode_hash,json=newBytecodeHash,proto3" json:"new_bytecode_hash,omitempty"` +} + +func (m *MsgUpdateContractBytecodeResponse) Reset() { *m = MsgUpdateContractBytecodeResponse{} } +func (m *MsgUpdateContractBytecodeResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateContractBytecodeResponse) ProtoMessage() {} +func (*MsgUpdateContractBytecodeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_197fdedece277fa0, []int{9} +} +func (m *MsgUpdateContractBytecodeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateContractBytecodeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateContractBytecodeResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateContractBytecodeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateContractBytecodeResponse.Merge(m, src) +} +func (m *MsgUpdateContractBytecodeResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateContractBytecodeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateContractBytecodeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateContractBytecodeResponse proto.InternalMessageInfo + +func (m *MsgUpdateContractBytecodeResponse) GetNewBytecodeHash() []byte { + if m != nil { + return m.NewBytecodeHash + } + return nil +} + type MsgUpdateZRC20PausedStatus struct { Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` Zrc20Addresses []string `protobuf:"bytes,2,rep,name=zrc20_addresses,json=zrc20Addresses,proto3" json:"zrc20_addresses,omitempty"` @@ -467,7 +571,7 @@ func (m *MsgUpdateZRC20PausedStatus) Reset() { *m = MsgUpdateZRC20Paused func (m *MsgUpdateZRC20PausedStatus) String() string { return proto.CompactTextString(m) } func (*MsgUpdateZRC20PausedStatus) ProtoMessage() {} func (*MsgUpdateZRC20PausedStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_197fdedece277fa0, []int{8} + return fileDescriptor_197fdedece277fa0, []int{10} } func (m *MsgUpdateZRC20PausedStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,7 +628,7 @@ func (m *MsgUpdateZRC20PausedStatusResponse) Reset() { *m = MsgUpdateZRC func (m *MsgUpdateZRC20PausedStatusResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateZRC20PausedStatusResponse) ProtoMessage() {} func (*MsgUpdateZRC20PausedStatusResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_197fdedece277fa0, []int{9} + return fileDescriptor_197fdedece277fa0, []int{11} } func (m *MsgUpdateZRC20PausedStatusResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -563,6 +667,8 @@ func init() { proto.RegisterType((*MsgDeployFungibleCoinZRC20Response)(nil), "zetachain.zetacore.fungible.MsgDeployFungibleCoinZRC20Response") proto.RegisterType((*MsgRemoveForeignCoin)(nil), "zetachain.zetacore.fungible.MsgRemoveForeignCoin") proto.RegisterType((*MsgRemoveForeignCoinResponse)(nil), "zetachain.zetacore.fungible.MsgRemoveForeignCoinResponse") + proto.RegisterType((*MsgUpdateContractBytecode)(nil), "zetachain.zetacore.fungible.MsgUpdateContractBytecode") + proto.RegisterType((*MsgUpdateContractBytecodeResponse)(nil), "zetachain.zetacore.fungible.MsgUpdateContractBytecodeResponse") proto.RegisterType((*MsgUpdateZRC20PausedStatus)(nil), "zetachain.zetacore.fungible.MsgUpdateZRC20PausedStatus") proto.RegisterType((*MsgUpdateZRC20PausedStatusResponse)(nil), "zetachain.zetacore.fungible.MsgUpdateZRC20PausedStatusResponse") } @@ -570,54 +676,59 @@ func init() { func init() { proto.RegisterFile("fungible/tx.proto", fileDescriptor_197fdedece277fa0) } var fileDescriptor_197fdedece277fa0 = []byte{ - // 744 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x4d, 0x4f, 0xdb, 0x4a, - 0x14, 0x8d, 0x09, 0x09, 0xc9, 0x7d, 0x8f, 0xbc, 0x30, 0x2f, 0x02, 0x3f, 0xf3, 0x14, 0x42, 0xa8, - 0x44, 0x54, 0x09, 0x9b, 0xa6, 0x1f, 0xa8, 0x52, 0x3f, 0x04, 0x01, 0x24, 0xa4, 0xa6, 0x42, 0xa6, - 0x51, 0x55, 0x36, 0x96, 0x63, 0x0f, 0xc6, 0x6a, 0xec, 0x89, 0x3c, 0x93, 0x86, 0xb0, 0xeb, 0x96, - 0x15, 0x52, 0xff, 0x47, 0x77, 0xfd, 0x0f, 0x2c, 0xd9, 0x54, 0xaa, 0xba, 0x40, 0x15, 0xfc, 0x91, - 0xca, 0x63, 0xc7, 0x84, 0x0f, 0x27, 0x85, 0x55, 0xe6, 0x4e, 0xe6, 0x9c, 0x7b, 0xce, 0xdc, 0x7b, - 0x3d, 0x30, 0xb5, 0xd7, 0x71, 0x2d, 0xbb, 0xd9, 0xc2, 0x0a, 0x3b, 0x90, 0xdb, 0x1e, 0x61, 0x04, - 0xcd, 0x1e, 0x62, 0xa6, 0x1b, 0xfb, 0xba, 0xed, 0xca, 0x7c, 0x45, 0x3c, 0x2c, 0xf7, 0x4f, 0x49, - 0xff, 0x1a, 0xc4, 0x71, 0x88, 0xab, 0x04, 0x3f, 0x01, 0x42, 0x2a, 0x58, 0xc4, 0x22, 0x7c, 0xa9, - 0xf8, 0xab, 0x60, 0xb7, 0xfc, 0x4d, 0x80, 0xff, 0xea, 0xd4, 0x6a, 0xb4, 0x4d, 0x9d, 0xe1, 0x5d, - 0xb5, 0x56, 0x5d, 0x7e, 0x6f, 0xb3, 0x7d, 0xd3, 0xd3, 0xbb, 0x9b, 0x18, 0x23, 0x11, 0x26, 0x0c, - 0x0f, 0xeb, 0x8c, 0x78, 0xa2, 0x50, 0x12, 0x2a, 0x59, 0xb5, 0x1f, 0xa2, 0x05, 0x98, 0x3c, 0xf4, - 0x8c, 0xea, 0xb2, 0xa6, 0x9b, 0xa6, 0x87, 0x29, 0x15, 0xc7, 0xf8, 0xff, 0x7f, 0xf3, 0xcd, 0xd5, - 0x60, 0x0f, 0x7d, 0x80, 0xbc, 0x8b, 0xbb, 0x5a, 0x37, 0x64, 0xd4, 0xf6, 0x30, 0x16, 0xd3, 0xfe, - 0xb9, 0x35, 0xe5, 0xe4, 0x6c, 0x2e, 0xf1, 0xf3, 0x6c, 0x6e, 0xd1, 0xb2, 0xd9, 0x7e, 0xa7, 0x29, - 0x1b, 0xc4, 0x51, 0x0c, 0x42, 0x1d, 0x42, 0xc3, 0x9f, 0x25, 0x6a, 0x7e, 0x54, 0x58, 0xaf, 0x8d, - 0xa9, 0xdc, 0xb0, 0x5d, 0xa6, 0xe6, 0x5c, 0xdc, 0x1d, 0x50, 0x56, 0x5e, 0x80, 0xf9, 0x58, 0xd9, - 0x2a, 0xa6, 0x6d, 0xe2, 0x52, 0x5c, 0xf6, 0x60, 0x26, 0x3a, 0xb4, 0xd3, 0xa3, 0x0c, 0x3b, 0x35, - 0xe2, 0x32, 0x4f, 0x37, 0xd8, 0x10, 0x67, 0x2f, 0x61, 0xd6, 0x17, 0x4d, 0xf9, 0x79, 0xcd, 0x08, - 0x01, 0xd7, 0x7c, 0x8a, 0x2e, 0xee, 0x5e, 0x65, 0x0c, 0x3d, 0x97, 0xe7, 0x61, 0x2e, 0x26, 0x67, - 0x24, 0xeb, 0x68, 0x0c, 0xa4, 0x3a, 0xb5, 0xd6, 0x71, 0xbb, 0x45, 0x7a, 0x9b, 0x61, 0xd1, 0x6a, - 0xc4, 0x76, 0xb9, 0x91, 0x21, 0xd2, 0x0a, 0x90, 0xda, 0xf0, 0x8f, 0x84, 0x22, 0x82, 0x00, 0x55, - 0x20, 0xbf, 0x47, 0x3c, 0x6c, 0x5b, 0xae, 0xc6, 0x1b, 0x42, 0xb3, 0x4d, 0x31, 0x59, 0x12, 0x2a, - 0x49, 0x35, 0x17, 0xee, 0xd7, 0xfc, 0xed, 0x2d, 0x13, 0x49, 0x90, 0x31, 0xb1, 0x61, 0x3b, 0x7a, - 0x8b, 0x8a, 0xe3, 0x25, 0xa1, 0x32, 0xa9, 0x46, 0x31, 0x42, 0x30, 0xee, 0xea, 0x0e, 0x16, 0x53, - 0x9c, 0x9a, 0xaf, 0xd1, 0x34, 0xa4, 0x69, 0xcf, 0x69, 0x92, 0x56, 0x50, 0x35, 0x35, 0x8c, 0xd0, - 0x12, 0x64, 0x0d, 0x62, 0xbb, 0x9a, 0x5f, 0x1f, 0x71, 0xa2, 0x24, 0x54, 0x72, 0xd5, 0xbc, 0x1c, - 0x36, 0x9b, 0xef, 0xe3, 0x5d, 0xaf, 0x8d, 0xd5, 0x8c, 0x11, 0xae, 0xd0, 0x2c, 0x64, 0x2d, 0x9d, - 0x6a, 0x2d, 0xdb, 0xb1, 0x99, 0x98, 0xe1, 0xca, 0x32, 0x96, 0x4e, 0xdf, 0xf8, 0x71, 0xf9, 0x01, - 0x94, 0xe3, 0xef, 0x22, 0xba, 0xb2, 0x75, 0x28, 0xd4, 0xa9, 0xa5, 0x62, 0x87, 0x7c, 0xc2, 0x9b, - 0xa1, 0x29, 0x62, 0xbb, 0x43, 0xee, 0xaa, 0xef, 0x67, 0xec, 0xd2, 0x4f, 0xb9, 0x08, 0xff, 0xdf, - 0xc6, 0x12, 0x65, 0xf9, 0x2a, 0xf0, 0xc2, 0x0c, 0x74, 0xd5, 0xb6, 0xde, 0xa1, 0xd8, 0xdc, 0x61, - 0x3a, 0xeb, 0xd0, 0x21, 0xc9, 0x16, 0xe1, 0x9f, 0x2b, 0xd3, 0x80, 0xfd, 0x3e, 0x49, 0x56, 0xb2, - 0x6a, 0x6e, 0x70, 0x1e, 0x30, 0x45, 0x75, 0x48, 0xeb, 0x06, 0xb3, 0x89, 0xcb, 0x2b, 0x94, 0xab, - 0x3e, 0x95, 0x87, 0xcc, 0xb1, 0x1c, 0x08, 0x19, 0xd4, 0xb0, 0xca, 0xc1, 0x6a, 0x48, 0x12, 0x5e, - 0x5e, 0x8c, 0xde, 0xbe, 0xad, 0x87, 0x55, 0x10, 0xe3, 0x98, 0x50, 0x16, 0x52, 0xdb, 0xab, 0x8d, - 0x9d, 0x8d, 0x7c, 0x02, 0xfd, 0x05, 0x13, 0x8d, 0xb7, 0x41, 0x20, 0x54, 0xbf, 0xa7, 0x20, 0x59, - 0xa7, 0x16, 0xfa, 0x22, 0xc0, 0x4c, 0x5c, 0xa3, 0xae, 0x0c, 0x15, 0x1f, 0x5f, 0x55, 0xe9, 0xf5, - 0x3d, 0x81, 0x7d, 0x47, 0xe8, 0xb3, 0x00, 0x53, 0x37, 0x9b, 0xe1, 0xd1, 0x28, 0xda, 0x1b, 0x10, - 0xe9, 0xf9, 0x9d, 0x21, 0x91, 0x86, 0x23, 0x01, 0x0a, 0xb7, 0x7e, 0x5a, 0x9e, 0x8c, 0xe2, 0xbc, - 0x0d, 0x25, 0xbd, 0xb8, 0x0f, 0x2a, 0x12, 0x73, 0x2c, 0xc0, 0x74, 0xcc, 0x37, 0xfc, 0xd9, 0x9f, - 0x11, 0x5f, 0xc7, 0x49, 0xaf, 0xee, 0x87, 0x8b, 0x24, 0xf9, 0x9d, 0x13, 0x37, 0x49, 0x2b, 0x77, - 0xe0, 0x1e, 0x04, 0x8e, 0xee, 0x9c, 0x11, 0xb3, 0xb0, 0xb6, 0x75, 0x72, 0x5e, 0x14, 0x4e, 0xcf, - 0x8b, 0xc2, 0xaf, 0xf3, 0xa2, 0x70, 0x7c, 0x51, 0x4c, 0x9c, 0x5e, 0x14, 0x13, 0x3f, 0x2e, 0x8a, - 0x89, 0x5d, 0x65, 0xe0, 0x29, 0xf2, 0xa9, 0x97, 0x78, 0x16, 0xa5, 0x9f, 0x45, 0x39, 0x50, 0x2e, - 0x5f, 0x61, 0xff, 0x5d, 0x6a, 0xa6, 0xf9, 0x0b, 0xfa, 0xf8, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xc4, 0xe2, 0x45, 0x29, 0x9e, 0x07, 0x00, 0x00, + // 831 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4d, 0x6f, 0xdb, 0x36, + 0x18, 0xb6, 0xe2, 0xc6, 0x89, 0xdf, 0xb5, 0x8e, 0xc3, 0x19, 0xad, 0xa6, 0x0c, 0x4e, 0xaa, 0x0e, + 0xa8, 0x57, 0x20, 0x52, 0xe6, 0x7d, 0x14, 0x03, 0xf6, 0x81, 0xc4, 0x6d, 0xb0, 0x02, 0xf3, 0x56, + 0x28, 0x33, 0x86, 0xf5, 0x22, 0xd0, 0x12, 0x23, 0x0b, 0xb3, 0x48, 0x43, 0xa4, 0xe7, 0xba, 0xb7, + 0x5d, 0x7b, 0x2a, 0xb6, 0xff, 0xb1, 0xdb, 0xfe, 0x43, 0x8f, 0x3d, 0x0e, 0x3b, 0x14, 0x43, 0x72, + 0xd9, 0xcf, 0x28, 0x44, 0x7d, 0x54, 0x76, 0x2c, 0x3b, 0xcd, 0x49, 0x7c, 0xe9, 0xf7, 0x7d, 0xf8, + 0x3c, 0xe4, 0xf3, 0xd2, 0x84, 0xed, 0xd3, 0x31, 0xf5, 0xfc, 0xfe, 0x90, 0x98, 0xe2, 0xa9, 0x31, + 0x0a, 0x99, 0x60, 0x68, 0xe7, 0x19, 0x11, 0xd8, 0x19, 0x60, 0x9f, 0x1a, 0x72, 0xc4, 0x42, 0x62, + 0xa4, 0x59, 0xda, 0xfb, 0x0e, 0x0b, 0x02, 0x46, 0xcd, 0xf8, 0x13, 0x57, 0x68, 0x0d, 0x8f, 0x79, + 0x4c, 0x0e, 0xcd, 0x68, 0x14, 0xcf, 0xea, 0x7f, 0x2b, 0xf0, 0x41, 0x97, 0x7b, 0xbd, 0x91, 0x8b, + 0x05, 0x79, 0x62, 0x75, 0xda, 0x07, 0x3f, 0xfb, 0x62, 0xe0, 0x86, 0x78, 0x72, 0x4c, 0x08, 0x52, + 0x61, 0xc3, 0x09, 0x09, 0x16, 0x2c, 0x54, 0x95, 0x3d, 0xa5, 0x55, 0xb5, 0xd2, 0x10, 0xdd, 0x81, + 0x1b, 0xcf, 0x42, 0xa7, 0x7d, 0x60, 0x63, 0xd7, 0x0d, 0x09, 0xe7, 0xea, 0x9a, 0xfc, 0xfd, 0xba, + 0x9c, 0x3c, 0x8c, 0xe7, 0xd0, 0x2f, 0x50, 0xa7, 0x64, 0x62, 0x4f, 0x12, 0x44, 0xfb, 0x94, 0x10, + 0xb5, 0x12, 0xe5, 0x1d, 0x99, 0x2f, 0x5f, 0xef, 0x96, 0xfe, 0x7d, 0xbd, 0x7b, 0xd7, 0xf3, 0xc5, + 0x60, 0xdc, 0x37, 0x1c, 0x16, 0x98, 0x0e, 0xe3, 0x01, 0xe3, 0xc9, 0x67, 0x9f, 0xbb, 0xbf, 0x9a, + 0x62, 0x3a, 0x22, 0xdc, 0xe8, 0xf9, 0x54, 0x58, 0x35, 0x4a, 0x26, 0x39, 0x66, 0xfa, 0x1d, 0xb8, + 0x5d, 0x48, 0xdb, 0x22, 0x7c, 0xc4, 0x28, 0x27, 0x7a, 0x08, 0xb7, 0xb2, 0xa4, 0x93, 0x29, 0x17, + 0x24, 0xe8, 0x30, 0x2a, 0x42, 0xec, 0x88, 0x25, 0xca, 0xbe, 0x86, 0x9d, 0x88, 0x34, 0x97, 0xf9, + 0xb6, 0x93, 0x14, 0xcc, 0xe9, 0x54, 0x29, 0x99, 0xcc, 0x22, 0x26, 0x9a, 0xf5, 0xdb, 0xb0, 0x5b, + 0xb0, 0x66, 0x46, 0xeb, 0xf9, 0x1a, 0x68, 0x5d, 0xee, 0x3d, 0x20, 0xa3, 0x21, 0x9b, 0x1e, 0x27, + 0x87, 0xd6, 0x61, 0x3e, 0x95, 0x42, 0x96, 0x50, 0x6b, 0xc0, 0xfa, 0xc3, 0x28, 0x25, 0x21, 0x11, + 0x07, 0xa8, 0x05, 0xf5, 0x53, 0x16, 0x12, 0xdf, 0xa3, 0xb6, 0x34, 0x84, 0xed, 0xbb, 0x6a, 0x79, + 0x4f, 0x69, 0x95, 0xad, 0x5a, 0x32, 0xdf, 0x89, 0xa6, 0x1f, 0xb9, 0x48, 0x83, 0x4d, 0x97, 0x38, + 0x7e, 0x80, 0x87, 0x5c, 0xbd, 0xb6, 0xa7, 0xb4, 0x6e, 0x58, 0x59, 0x8c, 0x10, 0x5c, 0xa3, 0x38, + 0x20, 0xea, 0xba, 0x84, 0x96, 0x63, 0x74, 0x13, 0x2a, 0x7c, 0x1a, 0xf4, 0xd9, 0x30, 0x3e, 0x35, + 0x2b, 0x89, 0xd0, 0x3e, 0x54, 0x1d, 0xe6, 0x53, 0x3b, 0x3a, 0x1f, 0x75, 0x63, 0x4f, 0x69, 0xd5, + 0xda, 0x75, 0x23, 0x31, 0x5b, 0xa4, 0xe3, 0xa7, 0xe9, 0x88, 0x58, 0x9b, 0x4e, 0x32, 0x42, 0x3b, + 0x50, 0xf5, 0x30, 0xb7, 0x87, 0x7e, 0xe0, 0x0b, 0x75, 0x53, 0x32, 0xdb, 0xf4, 0x30, 0xff, 0x3e, + 0x8a, 0xf5, 0x8f, 0x40, 0x2f, 0xde, 0x8b, 0x6c, 0xcb, 0x1e, 0x40, 0xa3, 0xcb, 0x3d, 0x8b, 0x04, + 0xec, 0x37, 0x72, 0x9c, 0x88, 0x62, 0x3e, 0x5d, 0xb2, 0x57, 0xa9, 0x9e, 0xb5, 0xb7, 0x7a, 0xf4, + 0x26, 0x7c, 0xb8, 0x08, 0x25, 0x5b, 0xe5, 0x8f, 0x7c, 0x33, 0xa4, 0xc7, 0x76, 0x34, 0x15, 0xc4, + 0x61, 0xee, 0xb2, 0x66, 0xf8, 0x18, 0xea, 0x05, 0x3e, 0xd9, 0x72, 0x66, 0xed, 0x81, 0x0e, 0xa0, + 0x11, 0xb9, 0xab, 0x9f, 0x80, 0x66, 0xe9, 0x65, 0x99, 0x8e, 0x28, 0x99, 0xa4, 0xeb, 0xa5, 0x86, + 0xfa, 0x31, 0xe7, 0xf4, 0x79, 0x4e, 0x29, 0x73, 0x74, 0x0f, 0xb6, 0x67, 0x60, 0x07, 0x98, 0x0f, + 0x24, 0xcb, 0xeb, 0xd6, 0x56, 0x0e, 0xf3, 0x3b, 0xcc, 0x07, 0xfa, 0x5f, 0x8a, 0xb4, 0x5f, 0xae, + 0x77, 0x1e, 0xe3, 0x31, 0x27, 0xee, 0x89, 0xc0, 0x62, 0xcc, 0x97, 0xc8, 0xbc, 0x0b, 0x5b, 0x33, + 0x3d, 0x4f, 0x22, 0x95, 0xe5, 0x56, 0xd5, 0xaa, 0xe5, 0xbb, 0x9e, 0x70, 0xd4, 0x85, 0x0a, 0x76, + 0x84, 0xcf, 0xa8, 0x94, 0x55, 0x6b, 0x7f, 0x6e, 0x2c, 0xb9, 0xad, 0x8c, 0x98, 0x48, 0x9e, 0xc3, + 0xa1, 0x2c, 0xb6, 0x12, 0x90, 0xc4, 0x22, 0x05, 0x7c, 0xd3, 0x2d, 0xb8, 0xd7, 0x06, 0xb5, 0x08, + 0x09, 0x55, 0x61, 0xfd, 0xf1, 0x61, 0xef, 0xe4, 0x61, 0xbd, 0x84, 0xde, 0x83, 0x8d, 0xde, 0x0f, + 0x71, 0xa0, 0xb4, 0xff, 0xaf, 0x40, 0xb9, 0xcb, 0x3d, 0xf4, 0xa7, 0x02, 0xb7, 0x8a, 0xda, 0xf1, + 0xfe, 0x52, 0xf2, 0xc5, 0xde, 0xd5, 0xbe, 0xbd, 0x62, 0x61, 0x76, 0xa8, 0xbf, 0x2b, 0xb0, 0x7d, + 0xd1, 0xf2, 0x9f, 0xac, 0x82, 0xbd, 0x50, 0xa2, 0x7d, 0xf9, 0xce, 0x25, 0x19, 0x87, 0xe7, 0x0a, + 0x34, 0x16, 0x5e, 0xa0, 0x9f, 0xad, 0xc2, 0x5c, 0x54, 0xa5, 0x7d, 0x75, 0x95, 0xaa, 0x8c, 0xcc, + 0x0b, 0x05, 0x6e, 0x16, 0xfc, 0x53, 0x7d, 0x71, 0x39, 0xe0, 0xf9, 0x3a, 0xed, 0x9b, 0xab, 0xd5, + 0x2d, 0xa0, 0x74, 0xe1, 0xbe, 0xb8, 0x24, 0xa5, 0xf9, 0xba, 0xcb, 0x52, 0x2a, 0xbc, 0x0b, 0x22, + 0x33, 0x17, 0x35, 0xf7, 0xfd, 0x77, 0x90, 0x9b, 0x2f, 0x5c, 0x6d, 0xe6, 0x15, 0xed, 0x79, 0xf4, + 0xe8, 0xe5, 0x59, 0x53, 0x79, 0x75, 0xd6, 0x54, 0xfe, 0x3b, 0x6b, 0x2a, 0x2f, 0xce, 0x9b, 0xa5, + 0x57, 0xe7, 0xcd, 0xd2, 0x3f, 0xe7, 0xcd, 0xd2, 0x13, 0x33, 0xf7, 0x06, 0x88, 0xa0, 0xf7, 0xe5, + 0x2a, 0x66, 0xba, 0x8a, 0xf9, 0xd4, 0x7c, 0xfb, 0xfc, 0x89, 0x1e, 0x04, 0xfd, 0x8a, 0x7c, 0xba, + 0x7c, 0xfa, 0x26, 0x00, 0x00, 0xff, 0xff, 0x05, 0x67, 0x8a, 0xaa, 0x17, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -636,6 +747,7 @@ type MsgClient interface { RemoveForeignCoin(ctx context.Context, in *MsgRemoveForeignCoin, opts ...grpc.CallOption) (*MsgRemoveForeignCoinResponse, error) UpdateSystemContract(ctx context.Context, in *MsgUpdateSystemContract, opts ...grpc.CallOption) (*MsgUpdateSystemContractResponse, error) UpdateZRC20WithdrawFee(ctx context.Context, in *MsgUpdateZRC20WithdrawFee, opts ...grpc.CallOption) (*MsgUpdateZRC20WithdrawFeeResponse, error) + UpdateContractBytecode(ctx context.Context, in *MsgUpdateContractBytecode, opts ...grpc.CallOption) (*MsgUpdateContractBytecodeResponse, error) UpdateZRC20PausedStatus(ctx context.Context, in *MsgUpdateZRC20PausedStatus, opts ...grpc.CallOption) (*MsgUpdateZRC20PausedStatusResponse, error) } @@ -683,6 +795,15 @@ func (c *msgClient) UpdateZRC20WithdrawFee(ctx context.Context, in *MsgUpdateZRC return out, nil } +func (c *msgClient) UpdateContractBytecode(ctx context.Context, in *MsgUpdateContractBytecode, opts ...grpc.CallOption) (*MsgUpdateContractBytecodeResponse, error) { + out := new(MsgUpdateContractBytecodeResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.fungible.Msg/UpdateContractBytecode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *msgClient) UpdateZRC20PausedStatus(ctx context.Context, in *MsgUpdateZRC20PausedStatus, opts ...grpc.CallOption) (*MsgUpdateZRC20PausedStatusResponse, error) { out := new(MsgUpdateZRC20PausedStatusResponse) err := c.cc.Invoke(ctx, "/zetachain.zetacore.fungible.Msg/UpdateZRC20PausedStatus", in, out, opts...) @@ -698,6 +819,7 @@ type MsgServer interface { RemoveForeignCoin(context.Context, *MsgRemoveForeignCoin) (*MsgRemoveForeignCoinResponse, error) UpdateSystemContract(context.Context, *MsgUpdateSystemContract) (*MsgUpdateSystemContractResponse, error) UpdateZRC20WithdrawFee(context.Context, *MsgUpdateZRC20WithdrawFee) (*MsgUpdateZRC20WithdrawFeeResponse, error) + UpdateContractBytecode(context.Context, *MsgUpdateContractBytecode) (*MsgUpdateContractBytecodeResponse, error) UpdateZRC20PausedStatus(context.Context, *MsgUpdateZRC20PausedStatus) (*MsgUpdateZRC20PausedStatusResponse, error) } @@ -717,6 +839,9 @@ func (*UnimplementedMsgServer) UpdateSystemContract(ctx context.Context, req *Ms func (*UnimplementedMsgServer) UpdateZRC20WithdrawFee(ctx context.Context, req *MsgUpdateZRC20WithdrawFee) (*MsgUpdateZRC20WithdrawFeeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateZRC20WithdrawFee not implemented") } +func (*UnimplementedMsgServer) UpdateContractBytecode(ctx context.Context, req *MsgUpdateContractBytecode) (*MsgUpdateContractBytecodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateContractBytecode not implemented") +} func (*UnimplementedMsgServer) UpdateZRC20PausedStatus(ctx context.Context, req *MsgUpdateZRC20PausedStatus) (*MsgUpdateZRC20PausedStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateZRC20PausedStatus not implemented") } @@ -797,6 +922,24 @@ func _Msg_UpdateZRC20WithdrawFee_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Msg_UpdateContractBytecode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateContractBytecode) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateContractBytecode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.fungible.Msg/UpdateContractBytecode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateContractBytecode(ctx, req.(*MsgUpdateContractBytecode)) + } + return interceptor(ctx, in, info, handler) +} + func _Msg_UpdateZRC20PausedStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgUpdateZRC20PausedStatus) if err := dec(in); err != nil { @@ -835,6 +978,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateZRC20WithdrawFee", Handler: _Msg_UpdateZRC20WithdrawFee_Handler, }, + { + MethodName: "UpdateContractBytecode", + Handler: _Msg_UpdateContractBytecode_Handler, + }, { MethodName: "UpdateZRC20PausedStatus", Handler: _Msg_UpdateZRC20PausedStatus_Handler, @@ -1128,6 +1275,80 @@ func (m *MsgRemoveForeignCoinResponse) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *MsgUpdateContractBytecode) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateContractBytecode) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateContractBytecode) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewBytecodeAddress) > 0 { + i -= len(m.NewBytecodeAddress) + copy(dAtA[i:], m.NewBytecodeAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewBytecodeAddress))) + i-- + dAtA[i] = 0x1a + } + if len(m.ContractAddress) > 0 { + i -= len(m.ContractAddress) + copy(dAtA[i:], m.ContractAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateContractBytecodeResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateContractBytecodeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateContractBytecodeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewBytecodeHash) > 0 { + i -= len(m.NewBytecodeHash) + copy(dAtA[i:], m.NewBytecodeHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewBytecodeHash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *MsgUpdateZRC20PausedStatus) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1332,6 +1553,40 @@ func (m *MsgRemoveForeignCoinResponse) Size() (n int) { return n } +func (m *MsgUpdateContractBytecode) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ContractAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.NewBytecodeAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgUpdateContractBytecodeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.NewBytecodeHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + func (m *MsgUpdateZRC20PausedStatus) Size() (n int) { if m == nil { return 0 @@ -2199,6 +2454,236 @@ func (m *MsgRemoveForeignCoinResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgUpdateContractBytecode) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateContractBytecode: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateContractBytecode: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewBytecodeAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NewBytecodeAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateContractBytecodeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateContractBytecodeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateContractBytecodeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewBytecodeHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NewBytecodeHash = append(m.NewBytecodeHash[:0], dAtA[iNdEx:postIndex]...) + if m.NewBytecodeHash == nil { + m.NewBytecodeHash = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *MsgUpdateZRC20PausedStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 From bc0e26d3888088c369c5fa77a9bf8604f825abe7 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 21 Sep 2023 11:29:19 +0200 Subject: [PATCH 7/8] feat(`crosschain`): general improvements for gas payments and revert txs (#1064) * pay gas on revert * fix gas limit * update smoke test * make generate * add revert gas limit note * fix out amount from gas payment calculation * add queryWithdrawalFee method * implement pay gas native * fix non-existing module account * add conditional burning of the fees * fix smoke test btc amount * use Zeta coin for CLI integration tests * add protocol gas fee and gas limit queries * use gas limit and gas price in PayGasNative * uncomment smoke tests * fix unpack * experiment integration tests fix * fix no error check * set addresses back * fix erorr undefined * fix mocks * change error messages * comments * improve crosschain testkeeper * fix gas price native, remove burning * add test for pay gas native * goimports * test for PayGasInZetaAndUpdateCctx * change test message * refactor file naming * improve system contract naming * add make mocks * fix gas payment tests * get zrc20 from asset * implement CallUniswapV2RouterSwapExactTokenForETH * Implement PayGasInERC20AndUpdateCctx * use cosmoserror * add approve * goimports * add success test * improve error messaging * implement test error cases * refund amount * goimports * use specific error for no liquidity pool * use input amount * smoke test commented * goimport * fix unit test * complete smoke test * add sender to erc20 cctx * use pool path * update mocks * update post tx gas limit * fix evm panic call * add back all smoke test * goimports * fix undefined error * fix coin 2 --------- Co-authored-by: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> --- app/app.go | 2 +- .../localnet/orchestrator/smoketest/main.go | 3 + .../smoketest/test_crosschain_swap.go | 4 +- .../smoketest/test_deposit_eth.go | 42 +- .../smoketest/test_erc20_refund.go | 200 +++++ docs/spec/crosschain/messages.md | 4 +- go.mod | 5 +- go.sum | 123 +-- testutil/keeper/crosschain.go | 36 +- testutil/keeper/fungible.go | 30 +- testutil/keeper/mocks/crosschain/fungible.go | 228 ++++- testutil/network/network_config.go | 1 + x/crosschain/client/cli/cli_cctx.go | 20 +- .../client/integrationtests/cli_helpers.go | 14 +- .../integrationtests/inbound_voter_test.go | 16 +- .../integrationtests/outbound_voter_test.go | 26 +- x/crosschain/genesis_test.go | 2 +- x/crosschain/keeper/abci_test.go | 2 +- x/crosschain/keeper/cctx_utils.go | 87 ++ x/crosschain/keeper/cctx_utils_test.go | 140 +++ x/crosschain/keeper/evm_hooks.go | 9 +- x/crosschain/keeper/gas_payment.go | 352 ++++++++ x/crosschain/keeper/gas_payment_test.go | 802 ++++++++++++++++++ .../grpc_query_in_tx_hash_to_cctx_test.go | 6 +- .../keeper/in_tx_hash_to_cctx_test.go | 6 +- .../keeper_cross_chain_tx_vote_inbound_tx.go | 71 +- .../keeper_cross_chain_tx_vote_outbound_tx.go | 22 +- .../keeper/keeper_out_tx_tracker_test.go | 6 +- x/crosschain/keeper/keeper_tss_voter.go | 9 + x/crosschain/keeper/keeper_utils.go | 143 ---- x/crosschain/keeper/zeta_conversion_rate.go | 2 +- x/crosschain/module.go | 9 +- x/crosschain/types/cctx_utils.go | 18 +- x/crosschain/types/cctx_utils_test.go | 52 ++ x/crosschain/types/errors.go | 54 +- x/crosschain/types/expected_keepers.go | 33 +- ...blocker_deploy_system_contracts_privnet.go | 6 +- x/fungible/keeper/deposits.go | 26 +- x/fungible/keeper/evm.go | 107 ++- x/fungible/keeper/foreign_coins.go | 12 + x/fungible/keeper/foreign_coins_test.go | 113 +++ x/fungible/keeper/system_contract.go | 445 +++++++++- x/observer/types/core_params_testnet.go | 7 +- zetaclient/evm_client.go | 18 +- zetaclient/tx.go | 2 +- 45 files changed, 2874 insertions(+), 441 deletions(-) create mode 100644 contrib/localnet/orchestrator/smoketest/test_erc20_refund.go create mode 100644 x/crosschain/keeper/cctx_utils.go create mode 100644 x/crosschain/keeper/cctx_utils_test.go create mode 100644 x/crosschain/keeper/gas_payment.go create mode 100644 x/crosschain/keeper/gas_payment_test.go delete mode 100644 x/crosschain/keeper/keeper_utils.go create mode 100644 x/crosschain/types/cctx_utils_test.go diff --git a/app/app.go b/app/app.go index 42c2cc6d20..53bfee51cd 100644 --- a/app/app.go +++ b/app/app.go @@ -464,7 +464,7 @@ func New( groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, interfaceRegistry), evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, evmSs), feemarket.NewAppModule(app.FeeMarketKeeper, feeSs), - zetaCoreModule.NewAppModule(appCodec, app.ZetaCoreKeeper, app.StakingKeeper), + zetaCoreModule.NewAppModule(appCodec, app.ZetaCoreKeeper, app.StakingKeeper, app.AccountKeeper), zetaObserverModule.NewAppModule(appCodec, *app.ZetaObserverKeeper, app.AccountKeeper, app.BankKeeper), fungibleModule.NewAppModule(appCodec, app.FungibleKeeper, app.AccountKeeper, app.BankKeeper), emissionsModule.NewAppModule(appCodec, app.EmissionsKeeper, app.AccountKeeper), diff --git a/contrib/localnet/orchestrator/smoketest/main.go b/contrib/localnet/orchestrator/smoketest/main.go index 09f307de7c..44607b3c22 100644 --- a/contrib/localnet/orchestrator/smoketest/main.go +++ b/contrib/localnet/orchestrator/smoketest/main.go @@ -300,6 +300,9 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { smokeTest.TestPauseZRC20() smokeTest.CheckZRC20ReserveAndSupply() + smokeTest.TestERC20DepositAndCallRefund() + smokeTest.CheckZRC20ReserveAndSupply() + smokeTest.TestUpdateBytecode() smokeTest.CheckZRC20ReserveAndSupply() diff --git a/contrib/localnet/orchestrator/smoketest/test_crosschain_swap.go b/contrib/localnet/orchestrator/smoketest/test_crosschain_swap.go index d4e5c5c604..7e40cb8084 100644 --- a/contrib/localnet/orchestrator/smoketest/test_crosschain_swap.go +++ b/contrib/localnet/orchestrator/smoketest/test_crosschain_swap.go @@ -170,7 +170,8 @@ func (sm *SmokeTest) TestCrosschainSwap() { memo = append(sm.ZEVMSwapAppAddr.Bytes(), memo...) fmt.Printf("memo length %d\n", len(memo)) - txid, err := SendToTSSFromDeployerWithMemo(BTCTSSAddress, 0.001, utxos[0:2], sm.btcRPCClient, memo) + amount := 0.1 + txid, err := SendToTSSFromDeployerWithMemo(BTCTSSAddress, amount, utxos[0:2], sm.btcRPCClient, memo) fmt.Printf("Sent BTC to TSS txid %s; now mining 10 blocks for confirmation\n", txid) _, err = sm.btcRPCClient.GenerateToAddress(10, BTCDeployerAddress, nil) if err != nil { @@ -182,6 +183,7 @@ func (sm *SmokeTest) TestCrosschainSwap() { fmt.Printf(" inboudn tx hash %s\n", cctx.InboundTxParams.InboundTxObservedHash) fmt.Printf(" status %s\n", cctx.CctxStatus.Status.String()) fmt.Printf(" status msg: %s\n", cctx.CctxStatus.StatusMessage) + if cctx.CctxStatus.Status != types.CctxStatus_Reverted { panic(fmt.Sprintf("expected reverted status; got %s", cctx.CctxStatus.Status.String())) } diff --git a/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go b/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go index cea789d273..2a02176ada 100644 --- a/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go +++ b/contrib/localnet/orchestrator/smoketest/test_deposit_eth.go @@ -194,12 +194,17 @@ func (sm *SmokeTest) TestDepositAndCallRefund() { if err != nil { panic(err) } - value := big.NewInt(100000000000000000) // in wei (1 eth) - gasLimit := uint64(23000) // in units + + // in wei (10 eth) + value := big.NewInt(1e18) + value = value.Mul(value, big.NewInt(10)) + + gasLimit := uint64(23000) // in units gasPrice, err := goerliClient.SuggestGasPrice(context.Background()) if err != nil { panic(err) } + data := append(sm.BTCZRC20Addr.Bytes(), []byte("hello sailors")...) // this data tx := ethtypes.NewTransaction(nonce, TSSAddress, value, gasLimit, gasPrice, data) chainID, err := goerliClient.NetworkID(context.Background()) @@ -232,6 +237,7 @@ func (sm *SmokeTest) TestDepositAndCallRefund() { fmt.Printf("cctx status message: %s", cctx.CctxStatus.StatusMessage) revertTxHash := cctx.GetCurrentOutTxParam().OutboundTxHash fmt.Printf("GOERLI revert tx receipt: status %d\n", receipt.Status) + tx, _, err := sm.goerliClient.TransactionByHash(context.Background(), ethcommon.HexToHash(revertTxHash)) if err != nil { panic(err) @@ -240,13 +246,41 @@ func (sm *SmokeTest) TestDepositAndCallRefund() { if err != nil { panic(err) } - if cctx.CctxStatus.Status != types.CctxStatus_Reverted || receipt.Status == 0 || *tx.To() != DeployerAddress || tx.Value().Cmp(value) != 0 { + + printTxInfo := func() { // debug info when test fails fmt.Printf(" tx: %+v\n", tx) fmt.Printf(" receipt: %+v\n", receipt) fmt.Printf("cctx http://localhost:1317/zeta-chain/crosschain/cctx/%s\n", cctx.Index) - panic(fmt.Sprintf("expected cctx status PendingRevert; got %s", cctx.CctxStatus.Status)) } + + if cctx.CctxStatus.Status != types.CctxStatus_Reverted { + printTxInfo() + panic(fmt.Sprintf("expected cctx status to be PendingRevert; got %s", cctx.CctxStatus.Status)) + } + + if receipt.Status == 0 { + printTxInfo() + panic("expected the revert tx receipt to have status 1; got 0") + } + + if *tx.To() != DeployerAddress { + printTxInfo() + panic(fmt.Sprintf("expected tx to %s; got %s", DeployerAddress.Hex(), tx.To().Hex())) + } + + // the received value must be lower than the original value because of the paid fees for the revert tx + // we check that the value is still greater than 0 + if tx.Value().Cmp(value) != -1 || tx.Value().Cmp(big.NewInt(0)) != 1 { + printTxInfo() + panic(fmt.Sprintf("expected tx value %s; should be non-null and lower than %s", tx.Value().String(), value.String())) + } + + fmt.Printf("REVERT tx receipt: %d\n", receipt.Status) + fmt.Printf(" tx hash: %s\n", receipt.TxHash.String()) + fmt.Printf(" to: %s\n", tx.To().String()) + fmt.Printf(" value: %s\n", tx.Value().String()) + fmt.Printf(" block num: %d\n", receipt.BlockNumber) }() } diff --git a/contrib/localnet/orchestrator/smoketest/test_erc20_refund.go b/contrib/localnet/orchestrator/smoketest/test_erc20_refund.go new file mode 100644 index 0000000000..e8d5686313 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/test_erc20_refund.go @@ -0,0 +1,200 @@ +//go:build PRIVNET +// +build PRIVNET + +package main + +import ( + "context" + "errors" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func (sm *SmokeTest) TestERC20DepositAndCallRefund() { + startTime := time.Now() + defer func() { + fmt.Printf("test finishes in %s\n", time.Since(startTime)) + }() + LoudPrintf("Deposit a non-gas ZRC20 into ZEVM and call a contract that reverts; should refund on ZetaChain if no liquidity pool, should refund on origin if liquidity pool\n") + + // Get the initial balance of the deployer + initialBal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + + fmt.Println("Sending a deposit that should revert without a liquidity pool makes the cctx aborted") + + amount := big.NewInt(1e4) + + // send the deposit + inTxHash, err := sm.sendInvalidUSDTDeposit(amount) + if err != nil { + panic(err) + } + + // There is no liquidity pool, therefore the cctx should abort + cctx := WaitCctxMinedByInTxHash(inTxHash, sm.cctxClient) + if cctx.CctxStatus.Status != types.CctxStatus_Aborted { + panic(fmt.Sprintf("expected cctx status to be Aborted; got %s", cctx.CctxStatus.Status)) + } + + // Check that the erc20 in the aborted cctx was refunded on ZetaChain + newBalance, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + expectedBalance := initialBal.Add(initialBal, amount) + if newBalance.Cmp(expectedBalance) != 0 { + panic(fmt.Sprintf("expected balance to be %s after refund; got %s", expectedBalance.String(), newBalance.String())) + } + fmt.Println("CCTX has been aborted and the erc20 has been refunded on ZetaChain") + + amount = big.NewInt(1e7) + goerliBalance, err := sm.USDTERC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + + fmt.Println("Sending a deposit that should revert with a liquidity pool") + + fmt.Println("Creating the liquidity pool USTD/ZETA") + err = sm.createZetaERC20LiquidityPool() + if err != nil { + panic(err) + } + fmt.Println("Liquidity pool created") + + // send the deposit + inTxHash, err = sm.sendInvalidUSDTDeposit(amount) + if err != nil { + panic(err) + } + + // there is a liquidity pool, therefore the cctx should revert + cctx = WaitCctxMinedByInTxHash(inTxHash, sm.cctxClient) + + // the revert tx creation will fail because the sender, used as the recipient, is not defined in the cctx + if cctx.CctxStatus.Status != types.CctxStatus_Reverted { + panic(fmt.Sprintf("expected cctx status to be PendingRevert; got %s", cctx.CctxStatus.Status)) + } + + // get revert tx + revertTxHash := cctx.GetCurrentOutTxParam().OutboundTxHash + _, _, err = sm.goerliClient.TransactionByHash(context.Background(), ethcommon.HexToHash(revertTxHash)) + if err != nil { + panic(err) + } + receipt, err := sm.goerliClient.TransactionReceipt(context.Background(), ethcommon.HexToHash(revertTxHash)) + if err != nil { + panic(err) + } + if receipt.Status == 0 { + panic("expected the revert tx receipt to have status 1; got 0") + } + + // check that the erc20 in the reverted cctx was refunded on Goerli + newGoerliBalance, err := sm.USDTERC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + // the new balance must be higher than the previous one because of the revert refund + if goerliBalance.Cmp(newGoerliBalance) != -1 { + panic(fmt.Sprintf("expected balance to be higher than %s after refund; got %s", goerliBalance.String(), newGoerliBalance.String())) + } + // it must also be lower than the previous balance + the amount because of the gas fee for the revert tx + balancePlusAmount := goerliBalance.Add(goerliBalance, amount) + if newGoerliBalance.Cmp(balancePlusAmount) != -1 { + panic(fmt.Sprintf("expected balance to be lower than %s after refund; got %s", balancePlusAmount.String(), newGoerliBalance.String())) + } + + fmt.Println("ERC20 CCTX successfully reverted") + fmt.Println("\tbalance before refund: ", goerliBalance.String()) + fmt.Println("\tamount: ", amount.String()) + fmt.Println("\tbalance after refund: ", newGoerliBalance.String()) +} + +func (sm *SmokeTest) createZetaERC20LiquidityPool() error { + amount := big.NewInt(1e10) + txHash := sm.DepositERC20(amount, []byte{}) + WaitCctxMinedByInTxHash(txHash.Hex(), sm.cctxClient) + + tx, err := sm.USDTZRC20.Approve(sm.zevmAuth, sm.UniswapV2RouterAddr, big.NewInt(1e10)) + if err != nil { + return err + } + receipt := MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status == 0 { + return errors.New("approve failed") + } + + previousValue := sm.zevmAuth.Value + sm.zevmAuth.Value = big.NewInt(1e10) + tx, err = sm.UniswapV2Router.AddLiquidityETH( + sm.zevmAuth, + sm.USDTZRC20Addr, + amount, + BigZero, + BigZero, + DeployerAddress, + big.NewInt(time.Now().Add(10*time.Minute).Unix()), + ) + sm.zevmAuth.Value = previousValue + if err != nil { + return err + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status == 0 { + return errors.New("add liquidity failed") + } + + return nil +} + +func (sm *SmokeTest) sendInvalidUSDTDeposit(amount *big.Int) (string, error) { + // send the tx + USDT := sm.USDTERC20 + tx, err := USDT.Mint(sm.goerliAuth, amount) + if err != nil { + return "", err + } + receipt := MustWaitForTxReceipt(sm.goerliClient, tx) + fmt.Printf("Mint receipt tx hash: %s\n", tx.Hash().Hex()) + + tx, err = USDT.Approve(sm.goerliAuth, sm.ERC20CustodyAddr, amount) + if err != nil { + return "", err + } + receipt = MustWaitForTxReceipt(sm.goerliClient, tx) + fmt.Printf("USDT Approve receipt tx hash: %s\n", tx.Hash().Hex()) + + tx, err = sm.ERC20Custody.Deposit( + sm.goerliAuth, + DeployerAddress.Bytes(), + sm.USDTERC20Addr, + amount, + []byte("this is an invalid msg that will cause the contract to revert"), + ) + if err != nil { + return "", err + } + + fmt.Printf("GOERLI tx sent: %s; to %s, nonce %d\n", tx.Hash().String(), tx.To().Hex(), tx.Nonce()) + receipt = MustWaitForTxReceipt(sm.goerliClient, tx) + if receipt.Status == 0 { + return "", errors.New("expected the tx receipt to have status 1; got 0") + } + fmt.Printf("GOERLI tx receipt: %d\n", receipt.Status) + fmt.Printf(" tx hash: %s\n", receipt.TxHash.String()) + fmt.Printf(" to: %s\n", tx.To().String()) + fmt.Printf(" value: %d\n", tx.Value()) + fmt.Printf(" block num: %d\n", receipt.BlockNumber) + + return tx.Hash().Hex(), nil +} diff --git a/docs/spec/crosschain/messages.md b/docs/spec/crosschain/messages.md index a64c725032..ba1161d149 100644 --- a/docs/spec/crosschain/messages.md +++ b/docs/spec/crosschain/messages.md @@ -84,7 +84,7 @@ message MsgNonceVoter { ## MsgVoteOnObservedOutboundTx -Casts a vote on an outbound transaction observed on a connected chain (after +VoteOnObservedOutboundTx casts a vote on an outbound transaction observed on a connected chain (after it has been broadcasted to and finalized on a connected chain). If this is the first vote, a new ballot is created. When a threshold of votes is reached, the ballot is finalized. When a ballot is finalized, the outbound @@ -145,7 +145,7 @@ message MsgVoteOnObservedOutboundTx { ## MsgVoteOnObservedInboundTx -Casts a vote on an inbound transaction observed on a connected chain. If this +VoteOnObservedInboundTx casts a vote on an inbound transaction observed on a connected chain. If this is the first vote, a new ballot is created. When a threshold of votes is reached, the ballot is finalized. When a ballot is finalized, a new CCTX is created. diff --git a/go.mod b/go.mod index cc29fa1ce0..2ac6cf2de1 100644 --- a/go.mod +++ b/go.mod @@ -187,7 +187,7 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect @@ -197,8 +197,6 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipns v0.3.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipld/go-ipld-prime v0.20.0 // indirect @@ -217,7 +215,6 @@ require ( github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p v0.27.8 github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-core v0.20.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect diff --git a/go.sum b/go.sum index 9a52b53dcc..741d11222e 100644 --- a/go.sum +++ b/go.sum @@ -690,7 +690,6 @@ github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -780,7 +779,6 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= @@ -1033,7 +1031,6 @@ github.com/cosmos/ibc-go/v6 v6.1.0 h1:o7oXws2vKkKfOFzJI+oNylRn44PCNt5wzHd/zKQKbv github.com/cosmos/ibc-go/v6 v6.1.0/go.mod h1:CY3zh2HLfetRiW8LY6kVHMATe90Wj/UOoY8T6cuB0is= github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= -github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -1070,13 +1067,10 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0/go.mod h1:d0H8xGMWbiIQP7gN3v2rByWUcuZPm9YsgmnfoxgbINc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= @@ -1089,10 +1083,8 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= @@ -1244,7 +1236,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -1317,7 +1308,6 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -1569,8 +1559,6 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= -github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -1617,8 +1605,8 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/goreleaser/goreleaser v0.136.0/go.mod h1:wiKrPUeSNh6Wu8nUHxZydSOVQ/OZvOaO7DTtFqie904= @@ -1775,8 +1763,6 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= -github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= @@ -1817,37 +1803,21 @@ github.com/informalsystems/tm-load-test v1.3.0/go.mod h1:OQ5AQ9TbT5hKWBNIwsMjn6B github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= -github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= -github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= -github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= -github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipns v0.2.0 h1:BgmNtQhqOw5XEZ8RAfWEpK4DhqaYiuP6h71MhIp7xXU= -github.com/ipfs/go-ipns v0.2.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24= -github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= -github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= @@ -1867,7 +1837,6 @@ github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5D github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= @@ -1950,7 +1919,6 @@ github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiD github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -1972,18 +1940,12 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= @@ -2036,40 +1998,23 @@ github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= -github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.27.8 h1:IX5x/4yKwyPQeVS2AXHZ3J4YATM9oHBGH1gBc23jBAI= github.com/libp2p/go-libp2p v0.27.8/go.mod h1:eCFFtd0s5i/EVKR7+5Ki8bM7qwkNW3TPTTSSW9sz8NE= -github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.20.0 h1:PGKM74+T+O/FaZNARNW32i90RMBHCcgd/hkum2UQ5eY= -github.com/libp2p/go-libp2p-core v0.20.0/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= -github.com/libp2p/go-libp2p-kad-dht v0.18.0 h1:akqO3gPMwixR7qFSFq70ezRun97g5hrA/lBW9jrjUYM= -github.com/libp2p/go-libp2p-kad-dht v0.18.0/go.mod h1:Gb92MYIPm3K2pJLGn8wl0m8wiKDvHrYpg+rOd0GzzPA= github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= -github.com/libp2p/go-libp2p-kbucket v0.4.7 h1:spZAcgxifvFZHBD8tErvppbnNiKA5uokDu3CV7axu70= -github.com/libp2p/go-libp2p-kbucket v0.4.7/go.mod h1:XyVo99AfQH0foSf176k4jY1xUJ2+jUJIZCSDm7r2YKk= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= -github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= -github.com/libp2p/go-libp2p-peerstore v0.8.0 h1:bzTG693TA1Ju/zKmUCQzDLSqiJnyRFVwPpuloZ/OZtI= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= -github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= @@ -2077,10 +2022,6 @@ github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= github.com/libp2p/go-reuseport v0.3.0 h1:iiZslO5byUYZEg9iCwJGf5h+sf1Agmqx2V2FDjPyvUw= github.com/libp2p/go-reuseport v0.3.0/go.mod h1:laea40AimhtfEqysZ71UpYj4S+R9VpH8PgqLo7L+SwI= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= @@ -2152,8 +2093,6 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -2194,8 +2133,6 @@ github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= -github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -2215,9 +2152,6 @@ github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLT github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= @@ -2288,9 +2222,7 @@ github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinK github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= @@ -2298,47 +2230,28 @@ github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2 github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= -github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= -github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= -github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= -github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= -github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= -github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= -github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -2411,8 +2324,6 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -2431,7 +2342,6 @@ github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+t github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -2553,8 +2463,6 @@ github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUI github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= @@ -2584,7 +2492,6 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= @@ -2646,8 +2553,6 @@ github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraN github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= -github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= @@ -2774,13 +2679,11 @@ github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvR github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= @@ -2795,7 +2698,6 @@ github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34c github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -2876,7 +2778,6 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -2983,7 +2884,6 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -3019,12 +2919,10 @@ github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= @@ -3170,17 +3068,13 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= -go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= -go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= @@ -3265,8 +3159,6 @@ golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -3345,7 +3237,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -3488,7 +3379,6 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -3658,7 +3548,6 @@ golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -3675,8 +3564,6 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -3692,8 +3579,6 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3711,8 +3596,6 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -3862,8 +3745,6 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -4351,8 +4232,6 @@ k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= diff --git a/testutil/keeper/crosschain.go b/testutil/keeper/crosschain.go index c8bb95e435..f96dc7e87c 100644 --- a/testutil/keeper/crosschain.go +++ b/testutil/keeper/crosschain.go @@ -8,11 +8,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" tmdb "github.com/tendermint/tm-db" - crosschainmocks "github.com/zeta-chain/zetacore/testutil/keeper/mocks/crosschain" "github.com/zeta-chain/zetacore/x/crosschain/keeper" "github.com/zeta-chain/zetacore/x/crosschain/types" - fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" ) type CrosschainMockOptions struct { @@ -35,7 +33,10 @@ var ( ) // CrosschainKeeper initializes a crosschain keeper for testing purposes with option to mock specific keepers -func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) (*keeper.Keeper, sdk.Context) { +func CrosschainKeeperWithMocks( + t testing.TB, + mockOptions CrosschainMockOptions, +) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { storeKey := sdk.NewKVStoreKey(types.StoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) @@ -47,14 +48,30 @@ func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) // Create regular keepers sdkKeepers := NewSDKKeepers(cdc, db, stateStore) - // Create observer keeper - var observerKeeper types.ZetaObserverKeeper = initObserverKeeper( + // Create zeta keepers + observerKeeperTmp := initObserverKeeper( cdc, db, stateStore, sdkKeepers.StakingKeeper, sdkKeepers.ParamsKeeper, ) + fungiblekeeperTmp := initFungibleKeeper( + cdc, + db, + stateStore, + sdkKeepers.ParamsKeeper, + sdkKeepers.AuthKeeper, + sdkKeepers.BankKeeper, + sdkKeepers.EvmKeeper, + observerKeeperTmp, + ) + zetaKeepers := ZetaKeepers{ + ObserverKeeper: observerKeeperTmp, + FungibleKeeper: fungiblekeeperTmp, + } + var observerKeeper types.ZetaObserverKeeper = observerKeeperTmp + var fungibleKeeper types.FungibleKeeper = fungiblekeeperTmp // Create the fungible keeper stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) @@ -65,6 +82,7 @@ func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) // Initialize modules genesis sdkKeepers.InitGenesis(ctx) + zetaKeepers.InitGenesis(ctx) // Add a proposer to the context ctx = sdkKeepers.InitBlockProposer(t, ctx) @@ -73,7 +91,6 @@ func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) var authKeeper types.AccountKeeper = sdkKeepers.AuthKeeper var bankKeeper types.BankKeeper = sdkKeepers.BankKeeper var stakingKeeper types.StakingKeeper = sdkKeepers.StakingKeeper - var fungibleKeeper types.FungibleKeeper = &fungiblekeeper.Keeper{} if mockOptions.UseAccountMock { authKeeper = crosschainmocks.NewCrosschainAccountKeeper(t) } @@ -102,16 +119,17 @@ func CrosschainKeeperWithMocks(t testing.TB, mockOptions CrosschainMockOptions) fungibleKeeper, ) - return k, ctx + return k, ctx, sdkKeepers, zetaKeepers } // CrosschainKeeperAllMocks initializes a crosschain keeper for testing purposes with all mocks func CrosschainKeeperAllMocks(t testing.TB) (*keeper.Keeper, sdk.Context) { - return CrosschainKeeperWithMocks(t, CrosschainMocksAll) + k, ctx, _, _ := CrosschainKeeperWithMocks(t, CrosschainMocksAll) + return k, ctx } // CrosschainKeeper initializes a crosschain keeper for testing purposes -func CrosschainKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { +func CrosschainKeeper(t testing.TB) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { return CrosschainKeeperWithMocks(t, CrosschainNoMocks) } diff --git a/testutil/keeper/fungible.go b/testutil/keeper/fungible.go index fe9df11be8..6f26a2733e 100644 --- a/testutil/keeper/fungible.go +++ b/testutil/keeper/fungible.go @@ -3,13 +3,14 @@ package keeper import ( "testing" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" tmdb "github.com/tendermint/tm-db" - fungiblemocks "github.com/zeta-chain/zetacore/testutil/keeper/mocks/fungible" fungiblemodule "github.com/zeta-chain/zetacore/x/fungible" "github.com/zeta-chain/zetacore/x/fungible/keeper" @@ -33,6 +34,33 @@ var ( FungibleNoMocks = FungibleMockOptions{} ) +func initFungibleKeeper( + cdc codec.Codec, + db *tmdb.MemDB, + ss store.CommitMultiStore, + paramKeeper paramskeeper.Keeper, + authKeeper types.AccountKeeper, + bankKeepr types.BankKeeper, + evmKeeper types.EVMKeeper, + observerKeeper types.ObserverKeeper, +) *keeper.Keeper { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + memKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, db) + + return keeper.NewKeeper( + cdc, + storeKey, + memKey, + paramKeeper.Subspace(types.ModuleName), + authKeeper, + evmKeeper, + bankKeepr, + observerKeeper, + ) +} + // FungibleKeeperWithMocks initializes a fungible keeper for testing purposes with option to mock specific keepers func FungibleKeeperWithMocks(t testing.TB, mockOptions FungibleMockOptions) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { storeKey := sdk.NewKVStoreKey(types.StoreKey) diff --git a/testutil/keeper/mocks/crosschain/fungible.go b/testutil/keeper/mocks/crosschain/fungible.go index ccd55ffa06..a6b763b8a3 100644 --- a/testutil/keeper/mocks/crosschain/fungible.go +++ b/testutil/keeper/mocks/crosschain/fungible.go @@ -22,8 +22,8 @@ type CrosschainFungibleKeeper struct { mock.Mock } -// CallUniswapv2RouterSwapExactETHForToken provides a mock function with given fields: ctx, sender, to, amountIn, outZRC4, noEthereumTxEvent -func (_m *CrosschainFungibleKeeper) CallUniswapv2RouterSwapExactETHForToken(ctx types.Context, sender common.Address, to common.Address, amountIn *big.Int, outZRC4 common.Address, noEthereumTxEvent bool) ([]*big.Int, error) { +// CallUniswapV2RouterSwapExactETHForToken provides a mock function with given fields: ctx, sender, to, amountIn, outZRC4, noEthereumTxEvent +func (_m *CrosschainFungibleKeeper) CallUniswapV2RouterSwapExactETHForToken(ctx types.Context, sender common.Address, to common.Address, amountIn *big.Int, outZRC4 common.Address, noEthereumTxEvent bool) ([]*big.Int, error) { ret := _m.Called(ctx, sender, to, amountIn, outZRC4, noEthereumTxEvent) var r0 []*big.Int @@ -48,6 +48,46 @@ func (_m *CrosschainFungibleKeeper) CallUniswapv2RouterSwapExactETHForToken(ctx return r0, r1 } +// CallUniswapV2RouterSwapExactTokensForTokens provides a mock function with given fields: ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent +func (_m *CrosschainFungibleKeeper) CallUniswapV2RouterSwapExactTokensForTokens(ctx types.Context, sender common.Address, to common.Address, amountIn *big.Int, inZRC4 common.Address, outZRC4 common.Address, noEthereumTxEvent bool) ([]*big.Int, error) { + ret := _m.Called(ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent) + + var r0 []*big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, *big.Int, common.Address, common.Address, bool) ([]*big.Int, error)); ok { + return rf(ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent) + } + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, *big.Int, common.Address, common.Address, bool) []*big.Int); ok { + r0 = rf(ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, common.Address, common.Address, *big.Int, common.Address, common.Address, bool) error); ok { + r1 = rf(ctx, sender, to, amountIn, inZRC4, outZRC4, noEthereumTxEvent) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CallZRC20Approve provides a mock function with given fields: ctx, owner, zrc20address, spender, amount, noEthereumTxEvent +func (_m *CrosschainFungibleKeeper) CallZRC20Approve(ctx types.Context, owner common.Address, zrc20address common.Address, spender common.Address, amount *big.Int, noEthereumTxEvent bool) error { + ret := _m.Called(ctx, owner, zrc20address, spender, amount, noEthereumTxEvent) + + var r0 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, common.Address, *big.Int, bool) error); ok { + r0 = rf(ctx, owner, zrc20address, spender, amount, noEthereumTxEvent) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // CallZRC20Burn provides a mock function with given fields: ctx, sender, zrc20address, amount, noEthereumTxEvent func (_m *CrosschainFungibleKeeper) CallZRC20Burn(ctx types.Context, sender common.Address, zrc20address common.Address, amount *big.Int, noEthereumTxEvent bool) error { ret := _m.Called(ctx, sender, zrc20address, amount, noEthereumTxEvent) @@ -102,6 +142,32 @@ func (_m *CrosschainFungibleKeeper) DepositCoinZeta(ctx types.Context, to common return r0 } +// DepositZRC20 provides a mock function with given fields: ctx, contract, to, amount +func (_m *CrosschainFungibleKeeper) DepositZRC20(ctx types.Context, contract common.Address, to common.Address, amount *big.Int) (*evmtypes.MsgEthereumTxResponse, error) { + ret := _m.Called(ctx, contract, to, amount) + + var r0 *evmtypes.MsgEthereumTxResponse + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, *big.Int) (*evmtypes.MsgEthereumTxResponse, error)); ok { + return rf(ctx, contract, to, amount) + } + if rf, ok := ret.Get(0).(func(types.Context, common.Address, common.Address, *big.Int) *evmtypes.MsgEthereumTxResponse); ok { + r0 = rf(ctx, contract, to, amount) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evmtypes.MsgEthereumTxResponse) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, common.Address, common.Address, *big.Int) error); ok { + r1 = rf(ctx, contract, to, amount) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // FundGasStabilityPool provides a mock function with given fields: ctx, chainID, amount func (_m *CrosschainFungibleKeeper) FundGasStabilityPool(ctx types.Context, chainID int64, amount *big.Int) error { ret := _m.Called(ctx, chainID, amount) @@ -148,6 +214,30 @@ func (_m *CrosschainFungibleKeeper) GetAllForeignCoinsForChain(ctx types.Context return r0 } +// GetForeignCoinFromAsset provides a mock function with given fields: ctx, asset, chainID +func (_m *CrosschainFungibleKeeper) GetForeignCoinFromAsset(ctx types.Context, asset string, chainID int64) (fungibletypes.ForeignCoins, bool) { + ret := _m.Called(ctx, asset, chainID) + + var r0 fungibletypes.ForeignCoins + var r1 bool + if rf, ok := ret.Get(0).(func(types.Context, string, int64) (fungibletypes.ForeignCoins, bool)); ok { + return rf(ctx, asset, chainID) + } + if rf, ok := ret.Get(0).(func(types.Context, string, int64) fungibletypes.ForeignCoins); ok { + r0 = rf(ctx, asset, chainID) + } else { + r0 = ret.Get(0).(fungibletypes.ForeignCoins) + } + + if rf, ok := ret.Get(1).(func(types.Context, string, int64) bool); ok { + r1 = rf(ctx, asset, chainID) + } else { + r1 = ret.Get(1).(bool) + } + + return r0, r1 +} + // GetForeignCoins provides a mock function with given fields: ctx, zrc20Addr func (_m *CrosschainFungibleKeeper) GetForeignCoins(ctx types.Context, zrc20Addr string) (fungibletypes.ForeignCoins, bool) { ret := _m.Called(ctx, zrc20Addr) @@ -196,6 +286,84 @@ func (_m *CrosschainFungibleKeeper) GetSystemContract(ctx types.Context) (fungib return r0, r1 } +// GetUniswapV2Router02Address provides a mock function with given fields: ctx +func (_m *CrosschainFungibleKeeper) GetUniswapV2Router02Address(ctx types.Context) (common.Address, error) { + ret := _m.Called(ctx) + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(types.Context) (common.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(types.Context) common.Address); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(types.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryGasLimit provides a mock function with given fields: ctx, contract +func (_m *CrosschainFungibleKeeper) QueryGasLimit(ctx types.Context, contract common.Address) (*big.Int, error) { + ret := _m.Called(ctx, contract) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address) (*big.Int, error)); ok { + return rf(ctx, contract) + } + if rf, ok := ret.Get(0).(func(types.Context, common.Address) *big.Int); ok { + r0 = rf(ctx, contract) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, common.Address) error); ok { + r1 = rf(ctx, contract) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryProtocolFlatFee provides a mock function with given fields: ctx, contract +func (_m *CrosschainFungibleKeeper) QueryProtocolFlatFee(ctx types.Context, contract common.Address) (*big.Int, error) { + ret := _m.Called(ctx, contract) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, common.Address) (*big.Int, error)); ok { + return rf(ctx, contract) + } + if rf, ok := ret.Get(0).(func(types.Context, common.Address) *big.Int); ok { + r0 = rf(ctx, contract) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, common.Address) error); ok { + r1 = rf(ctx, contract) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // QuerySystemContractGasCoinZRC20 provides a mock function with given fields: ctx, chainID func (_m *CrosschainFungibleKeeper) QuerySystemContractGasCoinZRC20(ctx types.Context, chainID *big.Int) (common.Address, error) { ret := _m.Called(ctx, chainID) @@ -222,8 +390,60 @@ func (_m *CrosschainFungibleKeeper) QuerySystemContractGasCoinZRC20(ctx types.Co return r0, r1 } -// QueryUniswapv2RouterGetAmountsIn provides a mock function with given fields: ctx, amountOut, outZRC4 -func (_m *CrosschainFungibleKeeper) QueryUniswapv2RouterGetAmountsIn(ctx types.Context, amountOut *big.Int, outZRC4 common.Address) (*big.Int, error) { +// QueryUniswapV2RouterGetZRC4AmountsIn provides a mock function with given fields: ctx, amountOut, inZRC4 +func (_m *CrosschainFungibleKeeper) QueryUniswapV2RouterGetZRC4AmountsIn(ctx types.Context, amountOut *big.Int, inZRC4 common.Address) (*big.Int, error) { + ret := _m.Called(ctx, amountOut, inZRC4) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, *big.Int, common.Address) (*big.Int, error)); ok { + return rf(ctx, amountOut, inZRC4) + } + if rf, ok := ret.Get(0).(func(types.Context, *big.Int, common.Address) *big.Int); ok { + r0 = rf(ctx, amountOut, inZRC4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, *big.Int, common.Address) error); ok { + r1 = rf(ctx, amountOut, inZRC4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn provides a mock function with given fields: ctx, amountOut, inZRC4, outZRC4 +func (_m *CrosschainFungibleKeeper) QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx types.Context, amountOut *big.Int, inZRC4 common.Address, outZRC4 common.Address) (*big.Int, error) { + ret := _m.Called(ctx, amountOut, inZRC4, outZRC4) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, *big.Int, common.Address, common.Address) (*big.Int, error)); ok { + return rf(ctx, amountOut, inZRC4, outZRC4) + } + if rf, ok := ret.Get(0).(func(types.Context, *big.Int, common.Address, common.Address) *big.Int); ok { + r0 = rf(ctx, amountOut, inZRC4, outZRC4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, *big.Int, common.Address, common.Address) error); ok { + r1 = rf(ctx, amountOut, inZRC4, outZRC4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryUniswapV2RouterGetZetaAmountsIn provides a mock function with given fields: ctx, amountOut, outZRC4 +func (_m *CrosschainFungibleKeeper) QueryUniswapV2RouterGetZetaAmountsIn(ctx types.Context, amountOut *big.Int, outZRC4 common.Address) (*big.Int, error) { ret := _m.Called(ctx, amountOut, outZRC4) var r0 *big.Int diff --git a/testutil/network/network_config.go b/testutil/network/network_config.go index 29391739af..2aabd219e1 100644 --- a/testutil/network/network_config.go +++ b/testutil/network/network_config.go @@ -24,6 +24,7 @@ import ( // genesis and single validator. All other parameters are inherited from cosmos-sdk/testutil/network.DefaultConfig func DefaultConfig() Config { encoding := app.MakeEncodingConfig() + return Config{ Codec: encoding.Codec, TxConfig: encoding.TxConfig, diff --git a/x/crosschain/client/cli/cli_cctx.go b/x/crosschain/client/cli/cli_cctx.go index 1a701c8416..058233bb77 100644 --- a/x/crosschain/client/cli/cli_cctx.go +++ b/x/crosschain/client/cli/cli_cctx.go @@ -99,14 +99,23 @@ func CmdCCTXInboundVoter() *cobra.Command { } amount := math.NewUintFromString(args[5]) + argsMessage := args[6] argsInTxHash := args[7] + argsInBlockHeight, err := strconv.ParseUint(args[8], 10, 64) - argsCoinType := common.CoinType(common.CoinType_value[args[9]]) - argsAsset := args[10] if err != nil { return err } + + coinType, ok := common.CoinType_value[args[9]] + if !ok { + return fmt.Errorf("wrong coin type %s", args[9]) + } + argsCoinType := common.CoinType(coinType) + + argsAsset := args[10] + clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err @@ -189,7 +198,12 @@ func CmdCCTXOutboundVoter() *cobra.Command { return err } - argsCoinType := common.CoinType(common.CoinType_value[args[10]]) + coinType, ok := common.CoinType_value[args[10]] + if !ok { + return fmt.Errorf("wrong coin type %s", args[10]) + } + argsCoinType := common.CoinType(coinType) + clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err diff --git a/x/crosschain/client/integrationtests/cli_helpers.go b/x/crosschain/client/integrationtests/cli_helpers.go index 0cad26f293..06a3198b1d 100644 --- a/x/crosschain/client/integrationtests/cli_helpers.go +++ b/x/crosschain/client/integrationtests/cli_helpers.go @@ -27,12 +27,6 @@ import ( "github.com/zeta-chain/zetacore/x/crosschain/client/cli" ) -func MsgVoteOnObservedInboundTxExec(clientCtx client.Context, chain, obsType fmt.Stringer, extraArgs ...string) (testutil.BufferWriter, error) { - args := []string{chain.String(), obsType.String()} - args = append(args, extraArgs...) - return clitestutil.ExecTestCLICmd(clientCtx, cli.CmdCCTXInboundVoter(), args) -} - func TxSignExec(clientCtx client.Context, from fmt.Stringer, filename string, extraArgs ...string) (testutil.BufferWriter, error) { args := []string{ fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest), @@ -142,7 +136,7 @@ func BuildSignedOutboundVote(t testing.TB, val *network.Validator, denom string, status, strconv.FormatInt(common.GoerliChain().ChainId, 10), "1", - "Gas", + "Zeta", } txArgs := []string{ fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), @@ -173,7 +167,7 @@ func BuildSignedInboundVote(t testing.TB, val *network.Validator, denom string, message, "0x19398991572a825894b34b904ac1e3692720895351466b5c9e6bb7ae1e21d680", "100", - "Gas", + "Zeta", "", } txArgs := []string{ @@ -205,7 +199,7 @@ func GetBallotIdentifier(message string) string { "0x19398991572a825894b34b904ac1e3692720895351466b5c9e6bb7ae1e21d680", 100, 250_000, - common.CoinType_Gas, + common.CoinType_Zeta, "", ) return msg.Digest() @@ -224,7 +218,7 @@ func GetBallotIdentifierOutBound(cctxindex, outtxHash, valueReceived string) str 0, common.GoerliChain().ChainId, 1, - common.CoinType_Gas, + common.CoinType_Zeta, ) return msg.Digest() } diff --git a/x/crosschain/client/integrationtests/inbound_voter_test.go b/x/crosschain/client/integrationtests/inbound_voter_test.go index c78b990199..6305295b2a 100644 --- a/x/crosschain/client/integrationtests/inbound_voter_test.go +++ b/x/crosschain/client/integrationtests/inbound_voter_test.go @@ -129,8 +129,12 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { test := test s.Run(test.name, func() { broadcaster := s.network.Validators[0] + + // Vote the gas price for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) + s.Require().NoError(err) + var account authtypes.AccountI s.NoError(val.ClientCtx.Codec.UnmarshalInterfaceJSON(out.Bytes(), &account)) signedTx := BuildSignedGasPriceVote(s.T(), val, s.cfg.BondDenom, account) @@ -138,8 +142,12 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Vote the tss for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) + s.Require().NoError(err) + var account authtypes.AccountI s.NoError(val.ClientCtx.Codec.UnmarshalInterfaceJSON(out.Bytes(), &account)) signedTx := BuildSignedTssVote(s.T(), val, s.cfg.BondDenom, account) @@ -147,6 +155,8 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Vote the inbound tx for _, val := range s.network.Validators { vote := test.votes[val.Address.String()] if vote == observerTypes.VoteType_NotYetVoted { @@ -164,14 +174,16 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } - s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Get the ballot ballotIdentifier := GetBallotIdentifier(test.name) out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observerCli.CmdBallotByIdentifier(), []string{ballotIdentifier, "--output", "json"}) s.Require().NoError(err) ballot := observerTypes.QueryBallotByIdentifierResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &ballot)) + // Check the vote in the ballot s.Assert().Equal(len(test.votes), len(ballot.Voters)) for _, vote := range ballot.Voters { if test.votes[vote.VoterAddress] == observerTypes.VoteType_FailureObservation { @@ -182,6 +194,7 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { } s.Assert().Equal(test.ballotResult, ballot.BallotStatus) + // Get the cctx and check its status cctxIdentifier := ballotIdentifier if test.falseBallotIdentifier != "" { cctxIdentifier = test.falseBallotIdentifier @@ -189,7 +202,6 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschainCli.CmdShowSend(), []string{cctxIdentifier, "--output", "json"}) cctx := crosschaintypes.QueryGetCctxResponse{} if test.cctxStatus == crosschaintypes.CctxStatus_PendingRevert { - s.Require().Error(err) s.Require().Contains(out.String(), "not found") } else { s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &cctx)) diff --git a/x/crosschain/client/integrationtests/outbound_voter_test.go b/x/crosschain/client/integrationtests/outbound_voter_test.go index 54c7c83605..7671708295 100644 --- a/x/crosschain/client/integrationtests/outbound_voter_test.go +++ b/x/crosschain/client/integrationtests/outbound_voter_test.go @@ -122,6 +122,8 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { test := test s.Run(test.name, func() { broadcaster := s.network.Validators[0] + + // Vote the gas price for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) var account authtypes.AccountI @@ -131,6 +133,8 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Vote the tss for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) var account authtypes.AccountI @@ -140,6 +144,8 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Vote the inbound tx for _, val := range s.network.Validators { out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) var account authtypes.AccountI @@ -149,14 +155,16 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } - s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Get the ballot cctxIdentifier := GetBallotIdentifier(test.name) out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschainCli.CmdShowSend(), []string{cctxIdentifier, "--output", "json"}) cctx := crosschaintypes.QueryGetCctxResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &cctx)) s.Assert().Equal(crosschaintypes.CctxStatus_PendingOutbound, cctx.CrossChainTx.CctxStatus.Status) + // Check the vote in the ballot and vote the outbound tx fakeVotes := []string{} for _, val := range s.network.Validators { valVote := Vote{} @@ -171,6 +179,7 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) var account authtypes.AccountI s.NoError(val.ClientCtx.Codec.UnmarshalInterfaceJSON(out.Bytes(), &account)) + outTxhash := test.name if valVote.isFakeVote { outTxhash = outTxhash + "falseVote" @@ -184,21 +193,27 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { votestring = "1" } + // Vote the outbound tx signedTx := BuildSignedOutboundVote(s.T(), val, s.cfg.BondDenom, account, cctxIdentifier, outTxhash, test.valueReceived, votestring) out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) + + // Get the cctx out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschainCli.CmdShowSend(), []string{cctxIdentifier, "--output", "json"}) cctx = crosschaintypes.QueryGetCctxResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &cctx)) s.Assert().Equal(test.cctxStatus, cctx.CrossChainTx.CctxStatus.Status) + outboundBallotIdentifier := GetBallotIdentifierOutBound(cctxIdentifier, test.name, test.valueReceived) + out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observerCli.CmdBallotByIdentifier(), []string{outboundBallotIdentifier, "--output", "json"}) s.Require().NoError(err) ballot := observerTypes.QueryBallotByIdentifierResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &ballot)) + // Check the votes s.Require().Equal(test.correctBallotResult, ballot.BallotStatus) for _, vote := range test.votes { for _, ballotvote := range ballot.Voters { @@ -220,18 +235,15 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &fakeBallot)) for _, vote := range test.votes { if vote.isFakeVote { - for _, ballotvote := range fakeBallot.Voters { - if vote.voterAddress == ballotvote.VoterAddress { - s.Assert().Equal(vote.voteType, ballotvote.VoteType) + for _, ballotVote := range fakeBallot.Voters { + if vote.voterAddress == ballotVote.VoterAddress { + s.Assert().Equal(vote.voteType, ballotVote.VoteType) break } } } } - } - }) - } } diff --git a/x/crosschain/genesis_test.go b/x/crosschain/genesis_test.go index af745a938d..994c83f67a 100644 --- a/x/crosschain/genesis_test.go +++ b/x/crosschain/genesis_test.go @@ -48,7 +48,7 @@ func TestGenesis(t *testing.T) { } // Init and export - k, ctx := keepertest.CrosschainKeeper(t) + k, ctx, _, _ := keepertest.CrosschainKeeper(t) crosschain.InitGenesis(ctx, *k, genesisState) got := crosschain.ExportGenesis(ctx, *k) require.NotNil(t, got) diff --git a/x/crosschain/keeper/abci_test.go b/x/crosschain/keeper/abci_test.go index 374f307f73..1a8e484a1d 100644 --- a/x/crosschain/keeper/abci_test.go +++ b/x/crosschain/keeper/abci_test.go @@ -205,7 +205,7 @@ func TestKeeper_CheckAndUpdateCctxGasPrice(t *testing.T) { } func TestKeeper_IncreaseCctxGasPrice(t *testing.T) { - k, ctx := testkeeper.CrosschainKeeper(t) + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) t.Run("can increase gas", func(t *testing.T) { // sample cctx diff --git a/x/crosschain/keeper/cctx_utils.go b/x/crosschain/keeper/cctx_utils.go new file mode 100644 index 0000000000..2333cf7add --- /dev/null +++ b/x/crosschain/keeper/cctx_utils.go @@ -0,0 +1,87 @@ +package keeper + +import ( + "errors" + "fmt" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/crosschain/types" + zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// UpdateNonce sets the CCTX outbound nonce to the next nonce, and updates the nonce of blockchain state. +// It also updates the PendingNonces that is used to track the unfulfilled outbound txs. +func (k Keeper) UpdateNonce(ctx sdk.Context, receiveChainID int64, cctx *types.CrossChainTx) error { + chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(receiveChainID) + if chain == nil { + return zetaObserverTypes.ErrSupportedChains + } + + nonce, found := k.GetChainNonces(ctx, chain.ChainName.String()) + if !found { + return sdkerrors.Wrap(types.ErrCannotFindReceiverNonce, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) + } + + // SET nonce + cctx.GetCurrentOutTxParam().OutboundTxTssNonce = nonce.Nonce + tss, found := k.GetTSS(ctx) + if !found { + return sdkerrors.Wrap(types.ErrCannotFindTSSKeys, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) + } + + p, found := k.GetPendingNonces(ctx, tss.TssPubkey, uint64(receiveChainID)) + if !found { + return sdkerrors.Wrap(types.ErrCannotFindPendingNonces, fmt.Sprintf("chain_id %d, nonce %d", receiveChainID, nonce.Nonce)) + } + + if p.NonceHigh != int64(nonce.Nonce) { + return sdkerrors.Wrap(types.ErrNonceMismatch, fmt.Sprintf("chain_id %d, high nonce %d, current nonce %d", receiveChainID, p.NonceHigh, nonce.Nonce)) + } + + nonce.Nonce++ + p.NonceHigh++ + k.SetChainNonces(ctx, nonce) + k.SetPendingNonces(ctx, p) + return nil +} + +// RefundAmountOnZetaChain refunds the amount of the cctx on ZetaChain in case of aborted cctx +// NOTE: GetCurrentOutTxParam should contain the last up to date cctx amount +func (k Keeper) RefundAmountOnZetaChain(ctx sdk.Context, cctx types.CrossChainTx, inputAmount math.Uint) error { + // preliminary checks + if cctx.InboundTxParams.CoinType != common.CoinType_ERC20 { + return errors.New("unsupported coin type for refund on ZetaChain") + } + if !common.IsEVMChain(cctx.InboundTxParams.SenderChainId) { + return errors.New("only EVM chains are supported for refund on ZetaChain") + } + sender := ethcommon.HexToAddress(cctx.InboundTxParams.Sender) + if sender == (ethcommon.Address{}) { + return errors.New("invalid sender address") + } + if inputAmount.IsNil() || inputAmount.IsZero() { + return errors.New("no amount to refund") + } + + // get address of the zrc20 + fc, found := k.fungibleKeeper.GetForeignCoinFromAsset(ctx, cctx.InboundTxParams.Asset, cctx.InboundTxParams.SenderChainId) + if !found { + return fmt.Errorf("asset %s zrc not found", cctx.InboundTxParams.Asset) + } + zrc20 := ethcommon.HexToAddress(fc.Zrc20ContractAddress) + if zrc20 == (ethcommon.Address{}) { + return fmt.Errorf("asset %s invalid zrc address", cctx.InboundTxParams.Asset) + } + + // deposit the amount to the sender + if _, err := k.fungibleKeeper.DepositZRC20(ctx, zrc20, sender, inputAmount.BigInt()); err != nil { + return errors.New("failed to deposit zrc20 on ZetaChain" + err.Error()) + } + + return nil +} diff --git a/x/crosschain/keeper/cctx_utils_test.go b/x/crosschain/keeper/cctx_utils_test.go new file mode 100644 index 0000000000..bdeb9eff4d --- /dev/null +++ b/x/crosschain/keeper/cctx_utils_test.go @@ -0,0 +1,140 @@ +package keeper_test + +import ( + "testing" + + "cosmossdk.io/math" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestKeeper_RefundAmountOnZetaChain(t *testing.T) { + t.Run("should refund amount on zeta chain", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + asset := sample.EthAddress().String() + sender := sample.EthAddress() + chainID := getValidEthChainID(t) + + // deploy zrc20 + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20Addr := deployZRC20( + t, + ctx, + zk.FungibleKeeper, + sdkk.EvmKeeper, + chainID, + "bar", + asset, + "bar", + ) + + err := k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: chainID, + Sender: sender.String(), + Asset: asset, + }}, + math.NewUint(42), + ) + require.NoError(t, err) + + // check amount deposited in balance + balance, err := zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20Addr, sender) + require.NoError(t, err) + require.Equal(t, uint64(42), balance.Uint64()) + + // can refund again + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: chainID, + Sender: sender.String(), + Asset: asset, + }}, + math.NewUint(42), + ) + require.NoError(t, err) + balance, err = zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20Addr, sender) + require.NoError(t, err) + require.Equal(t, uint64(84), balance.Uint64()) + }) + + t.Run("should fail with invalid cctx", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + + err := k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_Zeta, + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "unsupported coin type") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_Gas, + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "unsupported coin type") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: 999999, + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "only EVM chains are supported") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: getValidEthChainID(t), + Sender: "invalid", + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "invalid sender address") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: getValidEthChainID(t), + Sender: sample.EthAddress().String(), + }, + }, + math.Uint{}, + ) + require.ErrorContains(t, err, "no amount to refund") + + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: getValidEthChainID(t), + Sender: sample.EthAddress().String(), + }}, + math.ZeroUint(), + ) + require.ErrorContains(t, err, "no amount to refund") + + // the foreign coin has not been set + err = k.RefundAmountOnZetaChain(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: common.CoinType_ERC20, + SenderChainId: getValidEthChainID(t), + Sender: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + }}, + math.NewUint(42), + ) + require.ErrorContains(t, err, "zrc not found") + }) +} diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index a87e0a041c..a9779766d8 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -224,8 +224,13 @@ func (k Keeper) ProcessZetaSentEvent(ctx sdk.Context, event *connectorzevm.ZetaC // Create the CCTX cctx := k.CreateNewCCTX(ctx, msg, sendHash, tss.TssPubkey, types.CctxStatus_PendingOutbound, &senderChain, receiverChain) - // Pay gas in Zeta and update the amount for the cctx - if err := k.PayGasInZetaAndUpdateCctx(ctx, receiverChain.ChainId, &cctx, true); err != nil { + if err := k.PayGasAndUpdateCctx( + ctx, + receiverChain.ChainId, + &cctx, + amount, + true, + ); err != nil { return fmt.Errorf("ProcessWithdrawalEvent: pay gas failed: %s", err.Error()) } diff --git a/x/crosschain/keeper/gas_payment.go b/x/crosschain/keeper/gas_payment.go new file mode 100644 index 0000000000..9cd5e0f916 --- /dev/null +++ b/x/crosschain/keeper/gas_payment.go @@ -0,0 +1,352 @@ +package keeper + +import ( + "errors" + "fmt" + "math/big" + + cosmoserrors "cosmossdk.io/errors" + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/crosschain/types" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// PayGasAndUpdateCctx updates the outbound tx with the new amount after paying the gas fee +// **Caller should feed temporary ctx into this function** +func (k Keeper) PayGasAndUpdateCctx( + ctx sdk.Context, + chainID int64, + cctx *types.CrossChainTx, + inputAmount math.Uint, + noEthereumTxEvent bool, +) error { + // Dispatch to the correct function based on the coin type + switch cctx.InboundTxParams.CoinType { + case common.CoinType_Zeta: + return k.PayGasInZetaAndUpdateCctx(ctx, chainID, cctx, inputAmount, noEthereumTxEvent) + case common.CoinType_Gas: + return k.PayGasNativeAndUpdateCctx(ctx, chainID, cctx, inputAmount) + case common.CoinType_ERC20: + return k.PayGasInERC20AndUpdateCctx(ctx, chainID, cctx, inputAmount, noEthereumTxEvent) + default: + // can't pay gas with coin type + return fmt.Errorf("can't pay gas with coin type %s", cctx.InboundTxParams.CoinType.String()) + } +} + +// ChainGasParams returns the params to calculates the fees for gas for a chain +// tha gas address, the gas limit, gas price and protocol flat fee are returned +func (k Keeper) ChainGasParams( + ctx sdk.Context, + chainID int64, +) (gasZRC20 ethcommon.Address, gasLimit, gasPrice, protocolFee math.Uint, err error) { + gasZRC20, err = k.fungibleKeeper.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + if err != nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, err + } + + // get the gas limit + gasLimitQueried, err := k.fungibleKeeper.QueryGasLimit(ctx, gasZRC20) + if err != nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, err + } + if gasLimitQueried == nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, errors.New("gas limit is nil") + } + gasLimit = math.NewUintFromBigInt(gasLimitQueried) + + // get the protocol flat fee + protocolFlatFeeQueried, err := k.fungibleKeeper.QueryProtocolFlatFee(ctx, gasZRC20) + if err != nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, err + } + if protocolFlatFeeQueried == nil { + return gasZRC20, gasLimit, gasPrice, protocolFee, errors.New("protocol flat fee is nil") + } + protocolFee = math.NewUintFromBigInt(protocolFlatFeeQueried) + + // get the gas price + gasPrice, isFound := k.GetMedianGasPriceInUint(ctx, chainID) + if !isFound { + return gasZRC20, gasLimit, gasPrice, protocolFee, types.ErrUnableToGetGasPrice + } + + return +} + +// PayGasNativeAndUpdateCctx updates the outbound tx with the new amount subtracting the gas fee +// **Caller should feed temporary ctx into this function** +func (k Keeper) PayGasNativeAndUpdateCctx( + ctx sdk.Context, + chainID int64, + cctx *types.CrossChainTx, + inputAmount math.Uint, +) error { + // preliminary checks + if cctx.InboundTxParams.CoinType != common.CoinType_Gas { + return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in native gas with %s", cctx.InboundTxParams.CoinType.String()) + } + if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + return zetaObserverTypes.ErrSupportedChains + } + + // get gas params + _, gasLimit, gasPrice, protocolFlatFee, err := k.ChainGasParams(ctx, chainID) + if err != nil { + return cosmoserrors.Wrap(types.ErrCannotFindGasParams, err.Error()) + } + + // calculate the final gas fee + outTxGasFee := gasLimit.Mul(gasPrice).Add(protocolFlatFee) + + // subtract the withdraw fee from the input amount + if outTxGasFee.GT(inputAmount) { + return cosmoserrors.Wrap(types.ErrNotEnoughGas, fmt.Sprintf("outTxGasFee(%s) more than available gas for tx (%s) | Identifiers : %s ", + outTxGasFee, + inputAmount, + cctx.LogIdentifierForCCTX()), + ) + } + ctx.Logger().Info("Subtracting amount from inbound tx", "amount", inputAmount.String(), "fee", outTxGasFee.String()) + newAmount := inputAmount.Sub(outTxGasFee) + + // update cctx + cctx.GetCurrentOutTxParam().Amount = newAmount + cctx.GetCurrentOutTxParam().OutboundTxGasLimit = gasLimit.Uint64() + cctx.GetCurrentOutTxParam().OutboundTxGasPrice = gasPrice.String() + + return nil +} + +// PayGasInERC20AndUpdateCctx updates parameter cctx amount subtracting the gas fee +// the gas fee in ERC20 is calculated by swapping ERC20 -> Zeta -> Gas +// if the route is not available, the gas payment will fail +// **Caller should feed temporary ctx into this function** +func (k Keeper) PayGasInERC20AndUpdateCctx( + ctx sdk.Context, + chainID int64, + cctx *types.CrossChainTx, + inputAmount math.Uint, + noEthereumTxEvent bool, +) error { + // preliminary checks + if cctx.InboundTxParams.CoinType != common.CoinType_ERC20 { + return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in erc20 with %s", cctx.InboundTxParams.CoinType.String()) + } + if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + return zetaObserverTypes.ErrSupportedChains + } + + // get gas params + gasZRC20, gasLimit, gasPrice, protocolFlatFee, err := k.ChainGasParams(ctx, chainID) + if err != nil { + return cosmoserrors.Wrap(types.ErrCannotFindGasParams, err.Error()) + } + outTxGasFee := gasLimit.Mul(gasPrice).Add(protocolFlatFee) + + // get address of the zrc20 + fc, found := k.fungibleKeeper.GetForeignCoinFromAsset(ctx, cctx.InboundTxParams.Asset, chainID) + if !found { + return cosmoserrors.Wrapf(types.ErrForeignCoinNotFound, "zrc20 from asset %s not found", cctx.InboundTxParams.Asset) + } + zrc20 := ethcommon.HexToAddress(fc.Zrc20ContractAddress) + if zrc20 == (ethcommon.Address{}) { + return cosmoserrors.Wrapf(types.ErrForeignCoinNotFound, "zrc20 from asset %s invalid address", cctx.InboundTxParams.Asset) + } + + // get the necessary ERC20 amount for gas + feeInZRC20, err := k.fungibleKeeper.QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx, outTxGasFee.BigInt(), zrc20, gasZRC20) + if err != nil { + // NOTE: this is the first method that fails when a liquidity pool is not set for the gas ZRC20, so we return a specific error + return cosmoserrors.Wrap(types.ErrNoLiquidityPool, err.Error()) + } + + // subtract the withdraw fee from the input amount + if math.NewUintFromBigInt(feeInZRC20).GT(inputAmount) { + return cosmoserrors.Wrap(types.ErrNotEnoughGas, fmt.Sprintf("feeInZRC20(%s) more than available gas for tx (%s) | Identifiers : %s ", + feeInZRC20, + inputAmount, + cctx.LogIdentifierForCCTX()), + ) + } + newAmount := inputAmount.Sub(math.NewUintFromBigInt(feeInZRC20)) + + // mint the amount of ERC20 to be burnt as gas fee + _, err = k.fungibleKeeper.DepositZRC20(ctx, zrc20, types.ModuleAddressEVM, feeInZRC20) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + ctx.Logger().Info("Minted ERC20 for gas fee", + "zrc20", zrc20.Hex(), + "amount", feeInZRC20, + ) + + // approve the uniswapv2 router to spend the ERC20 + routerAddress, err := k.fungibleKeeper.GetUniswapV2Router02Address(ctx) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + err = k.fungibleKeeper.CallZRC20Approve( + ctx, + types.ModuleAddressEVM, + zrc20, + routerAddress, + feeInZRC20, + noEthereumTxEvent, + ) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + + // swap the fee in ERC20 into gas passing through Zeta and burn the gas ZRC20 + amounts, err := k.fungibleKeeper.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + feeInZRC20, + zrc20, + gasZRC20, + noEthereumTxEvent, + ) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + ctx.Logger().Info("CallUniswapV2RouterSwapExactTokensForTokens", + "zrc20AmountIn", amounts[0], + "gasAmountOut", amounts[2], + ) + gasObtained := amounts[2] + + // check if the final gas received after swap matches the gas fee defined + // if not there might be issues with the pool liquidity and it is safer from an accounting perspective to return an error + if gasObtained.Cmp(outTxGasFee.BigInt()) != 0 { + return cosmoserrors.Wrapf(types.ErrInvalidGasAmount, "gas obtained for burn (%s) not equal to gas fee(%s)", gasObtained, outTxGasFee) + } + + // burn the gas ZRC20 + err = k.fungibleKeeper.CallZRC20Burn(ctx, types.ModuleAddressEVM, gasZRC20, gasObtained, noEthereumTxEvent) + if err != nil { + return cosmoserrors.Wrap(fungibletypes.ErrContractCall, err.Error()) + } + ctx.Logger().Info("Burning gas ZRC20", + "zrc20", gasZRC20.Hex(), + "amount", gasObtained, + ) + + // update cctx + cctx.GetCurrentOutTxParam().Amount = newAmount + cctx.GetCurrentOutTxParam().OutboundTxGasLimit = gasLimit.Uint64() + cctx.GetCurrentOutTxParam().OutboundTxGasPrice = gasPrice.String() + + return nil +} + +// PayGasInZetaAndUpdateCctx updates parameter cctx with the gas price and gas fee for the outbound tx; +// it also makes a trade to fulfill the outbound tx gas fee in ZETA by swapping ZETA for some gas ZRC20 balances +// The gas ZRC20 balance is subsequently burned to account for the expense of TSS address gas fee payment in the outbound tx. +// zetaBurnt represents the amount of Zeta that has been burnt for the tx, the final amount for the tx is zetaBurnt - gasFee +// **Caller should feed temporary ctx into this function** +func (k Keeper) PayGasInZetaAndUpdateCctx( + ctx sdk.Context, + chainID int64, + cctx *types.CrossChainTx, + zetaBurnt math.Uint, + noEthereumTxEvent bool, +) error { + // preliminary checks + if cctx.InboundTxParams.CoinType != common.CoinType_Zeta { + return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in zeta with %s", cctx.InboundTxParams.CoinType.String()) + } + if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + return zetaObserverTypes.ErrSupportedChains + } + + gasZRC20, err := k.fungibleKeeper.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to get system contract gas coin") + } + + // get the gas price + gasPrice, isFound := k.GetMedianGasPriceInUint(ctx, chainID) + if !isFound { + return cosmoserrors.Wrap(types.ErrUnableToGetGasPrice, fmt.Sprintf(" chain %d | Identifiers : %s ", + chainID, + cctx.LogIdentifierForCCTX()), + ) + } + gasPrice = gasPrice.MulUint64(2) // overpays gas price by 2x + + // get the gas fee in gas token + gasLimit := sdk.NewUint(cctx.GetCurrentOutTxParam().OutboundTxGasLimit) + outTxGasFee := gasLimit.Mul(gasPrice) + + // get the gas fee in Zeta using system uniswapv2 pool wzeta/gasZRC20 and adding the protocol fee + outTxGasFeeInZeta, err := k.fungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, outTxGasFee.BigInt(), gasZRC20) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to QueryUniswapv2RouterGetAmountsIn") + } + feeInZeta := types.GetProtocolFee().Add(math.NewUintFromBigInt(outTxGasFeeInZeta)) + + // reduce the amount of the outbound tx + if feeInZeta.GT(zetaBurnt) { + return cosmoserrors.Wrap(types.ErrNotEnoughZetaBurnt, fmt.Sprintf("feeInZeta(%s) more than zetaBurnt (%s) | Identifiers : %s ", + feeInZeta, + zetaBurnt, + cctx.LogIdentifierForCCTX()), + ) + } + ctx.Logger().Info("Subtracting amount from inbound tx", + "amount", zetaBurnt.String(), + "feeInZeta", feeInZeta.String(), + ) + newAmount := zetaBurnt.Sub(feeInZeta) + + // ** The following logic converts the outTxGasFeeInZeta into gasZRC20 and burns it ** + // swap the outTxGasFeeInZeta portion of zeta to the real gas ZRC20 and burn it, in a temporary context. + { + coins := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(feeInZeta.BigInt()))) + err := k.bankKeeper.MintCoins(ctx, types.ModuleName, coins) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to mint coins") + } + + amounts, err := k.fungibleKeeper.CallUniswapV2RouterSwapExactETHForToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + outTxGasFeeInZeta, + gasZRC20, + noEthereumTxEvent, + ) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to CallUniswapv2RouterSwapExactETHForToken") + } + + ctx.Logger().Info("gas fee", "outTxGasFee", outTxGasFee, "outTxGasFeeInZeta", outTxGasFeeInZeta) + ctx.Logger().Info("CallUniswapv2RouterSwapExactETHForToken", + "zetaAmountIn", amounts[0], + "zrc20AmountOut", amounts[1], + ) + err = k.fungibleKeeper.CallZRC20Burn(ctx, types.ModuleAddressEVM, gasZRC20, amounts[1], noEthereumTxEvent) + if err != nil { + return cosmoserrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to CallZRC20Burn") + } + } + + // Update the cctx + cctx.GetCurrentOutTxParam().OutboundTxGasPrice = gasPrice.String() + cctx.GetCurrentOutTxParam().Amount = newAmount + if cctx.ZetaFees.IsNil() { + cctx.ZetaFees = feeInZeta + } else { + cctx.ZetaFees = cctx.ZetaFees.Add(feeInZeta) + } + + return nil +} diff --git a/x/crosschain/keeper/gas_payment_test.go b/x/crosschain/keeper/gas_payment_test.go new file mode 100644 index 0000000000..a9c385c7d8 --- /dev/null +++ b/x/crosschain/keeper/gas_payment_test.go @@ -0,0 +1,802 @@ +package keeper_test + +import ( + "math/big" + "testing" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/ethereum/go-ethereum/common" + evmkeeper "github.com/evmos/ethermint/x/evm/keeper" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + zetacommon "github.com/zeta-chain/zetacore/common" + testkeeper "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" + fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// get a valid chain id independently of the build flag +func getValidEthChainID(t *testing.T) int64 { + list := zetacommon.DefaultChainsList() + require.True(t, len(list) > 1) + require.NotNil(t, list[1]) + require.False(t, zetacommon.IsBitcoinChain(list[1].ChainId)) + + return list[1].ChainId +} + +// assert that a contract has been deployed by checking stored code is non-empty. +func assertContractDeployment(t *testing.T, k *evmkeeper.Keeper, ctx sdk.Context, contractAddress common.Address) { + acc := k.GetAccount(ctx, contractAddress) + require.NotNil(t, acc) + + code := k.GetCode(ctx, common.BytesToHash(acc.CodeHash)) + require.NotEmpty(t, code) +} + +// deploySystemContracts deploys the system contracts and returns their addresses. +func deploySystemContracts( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, +) (wzeta, uniswapV2Factory, uniswapV2Router, connector, systemContract common.Address) { + var err error + + wzeta, err = k.DeployWZETA(ctx) + require.NoError(t, err) + require.NotEmpty(t, wzeta) + assertContractDeployment(t, evmk, ctx, wzeta) + + uniswapV2Factory, err = k.DeployUniswapV2Factory(ctx) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Factory) + assertContractDeployment(t, evmk, ctx, uniswapV2Factory) + + uniswapV2Router, err = k.DeployUniswapV2Router02(ctx, uniswapV2Factory, wzeta) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Router) + assertContractDeployment(t, evmk, ctx, uniswapV2Router) + + connector, err = k.DeployConnectorZEVM(ctx, wzeta) + require.NoError(t, err) + require.NotEmpty(t, connector) + assertContractDeployment(t, evmk, ctx, connector) + + systemContract, err = k.DeploySystemContract(ctx, wzeta, uniswapV2Factory, uniswapV2Router) + require.NoError(t, err) + require.NotEmpty(t, systemContract) + assertContractDeployment(t, evmk, ctx, systemContract) + + return +} + +// setupGasCoin is a helper function to setup the gas coin for testing +func setupGasCoin( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, + chainID int64, + assetName string, + symbol string, +) (zrc20 common.Address) { + addr, err := k.SetupChainGasCoinAndPool( + ctx, + chainID, + assetName, + symbol, + 8, + ) + require.NoError(t, err) + assertContractDeployment(t, evmk, ctx, addr) + return addr +} + +// deployZRC20 deploys a ZRC20 contract and returns its address +func deployZRC20( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, + chainID int64, + assetName string, + assetAddress string, + symbol string, +) (zrc20 common.Address) { + addr, err := k.DeployZRC20Contract( + ctx, + assetName, + symbol, + 8, + chainID, + 0, + assetAddress, + big.NewInt(21_000), + ) + require.NoError(t, err) + assertContractDeployment(t, evmk, ctx, addr) + return addr +} + +// setupZRC20Pool setup a Uniswap pool with liquidity for the pair zeta/asset +func setupZRC20Pool( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + bankKeeper bankkeeper.Keeper, + zrc20Addr common.Address, +) { + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + require.NoError(t, err) + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + require.NoError(t, err) + + // enough for the small numbers used in test + liquidityAmount := big.NewInt(1e17) + + // mint some zrc20 and zeta + _, err = k.DepositZRC20(ctx, zrc20Addr, types.ModuleAddressEVM, liquidityAmount) + require.NoError(t, err) + err = bankKeeper.MintCoins( + ctx, + types.ModuleName, + sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(liquidityAmount))), + ) + require.NoError(t, err) + + // approve the router to spend the zeta + err = k.CallZRC20Approve( + ctx, + types.ModuleAddressEVM, + zrc20Addr, + routerAddress, + liquidityAmount, + false, + ) + require.NoError(t, err) + + // add the liquidity + //function addLiquidityETH( + // address token, + // uint amountTokenDesired, + // uint amountTokenMin, + // uint amountETHMin, + // address to, + // uint deadline + //) + _, err = k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + liquidityAmount, + big.NewInt(5_000_000), + true, + false, + "addLiquidityETH", + zrc20Addr, + liquidityAmount, + fungiblekeeper.BigIntZero, + fungiblekeeper.BigIntZero, + types.ModuleAddressEVM, + liquidityAmount, + ) + require.NoError(t, err) +} + +func setAdminDeployFungibleCoin(ctx sdk.Context, zk testkeeper.ZetaKeepers, admin string) { + params := zk.ObserverKeeper.GetParams(ctx) + params.AdminPolicy = []*observertypes.Admin_Policy{ + { + PolicyType: observertypes.Policy_Type_deploy_fungible_coin, + Address: admin, + }, + } + zk.ObserverKeeper.SetParams(ctx, params) +} + +var ( + // gasLimit = big.NewInt(21_000) - value used in SetupChainGasCoinAndPool for gas limit initialization + withdrawFee uint64 = 1000 + gasPrice uint64 = 2 + inputAmount uint64 = 100000 +) + +func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { + t.Run("can pay gas in native gas", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, zrc20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + // total fees must be 21000*2+1000=43000 + // if the input amount of the cctx is 100000, the output amount must be 100000-43000=57000 + err = k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount)) + require.NoError(t, err) + require.Equal(t, uint64(57000), cctx.GetCurrentOutTxParam().Amount.Uint64()) + require.Equal(t, uint64(21_000), cctx.GetCurrentOutTxParam().OutboundTxGasLimit) + require.Equal(t, "2", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) + }) + + t.Run("should fail if not coin type gas", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + } + err := k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount)) + require.ErrorIs(t, err, types.ErrInvalidCoinType) + }) + + t.Run("should fail if chain is not supported", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + } + err := k.PayGasNativeAndUpdateCctx(ctx, 999999, &cctx, math.NewUint(inputAmount)) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + }) + + t.Run("should fail if can't query the gas price", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + err := k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount)) + require.ErrorIs(t, err, types.ErrCannotFindGasParams) + }) + + t.Run("should fail if not enough amount for the fee", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, zrc20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + // 42999 < 43000 + err = k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(42999)) + require.ErrorIs(t, err, types.ErrNotEnoughGas) + }) +} + +func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { + t.Run("can pay gas in erc20", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin, erc20 and set fee params + chainID := getValidEthChainID(t) + assetAddress := sample.EthAddress().String() + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") + zrc20Addr := deployZRC20( + t, + ctx, + zk.FungibleKeeper, + sdkk.EvmKeeper, + chainID, + "bar", + assetAddress, + "bar", + ) + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, gasZRC20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + setupZRC20Pool( + t, + ctx, + zk.FungibleKeeper, + sdkk.BankKeeper, + zrc20Addr, + ) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + Asset: assetAddress, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + // total fees in gas must be 21000*2+1000=43000 + // we calculate what it represents in erc20 + expectedInZeta, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(43000), gasZRC20) + require.NoError(t, err) + expectedInZRC20, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, expectedInZeta, zrc20Addr) + require.NoError(t, err) + + err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.NoError(t, err) + require.Equal(t, inputAmount-expectedInZRC20.Uint64(), cctx.GetCurrentOutTxParam().Amount.Uint64()) + require.Equal(t, uint64(21_000), cctx.GetCurrentOutTxParam().OutboundTxGasLimit) + require.Equal(t, "2", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) + }) + + t.Run("should fail if not coin type erc20", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + } + err := k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, types.ErrInvalidCoinType) + }) + + t.Run("should fail if chain is not supported", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + }, + } + err := k.PayGasInERC20AndUpdateCctx(ctx, 999999, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + }) + + t.Run("should fail if can't query the gas price", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + err := k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, types.ErrCannotFindGasParams) + }) + + t.Run("should fail if can't find the ZRC20", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin, erc20 and set fee params + chainID := getValidEthChainID(t) + assetAddress := sample.EthAddress().String() + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, gasZRC20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // zrc20 not deployed + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + Asset: assetAddress, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, types.ErrForeignCoinNotFound) + }) + + t.Run("should fail if liquidity pool not setup", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin, erc20 and set fee params + chainID := getValidEthChainID(t) + assetAddress := sample.EthAddress().String() + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") + deployZRC20( + t, + ctx, + zk.FungibleKeeper, + sdkk.EvmKeeper, + chainID, + "bar", + assetAddress, + "bar", + ) + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, gasZRC20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // liquidity pool not set + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + Asset: assetAddress, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) + require.ErrorIs(t, err, types.ErrNoLiquidityPool) + }) + + t.Run("should fail if not enough amount for the fee", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin, erc20 and set fee params + chainID := getValidEthChainID(t) + assetAddress := sample.EthAddress().String() + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") + zrc20Addr := deployZRC20( + t, + ctx, + zk.FungibleKeeper, + sdkk.EvmKeeper, + chainID, + "bar", + assetAddress, + "bar", + ) + _, err := zk.FungibleKeeper.UpdateZRC20WithdrawFee( + sdk.UnwrapSDKContext(ctx), + fungibletypes.NewMsgUpdateZRC20WithdrawFee(admin, gasZRC20.String(), sdk.NewUint(withdrawFee)), + ) + require.NoError(t, err) + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + setupZRC20Pool( + t, + ctx, + zk.FungibleKeeper, + sdkk.BankKeeper, + zrc20Addr, + ) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_ERC20, + Asset: assetAddress, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: zetacommon.ZetaChain().ChainId, + }, + { + ReceiverChainId: chainID, + }, + }, + } + + // total fees in gas must be 21000*2+1000=43000 + // we calculate what it represents in erc20 + expectedInZeta, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(43000), gasZRC20) + require.NoError(t, err) + expectedInZRC20, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, expectedInZeta, zrc20Addr) + require.NoError(t, err) + + // Provide expected value minus 1 + err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUintFromBigInt(expectedInZRC20).SubUint64(1), false) + require.ErrorIs(t, err, types.ErrNotEnoughGas) + }) +} + +func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { + t.Run("can pay gas in zeta", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: chainID, + OutboundTxGasLimit: 1000, + }, + }, + ZetaFees: math.NewUint(100), + } + // gasLimit * gasPrice * 2 = 1000 * 2 * 2 = 4000 + expectedOutTxGasFeeInZeta, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(4000), zrc20) + require.NoError(t, err) + + // the output amount must be input amount - (out tx fee in zeta + protocol flat fee) + expectedFeeInZeta := types.GetProtocolFee().Add(math.NewUintFromBigInt(expectedOutTxGasFeeInZeta)) + inputAmount := expectedFeeInZeta.Add(math.NewUint(100000)) + err = k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, inputAmount, false) + require.NoError(t, err) + require.Equal(t, "100000", cctx.GetCurrentOutTxParam().Amount.String()) + require.Equal(t, "4", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) // gas price is doubled + require.True(t, cctx.ZetaFees.Equal(expectedFeeInZeta.Add(math.NewUint(100))), "expected %s, got %s", expectedFeeInZeta.String(), cctx.ZetaFees.String()) + + // can call with undefined zeta fees + cctx = types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: chainID, + OutboundTxGasLimit: 1000, + }, + }, + } + expectedOutTxGasFeeInZeta, err = zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(4000), zrc20) + require.NoError(t, err) + expectedFeeInZeta = types.GetProtocolFee().Add(math.NewUintFromBigInt(expectedOutTxGasFeeInZeta)) + inputAmount = expectedFeeInZeta.Add(math.NewUint(100000)) + err = k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, inputAmount, false) + require.NoError(t, err) + require.Equal(t, "100000", cctx.GetCurrentOutTxParam().Amount.String()) + require.Equal(t, "4", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) // gas price is doubled + require.True(t, cctx.ZetaFees.Equal(expectedFeeInZeta), "expected %s, got %s", expectedFeeInZeta.String(), cctx.ZetaFees.String()) + }) + + t.Run("should fail if pay gas in zeta with coin type other than zeta", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Gas, + }, + } + err := k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(100000), false) + require.ErrorIs(t, err, types.ErrInvalidCoinType) + }) + + t.Run("should fail if chain is not supported", func(t *testing.T) { + k, ctx, _, _ := testkeeper.CrosschainKeeper(t) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + } + err := k.PayGasInZetaAndUpdateCctx(ctx, 999999, &cctx, math.NewUint(100000), false) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + }) + + t.Run("should fail if can't query the gas price", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // gas price not set + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: chainID, + OutboundTxGasLimit: 1000, + }, + }, + } + + err := k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(100000), false) + require.ErrorIs(t, err, types.ErrUnableToGetGasPrice) + }) + + t.Run("should fail if not enough amount for the fee", func(t *testing.T) { + k, ctx, sdkk, zk := testkeeper.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy gas coin and set fee params + chainID := getValidEthChainID(t) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: chainID, + MedianIndex: 0, + Prices: []uint64{gasPrice}, + }) + + // create a cctx reverted from zeta + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: zetacommon.CoinType_Zeta, + }, + OutboundTxParams: []*types.OutboundTxParams{ + { + ReceiverChainId: chainID, + OutboundTxGasLimit: 1000, + }, + }, + ZetaFees: math.NewUint(100), + } + expectedOutTxGasFeeInZeta, err := zk.FungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(4000), zrc20) + require.NoError(t, err) + expectedFeeInZeta := types.GetProtocolFee().Add(math.NewUintFromBigInt(expectedOutTxGasFeeInZeta)) + + // set input amount lower than total zeta fee + inputAmount := expectedFeeInZeta.Sub(math.NewUint(1)) + err = k.PayGasInZetaAndUpdateCctx(ctx, chainID, &cctx, inputAmount, false) + require.ErrorIs(t, err, types.ErrNotEnoughZetaBurnt) + }) +} diff --git a/x/crosschain/keeper/grpc_query_in_tx_hash_to_cctx_test.go b/x/crosschain/keeper/grpc_query_in_tx_hash_to_cctx_test.go index 0bcce1517b..5704fdc54a 100644 --- a/x/crosschain/keeper/grpc_query_in_tx_hash_to_cctx_test.go +++ b/x/crosschain/keeper/grpc_query_in_tx_hash_to_cctx_test.go @@ -20,7 +20,7 @@ import ( ) func TestInTxHashToCctxQuerySingle(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) wctx := sdk.WrapSDKContext(ctx) msgs := createNInTxHashToCctx(keeper, ctx, 2) for _, tc := range []struct { @@ -71,7 +71,7 @@ func TestInTxHashToCctxQuerySingle(t *testing.T) { } func TestInTxHashToCctxQueryPaginated(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) wctx := sdk.WrapSDKContext(ctx) msgs := createNInTxHashToCctx(keeper, ctx, 5) @@ -148,7 +148,7 @@ func createInTxHashToCctxWithCctxs(keeper *crosschainkeeper.Keeper, ctx sdk.Cont } func TestKeeper_InTxHashToCctxDataQuery(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) wctx := sdk.WrapSDKContext(ctx) t.Run("can query all cctxs data with in tx hash", func(t *testing.T) { diff --git a/x/crosschain/keeper/in_tx_hash_to_cctx_test.go b/x/crosschain/keeper/in_tx_hash_to_cctx_test.go index 550b3395e1..6eb0118cf9 100644 --- a/x/crosschain/keeper/in_tx_hash_to_cctx_test.go +++ b/x/crosschain/keeper/in_tx_hash_to_cctx_test.go @@ -24,7 +24,7 @@ func createNInTxHashToCctx(keeper *keeper.Keeper, ctx sdk.Context, n int) []type } func TestInTxHashToCctxGet(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNInTxHashToCctx(keeper, ctx, 10) for _, item := range items { rst, found := keeper.GetInTxHashToCctx(ctx, @@ -38,7 +38,7 @@ func TestInTxHashToCctxGet(t *testing.T) { } } func TestInTxHashToCctxRemove(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNInTxHashToCctx(keeper, ctx, 10) for _, item := range items { keeper.RemoveInTxHashToCctx(ctx, @@ -52,7 +52,7 @@ func TestInTxHashToCctxRemove(t *testing.T) { } func TestInTxHashToCctxGetAll(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNInTxHashToCctx(keeper, ctx, 10) require.ElementsMatch(t, nullify.Fill(items), diff --git a/x/crosschain/keeper/keeper_cross_chain_tx_vote_inbound_tx.go b/x/crosschain/keeper/keeper_cross_chain_tx_vote_inbound_tx.go index fac94ec7f4..fba173c240 100644 --- a/x/crosschain/keeper/keeper_cross_chain_tx_vote_inbound_tx.go +++ b/x/crosschain/keeper/keeper_cross_chain_tx_vote_inbound_tx.go @@ -14,7 +14,7 @@ import ( // FIXME: use more specific error types & codes -// Casts a vote on an inbound transaction observed on a connected chain. If this +// VoteOnObservedInboundTx casts a vote on an inbound transaction observed on a connected chain. If this // is the first vote, a new ballot is created. When a threshold of votes is // reached, the ballot is finalized. When a ballot is finalized, a new CCTX is // created. @@ -57,6 +57,7 @@ import ( // Only observer validators are authorized to broadcast this message. func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.MsgVoteOnObservedInboundTx) (*types.MsgVoteOnObservedInboundTxResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + observationType := observerTypes.ObservationType_InBoundTx if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { return nil, types.ErrNotEnoughPermissions @@ -128,6 +129,7 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg if receiverChain.IsZetaChain() { tmpCtx, commit := ctx.CacheContext() isContractReverted, err := k.HandleEVMDeposit(tmpCtx, &cctx, *msg, observationChain) + if err != nil && !isContractReverted { // exceptional case; internal error; should abort CCTX cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, err.Error()) return &types.MsgVoteOnObservedInboundTxResponse{}, nil @@ -138,27 +140,60 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, "invalid sender chain") return &types.MsgVoteOnObservedInboundTxResponse{}, nil } - medianGasPrice, isFound := k.GetMedianGasPriceInUint(ctx, chain.ChainId) - if !isFound { - cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, "cannot find gas price") - return &types.MsgVoteOnObservedInboundTxResponse{}, nil - } // create new OutboundTxParams for the revert cctx.OutboundTxParams = append(cctx.OutboundTxParams, &types.OutboundTxParams{ - Receiver: cctx.InboundTxParams.Sender, - ReceiverChainId: cctx.InboundTxParams.SenderChainId, - Amount: cctx.InboundTxParams.Amount, - CoinType: cctx.InboundTxParams.CoinType, - OutboundTxGasLimit: 0, // for fungible refund, use default gasLimit - OutboundTxGasPrice: medianGasPrice.MulUint64(2).String(), + Receiver: cctx.InboundTxParams.Sender, + ReceiverChainId: cctx.InboundTxParams.SenderChainId, + Amount: cctx.InboundTxParams.Amount, + CoinType: cctx.InboundTxParams.CoinType, + // use same gas limit as outbound + //TODO: determine a specific revert gas limit https://github.com/zeta-chain/node/issues/1065 + OutboundTxGasLimit: msg.GasLimit, }) - if err = k.UpdateNonce(ctx, chain.ChainId, &cctx); err != nil { + + // we create a new cached context, and we don't commit the previous one with EVM deposit + tmpCtx, commit := ctx.CacheContext() + err = func() error { + err := k.PayGasAndUpdateCctx( + tmpCtx, + chain.ChainId, + &cctx, + cctx.InboundTxParams.Amount, + false, + ) + if err != nil { + return err + } + err = k.UpdateNonce(tmpCtx, chain.ChainId, &cctx) + if err != nil { + return err + } + return nil + }() + if err != nil { + // do not commit anything here as the CCTX should be aborted + + // gas payment for erc20 type might fail because no liquidity pool is defined to swap the zrc20 token into the gas token + // in this gas we should refund the sender on ZetaChain + if cctx.InboundTxParams.CoinType == common.CoinType_ERC20 { + + if err := k.RefundAmountOnZetaChain(ctx, cctx, cctx.InboundTxParams.Amount); err != nil { + // log the error + k.Logger(ctx).Error("failed to refund amount of aborted cctx on ZetaChain", + "error", err, + "sender", cctx.InboundTxParams.Sender, + "amount", cctx.InboundTxParams.Amount.String(), + ) + } + } + cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, err.Error()) return &types.MsgVoteOnObservedInboundTxResponse{}, nil } - // do not commit() here; + commit() cctx.CctxStatus.ChangeStatus(types.CctxStatus_PendingRevert, revertMessage) return &types.MsgVoteOnObservedInboundTxResponse{}, nil + } else { // successful HandleEVMDeposit; commit() cctx.CctxStatus.ChangeStatus(types.CctxStatus_OutboundMined, "Remote omnichain contract call completed") @@ -167,7 +202,13 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg } else { // Cross Chain SWAP tmpCtx, commit := ctx.CacheContext() err = func() error { - err := k.PayGasInZetaAndUpdateCctx(tmpCtx, receiverChain.ChainId, &cctx, false) + err := k.PayGasAndUpdateCctx( + tmpCtx, + receiverChain.ChainId, + &cctx, + cctx.InboundTxParams.Amount, + false, + ) if err != nil { return err } diff --git a/x/crosschain/keeper/keeper_cross_chain_tx_vote_outbound_tx.go b/x/crosschain/keeper/keeper_cross_chain_tx_vote_outbound_tx.go index a72bc84a07..6b8f0b02a9 100644 --- a/x/crosschain/keeper/keeper_cross_chain_tx_vote_outbound_tx.go +++ b/x/crosschain/keeper/keeper_cross_chain_tx_vote_outbound_tx.go @@ -16,7 +16,7 @@ import ( observerTypes "github.com/zeta-chain/zetacore/x/observer/types" ) -// Casts a vote on an outbound transaction observed on a connected chain (after +// VoteOnObservedOutboundTx casts a vote on an outbound transaction observed on a connected chain (after // it has been broadcasted to and finalized on a connected chain). If this is // the first vote, a new ballot is created. When a threshold of votes is // reached, the ballot is finalized. When a ballot is finalized, the outbound @@ -159,13 +159,21 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms case types.CctxStatus_PendingOutbound: // create new OutboundTxParams for the revert cctx.OutboundTxParams = append(cctx.OutboundTxParams, &types.OutboundTxParams{ - Receiver: cctx.InboundTxParams.Sender, - ReceiverChainId: cctx.InboundTxParams.SenderChainId, - Amount: cctx.InboundTxParams.Amount, - CoinType: cctx.InboundTxParams.CoinType, - OutboundTxGasLimit: cctx.OutboundTxParams[0].OutboundTxGasLimit, // NOTE(pwu): revert gas limit = initial outbound gas limit set by user; + Receiver: cctx.InboundTxParams.Sender, + ReceiverChainId: cctx.InboundTxParams.SenderChainId, + Amount: cctx.InboundTxParams.Amount, + CoinType: cctx.InboundTxParams.CoinType, + // NOTE(pwu): revert gas limit = initial outbound gas limit set by user + //TODO: determine a specific revert gas limit https://github.com/zeta-chain/node/issues/1065 + OutboundTxGasLimit: cctx.OutboundTxParams[0].OutboundTxGasLimit, }) - err := k.PayGasInZetaAndUpdateCctx(tmpCtx, cctx.InboundTxParams.SenderChainId, &cctx, false) + err := k.PayGasAndUpdateCctx( + tmpCtx, + cctx.InboundTxParams.SenderChainId, + &cctx, + cctx.OutboundTxParams[0].Amount, + false, + ) if err != nil { return err } diff --git a/x/crosschain/keeper/keeper_out_tx_tracker_test.go b/x/crosschain/keeper/keeper_out_tx_tracker_test.go index 16570daad4..d6835b1623 100644 --- a/x/crosschain/keeper/keeper_out_tx_tracker_test.go +++ b/x/crosschain/keeper/keeper_out_tx_tracker_test.go @@ -31,7 +31,7 @@ func createNOutTxTracker(keeper *keeper.Keeper, ctx sdk.Context, n int) []types. } func TestOutTxTrackerGet(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNOutTxTracker(keeper, ctx, 10) for _, item := range items { rst, found := keeper.GetOutTxTracker(ctx, @@ -46,7 +46,7 @@ func TestOutTxTrackerGet(t *testing.T) { } } func TestOutTxTrackerRemove(t *testing.T) { - k, ctx := keepertest.CrosschainKeeper(t) + k, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNOutTxTracker(k, ctx, 10) for _, item := range items { k.RemoveOutTxTracker(ctx, @@ -62,7 +62,7 @@ func TestOutTxTrackerRemove(t *testing.T) { } func TestOutTxTrackerGetAll(t *testing.T) { - keeper, ctx := keepertest.CrosschainKeeper(t) + keeper, ctx, _, _ := keepertest.CrosschainKeeper(t) items := createNOutTxTracker(keeper, ctx, 10) require.ElementsMatch(t, nullify.Fill(items), diff --git a/x/crosschain/keeper/keeper_tss_voter.go b/x/crosschain/keeper/keeper_tss_voter.go index f28904ba66..0dc818d48f 100644 --- a/x/crosschain/keeper/keeper_tss_voter.go +++ b/x/crosschain/keeper/keeper_tss_voter.go @@ -128,3 +128,12 @@ func (k msgServer) UpdateTssAddress(goCtx context.Context, msg *types.MsgUpdateT return &types.MsgUpdateTssAddressResponse{}, nil } + +// IsAuthorizedNodeAccount checks whether a signer is authorized to sign , by checking their address against the observer mapper which contains the observer list for the chain and type +func (k Keeper) IsAuthorizedNodeAccount(ctx sdk.Context, address string) bool { + _, found := k.zetaObserverKeeper.GetNodeAccount(ctx, address) + if found { + return true + } + return false +} diff --git a/x/crosschain/keeper/keeper_utils.go b/x/crosschain/keeper/keeper_utils.go deleted file mode 100644 index 77882f6a2b..0000000000 --- a/x/crosschain/keeper/keeper_utils.go +++ /dev/null @@ -1,143 +0,0 @@ -package keeper - -import ( - "fmt" - "math/big" - - "github.com/zeta-chain/zetacore/cmd/zetacored/config" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/zeta-chain/zetacore/x/crosschain/types" - zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" -) - -// IsAuthorizedNodeAccount checks whether a signer is authorized to sign , by checking their address against the observer mapper which contains the observer list for the chain and type -func (k Keeper) IsAuthorizedNodeAccount(ctx sdk.Context, address string) bool { - _, found := k.zetaObserverKeeper.GetNodeAccount(ctx, address) - if found { - return true - } - return false -} - -// PayGasInZetaAndUpdateCctx updates parameter cctx with the gas price and gas fee for the outbound tx; -// it also makes a trade to fulfill the outbound tx gas fee in ZETA by swapping ZETA for some gas ZRC20 balances -// The gas ZRC20 balance is subsequently burned to account for the expense of TSS address gas fee payment in the outbound tx. -// **Caller should feed temporary ctx into this function** -func (k Keeper) PayGasInZetaAndUpdateCctx(ctx sdk.Context, chainID int64, cctx *types.CrossChainTx, noEthereumTxEvent bool) error { - // TODO: this check currently break the integration tests, enable it when integration tests are fixed - // https://github.com/zeta-chain/node/issues/1022 - //if cctx.InboundTxParams.CoinType != common.CoinType_Zeta { - // return sdkerrors.Wrapf(zetaObserverTypes.ErrInvalidCoinType, "can't pay gas in zeta with %s", cctx.InboundTxParams.CoinType.String()) - //} - - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID) - if chain == nil { - return zetaObserverTypes.ErrSupportedChains - } - medianGasPrice, isFound := k.GetMedianGasPriceInUint(ctx, chain.ChainId) - if !isFound { - return sdkerrors.Wrap(types.ErrUnableToGetGasPrice, fmt.Sprintf(" chain %d | Identifiers : %s ", - cctx.GetCurrentOutTxParam().ReceiverChainId, - cctx.LogIdentifierForCCTX()), - ) - } - medianGasPrice = medianGasPrice.MulUint64(2) // overpays gas price by 2x - cctx.GetCurrentOutTxParam().OutboundTxGasPrice = medianGasPrice.String() - gasLimit := sdk.NewUint(cctx.GetCurrentOutTxParam().OutboundTxGasLimit) - outTxGasFee := gasLimit.Mul(medianGasPrice) - - // the following logic computes outbound tx gas fee, and convert into ZETA using system uniswapv2 pool wzeta/gasZRC20 - gasZRC20, err := k.fungibleKeeper.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chain.ChainId)) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to get system contract gas coin") - } - - outTxGasFeeInZeta, err := k.fungibleKeeper.QueryUniswapv2RouterGetAmountsIn(ctx, outTxGasFee.BigInt(), gasZRC20) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to QueryUniswapv2RouterGetAmountsIn") - } - feeInZeta := types.GetProtocolFee().Add(math.NewUintFromBigInt(outTxGasFeeInZeta)) - - cctx.ZetaFees = cctx.ZetaFees.Add(feeInZeta) - - if cctx.ZetaFees.GT(cctx.InboundTxParams.Amount) { - return sdkerrors.Wrap(types.ErrNotEnoughZetaBurnt, fmt.Sprintf("feeInZeta(%s) more than zetaBurnt (%s) | Identifiers : %s ", - cctx.ZetaFees, - cctx.InboundTxParams.Amount, - cctx.LogIdentifierForCCTX()), - ) - } - - ctx.Logger().Info("Subtracting amount from inbound tx", "amount", cctx.InboundTxParams.Amount.String(), "feeInZeta", - cctx.ZetaFees.String()) - cctx.GetCurrentOutTxParam().Amount = cctx.InboundTxParams.Amount.Sub(cctx.ZetaFees) - - // ** The following logic converts the outTxGasFeeInZeta into gasZRC20 and burns it ** - // swap the outTxGasFeeInZeta portion of zeta to the real gas ZRC20 and burn it, in a temporary context. - { - coins := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(feeInZeta.BigInt()))) - err := k.bankKeeper.MintCoins(ctx, types.ModuleName, coins) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to mint coins") - } - - amounts, err := k.fungibleKeeper.CallUniswapv2RouterSwapExactETHForToken( - ctx, - types.ModuleAddressEVM, - types.ModuleAddressEVM, - outTxGasFeeInZeta, - gasZRC20, - noEthereumTxEvent, - ) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to CallUniswapv2RouterSwapExactETHForToken") - } - ctx.Logger().Info("gas fee", "outTxGasFee", outTxGasFee, "outTxGasFeeInZeta", outTxGasFeeInZeta) - ctx.Logger().Info("CallUniswapv2RouterSwapExactETHForToken", "zetaAmountIn", amounts[0], "zrc20AmountOut", amounts[1]) - err = k.fungibleKeeper.CallZRC20Burn(ctx, types.ModuleAddressEVM, gasZRC20, amounts[1], noEthereumTxEvent) - if err != nil { - return sdkerrors.Wrap(err, "PayGasInZetaAndUpdateCctx: unable to CallZRC20Burn") - } - } - - return nil -} - -// UpdateNonce sets the CCTX outbound nonce to the next nonce, and updates the nonce of blockchain state. -// It also updates the PendingNonces that is used to track the unfulfilled outbound txs. -func (k Keeper) UpdateNonce(ctx sdk.Context, receiveChainID int64, cctx *types.CrossChainTx) error { - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(receiveChainID) - if chain == nil { - return zetaObserverTypes.ErrSupportedChains - } - - nonce, found := k.GetChainNonces(ctx, chain.ChainName.String()) - if !found { - return sdkerrors.Wrap(types.ErrCannotFindReceiverNonce, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) - } - - // SET nonce - cctx.GetCurrentOutTxParam().OutboundTxTssNonce = nonce.Nonce - tss, found := k.GetTSS(ctx) - if !found { - return sdkerrors.Wrap(types.ErrCannotFindTSSKeys, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) - } - - p, found := k.GetPendingNonces(ctx, tss.TssPubkey, uint64(receiveChainID)) - if !found { - return sdkerrors.Wrap(types.ErrCannotFindPendingNonces, fmt.Sprintf("chain_id %d, nonce %d", receiveChainID, nonce.Nonce)) - } - - if p.NonceHigh != int64(nonce.Nonce) { - return sdkerrors.Wrap(types.ErrNonceMismatch, fmt.Sprintf("chain_id %d, high nonce %d, current nonce %d", receiveChainID, p.NonceHigh, nonce.Nonce)) - } - - nonce.Nonce++ - p.NonceHigh++ - k.SetChainNonces(ctx, nonce) - k.SetPendingNonces(ctx, p) - return nil -} diff --git a/x/crosschain/keeper/zeta_conversion_rate.go b/x/crosschain/keeper/zeta_conversion_rate.go index b1c0e4df61..abb43e02ec 100644 --- a/x/crosschain/keeper/zeta_conversion_rate.go +++ b/x/crosschain/keeper/zeta_conversion_rate.go @@ -30,7 +30,7 @@ func (k Keeper) ConvertGasToZeta(context context.Context, request *types.QueryCo if err != nil { return nil, status.Error(codes.NotFound, "zrc20 not found") } - outTxGasFeeInZeta, err := k.fungibleKeeper.QueryUniswapv2RouterGetAmountsIn(ctx, outTxGasFee.BigInt(), zrc20) + outTxGasFeeInZeta, err := k.fungibleKeeper.QueryUniswapV2RouterGetZetaAmountsIn(ctx, outTxGasFee.BigInt(), zrc20) if err != nil { return nil, status.Error(codes.Internal, "zQueryUniswapv2RouterGetAmountsIn failed") } diff --git a/x/crosschain/module.go b/x/crosschain/module.go index 314af4cc07..4be40efde9 100644 --- a/x/crosschain/module.go +++ b/x/crosschain/module.go @@ -107,16 +107,20 @@ type AppModule struct { keeper keeper.Keeper stakingKeeper types.StakingKeeper + authKeeper types.AccountKeeper } func NewAppModule( cdc codec.Codec, keeper keeper.Keeper, - stakingKeeper types.StakingKeeper) AppModule { + stakingKeeper types.StakingKeeper, + authKeeper types.AccountKeeper, +) AppModule { return AppModule{ AppModuleBasic: NewAppModuleBasic(cdc), keeper: keeper, stakingKeeper: stakingKeeper, + authKeeper: authKeeper, } } @@ -164,6 +168,9 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.Ra InitGenesis(ctx, am.keeper, genState) + // ensure account is created + am.authKeeper.GetModuleAccount(ctx, types.ModuleName) + return []abci.ValidatorUpdate{} } diff --git a/x/crosschain/types/cctx_utils.go b/x/crosschain/types/cctx_utils.go index d05eb24f3a..d6807b63b1 100644 --- a/x/crosschain/types/cctx_utils.go +++ b/x/crosschain/types/cctx_utils.go @@ -5,16 +5,32 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) +// GetCurrentOutTxParam returns the current outbound tx params. // There can only be one active outtx. // OutboundTxParams[0] is the original outtx, if it reverts, then // OutboundTxParams[1] is the new outtx. -func (m *CrossChainTx) GetCurrentOutTxParam() *OutboundTxParams { +func (m CrossChainTx) GetCurrentOutTxParam() *OutboundTxParams { if len(m.OutboundTxParams) == 0 { return &OutboundTxParams{} } return m.OutboundTxParams[len(m.OutboundTxParams)-1] } +// IsCurrentOutTxRevert returns true if the current outbound tx is the revert tx. +func (m CrossChainTx) IsCurrentOutTxRevert() bool { + return len(m.OutboundTxParams) == 2 +} + +// OriginalDestinationChainID returns the original destination of the outbound tx, reverted or not +// If there is no outbound tx, return -1 +func (m CrossChainTx) OriginalDestinationChainID() int64 { + if len(m.OutboundTxParams) == 0 { + return -1 + } + return m.OutboundTxParams[0].ReceiverChainId +} + +// GetAllAuthzZetaclientTxTypes returns all the authz types for zetaclient func GetAllAuthzZetaclientTxTypes() []string { return []string{ sdk.MsgTypeURL(&MsgNonceVoter{}), diff --git a/x/crosschain/types/cctx_utils_test.go b/x/crosschain/types/cctx_utils_test.go new file mode 100644 index 0000000000..4fec09f3b6 --- /dev/null +++ b/x/crosschain/types/cctx_utils_test.go @@ -0,0 +1,52 @@ +package types_test + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestCrossChainTx_GetCurrentOutTxParam(t *testing.T) { + r := rand.New(rand.NewSource(42)) + cctx := sample.CrossChainTx(t, "foo") + + cctx.OutboundTxParams = []*types.OutboundTxParams{} + require.Equal(t, &types.OutboundTxParams{}, cctx.GetCurrentOutTxParam()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r)} + require.Equal(t, cctx.OutboundTxParams[0], cctx.GetCurrentOutTxParam()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r), sample.OutboundTxParams(r)} + require.Equal(t, cctx.OutboundTxParams[1], cctx.GetCurrentOutTxParam()) +} + +func TestCrossChainTx_IsCurrentOutTxRevert(t *testing.T) { + r := rand.New(rand.NewSource(42)) + cctx := sample.CrossChainTx(t, "foo") + + cctx.OutboundTxParams = []*types.OutboundTxParams{} + require.False(t, cctx.IsCurrentOutTxRevert()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r)} + require.False(t, cctx.IsCurrentOutTxRevert()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r), sample.OutboundTxParams(r)} + require.True(t, cctx.IsCurrentOutTxRevert()) +} + +func TestCrossChainTx_OriginalDestinationChainID(t *testing.T) { + r := rand.New(rand.NewSource(42)) + cctx := sample.CrossChainTx(t, "foo") + + cctx.OutboundTxParams = []*types.OutboundTxParams{} + require.Equal(t, int64(-1), cctx.OriginalDestinationChainID()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r)} + require.Equal(t, cctx.OutboundTxParams[0].ReceiverChainId, cctx.OriginalDestinationChainID()) + + cctx.OutboundTxParams = []*types.OutboundTxParams{sample.OutboundTxParams(r), sample.OutboundTxParams(r)} + require.Equal(t, cctx.OutboundTxParams[0].ReceiverChainId, cctx.OriginalDestinationChainID()) +} diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index 413740dd60..b8191ef9fa 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -5,33 +5,37 @@ import ( ) var ( - ErrUnsupportedChain = errorsmod.Register(ModuleName, 1102, "chain parse error") - ErrInvalidChainID = errorsmod.Register(ModuleName, 1101, "chain id cannot be negative") - ErrInvalidPubKeySet = errorsmod.Register(ModuleName, 1106, "invalid pubkeyset") - ErrUnableToGetGasPrice = errorsmod.Register(ModuleName, 1107, "unable to get gas price") - ErrNotEnoughZetaBurnt = errorsmod.Register(ModuleName, 1109, "not enough zeta burnt") - ErrCannotFindReceiverNonce = errorsmod.Register(ModuleName, 1110, "cannot find receiver chain nonce") - ErrCannotFindPendingTxQueue = errorsmod.Register(ModuleName, 1111, "cannot find pending tx queue") + ErrUnsupportedChain = errorsmod.Register(ModuleName, 1102, "chain parse error") + ErrInvalidChainID = errorsmod.Register(ModuleName, 1101, "chain id cannot be negative") + ErrInvalidPubKeySet = errorsmod.Register(ModuleName, 1106, "invalid pubkeyset") + ErrUnableToGetGasPrice = errorsmod.Register(ModuleName, 1107, "unable to get gas price") + ErrNotEnoughZetaBurnt = errorsmod.Register(ModuleName, 1109, "not enough zeta burnt") + ErrCannotFindReceiverNonce = errorsmod.Register(ModuleName, 1110, "cannot find receiver chain nonce") - ErrGasCoinNotFound = errorsmod.Register(ModuleName, 1113, "Err gas coin not found for SenderChain") - ErrUnableToDepositZRC20 = errorsmod.Register(ModuleName, 1114, "Unable to deposit ZRC20 ") - ErrUnableToParseContract = errorsmod.Register(ModuleName, 1115, "Cannot parse contract and data") - ErrCannotProcessWithdrawal = errorsmod.Register(ModuleName, 1116, "Cannot process withdrawal event") - ErrForeignCoinNotFound = errorsmod.Register(ModuleName, 1118, "Err gas coin not found for SenderChain") - ErrNotEnoughPermissions = errorsmod.Register(ModuleName, 1119, "Not enough permissions for current actions") + ErrGasCoinNotFound = errorsmod.Register(ModuleName, 1113, "gas coin not found for SenderChain") + ErrUnableToParseContract = errorsmod.Register(ModuleName, 1115, "cannot parse contract and data") + ErrCannotProcessWithdrawal = errorsmod.Register(ModuleName, 1116, "cannot process withdrawal event") + ErrForeignCoinNotFound = errorsmod.Register(ModuleName, 1118, "gas coin not found for SenderChain") + ErrNotEnoughPermissions = errorsmod.Register(ModuleName, 1119, "not enough permissions for current actions") - ErrCannotFindPendingNonces = errorsmod.Register(ModuleName, 1121, "Err Cannot find pending nonces") - ErrCannotFindTSSKeys = errorsmod.Register(ModuleName, 1122, "Err Cannot find TSS keys") - ErrNonceMismatch = errorsmod.Register(ModuleName, 1123, "Err Nonce mismatch") - ErrNotFoundCoreParams = errorsmod.Register(ModuleName, 1126, "Not found chain core params") - ErrUnableToSendCoinType = errorsmod.Register(ModuleName, 1127, "Unable to send this coin type to a receiver chain") + ErrCannotFindPendingNonces = errorsmod.Register(ModuleName, 1121, "cannot find pending nonces") + ErrCannotFindTSSKeys = errorsmod.Register(ModuleName, 1122, "cannot find TSS keys") + ErrNonceMismatch = errorsmod.Register(ModuleName, 1123, "nonce mismatch") + ErrNotFoundCoreParams = errorsmod.Register(ModuleName, 1126, "not found chain core params") + ErrUnableToSendCoinType = errorsmod.Register(ModuleName, 1127, "unable to send this coin type to a receiver chain") - ErrInvalidAddress = errorsmod.Register(ModuleName, 1128, "Invalid address") - ErrDeployContract = errorsmod.Register(ModuleName, 1129, "Unable to deploy contract") - ErrUnableToUpdateTss = errorsmod.Register(ModuleName, 1130, "Unable to update TSS address") - ErrNotEnoughFunds = errorsmod.Register(ModuleName, 1131, "Not enough funds") + ErrInvalidAddress = errorsmod.Register(ModuleName, 1128, "invalid address") + ErrDeployContract = errorsmod.Register(ModuleName, 1129, "unable to deploy contract") + ErrUnableToUpdateTss = errorsmod.Register(ModuleName, 1130, "unable to update TSS address") + ErrNotEnoughGas = errorsmod.Register(ModuleName, 1131, "not enough gas") + ErrNotEnoughFunds = errorsmod.Register(ModuleName, 1132, "not enough funds") - ErrProofVerificationFail = errorsmod.Register(ModuleName, 1132, "Proof verification fail") - ErrCannotFindCctx = errorsmod.Register(ModuleName, 1133, "Cannot find cctx") - ErrStatusNotPending = errorsmod.Register(ModuleName, 1134, "Status not pending") + ErrProofVerificationFail = errorsmod.Register(ModuleName, 1133, "Proof verification fail") + ErrCannotFindCctx = errorsmod.Register(ModuleName, 1134, "Cannot find cctx") + ErrStatusNotPending = errorsmod.Register(ModuleName, 1135, "Status not pending") + + ErrCannotFindGasParams = errorsmod.Register(ModuleName, 1136, "cannot find gas params") + ErrInvalidGasAmount = errorsmod.Register(ModuleName, 1137, "invalid gas amount") + ErrNoLiquidityPool = errorsmod.Register(ModuleName, 1138, "no liquidity pool") + ErrInvalidCoinType = errorsmod.Register(ModuleName, 1139, "invalid coin type") ) diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index f6f31365b2..eaaf36b966 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -74,11 +74,23 @@ type FungibleKeeper interface { GetAllForeignCoins(ctx sdk.Context) (list []fungibletypes.ForeignCoins) SetForeignCoins(ctx sdk.Context, foreignCoins fungibletypes.ForeignCoins) GetAllForeignCoinsForChain(ctx sdk.Context, foreignChainID int64) (list []fungibletypes.ForeignCoins) + GetForeignCoinFromAsset(ctx sdk.Context, asset string, chainID int64) (fungibletypes.ForeignCoins, bool) GetSystemContract(ctx sdk.Context) (val fungibletypes.SystemContract, found bool) QuerySystemContractGasCoinZRC20(ctx sdk.Context, chainID *big.Int) (eth.Address, error) - QueryUniswapv2RouterGetAmountsIn(ctx sdk.Context, amountOut *big.Int, outZRC4 eth.Address) (*big.Int, error) + GetUniswapV2Router02Address(ctx sdk.Context) (eth.Address, error) + QueryUniswapV2RouterGetZetaAmountsIn(ctx sdk.Context, amountOut *big.Int, outZRC4 eth.Address) (*big.Int, error) + QueryUniswapV2RouterGetZRC4AmountsIn(ctx sdk.Context, amountOut *big.Int, inZRC4 eth.Address) (*big.Int, error) + QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx sdk.Context, amountOut *big.Int, inZRC4, outZRC4 eth.Address) (*big.Int, error) + QueryGasLimit(ctx sdk.Context, contract eth.Address) (*big.Int, error) + QueryProtocolFlatFee(ctx sdk.Context, contract eth.Address) (*big.Int, error) SetGasPrice(ctx sdk.Context, chainID *big.Int, gasPrice *big.Int) (uint64, error) DepositCoinZeta(ctx sdk.Context, to eth.Address, amount *big.Int) error + DepositZRC20( + ctx sdk.Context, + contract eth.Address, + to eth.Address, + amount *big.Int, + ) (*evmtypes.MsgEthereumTxResponse, error) ZRC20DepositAndCallContract( ctx sdk.Context, from []byte, @@ -91,7 +103,16 @@ type FungibleKeeper interface { coinType common.CoinType, asset string, ) (*evmtypes.MsgEthereumTxResponse, error) - CallUniswapv2RouterSwapExactETHForToken( + CallUniswapV2RouterSwapExactTokensForTokens( + ctx sdk.Context, + sender eth.Address, + to eth.Address, + amountIn *big.Int, + inZRC4, + outZRC4 eth.Address, + noEthereumTxEvent bool, + ) (ret []*big.Int, err error) + CallUniswapV2RouterSwapExactETHForToken( ctx sdk.Context, sender eth.Address, to eth.Address, @@ -100,6 +121,14 @@ type FungibleKeeper interface { noEthereumTxEvent bool, ) ([]*big.Int, error) CallZRC20Burn(ctx sdk.Context, sender eth.Address, zrc20address eth.Address, amount *big.Int, noEthereumTxEvent bool) error + CallZRC20Approve( + ctx sdk.Context, + owner eth.Address, + zrc20address eth.Address, + spender eth.Address, + amount *big.Int, + noEthereumTxEvent bool, + ) error DeployZRC20Contract( ctx sdk.Context, name, symbol string, diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go index 19db995327..0c155cfa7a 100644 --- a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go @@ -81,15 +81,17 @@ func (k Keeper) BlockOneDeploySystemContracts(goCtx context.Context) error { return err } - _, err = k.SetupChainGasCoinAndPool(ctx, common.GoerliChain().ChainId, "ETH", "gETH", 18) + ETHZRC20Addr, err := k.SetupChainGasCoinAndPool(ctx, common.GoerliChain().ChainId, "ETH", "gETH", 18) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } + ctx.Logger().Info("Deployed ETH ZRC20 at " + ETHZRC20Addr.String()) - _, err = k.SetupChainGasCoinAndPool(ctx, common.BtcRegtestChain().ChainId, "BTC", "tBTC", 8) + BTCZRC20Addr, err := k.SetupChainGasCoinAndPool(ctx, common.BtcRegtestChain().ChainId, "BTC", "tBTC", 8) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } + ctx.Logger().Info("Deployed BTC ZRC20 at " + BTCZRC20Addr.String()) //FIXME: clean up and config the above based on localnet/testnet/mainnet diff --git a/x/fungible/keeper/deposits.go b/x/fungible/keeper/deposits.go index c95f6ed48f..8206f744bc 100644 --- a/x/fungible/keeper/deposits.go +++ b/x/fungible/keeper/deposits.go @@ -17,26 +17,28 @@ func (k Keeper) DepositCoinZeta(ctx sdk.Context, to eth.Address, amount *big.Int return k.MintZetaToEVMAccount(ctx, zetaToAddress, amount) } -func (k Keeper) ZRC20DepositAndCallContract(ctx sdk.Context, from []byte, to eth.Address, amount *big.Int, senderChain *common.Chain, - message string, contract eth.Address, data []byte, coinType common.CoinType, asset string) (*evmtypes.MsgEthereumTxResponse, error) { +func (k Keeper) ZRC20DepositAndCallContract( + ctx sdk.Context, + from []byte, + to eth.Address, + amount *big.Int, + senderChain *common.Chain, + message string, + contract eth.Address, + data []byte, + coinType common.CoinType, + asset string, +) (*evmtypes.MsgEthereumTxResponse, error) { var Zrc20Contract eth.Address var coin fungibletypes.ForeignCoins + var found bool if coinType == common.CoinType_Gas { - var found bool coin, found = k.GetGasCoinForForeignCoin(ctx, senderChain.ChainId) if !found { return nil, types.ErrGasCoinNotFound } } else { - foreignCoinList := k.GetAllForeignCoinsForChain(ctx, senderChain.ChainId) - found := false - for _, foreignCoin := range foreignCoinList { - if foreignCoin.Asset == asset && foreignCoin.ForeignChainId == senderChain.ChainId { - coin = foreignCoin - found = true - break - } - } + coin, found = k.GetForeignCoinFromAsset(ctx, asset, senderChain.ChainId) if !found { return nil, types.ErrForeignCoinNotFound } diff --git a/x/fungible/keeper/evm.go b/x/fungible/keeper/evm.go index 0f0e240ca5..c86df4d92a 100644 --- a/x/fungible/keeper/evm.go +++ b/x/fungible/keeper/evm.go @@ -39,11 +39,11 @@ var ( ) func (k Keeper) deployContract(ctx sdk.Context, metadata *bind.MetaData, ctorArguments ...interface{}) (common.Address, error) { - abi, err := metadata.GetAbi() + contractABI, err := metadata.GetAbi() if err != nil { return common.Address{}, cosmoserrors.Wrapf(types.ErrABIGet, "failed to get ABI: %s", err.Error()) } - ctorArgs, err := abi.Pack( + ctorArgs, err := contractABI.Pack( "", // function--empty string for constructor ctorArguments..., // feeToSetter ) @@ -195,11 +195,11 @@ func (k Keeper) DepositZRC20( to common.Address, amount *big.Int, ) (*evmtypes.MsgEthereumTxResponse, error) { - abi, err := zrc20.ZRC20MetaData.GetAbi() + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return nil, err } - return k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, BigIntZero, nil, true, false, "deposit", to, amount) + return k.CallEVM(ctx, *zrc20ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, true, false, "deposit", to, amount) } // DepositZRC20AndCallContract deposits into ZRC4 and call contract function in a single tx @@ -226,6 +226,43 @@ func (k Keeper) DepositZRC20AndCallContract(ctx sdk.Context, "depositAndCall", context, zrc20Addr, amount, targetContract, message) } +// QueryWithdrawGasFee returns the gas fee for a withdrawal transaction associated with a given zrc20 +func (k Keeper) QueryWithdrawGasFee(ctx sdk.Context, contract common.Address) (*big.Int, error) { + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, err + } + res, err := k.CallEVM( + ctx, + *zrc20ABI, + types.ModuleAddressEVM, + contract, + BigIntZero, + nil, + false, + false, + "withdrawGasFee", + ) + if err != nil { + return nil, err + } + + unpacked, err := zrc20ABI.Unpack("withdrawGasFee", res.Ret) + if err != nil { + return nil, err + } + if len(unpacked) < 2 { + return nil, fmt.Errorf("expect 2 returned values, got %d", len(unpacked)) + } + + GasFee, ok := unpacked[1].(*big.Int) + if !ok { + return nil, errors.New("can't read returned value as big.Int") + } + + return GasFee, nil +} + // QueryProtocolFlatFee returns the protocol flat fee associated with a given zrc20 func (k Keeper) QueryProtocolFlatFee(ctx sdk.Context, contract common.Address) (*big.Int, error) { zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() @@ -263,6 +300,43 @@ func (k Keeper) QueryProtocolFlatFee(ctx sdk.Context, contract common.Address) ( return protocolGasFee, nil } +// QueryGasLimit returns the gas limit for a withdrawal transaction associated with a given zrc20 +func (k Keeper) QueryGasLimit(ctx sdk.Context, contract common.Address) (*big.Int, error) { + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil, err + } + res, err := k.CallEVM( + ctx, + *zrc20ABI, + types.ModuleAddressEVM, + contract, + BigIntZero, + nil, + false, + false, + "GAS_LIMIT", + ) + if err != nil { + return nil, err + } + + unpacked, err := zrc20ABI.Unpack("GAS_LIMIT", res.Ret) + if err != nil { + return nil, err + } + if len(unpacked) == 0 { + return nil, fmt.Errorf("expect 1 returned values, got %d", len(unpacked)) + } + + gasLimit, ok := unpacked[0].(*big.Int) + if !ok { + return nil, errors.New("can't read returned value as big.Int") + } + + return gasLimit, nil +} + // QueryZRC20Data returns the data of a deployed ZRC20 contract func (k Keeper) QueryZRC20Data( ctx sdk.Context, @@ -274,35 +348,40 @@ func (k Keeper) QueryZRC20Data( decimalRes types.ZRC20Uint8Response ) - zrc4, _ := zrc20.ZRC20MetaData.GetAbi() + zrc4ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return types.ZRC20Data{}, sdkerrors.Wrapf( + types.ErrABIUnpack, "failed to get ABI: %s", err.Error(), + ) + } // Name - res, err := k.CallEVM(ctx, *zrc4, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "name") + res, err := k.CallEVM(ctx, *zrc4ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "name") if err != nil { return types.ZRC20Data{}, err } - if err := zrc4.UnpackIntoInterface(&nameRes, "name", res.Ret); err != nil { + if err := zrc4ABI.UnpackIntoInterface(&nameRes, "name", res.Ret); err != nil { return types.ZRC20Data{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack name: %s", err.Error()) } // Symbol - res, err = k.CallEVM(ctx, *zrc4, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "symbol") + res, err = k.CallEVM(ctx, *zrc4ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "symbol") if err != nil { return types.ZRC20Data{}, err } - if err := zrc4.UnpackIntoInterface(&symbolRes, "symbol", res.Ret); err != nil { + if err := zrc4ABI.UnpackIntoInterface(&symbolRes, "symbol", res.Ret); err != nil { return types.ZRC20Data{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack symbol: %s", err.Error()) } // Decimals - res, err = k.CallEVM(ctx, *zrc4, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "decimals") + res, err = k.CallEVM(ctx, *zrc4ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "decimals") if err != nil { return types.ZRC20Data{}, err } - if err := zrc4.UnpackIntoInterface(&decimalRes, "decimals", res.Ret); err != nil { + if err := zrc4ABI.UnpackIntoInterface(&decimalRes, "decimals", res.Ret); err != nil { return types.ZRC20Data{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack decimals: %s", err.Error()) } @@ -314,17 +393,17 @@ func (k Keeper) BalanceOfZRC4( ctx sdk.Context, contract, account common.Address, ) (*big.Int, error) { - abi, err := zrc20.ZRC20MetaData.GetAbi() + zrc4ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) } - res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "balanceOf", + res, err := k.CallEVM(ctx, *zrc4ABI, types.ModuleAddressEVM, contract, BigIntZero, nil, false, false, "balanceOf", account) if err != nil { return nil, err } - unpacked, err := abi.Unpack("balanceOf", res.Ret) + unpacked, err := zrc4ABI.Unpack("balanceOf", res.Ret) if err != nil || len(unpacked) == 0 { return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, err.Error()) } diff --git a/x/fungible/keeper/foreign_coins.go b/x/fungible/keeper/foreign_coins.go index 7e51a90be6..7450b66cd8 100644 --- a/x/fungible/keeper/foreign_coins.go +++ b/x/fungible/keeper/foreign_coins.go @@ -80,6 +80,7 @@ func (k Keeper) GetAllForeignCoins(ctx sdk.Context) (list []types.ForeignCoins) return } +// GetGasCoinForForeignCoin returns the gas coin for a given chain func (k Keeper) GetGasCoinForForeignCoin(ctx sdk.Context, chainID int64) (types.ForeignCoins, bool) { foreignCoinList := k.GetAllForeignCoinsForChain(ctx, chainID) for _, coin := range foreignCoinList { @@ -89,3 +90,14 @@ func (k Keeper) GetGasCoinForForeignCoin(ctx sdk.Context, chainID int64) (types. } return types.ForeignCoins{}, false } + +// GetForeignCoinFromAsset returns the foreign coin for a given asset for a given chain +func (k Keeper) GetForeignCoinFromAsset(ctx sdk.Context, asset string, chainID int64) (types.ForeignCoins, bool) { + foreignCoinList := k.GetAllForeignCoinsForChain(ctx, chainID) + for _, coin := range foreignCoinList { + if coin.Asset == asset && coin.ForeignChainId == chainID { + return coin, true + } + } + return types.ForeignCoins{}, false +} diff --git a/x/fungible/keeper/foreign_coins_test.go b/x/fungible/keeper/foreign_coins_test.go index 56248eb016..347630002d 100644 --- a/x/fungible/keeper/foreign_coins_test.go +++ b/x/fungible/keeper/foreign_coins_test.go @@ -2,6 +2,12 @@ package keeper_test import ( "strconv" + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/x/fungible/keeper" @@ -17,3 +23,110 @@ func createNForeignCoins(keeper *keeper.Keeper, ctx sdk.Context, n int) []types. } return items } + +func setForeignCoins(ctx sdk.Context, k *keeper.Keeper, fc ...types.ForeignCoins) { + for _, item := range fc { + k.SetForeignCoins(ctx, item) + } +} + +func TestKeeper_GetGasCoinForForeignCoin(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + + // populate + setForeignCoins(ctx, k, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_Gas, + Name: "bar", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 2, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + ForeignChainId: 2, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + ) + + fc, found := k.GetGasCoinForForeignCoin(ctx, 1) + require.True(t, found) + require.Equal(t, "bar", fc.Name) + fc, found = k.GetGasCoinForForeignCoin(ctx, 2) + require.False(t, found) + fc, found = k.GetGasCoinForForeignCoin(ctx, 3) + require.False(t, found) +} + +func TestKeeperGetForeignCoinFromAsset(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + + gasAsset := sample.EthAddress().String() + + // populate + setForeignCoins(ctx, k, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: gasAsset, + ForeignChainId: 1, + CoinType: common.CoinType_ERC20, + Name: "bar", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + ForeignChainId: 1, + CoinType: common.CoinType_Gas, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + ForeignChainId: 2, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + types.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().String(), + Asset: sample.EthAddress().String(), + ForeignChainId: 2, + CoinType: common.CoinType_ERC20, + Name: "foo", + }, + ) + + fc, found := k.GetForeignCoinFromAsset(ctx, gasAsset, 1) + require.True(t, found) + require.Equal(t, "bar", fc.Name) + fc, found = k.GetForeignCoinFromAsset(ctx, sample.EthAddress().String(), 1) + require.False(t, found) + fc, found = k.GetForeignCoinFromAsset(ctx, gasAsset, 2) + require.False(t, found) + fc, found = k.GetForeignCoinFromAsset(ctx, gasAsset, 3) + require.False(t, found) +} diff --git a/x/fungible/keeper/system_contract.go b/x/fungible/keeper/system_contract.go index 5c2c888b74..2688e2914a 100644 --- a/x/fungible/keeper/system_contract.go +++ b/x/fungible/keeper/system_contract.go @@ -54,6 +54,7 @@ func (k *Keeper) GetSystemContractAddress(ctx sdk.Context) (ethcommon.Address, e return systemAddress, nil } +// GetWZetaContractAddress returns the wzeta contract address on ZetaChain func (k *Keeper) GetWZetaContractAddress(ctx sdk.Context) (ethcommon.Address, error) { system, found := k.GetSystemContract(ctx) if !found { @@ -62,7 +63,17 @@ func (k *Keeper) GetWZetaContractAddress(ctx sdk.Context) (ethcommon.Address, er systemAddress := ethcommon.HexToAddress(system.SystemContract) sysABI, _ := systemcontract.SystemContractMetaData.GetAbi() - res, err := k.CallEVM(ctx, *sysABI, types.ModuleAddressEVM, systemAddress, BigIntZero, nil, false, false, "wZetaContractAddress") + res, err := k.CallEVM( + ctx, + *sysABI, + types.ModuleAddressEVM, + systemAddress, + BigIntZero, + nil, + false, + false, + "wZetaContractAddress", + ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to call wZetaContractAddress") } @@ -76,6 +87,7 @@ func (k *Keeper) GetWZetaContractAddress(ctx sdk.Context) (ethcommon.Address, er return wzetaResponse.Value, nil } +// GetUniswapV2FactoryAddress returns the uniswapv2 factory contract address on ZetaChain func (k *Keeper) GetUniswapV2FactoryAddress(ctx sdk.Context) (ethcommon.Address, error) { system, found := k.GetSystemContract(ctx) if !found { @@ -84,7 +96,17 @@ func (k *Keeper) GetUniswapV2FactoryAddress(ctx sdk.Context) (ethcommon.Address, systemAddress := ethcommon.HexToAddress(system.SystemContract) sysABI, _ := systemcontract.SystemContractMetaData.GetAbi() - res, err := k.CallEVM(ctx, *sysABI, types.ModuleAddressEVM, systemAddress, BigIntZero, nil, false, false, "uniswapv2FactoryAddress") + res, err := k.CallEVM( + ctx, + *sysABI, + types.ModuleAddressEVM, + systemAddress, + BigIntZero, + nil, + false, + false, + "uniswapv2FactoryAddress", + ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to call uniswapv2FactoryAddress") } @@ -98,6 +120,7 @@ func (k *Keeper) GetUniswapV2FactoryAddress(ctx sdk.Context) (ethcommon.Address, return wzetaResponse.Value, nil } +// GetUniswapV2Router02Address returns the uniswapv2 router02 address on ZetaChain func (k *Keeper) GetUniswapV2Router02Address(ctx sdk.Context) (ethcommon.Address, error) { system, found := k.GetSystemContract(ctx) if !found { @@ -106,7 +129,17 @@ func (k *Keeper) GetUniswapV2Router02Address(ctx sdk.Context) (ethcommon.Address systemAddress := ethcommon.HexToAddress(system.SystemContract) sysABI, _ := systemcontract.SystemContractMetaData.GetAbi() - res, err := k.CallEVM(ctx, *sysABI, types.ModuleAddressEVM, systemAddress, BigIntZero, nil, false, false, "uniswapv2Router02Address") + res, err := k.CallEVM( + ctx, + *sysABI, + types.ModuleAddressEVM, + systemAddress, + BigIntZero, + nil, + false, + false, + "uniswapv2Router02Address", + ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to call uniswapv2Router02Address") } @@ -120,6 +153,7 @@ func (k *Keeper) GetUniswapV2Router02Address(ctx sdk.Context) (ethcommon.Address return routerResponse.Value, nil } +// CallWZetaDeposit calls the deposit method of the wzeta contract func (k *Keeper) CallWZetaDeposit(ctx sdk.Context, sender ethcommon.Address, amount *big.Int) error { wzetaAddress, err := k.GetWZetaContractAddress(ctx) if err != nil { @@ -130,23 +164,51 @@ func (k *Keeper) CallWZetaDeposit(ctx sdk.Context, sender ethcommon.Address, amo return err } gasLimit := big.NewInt(70_000) // for some reason, GasEstimate for this contract call is always insufficient - _, err = k.CallEVM(ctx, *abi, sender, wzetaAddress, amount, gasLimit, true, false, "deposit") + + _, err = k.CallEVM( + ctx, + *abi, + sender, + wzetaAddress, + amount, + gasLimit, + true, + false, + "deposit", + ) if err != nil { return cosmoserrors.Wrapf(err, "failed to call wzeta deposit") } return nil } +// QueryWZetaBalanceOf returns the balance of the given address in the wzeta contract func (k *Keeper) QueryWZetaBalanceOf(ctx sdk.Context, addr ethcommon.Address) (*big.Int, error) { wzetaAddress, err := k.GetWZetaContractAddress(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get wzeta contract address") } - wzetaABI, _ := connectorzevm.WZETAMetaData.GetAbi() - res, err := k.CallEVM(ctx, *wzetaABI, addr, wzetaAddress, big.NewInt(0), nil, false, false, "balanceOf", addr) + wzetaABI, err := connectorzevm.WZETAMetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get wzeta abi") + } + + res, err := k.CallEVM( + ctx, + *wzetaABI, + addr, + wzetaAddress, + big.NewInt(0), + nil, + false, + false, + "balanceOf", + addr, + ) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to call balanceOf") } + type BigIntResponse struct { Value *big.Int } @@ -154,21 +216,38 @@ func (k *Keeper) QueryWZetaBalanceOf(ctx sdk.Context, addr ethcommon.Address) (* if err := wzetaABI.UnpackIntoInterface(&balanceResponse, "balanceOf", res.Ret); err != nil { return nil, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack balanceOf: %s", err.Error()) } + return balanceResponse.Value, nil } +// QuerySystemContractGasCoinZRC20 returns the gas coin zrc20 address for the given chain id func (k *Keeper) QuerySystemContractGasCoinZRC20(ctx sdk.Context, chainid *big.Int) (ethcommon.Address, error) { system, found := k.GetSystemContract(ctx) if !found { return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrStateVariableNotFound, "failed to get system contract variable") } systemAddress := ethcommon.HexToAddress(system.SystemContract) - sysABI, _ := systemcontract.SystemContractMetaData.GetAbi() + sysABI, err := systemcontract.SystemContractMetaData.GetAbi() + if err != nil { + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to get system contract abi") + } - res, err := k.CallEVM(ctx, *sysABI, types.ModuleAddressEVM, systemAddress, BigIntZero, nil, false, false, "gasCoinZRC20ByChainId", chainid) + res, err := k.CallEVM( + ctx, + *sysABI, + types.ModuleAddressEVM, + systemAddress, + BigIntZero, + nil, + false, + false, + "gasCoinZRC20ByChainId", + chainid, + ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to call gasCoinZRC20ByChainId") } + type AddressResponse struct { Value ethcommon.Address } @@ -179,14 +258,22 @@ func (k *Keeper) QuerySystemContractGasCoinZRC20(ctx sdk.Context, chainid *big.I return zrc20Res.Value, nil } -// returns the amount [in, out] -func (k *Keeper) CallUniswapv2RouterSwapExactETHForToken(ctx sdk.Context, sender ethcommon.Address, - to ethcommon.Address, amountIn *big.Int, outZRC4 ethcommon.Address, noEthereumTxEvent bool) ([]*big.Int, error) { +// CallUniswapV2RouterSwapExactTokensForTokens calls the swapExactTokensForETH method of the uniswapv2 router contract +// to swap tokens to another tokens using wZeta as intermediary +func (k *Keeper) CallUniswapV2RouterSwapExactTokensForTokens( + ctx sdk.Context, + sender ethcommon.Address, + to ethcommon.Address, + amountIn *big.Int, + inZRC4, + outZRC4 ethcommon.Address, + noEthereumTxEvent bool, +) (ret []*big.Int, err error) { routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get router abi") } - wzeta, err := k.GetWZetaContractAddress(ctx) + wzetaAddr, err := k.GetWZetaContractAddress(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") } @@ -194,10 +281,140 @@ func (k *Keeper) CallUniswapv2RouterSwapExactETHForToken(ctx sdk.Context, sender if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") } + + //function swapExactTokensForTokens( + // uint amountIn, + // uint amountOutMin, + // address[] calldata path, + // address to, + // uint deadline + //) + res, err := k.CallEVM( + ctx, + *routerABI, + sender, + routerAddress, + BigIntZero, + big.NewInt(1000_000), + true, + noEthereumTxEvent, + "swapExactTokensForTokens", + amountIn, + BigIntZero, + []ethcommon.Address{inZRC4, wzetaAddr, outZRC4}, + to, + big.NewInt(1e17), + ) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactTokensForTokens") + } + + amounts := new([3]*big.Int) + err = routerABI.UnpackIntoInterface(&amounts, "swapExactTokensForTokens", res.Ret) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to UnpackIntoInterface swapExactTokensForTokens") + } + return (*amounts)[:], nil +} + +// CallUniswapV2RouterSwapExactTokensForETH calls the swapExactTokensForETH method of the uniswapv2 router contract +func (k *Keeper) CallUniswapV2RouterSwapExactTokensForETH( + ctx sdk.Context, + sender ethcommon.Address, + to ethcommon.Address, + amountIn *big.Int, + inZRC4 ethcommon.Address, + noEthereumTxEvent bool, +) (ret []*big.Int, err error) { + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get router abi") + } + wzetaAddr, err := k.GetWZetaContractAddress(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") + } + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + } + + //function swapExactTokensForETH( + // uint amountIn, + // uint amountOutMin, + // address[] calldata path, + // address to, + // uint deadline + //) + ctx.Logger().Error("Calling swapExactTokensForETH") + res, err := k.CallEVM( + ctx, + *routerABI, + sender, + routerAddress, + BigIntZero, + big.NewInt(300_000), + true, + noEthereumTxEvent, + "swapExactTokensForETH", + amountIn, + BigIntZero, + []ethcommon.Address{inZRC4, wzetaAddr}, + to, + big.NewInt(1e17), + ) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactTokensForETH") + } + + amounts := new([2]*big.Int) + err = routerABI.UnpackIntoInterface(&amounts, "swapExactTokensForETH", res.Ret) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to UnpackIntoInterface swapExactTokensForETH") + } + return (*amounts)[:], nil +} + +// CallUniswapV2RouterSwapExactETHForToken calls the swapExactETHForTokens method of the uniswapv2 router contract +func (k *Keeper) CallUniswapV2RouterSwapExactETHForToken( + ctx sdk.Context, + sender ethcommon.Address, + to ethcommon.Address, + amountIn *big.Int, + outZRC4 ethcommon.Address, + noEthereumTxEvent bool, +) ([]*big.Int, error) { + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get router abi") + } + + wzetaAddr, err := k.GetWZetaContractAddress(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") + } + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + } + //function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable //returns (uint[] memory amounts); - res, err := k.CallEVM(ctx, *routerABI, sender, routerAddress, amountIn, big.NewInt(300_000), true, noEthereumTxEvent, - "swapExactETHForTokens", BigIntZero, []ethcommon.Address{wzeta, outZRC4}, to, big.NewInt(1e17)) + res, err := k.CallEVM( + ctx, + *routerABI, + sender, + routerAddress, + amountIn, + big.NewInt(300_000), + true, + noEthereumTxEvent, + "swapExactETHForTokens", + BigIntZero, + []ethcommon.Address{wzetaAddr, outZRC4}, + to, + big.NewInt(1e17), + ) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactETHForTokens") } @@ -210,13 +427,20 @@ func (k *Keeper) CallUniswapv2RouterSwapExactETHForToken(ctx sdk.Context, sender return (*amounts)[:], nil } -func (k *Keeper) CallUniswapv2RouterSwapEthForExactToken(ctx sdk.Context, sender ethcommon.Address, to ethcommon.Address, maxAmountIn *big.Int, amountOut *big.Int, outZRC4 ethcommon.Address) ([]*big.Int, error) { - +// CallUniswapV2RouterSwapEthForExactToken calls the swapETHForExactTokens method of the uniswapv2 router contract +func (k *Keeper) CallUniswapV2RouterSwapEthForExactToken( + ctx sdk.Context, + sender ethcommon.Address, + to ethcommon.Address, + maxAmountIn *big.Int, + amountOut *big.Int, + outZRC4 ethcommon.Address, +) ([]*big.Int, error) { routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get router abi") } - wzeta, err := k.GetWZetaContractAddress(ctx) + wzetaAddr, err := k.GetWZetaContractAddress(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") } @@ -224,10 +448,24 @@ func (k *Keeper) CallUniswapv2RouterSwapEthForExactToken(ctx sdk.Context, sender if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") } + //function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) //returns (uint[] memory amounts); - res, err := k.CallEVM(ctx, *routerABI, sender, routerAddress, maxAmountIn, big.NewInt(300_000), true, false, - "swapETHForExactTokens", amountOut, []ethcommon.Address{wzeta, outZRC4}, to, big.NewInt(1e17)) + res, err := k.CallEVM( + ctx, + *routerABI, + sender, + routerAddress, + maxAmountIn, + big.NewInt(300_000), + true, + false, + "swapETHForExactTokens", + amountOut, + []ethcommon.Address{wzetaAddr, outZRC4}, + to, + big.NewInt(1e17), + ) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapETHForExactTokens") } @@ -240,24 +478,77 @@ func (k *Keeper) CallUniswapv2RouterSwapEthForExactToken(ctx sdk.Context, sender return (*amounts)[:], nil } -func (k *Keeper) QueryUniswapv2RouterGetAmountsIn(ctx sdk.Context, amountOut *big.Int, outZRC4 ethcommon.Address) (*big.Int, error) { +// QueryUniswapV2RouterGetZetaAmountsIn returns the amount of zeta needed to buy the given amount of ZRC4 tokens +func (k *Keeper) QueryUniswapV2RouterGetZetaAmountsIn(ctx sdk.Context, amountOut *big.Int, outZRC4 ethcommon.Address) (*big.Int, error) { routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get router abi") } - wzeta, err := k.GetWZetaContractAddress(ctx) + wzetaAddr, err := k.GetWZetaContractAddress(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") } + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + } + + //function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts); + k.Logger(ctx).Info("getAmountsIn", "outZRC20", outZRC4.Hex(), "amountOut", amountOut, "wzeta", wzetaAddr.Hex()) + res, err := k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + BigIntZero, + nil, + false, + false, + "getAmountsIn", + amountOut, + []ethcommon.Address{wzetaAddr, outZRC4}, + ) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") + } + + amounts := new([2]*big.Int) + err = routerABI.UnpackIntoInterface(&amounts, "getAmountsIn", res.Ret) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to unpack getAmountsIn") + } + return (*amounts)[0], nil +} +// QueryUniswapV2RouterGetZRC4AmountsIn returns the amount of ZRC4 tokens needed to buy the given amount of zeta +func (k *Keeper) QueryUniswapV2RouterGetZRC4AmountsIn(ctx sdk.Context, amountOut *big.Int, inZRC4 ethcommon.Address) (*big.Int, error) { + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get router abi") + } + wzetaAddr, err := k.GetWZetaContractAddress(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") + } routerAddress, err := k.GetUniswapV2Router02Address(ctx) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") } + //function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts); - k.Logger(ctx).Info("getAmountsIn", "outZRC20", outZRC4.Hex(), "amountOut", amountOut, "wzeta", wzeta.Hex()) - res, err := k.CallEVM(ctx, *routerABI, types.ModuleAddressEVM, routerAddress, BigIntZero, nil, false, false, - "getAmountsIn", amountOut, []ethcommon.Address{wzeta, outZRC4}) + res, err := k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + BigIntZero, + nil, + false, + false, + "getAmountsIn", + amountOut, + []ethcommon.Address{inZRC4, wzetaAddr}, + ) if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") } @@ -270,30 +561,92 @@ func (k *Keeper) QueryUniswapv2RouterGetAmountsIn(ctx sdk.Context, amountOut *bi return (*amounts)[0], nil } -func (k *Keeper) CallZRC20Burn(ctx sdk.Context, sender ethcommon.Address, zrc20address ethcommon.Address, - amount *big.Int, noEthereumTxEvent bool) error { +// QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn returns the amount of ZRC4 tokens needed to buy another ZRC4 token, it uses the WZeta contract as a bridge +func (k *Keeper) QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx sdk.Context, amountOut *big.Int, inZRC4, outZRC4 ethcommon.Address) (*big.Int, error) { + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to get router abi") + } + wzetaAddr, err := k.GetWZetaContractAddress(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetWZetaContractAddress") + } + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + } + + //function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts); + res, err := k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + BigIntZero, + nil, + false, + false, + "getAmountsIn", + amountOut, + []ethcommon.Address{inZRC4, wzetaAddr, outZRC4}, + ) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") + } + + amounts := new([3]*big.Int) + err = routerABI.UnpackIntoInterface(&amounts, "getAmountsIn", res.Ret) + if err != nil { + return nil, cosmoserrors.Wrapf(err, "failed to unpack getAmountsIn") + } + return (*amounts)[0], nil +} + +// CallZRC20Burn calls the burn method of the zrc20 contract +func (k *Keeper) CallZRC20Burn( + ctx sdk.Context, + sender ethcommon.Address, + zrc20address ethcommon.Address, + amount *big.Int, + noEthereumTxEvent bool, +) error { zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return cosmoserrors.Wrapf(err, "failed to get zrc20 abi") } - _, err = k.CallEVM(ctx, *zrc20ABI, sender, zrc20address, big.NewInt(0), big.NewInt(100_000), true, noEthereumTxEvent, - "burn", amount) + + _, err = k.CallEVM( + ctx, + *zrc20ABI, + sender, + zrc20address, + big.NewInt(0), + big.NewInt(100_000), + true, + noEthereumTxEvent, + "burn", + amount, + ) if err != nil { return cosmoserrors.Wrapf(err, "failed to CallEVM method burn") } + return nil } +// CallZRC20Deposit calls the deposit method of the zrc20 contract func (k *Keeper) CallZRC20Deposit( ctx sdk.Context, sender ethcommon.Address, zrc20address ethcommon.Address, to ethcommon.Address, - amount *big.Int) error { + amount *big.Int, +) error { zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { return cosmoserrors.Wrapf(err, "failed to get zrc20 abi") } + _, err = k.CallEVM( ctx, *zrc20ABI, @@ -312,3 +665,37 @@ func (k *Keeper) CallZRC20Deposit( } return nil } + +// CallZRC20Approve calls the approve method of the zrc20 contract +func (k *Keeper) CallZRC20Approve( + ctx sdk.Context, + owner ethcommon.Address, + zrc20address ethcommon.Address, + spender ethcommon.Address, + amount *big.Int, + noEthereumTxEvent bool, +) error { + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return cosmoserrors.Wrapf(err, "failed to get zrc20 abi") + } + + _, err = k.CallEVM( + ctx, + *zrc20ABI, + owner, + zrc20address, + BigIntZero, + nil, + true, + noEthereumTxEvent, + "approve", + spender, + amount, + ) + if err != nil { + return cosmoserrors.Wrapf(err, "failed to CallEVM method approve") + } + + return nil +} diff --git a/x/observer/types/core_params_testnet.go b/x/observer/types/core_params_testnet.go index 1505f1ca01..b7c4cb07bb 100644 --- a/x/observer/types/core_params_testnet.go +++ b/x/observer/types/core_params_testnet.go @@ -14,9 +14,10 @@ func GetCoreParams() CoreParamsList { params := CoreParamsList{ CoreParams: []*CoreParams{ { - ChainId: common.GoerliChain().ChainId, - ConfirmationCount: 6, - ZetaTokenContractAddress: "", + ChainId: common.GoerliChain().ChainId, + ConfirmationCount: 6, + // This is the actual Zeta token Goerli testnet, we need to specify this address for the integration tests to pass + ZetaTokenContractAddress: "0x0000c304d2934c00db1d51995b9f6996affd17c0", ConnectorContractAddress: "", Erc20CustodyContractAddress: "", InTxTicker: 12, diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 1d77e6fb5a..0a6ce3f698 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -784,8 +784,22 @@ func (ob *EVMChainClient) observeInTX() error { ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation!: %s", event.Raw.TxHash.Hex()) continue } + + // get the sender of the event's transaction + tx, _, err := ob.EvmClient.TransactionByHash(context.Background(), event.Raw.TxHash) + if err != nil { + ob.logger.ExternalChainWatcher.Error().Err(err).Msg(fmt.Sprintf("failed to get transaction by hash: %s", event.Raw.TxHash.Hex())) + continue + } + signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) + sender, err := signer.Sender(tx) + if err != nil { + ob.logger.ExternalChainWatcher.Error().Err(err).Msg(fmt.Sprintf("can't recover the sender from the tx hash: %s", event.Raw.TxHash.Hex())) + continue + } + zetaHash, err := ob.zetaClient.PostSend( - "", + sender.Hex(), ob.chain.ChainId, "", clienttypes.BytesToEthHex(event.Recipient), @@ -803,7 +817,7 @@ func (ob *EVMChainClient) observeInTX() error { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting to zeta core") continue } - ob.logger.ExternalChainWatcher.Info().Msgf("ZRC20Cusotdy Deposited event detected and reported: PostSend zeta tx: %s", zetaHash) + ob.logger.ExternalChainWatcher.Info().Msgf("ZRC20Custody Deposited event detected and reported: PostSend zeta tx: %s", zetaHash) } }() diff --git a/zetaclient/tx.go b/zetaclient/tx.go index 4e0b0b150c..e88e469044 100644 --- a/zetaclient/tx.go +++ b/zetaclient/tx.go @@ -20,7 +20,7 @@ const ( PostGasPriceGasLimit = 1_500_000 AddTxHashToOutTxTrackerGasLimit = 200_000 PostNonceGasLimit = 200_000 - PostSendEVMGasLimit = 1_000_000 // likely emit a lot of logs, so costly + PostSendEVMGasLimit = 1_500_000 // likely emit a lot of logs, so costly PostSendNonEVMGasLimit = 1_000_000 PostReceiveConfirmationGasLimit = 200_000 PostBlameDataGasLimit = 200_000 From 2765dc4cf069ca2a9427d8daa239c70337f3aefa Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 21 Sep 2023 18:05:45 +0200 Subject: [PATCH 8/8] test(`fungible`): increase keeper code coverage (#1128) * initialize system contract * system contract tests * update_system_contract_test * remove foreign coin * add res and fix event emit * deploy fungible coin * gas price * format imports * make generate --------- Co-authored-by: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> --- docs/openapi/openapi.swagger.yaml | 3 + proto/fungible/tx.proto | 4 +- testutil/sample/sample.go | 7 + ...blocker_deploy_system_contracts_privnet.go | 2 +- x/fungible/keeper/evm.go | 15 +- x/fungible/keeper/gas_price.go | 6 +- x/fungible/keeper/gas_price_test.go | 75 +++++++++ .../msg_server_deploy_fungible_coin_zrc20.go | 47 +++--- ..._server_deploy_fungible_coin_zrc20_test.go | 147 ++++++++++++++++ .../msg_server_remove_foreign_coin_test.go | 60 +++++++ x/fungible/keeper/msg_server_test.go | 16 -- .../msg_server_update_system_contract_test.go | 108 ++++++++++++ x/fungible/keeper/system_contract.go | 6 +- x/fungible/keeper/system_contract_test.go | 120 ++++++++++++- .../types/message_update_system_contract.go | 2 +- x/fungible/types/tx.pb.go | 158 ++++++++++++------ 16 files changed, 666 insertions(+), 110 deletions(-) create mode 100644 x/fungible/keeper/gas_price_test.go create mode 100644 x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go create mode 100644 x/fungible/keeper/msg_server_remove_foreign_coin_test.go delete mode 100644 x/fungible/keeper/msg_server_test.go create mode 100644 x/fungible/keeper/msg_server_update_system_contract_test.go diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index b6e222894a..e1cf35b007 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -50785,6 +50785,9 @@ definitions: type: boolean fungibleMsgDeployFungibleCoinZRC20Response: type: object + properties: + address: + type: string fungibleMsgRemoveForeignCoinResponse: type: object fungibleMsgUpdateContractBytecodeResponse: diff --git a/proto/fungible/tx.proto b/proto/fungible/tx.proto index 5e2b7d5299..bd7a67794a 100644 --- a/proto/fungible/tx.proto +++ b/proto/fungible/tx.proto @@ -45,7 +45,9 @@ message MsgDeployFungibleCoinZRC20 { int64 gas_limit = 8; } -message MsgDeployFungibleCoinZRC20Response {} +message MsgDeployFungibleCoinZRC20Response { + string address = 1; +} message MsgRemoveForeignCoin { string creator = 1; diff --git a/testutil/sample/sample.go b/testutil/sample/sample.go index 22b57c6cde..2eef2b61b0 100644 --- a/testutil/sample/sample.go +++ b/testutil/sample/sample.go @@ -7,6 +7,8 @@ import ( "strconv" "testing" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -113,3 +115,8 @@ func StringRandom(r *rand.Rand, length int) string { } return string(result) } + +// Coins returns a sample sdk.Coins +func Coins() sdk.Coins { + return sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewInt(42))) +} diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go index 0c155cfa7a..579767fe35 100644 --- a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go @@ -133,7 +133,7 @@ func (k Keeper) TestUpdateSystemContractAddress(goCtx context.Context) error { return sdkerrors.Wrapf(err, "failed to DeploySystemContract") } creator := k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_deploy_fungible_coin) - msg := types.NewMessageUpdateSystemContract(creator, SystemContractAddress.Hex()) + msg := types.NewMsgUpdateSystemContract(creator, SystemContractAddress.Hex()) _, err = k.UpdateSystemContract(ctx, msg) k.Logger(ctx).Info("System contract updated", "new address", SystemContractAddress.String()) return err diff --git a/x/fungible/keeper/evm.go b/x/fungible/keeper/evm.go index c86df4d92a..df739a5157 100644 --- a/x/fungible/keeper/evm.go +++ b/x/fungible/keeper/evm.go @@ -38,7 +38,8 @@ var ( ZEVMGasLimitDepositAndCall = big.NewInt(1_000_000) ) -func (k Keeper) deployContract(ctx sdk.Context, metadata *bind.MetaData, ctorArguments ...interface{}) (common.Address, error) { +// DeployContract deploys a new contract in the ZEVM +func (k Keeper) DeployContract(ctx sdk.Context, metadata *bind.MetaData, ctorArguments ...interface{}) (common.Address, error) { contractABI, err := metadata.GetAbi() if err != nil { return common.Address{}, cosmoserrors.Wrapf(types.ErrABIGet, "failed to get ABI: %s", err.Error()) @@ -104,7 +105,7 @@ func (k Keeper) DeployZRC20Contract( if !found { return common.Address{}, cosmoserrors.Wrapf(types.ErrSystemContractNotFound, "system contract not found") } - contractAddr, err := k.deployContract(ctx, zrc20.ZRC20MetaData, + contractAddr, err := k.DeployContract(ctx, zrc20.ZRC20MetaData, name, // name symbol, // symbol decimals, // decimals @@ -134,7 +135,7 @@ func (k Keeper) DeployZRC20Contract( func (k Keeper) DeploySystemContract(ctx sdk.Context, wzeta common.Address, v2factory common.Address, router02 common.Address) (common.Address, error) { system, _ := k.GetSystemContract(ctx) - contractAddr, err := k.deployContract(ctx, systemcontract.SystemContractMetaData, wzeta, v2factory, router02) + contractAddr, err := k.DeployContract(ctx, systemcontract.SystemContractMetaData, wzeta, v2factory, router02) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "failed to deploy SystemContract") } @@ -150,7 +151,7 @@ func (k Keeper) DeployUniswapV2Factory(ctx sdk.Context) (common.Address, error) // https://etherscan.io/address/0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f#code refFactoryBytecode := "0x608060405234801561001057600080fd5b506040516136863803806136868339818101604052602081101561003357600080fd5b5051600180546001600160a01b0319166001600160a01b03909216919091179055613623806100636000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a2e74af61161005b578063a2e74af6146100fd578063c9c6539614610132578063e6a439051461016d578063f46901ed146101a857610088565b8063017e7e581461008d578063094b7415146100be5780631e3dd18b146100c6578063574f2ba3146100e3575b600080fd5b6100956101db565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100956101f7565b610095600480360360208110156100dc57600080fd5b5035610213565b6100eb610247565b60408051918252519081900360200190f35b6101306004803603602081101561011357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661024d565b005b6100956004803603604081101561014857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661031a565b6100956004803603604081101561018357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661076d565b610130600480360360208110156101be57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166107a0565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6003818154811061022057fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60035490565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102d357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156103b757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056323a204944454e544943414c5f4144445245535345530000604482015290519081900360640190fd5b6000808373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16106103f45783856103f7565b84845b909250905073ffffffffffffffffffffffffffffffffffffffff821661047e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f556e697377617056323a205a45524f5f41444452455353000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526002602090815260408083208585168452909152902054161561051f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f556e697377617056323a20504149525f45584953545300000000000000000000604482015290519081900360640190fd5b6060604051806020016105319061086d565b6020820181038252601f19601f82011660405250905060008383604051602001808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140192505050604051602081830303815290604052805190602001209050808251602084016000f5604080517f485cc95500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152868116602483015291519297509087169163485cc9559160448082019260009290919082900301818387803b15801561065e57600080fd5b505af1158015610672573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff84811660008181526002602081815260408084208987168086529083528185208054978d167fffffffffffffffffffffffff000000000000000000000000000000000000000098891681179091559383528185208686528352818520805488168517905560038054600181018255958190527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b90950180549097168417909655925483519283529082015281517f0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9929181900390910190a35050505092915050565b600260209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16331461082657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b612d748061087b8339019056fe60806040526001600c5534801561001557600080fd5b506040514690806052612d228239604080519182900360520182208282018252600a8352692ab734b9bbb0b8102b1960b11b6020938401528151808301835260018152603160f81b908401528151808401919091527fbfcc8ef98ffbf7b6c3fec7bf5185b566b9863e35a9d83acd49ad6824b5969738818301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101949094523060a0808601919091528151808603909101815260c09094019052825192019190912060035550600580546001600160a01b03191633179055612c1d806101056000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80636a627842116100f9578063ba9a7a5611610097578063d21220a711610071578063d21220a7146105da578063d505accf146105e2578063dd62ed3e14610640578063fff6cae91461067b576101b9565b8063ba9a7a5614610597578063bc25cf771461059f578063c45a0155146105d2576101b9565b80637ecebe00116100d35780637ecebe00146104d757806389afcb441461050a57806395d89b4114610556578063a9059cbb1461055e576101b9565b80636a6278421461046957806370a082311461049c5780637464fc3d146104cf576101b9565b806323b872dd116101665780633644e515116101405780633644e51514610416578063485cc9551461041e5780635909c0d5146104595780635a3d549314610461576101b9565b806323b872dd146103ad57806330adf81f146103f0578063313ce567146103f8576101b9565b8063095ea7b311610197578063095ea7b3146103155780630dfe16811461036257806318160ddd14610393576101b9565b8063022c0d9f146101be57806306fdde03146102595780630902f1ac146102d6575b600080fd5b610257600480360360808110156101d457600080fd5b81359160208101359173ffffffffffffffffffffffffffffffffffffffff604083013516919081019060808101606082013564010000000081111561021857600080fd5b82018360208201111561022a57600080fd5b8035906020019184600183028401116401000000008311171561024c57600080fd5b509092509050610683565b005b610261610d57565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561029b578181015183820152602001610283565b50505050905090810190601f1680156102c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102de610d90565b604080516dffffffffffffffffffffffffffff948516815292909316602083015263ffffffff168183015290519081900360600190f35b61034e6004803603604081101561032b57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610de5565b604080519115158252519081900360200190f35b61036a610dfc565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61039b610e18565b60408051918252519081900360200190f35b61034e600480360360608110156103c357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610e1e565b61039b610efd565b610400610f21565b6040805160ff9092168252519081900360200190f35b61039b610f26565b6102576004803603604081101561043457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610f2c565b61039b611005565b61039b61100b565b61039b6004803603602081101561047f57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611011565b61039b600480360360208110156104b257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113cb565b61039b6113dd565b61039b600480360360208110156104ed57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113e3565b61053d6004803603602081101561052057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166113f5565b6040805192835260208301919091528051918290030190f35b610261611892565b61034e6004803603604081101561057457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356118cb565b61039b6118d8565b610257600480360360208110156105b557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166118de565b61036a611ad4565b61036a611af0565b610257600480360360e08110156105f857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611b0c565b61039b6004803603604081101561065657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611dd8565b610257611df5565b600c546001146106f457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55841515806107075750600084115b61075c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612b2f6025913960400191505060405180910390fd5b600080610767610d90565b5091509150816dffffffffffffffffffffffffffff168710801561079a5750806dffffffffffffffffffffffffffff1686105b6107ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612b786021913960400191505060405180910390fd5b600654600754600091829173ffffffffffffffffffffffffffffffffffffffff91821691908116908916821480159061085457508073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614155b6108bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f556e697377617056323a20494e56414c49445f544f0000000000000000000000604482015290519081900360640190fd5b8a156108d0576108d0828a8d611fdb565b89156108e1576108e1818a8c611fdb565b86156109c3578873ffffffffffffffffffffffffffffffffffffffff166310d1e85c338d8d8c8c6040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156109aa57600080fd5b505af11580156109be573d6000803e3d6000fd5b505050505b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015610a2f57600080fd5b505afa158015610a43573d6000803e3d6000fd5b505050506040513d6020811015610a5957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191955073ffffffffffffffffffffffffffffffffffffffff8316916370a0823191602480820192602092909190829003018186803b158015610acb57600080fd5b505afa158015610adf573d6000803e3d6000fd5b505050506040513d6020811015610af557600080fd5b5051925060009150506dffffffffffffffffffffffffffff85168a90038311610b1f576000610b35565b89856dffffffffffffffffffffffffffff160383035b9050600089856dffffffffffffffffffffffffffff16038311610b59576000610b6f565b89856dffffffffffffffffffffffffffff160383035b90506000821180610b805750600081115b610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180612b546024913960400191505060405180910390fd5b6000610c09610beb84600363ffffffff6121e816565b610bfd876103e863ffffffff6121e816565b9063ffffffff61226e16565b90506000610c21610beb84600363ffffffff6121e816565b9050610c59620f4240610c4d6dffffffffffffffffffffffffffff8b8116908b1663ffffffff6121e816565b9063ffffffff6121e816565b610c69838363ffffffff6121e816565b1015610cd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f556e697377617056323a204b0000000000000000000000000000000000000000604482015290519081900360640190fd5b5050610ce4848488886122e0565b60408051838152602081018390528082018d9052606081018c9052905173ffffffffffffffffffffffffffffffffffffffff8b169133917fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229181900360800190a350506001600c55505050505050505050565b6040518060400160405280600a81526020017f556e69737761702056320000000000000000000000000000000000000000000081525081565b6008546dffffffffffffffffffffffffffff808216926e0100000000000000000000000000008304909116917c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690565b6000610df233848461259c565b5060015b92915050565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610ee85773ffffffffffffffffffffffffffffffffffffffff84166000908152600260209081526040808320338452909152902054610eb6908363ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff851660009081526002602090815260408083203384529091529020555b610ef384848461260b565b5060019392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60035481565b60055473ffffffffffffffffffffffffffffffffffffffff163314610fb257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f556e697377617056323a20464f5242494444454e000000000000000000000000604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560078054929093169116179055565b60095481565b600a5481565b6000600c5460011461108457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611094610d90565b50600654604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905193955091935060009273ffffffffffffffffffffffffffffffffffffffff909116916370a08231916024808301926020929190829003018186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905192935060009273ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b1580156111b157600080fd5b505afa1580156111c5573d6000803e3d6000fd5b505050506040513d60208110156111db57600080fd5b505190506000611201836dffffffffffffffffffffffffffff871663ffffffff61226e16565b90506000611225836dffffffffffffffffffffffffffff871663ffffffff61226e16565b9050600061123387876126ec565b600054909150806112705761125c6103e8610bfd611257878763ffffffff6121e816565b612878565b985061126b60006103e86128ca565b6112cd565b6112ca6dffffffffffffffffffffffffffff8916611294868463ffffffff6121e816565b8161129b57fe5b046dffffffffffffffffffffffffffff89166112bd868563ffffffff6121e816565b816112c457fe5b0461297a565b98505b60008911611326576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612bc16028913960400191505060405180910390fd5b6113308a8a6128ca565b61133c86868a8a6122e0565b811561137e5760085461137a906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b6040805185815260208101859052815133927f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f928290030190a250506001600c5550949695505050505050565b60016020526000908152604090205481565b600b5481565b60046020526000908152604090205481565b600080600c5460011461146957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c81905580611479610d90565b50600654600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905194965092945073ffffffffffffffffffffffffffffffffffffffff9182169391169160009184916370a08231916024808301926020929190829003018186803b1580156114fb57600080fd5b505afa15801561150f573d6000803e3d6000fd5b505050506040513d602081101561152557600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8516916370a08231916024808301926020929190829003018186803b15801561159957600080fd5b505afa1580156115ad573d6000803e3d6000fd5b505050506040513d60208110156115c357600080fd5b5051306000908152600160205260408120549192506115e288886126ec565b600054909150806115f9848763ffffffff6121e816565b8161160057fe5b049a5080611614848663ffffffff6121e816565b8161161b57fe5b04995060008b11801561162e575060008a115b611683576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612b996028913960400191505060405180910390fd5b61168d3084612992565b611698878d8d611fdb565b6116a3868d8c611fdb565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8916916370a08231916024808301926020929190829003018186803b15801561170f57600080fd5b505afa158015611723573d6000803e3d6000fd5b505050506040513d602081101561173957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191965073ffffffffffffffffffffffffffffffffffffffff8816916370a0823191602480820192602092909190829003018186803b1580156117ab57600080fd5b505afa1580156117bf573d6000803e3d6000fd5b505050506040513d60208110156117d557600080fd5b505193506117e585858b8b6122e0565b811561182757600854611823906dffffffffffffffffffffffffffff808216916e01000000000000000000000000000090041663ffffffff6121e816565b600b555b604080518c8152602081018c9052815173ffffffffffffffffffffffffffffffffffffffff8f169233927fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496929081900390910190a35050505050505050506001600c81905550915091565b6040518060400160405280600681526020017f554e492d5632000000000000000000000000000000000000000000000000000081525081565b6000610df233848461260b565b6103e881565b600c5460011461194f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654600754600854604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff9485169490931692611a2b9285928792611a26926dffffffffffffffffffffffffffff169185916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b505afa158015611a02573d6000803e3d6000fd5b505050506040513d6020811015611a1857600080fd5b50519063ffffffff61226e16565b611fdb565b600854604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611aca9284928792611a26926e01000000000000000000000000000090046dffffffffffffffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff8616916370a0823191602480820192602092909190829003018186803b1580156119ee57600080fd5b50506001600c5550565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b42841015611b7b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f556e697377617056323a20455850495245440000000000000000000000000000604482015290519081900360640190fd5b60035473ffffffffffffffffffffffffffffffffffffffff80891660008181526004602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015611cdc573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611d5757508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611dc257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f556e697377617056323a20494e56414c49445f5349474e415455524500000000604482015290519081900360640190fd5b611dcd89898961259c565b505050505050505050565b600260209081526000928352604080842090915290825290205481565b600c54600114611e6657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f556e697377617056323a204c4f434b4544000000000000000000000000000000604482015290519081900360640190fd5b6000600c55600654604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051611fd49273ffffffffffffffffffffffffffffffffffffffff16916370a08231916024808301926020929190829003018186803b158015611edd57600080fd5b505afa158015611ef1573d6000803e3d6000fd5b505050506040513d6020811015611f0757600080fd5b5051600754604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff909216916370a0823191602480820192602092909190829003018186803b158015611f7a57600080fd5b505afa158015611f8e573d6000803e3d6000fd5b505050506040513d6020811015611fa457600080fd5b50516008546dffffffffffffffffffffffffffff808216916e0100000000000000000000000000009004166122e0565b6001600c55565b604080518082018252601981527f7472616e7366657228616464726573732c75696e743235362900000000000000602091820152815173ffffffffffffffffffffffffffffffffffffffff85811660248301526044808301869052845180840390910181526064909201845291810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251815160009460609489169392918291908083835b602083106120e157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120a4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612143576040519150601f19603f3d011682016040523d82523d6000602084013e612148565b606091505b5091509150818015612176575080511580612176575080806020019051602081101561217357600080fd5b50515b6121e157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f556e697377617056323a205452414e534645525f4641494c4544000000000000604482015290519081900360640190fd5b5050505050565b60008115806122035750508082028282828161220057fe5b04145b610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b80820382811115610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6dffffffffffffffffffffffffffff841180159061230c57506dffffffffffffffffffffffffffff8311155b61237757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f556e697377617056323a204f564552464c4f5700000000000000000000000000604482015290519081900360640190fd5b60085463ffffffff428116917c0100000000000000000000000000000000000000000000000000000000900481168203908116158015906123c757506dffffffffffffffffffffffffffff841615155b80156123e257506dffffffffffffffffffffffffffff831615155b15612492578063ffffffff16612425856123fb86612a57565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169063ffffffff612a7b16565b600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092169290920201905563ffffffff8116612465846123fb87612a57565b600a80547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216929092020190555b600880547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000166dffffffffffffffffffffffffffff888116919091177fffffffff0000000000000000000000000000ffffffffffffffffffffffffffff166e0100000000000000000000000000008883168102919091177bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff871602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260016020526040902054612641908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600160205260408082209390935590841681522054612683908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b15801561275757600080fd5b505afa15801561276b573d6000803e3d6000fd5b505050506040513d602081101561278157600080fd5b5051600b5473ffffffffffffffffffffffffffffffffffffffff821615801594509192509061286457801561285f5760006127d86112576dffffffffffffffffffffffffffff88811690881663ffffffff6121e816565b905060006127e583612878565b90508082111561285c576000612813612804848463ffffffff61226e16565b6000549063ffffffff6121e816565b905060006128388361282c86600563ffffffff6121e816565b9063ffffffff612abc16565b9050600081838161284557fe5b04905080156128585761285887826128ca565b5050505b50505b612870565b8015612870576000600b555b505092915050565b600060038211156128bb575080600160028204015b818110156128b5578091506002818285816128a457fe5b0401816128ad57fe5b04905061288d565b506128c5565b81156128c5575060015b919050565b6000546128dd908263ffffffff612abc16565b600090815573ffffffffffffffffffffffffffffffffffffffff8316815260016020526040902054612915908263ffffffff612abc16565b73ffffffffffffffffffffffffffffffffffffffff831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000818310612989578161298b565b825b9392505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260409020546129c8908263ffffffff61226e16565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081209190915554612a02908263ffffffff61226e16565b600090815560408051838152905173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a35050565b6dffffffffffffffffffffffffffff166e0100000000000000000000000000000290565b60006dffffffffffffffffffffffffffff82167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841681612ab457fe5b049392505050565b80820182811015610df657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fdfe556e697377617056323a20494e53554646494349454e545f4f55545055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f494e5055545f414d4f554e54556e697377617056323a20494e53554646494349454e545f4c4951554944495459556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4255524e4544556e697377617056323a20494e53554646494349454e545f4c49515549444954595f4d494e544544a265627a7a723158207dca18479e58487606bf70c79e44d8dee62353c9ee6d01f9a9d70885b8765f2264736f6c63430005100032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429a265627a7a723158202760f92d7fa1db6f5aa16307bad65df4ebcc8550c4b1f03755ab8dfd830c178f64736f6c63430005100032" uniswapv2factory.UniswapV2FactoryMetaData.Bin = refFactoryBytecode - contractAddr, err := k.deployContract(ctx, uniswapv2factory.UniswapV2FactoryMetaData, types.ModuleAddressEVM) + contractAddr, err := k.DeployContract(ctx, uniswapv2factory.UniswapV2FactoryMetaData, types.ModuleAddressEVM) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "UniswapV2FactoryContract") } @@ -159,7 +160,7 @@ func (k Keeper) DeployUniswapV2Factory(ctx sdk.Context) (common.Address, error) } func (k Keeper) DeployUniswapV2Router02(ctx sdk.Context, factory common.Address, wzeta common.Address) (common.Address, error) { - contractAddr, err := k.deployContract(ctx, uniswapv2router02.UniswapV2Router02MetaData, factory, wzeta) + contractAddr, err := k.DeployContract(ctx, uniswapv2router02.UniswapV2Router02MetaData, factory, wzeta) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "UniswapV2Router02") } @@ -167,7 +168,7 @@ func (k Keeper) DeployUniswapV2Router02(ctx sdk.Context, factory common.Address, } func (k Keeper) DeployWZETA(ctx sdk.Context) (common.Address, error) { - contractAddr, err := k.deployContract(ctx, wzeta.WETH9MetaData) + contractAddr, err := k.DeployContract(ctx, wzeta.WETH9MetaData) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "WZETA") } @@ -175,7 +176,7 @@ func (k Keeper) DeployWZETA(ctx sdk.Context) (common.Address, error) { } func (k Keeper) DeployConnectorZEVM(ctx sdk.Context, wzeta common.Address) (common.Address, error) { - contractAddr, err := k.deployContract(ctx, connectorzevm.ZetaConnectorZEVMMetaData, wzeta) + contractAddr, err := k.DeployContract(ctx, connectorzevm.ZetaConnectorZEVMMetaData, wzeta) if err != nil { return common.Address{}, cosmoserrors.Wrapf(err, "ZetaConnectorZEVM") } diff --git a/x/fungible/keeper/gas_price.go b/x/fungible/keeper/gas_price.go index cca8c03597..f492ddb2ec 100644 --- a/x/fungible/keeper/gas_price.go +++ b/x/fungible/keeper/gas_price.go @@ -10,7 +10,7 @@ import ( "github.com/zeta-chain/zetacore/x/fungible/types" ) -// sets gas price on the system contract in zEVM; return the gasUsed and error code +// SetGasPrice sets gas price on the system contract in zEVM; return the gasUsed and error code func (k Keeper) SetGasPrice(ctx sdk.Context, chainid *big.Int, gasPrice *big.Int) (uint64, error) { system, found := k.GetSystemContract(ctx) if !found { @@ -66,9 +66,9 @@ func (k Keeper) SetGasZetaPool(ctx sdk.Context, chainid *big.Int, pool common.Ad if err != nil { return sdkerrors.Wrapf(types.ErrABIGet, "SystemContractMetaData") } - res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, oracle, BigIntZero, nil, true, false, "SetGasZetaPool", chainid, pool) + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, oracle, BigIntZero, nil, true, false, "setGasZetaPool", chainid, pool) if err != nil || res.Failed() { - return sdkerrors.Wrapf(types.ErrContractCall, "SetGasZetaPool") + return sdkerrors.Wrapf(types.ErrContractCall, "setGasZetaPool") } return nil diff --git a/x/fungible/keeper/gas_price_test.go b/x/fungible/keeper/gas_price_test.go new file mode 100644 index 0000000000..ec1bf267d8 --- /dev/null +++ b/x/fungible/keeper/gas_price_test.go @@ -0,0 +1,75 @@ +package keeper_test + +import ( + "math/big" + "testing" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/keeper" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestKeeper_SetGasPrice(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, _, _, _, system := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + queryGasPrice := func(chainID *big.Int) *big.Int { + abi, err := systemcontract.SystemContractMetaData.GetAbi() + require.NoError(t, err) + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, system, keeper.BigIntZero, nil, false, false, "gasPriceByChainId", chainID) + require.NoError(t, err) + unpacked, err := abi.Unpack("gasPriceByChainId", res.Ret) + require.NoError(t, err) + gasPrice, ok := unpacked[0].(*big.Int) + require.True(t, ok) + return gasPrice + } + + _, err := k.SetGasPrice(ctx, big.NewInt(1), big.NewInt(42)) + require.NoError(t, err) + require.Equal(t, big.NewInt(42), queryGasPrice(big.NewInt(1))) +} + +func TestKeeper_SetGasCoin(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + gas := sample.EthAddress() + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + err := k.SetGasCoin(ctx, big.NewInt(1), gas) + require.NoError(t, err) + + found, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(1)) + require.NoError(t, err) + require.Equal(t, gas.Hex(), found.Hex()) +} + +func TestKeeper_SetGasZetaPool(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + zrc20 := sample.EthAddress() + + _, _, _, _, system := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + queryZetaPool := func(chainID *big.Int) ethcommon.Address { + abi, err := systemcontract.SystemContractMetaData.GetAbi() + require.NoError(t, err) + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, system, keeper.BigIntZero, nil, false, false, "gasZetaPoolByChainId", chainID) + require.NoError(t, err) + unpacked, err := abi.Unpack("gasZetaPoolByChainId", res.Ret) + require.NoError(t, err) + pool, ok := unpacked[0].(ethcommon.Address) + require.True(t, ok) + return pool + } + + err := k.SetGasZetaPool(ctx, big.NewInt(1), zrc20) + require.NoError(t, err) + require.NotEqual(t, ethcommon.Address{}, queryZetaPool(big.NewInt(1))) +} diff --git a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go index 41b678e349..db782a6491 100644 --- a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go +++ b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go @@ -4,6 +4,8 @@ import ( "context" "math/big" + "github.com/ethereum/go-ethereum/common" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" zetacommon "github.com/zeta-chain/zetacore/common" @@ -31,6 +33,10 @@ import ( // Only the admin policy account is authorized to broadcast this message. func (k msgServer) DeployFungibleCoinZRC20(goCtx context.Context, msg *types.MsgDeployFungibleCoinZRC20) (*types.MsgDeployFungibleCoinZRC20Response, error) { ctx := sdk.UnwrapSDKContext(goCtx) + + var address common.Address + var err error + if msg.Creator != k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_deploy_fungible_coin) { return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") } @@ -38,34 +44,35 @@ func (k msgServer) DeployFungibleCoinZRC20(goCtx context.Context, msg *types.Msg return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "decimals must be less than 256") } if msg.CoinType == zetacommon.CoinType_Gas { - _, err := k.SetupChainGasCoinAndPool(ctx, msg.ForeignChainId, msg.Name, msg.Symbol, uint8(msg.Decimals)) + address, err = k.SetupChainGasCoinAndPool(ctx, msg.ForeignChainId, msg.Name, msg.Symbol, uint8(msg.Decimals)) if err != nil { return nil, sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } } else { - addr, err := k.DeployZRC20Contract(ctx, msg.Name, msg.Symbol, uint8(msg.Decimals), msg.ForeignChainId, msg.CoinType, msg.ERC20, big.NewInt(msg.GasLimit)) + address, err = k.DeployZRC20Contract(ctx, msg.Name, msg.Symbol, uint8(msg.Decimals), msg.ForeignChainId, msg.CoinType, msg.ERC20, big.NewInt(msg.GasLimit)) if err != nil { return nil, err } + } - err = ctx.EventManager().EmitTypedEvent( - &types.EventZRC20Deployed{ - MsgTypeUrl: sdk.MsgTypeURL(&types.MsgDeployFungibleCoinZRC20{}), - ChainId: msg.ForeignChainId, - Contract: addr.String(), - Name: msg.Name, - Symbol: msg.Symbol, - Decimals: int64(msg.Decimals), - CoinType: msg.CoinType, - Erc20: msg.ERC20, - GasLimit: msg.GasLimit, - }, - ) - if err != nil { - return nil, sdkerrors.Wrapf(err, "failed to emit event") - } - + err = ctx.EventManager().EmitTypedEvent( + &types.EventZRC20Deployed{ + MsgTypeUrl: sdk.MsgTypeURL(&types.MsgDeployFungibleCoinZRC20{}), + ChainId: msg.ForeignChainId, + Contract: address.String(), + Name: msg.Name, + Symbol: msg.Symbol, + Decimals: int64(msg.Decimals), + CoinType: msg.CoinType, + Erc20: msg.ERC20, + GasLimit: msg.GasLimit, + }, + ) + if err != nil { + return nil, sdkerrors.Wrapf(err, "failed to emit event") } - return &types.MsgDeployFungibleCoinZRC20Response{}, nil + return &types.MsgDeployFungibleCoinZRC20Response{ + Address: address.Hex(), + }, nil } diff --git a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go new file mode 100644 index 0000000000..5eef132e3f --- /dev/null +++ b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go @@ -0,0 +1,147 @@ +package keeper_test + +import ( + "math/big" + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/keeper" + "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_DeployFungibleCoinZRC20(t *testing.T) { + t.Run("can deploy a new zrc20", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + res, err := msgServer.DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + admin, + sample.EthAddress().Hex(), + chainID, + 8, + "foo", + "foo", + common.CoinType_Gas, + 1000000, + )) + require.NoError(t, err) + gasAddress := res.Address + assertContractDeployment(t, sdkk.EvmKeeper, ctx, ethcommon.HexToAddress(gasAddress)) + + // can retrieve the gas coin + foreignCoin, found := k.GetForeignCoins(ctx, gasAddress) + require.True(t, found) + require.Equal(t, foreignCoin.CoinType, common.CoinType_Gas) + require.Contains(t, foreignCoin.Name, "foo") + + gas, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.NoError(t, err) + require.Equal(t, gasAddress, gas.Hex()) + + // can deploy non-gas zrc20 + res, err = msgServer.DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + admin, + sample.EthAddress().Hex(), + chainID, + 8, + "bar", + "bar", + common.CoinType_ERC20, + 1000000, + )) + require.NoError(t, err) + assertContractDeployment(t, sdkk.EvmKeeper, ctx, ethcommon.HexToAddress(res.Address)) + + foreignCoin, found = k.GetForeignCoins(ctx, res.Address) + require.True(t, found) + require.Equal(t, foreignCoin.CoinType, common.CoinType_ERC20) + require.Contains(t, foreignCoin.Name, "bar") + + // gas should remain the same + gas, err = k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.NoError(t, err) + require.NotEqual(t, res.Address, gas.Hex()) + require.Equal(t, gasAddress, gas.Hex()) + }) + + t.Run("should not deploy a new zrc20 if not admin", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // should not deploy a new zrc20 if not admin + _, err := keeper.NewMsgServerImpl(*k).DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + sample.AccAddress(), + sample.EthAddress().Hex(), + chainID, + 8, + "foo", + "foo", + common.CoinType_Gas, + 1000000, + )) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should not deploy a new zrc20 with wrong decimal", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // should not deploy a new zrc20 if not admin + _, err := keeper.NewMsgServerImpl(*k).DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + admin, + sample.EthAddress().Hex(), + chainID, + 256, + "foo", + "foo", + common.CoinType_Gas, + 1000000, + )) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) + }) + + t.Run("should not deploy a new zrc20 with invalid chain ID", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // should not deploy a new zrc20 if not admin + _, err := keeper.NewMsgServerImpl(*k).DeployFungibleCoinZRC20(ctx, types.NewMsgDeployFungibleCoinZRC20( + admin, + sample.EthAddress().Hex(), + 9999999, + 8, + "foo", + "foo", + common.CoinType_Gas, + 1000000, + )) + require.Error(t, err) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + }) +} diff --git a/x/fungible/keeper/msg_server_remove_foreign_coin_test.go b/x/fungible/keeper/msg_server_remove_foreign_coin_test.go new file mode 100644 index 0000000000..c866d81f21 --- /dev/null +++ b/x/fungible/keeper/msg_server_remove_foreign_coin_test.go @@ -0,0 +1,60 @@ +package keeper_test + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/keeper" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestMsgServer_RemoveForeignCoin(t *testing.T) { + t.Run("can remove a foreign coin", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foo", "foo") + + _, found := k.GetForeignCoins(ctx, zrc20.Hex()) + require.True(t, found) + + _, err := msgServer.RemoveForeignCoin(ctx, types.NewMsgRemoveForeignCoin(admin, zrc20.Hex())) + require.NoError(t, err) + _, found = k.GetForeignCoins(ctx, zrc20.Hex()) + require.False(t, found) + }) + + t.Run("should fail if not admin", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foo", "foo") + + _, err := msgServer.RemoveForeignCoin(ctx, types.NewMsgRemoveForeignCoin(sample.AccAddress(), zrc20.Hex())) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should fail if not found", func(t *testing.T) { + k, ctx, _, zk := keepertest.FungibleKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + _, err := msgServer.RemoveForeignCoin(ctx, types.NewMsgRemoveForeignCoin(admin, sample.EthAddress().Hex())) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) + }) +} diff --git a/x/fungible/keeper/msg_server_test.go b/x/fungible/keeper/msg_server_test.go deleted file mode 100644 index b4b4427f8e..0000000000 --- a/x/fungible/keeper/msg_server_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package keeper_test - -import ( - "context" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - keepertest "github.com/zeta-chain/zetacore/testutil/keeper" - "github.com/zeta-chain/zetacore/x/fungible/keeper" - "github.com/zeta-chain/zetacore/x/fungible/types" -) - -func setupMsgServer(t testing.TB) (types.MsgServer, context.Context) { - k, ctx, _, _ := keepertest.FungibleKeeper(t) - return keeper.NewMsgServerImpl(*k), sdk.WrapSDKContext(ctx) -} diff --git a/x/fungible/keeper/msg_server_update_system_contract_test.go b/x/fungible/keeper/msg_server_update_system_contract_test.go new file mode 100644 index 0000000000..1d38265022 --- /dev/null +++ b/x/fungible/keeper/msg_server_update_system_contract_test.go @@ -0,0 +1,108 @@ +package keeper_test + +import ( + "math/big" + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" + zetacommon "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/fungible/keeper" + "github.com/zeta-chain/zetacore/x/fungible/types" +) + +func TestKeeper_UpdateSystemContract(t *testing.T) { + t.Run("can update the system contract", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + queryZRC20SystemContract := func(contract common.Address) string { + abi, err := zrc20.ZRC20MetaData.GetAbi() + require.NoError(t, err) + res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, contract, keeper.BigIntZero, nil, false, false, "SYSTEM_CONTRACT_ADDRESS") + require.NoError(t, err) + unpacked, err := abi.Unpack("SYSTEM_CONTRACT_ADDRESS", res.Ret) + require.NoError(t, err) + address, ok := unpacked[0].(common.Address) + require.True(t, ok) + return address.Hex() + } + + chains := zetacommon.DefaultChainsList() + require.True(t, len(chains) > 1) + require.NotNil(t, chains[0]) + require.NotNil(t, chains[1]) + chainID1 := chains[0].ChainId + chainID2 := chains[1].ChainId + + wzeta, factory, router, _, oldSystemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + gas1 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID1, "foo", "foo") + gas2 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID2, "bar", "bar") + + // deploy a new system contracts + newSystemContract, err := k.DeployContract(ctx, systemcontract.SystemContractMetaData, wzeta, factory, router) + require.NoError(t, err) + require.NotEqual(t, oldSystemContract, newSystemContract) + + // can update the system contract + _, err = k.UpdateSystemContract(ctx, types.NewMsgUpdateSystemContract(admin, newSystemContract.Hex())) + require.NoError(t, err) + + // can retrieve the system contract + sc, found := k.GetSystemContract(ctx) + require.True(t, found) + require.Equal(t, newSystemContract.Hex(), sc.SystemContract) + + // check gas updated + foundGas1, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID1)) + require.NoError(t, err) + require.Equal(t, gas1, foundGas1) + foundGas2, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID2)) + require.NoError(t, err) + require.Equal(t, gas2, foundGas2) + + require.Equal(t, newSystemContract.Hex(), queryZRC20SystemContract(gas1)) + require.Equal(t, newSystemContract.Hex(), queryZRC20SystemContract(gas2)) + }) + + t.Run("should not update the system contract if not admin", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // deploy a new system contracts + wzeta, factory, router, _, oldSystemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + newSystemContract, err := k.DeployContract(ctx, systemcontract.SystemContractMetaData, wzeta, factory, router) + require.NoError(t, err) + require.NotEqual(t, oldSystemContract, newSystemContract) + + // should not update the system contract if not admin + _, err = k.UpdateSystemContract(ctx, types.NewMsgUpdateSystemContract(sample.AccAddress(), newSystemContract.Hex())) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + }) + + t.Run("should not update the system contract if invalid address", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + admin := sample.AccAddress() + setAdminDeployFungibleCoin(ctx, zk, admin) + + // deploy a new system contracts + wzeta, factory, router, _, oldSystemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + newSystemContract, err := k.DeployContract(ctx, systemcontract.SystemContractMetaData, wzeta, factory, router) + require.NoError(t, err) + require.NotEqual(t, oldSystemContract, newSystemContract) + + // should not update the system contract if invalid address + _, err = k.UpdateSystemContract(ctx, types.NewMsgUpdateSystemContract(admin, "invalid")) + require.Error(t, err) + require.ErrorIs(t, err, sdkerrors.ErrInvalidAddress) + }) +} diff --git a/x/fungible/keeper/system_contract.go b/x/fungible/keeper/system_contract.go index 2688e2914a..b49141b031 100644 --- a/x/fungible/keeper/system_contract.go +++ b/x/fungible/keeper/system_contract.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/connectorzevm.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/wzeta.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" @@ -188,9 +187,10 @@ func (k *Keeper) QueryWZetaBalanceOf(ctx sdk.Context, addr ethcommon.Address) (* if err != nil { return nil, cosmoserrors.Wrapf(err, "failed to get wzeta contract address") } - wzetaABI, err := connectorzevm.WZETAMetaData.GetAbi() + + wzetaABI, err := wzeta.WETH9MetaData.GetAbi() if err != nil { - return nil, cosmoserrors.Wrapf(err, "failed to get wzeta abi") + return nil, cosmoserrors.Wrapf(err, "failed to get ABI") } res, err := k.CallEVM( diff --git a/x/fungible/keeper/system_contract_test.go b/x/fungible/keeper/system_contract_test.go index ff60389a13..3874f52435 100644 --- a/x/fungible/keeper/system_contract_test.go +++ b/x/fungible/keeper/system_contract_test.go @@ -1,16 +1,126 @@ package keeper_test import ( - "fmt" + "math/big" "testing" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/fungible/types" ) func TestKeeper_GetSystemContract(t *testing.T) { - keeper, ctx, _, _ := keepertest.FungibleKeeper(t) - keeper.SetSystemContract(ctx, types.SystemContract{SystemContract: "test"}) - val, b := keeper.GetSystemContract(ctx) - fmt.Println(val, b) + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.SetSystemContract(ctx, types.SystemContract{SystemContract: "test"}) + val, found := k.GetSystemContract(ctx) + require.True(t, found) + require.Equal(t, types.SystemContract{SystemContract: "test"}, val) + + // can remove contract + k.RemoveSystemContract(ctx) + _, found = k.GetSystemContract(ctx) + require.False(t, found) +} + +func TestKeeper_GetSystemContractAddress(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetSystemContractAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + _, _, _, _, systemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetSystemContractAddress(ctx) + require.NoError(t, err) + require.Equal(t, systemContract, found) +} + +func TestKeeper_GetWZetaContractAddress(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetWZetaContractAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + wzeta, _, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetWZetaContractAddress(ctx) + require.NoError(t, err) + require.Equal(t, wzeta, found) +} + +func TestKeeper_GetUniswapV2FactoryAddress(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetUniswapV2FactoryAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + _, factory, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetUniswapV2FactoryAddress(ctx) + require.NoError(t, err) + require.Equal(t, factory, found) +} + +func TestKeeper_GetUniswapV2Router02Address(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetUniswapV2Router02Address(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + _, _, router, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetUniswapV2Router02Address(ctx) + require.NoError(t, err) + require.Equal(t, router, found) +} + +func TestKeeper_CallWZetaDeposit(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // mint tokens + addr := sample.Bech32AccAddress() + ethAddr := common.BytesToAddress(addr.Bytes()) + coins := sample.Coins() + err := sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sample.Coins()) + require.NoError(t, err) + err = sdkk.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) + require.NoError(t, err) + + // fail if no system contract + err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) + require.Error(t, err) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // deposit + err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) + require.NoError(t, err) + + balance, err := k.QueryWZetaBalanceOf(ctx, ethAddr) + require.NoError(t, err) + require.Equal(t, big.NewInt(42), balance) +} + +func TestKeeper_QuerySystemContractGasCoinZRC20(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + found, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.NoError(t, err) + require.Equal(t, zrc20, found) } diff --git a/x/fungible/types/message_update_system_contract.go b/x/fungible/types/message_update_system_contract.go index 201aad573f..b6879f2ff6 100644 --- a/x/fungible/types/message_update_system_contract.go +++ b/x/fungible/types/message_update_system_contract.go @@ -10,7 +10,7 @@ const TypeMsgUpdateSystemContract = "update_system_contract" var _ sdk.Msg = &MsgUpdateSystemContract{} -func NewMessageUpdateSystemContract(creator string, systemContractAddr string) *MsgUpdateSystemContract { +func NewMsgUpdateSystemContract(creator string, systemContractAddr string) *MsgUpdateSystemContract { return &MsgUpdateSystemContract{ Creator: creator, NewSystemContractAddress: systemContractAddr, diff --git a/x/fungible/types/tx.pb.go b/x/fungible/types/tx.pb.go index eafc374a03..62cb8d4ac8 100644 --- a/x/fungible/types/tx.pb.go +++ b/x/fungible/types/tx.pb.go @@ -334,6 +334,7 @@ func (m *MsgDeployFungibleCoinZRC20) GetGasLimit() int64 { } type MsgDeployFungibleCoinZRC20Response struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` } func (m *MsgDeployFungibleCoinZRC20Response) Reset() { *m = MsgDeployFungibleCoinZRC20Response{} } @@ -369,6 +370,13 @@ func (m *MsgDeployFungibleCoinZRC20Response) XXX_DiscardUnknown() { var xxx_messageInfo_MsgDeployFungibleCoinZRC20Response proto.InternalMessageInfo +func (m *MsgDeployFungibleCoinZRC20Response) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + type MsgRemoveForeignCoin struct { Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` @@ -676,59 +684,60 @@ func init() { func init() { proto.RegisterFile("fungible/tx.proto", fileDescriptor_197fdedece277fa0) } var fileDescriptor_197fdedece277fa0 = []byte{ - // 831 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4d, 0x6f, 0xdb, 0x36, - 0x18, 0xb6, 0xe2, 0xc6, 0x89, 0xdf, 0xb5, 0x8e, 0xc3, 0x19, 0xad, 0xa6, 0x0c, 0x4e, 0xaa, 0x0e, - 0xa8, 0x57, 0x20, 0x52, 0xe6, 0x7d, 0x14, 0x03, 0xf6, 0x81, 0xc4, 0x6d, 0xb0, 0x02, 0xf3, 0x56, - 0x28, 0x33, 0x86, 0xf5, 0x22, 0xd0, 0x12, 0x23, 0x0b, 0xb3, 0x48, 0x43, 0xa4, 0xe7, 0xba, 0xb7, - 0x5d, 0x7b, 0x2a, 0xb6, 0xff, 0xb1, 0xdb, 0xfe, 0x43, 0x8f, 0x3d, 0x0e, 0x3b, 0x14, 0x43, 0x72, - 0xd9, 0xcf, 0x28, 0x44, 0x7d, 0x54, 0x76, 0x2c, 0x3b, 0xcd, 0x49, 0x7c, 0xe9, 0xf7, 0x7d, 0xf8, - 0x3c, 0xe4, 0xf3, 0xd2, 0x84, 0xed, 0xd3, 0x31, 0xf5, 0xfc, 0xfe, 0x90, 0x98, 0xe2, 0xa9, 0x31, - 0x0a, 0x99, 0x60, 0x68, 0xe7, 0x19, 0x11, 0xd8, 0x19, 0x60, 0x9f, 0x1a, 0x72, 0xc4, 0x42, 0x62, - 0xa4, 0x59, 0xda, 0xfb, 0x0e, 0x0b, 0x02, 0x46, 0xcd, 0xf8, 0x13, 0x57, 0x68, 0x0d, 0x8f, 0x79, - 0x4c, 0x0e, 0xcd, 0x68, 0x14, 0xcf, 0xea, 0x7f, 0x2b, 0xf0, 0x41, 0x97, 0x7b, 0xbd, 0x91, 0x8b, - 0x05, 0x79, 0x62, 0x75, 0xda, 0x07, 0x3f, 0xfb, 0x62, 0xe0, 0x86, 0x78, 0x72, 0x4c, 0x08, 0x52, - 0x61, 0xc3, 0x09, 0x09, 0x16, 0x2c, 0x54, 0x95, 0x3d, 0xa5, 0x55, 0xb5, 0xd2, 0x10, 0xdd, 0x81, - 0x1b, 0xcf, 0x42, 0xa7, 0x7d, 0x60, 0x63, 0xd7, 0x0d, 0x09, 0xe7, 0xea, 0x9a, 0xfc, 0xfd, 0xba, - 0x9c, 0x3c, 0x8c, 0xe7, 0xd0, 0x2f, 0x50, 0xa7, 0x64, 0x62, 0x4f, 0x12, 0x44, 0xfb, 0x94, 0x10, - 0xb5, 0x12, 0xe5, 0x1d, 0x99, 0x2f, 0x5f, 0xef, 0x96, 0xfe, 0x7d, 0xbd, 0x7b, 0xd7, 0xf3, 0xc5, - 0x60, 0xdc, 0x37, 0x1c, 0x16, 0x98, 0x0e, 0xe3, 0x01, 0xe3, 0xc9, 0x67, 0x9f, 0xbb, 0xbf, 0x9a, - 0x62, 0x3a, 0x22, 0xdc, 0xe8, 0xf9, 0x54, 0x58, 0x35, 0x4a, 0x26, 0x39, 0x66, 0xfa, 0x1d, 0xb8, - 0x5d, 0x48, 0xdb, 0x22, 0x7c, 0xc4, 0x28, 0x27, 0x7a, 0x08, 0xb7, 0xb2, 0xa4, 0x93, 0x29, 0x17, - 0x24, 0xe8, 0x30, 0x2a, 0x42, 0xec, 0x88, 0x25, 0xca, 0xbe, 0x86, 0x9d, 0x88, 0x34, 0x97, 0xf9, - 0xb6, 0x93, 0x14, 0xcc, 0xe9, 0x54, 0x29, 0x99, 0xcc, 0x22, 0x26, 0x9a, 0xf5, 0xdb, 0xb0, 0x5b, - 0xb0, 0x66, 0x46, 0xeb, 0xf9, 0x1a, 0x68, 0x5d, 0xee, 0x3d, 0x20, 0xa3, 0x21, 0x9b, 0x1e, 0x27, - 0x87, 0xd6, 0x61, 0x3e, 0x95, 0x42, 0x96, 0x50, 0x6b, 0xc0, 0xfa, 0xc3, 0x28, 0x25, 0x21, 0x11, - 0x07, 0xa8, 0x05, 0xf5, 0x53, 0x16, 0x12, 0xdf, 0xa3, 0xb6, 0x34, 0x84, 0xed, 0xbb, 0x6a, 0x79, - 0x4f, 0x69, 0x95, 0xad, 0x5a, 0x32, 0xdf, 0x89, 0xa6, 0x1f, 0xb9, 0x48, 0x83, 0x4d, 0x97, 0x38, - 0x7e, 0x80, 0x87, 0x5c, 0xbd, 0xb6, 0xa7, 0xb4, 0x6e, 0x58, 0x59, 0x8c, 0x10, 0x5c, 0xa3, 0x38, - 0x20, 0xea, 0xba, 0x84, 0x96, 0x63, 0x74, 0x13, 0x2a, 0x7c, 0x1a, 0xf4, 0xd9, 0x30, 0x3e, 0x35, - 0x2b, 0x89, 0xd0, 0x3e, 0x54, 0x1d, 0xe6, 0x53, 0x3b, 0x3a, 0x1f, 0x75, 0x63, 0x4f, 0x69, 0xd5, - 0xda, 0x75, 0x23, 0x31, 0x5b, 0xa4, 0xe3, 0xa7, 0xe9, 0x88, 0x58, 0x9b, 0x4e, 0x32, 0x42, 0x3b, - 0x50, 0xf5, 0x30, 0xb7, 0x87, 0x7e, 0xe0, 0x0b, 0x75, 0x53, 0x32, 0xdb, 0xf4, 0x30, 0xff, 0x3e, - 0x8a, 0xf5, 0x8f, 0x40, 0x2f, 0xde, 0x8b, 0x6c, 0xcb, 0x1e, 0x40, 0xa3, 0xcb, 0x3d, 0x8b, 0x04, - 0xec, 0x37, 0x72, 0x9c, 0x88, 0x62, 0x3e, 0x5d, 0xb2, 0x57, 0xa9, 0x9e, 0xb5, 0xb7, 0x7a, 0xf4, - 0x26, 0x7c, 0xb8, 0x08, 0x25, 0x5b, 0xe5, 0x8f, 0x7c, 0x33, 0xa4, 0xc7, 0x76, 0x34, 0x15, 0xc4, - 0x61, 0xee, 0xb2, 0x66, 0xf8, 0x18, 0xea, 0x05, 0x3e, 0xd9, 0x72, 0x66, 0xed, 0x81, 0x0e, 0xa0, - 0x11, 0xb9, 0xab, 0x9f, 0x80, 0x66, 0xe9, 0x65, 0x99, 0x8e, 0x28, 0x99, 0xa4, 0xeb, 0xa5, 0x86, - 0xfa, 0x31, 0xe7, 0xf4, 0x79, 0x4e, 0x29, 0x73, 0x74, 0x0f, 0xb6, 0x67, 0x60, 0x07, 0x98, 0x0f, - 0x24, 0xcb, 0xeb, 0xd6, 0x56, 0x0e, 0xf3, 0x3b, 0xcc, 0x07, 0xfa, 0x5f, 0x8a, 0xb4, 0x5f, 0xae, - 0x77, 0x1e, 0xe3, 0x31, 0x27, 0xee, 0x89, 0xc0, 0x62, 0xcc, 0x97, 0xc8, 0xbc, 0x0b, 0x5b, 0x33, - 0x3d, 0x4f, 0x22, 0x95, 0xe5, 0x56, 0xd5, 0xaa, 0xe5, 0xbb, 0x9e, 0x70, 0xd4, 0x85, 0x0a, 0x76, - 0x84, 0xcf, 0xa8, 0x94, 0x55, 0x6b, 0x7f, 0x6e, 0x2c, 0xb9, 0xad, 0x8c, 0x98, 0x48, 0x9e, 0xc3, - 0xa1, 0x2c, 0xb6, 0x12, 0x90, 0xc4, 0x22, 0x05, 0x7c, 0xd3, 0x2d, 0xb8, 0xd7, 0x06, 0xb5, 0x08, - 0x09, 0x55, 0x61, 0xfd, 0xf1, 0x61, 0xef, 0xe4, 0x61, 0xbd, 0x84, 0xde, 0x83, 0x8d, 0xde, 0x0f, - 0x71, 0xa0, 0xb4, 0xff, 0xaf, 0x40, 0xb9, 0xcb, 0x3d, 0xf4, 0xa7, 0x02, 0xb7, 0x8a, 0xda, 0xf1, - 0xfe, 0x52, 0xf2, 0xc5, 0xde, 0xd5, 0xbe, 0xbd, 0x62, 0x61, 0x76, 0xa8, 0xbf, 0x2b, 0xb0, 0x7d, - 0xd1, 0xf2, 0x9f, 0xac, 0x82, 0xbd, 0x50, 0xa2, 0x7d, 0xf9, 0xce, 0x25, 0x19, 0x87, 0xe7, 0x0a, - 0x34, 0x16, 0x5e, 0xa0, 0x9f, 0xad, 0xc2, 0x5c, 0x54, 0xa5, 0x7d, 0x75, 0x95, 0xaa, 0x8c, 0xcc, - 0x0b, 0x05, 0x6e, 0x16, 0xfc, 0x53, 0x7d, 0x71, 0x39, 0xe0, 0xf9, 0x3a, 0xed, 0x9b, 0xab, 0xd5, - 0x2d, 0xa0, 0x74, 0xe1, 0xbe, 0xb8, 0x24, 0xa5, 0xf9, 0xba, 0xcb, 0x52, 0x2a, 0xbc, 0x0b, 0x22, - 0x33, 0x17, 0x35, 0xf7, 0xfd, 0x77, 0x90, 0x9b, 0x2f, 0x5c, 0x6d, 0xe6, 0x15, 0xed, 0x79, 0xf4, - 0xe8, 0xe5, 0x59, 0x53, 0x79, 0x75, 0xd6, 0x54, 0xfe, 0x3b, 0x6b, 0x2a, 0x2f, 0xce, 0x9b, 0xa5, - 0x57, 0xe7, 0xcd, 0xd2, 0x3f, 0xe7, 0xcd, 0xd2, 0x13, 0x33, 0xf7, 0x06, 0x88, 0xa0, 0xf7, 0xe5, - 0x2a, 0x66, 0xba, 0x8a, 0xf9, 0xd4, 0x7c, 0xfb, 0xfc, 0x89, 0x1e, 0x04, 0xfd, 0x8a, 0x7c, 0xba, - 0x7c, 0xfa, 0x26, 0x00, 0x00, 0xff, 0xff, 0x05, 0x67, 0x8a, 0xaa, 0x17, 0x09, 0x00, 0x00, + // 843 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x16, 0xad, 0x58, 0xb6, 0xa6, 0x89, 0x2c, 0x6f, 0x85, 0x84, 0xa5, 0x0b, 0xd9, 0x61, 0x0a, + 0x44, 0x0d, 0x60, 0xd2, 0x55, 0x7f, 0x82, 0x02, 0x6d, 0x0a, 0x5b, 0x89, 0xd1, 0x00, 0x55, 0x1b, + 0xd0, 0x15, 0x8a, 0xe6, 0x42, 0xac, 0xc8, 0x35, 0x45, 0x54, 0xdc, 0x15, 0xb8, 0xab, 0x2a, 0xca, + 0xad, 0xd7, 0x9c, 0x82, 0xf6, 0x3d, 0x7a, 0xeb, 0x3b, 0xe4, 0x98, 0x63, 0xd1, 0x43, 0x50, 0xd8, + 0x97, 0x3e, 0x46, 0xc1, 0xe5, 0x4f, 0x28, 0x59, 0x94, 0x1c, 0x9f, 0xb8, 0xb3, 0x9a, 0xf9, 0xf6, + 0x9b, 0x99, 0x6f, 0x56, 0x0b, 0xdb, 0xa7, 0x63, 0xea, 0xf9, 0xfd, 0x21, 0x31, 0xc5, 0x33, 0x63, + 0x14, 0x32, 0xc1, 0xd0, 0xce, 0x73, 0x22, 0xb0, 0x33, 0xc0, 0x3e, 0x35, 0xe4, 0x8a, 0x85, 0xc4, + 0x48, 0xbd, 0xb4, 0xf7, 0x1d, 0x16, 0x04, 0x8c, 0x9a, 0xf1, 0x27, 0x8e, 0xd0, 0x1a, 0x1e, 0xf3, + 0x98, 0x5c, 0x9a, 0xd1, 0x2a, 0xde, 0xd5, 0xff, 0x52, 0xe0, 0x83, 0x2e, 0xf7, 0x7a, 0x23, 0x17, + 0x0b, 0xf2, 0xd4, 0xea, 0xb4, 0x0f, 0x7e, 0xf2, 0xc5, 0xc0, 0x0d, 0xf1, 0xe4, 0x98, 0x10, 0xa4, + 0xc2, 0x86, 0x13, 0x12, 0x2c, 0x58, 0xa8, 0x2a, 0x7b, 0x4a, 0xab, 0x6a, 0xa5, 0x26, 0xba, 0x03, + 0x37, 0x9e, 0x87, 0x4e, 0xfb, 0xc0, 0xc6, 0xae, 0x1b, 0x12, 0xce, 0xd5, 0x35, 0xf9, 0xfb, 0x75, + 0xb9, 0x79, 0x18, 0xef, 0xa1, 0x9f, 0xa1, 0x4e, 0xc9, 0xc4, 0x9e, 0x24, 0x88, 0xf6, 0x29, 0x21, + 0x6a, 0x25, 0xf2, 0x3b, 0x32, 0x5f, 0xbd, 0xd9, 0x2d, 0xfd, 0xf3, 0x66, 0xf7, 0xae, 0xe7, 0x8b, + 0xc1, 0xb8, 0x6f, 0x38, 0x2c, 0x30, 0x1d, 0xc6, 0x03, 0xc6, 0x93, 0xcf, 0x3e, 0x77, 0x7f, 0x31, + 0xc5, 0x74, 0x44, 0xb8, 0xd1, 0xf3, 0xa9, 0xb0, 0x6a, 0x94, 0x4c, 0x72, 0xcc, 0xf4, 0x3b, 0x70, + 0xbb, 0x90, 0xb6, 0x45, 0xf8, 0x88, 0x51, 0x4e, 0xf4, 0x10, 0x6e, 0x65, 0x4e, 0x27, 0x53, 0x2e, + 0x48, 0xd0, 0x61, 0x54, 0x84, 0xd8, 0x11, 0x4b, 0x32, 0xfb, 0x1a, 0x76, 0x22, 0xd2, 0x5c, 0xfa, + 0xdb, 0x4e, 0x12, 0x30, 0x97, 0xa7, 0x4a, 0xc9, 0x64, 0x16, 0x31, 0xc9, 0x59, 0xbf, 0x0d, 0xbb, + 0x05, 0x67, 0x66, 0xb4, 0x5e, 0xac, 0x81, 0xd6, 0xe5, 0xde, 0x43, 0x32, 0x1a, 0xb2, 0xe9, 0x71, + 0xd2, 0xb4, 0x0e, 0xf3, 0xa9, 0x4c, 0x64, 0x09, 0xb5, 0x06, 0xac, 0x3f, 0x8a, 0x5c, 0x12, 0x12, + 0xb1, 0x81, 0x5a, 0x50, 0x3f, 0x65, 0x21, 0xf1, 0x3d, 0x6a, 0x4b, 0x41, 0xd8, 0xbe, 0xab, 0x96, + 0xf7, 0x94, 0x56, 0xd9, 0xaa, 0x25, 0xfb, 0x9d, 0x68, 0xfb, 0xb1, 0x8b, 0x34, 0xd8, 0x74, 0x89, + 0xe3, 0x07, 0x78, 0xc8, 0xd5, 0x6b, 0x7b, 0x4a, 0xeb, 0x86, 0x95, 0xd9, 0x08, 0xc1, 0x35, 0x8a, + 0x03, 0xa2, 0xae, 0x4b, 0x68, 0xb9, 0x46, 0x37, 0xa1, 0xc2, 0xa7, 0x41, 0x9f, 0x0d, 0xe3, 0xae, + 0x59, 0x89, 0x85, 0xf6, 0xa1, 0xea, 0x30, 0x9f, 0xda, 0x51, 0x7f, 0xd4, 0x8d, 0x3d, 0xa5, 0x55, + 0x6b, 0xd7, 0x8d, 0x44, 0x6c, 0x51, 0x1e, 0x3f, 0x4e, 0x47, 0xc4, 0xda, 0x74, 0x92, 0x15, 0xda, + 0x81, 0xaa, 0x87, 0xb9, 0x3d, 0xf4, 0x03, 0x5f, 0xa8, 0x9b, 0x92, 0xd9, 0xa6, 0x87, 0xf9, 0x77, + 0x91, 0xad, 0x3f, 0x00, 0xbd, 0xb8, 0x16, 0x69, 0xc9, 0xa2, 0x9a, 0xa4, 0x0d, 0x48, 0x6a, 0x92, + 0x98, 0xfa, 0x43, 0x68, 0x74, 0xb9, 0x67, 0x91, 0x80, 0xfd, 0x4a, 0x8e, 0x93, 0x74, 0x99, 0x4f, + 0x97, 0x54, 0x31, 0xcd, 0x74, 0xed, 0x6d, 0xa6, 0x7a, 0x13, 0x3e, 0x5c, 0x84, 0x92, 0xb5, 0xec, + 0xf7, 0xfc, 0x98, 0xa4, 0x0d, 0x3d, 0x9a, 0x0a, 0xe2, 0x30, 0x77, 0xd9, 0x98, 0x7c, 0x0c, 0xf5, + 0x02, 0x05, 0x6d, 0x39, 0xb3, 0xc2, 0x41, 0x07, 0xd0, 0x88, 0x74, 0xd7, 0x4f, 0x40, 0x33, 0xf7, + 0xb2, 0x74, 0x47, 0x94, 0x4c, 0xd2, 0xf3, 0x52, 0xa9, 0xfd, 0x90, 0x9b, 0x81, 0x79, 0x4e, 0x59, + 0xe5, 0xee, 0xc1, 0xf6, 0x0c, 0xec, 0x00, 0xf3, 0x81, 0x64, 0x79, 0xdd, 0xda, 0xca, 0x61, 0x7e, + 0x8b, 0xf9, 0x40, 0xff, 0x53, 0x91, 0xc2, 0xcc, 0x4d, 0xd5, 0x13, 0x3c, 0xe6, 0xc4, 0x3d, 0x11, + 0x58, 0x8c, 0xf9, 0x92, 0x34, 0xef, 0xc2, 0xd6, 0xcc, 0x6d, 0x40, 0xa2, 0x2c, 0xcb, 0xad, 0xaa, + 0x55, 0xcb, 0xdf, 0x07, 0x84, 0xa3, 0x2e, 0x54, 0xb0, 0x23, 0x7c, 0x46, 0x65, 0x5a, 0xb5, 0xf6, + 0xe7, 0xc6, 0x92, 0x7b, 0xcc, 0x88, 0x89, 0xe4, 0x39, 0x1c, 0xca, 0x60, 0x2b, 0x01, 0xd1, 0x3f, + 0x92, 0xe2, 0x29, 0xe0, 0x9b, 0x96, 0xe0, 0x5e, 0x1b, 0xd4, 0x22, 0x24, 0x54, 0x85, 0xf5, 0x27, + 0x87, 0xbd, 0x93, 0x47, 0xf5, 0x12, 0x7a, 0x0f, 0x36, 0x7a, 0xdf, 0xc7, 0x86, 0xd2, 0xfe, 0xaf, + 0x02, 0xe5, 0x2e, 0xf7, 0xd0, 0x1f, 0x0a, 0xdc, 0x2a, 0x1a, 0xd4, 0xfb, 0x4b, 0xc9, 0x17, 0xab, + 0x5a, 0xfb, 0xe6, 0x8a, 0x81, 0x59, 0x53, 0x7f, 0x53, 0x60, 0xfb, 0xa2, 0xe4, 0x3f, 0x59, 0x05, + 0x7b, 0x21, 0x44, 0xfb, 0xf2, 0x9d, 0x43, 0x32, 0x0e, 0x2f, 0x14, 0x68, 0x2c, 0xbc, 0x5a, 0x3f, + 0x5b, 0x85, 0xb9, 0x28, 0x4a, 0xfb, 0xea, 0x2a, 0x51, 0x19, 0x99, 0x97, 0x0a, 0xdc, 0x2c, 0xf8, + 0x0f, 0xfb, 0xe2, 0x72, 0xc0, 0xf3, 0x71, 0xda, 0x83, 0xab, 0xc5, 0x2d, 0xa0, 0x74, 0xe1, 0xbe, + 0xb8, 0x24, 0xa5, 0xf9, 0xb8, 0xcb, 0x52, 0x2a, 0xbc, 0x0b, 0x22, 0x31, 0x17, 0x0d, 0xf7, 0xfd, + 0x77, 0x48, 0x37, 0x1f, 0xb8, 0x5a, 0xcc, 0x2b, 0xc6, 0xf3, 0xe8, 0xf1, 0xab, 0xb3, 0xa6, 0xf2, + 0xfa, 0xac, 0xa9, 0xfc, 0x7b, 0xd6, 0x54, 0x5e, 0x9e, 0x37, 0x4b, 0xaf, 0xcf, 0x9b, 0xa5, 0xbf, + 0xcf, 0x9b, 0xa5, 0xa7, 0x66, 0xee, 0x75, 0x10, 0x41, 0xef, 0xcb, 0x53, 0xcc, 0xf4, 0x14, 0xf3, + 0x99, 0xf9, 0xf6, 0x61, 0x14, 0x3d, 0x15, 0xfa, 0x15, 0xf9, 0xa8, 0xf9, 0xf4, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x16, 0xf6, 0xee, 0xe7, 0x31, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1212,6 +1221,13 @@ func (m *MsgDeployFungibleCoinZRC20Response) MarshalToSizedBuffer(dAtA []byte) ( _ = i var l int _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintTx(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -1524,6 +1540,10 @@ func (m *MsgDeployFungibleCoinZRC20Response) Size() (n int) { } var l int _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -2269,6 +2289,38 @@ func (m *MsgDeployFungibleCoinZRC20Response) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: MsgDeployFungibleCoinZRC20Response: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:])