From c99bdbd533707a45fad97017fb964578c3e87fde Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Tue, 18 Mar 2025 14:33:28 +1000 Subject: [PATCH] LogTopic - empty list is wildcard log topic (#8420) * empty list is wildcard log topic Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../ethereum/api/query/BlockchainQueries.java | 6 ++-- .../besu/ethereum/api/query/LogsQuery.java | 2 +- .../internal/filter/LogsQueryTest.java | 21 ----------- .../ethereum/api/query/LogsQueryTest.java | 35 +++++++++++++++++++ 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 958f73b76..3e3680354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ have support in besu-native can run mainnet ethereum configurations. Windows su - Add a fallback pivot strategy when the safe block does not change for a long time, to make possible to complete the initial sync in case the chain is not finalizing [#8395](https://github.com/hyperledger/besu/pull/8395) - Fix issue with new QBFT/IBFT blocks being produced under certain circumstances. [#8308](https://github.com/hyperledger/besu/issues/8308) - Fix QBFT and IBFT transitions that change the mining beneficiary [#8387](https://github.com/hyperledger/besu/issues/8387) +- `eth_getLogs` - empty topic is a wildcard match [#8420](https://github.com/hyperledger/besu/pull/8420) ## 25.2.2 hotfix - Pectra - Sepolia: Fix for deposit contract log decoding [#8383](https://github.com/hyperledger/besu/pull/8383) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java index 4c1757b25..eb16f1788 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java @@ -795,7 +795,7 @@ public class BlockchainQueries { * @param toBlockNumber The block number defining the last block in the search range (inclusive). * @param query Constraints on required topics by topic index. For a given index if the set of * topics is non-empty, the topic at this index must match one of the values in the set. - * @param isQueryAlive Whether or not the backend query should stay alive. + * @param isQueryAlive Whether the backend query should stay alive. * @return The set of logs matching the given constraints. */ public List matchingLogs( @@ -988,8 +988,8 @@ public class BlockchainQueries { /** * Wraps an operation on MutableWorldState with try-with-resources the corresponding block hash. - * This method provides access to the worldstate via a mapper function in order to ensure all of - * the uses of the MutableWorldState are subsequently closed, via the try-with-resources block. + * This method provides access to the worldstate via a mapper function in order to ensure all uses + * of the MutableWorldState are subsequently closed, via the try-with-resources block. * * @param return type of the operation on the MutableWorldState * @param blockHash the block hash diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/LogsQuery.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/LogsQuery.java index a604721f8..7d41f9ce2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/LogsQuery.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/LogsQuery.java @@ -99,7 +99,7 @@ public class LogsQuery { } private boolean matchesTopic(final LogTopic topic, final List matchCriteria) { - return matchCriteria.contains(null) || matchCriteria.contains(topic); + return matchCriteria.isEmpty() || matchCriteria.contains(null) || matchCriteria.contains(topic); } @Override diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/filter/LogsQueryTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/filter/LogsQueryTest.java index a9f06ed27..6f83966f2 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/filter/LogsQueryTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/filter/LogsQueryTest.java @@ -14,8 +14,6 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.datatypes.Address; @@ -428,23 +426,4 @@ public class LogsQueryTest { assertThat(query.couldMatch(LogsBloomFilter.builder().insertLog(log).build())).isTrue(); assertThat(query.matches(log)).isTrue(); } - - @Test - public void emptySubTopicProducesNoMatches() { - final Address address = Address.fromHexString("0x1111111111111111111111111111111111111111"); - - final LogTopic topic1 = - LogTopic.fromHexString( - "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - final LogTopic topic2 = - LogTopic.fromHexString( - "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); - final List> queryParameter = - Lists.newArrayList(singletonList(topic1), emptyList()); - - final LogsQuery query = new LogsQuery.Builder().address(address).topics(queryParameter).build(); - final Log log = new Log(address, data, Lists.newArrayList(topic1, topic2)); - - assertThat(query.matches(log)).isFalse(); - } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/LogsQueryTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/LogsQueryTest.java index 748222d2f..710ecf285 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/LogsQueryTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/LogsQueryTest.java @@ -71,4 +71,39 @@ public class LogsQueryTest { List.of(ERC20_TRANSFER_EVENT, SECOND_ADDRESS_TOPIC, FIRST_ADDRESS_TOPIC)))) .isTrue(); } + + @Test + public void testWildcardMatches() { + final LogsQuery query = + new LogsQuery( + List.of(), + List.of( + List.of(), // wildcard match in first spot + List.of(SECOND_ADDRESS_TOPIC))); + + assertThat(query.matches(new Log(FIRST_ADDRESS, Bytes.EMPTY, List.of()))).isFalse(); + assertThat(query.matches(new Log(FIRST_ADDRESS, Bytes.EMPTY, List.of(ERC20_TRANSFER_EVENT)))) + .isFalse(); + assertThat( + query.matches( + new Log( + FIRST_ADDRESS, + Bytes.EMPTY, + List.of(ERC20_TRANSFER_EVENT, FIRST_ADDRESS_TOPIC)))) + .isFalse(); + assertThat( + query.matches( + new Log( + FIRST_ADDRESS, + Bytes.EMPTY, + List.of(ERC20_TRANSFER_EVENT, SECOND_ADDRESS_TOPIC)))) + .isTrue(); + assertThat( + query.matches( + new Log( + FIRST_ADDRESS, + Bytes.EMPTY, + List.of(ERC20_TRANSFER_EVENT, SECOND_ADDRESS_TOPIC, FIRST_ADDRESS_TOPIC)))) + .isTrue(); + } }