From 7f9c4fc2593bc607bf6357eb8591c5453777b473 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Mon, 30 Sep 2024 08:52:33 +1000 Subject: [PATCH 1/4] rename Hyperledger Besu to Besu (#7639) Signed-off-by: Sally MacFarlane --- MAINTAINERS.md | 2 +- SUPPORT.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index f699321ef..17958bdbd 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -82,7 +82,7 @@ The following steps must occur for a contributor to be "upgraded" as a maintaine - The proposed maintainer accepts the nomination and expresses a willingness to be a long-term (more than 6 month) committer by adding a comment in the proposal PR. - The PR will be communicated in all appropriate communication channels - including at least [besu-contributors channel on Hyperledger Discord](https://discord.gg/hyperledger), + including at least [besu-contributors channel on Discord](https://discord.gg/hyperledger), the [mailing list](https://lists.hyperledger.org/g/besu) and any maintainer/community call. - Approval by at least 3 current maintainers within two weeks of the proposal or diff --git a/SUPPORT.md b/SUPPORT.md index a9eb54acb..9e4a7b7b4 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -1,4 +1,4 @@ -# Hyperledger Besu Support +# Besu Support Welcome to the Besu repository! The following links are a set of guidelines for contributing to this repo and its packages. These are mostly guidelines, not rules. Use your best judgement, and feel free to propose changes to this document in a pull request. Contributions come in the form of code submissions, writing documentation, raising issues, helping others in chat, and any other actions that help develop Besu. @@ -6,13 +6,13 @@ Welcome to the Besu repository! The following links are a set of guidelines for Having Github, Discord, and Linux Foundation accounts is necessary for obtaining support for Besu through the community channels, wiki and issue management. * If you want to raise an issue, you can do so [on the github issue tab](https://github.com/hyperledger/besu/issues). -* Hyperledger Discord requires a [Discord account]. -* The Hyperledger wiki also requires a [Linux Foundation (LF) account] in order to edit pages. +* Discord requires a [Discord account]. +* The Besu wiki also requires a [Linux Foundation (LF) account] in order to edit pages. ### Useful support links * [Besu User Documentation] -* [Besu channel on Hyperledger Discord] +* [Besu channel on Discord] * [I just have a quick question](https://wiki.hyperledger.org/display/BESU/I+just+have+a+quick+question) * [Did you find a bug?](https://wiki.hyperledger.org/display/BESU/Reporting+Bugs) * [Issues](https://wiki.hyperledger.org/display/BESU/Issues) @@ -20,5 +20,5 @@ Having Github, Discord, and Linux Foundation accounts is necessary for obtaining [Besu User Documentation]: https://besu.hyperledger.org -[Besu channel on Hyperledger Discord]: https://discord.gg/hyperledger +[Besu channel on Discord]: https://discord.gg/hyperledger [Contributing Guidelines]: CONTRIBUTING.md From f541710c65f68840deef5308b7aec177dfdc386d Mon Sep 17 00:00:00 2001 From: Preeti <35308865+pr9t@users.noreply.github.com> Date: Mon, 30 Sep 2024 04:45:39 +0530 Subject: [PATCH 2/4] Chore:Resolved EnginerGetClientVersionV1 fails for local build (#7687) Signed-off-by: Preeti <35308865+pr9t@users.noreply.github.com> Co-authored-by: Sally MacFarlane --- .../internal/methods/engine/EngineGetClientVersionV1.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java index 689cb44e6..149728186 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java @@ -49,9 +49,11 @@ public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod { @Override public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { + String safeCommit = + (commit != null && commit.length() >= 8) ? commit.substring(0, 8) : "unknown"; return new JsonRpcSuccessResponse( request.getRequest().getId(), new EngineGetClientVersionResultV1( - ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, commit.substring(0, 8))); + ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, safeCommit)); } } From 23ad2b58b1670ad2107c81e3bcd4ad41f16f29ab Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 30 Sep 2024 10:05:24 +1000 Subject: [PATCH 3/4] Fix operator generator command excluding alloc field when generating config (#7684) Signed-off-by: Jason Frame --- .../operator/OperatorSubCommandTest.java | 64 ++++++++++++++++--- .../operator/config_generate_keys.json | 9 +-- .../config_generate_keys_ec_invalid.json | 9 +-- .../config_generate_keys_secp256r1.json | 9 +-- .../operator/config_import_keys.json | 9 +-- .../config_import_keys_invalid_keys.json | 9 +-- .../operator/config_import_keys_qbft.json | 9 +-- .../config_import_keys_secp256r1.json | 9 +-- ...ig_import_keys_secp256r1_invalid_keys.json | 9 +-- .../operator/config_no_config_section.json | 5 -- .../besu/config/GenesisReader.java | 8 +-- .../org/hyperledger/besu/config/JsonUtil.java | 20 ++++++ .../besu/config/GenesisReaderTest.java | 16 +++++ .../hyperledger/besu/config/JsonUtilTest.java | 30 +++++++++ 14 files changed, 149 insertions(+), 66 deletions(-) diff --git a/besu/src/test/java/org/hyperledger/besu/cli/subcommands/operator/OperatorSubCommandTest.java b/besu/src/test/java/org/hyperledger/besu/cli/subcommands/operator/OperatorSubCommandTest.java index 7e9a36719..ca3e6d95d 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/subcommands/operator/OperatorSubCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/subcommands/operator/OperatorSubCommandTest.java @@ -282,8 +282,10 @@ public class OperatorSubCommandTest extends CommandTestAbstract { false, singletonList("key.pub"), Optional.empty(), - Optional.of( - "0xf853a00000000000000000000000000000000000000000000000000000000000000000ea94d5feb0fc5a54a89f97aeb34c3df15397c19f6dd294d6a9a4c886eb008ac307abdc1f38745c1dd13a88808400000000c0")); + List.of( + new Field( + "extraData", + "0xf853a00000000000000000000000000000000000000000000000000000000000000000ea94d5feb0fc5a54a89f97aeb34c3df15397c19f6dd294d6a9a4c886eb008ac307abdc1f38745c1dd13a88808400000000c0"))); } @Test @@ -296,8 +298,49 @@ public class OperatorSubCommandTest extends CommandTestAbstract { false, singletonList("key.pub"), Optional.empty(), - Optional.of( - "0xf84fa00000000000000000000000000000000000000000000000000000000000000000ea94d5feb0fc5a54a89f97aeb34c3df15397c19f6dd294d6a9a4c886eb008ac307abdc1f38745c1dd13a88c080c0")); + List.of( + new Field( + "extraData", + "0xf84fa00000000000000000000000000000000000000000000000000000000000000000ea94d5feb0fc5a54a89f97aeb34c3df15397c19f6dd294d6a9a4c886eb008ac307abdc1f38745c1dd13a88c080c0"))); + } + + @Test + public void generatedGenesisFileShouldContainAllOriginalFieldsExcludingExtraData() + throws IOException { + final JsonObject alloc = + new JsonObject( + """ + { + "24defc2d149861d3d245749b81fe0e6b28e04f31": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + }, + "2a813d7db3de19b07f92268b6d4125ed295cbe00": { + "balance": "0x446c3b15f9926687d2c40534fdb542000000000000" + } + }"""); + final List fields = + List.of( + new Field("nonce", "0x0"), + new Field("timestamp", "0x5b3c3d18"), + new Field("gasUsed", "0x0"), + new Field( + "parentHash", "0x0000000000000000000000000000000000000000000000000000000000000000"), + new Field("gasLimit", "0x47b760"), + new Field("difficulty", "0x1"), + new Field( + "mixHash", "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365"), + new Field("coinbase", "0x0000000000000000000000000000000000000000"), + new Field("alloc", alloc.getMap().toString())); + + runCmdAndCheckOutput( + cmd(), + "/operator/config_generate_keys.json", + tmpOutputDirectoryPath, + "genesis.json", + false, + singletonList("key.pub"), + Optional.empty(), + fields); } private void runCmdAndCheckOutput( @@ -316,7 +359,7 @@ public class OperatorSubCommandTest extends CommandTestAbstract { generate, expectedKeyFiles, Optional.empty(), - Optional.empty()); + List.of()); } private void runCmdAndCheckOutput( @@ -336,9 +379,11 @@ public class OperatorSubCommandTest extends CommandTestAbstract { generate, expectedKeyFiles, signatureAlgorithm, - Optional.empty()); + List.of()); } + private record Field(String key, String value) {} + private void runCmdAndCheckOutput( final Cmd cmd, final String configFile, @@ -347,7 +392,7 @@ public class OperatorSubCommandTest extends CommandTestAbstract { final boolean generate, final Collection expectedKeyFiles, final Optional signatureAlgorithm, - final Optional expectedExtraData) + final List expectedFields) throws IOException { final URL configFilePath = this.getClass().getResource(configFile); parseCommand( @@ -368,8 +413,9 @@ public class OperatorSubCommandTest extends CommandTestAbstract { final String genesisString = contentOf(outputGenesisFile, UTF_8); final JsonObject genesisContent = new JsonObject(genesisString); assertThat(genesisContent.containsKey("extraData")).isTrue(); - expectedExtraData.ifPresent( - extraData -> assertThat(genesisContent.getString("extraData")).isEqualTo(extraData)); + + expectedFields.forEach( + field -> assertThat(genesisContent.getString(field.key)).isEqualTo(field.value)); final Path expectedKeysPath = outputDirectoryPath.resolve("keys"); final File keysDirectory = new File(expectedKeysPath.toUri()); diff --git a/besu/src/test/resources/operator/config_generate_keys.json b/besu/src/test/resources/operator/config_generate_keys.json index 3723fdc3b..212bb943e 100644 --- a/besu/src/test/resources/operator/config_generate_keys.json +++ b/besu/src/test/resources/operator/config_generate_keys.json @@ -4,7 +4,9 @@ "chainId": 2017, "eip150Block": 0, "ibft2": { - + "blockperiodseconds": 2, + "epochlength": 30000, + "requesttimeoutseconds": 10 } }, "nonce": "0x0", @@ -16,11 +18,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/besu/src/test/resources/operator/config_generate_keys_ec_invalid.json b/besu/src/test/resources/operator/config_generate_keys_ec_invalid.json index 1483c45f3..3699740ab 100644 --- a/besu/src/test/resources/operator/config_generate_keys_ec_invalid.json +++ b/besu/src/test/resources/operator/config_generate_keys_ec_invalid.json @@ -5,7 +5,9 @@ "eip150Block": 0, "ecCurve": "abcd", "ibft2": { - + "blockperiodseconds": 2, + "epochlength": 30000, + "requesttimeoutseconds": 10 } }, "nonce": "0x0", @@ -17,11 +19,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/besu/src/test/resources/operator/config_generate_keys_secp256r1.json b/besu/src/test/resources/operator/config_generate_keys_secp256r1.json index f66f588ff..bbfe9f0c6 100644 --- a/besu/src/test/resources/operator/config_generate_keys_secp256r1.json +++ b/besu/src/test/resources/operator/config_generate_keys_secp256r1.json @@ -5,7 +5,9 @@ "eip150Block": 0, "ecCurve": "secp256r1", "ibft2": { - + "blockperiodseconds": 2, + "epochlength": 30000, + "requesttimeoutseconds": 10 } }, "nonce": "0x0", @@ -17,11 +19,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/besu/src/test/resources/operator/config_import_keys.json b/besu/src/test/resources/operator/config_import_keys.json index db4e57b54..78e4cd334 100644 --- a/besu/src/test/resources/operator/config_import_keys.json +++ b/besu/src/test/resources/operator/config_import_keys.json @@ -4,7 +4,9 @@ "chainId": 2017, "petersburgBlock": 0, "ibft2": { - + "blockperiodseconds": 2, + "epochlength": 30000, + "requesttimeoutseconds": 10 } }, "nonce": "0x0", @@ -16,11 +18,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/besu/src/test/resources/operator/config_import_keys_invalid_keys.json b/besu/src/test/resources/operator/config_import_keys_invalid_keys.json index 3fc4561e3..b9c20be75 100644 --- a/besu/src/test/resources/operator/config_import_keys_invalid_keys.json +++ b/besu/src/test/resources/operator/config_import_keys_invalid_keys.json @@ -4,7 +4,9 @@ "chainId": 2017, "petersburgBlock": 0, "ibft2": { - + "blockperiodseconds": 2, + "epochlength": 30000, + "requesttimeoutseconds": 10 } }, "nonce": "0x0", @@ -16,11 +18,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/besu/src/test/resources/operator/config_import_keys_qbft.json b/besu/src/test/resources/operator/config_import_keys_qbft.json index fe757326b..449ba343e 100644 --- a/besu/src/test/resources/operator/config_import_keys_qbft.json +++ b/besu/src/test/resources/operator/config_import_keys_qbft.json @@ -4,7 +4,9 @@ "chainId": 2017, "petersburgBlock": 0, "qbft": { - + "blockperiodseconds": 2, + "epochlength": 30000, + "requesttimeoutseconds": 10 } }, "nonce": "0x0", @@ -16,11 +18,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/besu/src/test/resources/operator/config_import_keys_secp256r1.json b/besu/src/test/resources/operator/config_import_keys_secp256r1.json index bd189d023..b56654b13 100644 --- a/besu/src/test/resources/operator/config_import_keys_secp256r1.json +++ b/besu/src/test/resources/operator/config_import_keys_secp256r1.json @@ -5,7 +5,9 @@ "petersburgBlock": 0, "ecCurve": "secp256r1", "ibft2": { - + "blockperiodseconds": 2, + "epochlength": 30000, + "requesttimeoutseconds": 10 } }, "nonce": "0x0", @@ -17,11 +19,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/besu/src/test/resources/operator/config_import_keys_secp256r1_invalid_keys.json b/besu/src/test/resources/operator/config_import_keys_secp256r1_invalid_keys.json index 4f59b9ebd..0870f9e87 100644 --- a/besu/src/test/resources/operator/config_import_keys_secp256r1_invalid_keys.json +++ b/besu/src/test/resources/operator/config_import_keys_secp256r1_invalid_keys.json @@ -5,7 +5,9 @@ "petersburgBlock": 0, "ecCurve": "secp256r1", "ibft2": { - + "blockperiodseconds": 2, + "epochlength": 30000, + "requesttimeoutseconds": 10 } }, "nonce": "0x0", @@ -17,11 +19,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/besu/src/test/resources/operator/config_no_config_section.json b/besu/src/test/resources/operator/config_no_config_section.json index 2841aea9c..5dfa45479 100644 --- a/besu/src/test/resources/operator/config_no_config_section.json +++ b/besu/src/test/resources/operator/config_no_config_section.json @@ -9,11 +9,6 @@ "difficulty": "0x1", "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", "coinbase": "0x0000000000000000000000000000000000000000", - "ibft2": { - "blockperiodseconds": 2, - "epochlength": 30000, - "requesttimeoutseconds": 10 - }, "alloc": { "24defc2d149861d3d245749b81fe0e6b28e04f31": { "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisReader.java b/config/src/main/java/org/hyperledger/besu/config/GenesisReader.java index 316aa73d0..6b42c3c2e 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisReader.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisReader.java @@ -53,12 +53,12 @@ interface GenesisReader { private final ObjectNode rootWithoutAllocations; public FromObjectNode(final ObjectNode root) { - final var removedAllocations = root.remove(ALLOCATION_FIELD); this.allocations = - removedAllocations != null - ? (ObjectNode) removedAllocations + root.get(ALLOCATION_FIELD) != null + ? (ObjectNode) root.get(ALLOCATION_FIELD) : JsonUtil.createEmptyObjectNode(); - this.rootWithoutAllocations = normalizeKeys(root); + this.rootWithoutAllocations = + normalizeKeys(root, field -> !field.getKey().equals(ALLOCATION_FIELD)); } @Override diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonUtil.java b/config/src/main/java/org/hyperledger/besu/config/JsonUtil.java index bcb89c64e..430c74efb 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonUtil.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonUtil.java @@ -25,6 +25,7 @@ import java.util.OptionalInt; import java.util.OptionalLong; import java.util.Set; import java.util.function.Function; +import java.util.function.Predicate; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; @@ -37,6 +38,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeType; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.base.Predicates; import org.apache.tuweni.bytes.Bytes; /** The Json util class. */ @@ -59,11 +61,29 @@ public class JsonUtil { * @return a copy of the json object with all keys in lower case. */ public static ObjectNode normalizeKeys(final ObjectNode objectNode) { + return normalizeKeys(objectNode, Predicates.alwaysTrue()); + } + + /** + * Converts all the object keys (but none of the string values) to lowercase for easier lookup. + * This is useful in cases such as the 'genesis.json' file where all keys are assumed to be case + * insensitive. + * + * @param objectNode The ObjectNode to be normalized + * @param fieldPredicate The predicate to filter the fields to normalize + * @return a copy of the json object with all keys in lower case. + */ + public static ObjectNode normalizeKeys( + final ObjectNode objectNode, final Predicate> fieldPredicate) { final ObjectNode normalized = JsonUtil.createEmptyObjectNode(); objectNode .fields() .forEachRemaining( entry -> { + if (!fieldPredicate.test(entry)) { + return; + } + final String key = entry.getKey(); final JsonNode value = entry.getValue(); final String normalizedKey = normalizeKey(key); diff --git a/config/src/test/java/org/hyperledger/besu/config/GenesisReaderTest.java b/config/src/test/java/org/hyperledger/besu/config/GenesisReaderTest.java index 5d73a2829..f8327174a 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisReaderTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisReaderTest.java @@ -53,6 +53,22 @@ public class GenesisReaderTest { .containsExactly(new GenesisAccount(Address.BLS12_G2MUL, 0, Wei.ONE, null, Map.of(), null)); } + @Test + public void readGenesisFromObjectDoesNotModifyObjectNodeArg() { + final var configNode = mapper.createObjectNode(); + configNode.put("londonBlock", 1); + final var allocNode = mapper.createObjectNode(); + allocNode.put(Address.BLS12_G2MUL.toUnprefixedHexString(), generateAllocation(Wei.ONE)); + final var rootNode = mapper.createObjectNode(); + rootNode.put("chainId", 12); + rootNode.put(CONFIG_FIELD, configNode); + rootNode.put(ALLOCATION_FIELD, allocNode); + var rootNodeCopy = rootNode.deepCopy(); + new GenesisReader.FromObjectNode(rootNode); + + assertThat(rootNode).isEqualTo(rootNodeCopy); + } + @Test public void readGenesisFromURL(@TempDir final Path folder) throws IOException { final String jsonStr = diff --git a/config/src/test/java/org/hyperledger/besu/config/JsonUtilTest.java b/config/src/test/java/org/hyperledger/besu/config/JsonUtilTest.java index 1e1df382e..fa6b4ec14 100644 --- a/config/src/test/java/org/hyperledger/besu/config/JsonUtilTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/JsonUtilTest.java @@ -147,6 +147,36 @@ public class JsonUtilTest { assertThat(normalizedObj).isEqualTo(expectedObj); } + @Test + public void normalizeKeys_predicate() { + final ObjectNode originalObj = + mapper + .createObjectNode() + .put("Ant", "Tiny") + .put("Ape", "Smart") + .put("Armadillo", "Armored") + .put("Cat", "Meow") + .put("Bat", "Flying") + .put("Cow", "Moo") + .put("Crocodile", "Snap") + .put("Bear", "Strong") + .put("Cheetah", "Fast") + .put("Beaver", "Builder"); + + final ObjectNode expectedObj = + mapper + .createObjectNode() + .put("cat", "Meow") + .put("cow", "Moo") + .put("cheetah", "Fast") + .put("crocodile", "Snap"); + + final ObjectNode normalizedObj = + JsonUtil.normalizeKeys(originalObj, s -> s.getKey().startsWith("C")); + + assertThat(normalizedObj).isEqualTo(expectedObj); + } + @Test public void getLong_nonExistentKey() { final ObjectNode node = mapper.createObjectNode(); From ffef4d5844c3f6c2e4fb4b1cb5314dd087870ce6 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 30 Sep 2024 07:46:35 +0200 Subject: [PATCH 4/4] Fix for zombie invalid and penalized txs (#7659) Signed-off-by: Fabio Di Fabio Co-authored-by: Sally MacFarlane --- .../eth/transactions/layered/LayeredPendingTransactions.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java index 21c75b364..a79c05e3e 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java @@ -351,9 +351,7 @@ public class LayeredPendingTransactions implements PendingTransactions { } }); logDiscardedTransaction(candidatePendingTx, selectionResult); - } - - if (selectionResult.penalize()) { + } else if (selectionResult.penalize()) { ethScheduler.scheduleTxWorkerTask( () -> { synchronized (this) {