From 47fba4ddb83bb92c6668cd7cf3b095a329196eac Mon Sep 17 00:00:00 2001 From: blindchaser Date: Wed, 8 Jan 2025 18:44:08 -0500 Subject: [PATCH 1/6] fix: eth_subscribe with open ended range --- evmrpc/subscribe.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/evmrpc/subscribe.go b/evmrpc/subscribe.go index 80e242be9..502190810 100644 --- a/evmrpc/subscribe.go +++ b/evmrpc/subscribe.go @@ -147,6 +147,15 @@ func (a *SubscriptionAPI) Logs(ctx context.Context, filter *filters.FilterCriter if filter == nil { filter = &filters.FilterCriteria{} } + + // convert "fromBlock":"0x0","toBlock":"latest" to default subscription behavior + // by clearing both fromBlock and toBlock + if filter.FromBlock != nil && filter.FromBlock.Int64() == 0 && + filter.ToBlock != nil && filter.ToBlock.Int64() < 0 { + filter.FromBlock = nil + filter.ToBlock = nil + } + rpcSub := notifier.CreateSubscription() if filter.BlockHash != nil { From c5603bdec09a936699942b6bf44c9873c5d3674d Mon Sep 17 00:00:00 2001 From: blindchaser Date: Wed, 8 Jan 2025 19:45:33 -0500 Subject: [PATCH 2/6] fix --- evmrpc/subscribe.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/evmrpc/subscribe.go b/evmrpc/subscribe.go index 502190810..2dba3ca07 100644 --- a/evmrpc/subscribe.go +++ b/evmrpc/subscribe.go @@ -148,12 +148,16 @@ func (a *SubscriptionAPI) Logs(ctx context.Context, filter *filters.FilterCriter filter = &filters.FilterCriteria{} } - // convert "fromBlock":"0x0","toBlock":"latest" to default subscription behavior - // by clearing both fromBlock and toBlock + // when fromBlock is 0 and toBlock is latest, treat it as + // no fromBlock and toBlock specified if filter.FromBlock != nil && filter.FromBlock.Int64() == 0 && filter.ToBlock != nil && filter.ToBlock.Int64() < 0 { - filter.FromBlock = nil - filter.ToBlock = nil + unboundedFilter := &filters.FilterCriteria{ + BlockHash: nil, + Addresses: filter.Addresses, + Topics: filter.Topics, + } + filter = unboundedFilter } rpcSub := notifier.CreateSubscription() From e143f0dd1ad1d27906e089a83bb8628663c86477 Mon Sep 17 00:00:00 2001 From: blindchaser Date: Wed, 8 Jan 2025 20:46:47 -0500 Subject: [PATCH 3/6] test --- evmrpc/subscribe.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/evmrpc/subscribe.go b/evmrpc/subscribe.go index 2dba3ca07..997a9ecd7 100644 --- a/evmrpc/subscribe.go +++ b/evmrpc/subscribe.go @@ -148,12 +148,13 @@ func (a *SubscriptionAPI) Logs(ctx context.Context, filter *filters.FilterCriter filter = &filters.FilterCriteria{} } - // when fromBlock is 0 and toBlock is latest, treat it as - // no fromBlock and toBlock specified + // when fromBlock is 0 and toBlock is latest, adjust the filter + // to unbounded filter if filter.FromBlock != nil && filter.FromBlock.Int64() == 0 && filter.ToBlock != nil && filter.ToBlock.Int64() < 0 { unboundedFilter := &filters.FilterCriteria{ - BlockHash: nil, + FromBlock: filter.FromBlock, // keep "0x0" to fetch historical logs + ToBlock: nil, // set to nil to continue listening Addresses: filter.Addresses, Topics: filter.Topics, } From b8b86ce2890fb048367d25882ba60c46c9606fab Mon Sep 17 00:00:00 2001 From: blindchaser Date: Tue, 21 Jan 2025 14:54:26 -0500 Subject: [PATCH 4/6] set FromBlock to latest --- evmrpc/subscribe.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evmrpc/subscribe.go b/evmrpc/subscribe.go index 997a9ecd7..43b91a874 100644 --- a/evmrpc/subscribe.go +++ b/evmrpc/subscribe.go @@ -147,14 +147,14 @@ func (a *SubscriptionAPI) Logs(ctx context.Context, filter *filters.FilterCriter if filter == nil { filter = &filters.FilterCriteria{} } - // when fromBlock is 0 and toBlock is latest, adjust the filter // to unbounded filter if filter.FromBlock != nil && filter.FromBlock.Int64() == 0 && filter.ToBlock != nil && filter.ToBlock.Int64() < 0 { + latest := big.NewInt(a.logFetcher.ctxProvider(LatestCtxHeight).BlockHeight()) unboundedFilter := &filters.FilterCriteria{ - FromBlock: filter.FromBlock, // keep "0x0" to fetch historical logs - ToBlock: nil, // set to nil to continue listening + FromBlock: latest, // set to latest block height + ToBlock: nil, // set to nil to continue listening Addresses: filter.Addresses, Topics: filter.Topics, } From 0567ec69332ebd1229ed48937acae0cabef69159 Mon Sep 17 00:00:00 2001 From: blindchaser Date: Wed, 22 Jan 2025 19:46:24 -0500 Subject: [PATCH 5/6] fix unit test --- evmrpc/setup_test.go | 176 ++++++++++++--------------------------- evmrpc/subscribe.go | 1 - evmrpc/subscribe_test.go | 37 ++++++-- 3 files changed, 82 insertions(+), 132 deletions(-) diff --git a/evmrpc/setup_test.go b/evmrpc/setup_test.go index 565c7972b..df8c7a8ea 100644 --- a/evmrpc/setup_test.go +++ b/evmrpc/setup_test.go @@ -2,7 +2,6 @@ package evmrpc_test import ( "context" - "crypto/sha256" "encoding/hex" "encoding/json" "errors" @@ -214,7 +213,7 @@ func (c *MockClient) mockBlock(height int64) *coretypes.ResultBlock { }, }, LastCommit: &tmtypes.Commit{ - Height: MockHeight8 - 1, + Height: height - 1, }, }, } @@ -674,15 +673,16 @@ func generateTxData() { TxNonEvm = app.TestTx{} TxNonEvmWithSyntheticLog = app.TestTx{} bloomTx1 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ - Address: common.HexToAddress("0x1111111111111111111111111111111111111111"), - Topics: []common.Hash{common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111"), - common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111112")}, + Address: common.HexToAddress("0x1111111111111111111111111111111111111112"), + Topics: []common.Hash{ + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), + }, }}}}) if err := EVMKeeper.MockReceipt(Ctx, tx1.Hash(), &types.Receipt{ From: "0x1234567890123456789012345678901234567890", To: "0x1234567890123456789012345678901234567890", TransactionIndex: 0, - BlockNumber: MockHeight8, + BlockNumber: 9, TxType: 1, ContractAddress: "0x1234567890123456789012345678901234567890", CumulativeGasUsed: 124, @@ -691,8 +691,8 @@ func generateTxData() { Status: 0, EffectiveGasPrice: 100000000000, Logs: []*types.Log{{ - Address: "0x1111111111111111111111111111111111111111", - Topics: []string{"0x1111111111111111111111111111111111111111111111111111111111111111", "0x1111111111111111111111111111111111111111111111111111111111111112"}, + Address: "0x1111111111111111111111111111111111111112", + Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123"}, }}, LogsBloom: bloomTx1[:], }); err != nil { @@ -771,91 +771,56 @@ func buildTx(txData ethtypes.DynamicFeeTx) (client.TxBuilder, *ethtypes.Transact return builder, tx } -func setupLogs() { - // block height 2 - bloom1 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ - Address: common.HexToAddress("0x1111111111111111111111111111111111111112"), - Topics: []common.Hash{ - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), - }, - }, { +func setupLogsAtHeight(height int64) { + ctx := Ctx.WithBlockHeight(height) + + // Create bloom and logs for this block + log := ðtypes.Log{ Address: common.HexToAddress("0x1111111111111111111111111111111111111112"), Topics: []common.Hash{ common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), }, - }}}}) - CtxMultiTx := Ctx.WithBlockHeight(MockHeight2) - EVMKeeper.MockReceipt(CtxMultiTx, multiTxBlockTx1.Hash(), &types.Receipt{ - BlockNumber: MockHeight2, - TransactionIndex: 1, // start at 1 bc 0 is the non-evm tx - TxHashHex: multiTxBlockTx1.Hash().Hex(), - LogsBloom: bloom1[:], - Logs: []*types.Log{{ - Address: "0x1111111111111111111111111111111111111112", - Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, - }, { - Address: "0x1111111111111111111111111111111111111112", - Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123"}, - }}, - EffectiveGasPrice: 100, - }) - bloom2 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ - Address: common.HexToAddress("0x1111111111111111111111111111111111111113"), - Topics: []common.Hash{ - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), - }, - }}}}) - EVMKeeper.MockReceipt(CtxMultiTx, multiTxBlockTx2.Hash(), &types.Receipt{ - BlockNumber: MockHeight2, - TransactionIndex: 3, - TxHashHex: multiTxBlockTx2.Hash().Hex(), - LogsBloom: bloom2[:], - Logs: []*types.Log{{ - Address: "0x1111111111111111111111111111111111111113", - Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, - }}, - EffectiveGasPrice: 100, - }) - bloom3 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ - Address: common.HexToAddress("0x1111111111111111111111111111111111111114"), - Topics: []common.Hash{ - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), - }, - }}}}) - EVMKeeper.MockReceipt(CtxMultiTx, multiTxBlockTx3.Hash(), &types.Receipt{ - BlockNumber: MockHeight2, - TransactionIndex: 4, - TxHashHex: multiTxBlockTx3.Hash().Hex(), - LogsBloom: bloom3[:], - Logs: []*types.Log{{ - Address: "0x1111111111111111111111111111111111111114", - Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, - }}, - EffectiveGasPrice: 100, + } + receipt := ðtypes.Receipt{ + Logs: []*ethtypes.Log{log}, + } + bloom := ethtypes.CreateBloom(ethtypes.Receipts{receipt}) + to := common.HexToAddress("010203") + // Create a new transaction for this block + _, tx := buildTx(ethtypes.DynamicFeeTx{ + Nonce: uint64(height), + GasFeeCap: big.NewInt(10), + Gas: 1000, + To: &to, + Value: big.NewInt(1000), + Data: []byte("abc"), + ChainID: big.NewInt(config.DefaultChainID), }) - bloom4 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ - Address: common.HexToAddress("0x1111111111111111111111111111111111111115"), - Topics: []common.Hash{ - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), - }, - }}}}) - CtxMock := Ctx.WithBlockHeight(MockHeight8) - EVMKeeper.MockReceipt(CtxMock, multiTxBlockTx4.Hash(), &types.Receipt{ - BlockNumber: MockHeight8, - TransactionIndex: 1, - TxHashHex: multiTxBlockTx4.Hash().Hex(), - LogsBloom: bloom4[:], + + // Mock the receipt with + EVMKeeper.MockReceipt(ctx, tx.Hash(), &types.Receipt{ + BlockNumber: uint64(height), + TransactionIndex: 0, + TxHashHex: tx.Hash().Hex(), + LogsBloom: bloom[:], Logs: []*types.Log{{ - Address: "0x1111111111111111111111111111111111111115", - Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, + Address: log.Address.Hex(), + Topics: []string{log.Topics[0].Hex()}, }}, EffectiveGasPrice: 100, }) - // create a receipt with a synthetic log + + EVMKeeper.SetBlockBloom(ctx, []ethtypes.Bloom{bloom}) +} + +func setupLogs() { + // Setup logs for block 2 + setupLogsAtHeight(MockHeight2) + + // Setup logs for block 8 + setupLogsAtHeight(MockHeight8) + + // Setup synthetic logs for block 100 bloomSynth := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ Address: common.HexToAddress("0x1111111111111111111111111111111111111116"), Topics: []common.Hash{ @@ -863,6 +828,8 @@ func setupLogs() { common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), }, }}}}) + + CtxMock := Ctx.WithBlockHeight(MockHeight100) EVMKeeper.MockReceipt(CtxMock, multiTxBlockSynthTx.Hash(), &types.Receipt{ TxType: evmrpc.ShellEVMTxType, BlockNumber: MockHeight100, @@ -876,48 +843,7 @@ func setupLogs() { }}, EffectiveGasPrice: 0, }) - CtxDebugTrace := Ctx.WithBlockHeight(MockHeight101) - EVMKeeper.MockReceipt(CtxDebugTrace, common.HexToHash(DebugTraceHashHex), &types.Receipt{ - BlockNumber: MockHeight101, - TransactionIndex: 0, - TxHashHex: DebugTraceHashHex, - }) - CtxDebugTracePanic := Ctx.WithBlockHeight(MockHeight103) - EVMKeeper.MockReceipt(CtxDebugTracePanic, common.HexToHash(TestNonPanicTxHash), &types.Receipt{ - BlockNumber: MockHeight103, - TransactionIndex: 0, - TxHashHex: TestNonPanicTxHash, - }) - EVMKeeper.MockReceipt(CtxDebugTracePanic, common.HexToHash(TestPanicTxHash), &types.Receipt{ - BlockNumber: MockHeight103, - TransactionIndex: 1, - TxHashHex: TestPanicTxHash, - }) - txNonEvmBz, _ := Encoder(TxNonEvmWithSyntheticLog) - txNonEvmHash := sha256.Sum256(txNonEvmBz) - EVMKeeper.MockReceipt(CtxMultiTx, txNonEvmHash, &types.Receipt{ - BlockNumber: MockHeight2, - TransactionIndex: 1, - TxHashHex: common.Hash(txNonEvmHash).Hex(), - LogsBloom: bloomSynth[:], - Logs: []*types.Log{{ - Address: "0x1111111111111111111111111111111111111116", - Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000234", "0x0000000000000000000000000000000000000000000000000000000000000789"}, - Synthetic: true, - }}, - EffectiveGasPrice: 100, - }) - - // block 2 - EVMKeeper.SetBlockBloom(MultiTxCtx, []ethtypes.Bloom{bloom1, bloom2, bloom3}) - // block 8 - bloomTx1 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ - Address: common.HexToAddress("0x1111111111111111111111111111111111111111"), - Topics: []common.Hash{common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111"), - common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111112")}, - }}}}) - EVMKeeper.SetBlockBloom(Ctx, []ethtypes.Bloom{bloomSynth, bloom4, bloomTx1}) } //nolint:deadcode diff --git a/evmrpc/subscribe.go b/evmrpc/subscribe.go index 43b91a874..ac99c782a 100644 --- a/evmrpc/subscribe.go +++ b/evmrpc/subscribe.go @@ -197,7 +197,6 @@ func (a *SubscriptionAPI) Logs(ctx context.Context, filter *filters.FilterCriter } begin = lastToHeight filter.FromBlock = big.NewInt(lastToHeight + 1) - time.Sleep(SleepInterval) } }() diff --git a/evmrpc/subscribe_test.go b/evmrpc/subscribe_test.go index effaf5fc3..f6ea407de 100644 --- a/evmrpc/subscribe_test.go +++ b/evmrpc/subscribe_test.go @@ -108,7 +108,6 @@ func TestSubscribeNewLogs(t *testing.T) { "toBlock": "latest", "address": []common.Address{ common.HexToAddress("0x1111111111111111111111111111111111111112"), - common.HexToAddress("0xc0ffee254729296a45a3885639AC7E10F9d54979"), }, "topics": [][]common.Hash{ { @@ -116,12 +115,29 @@ func TestSubscribeNewLogs(t *testing.T) { }, }, } + + // Create buffered channels to prevent deadlock recvCh, done := sendWSRequestGood(t, "subscribe", "logs", data) - defer func() { done <- struct{}{} }() + defer func() { + select { + case done <- struct{}{}: + default: + } + }() + + // After subscription is set up, create new logs at height 9 + setupLogsAtHeight(MockHeight8 + 1) // Setup at height 9 + + // Use non-blocking send for NewHeadsCalled + select { + case NewHeadsCalled <- struct{}{}: + default: + } receivedSubMsg := false receivedEvents := false timer := time.NewTimer(2 * time.Second) + defer timer.Stop() var subscriptionId string @@ -133,7 +149,6 @@ func TestSubscribeNewLogs(t *testing.T) { t.Fatal("Received error:", resObj["error"]) } if !receivedSubMsg { - // get subscriptionId from first message subscriptionId = resObj["result"].(string) receivedSubMsg = true continue @@ -148,7 +163,14 @@ func TestSubscribeNewLogs(t *testing.T) { t.Fatal("Subscription ID does not match") } resultMap := paramMap["result"].(map[string]interface{}) - if resultMap["address"] != "0x1111111111111111111111111111111111111112" && resultMap["address"] != "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" { + + // Verify block number is 9 (MockHeight8 + 1) + blockNum := resultMap["blockNumber"].(string) + if blockNum != "0x9" { // height 9 in hex + t.Fatalf("Expected block number 0x9, got %s", blockNum) + } + + if resultMap["address"] != "0x1111111111111111111111111111111111111112" { t.Fatalf("Unexpected address, got %v", resultMap["address"]) } firstTopic := resultMap["topics"].([]interface{})[0].(string) @@ -156,8 +178,11 @@ func TestSubscribeNewLogs(t *testing.T) { t.Fatalf("Unexpected topic, got %v", firstTopic) } case <-timer.C: - if !receivedSubMsg || !receivedEvents { - t.Fatal("No message received within 5 seconds") + if !receivedSubMsg { + t.Fatal("No subscription message received within 5 seconds") + } + if !receivedEvents { + t.Fatal("No events received within 5 seconds") } return } From 2debf7cebdc6313802b1c3d69f350e18081c15e9 Mon Sep 17 00:00:00 2001 From: blindchaser Date: Thu, 23 Jan 2025 02:39:00 -0500 Subject: [PATCH 6/6] fix --- evmrpc/setup_test.go | 176 +++++++++++++++++++++++++++------------ evmrpc/subscribe_test.go | 44 ++-------- 2 files changed, 134 insertions(+), 86 deletions(-) diff --git a/evmrpc/setup_test.go b/evmrpc/setup_test.go index df8c7a8ea..565c7972b 100644 --- a/evmrpc/setup_test.go +++ b/evmrpc/setup_test.go @@ -2,6 +2,7 @@ package evmrpc_test import ( "context" + "crypto/sha256" "encoding/hex" "encoding/json" "errors" @@ -213,7 +214,7 @@ func (c *MockClient) mockBlock(height int64) *coretypes.ResultBlock { }, }, LastCommit: &tmtypes.Commit{ - Height: height - 1, + Height: MockHeight8 - 1, }, }, } @@ -673,16 +674,15 @@ func generateTxData() { TxNonEvm = app.TestTx{} TxNonEvmWithSyntheticLog = app.TestTx{} bloomTx1 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ - Address: common.HexToAddress("0x1111111111111111111111111111111111111112"), - Topics: []common.Hash{ - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), - }, + Address: common.HexToAddress("0x1111111111111111111111111111111111111111"), + Topics: []common.Hash{common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111"), + common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111112")}, }}}}) if err := EVMKeeper.MockReceipt(Ctx, tx1.Hash(), &types.Receipt{ From: "0x1234567890123456789012345678901234567890", To: "0x1234567890123456789012345678901234567890", TransactionIndex: 0, - BlockNumber: 9, + BlockNumber: MockHeight8, TxType: 1, ContractAddress: "0x1234567890123456789012345678901234567890", CumulativeGasUsed: 124, @@ -691,8 +691,8 @@ func generateTxData() { Status: 0, EffectiveGasPrice: 100000000000, Logs: []*types.Log{{ - Address: "0x1111111111111111111111111111111111111112", - Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123"}, + Address: "0x1111111111111111111111111111111111111111", + Topics: []string{"0x1111111111111111111111111111111111111111111111111111111111111111", "0x1111111111111111111111111111111111111111111111111111111111111112"}, }}, LogsBloom: bloomTx1[:], }); err != nil { @@ -771,56 +771,91 @@ func buildTx(txData ethtypes.DynamicFeeTx) (client.TxBuilder, *ethtypes.Transact return builder, tx } -func setupLogsAtHeight(height int64) { - ctx := Ctx.WithBlockHeight(height) - - // Create bloom and logs for this block - log := ðtypes.Log{ +func setupLogs() { + // block height 2 + bloom1 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ Address: common.HexToAddress("0x1111111111111111111111111111111111111112"), Topics: []common.Hash{ common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), }, - } - receipt := ðtypes.Receipt{ - Logs: []*ethtypes.Log{log}, - } - bloom := ethtypes.CreateBloom(ethtypes.Receipts{receipt}) - to := common.HexToAddress("010203") - // Create a new transaction for this block - _, tx := buildTx(ethtypes.DynamicFeeTx{ - Nonce: uint64(height), - GasFeeCap: big.NewInt(10), - Gas: 1000, - To: &to, - Value: big.NewInt(1000), - Data: []byte("abc"), - ChainID: big.NewInt(config.DefaultChainID), + }, { + Address: common.HexToAddress("0x1111111111111111111111111111111111111112"), + Topics: []common.Hash{ + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), + }, + }}}}) + CtxMultiTx := Ctx.WithBlockHeight(MockHeight2) + EVMKeeper.MockReceipt(CtxMultiTx, multiTxBlockTx1.Hash(), &types.Receipt{ + BlockNumber: MockHeight2, + TransactionIndex: 1, // start at 1 bc 0 is the non-evm tx + TxHashHex: multiTxBlockTx1.Hash().Hex(), + LogsBloom: bloom1[:], + Logs: []*types.Log{{ + Address: "0x1111111111111111111111111111111111111112", + Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, + }, { + Address: "0x1111111111111111111111111111111111111112", + Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123"}, + }}, + EffectiveGasPrice: 100, }) - - // Mock the receipt with - EVMKeeper.MockReceipt(ctx, tx.Hash(), &types.Receipt{ - BlockNumber: uint64(height), - TransactionIndex: 0, - TxHashHex: tx.Hash().Hex(), - LogsBloom: bloom[:], + bloom2 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ + Address: common.HexToAddress("0x1111111111111111111111111111111111111113"), + Topics: []common.Hash{ + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), + }, + }}}}) + EVMKeeper.MockReceipt(CtxMultiTx, multiTxBlockTx2.Hash(), &types.Receipt{ + BlockNumber: MockHeight2, + TransactionIndex: 3, + TxHashHex: multiTxBlockTx2.Hash().Hex(), + LogsBloom: bloom2[:], Logs: []*types.Log{{ - Address: log.Address.Hex(), - Topics: []string{log.Topics[0].Hex()}, + Address: "0x1111111111111111111111111111111111111113", + Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, }}, EffectiveGasPrice: 100, }) - - EVMKeeper.SetBlockBloom(ctx, []ethtypes.Bloom{bloom}) -} - -func setupLogs() { - // Setup logs for block 2 - setupLogsAtHeight(MockHeight2) - - // Setup logs for block 8 - setupLogsAtHeight(MockHeight8) - - // Setup synthetic logs for block 100 + bloom3 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ + Address: common.HexToAddress("0x1111111111111111111111111111111111111114"), + Topics: []common.Hash{ + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), + }, + }}}}) + EVMKeeper.MockReceipt(CtxMultiTx, multiTxBlockTx3.Hash(), &types.Receipt{ + BlockNumber: MockHeight2, + TransactionIndex: 4, + TxHashHex: multiTxBlockTx3.Hash().Hex(), + LogsBloom: bloom3[:], + Logs: []*types.Log{{ + Address: "0x1111111111111111111111111111111111111114", + Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000123", "0x0000000000000000000000000000000000000000000000000000000000000456"}, + }}, + EffectiveGasPrice: 100, + }) + bloom4 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ + Address: common.HexToAddress("0x1111111111111111111111111111111111111115"), + Topics: []common.Hash{ + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), + }, + }}}}) + CtxMock := Ctx.WithBlockHeight(MockHeight8) + EVMKeeper.MockReceipt(CtxMock, multiTxBlockTx4.Hash(), &types.Receipt{ + BlockNumber: MockHeight8, + TransactionIndex: 1, + TxHashHex: multiTxBlockTx4.Hash().Hex(), + LogsBloom: bloom4[:], + Logs: []*types.Log{{ + 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{ @@ -828,8 +863,6 @@ func setupLogs() { common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000456"), }, }}}}) - - CtxMock := Ctx.WithBlockHeight(MockHeight100) EVMKeeper.MockReceipt(CtxMock, multiTxBlockSynthTx.Hash(), &types.Receipt{ TxType: evmrpc.ShellEVMTxType, BlockNumber: MockHeight100, @@ -843,7 +876,48 @@ func setupLogs() { }}, EffectiveGasPrice: 0, }) + CtxDebugTrace := Ctx.WithBlockHeight(MockHeight101) + EVMKeeper.MockReceipt(CtxDebugTrace, common.HexToHash(DebugTraceHashHex), &types.Receipt{ + BlockNumber: MockHeight101, + TransactionIndex: 0, + TxHashHex: DebugTraceHashHex, + }) + CtxDebugTracePanic := Ctx.WithBlockHeight(MockHeight103) + EVMKeeper.MockReceipt(CtxDebugTracePanic, common.HexToHash(TestNonPanicTxHash), &types.Receipt{ + BlockNumber: MockHeight103, + TransactionIndex: 0, + TxHashHex: TestNonPanicTxHash, + }) + EVMKeeper.MockReceipt(CtxDebugTracePanic, common.HexToHash(TestPanicTxHash), &types.Receipt{ + BlockNumber: MockHeight103, + TransactionIndex: 1, + TxHashHex: TestPanicTxHash, + }) + txNonEvmBz, _ := Encoder(TxNonEvmWithSyntheticLog) + txNonEvmHash := sha256.Sum256(txNonEvmBz) + EVMKeeper.MockReceipt(CtxMultiTx, txNonEvmHash, &types.Receipt{ + BlockNumber: MockHeight2, + TransactionIndex: 1, + TxHashHex: common.Hash(txNonEvmHash).Hex(), + LogsBloom: bloomSynth[:], + Logs: []*types.Log{{ + Address: "0x1111111111111111111111111111111111111116", + Topics: []string{"0x0000000000000000000000000000000000000000000000000000000000000234", "0x0000000000000000000000000000000000000000000000000000000000000789"}, + Synthetic: true, + }}, + EffectiveGasPrice: 100, + }) + + // block 2 + EVMKeeper.SetBlockBloom(MultiTxCtx, []ethtypes.Bloom{bloom1, bloom2, bloom3}) + // block 8 + bloomTx1 := ethtypes.CreateBloom(ethtypes.Receipts{ðtypes.Receipt{Logs: []*ethtypes.Log{{ + Address: common.HexToAddress("0x1111111111111111111111111111111111111111"), + Topics: []common.Hash{common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111"), + common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111112")}, + }}}}) + EVMKeeper.SetBlockBloom(Ctx, []ethtypes.Bloom{bloomSynth, bloom4, bloomTx1}) } //nolint:deadcode diff --git a/evmrpc/subscribe_test.go b/evmrpc/subscribe_test.go index f6ea407de..c3117d0e7 100644 --- a/evmrpc/subscribe_test.go +++ b/evmrpc/subscribe_test.go @@ -102,42 +102,25 @@ func TestSubscribeEmptyLogs(t *testing.T) { } func TestSubscribeNewLogs(t *testing.T) { - t.Parallel() data := map[string]interface{}{ "fromBlock": "0x0", "toBlock": "latest", "address": []common.Address{ - common.HexToAddress("0x1111111111111111111111111111111111111112"), + common.HexToAddress("0x1111111111111111111111111111111111111111"), }, "topics": [][]common.Hash{ { - common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000123"), + common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111"), + common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111112"), }, }, } - - // Create buffered channels to prevent deadlock recvCh, done := sendWSRequestGood(t, "subscribe", "logs", data) - defer func() { - select { - case done <- struct{}{}: - default: - } - }() - - // After subscription is set up, create new logs at height 9 - setupLogsAtHeight(MockHeight8 + 1) // Setup at height 9 - - // Use non-blocking send for NewHeadsCalled - select { - case NewHeadsCalled <- struct{}{}: - default: - } + defer func() { done <- struct{}{} }() receivedSubMsg := false receivedEvents := false timer := time.NewTimer(2 * time.Second) - defer timer.Stop() var subscriptionId string @@ -149,6 +132,7 @@ func TestSubscribeNewLogs(t *testing.T) { t.Fatal("Received error:", resObj["error"]) } if !receivedSubMsg { + // get subscriptionId from first message subscriptionId = resObj["result"].(string) receivedSubMsg = true continue @@ -163,26 +147,16 @@ func TestSubscribeNewLogs(t *testing.T) { t.Fatal("Subscription ID does not match") } resultMap := paramMap["result"].(map[string]interface{}) - - // Verify block number is 9 (MockHeight8 + 1) - blockNum := resultMap["blockNumber"].(string) - if blockNum != "0x9" { // height 9 in hex - t.Fatalf("Expected block number 0x9, got %s", blockNum) - } - - if resultMap["address"] != "0x1111111111111111111111111111111111111112" { + if resultMap["address"] != "0x1111111111111111111111111111111111111111" && resultMap["address"] != "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" { t.Fatalf("Unexpected address, got %v", resultMap["address"]) } firstTopic := resultMap["topics"].([]interface{})[0].(string) - if firstTopic != "0x0000000000000000000000000000000000000000000000000000000000000123" { + if firstTopic != "0x1111111111111111111111111111111111111111111111111111111111111111" { t.Fatalf("Unexpected topic, got %v", firstTopic) } case <-timer.C: - if !receivedSubMsg { - t.Fatal("No subscription message received within 5 seconds") - } - if !receivedEvents { - t.Fatal("No events received within 5 seconds") + if !receivedSubMsg || !receivedEvents { + t.Fatal("No message received within 5 seconds") } return }