From edf3b5e5787a3018dadb913f8b6e38a9a2e9cf8a Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Tue, 19 Nov 2024 15:39:26 +1100 Subject: [PATCH] fix(eth): make trace_filter resilient to null rounds --- CHANGELOG.md | 4 ++++ itests/eth_transactions_test.go | 30 +++++++++++++++++++++++++++--- node/impl/full/eth.go | 3 +++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e76d29b6568..a9409fc7f91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ # UNRELEASED +## Bug Fixes + +- Make `EthTraceFilter` / `trace_filter` skip null rounds instead of erroring. ([filecoin-project/lotus#12702](https://github.com/filecoin-project/lotus/pull/12702)) + # UNRELEASED v1.31.0 See https://github.com/filecoin-project/lotus/blob/release/v1.31.0/CHANGELOG.md diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go index 478e61df8f3..a1aaed29923 100644 --- a/itests/eth_transactions_test.go +++ b/itests/eth_transactions_test.go @@ -761,7 +761,7 @@ func TestTraceFilter(t *testing.T) { blockTime := 100 * time.Millisecond client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC()) - ens.InterconnectAll().BeginMining(blockTime) + bms := ens.InterconnectAll().BeginMining(blockTime) ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() @@ -844,7 +844,7 @@ func TestTraceFilter(t *testing.T) { require.NotNil(t, tracesAddressFilter) require.NotEmpty(t, tracesAddressFilter) - //we should only get our contract deploy transaction + // we should only get our contract deploy transaction require.Len(t, tracesAddressFilter, 1) require.Equal(t, 1, tracesAddressFilter[0].TransactionPosition) require.Equal(t, hash, tracesAddressFilter[0].TransactionHash) @@ -864,8 +864,32 @@ func TestTraceFilter(t *testing.T) { require.NotNil(t, traces) require.NotEmpty(t, traces) - //we should only get the last two results from the first trace query + // we should only get the last two results from the first trace query require.Len(t, tracesAfterCount, 2) require.Equal(t, traces[1].TransactionHash, tracesAfterCount[0].TransactionHash) require.Equal(t, traces[2].TransactionHash, tracesAfterCount[1].TransactionHash) + + // make sure we have null rounds in the chain + bms[0].InjectNulls(2) + ch, err := client.ChainNotify(ctx) + require.NoError(t, err) + hc := <-ch // current + require.Equal(t, store.HCCurrent, hc[0].Type) + beforeNullHeight := hc[0].Val.Height() + hc = <-ch // wait for next block + require.Equal(t, store.HCApply, hc[0].Type) + afterNullHeight := hc[0].Val.Height() + require.Greater(t, afterNullHeight, beforeNullHeight+1) + hc = <-ch // one more, so "latest" points to the block after nulls + require.Equal(t, store.HCApply, hc[0].Type) + + // define filter criteria that spans a null round so it has to at lest consider it + toBlock = "latest" + filter = ethtypes.EthTraceFilterCriteria{ + FromBlock: &fromBlock, + ToBlock: &toBlock, + } + traces, err = client.EthTraceFilter(ctx, filter) + require.NoError(t, err) + require.Len(t, traces, 3) // still the same traces as before } diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 3c090398614..7d70d5198cd 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -1364,6 +1364,9 @@ func (a *EthModule) EthTraceFilter(ctx context.Context, filter ethtypes.EthTrace for blkNum := fromBlock; blkNum <= toBlock; blkNum++ { blockTraces, err := a.EthTraceBlock(ctx, strconv.FormatUint(uint64(blkNum), 10)) if err != nil { + if errors.Is(err, &api.ErrNullRound{}) { + continue + } return nil, xerrors.Errorf("cannot get trace for block %d: %w", blkNum, err) }