diff --git a/evmrpc/block.go b/evmrpc/block.go index 0d5d9a748..79ee00311 100644 --- a/evmrpc/block.go +++ b/evmrpc/block.go @@ -15,12 +15,14 @@ import ( wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/lib/ethapi" "github.com/ethereum/go-ethereum/rpc" "github.com/sei-protocol/sei-chain/x/evm/keeper" + "github.com/sei-protocol/sei-chain/x/evm/state" "github.com/sei-protocol/sei-chain/x/evm/types" rpcclient "github.com/tendermint/tendermint/rpc/client" "github.com/tendermint/tendermint/rpc/coretypes" @@ -37,6 +39,7 @@ type BlockAPI struct { connectionType ConnectionType namespace string includeShellReceipts bool + includeBankTransfers bool } type SeiBlockAPI struct { @@ -52,6 +55,7 @@ func NewBlockAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func(i txConfig: txConfig, connectionType: connectionType, includeShellReceipts: false, + includeBankTransfers: false, namespace: "eth", } } @@ -71,6 +75,7 @@ func NewSeiBlockAPI( txConfig: txConfig, connectionType: connectionType, includeShellReceipts: true, + includeBankTransfers: false, namespace: "sei", } return &SeiBlockAPI{ @@ -79,6 +84,20 @@ func NewSeiBlockAPI( } } +func NewSei2BlockAPI( + tmClient rpcclient.Client, + k *keeper.Keeper, + ctxProvider func(int64) sdk.Context, + txConfig client.TxConfig, + connectionType ConnectionType, + isPanicTx func(ctx context.Context, hash common.Hash) (bool, error), +) *SeiBlockAPI { + blockAPI := NewSeiBlockAPI(tmClient, k, ctxProvider, txConfig, connectionType, isPanicTx) + blockAPI.namespace = "sei2" + blockAPI.includeBankTransfers = true + return blockAPI +} + func (a *SeiBlockAPI) GetBlockByNumberExcludeTraceFail(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { // exclude synthetic txs return a.getBlockByNumber(ctx, number, fullTx, false, a.isPanicTx) @@ -130,7 +149,7 @@ func (a *BlockAPI) getBlockByHash(ctx context.Context, blockHash common.Hash, fu return nil, err } blockBloom := a.keeper.GetBlockBloom(a.ctxProvider(block.Block.Height)) - return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeShellReceipts, isPanicTx) + return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeBankTransfers, includeSyntheticTxs, isPanicTx) } func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { @@ -186,7 +205,7 @@ func (a *BlockAPI) getBlockByNumber( return nil, err } blockBloom := a.keeper.GetBlockBloom(a.ctxProvider(block.Block.Height)) - return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, includeSyntheticTxs, isPanicTx) + return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeBankTransfers, includeSyntheticTxs, isPanicTx) } func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (result []map[string]interface{}, returnErr error) { @@ -266,6 +285,7 @@ func EncodeTmBlock( k *keeper.Keeper, txDecoder sdk.TxDecoder, fullTx bool, + includeBankTransfers bool, includeSyntheticTxs bool, isPanicOrSynthetic func(ctx context.Context, hash common.Hash) (bool, error), ) (map[string]interface{}, error) { @@ -342,6 +362,34 @@ func EncodeTmBlock( TransactionIndex: (*hexutil.Uint64)(&ti), }) } + case *banktypes.MsgSend: + if !includeBankTransfers { + continue + } + th := sha256.Sum256(block.Block.Txs[i]) + if !fullTx { + transactions = append(transactions, "0x"+hex.EncodeToString(th[:])) + } else { + rpcTx := ðapi.RPCTransaction{ + BlockHash: &blockhash, + BlockNumber: (*hexutil.Big)(number), + Hash: th, + } + senderSeiAddr, err := sdk.AccAddressFromBech32(m.FromAddress) + if err != nil { + continue + } + rpcTx.From = k.GetEVMAddressOrDefault(ctx, senderSeiAddr) + recipientSeiAddr, err := sdk.AccAddressFromBech32(m.ToAddress) + if err != nil { + continue + } + recipientEvmAddr := k.GetEVMAddressOrDefault(ctx, recipientSeiAddr) + rpcTx.To = &recipientEvmAddr + amt := m.Amount.AmountOf("usei").Mul(state.SdkUseiToSweiMultiplier) + rpcTx.Value = (*hexutil.Big)(amt.BigInt()) + transactions = append(transactions, rpcTx) + } } } } diff --git a/evmrpc/block_test.go b/evmrpc/block_test.go index d273690aa..040a55310 100644 --- a/evmrpc/block_test.go +++ b/evmrpc/block_test.go @@ -205,7 +205,7 @@ func TestEncodeTmBlock_EmptyTransactions(t *testing.T) { } // Call EncodeTmBlock with empty transactions - result, err := evmrpc.EncodeTmBlock(ctx, block, blockRes, ethtypes.Bloom{}, k, Decoder, true, false, nil) + result, err := evmrpc.EncodeTmBlock(ctx, block, blockRes, ethtypes.Bloom{}, k, Decoder, true, false, false, nil) require.Nil(t, err) // Assert txHash is equal to ethtypes.EmptyTxsHash @@ -251,7 +251,7 @@ func TestEncodeBankMsg(t *testing.T) { }, }, } - res, err := evmrpc.EncodeTmBlock(ctx, &resBlock, &resBlockRes, ethtypes.Bloom{}, k, Decoder, true, false, nil) + res, err := evmrpc.EncodeTmBlock(ctx, &resBlock, &resBlockRes, ethtypes.Bloom{}, k, Decoder, true, false, false, nil) require.Nil(t, err) txs := res["transactions"].([]interface{}) require.Equal(t, 0, len(txs)) @@ -299,7 +299,7 @@ func TestEncodeWasmExecuteMsg(t *testing.T) { }, }, } - res, err := evmrpc.EncodeTmBlock(ctx, &resBlock, &resBlockRes, ethtypes.Bloom{}, k, Decoder, true, true, nil) + res, err := evmrpc.EncodeTmBlock(ctx, &resBlock, &resBlockRes, ethtypes.Bloom{}, k, Decoder, true, false, true, nil) require.Nil(t, err) txs := res["transactions"].([]interface{}) require.Equal(t, 1, len(txs)) @@ -319,3 +319,61 @@ func TestEncodeWasmExecuteMsg(t *testing.T) { S: nil, }, txs[0].(*ethapi.RPCTransaction)) } + +func TestEncodeBankTransferMsg(t *testing.T) { + k := &testkeeper.EVMTestApp.EvmKeeper + ctx := testkeeper.EVMTestApp.GetContextForDeliverTx(nil) + fromSeiAddr, fromEvmAddr := testkeeper.MockAddressPair() + k.SetAddressMapping(ctx, fromSeiAddr, fromEvmAddr) + toSeiAddr, _ := testkeeper.MockAddressPair() + b := TxConfig.NewTxBuilder() + b.SetMsgs(&banktypes.MsgSend{ + FromAddress: fromSeiAddr.String(), + ToAddress: toSeiAddr.String(), + Amount: sdk.NewCoins(sdk.NewCoin("usei", sdk.OneInt())), + }) + tx := b.GetTx() + bz, _ := Encoder(tx) + resBlock := coretypes.ResultBlock{ + BlockID: MockBlockID, + Block: &tmtypes.Block{ + Header: mockBlockHeader(MockHeight8), + Data: tmtypes.Data{ + Txs: []tmtypes.Tx{bz}, + }, + LastCommit: &tmtypes.Commit{ + Height: MockHeight8 - 1, + }, + }, + } + resBlockRes := coretypes.ResultBlockResults{ + TxsResults: []*abci.ExecTxResult{ + { + Data: bz, + }, + }, + ConsensusParamUpdates: &types2.ConsensusParams{ + Block: &types2.BlockParams{ + MaxBytes: 100000000, + MaxGas: 200000000, + }, + }, + } + res, err := evmrpc.EncodeTmBlock(ctx, &resBlock, &resBlockRes, ethtypes.Bloom{}, k, Decoder, true, true, false, nil) + require.Nil(t, err) + txs := res["transactions"].([]interface{}) + require.Equal(t, 1, len(txs)) + bh := common.HexToHash(MockBlockID.Hash.String()) + to := common.Address(toSeiAddr) + require.Equal(t, ðapi.RPCTransaction{ + BlockHash: &bh, + BlockNumber: (*hexutil.Big)(big.NewInt(MockHeight8)), + From: fromEvmAddr, + To: &to, + Value: (*hexutil.Big)(big.NewInt(1_000_000_000_000)), + Hash: common.Hash(sha256.Sum256(bz)), + V: nil, + R: nil, + S: nil, + }, txs[0].(*ethapi.RPCTransaction)) +} diff --git a/evmrpc/server.go b/evmrpc/server.go index 6bf207a96..b2153f041 100644 --- a/evmrpc/server.go +++ b/evmrpc/server.go @@ -71,6 +71,10 @@ func NewEVMHTTPServer( Namespace: "sei", Service: NewSeiBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP, isPanicOrSyntheticTxFunc), }, + { + Namespace: "sei2", + Service: NewSei2BlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP, isPanicOrSyntheticTxFunc), + }, { Namespace: "eth", Service: txAPI,