diff --git a/relayer/chains/cosmos/precompile/relayer/i_relayer_functions.abigen.go b/relayer/chains/cosmos/precompile/relayer/i_relayer_functions.abigen.go index cf2ee241a..a24626979 100644 --- a/relayer/chains/cosmos/precompile/relayer/i_relayer_functions.abigen.go +++ b/relayer/chains/cosmos/precompile/relayer/i_relayer_functions.abigen.go @@ -30,7 +30,7 @@ var ( // RelayerFunctionsMetaData contains all meta data concerning the RelayerFunctions contract. var RelayerFunctionsMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"acknowledgement\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"channelOpenAck\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"channelOpenConfirm\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"channelOpenInit\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"channelOpenTry\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"connectionOpenAck\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"connectionOpenConfirm\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"connectionOpenInit\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"connectionOpenTry\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"createClient\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"recvPacket\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"submitMisbehaviour\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"timeout\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"timeoutOnClose\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"updateClient\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeClient\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"acknowledgement\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"channelOpenAck\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"channelOpenConfirm\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"channelOpenInit\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"channelOpenTry\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"connectionOpenAck\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"connectionOpenConfirm\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"connectionOpenInit\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"connectionOpenTry\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"createClient\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"recvPacket\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"submitMisbehaviour\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"timeout\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"timeoutOnClose\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"updateClient\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data1\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data2\",\"type\":\"bytes\"}],\"name\":\"updateClientAndChannelOpenConfirm\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data1\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data2\",\"type\":\"bytes\"}],\"name\":\"updateClientAndChannelOpenTry\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data1\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data2\",\"type\":\"bytes\"}],\"name\":\"updateClientAndConnectionOpenConfirm\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data1\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data2\",\"type\":\"bytes\"}],\"name\":\"updateClientAndConnectionOpenTry\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeClient\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", } // RelayerFunctionsABI is the input ABI used to generate the binding from. @@ -494,6 +494,90 @@ func (_RelayerFunctions *RelayerFunctionsTransactorSession) UpdateClient(data [] return _RelayerFunctions.Contract.UpdateClient(&_RelayerFunctions.TransactOpts, data) } +// UpdateClientAndChannelOpenConfirm is a paid mutator transaction binding the contract method 0x0982b806. +// +// Solidity: function updateClientAndChannelOpenConfirm(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsTransactor) UpdateClientAndChannelOpenConfirm(opts *bind.TransactOpts, data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.contract.Transact(opts, "updateClientAndChannelOpenConfirm", data1, data2) +} + +// UpdateClientAndChannelOpenConfirm is a paid mutator transaction binding the contract method 0x0982b806. +// +// Solidity: function updateClientAndChannelOpenConfirm(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsSession) UpdateClientAndChannelOpenConfirm(data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.Contract.UpdateClientAndChannelOpenConfirm(&_RelayerFunctions.TransactOpts, data1, data2) +} + +// UpdateClientAndChannelOpenConfirm is a paid mutator transaction binding the contract method 0x0982b806. +// +// Solidity: function updateClientAndChannelOpenConfirm(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsTransactorSession) UpdateClientAndChannelOpenConfirm(data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.Contract.UpdateClientAndChannelOpenConfirm(&_RelayerFunctions.TransactOpts, data1, data2) +} + +// UpdateClientAndChannelOpenTry is a paid mutator transaction binding the contract method 0x33978088. +// +// Solidity: function updateClientAndChannelOpenTry(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsTransactor) UpdateClientAndChannelOpenTry(opts *bind.TransactOpts, data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.contract.Transact(opts, "updateClientAndChannelOpenTry", data1, data2) +} + +// UpdateClientAndChannelOpenTry is a paid mutator transaction binding the contract method 0x33978088. +// +// Solidity: function updateClientAndChannelOpenTry(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsSession) UpdateClientAndChannelOpenTry(data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.Contract.UpdateClientAndChannelOpenTry(&_RelayerFunctions.TransactOpts, data1, data2) +} + +// UpdateClientAndChannelOpenTry is a paid mutator transaction binding the contract method 0x33978088. +// +// Solidity: function updateClientAndChannelOpenTry(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsTransactorSession) UpdateClientAndChannelOpenTry(data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.Contract.UpdateClientAndChannelOpenTry(&_RelayerFunctions.TransactOpts, data1, data2) +} + +// UpdateClientAndConnectionOpenConfirm is a paid mutator transaction binding the contract method 0x70009dfc. +// +// Solidity: function updateClientAndConnectionOpenConfirm(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsTransactor) UpdateClientAndConnectionOpenConfirm(opts *bind.TransactOpts, data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.contract.Transact(opts, "updateClientAndConnectionOpenConfirm", data1, data2) +} + +// UpdateClientAndConnectionOpenConfirm is a paid mutator transaction binding the contract method 0x70009dfc. +// +// Solidity: function updateClientAndConnectionOpenConfirm(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsSession) UpdateClientAndConnectionOpenConfirm(data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.Contract.UpdateClientAndConnectionOpenConfirm(&_RelayerFunctions.TransactOpts, data1, data2) +} + +// UpdateClientAndConnectionOpenConfirm is a paid mutator transaction binding the contract method 0x70009dfc. +// +// Solidity: function updateClientAndConnectionOpenConfirm(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsTransactorSession) UpdateClientAndConnectionOpenConfirm(data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.Contract.UpdateClientAndConnectionOpenConfirm(&_RelayerFunctions.TransactOpts, data1, data2) +} + +// UpdateClientAndConnectionOpenTry is a paid mutator transaction binding the contract method 0x5f3a7169. +// +// Solidity: function updateClientAndConnectionOpenTry(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsTransactor) UpdateClientAndConnectionOpenTry(opts *bind.TransactOpts, data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.contract.Transact(opts, "updateClientAndConnectionOpenTry", data1, data2) +} + +// UpdateClientAndConnectionOpenTry is a paid mutator transaction binding the contract method 0x5f3a7169. +// +// Solidity: function updateClientAndConnectionOpenTry(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsSession) UpdateClientAndConnectionOpenTry(data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.Contract.UpdateClientAndConnectionOpenTry(&_RelayerFunctions.TransactOpts, data1, data2) +} + +// UpdateClientAndConnectionOpenTry is a paid mutator transaction binding the contract method 0x5f3a7169. +// +// Solidity: function updateClientAndConnectionOpenTry(bytes data1, bytes data2) payable returns(bool) +func (_RelayerFunctions *RelayerFunctionsTransactorSession) UpdateClientAndConnectionOpenTry(data1 []byte, data2 []byte) (*types.Transaction, error) { + return _RelayerFunctions.Contract.UpdateClientAndConnectionOpenTry(&_RelayerFunctions.TransactOpts, data1, data2) +} + // UpgradeClient is a paid mutator transaction binding the contract method 0x8a8e4c5d. // // Solidity: function upgradeClient(bytes data) payable returns(bytes) diff --git a/relayer/chains/cosmos/tx.go b/relayer/chains/cosmos/tx.go index db3bf972b..1f6f7f0de 100644 --- a/relayer/chains/cosmos/tx.go +++ b/relayer/chains/cosmos/tx.go @@ -809,10 +809,102 @@ var messageMap = map[reflect.Type]string{ reflect.TypeOf((*chantypes.MsgTimeoutOnClose)(nil)): "timeoutOnClose", } -func packData(method string, args ...interface{}) ([]byte, error) { +type methodCombo struct { + Methods []string + NewMethodName string +} + +var methodCombos = []*methodCombo{ + { + Methods: []string{ + "updateClient", + "connectionOpenTry", + }, + NewMethodName: "updateClientAndConnectionOpenTry", + }, + { + Methods: []string{ + "updateClient", + "connectionOpenConfirm", + }, + NewMethodName: "updateClientAndConnectionOpenConfirm", + }, + { + Methods: []string{ + "updateClient", + "channelOpenTry", + }, + NewMethodName: "updateClientAndChannelOpenTry", + }, + { + Methods: []string{ + "updateClient", + "channelOpenConfirm", + }, + NewMethodName: "updateClientAndChannelOpenConfirm", + }, +} + +func packData(method string, msgs ...sdk.Msg) ([]byte, error) { + args := make([]interface{}, 0, len(msgs)) + for _, m := range msgs { + input, err := proto.Marshal(m) + if err != nil { + return nil, err + } + args = append(args, input) + } return relayerABI.Pack(method, args...) } +type inputAndSigners struct { + Input []byte + Signers []sdk.AccAddress +} + +func extractMsgInputs(msgs []sdk.Msg) (results []*inputAndSigners, err error) { + for _, c := range methodCombos { + if len(msgs) < len(c.Methods) { + continue + } + + matched := true + for i, method := range c.Methods { + if messageMap[reflect.TypeOf(msgs[i])] != method { + matched = false + break + } + } + + if matched { + input, err := packData(c.NewMethodName, msgs[:len(c.Methods)]...) + if err != nil { + return nil, err + } + + results = append(results, &inputAndSigners{input, msgs[0].GetSigners()}) + msgs = msgs[len(c.Methods):] + break + } + } + + for _, m := range msgs { + t := reflect.TypeOf(m) + method, ok := messageMap[t] + if !ok { + return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T", m) + } + + input, err := packData(method, m) + if err != nil { + return nil, err + } + + results = append(results, &inputAndSigners{input, m.GetSigners()}) + } + return +} + func (cc *CosmosProvider) buildEvmMessages( ctx context.Context, txf *tx.Factory, @@ -843,12 +935,14 @@ func (cc *CosmosProvider) buildEvmMessages( var txGasLimit uint64 = 0 contractAddress := common.HexToAddress(cc.PCfg.PrecompiledContractAddress) blockNumber := new(big.Int) - for i, m := range txb.GetTx().GetMsgs() { - method, ok := messageMap[reflect.TypeOf(m)] - if !ok { - return nil, 0, sdk.Coins{}, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T", m) - } - signers := m.GetSigners() + + inputs, err := extractMsgInputs(txb.GetTx().GetMsgs()) + if err != nil { + return nil, 0, sdk.Coins{}, err + } + + for i, is := range inputs { + signers := is.Signers if len(signers) != 1 { return nil, 0, sdk.Coins{}, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "invalid signers length %d", len(signers)) } @@ -856,17 +950,9 @@ func (cc *CosmosProvider) buildEvmMessages( if err != nil { return nil, 0, sdk.Coins{}, err } - input, err := proto.Marshal(m) - if err != nil { - return nil, 0, sdk.Coins{}, err - } nonce := txf.Sequence() + uint64(i) amount := big.NewInt(0) - input, err = packData(method, input) - if err != nil { - return nil, 0, sdk.Coins{}, err - } - tx := evmtypes.NewTx(chainID, nonce, &contractAddress, amount, gasLimit, gasFeeCap, gasPrice, gasTipCap, input, ðtypes.AccessList{}) + tx := evmtypes.NewTx(chainID, nonce, &contractAddress, amount, gasLimit, gasFeeCap, gasPrice, gasTipCap, is.Input, ðtypes.AccessList{}) tx.From = from.Bytes() if err := tx.ValidateBasic(); err != nil { cc.log.Info("tx failed basic validation", zap.Error(err)) @@ -2001,8 +2087,7 @@ func (cc *CosmosProvider) calculateEvmGas(ctx context.Context, arg *evmtypes.Tra return err } var res jsonrpcMessage - err = json.Unmarshal(data, &res) - if err != nil { + if err = json.Unmarshal(data, &res); err != nil { return err } if res.Error == nil { @@ -2031,14 +2116,14 @@ func (cc *CosmosProvider) CalculateGas(ctx context.Context, txf tx.Factory, sign var gas uint64 chErr := make(chan error) - for i, m := range msgs { - go func(i int, m sdk.Msg) { - prefix, ok := messageMap[reflect.TypeOf(m)] - if !ok { - chErr <- fmt.Errorf("invalid message type %T", m) - return - } - signers := m.GetSigners() + inputs, err := extractMsgInputs(msgs) + if err != nil { + return txtypes.SimulateResponse{}, 0, err + } + + for i, is := range inputs { + go func(i int, is *inputAndSigners) { + signers := is.Signers if len(signers) == 0 { chErr <- fmt.Errorf("invalid signers length %d", len(signers)) return @@ -2048,12 +2133,7 @@ func (cc *CosmosProvider) CalculateGas(ctx context.Context, txf tx.Factory, sign chErr <- err return } - input, err := proto.Marshal(m) - if err != nil { - chErr <- err - return - } - data := hexutil.Bytes(addLengthPrefix(prefix, input)) + data := hexutil.Bytes(is.Input) nonce := hexutil.Uint64(txf.Sequence() + uint64(i)) arg := &evmtypes.TransactionArgs{ From: from, @@ -2077,9 +2157,9 @@ func (cc *CosmosProvider) CalculateGas(ctx context.Context, txf tx.Factory, sign atomic.AddUint64(&gas, g) chErr <- nil - }(i, m) + }(i, is) } - for range msgs { + for range inputs { if err = <-chErr; err != nil { return txtypes.SimulateResponse{}, 0, err }