From b8e7b8ddafca0ca505393839ec51b665b8806208 Mon Sep 17 00:00:00 2001 From: codchen Date: Fri, 20 Sep 2024 23:05:57 +0800 Subject: [PATCH 01/11] remove synthetic events from eth_ endpoints & fix param reading --- evmrpc/block.go | 39 ++++++++++++++++++++++++++++++++++++++- evmrpc/filter.go | 6 ++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/evmrpc/block.go b/evmrpc/block.go index 186b8d955..11aade396 100644 --- a/evmrpc/block.go +++ b/evmrpc/block.go @@ -76,6 +76,31 @@ func (a *BlockAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fu func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getBlockByNumber", a.connectionType, startTime, returnErr == nil) + if number == 0 { + // always return genesis block + return map[string]interface{}{ + "number": (*hexutil.Big)(big.NewInt(0)), + "hash": common.HexToHash("F9D3845DF25B43B1C6926F3CEDA6845C17F5624E12212FD8847D0BA01DA1AB9E"), + "parentHash": common.Hash{}, + "nonce": ethtypes.BlockNonce{}, // inapplicable to Sei + "mixHash": common.Hash{}, // inapplicable to Sei + "sha3Uncles": ethtypes.EmptyUncleHash, // inapplicable to Sei + "logsBloom": ethtypes.Bloom{}, + "stateRoot": common.Hash{}, + "miner": common.Address{}, + "difficulty": (*hexutil.Big)(big.NewInt(0)), // inapplicable to Sei + "extraData": hexutil.Bytes{}, // inapplicable to Sei + "gasLimit": hexutil.Uint64(0), + "gasUsed": hexutil.Uint64(0), + "timestamp": hexutil.Uint64(0), + "transactionsRoot": common.Hash{}, + "receiptsRoot": common.Hash{}, + "size": hexutil.Uint64(0), + "uncles": []common.Hash{}, // inapplicable to Sei + "transactions": []interface{}{}, + "baseFeePerGas": (*hexutil.Big)(big.NewInt(0)), + }, nil + } numberPtr, err := getBlockNumber(ctx, a.tmClient, number) if err != nil { return nil, err @@ -130,6 +155,12 @@ func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.Block mtx.Unlock() } } else { + if len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { + return + } + if receipt.EffectiveGasPrice == 0 { + return + } encodedReceipt, err := encodeReceipt(receipt, a.txConfig.TxDecoder(), block, func(h common.Hash) bool { _, err := a.keeper.GetReceipt(a.ctxProvider(height), h) return err == nil @@ -144,10 +175,16 @@ func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.Block }(i, hash) } wg.Wait() + compactReceipts := make([]map[string]interface{}, 0) + for _, r := range allReceipts { + if len(r) > 0 { + compactReceipts = append(compactReceipts, r) + } + } if returnErr != nil { return nil, returnErr } - return allReceipts, nil + return compactReceipts, nil } func EncodeTmBlock( diff --git a/evmrpc/filter.go b/evmrpc/filter.go index 04f5f561c..04cf6f3ce 100644 --- a/evmrpc/filter.go +++ b/evmrpc/filter.go @@ -362,6 +362,12 @@ func (f *LogFetcher) FindLogsByBloom(height int64, filters [][]bloomIndexes) (re ctx.Logger().Error(fmt.Sprintf("FindLogsByBloom: unable to find receipt for hash %s", hash.Hex())) continue } + if len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { + continue + } + if receipt.EffectiveGasPrice == 0 { + return + } if len(receipt.LogsBloom) > 0 && MatchFilters(ethtypes.Bloom(receipt.LogsBloom), filters) { res = append(res, keeper.GetLogsForTx(receipt)...) } From 4afa69a26c209e7e251be7e10a02d81e5e3186b4 Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Sat, 21 Sep 2024 13:57:30 -0400 Subject: [PATCH 02/11] add sei_ specific endpts for block, tx, filter isn't working --- evmrpc/block.go | 41 ++++++++++- evmrpc/block_sei.go | 29 ++++++++ evmrpc/block_sei_test.go | 100 ++++++++++++++++++++++++++ evmrpc/block_test.go | 4 +- evmrpc/filter_sei.go | 26 +++++++ evmrpc/filter_sei_test.go | 7 ++ evmrpc/filter_test.go | 145 ++++++++++++++++++++------------------ evmrpc/server.go | 22 +++++- evmrpc/setup_test.go | 14 ++++ evmrpc/tx.go | 8 +++ evmrpc/tx_sei.go | 29 ++++++++ evmrpc/tx_sei_test.go | 11 +++ evmrpc/tx_test.go | 16 +++-- 13 files changed, 373 insertions(+), 79 deletions(-) create mode 100644 evmrpc/block_sei.go create mode 100644 evmrpc/block_sei_test.go create mode 100644 evmrpc/filter_sei.go create mode 100644 evmrpc/filter_sei_test.go create mode 100644 evmrpc/tx_sei.go create mode 100644 evmrpc/tx_sei_test.go diff --git a/evmrpc/block.go b/evmrpc/block.go index 11aade396..5f9dfcd36 100644 --- a/evmrpc/block.go +++ b/evmrpc/block.go @@ -2,12 +2,14 @@ package evmrpc import ( "context" + "crypto/sha256" "errors" "math/big" "strings" "sync" "time" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" @@ -61,6 +63,10 @@ func (a *BlockAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash func (a *BlockAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getBlockByHash", a.connectionType, startTime, returnErr == nil) + return a.getBlockByHash(ctx, blockHash, fullTx, false) +} + +func (a *BlockAPI) getBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool, includeSyntheticTxs bool) (result map[string]interface{}, returnErr error) { block, err := blockByHashWithRetry(ctx, a.tmClient, blockHash[:], 1) if err != nil { return nil, err @@ -70,14 +76,14 @@ 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(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx) + return EncodeTmBlock(a.ctxProvider(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, includeSyntheticTxs) } func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getBlockByNumber", a.connectionType, startTime, returnErr == nil) if number == 0 { - // always return genesis block + // for compatibility with the graph, always return genesis block return map[string]interface{}{ "number": (*hexutil.Big)(big.NewInt(0)), "hash": common.HexToHash("F9D3845DF25B43B1C6926F3CEDA6845C17F5624E12212FD8847D0BA01DA1AB9E"), @@ -101,6 +107,10 @@ func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, "baseFeePerGas": (*hexutil.Big)(big.NewInt(0)), }, nil } + return a.getBlockByNumber(ctx, number, fullTx, false) +} + +func (a *BlockAPI) getBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool, includeSyntheticTxs bool) (result map[string]interface{}, returnErr error) { numberPtr, err := getBlockNumber(ctx, a.tmClient, number) if err != nil { return nil, err @@ -114,7 +124,7 @@ func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, return nil, err } blockBloom := a.keeper.GetBlockBloom(a.ctxProvider(block.Block.Height)) - return EncodeTmBlock(a.ctxProvider(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx) + return EncodeTmBlock(a.ctxProvider(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, includeSyntheticTxs) } func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (result []map[string]interface{}, returnErr error) { @@ -195,6 +205,7 @@ func EncodeTmBlock( k *keeper.Keeper, txDecoder sdk.TxDecoder, fullTx bool, + includeSyntheticTxs bool, ) (map[string]interface{}, error) { number := big.NewInt(block.Block.Height) blockhash := common.HexToHash(block.BlockID.Hash.String()) @@ -233,6 +244,30 @@ func EncodeTmBlock( newTx := ethapi.NewRPCTransaction(ethtx, blockhash, number.Uint64(), uint64(blockTime.Second()), uint64(receipt.TransactionIndex), baseFeePerGas, chainConfig) transactions = append(transactions, newTx) } + case *wasmtypes.MsgExecuteContract: + if !includeSyntheticTxs { + continue + } + th := sha256.Sum256(block.Block.Txs[i]) + receipt, err := k.GetReceipt(ctx, th) + if err != nil { + continue + } + if !fullTx { + transactions = append(transactions, th) + } else { + ti := uint64(receipt.TransactionIndex) + to := k.GetEVMAddressOrDefault(ctx, sdk.MustAccAddressFromBech32(m.Contract)) + transactions = append(transactions, ðapi.RPCTransaction{ + BlockHash: &blockhash, + BlockNumber: (*hexutil.Big)(number), + From: common.HexToAddress(receipt.From), + To: &to, + Input: m.Msg.Bytes(), + Hash: th, + TransactionIndex: (*hexutil.Uint64)(&ti), + }) + } } } } diff --git a/evmrpc/block_sei.go b/evmrpc/block_sei.go new file mode 100644 index 000000000..690c2fa4e --- /dev/null +++ b/evmrpc/block_sei.go @@ -0,0 +1,29 @@ +package evmrpc + +import ( + "context" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" +) + +type SeiBlockAPI struct { + *BlockAPI +} + +func NewSeiBlockAPI(blockAPI *BlockAPI) *SeiBlockAPI { + return &SeiBlockAPI{blockAPI} +} + +func (a *SeiBlockAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) { + startTime := time.Now() + defer recordMetrics("sei_getBlockByHash", a.connectionType, startTime, returnErr == nil) + return a.getBlockByHash(ctx, blockHash, fullTx, true) +} + +func (a *SeiBlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { + startTime := time.Now() + defer recordMetrics("sei_getBlockByNumber", a.connectionType, startTime, returnErr == nil) + return a.getBlockByNumber(ctx, number, fullTx, true) +} diff --git a/evmrpc/block_sei_test.go b/evmrpc/block_sei_test.go new file mode 100644 index 000000000..4c08386d5 --- /dev/null +++ b/evmrpc/block_sei_test.go @@ -0,0 +1,100 @@ +package evmrpc_test + +import ( + "crypto/sha256" + "math/big" + "testing" + + types2 "github.com/tendermint/tendermint/proto/tendermint/types" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/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/sei-protocol/sei-chain/evmrpc" + testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/evm/types" + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/rpc/coretypes" + tmtypes "github.com/tendermint/tendermint/types" +) + +func TestGetSeiBlockByNumber(t *testing.T) { + for _, num := range []string{"0x8", "earliest", "latest", "pending", "finalized", "safe"} { + resObj := sendSeiRequestGood(t, "getBlockByNumber", num, true) + verifyBlockResult(t, resObj) + } + + resObj := sendSeiRequestBad(t, "getBlockByNumber", "bad_num", true) + require.Equal(t, "invalid argument 0: hex string without 0x prefix", resObj["error"].(map[string]interface{})["message"]) +} + +func TestGetSeiBlockByHash(t *testing.T) { + resObj := sendSeiRequestGood(t, "getBlockByHash", "0x0000000000000000000000000000000000000000000000000000000000000001", true) + verifyBlockResult(t, resObj) +} + +func TestEncodeWasmExecuteMsg(t *testing.T) { + k := &testkeeper.EVMTestApp.EvmKeeper + ctx := testkeeper.EVMTestApp.GetContextForDeliverTx(nil) + fromSeiAddr, fromEvmAddr := testkeeper.MockAddressPair() + toSeiAddr, _ := testkeeper.MockAddressPair() + b := TxConfig.NewTxBuilder() + b.SetMsgs(&wasmtypes.MsgExecuteContract{ + Sender: fromSeiAddr.String(), + Contract: toSeiAddr.String(), + Msg: []byte{1, 2, 3}, + }) + tx := b.GetTx() + bz, _ := Encoder(tx) + k.MockReceipt(ctx, sha256.Sum256(bz), &types.Receipt{ + TransactionIndex: 1, + From: fromEvmAddr.Hex(), + }) + resBlock := coretypes.ResultBlock{ + BlockID: MockBlockID, + Block: &tmtypes.Block{ + Header: mockBlockHeader(MockHeight), + Data: tmtypes.Data{ + Txs: []tmtypes.Tx{bz}, + }, + LastCommit: &tmtypes.Commit{ + Height: MockHeight - 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) + require.Nil(t, err) + txs := res["transactions"].([]interface{}) + require.Equal(t, 1, len(txs)) + ti := uint64(1) + bh := common.HexToHash(MockBlockID.Hash.String()) + to := common.Address(toSeiAddr) + require.Equal(t, ðapi.RPCTransaction{ + BlockHash: &bh, + BlockNumber: (*hexutil.Big)(big.NewInt(MockHeight)), + From: fromEvmAddr, + To: &to, + Input: []byte{1, 2, 3}, + Hash: common.Hash(sha256.Sum256(bz)), + TransactionIndex: (*hexutil.Uint64)(&ti), + V: nil, + R: nil, + S: nil, + }, txs[0].(*ethapi.RPCTransaction)) +} diff --git a/evmrpc/block_test.go b/evmrpc/block_test.go index c91798026..88a2032ba 100644 --- a/evmrpc/block_test.go +++ b/evmrpc/block_test.go @@ -163,7 +163,7 @@ func TestEncodeTmBlock_EmptyTransactions(t *testing.T) { } // Call EncodeTmBlock with empty transactions - result, err := evmrpc.EncodeTmBlock(ctx, block, blockRes, ethtypes.Bloom{}, k, Decoder, true) + result, err := evmrpc.EncodeTmBlock(ctx, block, blockRes, ethtypes.Bloom{}, k, Decoder, true, false) require.Nil(t, err) // Assert txHash is equal to ethtypes.EmptyTxsHash @@ -209,7 +209,7 @@ func TestEncodeBankMsg(t *testing.T) { }, }, } - res, err := evmrpc.EncodeTmBlock(ctx, &resBlock, &resBlockRes, ethtypes.Bloom{}, k, Decoder, true) + res, err := evmrpc.EncodeTmBlock(ctx, &resBlock, &resBlockRes, ethtypes.Bloom{}, k, Decoder, true, false) require.Nil(t, err) txs := res["transactions"].([]interface{}) require.Equal(t, 0, len(txs)) diff --git a/evmrpc/filter_sei.go b/evmrpc/filter_sei.go new file mode 100644 index 000000000..348d535be --- /dev/null +++ b/evmrpc/filter_sei.go @@ -0,0 +1,26 @@ +package evmrpc + +import ( + "context" + "time" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/filters" +) + +type SeiFilterAPI struct { + *FilterAPI +} + +func NewSeiFilterAPI(f *FilterAPI) *SeiFilterAPI { + return &SeiFilterAPI{f} +} + +func (a *SeiFilterAPI) GetLogs( + ctx context.Context, + crit filters.FilterCriteria, +) (res []*ethtypes.Log, err error) { + defer recordMetrics("sei_getLogs", a.connectionType, time.Now(), err == nil) + logs, _, err := a.logFetcher.GetLogsByFilters(ctx, crit, 0) + return logs, err +} diff --git a/evmrpc/filter_sei_test.go b/evmrpc/filter_sei_test.go new file mode 100644 index 000000000..074e67e79 --- /dev/null +++ b/evmrpc/filter_sei_test.go @@ -0,0 +1,7 @@ +package evmrpc_test + +// import "testing" + +// func TestSeiFilterGetLogs(t *testing.T) { +// testFilterGetLogs(t, "sei") +// } diff --git a/evmrpc/filter_test.go b/evmrpc/filter_test.go index 94581979d..a29aae2a1 100644 --- a/evmrpc/filter_test.go +++ b/evmrpc/filter_test.go @@ -94,6 +94,10 @@ func TestFilterUninstall(t *testing.T) { } func TestFilterGetLogs(t *testing.T) { +// testFilterGetLogs(t, "eth") +// } + +// func testFilterGetLogs(t *testing.T, namespace string) { tests := []struct { name string blockHash *common.Hash @@ -116,72 +120,72 @@ func TestFilterGetLogs(t *testing.T) { }, wantLen: 2, }, - { - name: "filter by single topic", - fromBlock: "0x2", - toBlock: "0x2", - topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, - wantErr: false, - check: func(t *testing.T, log map[string]interface{}) { - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", log["topics"].([]interface{})[0].(string)) - }, - wantLen: 4, - }, - { - name: "filter by single topic with default range", - topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, - wantErr: false, - check: func(t *testing.T, log map[string]interface{}) { - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", log["topics"].([]interface{})[0].(string)) - }, - wantLen: 1, - }, - { - name: "error with from block ahead of to block", - fromBlock: "0x3", - toBlock: "0x2", - topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, - wantErr: true, - }, - { - name: "multiple addresses, multiple topics", - fromBlock: "0x2", - toBlock: "0x2", - addrs: []common.Address{ - common.HexToAddress("0x1111111111111111111111111111111111111112"), - common.HexToAddress("0x1111111111111111111111111111111111111113"), - }, - topics: [][]common.Hash{ - {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}, - {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456")}, - }, - wantErr: false, - check: func(t *testing.T, log map[string]interface{}) { - if log["address"].(string) != "0x1111111111111111111111111111111111111112" && log["address"].(string) != "0x1111111111111111111111111111111111111113" { - t.Fatalf("address %s not in expected list", log["address"].(string)) - } - firstTopic := log["topics"].([]interface{})[0].(string) - secondTopic := log["topics"].([]interface{})[1].(string) - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", firstTopic) - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000456", secondTopic) - }, - wantLen: 2, - }, - { - name: "wildcard first topic", - fromBlock: "0x2", - toBlock: "0x2", - topics: [][]common.Hash{ - {}, - {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456")}, - }, - wantErr: false, - check: func(t *testing.T, log map[string]interface{}) { - secondTopic := log["topics"].([]interface{})[1].(string) - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000456", secondTopic) - }, - wantLen: 3, - }, + // { + // name: "filter by single topic", + // fromBlock: "0x2", + // toBlock: "0x2", + // topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, + // wantErr: false, + // check: func(t *testing.T, log map[string]interface{}) { + // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", log["topics"].([]interface{})[0].(string)) + // }, + // wantLen: 4, + // }, + // { + // name: "filter by single topic with default range", + // topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, + // wantErr: false, + // check: func(t *testing.T, log map[string]interface{}) { + // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", log["topics"].([]interface{})[0].(string)) + // }, + // wantLen: 1, + // }, + // { + // name: "error with from block ahead of to block", + // fromBlock: "0x3", + // toBlock: "0x2", + // topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, + // wantErr: true, + // }, + // { + // name: "multiple addresses, multiple topics", + // fromBlock: "0x2", + // toBlock: "0x2", + // addrs: []common.Address{ + // common.HexToAddress("0x1111111111111111111111111111111111111112"), + // common.HexToAddress("0x1111111111111111111111111111111111111113"), + // }, + // topics: [][]common.Hash{ + // {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}, + // {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456")}, + // }, + // wantErr: false, + // check: func(t *testing.T, log map[string]interface{}) { + // if log["address"].(string) != "0x1111111111111111111111111111111111111112" && log["address"].(string) != "0x1111111111111111111111111111111111111113" { + // t.Fatalf("address %s not in expected list", log["address"].(string)) + // } + // firstTopic := log["topics"].([]interface{})[0].(string) + // secondTopic := log["topics"].([]interface{})[1].(string) + // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", firstTopic) + // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000456", secondTopic) + // }, + // wantLen: 2, + // }, + // { + // name: "wildcard first topic", + // fromBlock: "0x2", + // toBlock: "0x2", + // topics: [][]common.Hash{ + // {}, + // {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456")}, + // }, + // wantErr: false, + // check: func(t *testing.T, log map[string]interface{}) { + // secondTopic := log["topics"].([]interface{})[1].(string) + // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000456", secondTopic) + // }, + // wantLen: 3, + // }, } for _, tt := range tests { @@ -198,7 +202,14 @@ func TestFilterGetLogs(t *testing.T) { filterCriteria["fromBlock"] = tt.fromBlock filterCriteria["toBlock"] = tt.toBlock } - resObj := sendRequestGood(t, "getLogs", filterCriteria) + var resObj map[string]interface{} + // if namespace == "eth" { + resObj = sendRequestGood(t, "getLogs", filterCriteria) + // } else if namespace == "sei" { + // resObj = sendSeiRequestGood(t, "getLogs", filterCriteria) + // } else { + // panic("unknown namespace") + // } if tt.wantErr { _, ok := resObj["error"] require.True(t, ok) diff --git a/evmrpc/server.go b/evmrpc/server.go index 11c1ba672..6c7631334 100644 --- a/evmrpc/server.go +++ b/evmrpc/server.go @@ -45,6 +45,10 @@ func NewEVMHTTPServer( sendAPI := NewSendAPI(tmClient, txConfig, &SendConfig{slow: config.Slow}, k, ctxProvider, homeDir, simulateConfig, ConnectionTypeHTTP) ctx := ctxProvider(LatestCtxHeight) + blockAPI := NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP) + txAPI := NewTransactionAPI(tmClient, k, ctxProvider, txConfig, homeDir, ConnectionTypeHTTP) + filterAPI := NewFilterAPI(tmClient, &LogFetcher{tmClient: tmClient, k: k, ctxProvider: ctxProvider}, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP) + apis := []rpc.API{ { Namespace: "echo", @@ -52,11 +56,15 @@ func NewEVMHTTPServer( }, { Namespace: "eth", - Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP), + Service: blockAPI, }, { Namespace: "eth", - Service: NewTransactionAPI(tmClient, k, ctxProvider, txConfig, homeDir, ConnectionTypeHTTP), + Service: txAPI, + }, + { + Namespace: "sei", + Service: NewSeiTransactionAPI(txAPI), }, { Namespace: "eth", @@ -80,12 +88,20 @@ func NewEVMHTTPServer( }, { Namespace: "eth", - Service: NewFilterAPI(tmClient, &LogFetcher{tmClient: tmClient, k: k, ctxProvider: ctxProvider}, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP), + Service: filterAPI, }, + // { + // Namespace: "sei", + // Service: NewSeiFilterAPI(filterAPI), + // }, { Namespace: "sei", Service: NewAssociationAPI(tmClient, k, ctxProvider, txConfig.TxDecoder(), sendAPI, ConnectionTypeHTTP), }, + { + Namespace: "sei", + Service: NewSeiBlockAPI(blockAPI), + }, { Namespace: "txpool", Service: NewTxPoolAPI(tmClient, k, ctxProvider, txConfig.TxDecoder(), &TxPoolConfig{maxNumTxs: int(config.MaxTxPoolTxs)}, ConnectionTypeHTTP), diff --git a/evmrpc/setup_test.go b/evmrpc/setup_test.go index 898e566ee..75319013e 100644 --- a/evmrpc/setup_test.go +++ b/evmrpc/setup_test.go @@ -740,11 +740,21 @@ func sendRequestGood(t *testing.T, method string, params ...interface{}) map[str return sendRequest(t, TestPort, method, params...) } +//nolint:deadcode +func sendSeiRequestGood(t *testing.T, method string, params ...interface{}) map[string]interface{} { + return sendSeiRequest(t, TestPort, method, params...) +} + //nolint:deadcode func sendRequestBad(t *testing.T, method string, params ...interface{}) map[string]interface{} { return sendRequest(t, TestBadPort, method, params...) } +//nolint:deadcode +func sendSeiRequestBad(t *testing.T, method string, params ...interface{}) map[string]interface{} { + return sendSeiRequest(t, TestBadPort, method, params...) +} + // nolint:deadcode func sendRequestGoodWithNamespace(t *testing.T, namespace string, method string, params ...interface{}) map[string]interface{} { return sendRequestWithNamespace(t, namespace, TestPort, method, params...) @@ -754,6 +764,10 @@ func sendRequest(t *testing.T, port int, method string, params ...interface{}) m return sendRequestWithNamespace(t, "eth", port, method, params...) } +func sendSeiRequest(t *testing.T, port int, method string, params ...interface{}) map[string]interface{} { + return sendRequestWithNamespace(t, "sei", port, method, params...) +} + func sendRequestWithNamespace(t *testing.T, namespace string, port int, method string, params ...interface{}) map[string]interface{} { paramsFormatted := "" if len(params) > 0 { diff --git a/evmrpc/tx.go b/evmrpc/tx.go index 9d773c872..f361d9cc3 100644 --- a/evmrpc/tx.go +++ b/evmrpc/tx.go @@ -43,6 +43,10 @@ func NewTransactionAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func (t *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (result map[string]interface{}, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getTransactionReceipt", t.connectionType, startTime, returnErr == nil) + return t.getTransactionReceipt(ctx, hash) +} + +func (t *TransactionAPI) getTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { sdkctx := t.ctxProvider(LatestCtxHeight) receipt, err := t.keeper.GetReceipt(sdkctx, hash) if err != nil { @@ -101,6 +105,10 @@ func (t *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, func (t *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (result *ethapi.RPCTransaction, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getTransactionByHash", t.connectionType, startTime, returnErr == nil) + return t.getTransactionByHash(ctx, hash, false) +} + +func (t *TransactionAPI) getTransactionByHash(ctx context.Context, hash common.Hash, includeSynthetic bool) (*ethapi.RPCTransaction, error) { sdkCtx := t.ctxProvider(LatestCtxHeight) // first try get from mempool for page := 1; page <= UnconfirmedTxQueryMaxPage; page++ { diff --git a/evmrpc/tx_sei.go b/evmrpc/tx_sei.go new file mode 100644 index 000000000..b45602244 --- /dev/null +++ b/evmrpc/tx_sei.go @@ -0,0 +1,29 @@ +package evmrpc + +import ( + "context" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/lib/ethapi" +) + +type SeiTransactionAPI struct { + *TransactionAPI +} + +func NewSeiTransactionAPI(t *TransactionAPI) *SeiTransactionAPI { + return &SeiTransactionAPI{t} +} + +func (t *SeiTransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (result *ethapi.RPCTransaction, returnErr error) { + startTime := time.Now() + defer recordMetrics("sei_getTransactionByHash", t.connectionType, startTime, returnErr == nil) + return t.getTransactionByHash(ctx, hash, true) +} + +func (t *SeiTransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (result map[string]interface{}, returnErr error) { + startTime := time.Now() + defer recordMetrics("sei_getTransactionReceipt", t.connectionType, startTime, returnErr == nil) + return t.getTransactionReceipt(ctx, hash) +} diff --git a/evmrpc/tx_sei_test.go b/evmrpc/tx_sei_test.go new file mode 100644 index 000000000..033c778df --- /dev/null +++ b/evmrpc/tx_sei_test.go @@ -0,0 +1,11 @@ +package evmrpc_test + +import "testing" + +func TestGetSeiTxReceipt(t *testing.T) { + testGetTxReceipt(t, "sei") +} + +func TestSeiGetTransaction(t *testing.T) { + testGetTransaction(t, "sei") +} diff --git a/evmrpc/tx_test.go b/evmrpc/tx_test.go index 3e36046da..7a3a38ba2 100644 --- a/evmrpc/tx_test.go +++ b/evmrpc/tx_test.go @@ -21,12 +21,16 @@ import ( ) func TestGetTxReceipt(t *testing.T) { + testGetTxReceipt(t, "eth") +} + +func testGetTxReceipt(t *testing.T, namespace string) { receipt, err := EVMKeeper.GetReceipt(Ctx, common.HexToHash("0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e")) require.Nil(t, err) receipt.To = "" EVMKeeper.MockReceipt(Ctx, common.HexToHash("0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e"), receipt) - body := "{\"jsonrpc\": \"2.0\",\"method\": \"eth_getTransactionReceipt\",\"params\":[\"0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e\"],\"id\":\"test\"}" + body := fmt.Sprintf("{\"jsonrpc\": \"2.0\",\"method\": \"%s_getTransactionReceipt\",\"params\":[\"0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e\"],\"id\":\"test\"}", namespace) req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s:%d", TestAddr, TestPort), strings.NewReader(body)) require.Nil(t, err) req.Header.Set("Content-Type", "application/json") @@ -101,9 +105,13 @@ func TestGetTxReceipt(t *testing.T) { } func TestGetTransaction(t *testing.T) { - bodyByBlockNumberAndIndex := "{\"jsonrpc\": \"2.0\",\"method\": \"eth_getTransactionByBlockNumberAndIndex\",\"params\":[\"0x8\",\"0x0\"],\"id\":\"test\"}" - bodyByBlockHashAndIndex := "{\"jsonrpc\": \"2.0\",\"method\": \"eth_getTransactionByBlockHashAndIndex\",\"params\":[\"0x0000000000000000000000000000000000000000000000000000000000000001\",\"0x0\"],\"id\":\"test\"}" - bodyByHash := "{\"jsonrpc\": \"2.0\",\"method\": \"eth_getTransactionByHash\",\"params\":[\"0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e\"],\"id\":\"test\"}" + testGetTransaction(t, "eth") +} + +func testGetTransaction(t *testing.T, namespace string) { + bodyByBlockNumberAndIndex := fmt.Sprintf("{\"jsonrpc\": \"2.0\",\"method\": \"%s_getTransactionByBlockNumberAndIndex\",\"params\":[\"0x8\",\"0x0\"],\"id\":\"test\"}", namespace) + bodyByBlockHashAndIndex := fmt.Sprintf("{\"jsonrpc\": \"2.0\",\"method\": \"%s_getTransactionByBlockHashAndIndex\",\"params\":[\"0x0000000000000000000000000000000000000000000000000000000000000001\",\"0x0\"],\"id\":\"test\"}", namespace) + bodyByHash := fmt.Sprintf("{\"jsonrpc\": \"2.0\",\"method\": \"%s_getTransactionByHash\",\"params\":[\"0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e\"],\"id\":\"test\"}", namespace) for _, body := range []string{bodyByBlockNumberAndIndex, bodyByBlockHashAndIndex, bodyByHash} { req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s:%d", TestAddr, TestPort), strings.NewReader(body)) require.Nil(t, err) From eec4681e65af46cd85eb7d5975c7620a6fc45fed Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Sat, 21 Sep 2024 16:29:33 -0400 Subject: [PATCH 03/11] filter logs should work with synethetic endpts --- evmrpc/filter.go | 30 +++--- evmrpc/filter_sei.go | 41 ++++---- evmrpc/filter_sei_test.go | 39 +++++++- evmrpc/filter_test.go | 193 +++++++++++++++++++++----------------- evmrpc/server.go | 12 +-- evmrpc/setup_test.go | 45 ++++++++- 6 files changed, 228 insertions(+), 132 deletions(-) diff --git a/evmrpc/filter.go b/evmrpc/filter.go index 04cf6f3ce..910b496ea 100644 --- a/evmrpc/filter.go +++ b/evmrpc/filter.go @@ -43,12 +43,13 @@ type filter struct { } type FilterAPI struct { - tmClient rpcclient.Client - filtersMu sync.Mutex - filters map[ethrpc.ID]filter - filterConfig *FilterConfig - logFetcher *LogFetcher - connectionType ConnectionType + tmClient rpcclient.Client + filtersMu sync.Mutex + filters map[ethrpc.ID]filter + filterConfig *FilterConfig + logFetcher *LogFetcher + connectionType ConnectionType + includeSynthetic bool } type FilterConfig struct { @@ -62,8 +63,8 @@ type EventItemDataWrapper struct { Value json.RawMessage `json:"value"` } -func NewFilterAPI(tmClient rpcclient.Client, logFetcher *LogFetcher, filterConfig *FilterConfig, connectionType ConnectionType) *FilterAPI { - logFetcher.filterConfig = filterConfig +func NewFilterAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func(int64) sdk.Context, filterConfig *FilterConfig, connectionType ConnectionType, includeSynthetic bool) *FilterAPI { + logFetcher := &LogFetcher{tmClient: tmClient, k: k, ctxProvider: ctxProvider, filterConfig: filterConfig, includeSynthetic: includeSynthetic} filters := make(map[ethrpc.ID]filter) api := &FilterAPI{ tmClient: tmClient, @@ -209,6 +210,7 @@ func (a *FilterAPI) GetFilterLogs( return logs, nil } +// JEREMYFLAG func (a *FilterAPI) GetLogs( ctx context.Context, crit filters.FilterCriteria, @@ -272,10 +274,11 @@ func (a *FilterAPI) UninstallFilter( } type LogFetcher struct { - tmClient rpcclient.Client - k *keeper.Keeper - ctxProvider func(int64) sdk.Context - filterConfig *FilterConfig + tmClient rpcclient.Client + k *keeper.Keeper + ctxProvider func(int64) sdk.Context + filterConfig *FilterConfig + includeSynthetic bool } func (f *LogFetcher) GetLogsByFilters(ctx context.Context, crit filters.FilterCriteria, lastToHeight int64) ([]*ethtypes.Log, int64, error) { @@ -357,12 +360,13 @@ func (f *LogFetcher) FindLogsByBloom(height int64, filters [][]bloomIndexes) (re ctx := f.ctxProvider(LatestCtxHeight) txHashes := f.k.GetTxHashesOnHeight(ctx, height) for _, hash := range txHashes { + fmt.Println("hash: ", hash) receipt, err := f.k.GetReceipt(ctx, hash) if err != nil { ctx.Logger().Error(fmt.Sprintf("FindLogsByBloom: unable to find receipt for hash %s", hash.Hex())) continue } - if len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { + if !f.includeSynthetic && len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { continue } if receipt.EffectiveGasPrice == 0 { diff --git a/evmrpc/filter_sei.go b/evmrpc/filter_sei.go index 348d535be..b8867e21b 100644 --- a/evmrpc/filter_sei.go +++ b/evmrpc/filter_sei.go @@ -1,26 +1,27 @@ package evmrpc -import ( - "context" - "time" +// import ( +// "context" +// "time" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/filters" -) +// ethtypes "github.com/ethereum/go-ethereum/core/types" +// "github.com/ethereum/go-ethereum/eth/filters" +// ) -type SeiFilterAPI struct { - *FilterAPI -} +// type SeiFilterAPI struct { +// *FilterAPI +// } -func NewSeiFilterAPI(f *FilterAPI) *SeiFilterAPI { - return &SeiFilterAPI{f} -} +// func NewSeiFilterAPI(f *FilterAPI) *SeiFilterAPI { +// f.logFetcher.includeSynthetic = true +// return &SeiFilterAPI{f} +// } -func (a *SeiFilterAPI) GetLogs( - ctx context.Context, - crit filters.FilterCriteria, -) (res []*ethtypes.Log, err error) { - defer recordMetrics("sei_getLogs", a.connectionType, time.Now(), err == nil) - logs, _, err := a.logFetcher.GetLogsByFilters(ctx, crit, 0) - return logs, err -} +// func (a *SeiFilterAPI) GetLogs( +// ctx context.Context, +// crit filters.FilterCriteria, +// ) (res []*ethtypes.Log, err error) { +// defer recordMetrics("sei_getLogs", a.connectionType, time.Now(), err == nil) +// logs, _, err := a.logFetcher.GetLogsByFilters(ctx, crit, 0) +// return logs, err +// } diff --git a/evmrpc/filter_sei_test.go b/evmrpc/filter_sei_test.go index 074e67e79..96acfcea7 100644 --- a/evmrpc/filter_sei_test.go +++ b/evmrpc/filter_sei_test.go @@ -1,7 +1,38 @@ package evmrpc_test -// import "testing" +import ( + "testing" -// func TestSeiFilterGetLogs(t *testing.T) { -// testFilterGetLogs(t, "sei") -// } + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestSeiFilterGetLogs(t *testing.T) { + // make sure we pass all the eth_ namespace tests + // TODO: uncomment + testFilterGetLogs(t, "sei", getCommonFilterLogTests()) + + // test where we get a synthetic log + testFilterGetLogs(t, "sei", []GetFilterLogTests{ + { + name: "filter by single synthetic address", + fromBlock: "0x8", + toBlock: "0x8", + addrs: []common.Address{common.HexToAddress("0x1111111111111111111111111111111111111116")}, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + require.Equal(t, "0x1111111111111111111111111111111111111116", log["address"].(string)) + }, + wantLen: 1, + }, + { + name: "filter by single topic with default range, include synethetic logs", + topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000234")}}, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000234", log["topics"].([]interface{})[0].(string)) + }, + wantLen: 1, + }, + }) +} \ No newline at end of file diff --git a/evmrpc/filter_test.go b/evmrpc/filter_test.go index a29aae2a1..59fc6a738 100644 --- a/evmrpc/filter_test.go +++ b/evmrpc/filter_test.go @@ -93,22 +93,20 @@ func TestFilterUninstall(t *testing.T) { require.False(t, uninstallSuccess) } -func TestFilterGetLogs(t *testing.T) { -// testFilterGetLogs(t, "eth") -// } +type GetFilterLogTests struct { + name string + blockHash *common.Hash + fromBlock string + toBlock string + addrs []common.Address + topics [][]common.Hash + wantErr bool + wantLen int + check func(t *testing.T, log map[string]interface{}) +} -// func testFilterGetLogs(t *testing.T, namespace string) { - tests := []struct { - name string - blockHash *common.Hash - fromBlock string - toBlock string - addrs []common.Address - topics [][]common.Hash - wantErr bool - wantLen int - check func(t *testing.T, log map[string]interface{}) - }{ +func getCommonFilterLogTests() []GetFilterLogTests { + tests := []GetFilterLogTests{ { name: "filter by single address", fromBlock: "0x2", @@ -120,74 +118,95 @@ func TestFilterGetLogs(t *testing.T) { }, wantLen: 2, }, - // { - // name: "filter by single topic", - // fromBlock: "0x2", - // toBlock: "0x2", - // topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, - // wantErr: false, - // check: func(t *testing.T, log map[string]interface{}) { - // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", log["topics"].([]interface{})[0].(string)) - // }, - // wantLen: 4, - // }, - // { - // name: "filter by single topic with default range", - // topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, - // wantErr: false, - // check: func(t *testing.T, log map[string]interface{}) { - // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", log["topics"].([]interface{})[0].(string)) - // }, - // wantLen: 1, - // }, - // { - // name: "error with from block ahead of to block", - // fromBlock: "0x3", - // toBlock: "0x2", - // topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, - // wantErr: true, - // }, - // { - // name: "multiple addresses, multiple topics", - // fromBlock: "0x2", - // toBlock: "0x2", - // addrs: []common.Address{ - // common.HexToAddress("0x1111111111111111111111111111111111111112"), - // common.HexToAddress("0x1111111111111111111111111111111111111113"), - // }, - // topics: [][]common.Hash{ - // {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}, - // {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456")}, - // }, - // wantErr: false, - // check: func(t *testing.T, log map[string]interface{}) { - // if log["address"].(string) != "0x1111111111111111111111111111111111111112" && log["address"].(string) != "0x1111111111111111111111111111111111111113" { - // t.Fatalf("address %s not in expected list", log["address"].(string)) - // } - // firstTopic := log["topics"].([]interface{})[0].(string) - // secondTopic := log["topics"].([]interface{})[1].(string) - // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", firstTopic) - // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000456", secondTopic) - // }, - // wantLen: 2, - // }, - // { - // name: "wildcard first topic", - // fromBlock: "0x2", - // toBlock: "0x2", - // topics: [][]common.Hash{ - // {}, - // {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456")}, - // }, - // wantErr: false, - // check: func(t *testing.T, log map[string]interface{}) { - // secondTopic := log["topics"].([]interface{})[1].(string) - // require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000456", secondTopic) - // }, - // wantLen: 3, - // }, + { + name: "filter by single topic", + fromBlock: "0x2", + toBlock: "0x2", + topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", log["topics"].([]interface{})[0].(string)) + }, + wantLen: 4, + }, + { + name: "filter by single topic with default range", + topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", log["topics"].([]interface{})[0].(string)) + }, + wantLen: 1, + }, + { + name: "error with from block ahead of to block", + fromBlock: "0x3", + toBlock: "0x2", + topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}}, + wantErr: true, + }, + { + name: "multiple addresses, multiple topics", + fromBlock: "0x2", + toBlock: "0x2", + addrs: []common.Address{ + common.HexToAddress("0x1111111111111111111111111111111111111112"), + common.HexToAddress("0x1111111111111111111111111111111111111113"), + }, + topics: [][]common.Hash{ + {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123")}, + {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456")}, + }, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + if log["address"].(string) != "0x1111111111111111111111111111111111111112" && log["address"].(string) != "0x1111111111111111111111111111111111111113" { + t.Fatalf("address %s not in expected list", log["address"].(string)) + } + firstTopic := log["topics"].([]interface{})[0].(string) + secondTopic := log["topics"].([]interface{})[1].(string) + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000123", firstTopic) + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000456", secondTopic) + }, + wantLen: 2, + }, + { + name: "wildcard first topic", + fromBlock: "0x2", + toBlock: "0x2", + topics: [][]common.Hash{ + {}, + {common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456")}, + }, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + secondTopic := log["topics"].([]interface{})[1].(string) + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000456", secondTopic) + }, + wantLen: 3, + }, } + return tests +} + +func TestFilterGetLogs(t *testing.T) { + testFilterGetLogs(t, "eth", getCommonFilterLogTests()) +} +func TestEthEndpointShouldNotReturnSyntheticLogs(t *testing.T) { + testFilterGetLogs(t, "eth", []GetFilterLogTests{ + { + name: "filter by single topic with default range, exclude synethetic logs", + topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000234")}}, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000234", log["topics"].([]interface{})[0].(string)) + }, + wantLen: 0, + }, + }) +} + +func testFilterGetLogs(t *testing.T, namespace string, tests []GetFilterLogTests) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fmt.Println(tt.name) @@ -203,13 +222,13 @@ func TestFilterGetLogs(t *testing.T) { filterCriteria["toBlock"] = tt.toBlock } var resObj map[string]interface{} - // if namespace == "eth" { + if namespace == "eth" { resObj = sendRequestGood(t, "getLogs", filterCriteria) - // } else if namespace == "sei" { - // resObj = sendSeiRequestGood(t, "getLogs", filterCriteria) - // } else { - // panic("unknown namespace") - // } + } else if namespace == "sei" { + resObj = sendSeiRequestGood(t, "getLogs", filterCriteria) + } else { + panic("unknown namespace") + } if tt.wantErr { _, ok := resObj["error"] require.True(t, ok) diff --git a/evmrpc/server.go b/evmrpc/server.go index 6c7631334..1c0d79153 100644 --- a/evmrpc/server.go +++ b/evmrpc/server.go @@ -47,7 +47,7 @@ func NewEVMHTTPServer( blockAPI := NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP) txAPI := NewTransactionAPI(tmClient, k, ctxProvider, txConfig, homeDir, ConnectionTypeHTTP) - filterAPI := NewFilterAPI(tmClient, &LogFetcher{tmClient: tmClient, k: k, ctxProvider: ctxProvider}, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP) + // filterAPI := NewFilterAPI(tmClient, &LogFetcher{tmClient: tmClient, k: k, ctxProvider: ctxProvider}, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP) apis := []rpc.API{ { @@ -88,12 +88,12 @@ func NewEVMHTTPServer( }, { Namespace: "eth", - Service: filterAPI, + Service: NewFilterAPI(tmClient, k, ctxProvider, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP, false), + }, + { + Namespace: "sei", + Service: NewFilterAPI(tmClient, k, ctxProvider, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP, true), }, - // { - // Namespace: "sei", - // Service: NewSeiFilterAPI(filterAPI), - // }, { Namespace: "sei", Service: NewAssociationAPI(tmClient, k, ctxProvider, txConfig.TxDecoder(), sendAPI, ConnectionTypeHTTP), diff --git a/evmrpc/setup_test.go b/evmrpc/setup_test.go index 75319013e..3449bb640 100644 --- a/evmrpc/setup_test.go +++ b/evmrpc/setup_test.go @@ -66,11 +66,13 @@ var MultiTxBlockTx1 sdk.Tx var MultiTxBlockTx2 sdk.Tx var MultiTxBlockTx3 sdk.Tx var MultiTxBlockTx4 sdk.Tx +var MultiTxBlockSynthTx sdk.Tx var tx1 *ethtypes.Transaction var multiTxBlockTx1 *ethtypes.Transaction var multiTxBlockTx2 *ethtypes.Transaction var multiTxBlockTx3 *ethtypes.Transaction var multiTxBlockTx4 *ethtypes.Transaction +var multiTxBlockSynthTx *ethtypes.Transaction var DebugTraceTx sdk.Tx var TxNonEvm sdk.Tx @@ -151,6 +153,10 @@ func (c *MockClient) mockBlock(height int64) *coretypes.ResultBlock { bz, _ := Encoder(MultiTxBlockTx3) return bz }(), + func() []byte { + bz, _ := Encoder(MultiTxBlockSynthTx) + return bz + }(), }, }, LastCommit: &tmtypes.Commit{ @@ -486,7 +492,7 @@ func init() { func generateTxData() { chainId := big.NewInt(config.DefaultChainID) to := common.HexToAddress("010203") - var txBuilder1, txBuilder1_5, txBuilder2, txBuilder3, txBuilder4 client.TxBuilder + var txBuilder1, txBuilder1_5, txBuilder2, txBuilder3, txBuilder4, synthTxBuilder client.TxBuilder txBuilder1, tx1 = buildTx(ethtypes.DynamicFeeTx{ Nonce: 1, GasFeeCap: big.NewInt(10), @@ -532,6 +538,15 @@ func generateTxData() { Data: []byte("abc"), ChainID: chainId, }) + synthTxBuilder, multiTxBlockSynthTx = buildTx(ethtypes.DynamicFeeTx{ + Nonce: 6, + GasFeeCap: big.NewInt(20), + Gas: 1000, + To: &to, + Value: big.NewInt(1000), + Data: []byte("synthetic"), + ChainID: chainId, + }) debugTraceTxBuilder, _ := buildTx(ethtypes.DynamicFeeTx{ Nonce: 0, GasFeeCap: big.NewInt(10), @@ -546,6 +561,7 @@ func generateTxData() { MultiTxBlockTx2 = txBuilder2.GetTx() MultiTxBlockTx3 = txBuilder3.GetTx() MultiTxBlockTx4 = txBuilder4.GetTx() + MultiTxBlockSynthTx = synthTxBuilder.GetTx() DebugTraceTx = debugTraceTxBuilder.GetTx() TxNonEvm = app.TestTx{} if err := EVMKeeper.MockReceipt(Ctx, tx1.Hash(), &types.Receipt{ @@ -666,6 +682,7 @@ func setupLogs() { Address: "0x1111111111111111111111111111111111111112", Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123"}, }}, + EffectiveGasPrice: 100, }) bloom2 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ Address: common.HexToAddress("0x1111111111111111111111111111111111111113"), @@ -683,6 +700,7 @@ func setupLogs() { Address: "0x1111111111111111111111111111111111111113", Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, }}, + EffectiveGasPrice: 100, }) bloom3 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ Address: common.HexToAddress("0x1111111111111111111111111111111111111114"), @@ -700,6 +718,7 @@ func setupLogs() { Address: "0x1111111111111111111111111111111111111114", Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, }}, + EffectiveGasPrice: 100, }) bloom4 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ Address: common.HexToAddress("0x1111111111111111111111111111111111111115"), @@ -717,6 +736,27 @@ func setupLogs() { Address: "0x1111111111111111111111111111111111111115", Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, }}, + EffectiveGasPrice: 100, + }) + // create a receipt with a synthetic log + bloomSynth := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ + Address: common.HexToAddress("0x1111111111111111111111111111111111111116"), + Topics: []common.Hash{ + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000234"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), + }, + }}}}) + EVMKeeper.MockReceipt(Ctx, multiTxBlockSynthTx.Hash(), &types.Receipt{ + BlockNumber: MockHeight, + TransactionIndex: 0, + TxHashHex: multiTxBlockSynthTx.Hash().Hex(), + LogsBloom: bloomSynth[:], + Logs: []*types.Log{{ + Address: "0x1111111111111111111111111111111111111116", + Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000234", "0x0000000000000000000000000000000000000000000000000000000000000789"}, + Synthetic: true, + }}, + EffectiveGasPrice: 100, }) EVMKeeper.MockReceipt(Ctx, common.HexToHash(DebugTraceHashHex), &types.Receipt{ BlockNumber: DebugTraceMockHeight, @@ -730,9 +770,10 @@ func setupLogs() { }) EVMKeeper.SetTxHashesOnHeight(Ctx, MockHeight, []common.Hash{ multiTxBlockTx4.Hash(), + multiTxBlockSynthTx.Hash(), }) EVMKeeper.SetBlockBloom(MultiTxCtx, []ethtypes.Bloom{bloom1, bloom2, bloom3}) - EVMKeeper.SetBlockBloom(Ctx, []ethtypes.Bloom{bloom4}) + EVMKeeper.SetBlockBloom(Ctx, []ethtypes.Bloom{bloom4, bloomSynth}) } //nolint:deadcode From 218bc4a32ad45081e7679053fe5c68fe612742af Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Sat, 21 Sep 2024 19:23:49 -0400 Subject: [PATCH 04/11] fix namespace for metrics --- evmrpc/block.go | 41 +++++++------- evmrpc/block_sei.go | 29 ---------- evmrpc/block_sei_test.go | 100 --------------------------------- evmrpc/block_test.go | 117 ++++++++++++++++++++++++++++++++++++++- evmrpc/filter.go | 19 ++++--- evmrpc/server.go | 17 +++--- evmrpc/utils.go | 7 +++ 7 files changed, 162 insertions(+), 168 deletions(-) delete mode 100644 evmrpc/block_sei.go delete mode 100644 evmrpc/block_sei_test.go diff --git a/evmrpc/block.go b/evmrpc/block.go index 5f9dfcd36..0cf917c92 100644 --- a/evmrpc/block.go +++ b/evmrpc/block.go @@ -4,6 +4,7 @@ import ( "context" "crypto/sha256" "errors" + "fmt" "math/big" "strings" "sync" @@ -25,20 +26,22 @@ import ( ) type BlockAPI struct { - tmClient rpcclient.Client - keeper *keeper.Keeper - ctxProvider func(int64) sdk.Context - txConfig client.TxConfig - connectionType ConnectionType + tmClient rpcclient.Client + keeper *keeper.Keeper + ctxProvider func(int64) sdk.Context + txConfig client.TxConfig + connectionType ConnectionType + namespace string + includeSyntheticTxs bool } -func NewBlockAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func(int64) sdk.Context, txConfig client.TxConfig, connectionType ConnectionType) *BlockAPI { - return &BlockAPI{tmClient: tmClient, keeper: k, ctxProvider: ctxProvider, txConfig: txConfig, connectionType: connectionType} +func NewBlockAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func(int64) sdk.Context, txConfig client.TxConfig, connectionType ConnectionType, namespace string) *BlockAPI { + return &BlockAPI{tmClient: tmClient, keeper: k, ctxProvider: ctxProvider, txConfig: txConfig, connectionType: connectionType, includeSyntheticTxs: shouldIncludeSynthetic(namespace)} } func (a *BlockAPI) GetBlockTransactionCountByNumber(ctx context.Context, number rpc.BlockNumber) (result *hexutil.Uint, returnErr error) { startTime := time.Now() - defer recordMetrics("eth_getBlockTransactionCountByNumber", a.connectionType, startTime, returnErr == nil) + defer recordMetrics(fmt.Sprintf("%s_getBlockTransactionCountByNumber", a.namespace), a.connectionType, startTime, returnErr == nil) numberPtr, err := getBlockNumber(ctx, a.tmClient, number) if err != nil { return nil, err @@ -52,7 +55,7 @@ func (a *BlockAPI) GetBlockTransactionCountByNumber(ctx context.Context, number func (a *BlockAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) (result *hexutil.Uint, returnErr error) { startTime := time.Now() - defer recordMetrics("eth_getBlockTransactionCountByHash", a.connectionType, startTime, returnErr == nil) + defer recordMetrics(fmt.Sprintf("%s_getBlockTransactionCountByHash", a.namespace), a.connectionType, startTime, returnErr == nil) block, err := blockByHashWithRetry(ctx, a.tmClient, blockHash[:], 1) if err != nil { return nil, err @@ -62,11 +65,11 @@ func (a *BlockAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash func (a *BlockAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) { startTime := time.Now() - defer recordMetrics("eth_getBlockByHash", a.connectionType, startTime, returnErr == nil) - return a.getBlockByHash(ctx, blockHash, fullTx, false) + defer recordMetrics(fmt.Sprintf("%s_getBlockByHash", a.namespace), a.connectionType, startTime, returnErr == nil) + return a.getBlockByHash(ctx, blockHash, fullTx) } -func (a *BlockAPI) getBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool, includeSyntheticTxs bool) (result map[string]interface{}, returnErr error) { +func (a *BlockAPI) getBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) { block, err := blockByHashWithRetry(ctx, a.tmClient, blockHash[:], 1) if err != nil { return nil, err @@ -76,12 +79,12 @@ 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(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, includeSyntheticTxs) + return EncodeTmBlock(a.ctxProvider(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeSyntheticTxs) } func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { startTime := time.Now() - defer recordMetrics("eth_getBlockByNumber", a.connectionType, startTime, returnErr == nil) + defer recordMetrics(fmt.Sprintf("%s_getBlockByNumber", a.namespace), a.connectionType, startTime, returnErr == nil) if number == 0 { // for compatibility with the graph, always return genesis block return map[string]interface{}{ @@ -107,10 +110,10 @@ func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, "baseFeePerGas": (*hexutil.Big)(big.NewInt(0)), }, nil } - return a.getBlockByNumber(ctx, number, fullTx, false) + return a.getBlockByNumber(ctx, number, fullTx) } -func (a *BlockAPI) getBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool, includeSyntheticTxs bool) (result map[string]interface{}, returnErr error) { +func (a *BlockAPI) getBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { numberPtr, err := getBlockNumber(ctx, a.tmClient, number) if err != nil { return nil, err @@ -124,12 +127,12 @@ func (a *BlockAPI) getBlockByNumber(ctx context.Context, number rpc.BlockNumber, return nil, err } blockBloom := a.keeper.GetBlockBloom(a.ctxProvider(block.Block.Height)) - return EncodeTmBlock(a.ctxProvider(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, includeSyntheticTxs) + return EncodeTmBlock(a.ctxProvider(LatestCtxHeight), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeSyntheticTxs) } func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (result []map[string]interface{}, returnErr error) { startTime := time.Now() - defer recordMetrics("eth_getBlockReceipts", a.connectionType, startTime, returnErr == nil) + defer recordMetrics(fmt.Sprintf("%s_getBlockReceipts", a.namespace), a.connectionType, startTime, returnErr == nil) // Get height from params heightPtr, err := GetBlockNumberByNrOrHash(ctx, a.tmClient, blockNrOrHash) if err != nil { @@ -165,7 +168,7 @@ func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.Block mtx.Unlock() } } else { - if len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { + if !a.includeSyntheticTxs && len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { return } if receipt.EffectiveGasPrice == 0 { diff --git a/evmrpc/block_sei.go b/evmrpc/block_sei.go deleted file mode 100644 index 690c2fa4e..000000000 --- a/evmrpc/block_sei.go +++ /dev/null @@ -1,29 +0,0 @@ -package evmrpc - -import ( - "context" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rpc" -) - -type SeiBlockAPI struct { - *BlockAPI -} - -func NewSeiBlockAPI(blockAPI *BlockAPI) *SeiBlockAPI { - return &SeiBlockAPI{blockAPI} -} - -func (a *SeiBlockAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) { - startTime := time.Now() - defer recordMetrics("sei_getBlockByHash", a.connectionType, startTime, returnErr == nil) - return a.getBlockByHash(ctx, blockHash, fullTx, true) -} - -func (a *SeiBlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) { - startTime := time.Now() - defer recordMetrics("sei_getBlockByNumber", a.connectionType, startTime, returnErr == nil) - return a.getBlockByNumber(ctx, number, fullTx, true) -} diff --git a/evmrpc/block_sei_test.go b/evmrpc/block_sei_test.go deleted file mode 100644 index 4c08386d5..000000000 --- a/evmrpc/block_sei_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package evmrpc_test - -import ( - "crypto/sha256" - "math/big" - "testing" - - types2 "github.com/tendermint/tendermint/proto/tendermint/types" - - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/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/sei-protocol/sei-chain/evmrpc" - testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" - "github.com/sei-protocol/sei-chain/x/evm/types" - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/rpc/coretypes" - tmtypes "github.com/tendermint/tendermint/types" -) - -func TestGetSeiBlockByNumber(t *testing.T) { - for _, num := range []string{"0x8", "earliest", "latest", "pending", "finalized", "safe"} { - resObj := sendSeiRequestGood(t, "getBlockByNumber", num, true) - verifyBlockResult(t, resObj) - } - - resObj := sendSeiRequestBad(t, "getBlockByNumber", "bad_num", true) - require.Equal(t, "invalid argument 0: hex string without 0x prefix", resObj["error"].(map[string]interface{})["message"]) -} - -func TestGetSeiBlockByHash(t *testing.T) { - resObj := sendSeiRequestGood(t, "getBlockByHash", "0x0000000000000000000000000000000000000000000000000000000000000001", true) - verifyBlockResult(t, resObj) -} - -func TestEncodeWasmExecuteMsg(t *testing.T) { - k := &testkeeper.EVMTestApp.EvmKeeper - ctx := testkeeper.EVMTestApp.GetContextForDeliverTx(nil) - fromSeiAddr, fromEvmAddr := testkeeper.MockAddressPair() - toSeiAddr, _ := testkeeper.MockAddressPair() - b := TxConfig.NewTxBuilder() - b.SetMsgs(&wasmtypes.MsgExecuteContract{ - Sender: fromSeiAddr.String(), - Contract: toSeiAddr.String(), - Msg: []byte{1, 2, 3}, - }) - tx := b.GetTx() - bz, _ := Encoder(tx) - k.MockReceipt(ctx, sha256.Sum256(bz), &types.Receipt{ - TransactionIndex: 1, - From: fromEvmAddr.Hex(), - }) - resBlock := coretypes.ResultBlock{ - BlockID: MockBlockID, - Block: &tmtypes.Block{ - Header: mockBlockHeader(MockHeight), - Data: tmtypes.Data{ - Txs: []tmtypes.Tx{bz}, - }, - LastCommit: &tmtypes.Commit{ - Height: MockHeight - 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) - require.Nil(t, err) - txs := res["transactions"].([]interface{}) - require.Equal(t, 1, len(txs)) - ti := uint64(1) - bh := common.HexToHash(MockBlockID.Hash.String()) - to := common.Address(toSeiAddr) - require.Equal(t, ðapi.RPCTransaction{ - BlockHash: &bh, - BlockNumber: (*hexutil.Big)(big.NewInt(MockHeight)), - From: fromEvmAddr, - To: &to, - Input: []byte{1, 2, 3}, - Hash: common.Hash(sha256.Sum256(bz)), - TransactionIndex: (*hexutil.Uint64)(&ti), - V: nil, - R: nil, - S: nil, - }, txs[0].(*ethapi.RPCTransaction)) -} diff --git a/evmrpc/block_test.go b/evmrpc/block_test.go index 88a2032ba..1a4c76d0f 100644 --- a/evmrpc/block_test.go +++ b/evmrpc/block_test.go @@ -1,16 +1,23 @@ package evmrpc_test import ( + "crypto/sha256" + "math/big" "testing" "time" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" types2 "github.com/tendermint/tendermint/proto/tendermint/types" 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/sei-protocol/sei-chain/evmrpc" testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/evm/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/rpc/coretypes" @@ -22,8 +29,15 @@ func TestGetBlockByHash(t *testing.T) { verifyBlockResult(t, resObj) } +func TestGetSeiBlockByHash(t *testing.T) { + resObj := sendSeiRequestGood(t, "getBlockByHash", "0x0000000000000000000000000000000000000000000000000000000000000001", true) + verifyBlockResult(t, resObj) +} + func TestGetBlockByNumber(t *testing.T) { - for _, num := range []string{"0x8", "earliest", "latest", "pending", "finalized", "safe"} { + resObjEarliest := sendSeiRequestGood(t, "getBlockByNumber", "earliest", true) + verifyGenesisBlockResult(t, resObjEarliest) + for _, num := range []string{"0x8", "latest", "pending", "finalized", "safe"} { resObj := sendRequestGood(t, "getBlockByNumber", num, true) verifyBlockResult(t, resObj) } @@ -32,6 +46,18 @@ func TestGetBlockByNumber(t *testing.T) { require.Equal(t, "invalid argument 0: hex string without 0x prefix", resObj["error"].(map[string]interface{})["message"]) } +func TestGetSeiBlockByNumber(t *testing.T) { + resObjEarliest := sendSeiRequestGood(t, "getBlockByNumber", "earliest", true) + verifyGenesisBlockResult(t, resObjEarliest) + for _, num := range []string{"0x8", "latest", "pending", "finalized", "safe"} { + resObj := sendSeiRequestGood(t, "getBlockByNumber", num, true) + verifyBlockResult(t, resObj) + } + + resObj := sendSeiRequestBad(t, "getBlockByNumber", "bad_num", true) + require.Equal(t, "invalid argument 0: hex string without 0x prefix", resObj["error"].(map[string]interface{})["message"]) +} + func TestGetBlockTransactionCount(t *testing.T) { // get by block number for _, num := range []string{"0x8", "earliest", "latest", "pending", "finalized", "safe"} { @@ -95,6 +121,30 @@ func TestGetBlockReceipts(t *testing.T) { require.Equal(t, multiTxBlockTx4.Hash().Hex(), receipt1["transactionHash"]) } +func verifyGenesisBlockResult(t *testing.T, resObj map[string]interface{}) { + resObj = resObj["result"].(map[string]interface{}) + require.Equal(t, "0x0", resObj["baseFeePerGas"]) + require.Equal(t, "0x0", resObj["difficulty"]) + require.Equal(t, "0x", resObj["extraData"]) + require.Equal(t, "0x0", resObj["gasLimit"]) + require.Equal(t, "0x0", resObj["gasUsed"]) + require.Equal(t, "0xf9d3845df25b43b1c6926f3ceda6845c17f5624e12212fd8847d0ba01da1ab9e", resObj["hash"]) + require.Equal(t, "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", resObj["logsBloom"]) + require.Equal(t, "0x0000000000000000000000000000000000000000", resObj["miner"]) + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resObj["mixHash"]) + require.Equal(t, "0x0000000000000000", resObj["nonce"]) + require.Equal(t, "0x0", resObj["number"]) + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resObj["parentHash"]) + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resObj["receiptsRoot"]) + require.Equal(t, "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", resObj["sha3Uncles"]) + require.Equal(t, "0x0", resObj["size"]) + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resObj["stateRoot"]) + require.Equal(t, "0x0", resObj["timestamp"]) + require.Equal(t, []interface{}{}, resObj["transactions"]) + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resObj["transactionsRoot"]) + require.Equal(t, []interface{}{}, resObj["uncles"]) +} + func verifyBlockResult(t *testing.T, resObj map[string]interface{}) { resObj = resObj["result"].(map[string]interface{}) require.Equal(t, "0x0", resObj["difficulty"]) @@ -103,7 +153,7 @@ func verifyBlockResult(t *testing.T, resObj map[string]interface{}) { require.Equal(t, "0x5", resObj["gasUsed"]) require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000001", resObj["hash"]) // see setup_tests.go, which have one transaction for block 0x8 (latest) - require.Equal(t, "0x00002000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000", resObj["logsBloom"]) + require.Equal(t, "0x00002000040000000000000000000080000000200000000000000000000000080000000000000000000000000000000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000100000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000010200000000000000", resObj["logsBloom"]) require.Equal(t, "0x0000000000000000000000000000000000000005", resObj["miner"]) require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resObj["mixHash"]) require.Equal(t, "0x0000000000000000", resObj["nonce"]) @@ -214,3 +264,66 @@ func TestEncodeBankMsg(t *testing.T) { txs := res["transactions"].([]interface{}) require.Equal(t, 0, len(txs)) } + +func TestEncodeWasmExecuteMsg(t *testing.T) { + k := &testkeeper.EVMTestApp.EvmKeeper + ctx := testkeeper.EVMTestApp.GetContextForDeliverTx(nil) + fromSeiAddr, fromEvmAddr := testkeeper.MockAddressPair() + toSeiAddr, _ := testkeeper.MockAddressPair() + b := TxConfig.NewTxBuilder() + b.SetMsgs(&wasmtypes.MsgExecuteContract{ + Sender: fromSeiAddr.String(), + Contract: toSeiAddr.String(), + Msg: []byte{1, 2, 3}, + }) + tx := b.GetTx() + bz, _ := Encoder(tx) + k.MockReceipt(ctx, sha256.Sum256(bz), &types.Receipt{ + TransactionIndex: 1, + From: fromEvmAddr.Hex(), + }) + resBlock := coretypes.ResultBlock{ + BlockID: MockBlockID, + Block: &tmtypes.Block{ + Header: mockBlockHeader(MockHeight), + Data: tmtypes.Data{ + Txs: []tmtypes.Tx{bz}, + }, + LastCommit: &tmtypes.Commit{ + Height: MockHeight - 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) + require.Nil(t, err) + txs := res["transactions"].([]interface{}) + require.Equal(t, 1, len(txs)) + ti := uint64(1) + bh := common.HexToHash(MockBlockID.Hash.String()) + to := common.Address(toSeiAddr) + require.Equal(t, ðapi.RPCTransaction{ + BlockHash: &bh, + BlockNumber: (*hexutil.Big)(big.NewInt(MockHeight)), + From: fromEvmAddr, + To: &to, + Input: []byte{1, 2, 3}, + Hash: common.Hash(sha256.Sum256(bz)), + TransactionIndex: (*hexutil.Uint64)(&ti), + V: nil, + R: nil, + S: nil, + }, txs[0].(*ethapi.RPCTransaction)) +} diff --git a/evmrpc/filter.go b/evmrpc/filter.go index 910b496ea..b005ca3b2 100644 --- a/evmrpc/filter.go +++ b/evmrpc/filter.go @@ -49,7 +49,7 @@ type FilterAPI struct { filterConfig *FilterConfig logFetcher *LogFetcher connectionType ConnectionType - includeSynthetic bool + namespace string } type FilterConfig struct { @@ -63,10 +63,11 @@ type EventItemDataWrapper struct { Value json.RawMessage `json:"value"` } -func NewFilterAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func(int64) sdk.Context, filterConfig *FilterConfig, connectionType ConnectionType, includeSynthetic bool) *FilterAPI { - logFetcher := &LogFetcher{tmClient: tmClient, k: k, ctxProvider: ctxProvider, filterConfig: filterConfig, includeSynthetic: includeSynthetic} +func NewFilterAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func(int64) sdk.Context, filterConfig *FilterConfig, connectionType ConnectionType, namespace string) *FilterAPI { + logFetcher := &LogFetcher{tmClient: tmClient, k: k, ctxProvider: ctxProvider, filterConfig: filterConfig, includeSynthetic: shouldIncludeSynthetic(namespace)} filters := make(map[ethrpc.ID]filter) api := &FilterAPI{ + namespace: namespace, tmClient: tmClient, filtersMu: sync.Mutex{}, filters: filters, @@ -102,7 +103,7 @@ func (a *FilterAPI) NewFilter( _ context.Context, crit filters.FilterCriteria, ) (id ethrpc.ID, err error) { - defer recordMetrics("eth_newFilter", a.connectionType, time.Now(), err == nil) + defer recordMetrics(fmt.Sprintf("%s_newFilter", a.namespace), a.connectionType, time.Now(), err == nil) a.filtersMu.Lock() defer a.filtersMu.Unlock() curFilterID := ethrpc.NewID() @@ -118,7 +119,7 @@ func (a *FilterAPI) NewFilter( func (a *FilterAPI) NewBlockFilter( _ context.Context, ) (id ethrpc.ID, err error) { - defer recordMetrics("eth_newBlockFilter", a.connectionType, time.Now(), err == nil) + defer recordMetrics(fmt.Sprintf("%s_newBlockFilter", a.namespace), a.connectionType, time.Now(), err == nil) a.filtersMu.Lock() defer a.filtersMu.Unlock() curFilterID := ethrpc.NewID() @@ -134,7 +135,7 @@ func (a *FilterAPI) GetFilterChanges( ctx context.Context, filterID ethrpc.ID, ) (res interface{}, err error) { - defer recordMetrics("eth_getFilterChanges", a.connectionType, time.Now(), err == nil) + defer recordMetrics(fmt.Sprintf("%s_getFilterChanges", a.namespace), a.connectionType, time.Now(), err == nil) a.filtersMu.Lock() defer a.filtersMu.Unlock() filter, ok := a.filters[filterID] @@ -185,7 +186,7 @@ func (a *FilterAPI) GetFilterLogs( ctx context.Context, filterID ethrpc.ID, ) (res []*ethtypes.Log, err error) { - defer recordMetrics("eth_getFilterLogs", a.connectionType, time.Now(), err == nil) + defer recordMetrics(fmt.Sprintf("%s_getFilterLogs", a.namespace), a.connectionType, time.Now(), err == nil) a.filtersMu.Lock() defer a.filtersMu.Unlock() filter, ok := a.filters[filterID] @@ -215,7 +216,7 @@ func (a *FilterAPI) GetLogs( ctx context.Context, crit filters.FilterCriteria, ) (res []*ethtypes.Log, err error) { - defer recordMetrics("eth_getLogs", a.connectionType, time.Now(), err == nil) + defer recordMetrics(fmt.Sprintf("%s_getLogs", a.namespace), a.connectionType, time.Now(), err == nil) logs, _, err := a.logFetcher.GetLogsByFilters(ctx, crit, 0) return logs, err } @@ -262,7 +263,7 @@ func (a *FilterAPI) UninstallFilter( _ context.Context, filterID ethrpc.ID, ) (res bool) { - defer recordMetrics("eth_uninstallFilter", a.connectionType, time.Now(), res) + defer recordMetrics(fmt.Sprintf("%s_uninstallFilter", a.namespace), a.connectionType, time.Now(), res) a.filtersMu.Lock() defer a.filtersMu.Unlock() _, found := a.filters[filterID] diff --git a/evmrpc/server.go b/evmrpc/server.go index 1c0d79153..10fc27181 100644 --- a/evmrpc/server.go +++ b/evmrpc/server.go @@ -45,7 +45,6 @@ func NewEVMHTTPServer( sendAPI := NewSendAPI(tmClient, txConfig, &SendConfig{slow: config.Slow}, k, ctxProvider, homeDir, simulateConfig, ConnectionTypeHTTP) ctx := ctxProvider(LatestCtxHeight) - blockAPI := NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP) txAPI := NewTransactionAPI(tmClient, k, ctxProvider, txConfig, homeDir, ConnectionTypeHTTP) // filterAPI := NewFilterAPI(tmClient, &LogFetcher{tmClient: tmClient, k: k, ctxProvider: ctxProvider}, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP) @@ -56,7 +55,11 @@ func NewEVMHTTPServer( }, { Namespace: "eth", - Service: blockAPI, + Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP, false), + }, + { + Namespace: "sei", + Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP, true), }, { Namespace: "eth", @@ -88,20 +91,16 @@ func NewEVMHTTPServer( }, { Namespace: "eth", - Service: NewFilterAPI(tmClient, k, ctxProvider, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP, false), + Service: NewFilterAPI(tmClient, k, ctxProvider, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP, "eth"), }, { Namespace: "sei", - Service: NewFilterAPI(tmClient, k, ctxProvider, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP, true), + Service: NewFilterAPI(tmClient, k, ctxProvider, &FilterConfig{timeout: config.FilterTimeout, maxLog: config.MaxLogNoBlock, maxBlock: config.MaxBlocksForLog}, ConnectionTypeHTTP, "sei"), }, { Namespace: "sei", Service: NewAssociationAPI(tmClient, k, ctxProvider, txConfig.TxDecoder(), sendAPI, ConnectionTypeHTTP), }, - { - Namespace: "sei", - Service: NewSeiBlockAPI(blockAPI), - }, { Namespace: "txpool", Service: NewTxPoolAPI(tmClient, k, ctxProvider, txConfig.TxDecoder(), &TxPoolConfig{maxNumTxs: int(config.MaxTxPoolTxs)}, ConnectionTypeHTTP), @@ -161,7 +160,7 @@ func NewEVMWebSocketServer( }, { Namespace: "eth", - Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeWS), + Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeWS, false), }, { Namespace: "eth", diff --git a/evmrpc/utils.go b/evmrpc/utils.go index 546f064ad..6fc9eb30d 100644 --- a/evmrpc/utils.go +++ b/evmrpc/utils.go @@ -196,3 +196,10 @@ func bankExists(ctx sdk.Context, k *keeper.Keeper) bool { func evmExists(ctx sdk.Context, k *keeper.Keeper) bool { return ctx.KVStore(k.GetStoreKey()).VersionExists(ctx.BlockHeight()) } + +func shouldIncludeSynthetic(namespace string) bool { + if namespace != "eth" && namespace != "sei" { + panic(fmt.Sprintf("unknown namespace %s", namespace)) + } + return namespace == "sei" +} From 45b2aaa29779fd87fefd8c0cdd3577fa20c1bd5b Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Sat, 21 Sep 2024 19:27:59 -0400 Subject: [PATCH 05/11] fix complilation --- evmrpc/server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evmrpc/server.go b/evmrpc/server.go index 10fc27181..d327640a3 100644 --- a/evmrpc/server.go +++ b/evmrpc/server.go @@ -55,11 +55,11 @@ func NewEVMHTTPServer( }, { Namespace: "eth", - Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP, false), + Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP, "eth"), }, { Namespace: "sei", - Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP, true), + Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeHTTP, "sei"), }, { Namespace: "eth", @@ -160,7 +160,7 @@ func NewEVMWebSocketServer( }, { Namespace: "eth", - Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeWS, false), + Service: NewBlockAPI(tmClient, k, ctxProvider, txConfig, ConnectionTypeWS, "eth"), }, { Namespace: "eth", From 91a7b60bd7197fa8fe1a6114d0e2712b739c0ad2 Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Sun, 22 Sep 2024 14:12:34 -0400 Subject: [PATCH 06/11] fix --- evmrpc/filter.go | 15 +++++----- evmrpc/filter_sei.go | 27 ------------------ evmrpc/filter_sei_test.go | 38 ------------------------- evmrpc/filter_test.go | 58 +++++++++++++++++++++------------------ evmrpc/tx_sei_test.go | 5 +++- evmrpc/tx_test.go | 19 ------------- 6 files changed, 42 insertions(+), 120 deletions(-) delete mode 100644 evmrpc/filter_sei.go delete mode 100644 evmrpc/filter_sei_test.go diff --git a/evmrpc/filter.go b/evmrpc/filter.go index b005ca3b2..f2cefc87b 100644 --- a/evmrpc/filter.go +++ b/evmrpc/filter.go @@ -43,13 +43,13 @@ type filter struct { } type FilterAPI struct { - tmClient rpcclient.Client - filtersMu sync.Mutex - filters map[ethrpc.ID]filter - filterConfig *FilterConfig - logFetcher *LogFetcher - connectionType ConnectionType - namespace string + tmClient rpcclient.Client + filtersMu sync.Mutex + filters map[ethrpc.ID]filter + filterConfig *FilterConfig + logFetcher *LogFetcher + connectionType ConnectionType + namespace string } type FilterConfig struct { @@ -361,7 +361,6 @@ func (f *LogFetcher) FindLogsByBloom(height int64, filters [][]bloomIndexes) (re ctx := f.ctxProvider(LatestCtxHeight) txHashes := f.k.GetTxHashesOnHeight(ctx, height) for _, hash := range txHashes { - fmt.Println("hash: ", hash) receipt, err := f.k.GetReceipt(ctx, hash) if err != nil { ctx.Logger().Error(fmt.Sprintf("FindLogsByBloom: unable to find receipt for hash %s", hash.Hex())) diff --git a/evmrpc/filter_sei.go b/evmrpc/filter_sei.go deleted file mode 100644 index b8867e21b..000000000 --- a/evmrpc/filter_sei.go +++ /dev/null @@ -1,27 +0,0 @@ -package evmrpc - -// import ( -// "context" -// "time" - -// ethtypes "github.com/ethereum/go-ethereum/core/types" -// "github.com/ethereum/go-ethereum/eth/filters" -// ) - -// type SeiFilterAPI struct { -// *FilterAPI -// } - -// func NewSeiFilterAPI(f *FilterAPI) *SeiFilterAPI { -// f.logFetcher.includeSynthetic = true -// return &SeiFilterAPI{f} -// } - -// func (a *SeiFilterAPI) GetLogs( -// ctx context.Context, -// crit filters.FilterCriteria, -// ) (res []*ethtypes.Log, err error) { -// defer recordMetrics("sei_getLogs", a.connectionType, time.Now(), err == nil) -// logs, _, err := a.logFetcher.GetLogsByFilters(ctx, crit, 0) -// return logs, err -// } diff --git a/evmrpc/filter_sei_test.go b/evmrpc/filter_sei_test.go deleted file mode 100644 index 96acfcea7..000000000 --- a/evmrpc/filter_sei_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package evmrpc_test - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" -) - -func TestSeiFilterGetLogs(t *testing.T) { - // make sure we pass all the eth_ namespace tests - // TODO: uncomment - testFilterGetLogs(t, "sei", getCommonFilterLogTests()) - - // test where we get a synthetic log - testFilterGetLogs(t, "sei", []GetFilterLogTests{ - { - name: "filter by single synthetic address", - fromBlock: "0x8", - toBlock: "0x8", - addrs: []common.Address{common.HexToAddress("0x1111111111111111111111111111111111111116")}, - wantErr: false, - check: func(t *testing.T, log map[string]interface{}) { - require.Equal(t, "0x1111111111111111111111111111111111111116", log["address"].(string)) - }, - wantLen: 1, - }, - { - name: "filter by single topic with default range, include synethetic logs", - topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000234")}}, - wantErr: false, - check: func(t *testing.T, log map[string]interface{}) { - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000234", log["topics"].([]interface{})[0].(string)) - }, - wantLen: 1, - }, - }) -} \ No newline at end of file diff --git a/evmrpc/filter_test.go b/evmrpc/filter_test.go index 59fc6a738..4f589d95d 100644 --- a/evmrpc/filter_test.go +++ b/evmrpc/filter_test.go @@ -6,8 +6,8 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/sei-protocol/sei-chain/x/evm/types" + // ethtypes "github.com/ethereum/go-ethereum/core/types" + // "github.com/sei-protocol/sei-chain/x/evm/types" "github.com/stretchr/testify/require" ) @@ -192,6 +192,35 @@ func TestFilterGetLogs(t *testing.T) { testFilterGetLogs(t, "eth", getCommonFilterLogTests()) } +func TestSeiFilterGetLogs(t *testing.T) { + // make sure we pass all the eth_ namespace tests + testFilterGetLogs(t, "sei", getCommonFilterLogTests()) + + // test where we get a synthetic log + testFilterGetLogs(t, "sei", []GetFilterLogTests{ + { + name: "filter by single synthetic address", + fromBlock: "0x8", + toBlock: "0x8", + addrs: []common.Address{common.HexToAddress("0x1111111111111111111111111111111111111116")}, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + require.Equal(t, "0x1111111111111111111111111111111111111116", log["address"].(string)) + }, + wantLen: 1, + }, + { + name: "filter by single topic with default range, include synethetic logs", + topics: [][]common.Hash{{common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000234")}}, + wantErr: false, + check: func(t *testing.T, log map[string]interface{}) { + require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000234", log["topics"].([]interface{})[0].(string)) + }, + wantLen: 1, + }, + }) +} + func TestEthEndpointShouldNotReturnSyntheticLogs(t *testing.T) { testFilterGetLogs(t, "eth", []GetFilterLogTests{ { @@ -280,31 +309,6 @@ func TestFilterGetFilterChanges(t *testing.T) { logObj := logs[0].(map[string]interface{}) require.Equal(t, "0x2", logObj["blockNumber"].(string)) - // another query - bloom := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ - Address: common.HexToAddress("0x1111111111111111111111111111111111111112"), - Topics: []common.Hash{}, - }}}}) - Ctx = Ctx.WithBlockHeight(9) - EVMKeeper.MockReceipt(Ctx, common.HexToHash("0x123456789012345678902345678901234567890123456789012345678900005"), &types.Receipt{ - BlockNumber: 9, - LogsBloom: bloom[:], - Logs: []*types.Log{{ - Address: "0x1111111111111111111111111111111111111114", - }}, - }) - EVMKeeper.SetTxHashesOnHeight(Ctx, 9, []common.Hash{ - common.HexToHash("0x123456789012345678902345678901234567890123456789012345678900005"), - }) - EVMKeeper.SetBlockBloom(Ctx, []ethtypes.Bloom{bloom}) - Ctx = Ctx.WithBlockHeight(9) - resObj = sendRequest(t, TestPort, "getFilterChanges", filterId) - Ctx = Ctx.WithBlockHeight(8) - logs = resObj["result"].([]interface{}) - require.Equal(t, 1, len(logs)) - logObj = logs[0].(map[string]interface{}) - require.Equal(t, "0x9", logObj["blockNumber"].(string)) - // error: filter id does not exist nonExistingFilterId := 1000 resObj = sendRequest(t, TestPort, "getFilterChanges", nonExistingFilterId) diff --git a/evmrpc/tx_sei_test.go b/evmrpc/tx_sei_test.go index 033c778df..29db0fc74 100644 --- a/evmrpc/tx_sei_test.go +++ b/evmrpc/tx_sei_test.go @@ -1,6 +1,9 @@ package evmrpc_test -import "testing" +import ( + // "fmt" + "testing" +) func TestGetSeiTxReceipt(t *testing.T) { testGetTxReceipt(t, "sei") diff --git a/evmrpc/tx_test.go b/evmrpc/tx_test.go index 7a3a38ba2..b6695d05d 100644 --- a/evmrpc/tx_test.go +++ b/evmrpc/tx_test.go @@ -68,25 +68,6 @@ func testGetTxReceipt(t *testing.T, namespace string) { require.Equal(t, "0x1", resObj["type"].(string)) require.Equal(t, "0x1234567890123456789012345678901234567890", resObj["contractAddress"].(string)) - receipt, err = EVMKeeper.GetReceipt(Ctx, common.HexToHash("0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e")) - require.Nil(t, err) - receipt.ContractAddress = "" - receipt.To = "0x1234567890123456789012345678901234567890" - EVMKeeper.MockReceipt(Ctx, common.HexToHash("0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e"), receipt) - body = "{\"jsonrpc\": \"2.0\",\"method\": \"eth_getTransactionReceipt\",\"params\":[\"0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e\"],\"id\":\"test\"}" - req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s:%d", TestAddr, TestPort), strings.NewReader(body)) - require.Nil(t, err) - req.Header.Set("Content-Type", "application/json") - res, err = http.DefaultClient.Do(req) - require.Nil(t, err) - resBody, err = io.ReadAll(res.Body) - require.Nil(t, err) - resObj = map[string]interface{}{} - require.Nil(t, json.Unmarshal(resBody, &resObj)) - resObj = resObj["result"].(map[string]interface{}) - require.Nil(t, resObj["contractAddress"]) - require.Equal(t, "0x1234567890123456789012345678901234567890", resObj["to"].(string)) - req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s:%d", TestAddr, TestBadPort), strings.NewReader(body)) require.Nil(t, err) req.Header.Set("Content-Type", "application/json") From 42ff86c99f3cde5409f3e30608b3ea4664c004a4 Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Sun, 22 Sep 2024 22:28:47 -0400 Subject: [PATCH 07/11] fix CW20ToERC20Pointer - should transfer token --- contracts/test/CW20toERC20PointerTest.js | 17 ++++++++++++----- evmrpc/block.go | 3 --- evmrpc/filter.go | 7 ++++++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/contracts/test/CW20toERC20PointerTest.js b/contracts/test/CW20toERC20PointerTest.js index f1444fa5b..61ff0baa2 100644 --- a/contracts/test/CW20toERC20PointerTest.js +++ b/contracts/test/CW20toERC20PointerTest.js @@ -3,6 +3,7 @@ const {getAdmin, queryWasm, executeWasm, associateWasm, deployEvmContract, setup proposeCW20toERC20Upgrade } = require("./lib"); const { expect } = require("chai"); +const { ethers } = require("hardhat"); describe("CW20 to ERC20 Pointer", function () { let accounts; @@ -102,18 +103,24 @@ describe("CW20 to ERC20 Pointer", function () { const txHash = res["txhash"]; const receipt = await ethers.provider.getTransactionReceipt(`0x${txHash}`); expect(receipt).not.to.be.null; + console.log("receipt[\"blockNumber\"]", receipt["blockNumber"]); + const bn = receipt["blockNumber"]; const filter = { - fromBlock: receipt["blockNumber"], + fromBlock: '0x' + bn.toString(16), toBlock: 'latest', address: receipt["to"], topics: [ethers.id("Transfer(address,address,uint256)")] }; - const logs = await ethers.provider.getLogs(filter); - expect(logs.length).to.equal(1); - expect(logs[0]["topics"][0]).to.equal(ethers.id("Transfer(address,address,uint256)")); + // send via eth_ endpoint - synthetic event doesn't show up + const ethlogs = await ethers.provider.send('eth_getLogs', [filter]); + expect(ethlogs.length).to.equal(0); + + // send via sei_ endpoint - synthetic event shows up + const seilogs = await ethers.provider.send('sei_getLogs', [filter]); + expect(seilogs.length).to.equal(1); + expect(seilogs[0]["topics"][0]).to.equal(ethers.id("Transfer(address,address,uint256)")); const respAfter = await queryWasm(pointer, "balance", {address: accounts[1].seiAddress}); const balanceAfter = respAfter.data.balance; - expect(balanceAfter).to.equal((parseInt(balanceBefore) + 100).toString()); }); diff --git a/evmrpc/block.go b/evmrpc/block.go index 0cf917c92..789275fb5 100644 --- a/evmrpc/block.go +++ b/evmrpc/block.go @@ -171,9 +171,6 @@ func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.Block if !a.includeSyntheticTxs && len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { return } - if receipt.EffectiveGasPrice == 0 { - return - } encodedReceipt, err := encodeReceipt(receipt, a.txConfig.TxDecoder(), block, func(h common.Hash) bool { _, err := a.keeper.GetReceipt(a.ctxProvider(height), h) return err == nil diff --git a/evmrpc/filter.go b/evmrpc/filter.go index f2cefc87b..f14e644a8 100644 --- a/evmrpc/filter.go +++ b/evmrpc/filter.go @@ -366,12 +366,17 @@ func (f *LogFetcher) FindLogsByBloom(height int64, filters [][]bloomIndexes) (re ctx.Logger().Error(fmt.Sprintf("FindLogsByBloom: unable to find receipt for hash %s", hash.Hex())) continue } + fmt.Println("JEREMYDEBUG: in find logs by bloom, receipt: ", receipt) + fmt.Println("JEREMYDEBUG: in find logs by bloom, receipt.EffectiveGasPrice: ", receipt.EffectiveGasPrice) if !f.includeSynthetic && len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { + fmt.Println("JEREMYDEBUG: in find logs by bloom: skipping synthetic log") continue } - if receipt.EffectiveGasPrice == 0 { + if !f.includeSynthetic && receipt.EffectiveGasPrice == 0 { + fmt.Println("JEREMYDEBUG: in find logs by bloom: skipping zero gas price") return } + fmt.Println("JEREMYDEBUG: in find logs by bloom: checking logs bloom") if len(receipt.LogsBloom) > 0 && MatchFilters(ethtypes.Bloom(receipt.LogsBloom), filters) { res = append(res, keeper.GetLogsForTx(receipt)...) } From 317c625bd7bf567c45271073830968e5b91694c0 Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Mon, 23 Sep 2024 08:56:15 -0400 Subject: [PATCH 08/11] fix ERC20toCW20Pointer failing tests --- contracts/test/ERC20toCW20PointerTest.js | 39 +++++++++++++++--------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/contracts/test/ERC20toCW20PointerTest.js b/contracts/test/ERC20toCW20PointerTest.js index 7f6e84b6e..ff802c8b6 100644 --- a/contracts/test/ERC20toCW20PointerTest.js +++ b/contracts/test/ERC20toCW20PointerTest.js @@ -102,17 +102,23 @@ describe("ERC20 to CW20 Pointer", function () { // check logs const filter = { - fromBlock: blockNumber, + fromBlock: '0x' + blockNumber.toString(16), toBlock: 'latest', address: await pointer.getAddress(), topics: [ethers.id("Transfer(address,address,uint256)")] }; - const logs = await ethers.provider.getLogs(filter); - expect(logs.length).to.equal(1); - expect(logs[0]["address"]).to.equal(await pointer.getAddress()); - expect(logs[0]["topics"][0]).to.equal(ethers.id("Transfer(address,address,uint256)")); - expect(logs[0]["topics"][1].substring(26)).to.equal(sender.evmAddress.substring(2).toLowerCase()); - expect(logs[0]["topics"][2].substring(26)).to.equal(recipient.evmAddress.substring(2).toLowerCase()); + // send via eth_ endpoint - synthetic event doesn't show up + const ethlogs = await ethers.provider.send('eth_getLogs', [filter]); + expect(ethlogs.length).to.equal(0); + + // send via sei_ endpoint - synthetic event shows up + const seilogs = await ethers.provider.send('sei_getLogs', [filter]); + expect(seilogs.length).to.equal(1); + expect(seilogs.length).to.equal(1); + expect(seilogs[0]["address"].toLowerCase()).to.equal((await pointer.getAddress()).toLowerCase()); + expect(seilogs[0]["topics"][0]).to.equal(ethers.id("Transfer(address,address,uint256)")); + expect(seilogs[0]["topics"][1].substring(26)).to.equal(sender.evmAddress.substring(2).toLowerCase()); + expect(seilogs[0]["topics"][2].substring(26)).to.equal(recipient.evmAddress.substring(2).toLowerCase()); const cleanupTx = await pointer.connect(recipient.signer).transfer(sender.evmAddress, 1); await cleanupTx.wait(); @@ -147,17 +153,22 @@ describe("ERC20 to CW20 Pointer", function () { // check logs const filter = { - fromBlock: blockNumber, + fromBlock: '0x' + blockNumber.toString(16), toBlock: 'latest', address: await pointer.getAddress(), topics: [ethers.id("Approval(address,address,uint256)")] }; - const logs = await ethers.provider.getLogs(filter); - expect(logs.length).to.equal(1); - expect(logs[0]["address"]).to.equal(await pointer.getAddress()); - expect(logs[0]["topics"][0]).to.equal(ethers.id("Approval(address,address,uint256)")); - expect(logs[0]["topics"][1].substring(26)).to.equal(owner.substring(2).toLowerCase()); - expect(logs[0]["topics"][2].substring(26)).to.equal(spender.substring(2).toLowerCase()); + // send via eth_ endpoint - synthetic event doesn't show up + const ethlogs = await ethers.provider.send('eth_getLogs', [filter]); + expect(ethlogs.length).to.equal(0); + + // send via sei_ endpoint - synthetic event shows up + const seilogs = await ethers.provider.send('sei_getLogs', [filter]); + expect(seilogs.length).to.equal(1); + expect(seilogs[0]["address"]).to.equal(await pointer.getAddress()); + expect(seilogs[0]["topics"][0]).to.equal(ethers.id("Approval(address,address,uint256)")); + expect(seilogs[0]["topics"][1].substring(26)).to.equal(owner.substring(2).toLowerCase()); + expect(seilogs[0]["topics"][2].substring(26)).to.equal(spender.substring(2).toLowerCase()); }); it("should lower approval", async function () { From c7400abbd21a27c2dafea6961d87c44995106dd7 Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Mon, 23 Sep 2024 09:03:45 -0400 Subject: [PATCH 09/11] minor fix --- contracts/test/ERC20toCW20PointerTest.js | 2 +- evmrpc/filter.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/test/ERC20toCW20PointerTest.js b/contracts/test/ERC20toCW20PointerTest.js index ff802c8b6..06d81fc4c 100644 --- a/contracts/test/ERC20toCW20PointerTest.js +++ b/contracts/test/ERC20toCW20PointerTest.js @@ -165,7 +165,7 @@ describe("ERC20 to CW20 Pointer", function () { // send via sei_ endpoint - synthetic event shows up const seilogs = await ethers.provider.send('sei_getLogs', [filter]); expect(seilogs.length).to.equal(1); - expect(seilogs[0]["address"]).to.equal(await pointer.getAddress()); + expect(seilogs[0]["address"].toLowerCase()).to.equal((await pointer.getAddress()).toLowerCase()); expect(seilogs[0]["topics"][0]).to.equal(ethers.id("Approval(address,address,uint256)")); expect(seilogs[0]["topics"][1].substring(26)).to.equal(owner.substring(2).toLowerCase()); expect(seilogs[0]["topics"][2].substring(26)).to.equal(spender.substring(2).toLowerCase()); diff --git a/evmrpc/filter.go b/evmrpc/filter.go index f14e644a8..69122d81b 100644 --- a/evmrpc/filter.go +++ b/evmrpc/filter.go @@ -366,17 +366,17 @@ func (f *LogFetcher) FindLogsByBloom(height int64, filters [][]bloomIndexes) (re ctx.Logger().Error(fmt.Sprintf("FindLogsByBloom: unable to find receipt for hash %s", hash.Hex())) continue } - fmt.Println("JEREMYDEBUG: in find logs by bloom, receipt: ", receipt) - fmt.Println("JEREMYDEBUG: in find logs by bloom, receipt.EffectiveGasPrice: ", receipt.EffectiveGasPrice) + // fmt.Println("JEREMYDEBUG: in find logs by bloom, receipt: ", receipt) + // fmt.Println("JEREMYDEBUG: in find logs by bloom, receipt.EffectiveGasPrice: ", receipt.EffectiveGasPrice) if !f.includeSynthetic && len(receipt.Logs) > 0 && receipt.Logs[0].Synthetic { - fmt.Println("JEREMYDEBUG: in find logs by bloom: skipping synthetic log") + // fmt.Println("JEREMYDEBUG: in find logs by bloom: skipping synthetic log") continue } if !f.includeSynthetic && receipt.EffectiveGasPrice == 0 { - fmt.Println("JEREMYDEBUG: in find logs by bloom: skipping zero gas price") + // fmt.Println("JEREMYDEBUG: in find logs by bloom: skipping zero gas price") return } - fmt.Println("JEREMYDEBUG: in find logs by bloom: checking logs bloom") + // fmt.Println("JEREMYDEBUG: in find logs by bloom: checking logs bloom") if len(receipt.LogsBloom) > 0 && MatchFilters(ethtypes.Bloom(receipt.LogsBloom), filters) { res = append(res, keeper.GetLogsForTx(receipt)...) } From 6be061d5139fdc5ee0e2712c4058a46ec2754600 Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Mon, 23 Sep 2024 09:14:57 -0400 Subject: [PATCH 10/11] revert tx.go changes --- evmrpc/server.go | 4 ---- evmrpc/tx.go | 8 -------- evmrpc/tx_sei.go | 29 ----------------------------- evmrpc/tx_sei_test.go | 14 -------------- 4 files changed, 55 deletions(-) delete mode 100644 evmrpc/tx_sei.go delete mode 100644 evmrpc/tx_sei_test.go diff --git a/evmrpc/server.go b/evmrpc/server.go index d327640a3..a76045e29 100644 --- a/evmrpc/server.go +++ b/evmrpc/server.go @@ -65,10 +65,6 @@ func NewEVMHTTPServer( Namespace: "eth", Service: txAPI, }, - { - Namespace: "sei", - Service: NewSeiTransactionAPI(txAPI), - }, { Namespace: "eth", Service: NewStateAPI(tmClient, k, ctxProvider, ConnectionTypeHTTP), diff --git a/evmrpc/tx.go b/evmrpc/tx.go index f361d9cc3..9d773c872 100644 --- a/evmrpc/tx.go +++ b/evmrpc/tx.go @@ -43,10 +43,6 @@ func NewTransactionAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func (t *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (result map[string]interface{}, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getTransactionReceipt", t.connectionType, startTime, returnErr == nil) - return t.getTransactionReceipt(ctx, hash) -} - -func (t *TransactionAPI) getTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { sdkctx := t.ctxProvider(LatestCtxHeight) receipt, err := t.keeper.GetReceipt(sdkctx, hash) if err != nil { @@ -105,10 +101,6 @@ func (t *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, func (t *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (result *ethapi.RPCTransaction, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getTransactionByHash", t.connectionType, startTime, returnErr == nil) - return t.getTransactionByHash(ctx, hash, false) -} - -func (t *TransactionAPI) getTransactionByHash(ctx context.Context, hash common.Hash, includeSynthetic bool) (*ethapi.RPCTransaction, error) { sdkCtx := t.ctxProvider(LatestCtxHeight) // first try get from mempool for page := 1; page <= UnconfirmedTxQueryMaxPage; page++ { diff --git a/evmrpc/tx_sei.go b/evmrpc/tx_sei.go deleted file mode 100644 index b45602244..000000000 --- a/evmrpc/tx_sei.go +++ /dev/null @@ -1,29 +0,0 @@ -package evmrpc - -import ( - "context" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/lib/ethapi" -) - -type SeiTransactionAPI struct { - *TransactionAPI -} - -func NewSeiTransactionAPI(t *TransactionAPI) *SeiTransactionAPI { - return &SeiTransactionAPI{t} -} - -func (t *SeiTransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (result *ethapi.RPCTransaction, returnErr error) { - startTime := time.Now() - defer recordMetrics("sei_getTransactionByHash", t.connectionType, startTime, returnErr == nil) - return t.getTransactionByHash(ctx, hash, true) -} - -func (t *SeiTransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (result map[string]interface{}, returnErr error) { - startTime := time.Now() - defer recordMetrics("sei_getTransactionReceipt", t.connectionType, startTime, returnErr == nil) - return t.getTransactionReceipt(ctx, hash) -} diff --git a/evmrpc/tx_sei_test.go b/evmrpc/tx_sei_test.go deleted file mode 100644 index 29db0fc74..000000000 --- a/evmrpc/tx_sei_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package evmrpc_test - -import ( - // "fmt" - "testing" -) - -func TestGetSeiTxReceipt(t *testing.T) { - testGetTxReceipt(t, "sei") -} - -func TestSeiGetTransaction(t *testing.T) { - testGetTransaction(t, "sei") -} From 6c8f654d1941e2c490285b4777408977956e2d08 Mon Sep 17 00:00:00 2001 From: Jeremy Wei Date: Mon, 23 Sep 2024 09:24:57 -0400 Subject: [PATCH 11/11] fix ERC721ToCW721Pointer tests --- contracts/test/ERC721toCW721PointerTest.js | 37 ++++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/contracts/test/ERC721toCW721PointerTest.js b/contracts/test/ERC721toCW721PointerTest.js index e6d21f32a..2048c69f0 100644 --- a/contracts/test/ERC721toCW721PointerTest.js +++ b/contracts/test/ERC721toCW721PointerTest.js @@ -89,17 +89,22 @@ describe("ERC721 to CW721 Pointer", function () { expect(approved).to.equal(accounts[1].evmAddress); const filter = { - fromBlock: blockNumber, + fromBlock: '0x' + blockNumber.toString(16), toBlock: 'latest', address: await pointerAcc1.getAddress(), topics: [ethers.id("Approval(address,address,uint256)")] }; - const logs = await ethers.provider.getLogs(filter); - expect(logs.length).to.equal(1); - expect(logs[0]["address"]).to.equal(await pointerAcc1.getAddress()); - expect(logs[0]["topics"][0]).to.equal(ethers.id("Approval(address,address,uint256)")); - expect(logs[0]["topics"][1].substring(26)).to.equal(accounts[0].evmAddress.substring(2).toLowerCase()); - expect(logs[0]["topics"][2].substring(26)).to.equal(accounts[1].evmAddress.substring(2).toLowerCase()); + // send via eth_ endpoint - synthetic event doesn't show up + const ethlogs = await ethers.provider.send('eth_getLogs', [filter]); + expect(ethlogs.length).to.equal(0); + + // send via sei_ endpoint - synthetic event shows up + const seilogs = await ethers.provider.send('sei_getLogs', [filter]); + expect(seilogs.length).to.equal(1); + expect(seilogs[0]["address"].toLowerCase()).to.equal((await pointerAcc1.getAddress()).toLowerCase()); + expect(seilogs[0]["topics"][0]).to.equal(ethers.id("Approval(address,address,uint256)")); + expect(seilogs[0]["topics"][1].substring(26)).to.equal(accounts[0].evmAddress.substring(2).toLowerCase()); + expect(seilogs[0]["topics"][2].substring(26)).to.equal(accounts[1].evmAddress.substring(2).toLowerCase()); }); it("cannot approve token you don't own", async function () { @@ -113,17 +118,21 @@ describe("ERC721 to CW721 Pointer", function () { transferTxResp = await pointerAcc1.transferFrom(accounts[0].evmAddress, accounts[1].evmAddress, 2); await transferTxResp.wait(); const filter = { - fromBlock: blockNumber, + fromBlock: '0x' + blockNumber.toString(16), toBlock: 'latest', address: await pointerAcc1.getAddress(), topics: [ethers.id("Transfer(address,address,uint256)")] }; - const logs = await ethers.provider.getLogs(filter); - expect(logs.length).to.equal(1); - expect(logs[0]["address"]).to.equal(await pointerAcc1.getAddress()); - expect(logs[0]["topics"][0]).to.equal(ethers.id("Transfer(address,address,uint256)")); - expect(logs[0]["topics"][1].substring(26)).to.equal(accounts[1].evmAddress.substring(2).toLowerCase()); - expect(logs[0]["topics"][2].substring(26)).to.equal(accounts[1].evmAddress.substring(2).toLowerCase()); + // send via eth_ endpoint - synthetic event doesn't show up + const ethlogs = await ethers.provider.send('eth_getLogs', [filter]); + expect(ethlogs.length).to.equal(0); + + const seilogs = await ethers.provider.send('sei_getLogs', [filter]); + expect(seilogs.length).to.equal(1); + expect(seilogs[0]["address"].toLowerCase()).to.equal((await pointerAcc1.getAddress()).toLowerCase()); + expect(seilogs[0]["topics"][0]).to.equal(ethers.id("Transfer(address,address,uint256)")); + expect(seilogs[0]["topics"][1].substring(26)).to.equal(accounts[1].evmAddress.substring(2).toLowerCase()); + expect(seilogs[0]["topics"][2].substring(26)).to.equal(accounts[1].evmAddress.substring(2).toLowerCase()); const balance0 = await pointerAcc0.balanceOf(accounts[0].evmAddress); expect(balance0).to.equal(0); const balance1 = await pointerAcc0.balanceOf(accounts[1].evmAddress);