diff --git a/CHANGELOG.md b/CHANGELOG.md index f00527e9d..912ffc02c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - feat(cli): add --order-by-nonce flag to list messages sequentially when filtering by sender ([filecoin-project/lotus#13394](https://github.com/filecoin-project/lotus/pull/13394)) - fix(eth): use error code 3 for EExecutionReverted for Ethereum RPC tooling compatibility ([filecoin-project/lotus#13467](https://github.com/filecoin-project/lotus/pull/13467)) - BREAKING: RPC error codes changed - EActorNotFound (3→11), EExecutionReverted (11→3). Mismatched client/server versions will deserialize these errors as the wrong Go type, breaking errors.Is/As checks. +- fix(eth): trace_filter returns [] for null round ranges ([filecoin-project/lotus#13483](https://github.com/filecoin-project/lotus/pull/13483)) # Node v1.34.3 / 2025-12-03 diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go index 65072e5ef..e914c8c2f 100644 --- a/itests/eth_transactions_test.go +++ b/itests/eth_transactions_test.go @@ -897,4 +897,28 @@ func TestTraceFilter(t *testing.T) { traces, err = client.EthTraceFilter(ctx, filter) require.NoError(t, err) require.Len(t, traces, 3) // still the same traces as before + + // Query ONLY the null round epochs - should return empty array [], not null + // Get the current block number via Eth API + currentBlock, err := client.EthBlockNumber(ctx) + require.NoError(t, err) + // The 2 null rounds are at currentBlock-2 and currentBlock-1 + // (currentBlock is the first block mined after the nulls, then we waited for one more) + // With InjectNulls(2), the next block has 2 nulls before it, so: + // - currentBlock-2 = first null round + // - currentBlock-1 = second null round + // - currentBlock = first real block after nulls + nullStartNum := uint64(currentBlock) - 2 + nullEndNum := uint64(currentBlock) - 1 + nullStart := fmt.Sprintf("0x%x", nullStartNum) + nullEnd := fmt.Sprintf("0x%x", nullEndNum) + t.Logf("Testing null round range: %s to %s (block numbers %d to %d, current %d)", nullStart, nullEnd, nullStartNum, nullEndNum, currentBlock) + filter = ethtypes.EthTraceFilterCriteria{ + FromBlock: &nullStart, + ToBlock: &nullEnd, + } + nullRoundTraces, err := client.EthTraceFilter(ctx, filter) + require.NoError(t, err) + require.NotNil(t, nullRoundTraces, "trace_filter should return [] not null for all-null-round ranges") + require.Empty(t, nullRoundTraces) } diff --git a/node/impl/eth/trace.go b/node/impl/eth/trace.go index 64954a088..b3c80bfb3 100644 --- a/node/impl/eth/trace.go +++ b/node/impl/eth/trace.go @@ -278,7 +278,7 @@ func (e *ethTrace) EthTraceFilter(ctx context.Context, filter ethtypes.EthTraceF return nil, xerrors.Errorf("cannot parse toBlock: %w", err) } - var results []*ethtypes.EthTraceFilterResult + results := []*ethtypes.EthTraceFilterResult{} if filter.Count != nil { // If filter.Count is specified and it is 0, return an empty result set immediately.