diff --git a/CHANGELOG.md b/CHANGELOG.md index cb709ee61..c67929ce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ needed to include double quotes around the hexadecimal string. - [#2156](https://github.com/NibiruChain/nibiru/pull/2156) - test(evm-e2e): add E2E test using the Nibiru Oracle's ChainLink impl - [#2157](https://github.com/NibiruChain/nibiru/pull/2157) - fix(evm): Fix unit inconsistency related to AuthInfo.Fee and txData.Fee using effective fee - [#2160](https://github.com/NibiruChain/nibiru/pull/2160) - fix(evm-precompile): use bank.MsgServer Send in precompile IFunToken.bankMsgSend +- [#2161](https://github.com/NibiruChain/nibiru/pull/2161) - fix(evm): added tx logs events to the funtoken related txs - [#2162](https://github.com/NibiruChain/nibiru/pull/2162) - test(testutil): try retrying for 'panic: pebbledb: closed' #### Nibiru EVM | Before Audit 2 - 2024-12-06 diff --git a/eth/rpc/backend/backend_suite_test.go b/eth/rpc/backend/backend_suite_test.go index 0cc6fa7b6..a7efa8665 100644 --- a/eth/rpc/backend/backend_suite_test.go +++ b/eth/rpc/backend/backend_suite_test.go @@ -5,6 +5,7 @@ import ( "crypto/ecdsa" "fmt" "math/big" + "sync" "testing" "time" @@ -33,6 +34,9 @@ import ( "github.com/NibiruChain/nibiru/v2/x/common/testutil/testnetwork" ) +// testMutex is used to synchronize the tests which are broadcasting transactions concurrently +var testMutex sync.Mutex + var ( recipient = evmtest.NewEthPrivAcc().EthAddr amountToSend = evm.NativeToWei(big.NewInt(1)) @@ -95,7 +99,7 @@ func (s *BackendSuite) SetupSuite() { // Send Transfer TX and use the results in the tests s.Require().NoError(err) transferTxHash = s.SendNibiViaEthTransfer(recipient, amountToSend, true) - blockNumber, blockHash := WaitForReceipt(s, transferTxHash) + blockNumber, blockHash, _ := WaitForReceipt(s, transferTxHash) s.Require().NotNil(blockNumber) s.Require().NotNil(blockHash) transferTxBlockNumber = rpc.NewBlockNumber(blockNumber) @@ -104,7 +108,7 @@ func (s *BackendSuite) SetupSuite() { // Deploy test erc20 contract deployContractTxHash, contractAddress := s.DeployTestContract(true) testContractAddress = contractAddress - blockNumber, blockHash = WaitForReceipt(s, deployContractTxHash) + blockNumber, blockHash, _ = WaitForReceipt(s, deployContractTxHash) s.Require().NotNil(blockNumber) s.Require().NotNil(blockHash) deployContractBlockNumber = rpc.NewBlockNumber(blockNumber) @@ -167,22 +171,23 @@ func SendTransaction(s *BackendSuite, tx *gethcore.LegacyTx, waitForNextBlock bo return txHash } -func WaitForReceipt(s *BackendSuite, txHash gethcommon.Hash) (*big.Int, *gethcommon.Hash) { +// WaitForReceipt waits for a transaction to be included in a block, returns block number, block hash and receipt +func WaitForReceipt(s *BackendSuite, txHash gethcommon.Hash) (*big.Int, *gethcommon.Hash, *backend.TransactionReceipt) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() for { receipt, err := s.backend.GetTransactionReceipt(txHash) if err != nil { - return nil, nil + return nil, nil, nil } if receipt != nil { - return receipt.BlockNumber, &receipt.BlockHash + return receipt.BlockNumber, &receipt.BlockHash, receipt } select { case <-ctx.Done(): fmt.Println("Timeout reached, transaction not included in a block yet.") - return nil, nil + return nil, nil, nil default: time.Sleep(1 * time.Second) } @@ -191,11 +196,7 @@ func WaitForReceipt(s *BackendSuite, txHash gethcommon.Hash) (*big.Int, *gethcom // getCurrentNonce returns the current nonce of the funded account func (s *BackendSuite) getCurrentNonce(address gethcommon.Address) uint64 { - bn, err := s.backend.BlockNumber() - s.Require().NoError(err) - currentHeight := rpc.BlockNumber(bn) - - nonce, err := s.backend.GetTransactionCount(address, currentHeight) + nonce, err := s.backend.GetTransactionCount(address, rpc.EthPendingBlockNumber) s.Require().NoError(err) return uint64(*nonce) @@ -234,7 +235,7 @@ func (s *BackendSuite) buildContractCreationTx(nonce uint64) gethcore.Transactio // buildContractCallTx builds a contract call transaction func (s *BackendSuite) buildContractCallTx(nonce uint64, contractAddr gethcommon.Address) gethcore.Transaction { - // recipient := crypto.CreateAddress(s.fundedAccEthAddr, 29381) + //recipient := crypto.CreateAddress(s.fundedAccEthAddr, 29381) transferAmount := big.NewInt(100) packedArgs, err := embeds.SmartContract_TestERC20.ABI.Pack( diff --git a/eth/rpc/backend/nonce_test.go b/eth/rpc/backend/nonce_test.go index 8f79fef1e..cd35c9088 100644 --- a/eth/rpc/backend/nonce_test.go +++ b/eth/rpc/backend/nonce_test.go @@ -13,6 +13,10 @@ import ( // TestNonceIncrementWithMultipleMsgsTx tests that the nonce is incremented correctly // when multiple messages are included in a single transaction. func (s *BackendSuite) TestNonceIncrementWithMultipleMsgsTx() { + // Test is broadcasting txs. Lock to avoid nonce conflicts. + testMutex.Lock() + defer testMutex.Unlock() + nonce := s.getCurrentNonce(s.fundedAccEthAddr) // Create series of 3 tx messages. Expecting nonce to be incremented by 3 @@ -38,7 +42,7 @@ func (s *BackendSuite) TestNonceIncrementWithMultipleMsgsTx() { // Assert all transactions included in block for _, tx := range []gethcore.Transaction{creationTx, firstTransferTx, secondTransferTx} { - blockNum, blockHash := WaitForReceipt(s, tx.Hash()) + blockNum, blockHash, _ := WaitForReceipt(s, tx.Hash()) s.Require().NotNil(blockNum) s.Require().NotNil(blockHash) } diff --git a/eth/rpc/backend/tx_logs_test.go b/eth/rpc/backend/tx_logs_test.go new file mode 100644 index 000000000..262db1ff9 --- /dev/null +++ b/eth/rpc/backend/tx_logs_test.go @@ -0,0 +1,299 @@ +package backend_test + +import ( + "fmt" + "math/big" + + tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" + sdk "github.com/cosmos/cosmos-sdk/types" + gethcommon "github.com/ethereum/go-ethereum/common" + gethcore "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + + "github.com/NibiruChain/nibiru/v2/eth" + "github.com/NibiruChain/nibiru/v2/eth/rpc/backend" + "github.com/NibiruChain/nibiru/v2/x/common/testutil" + "github.com/NibiruChain/nibiru/v2/x/evm" + "github.com/NibiruChain/nibiru/v2/x/evm/embeds" + "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" + "github.com/NibiruChain/nibiru/v2/x/evm/precompile" +) + +// TestEthLogs checks that eth txs as well as funtoken txs produce tx_logs events and update tx index properly. +// To check that, we send a series of transactions: +// - 1: simple eth transfer +// - 2: deploying erc20 contract +// - 3. creating funtoken from erc20 +// - 4: creating funtoken from coin +// - 5. converting coin to erc20 +// - 6. converting erc20 born token to coin via precompile +// Each tx should emit some tx logs and emit proper tx index within ethereum tx event. +func (s *BackendSuite) TestLogs() { + // Test is broadcasting txs. Lock to avoid nonce conflicts. + testMutex.Lock() + defer testMutex.Unlock() + + // Start with fresh block + s.Require().NoError(s.network.WaitForNextBlock()) + + s.T().Log("TX1: Send simple nibi transfer") + randomEthAddr := evmtest.NewEthPrivAcc().EthAddr + txHashFirst := s.SendNibiViaEthTransfer(randomEthAddr, amountToSend, false) + + s.T().Log("TX2: Deploy ERC20 contract") + _, erc20ContractAddr := s.DeployTestContract(false) + erc20Addr, _ := eth.NewEIP55AddrFromStr(erc20ContractAddr.String()) + + s.T().Log("TX3: Create FunToken from ERC20") + nonce := s.getCurrentNonce(eth.NibiruAddrToEthAddr(s.node.Address)) + txResp, err := s.network.BroadcastMsgs(s.node.Address, &nonce, &evm.MsgCreateFunToken{ + Sender: s.node.Address.String(), + FromErc20: &erc20Addr, + }) + s.Require().NoError(err) + s.Require().NotNil(txResp) + s.Require().Equal( + uint32(0), + txResp.Code, + fmt.Sprintf("Failed to create FunToken from ERC20. RawLog: %s", txResp.RawLog), + ) + + s.T().Log("TX4: Create FunToken from unibi coin") + nonce++ + erc20FromCoinAddr := crypto.CreateAddress(evm.EVM_MODULE_ADDRESS, s.getCurrentNonce(evm.EVM_MODULE_ADDRESS)) + + txResp, err = s.network.BroadcastMsgs(s.node.Address, &nonce, &evm.MsgCreateFunToken{ + Sender: s.node.Address.String(), + FromBankDenom: evm.EVMBankDenom, + }) + s.Require().NoError(err) + s.Require().NotNil(txResp) + s.Require().Equal( + uint32(0), + txResp.Code, + fmt.Sprintf("Failed to create FunToken from unibi coin. RawLog: %s", txResp.RawLog), + ) + + s.T().Log("TX5: Convert coin to EVM") + nonce++ + txResp, err = s.network.BroadcastMsgs(s.node.Address, &nonce, &evm.MsgConvertCoinToEvm{ + Sender: s.node.Address.String(), + BankCoin: sdk.NewCoin(evm.EVMBankDenom, sdk.NewInt(1)), + ToEthAddr: eth.EIP55Addr{ + Address: s.fundedAccEthAddr, + }, + }) + s.Require().NoError(err) + s.Require().NotNil(txResp) + s.Require().Equal( + uint32(0), + txResp.Code, + fmt.Sprintf("Failed converting coin to evm. RawLog: %s", txResp.RawLog), + ) + + s.T().Log("TX6: Send erc20 token to coin using precompile") + randomNibiAddress := testutil.AccAddress() + packedArgsPass, err := embeds.SmartContract_FunToken.ABI.Pack( + "sendToBank", + erc20Addr.Address, + big.NewInt(1), + randomNibiAddress.String(), + ) + s.Require().NoError(err) + txHashLast := SendTransaction( + s, + &gethcore.LegacyTx{ + Nonce: s.getCurrentNonce(s.fundedAccEthAddr), + To: &precompile.PrecompileAddr_FunToken, + Data: packedArgsPass, + Gas: 1_500_000, + GasPrice: big.NewInt(1), + }, + false, + ) + + // Wait for all txs to be included in a block + blockNumFirstTx, _, _ := WaitForReceipt(s, txHashFirst) + blockNumLastTx, _, _ := WaitForReceipt(s, txHashLast) + s.Require().NotNil(blockNumFirstTx) + s.Require().NotNil(blockNumLastTx) + + // Check tx logs for each tx + type logsCheck struct { + txInfo string + logs []*gethcore.Log + expectEthTx bool + } + checks := []logsCheck{ + { + txInfo: "TX1 - simple eth transfer, should have empty logs", + logs: nil, + expectEthTx: true, + }, + { + txInfo: "TX2 - deploying erc20 contract, should have logs", + logs: []*gethcore.Log{ + // minting initial balance to the account + { + Address: erc20ContractAddr, + Topics: []gethcommon.Hash{ + crypto.Keccak256Hash([]byte("Transfer(address,address,uint256)")), + gethcommon.Address{}.Hash(), + s.fundedAccEthAddr.Hash(), + }, + }, + }, + expectEthTx: true, + }, + { + txInfo: "TX3 - create FunToken from ERC20, no eth tx, no logs", + logs: nil, + expectEthTx: false, + }, + { + txInfo: "TX4 - create FunToken from unibi coin, no eth tx, logs for contract deployment", + logs: []*gethcore.Log{ + // contract ownership to evm module + { + Address: erc20FromCoinAddr, + Topics: []gethcommon.Hash{ + crypto.Keccak256Hash([]byte("OwnershipTransferred(address,address)")), + gethcommon.Address{}.Hash(), + evm.EVM_MODULE_ADDRESS.Hash(), + }, + }, + }, + expectEthTx: false, + }, + { + txInfo: "TX5 - Convert coin to EVM, no eth tx, logs for minting tokens to the account", + logs: []*gethcore.Log{ + // minting to the account + { + Address: erc20FromCoinAddr, + Topics: []gethcommon.Hash{ + crypto.Keccak256Hash([]byte("Transfer(address,address,uint256)")), + gethcommon.Address{}.Hash(), + s.fundedAccEthAddr.Hash(), + }, + }, + }, + expectEthTx: false, + }, + { + txInfo: "TX6 - Send erc20 token to coin using precompile, eth tx, logs for transferring tokens to evm module", + logs: []*gethcore.Log{ + // transfer from account to evm module + { + Address: erc20ContractAddr, + Topics: []gethcommon.Hash{ + crypto.Keccak256Hash([]byte("Transfer(address,address,uint256)")), + s.fundedAccEthAddr.Hash(), + evm.EVM_MODULE_ADDRESS.Hash(), + }, + }, + }, + expectEthTx: true, + }, + } + + // Getting block results. Note: txs could be included in more than one block + blockNumber := blockNumFirstTx.Int64() + blockRes, err := s.backend.TendermintBlockResultByNumber(&blockNumber) + s.Require().NoError(err) + s.Require().NotNil(blockRes) + txIndex := 0 + ethTxIndex := 0 + for idx, check := range checks { + if txIndex+1 > len(blockRes.TxsResults) { + blockNumber++ + if blockNumber > blockNumLastTx.Int64() { + s.Fail("TX %d not found in block results", idx) + } + txIndex = 0 + ethTxIndex = 0 + blockRes, err = s.backend.TendermintBlockResultByNumber(&blockNumber) + s.Require().NoError(err) + s.Require().NotNil(blockRes) + } + s.assertTxLogsAndTxIndex(blockRes, txIndex, ethTxIndex, check.logs, check.expectEthTx, check.txInfo) + txIndex++ + if check.expectEthTx { + ethTxIndex++ + } + } +} + +// assertTxLogsAndTxIndex gets tx results from the block and checks tx logs and tx index. +func (s *BackendSuite) assertTxLogsAndTxIndex( + blockRes *tmrpctypes.ResultBlockResults, + txIndex int, + ethTxIndex int, + expectedTxLogs []*gethcore.Log, + expectedEthTx bool, + txInfo string, +) { + txResults := blockRes.TxsResults[txIndex] + s.Require().Equal(uint32(0x0), txResults.Code, "tx failed, %s. RawLog: %s", txInfo, txResults.Log) + + events := blockRes.TxsResults[txIndex].Events + + foundEthTx := false + for _, event := range events { + if event.Type == evm.TypeUrlEventTxLog { + logs, err := backend.ParseTxLogsFromEvent(event) + s.Require().NoError(err) + if len(expectedTxLogs) > 0 { + s.Require().GreaterOrEqual(len(logs), len(expectedTxLogs)) + s.assertTxLogsMatch(expectedTxLogs, logs, txInfo) + } else { + s.Require().Nil(logs) + } + } + if event.Type == evm.TypeUrlEventEthereumTx { + foundEthTx = true + if !expectedEthTx { + s.Fail("unexpected EventEthereumTx event for non-eth tx, %s", txInfo) + } + ethereumTx, err := evm.EventEthereumTxFromABCIEvent(event) + s.Require().NoError(err) + s.Require().Equal( + fmt.Sprintf("%d", ethTxIndex), + ethereumTx.Index, + "tx index mismatch, %s", txInfo, + ) + } + } + if expectedEthTx && !foundEthTx { + s.Fail("expected EventEthereumTx event not found, %s", txInfo) + } +} + +// assertTxLogsMatch checks that actual tx logs include the expected logs +func (s *BackendSuite) assertTxLogsMatch( + expectedLogs []*gethcore.Log, + actualLogs []*gethcore.Log, + txInfo string, +) { + for idx, expectedLog := range expectedLogs { + actualLog := actualLogs[idx] + s.Require().Equal( + expectedLog.Address, + actualLog.Address, fmt.Sprintf("log contract address mismatch, log index %d, %s", idx, txInfo), + ) + + s.Require().Equal( + len(expectedLog.Topics), + len(actualLog.Topics), + fmt.Sprintf("topics length mismatch, log index %d, %s", idx, txInfo), + ) + + for idx, topic := range expectedLog.Topics { + s.Require().Equal( + topic, + actualLog.Topics[idx], + fmt.Sprintf("topic mismatch, log index %d, %s", idx, txInfo), + ) + } + } +} diff --git a/eth/rpc/backend/utils_test.go b/eth/rpc/backend/utils_test.go index 94fc90fe4..083d24361 100644 --- a/eth/rpc/backend/utils_test.go +++ b/eth/rpc/backend/utils_test.go @@ -4,12 +4,16 @@ import ( "fmt" "github.com/cometbft/cometbft/proto/tendermint/crypto" + gethcommon "github.com/ethereum/go-ethereum/common" + gethcore "github.com/ethereum/go-ethereum/core/types" + + gethcrypto "github.com/ethereum/go-ethereum/crypto" "github.com/NibiruChain/nibiru/v2/eth/rpc/backend" ) func (s *BackendSuite) TestGetLogsFromBlockResults() { - blockWithTx := transferTxBlockNumber.Int64() + blockWithTx := deployContractBlockNumber.Int64() blockResults, err := s.backend.TendermintBlockResultByNumber(&blockWithTx) s.Require().NoError(err) s.Require().NotNil(blockResults) @@ -18,8 +22,16 @@ func (s *BackendSuite) TestGetLogsFromBlockResults() { s.Require().NoError(err) s.Require().NotNil(logs) - // TODO: ON: the structured event eth.evm.v1.EventTxLog is not emitted properly, so the logs are not retrieved - // Add proper checks after implementing + s.assertTxLogsMatch([]*gethcore.Log{ + { + Address: testContractAddress, + Topics: []gethcommon.Hash{ + gethcrypto.Keccak256Hash([]byte("Transfer(address,address,uint256)")), + gethcommon.Address{}.Hash(), + s.fundedAccEthAddr.Hash(), + }, + }, + }, logs[0], "deploy contract tx") } func (s *BackendSuite) TestGetHexProofs() { diff --git a/x/common/testutil/testnetwork/tx.go b/x/common/testutil/testnetwork/tx.go index a368c8a86..279381a2a 100644 --- a/x/common/testutil/testnetwork/tx.go +++ b/x/common/testutil/testnetwork/tx.go @@ -126,7 +126,9 @@ func (network *Network) ExecTxCmd( } func (chain *Network) BroadcastMsgs( - from sdk.AccAddress, msgs ...sdk.Msg, + from sdk.AccAddress, + accountSequence *uint64, + msgs ...sdk.Msg, ) (*sdk.TxResponse, error) { cfg := chain.Config kb, info, err := chain.keyBaseAndInfoForAddr(from) @@ -142,13 +144,18 @@ func (chain *Network) BroadcastMsgs( } txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(cfg.BondDenom, math.NewInt(1000)))) - txBuilder.SetGasLimit(uint64(1 * common.TO_MICRO)) + txBuilder.SetGasLimit(uint64(10 * common.TO_MICRO)) acc, err := cfg.AccountRetriever.GetAccount(chain.Validators[0].ClientCtx, from) if err != nil { return nil, err } - + var sequence uint64 + if accountSequence != nil { + sequence = *accountSequence + } else { + sequence = acc.GetSequence() + } txFactory := tx.Factory{} txFactory = txFactory. WithChainID(cfg.ChainID). @@ -156,7 +163,7 @@ func (chain *Network) BroadcastMsgs( WithTxConfig(cfg.TxConfig). WithAccountRetriever(cfg.AccountRetriever). WithAccountNumber(acc.GetAccountNumber()). - WithSequence(acc.GetSequence()) + WithSequence(sequence) err = tx.Sign(txFactory, info.Name, txBuilder, true) if err != nil { diff --git a/x/common/testutil/testnetwork/tx_test.go b/x/common/testutil/testnetwork/tx_test.go index 7912b8cea..267140460 100644 --- a/x/common/testutil/testnetwork/tx_test.go +++ b/x/common/testutil/testnetwork/tx_test.go @@ -16,7 +16,7 @@ func (s *TestSuite) TestSendTx() { fromAddr := s.network.Validators[0].Address toAddr := testutil.AccAddress() sendCoin := sdk.NewCoin(denoms.NIBI, math.NewInt(42)) - txResp, err := s.network.BroadcastMsgs(fromAddr, &banktypes.MsgSend{ + txResp, err := s.network.BroadcastMsgs(fromAddr, nil, &banktypes.MsgSend{ FromAddress: fromAddr.String(), ToAddress: toAddr.String(), Amount: sdk.NewCoins(sendCoin), diff --git a/x/evm/evmtest/tx.go b/x/evm/evmtest/tx.go index d68d16621..75022f62a 100644 --- a/x/evm/evmtest/tx.go +++ b/x/evm/evmtest/tx.go @@ -26,7 +26,7 @@ import ( ) // ExecuteNibiTransfer executes nibi transfer -func ExecuteNibiTransfer(deps *TestDeps, t *testing.T) *evm.MsgEthereumTx { +func ExecuteNibiTransfer(deps *TestDeps, t *testing.T) (*evm.MsgEthereumTx, *evm.MsgEthereumTxResponse) { nonce := deps.NewStateDB().GetNonce(deps.Sender.EthAddr) recipient := NewEthPrivAcc().EthAddr @@ -43,7 +43,7 @@ func ExecuteNibiTransfer(deps *TestDeps, t *testing.T) *evm.MsgEthereumTx { resp, err := deps.App.EvmKeeper.EthereumTx(sdk.WrapSDKContext(deps.Ctx), ethTxMsg) require.NoError(t, err) require.Empty(t, resp.VmError) - return ethTxMsg + return ethTxMsg, resp } type DeployContractResult struct { diff --git a/x/evm/keeper/call_contract.go b/x/evm/keeper/call_contract.go index ad4ac90c7..d6508eef3 100644 --- a/x/evm/keeper/call_contract.go +++ b/x/evm/keeper/call_contract.go @@ -137,14 +137,11 @@ func (k Keeper) CallContractWithInput( } k.ResetGasMeterAndConsumeGas(ctx, blockGasUsed) k.updateBlockBloom(ctx, evmResp, uint64(txConfig.LogIndex)) - // TODO: remove after migrating logs - //err = k.EmitLogEvents(ctx, evmResp) - //if err != nil { - // return nil, nil, errors.Wrap(err, "error emitting tx logs") - //} - // blockTxIdx := uint64(txConfig.TxIndex) + 1 - // k.EvmState.BlockTxIndex.Set(ctx, blockTxIdx) + err = k.EmitLogEvents(ctx, evmResp) + if err != nil { + return nil, nil, errors.Wrap(err, "error emitting tx logs") + } } return evmResp, evmObj, nil } diff --git a/x/evm/keeper/grpc_query_test.go b/x/evm/keeper/grpc_query_test.go index 28da63173..2b75914b2 100644 --- a/x/evm/keeper/grpc_query_test.go +++ b/x/evm/keeper/grpc_query_test.go @@ -767,7 +767,7 @@ func (s *Suite) TestTraceTx() { { name: "happy: simple nibi transfer tx", scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { - txMsg := evmtest.ExecuteNibiTransfer(deps, s.T()) + txMsg, _ := evmtest.ExecuteNibiTransfer(deps, s.T()) req = &evm.QueryTraceTxRequest{ Msg: txMsg, } @@ -843,7 +843,7 @@ func (s *Suite) TestTraceBlock() { name: "happy: simple nibi transfer tx", setup: nil, scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { - txMsg := evmtest.ExecuteNibiTransfer(deps, s.T()) + txMsg, _ := evmtest.ExecuteNibiTransfer(deps, s.T()) req = &evm.QueryTraceBlockRequest{ Txs: []*evm.MsgEthereumTx{ txMsg, diff --git a/x/oracle/keeper/app_test.go b/x/oracle/keeper/app_test.go index 197c73223..c8b5ebe33 100644 --- a/x/oracle/keeper/app_test.go +++ b/x/oracle/keeper/app_test.go @@ -117,7 +117,7 @@ func (s *TestSuite) sendPrevotes(prices []map[asset.Pair]sdk.Dec) []string { pricesStr, err := votes.ToString() s.Require().NoError(err) - _, err = s.network.BroadcastMsgs(val.Address, &types.MsgAggregateExchangeRatePrevote{ + _, err = s.network.BroadcastMsgs(val.Address, nil, &types.MsgAggregateExchangeRatePrevote{ Hash: types.GetAggregateVoteHash("1", pricesStr, val.ValAddress).String(), Feeder: val.Address.String(), Validator: val.ValAddress.String(), @@ -133,7 +133,7 @@ func (s *TestSuite) sendPrevotes(prices []map[asset.Pair]sdk.Dec) []string { func (s *TestSuite) sendVotes(rates []string) { for i, val := range s.network.Validators { - _, err := s.network.BroadcastMsgs(val.Address, &types.MsgAggregateExchangeRateVote{ + _, err := s.network.BroadcastMsgs(val.Address, nil, &types.MsgAggregateExchangeRateVote{ Salt: "1", ExchangeRates: rates[i], Feeder: val.Address.String(),