mirror of https://github.com/hyperledger/besu
Burn in candidate for 23.7.3 (#5906)
burn-in candidate for 23.7.3 from main sha 6dc10a9..eef40bd
6dc10a9..eef40bd
---
* Drop Kotti Network support (ETC) (#5816)
Signed-off-by: Diego López León <dieguitoll@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* fix ForkId if there are no Forks and the starting timestamp is not 0 (#5819)
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* enforce that BlobTransactions have at least one blob (#5826)
* enforce that BlobTransactions have at least one blob
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Do not create ignorable segments on `revert storage-variables` (#5830)
* fix the bug that creates the ignorable chain pruner segment, add rocks exception parsing to RocksDBColumnarKeyValueStorage subclasses
* parse rocksdb error for unprintable column family id's
Signed-off-by: garyschulte <garyschulte@gmail.com>
* add versioned hashes and number of blobs to toString() (#5831)
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* add parent beacon block root to payload id calculation (#5843)
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* bump version to 23.7.3-SNAPSHOT (#5854)
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* set the beacon root address to the correct value (#5853)
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* docs(readme): fix broken link to installation of binaries page (#5859)
Fixes #5858
Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Update RocksDB version from 8.0.0 to 8.3.2 (#5832)
Signed-off-by: Ameziane H <ameziane.hamlat@consensys.net>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* use non-deprecated authenticate methods (#5852)
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* move to Hyperledger shared runners for current github actions (#5860)
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Add range tracing with worldstate (#5844)
Implement a method to trace a range of blocks and have access to the worldstate before and after the tracing
Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Layered txpool by default and txpool options hoverhaul (#5772)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Fix issue 5824 - Duplicate key errors in EthScheduler-Transactions (#5857)
Fix issue 5824 - Duplicate key errors in EthScheduler-Transactions
Signed-off-by: Ameziane H <ameziane.hamlat@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* updated gradle verification metadata (#5870)
* removed old artefacts [skip ci]
* works with compileTestJava
* restored metadata needed for codeQL and trusted-artifacts block for javadoc/sources
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
---------
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* [4844] Add encodingContext to TransactionEncoder and TransactionDecoder (#5820)
* Add decode type to TransactionDecoder
* Refactoring TransactionDecoder
* Invert methods order
* Use Transaction encoder instead of writeTo
* Move enter and leave list to inner method as pr suggestion
* Size calculation should use opaque bytes instead of rlp
---------
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* #5868: fix beacon root address and modulus for devnet 9 (#5871)
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* payload attributes: fix wrong warning and fail if beacon root is available before cancun (#5872)
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Merge MutableAccount and EVMAccount (#5863)
Merge MutableAccount and EVMAccount functionalities by removing
EVMAccount, all calls to getMutable, and the WrappedEVMAccount that was
wrapping non-EVMAccounts in a mutable fashion. Instead, use a
MutableAccount in all cases an EVMAccount would have been used. This
also tends to reduce a level of layering in many places.
Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Add world context to transaction tracing API (#5836)
* Add world context to transaction tracing API
Signed-off-by: Franklin Delehelle <franklin.delehelle@odena.eu>
* Update changelog with PR ID
Signed-off-by: Franklin Delehelle <franklin.delehelle@odena.eu>
* Add the Transaction to traceEndTransaction
Signed-off-by: Franklin Delehelle <franklin.delehelle@odena.eu>
* Rebase on main
Signed-off-by: Franklin Delehelle <franklin.delehelle@odena.eu>
* Add receipt-linked information to the transaction tracer
Signed-off-by: Franklin Delehelle <franklin.delehelle@odena.eu>
* added test
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
---------
Signed-off-by: Franklin Delehelle <franklin.delehelle@odena.eu>
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Co-authored-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Bonsai based reference test worldstate (#5686)
* create a bonsai based reference test worldstate
-> getOrCreate in BonsaiWorldStateUpdateAccumulator - do not throw if we discover an empty account in a non-null BonsaiValue<Account>
-> add curentStateRoot to t8n
-> storageEntriesFrom and streamAccounts implemented in BonsaiWorldStateKeyValueStorage
-> add endKey version of streamFromKey
* bonsai fix for self-destruct and create2 at the same address and same block
Signed-off-by: garyschulte <garyschulte@gmail.com>
Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
Co-authored-by: Karim TAAM <karim.t2am@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Don't start BFT mining coordinators until initial sync has completed (#5861)
* Don't start BFT mining coordinators until initial sync has completed
Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>
* Fix unit tests
Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>
* Fix 'enable' logic
Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>
---------
Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* display only peers ready for requets on ethstats (#5880)
* display only ready for requets peers in ethstats
Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
* cast to int
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
---------
Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* [MINOR] test RLP used for encode/decode blob tx should contain to field (#5883)
* validate to field on encode/decode for blob tx
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
* revert decode/encode checks - tis done later in tx validation
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
---------
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Fix: correctly convert percentage options in TOML configuration file (#5886)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* EIP7516 - Add BlobBaseFee opcode to Cancun EVM (#5884)
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Fix snapsync heal (#5838)
Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Upgrade besu-native (#5893)
Upgrade besu-native to 0.8.2
Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Tune G1GC to reduce Besu memory footprint (#5879)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Add updated storage to evmtool json trace (#5892)
Add the EIP-3155 "storage" option to the standard tracer, with the
caveat only updated storage is logged.
Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* Update holesky with fixed extraData, genesis time, shanghaiTime (#5890)
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* [CHANGELOG] removed duplicated line (#5904)
* removed duplicated line [skip ci]
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
* fixed spelling on Holesky
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
---------
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
* add 23.7.2 release SHAs and bump to 23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-23.7.3-RC version
Signed-off-by: garyschulte <garyschulte@gmail.com>
---------
Signed-off-by: Diego López León <dieguitoll@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com>
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Signed-off-by: Ameziane H <ameziane.hamlat@consensys.net>
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
Signed-off-by: Franklin Delehelle <franklin.delehelle@odena.eu>
Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Co-authored-by: Diego López León <dieguitoll@gmail.com>
Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com>
Co-authored-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Co-authored-by: Peter Somogyvari <petermetz@users.noreply.github.com>
Co-authored-by: ahamlat <ameziane.hamlat@consensys.net>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
Co-authored-by: matkt <karim.t2am@gmail.com>
Co-authored-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Co-authored-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
Co-authored-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
Co-authored-by: delehef <franklin.delehelle@odena.eu>
Co-authored-by: Matt Whitehead <matthew1001@gmail.com>
Co-authored-by: Simon Dudley <simon.dudley@consensys.net>
release-23.7.x
parent
7f959f2831
commit
ed9d80e10e
@ -0,0 +1,44 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.cli.converter; |
||||
|
||||
import org.hyperledger.besu.cli.converter.exception.DurationConversionException; |
||||
|
||||
import java.time.Duration; |
||||
|
||||
import picocli.CommandLine; |
||||
|
||||
/** The Duration (milliseconds) Cli type converter. */ |
||||
public class DurationMillisConverter |
||||
implements CommandLine.ITypeConverter<Duration>, TypeFormatter<Duration> { |
||||
|
||||
@Override |
||||
public Duration convert(final String value) throws DurationConversionException { |
||||
try { |
||||
final long millis = Long.parseLong(value); |
||||
if (millis < 0) { |
||||
throw new DurationConversionException(millis); |
||||
} |
||||
return Duration.ofMillis(Long.parseLong(value)); |
||||
} catch (NullPointerException | IllegalArgumentException e) { |
||||
throw new DurationConversionException(value); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public String format(final Duration value) { |
||||
return Long.toString(value.toMillis()); |
||||
} |
||||
} |
@ -0,0 +1,39 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.cli.converter.exception; |
||||
|
||||
import static java.lang.String.format; |
||||
|
||||
/** The custom Duration conversion exception. */ |
||||
public final class DurationConversionException extends Exception { |
||||
|
||||
/** |
||||
* Instantiates a new Duration conversion exception for malformed value. |
||||
* |
||||
* @param value the value |
||||
*/ |
||||
public DurationConversionException(final String value) { |
||||
super(format("'%s' is not a long", value)); |
||||
} |
||||
|
||||
/** |
||||
* Instantiates a new Duration conversion exception for negative value. |
||||
* |
||||
* @param value the millis |
||||
*/ |
||||
public DurationConversionException(final long value) { |
||||
super(format("negative value '%d' is not allowed", value)); |
||||
} |
||||
} |
@ -0,0 +1,263 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.cli.options.stable; |
||||
|
||||
import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_DOUBLE_FORMAT_HELP; |
||||
import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_INTEGER_FORMAT_HELP; |
||||
import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_LONG_FORMAT_HELP; |
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration.Implementation.LAYERED; |
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration.Implementation.LEGACY; |
||||
|
||||
import org.hyperledger.besu.cli.converter.FractionConverter; |
||||
import org.hyperledger.besu.cli.converter.PercentageConverter; |
||||
import org.hyperledger.besu.cli.options.CLIOptions; |
||||
import org.hyperledger.besu.cli.util.CommandLineUtils; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; |
||||
import org.hyperledger.besu.util.number.Fraction; |
||||
import org.hyperledger.besu.util.number.Percentage; |
||||
|
||||
import java.io.File; |
||||
import java.util.List; |
||||
|
||||
import picocli.CommandLine; |
||||
|
||||
/** The Transaction pool Cli stable options. */ |
||||
public class TransactionPoolOptions implements CLIOptions<TransactionPoolConfiguration> { |
||||
private static final String TX_POOL_IMPLEMENTATION = "--tx-pool"; |
||||
private static final String TX_POOL_DISABLE_LOCALS = "--tx-pool-disable-locals"; |
||||
private static final String TX_POOL_ENABLE_SAVE_RESTORE = "--tx-pool-enable-save-restore"; |
||||
private static final String TX_POOL_SAVE_FILE = "--tx-pool-save-file"; |
||||
private static final String TX_POOL_PRICE_BUMP = "--tx-pool-price-bump"; |
||||
private static final String RPC_TX_FEECAP = "--rpc-tx-feecap"; |
||||
private static final String STRICT_TX_REPLAY_PROTECTION_ENABLED_FLAG = |
||||
"--strict-tx-replay-protection-enabled"; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_IMPLEMENTATION}, |
||||
paramLabel = "<Enum>", |
||||
description = "The Transaction Pool implementation to use(default: ${DEFAULT-VALUE})", |
||||
arity = "0..1") |
||||
private TransactionPoolConfiguration.Implementation txPoolImplementation = LAYERED; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_DISABLE_LOCALS}, |
||||
paramLabel = "<Boolean>", |
||||
description = |
||||
"Set to true if transactions sent via RPC should have the same checks and not be prioritized over remote ones (default: ${DEFAULT-VALUE})", |
||||
fallbackValue = "true", |
||||
arity = "0..1") |
||||
private Boolean disableLocalTxs = TransactionPoolConfiguration.DEFAULT_DISABLE_LOCAL_TXS; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_ENABLE_SAVE_RESTORE}, |
||||
paramLabel = "<Boolean>", |
||||
description = |
||||
"Set to true to enable saving the txpool content to file on shutdown and reloading it on startup (default: ${DEFAULT-VALUE})", |
||||
fallbackValue = "true", |
||||
arity = "0..1") |
||||
private Boolean saveRestoreEnabled = TransactionPoolConfiguration.DEFAULT_ENABLE_SAVE_RESTORE; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_SAVE_FILE}, |
||||
paramLabel = "<STRING>", |
||||
description = |
||||
"If saving the txpool content is enabled, define a custom path for the save file (default: ${DEFAULT-VALUE} in the data-dir)", |
||||
arity = "1") |
||||
private File saveFile = TransactionPoolConfiguration.DEFAULT_SAVE_FILE; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_PRICE_BUMP}, |
||||
paramLabel = "<Percentage>", |
||||
converter = PercentageConverter.class, |
||||
description = |
||||
"Price bump percentage to replace an already existing transaction (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
private Percentage priceBump = TransactionPoolConfiguration.DEFAULT_PRICE_BUMP; |
||||
|
||||
@CommandLine.Option( |
||||
names = {RPC_TX_FEECAP}, |
||||
description = |
||||
"Maximum transaction fees (in Wei) accepted for transaction submitted through RPC (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
private Wei txFeeCap = TransactionPoolConfiguration.DEFAULT_RPC_TX_FEE_CAP; |
||||
|
||||
@CommandLine.Option( |
||||
names = {STRICT_TX_REPLAY_PROTECTION_ENABLED_FLAG}, |
||||
paramLabel = "<Boolean>", |
||||
description = |
||||
"Require transactions submitted via JSON-RPC to use replay protection in accordance with EIP-155 (default: ${DEFAULT-VALUE})", |
||||
fallbackValue = "true", |
||||
arity = "0..1") |
||||
private Boolean strictTxReplayProtectionEnabled = false; |
||||
|
||||
@CommandLine.ArgGroup( |
||||
validate = false, |
||||
heading = "@|bold Tx Pool Layered Implementation Options|@%n") |
||||
private final Layered layeredOptions = new Layered(); |
||||
|
||||
static class Layered { |
||||
private static final String TX_POOL_LAYER_MAX_CAPACITY = "--tx-pool-layer-max-capacity"; |
||||
private static final String TX_POOL_MAX_PRIORITIZED = "--tx-pool-max-prioritized"; |
||||
private static final String TX_POOL_MAX_FUTURE_BY_SENDER = "--tx-pool-max-future-by-sender"; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_LAYER_MAX_CAPACITY}, |
||||
paramLabel = MANDATORY_LONG_FORMAT_HELP, |
||||
description = |
||||
"Max amount of memory space, in bytes, that any layer within the transaction pool could occupy (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
Long txPoolLayerMaxCapacity = |
||||
TransactionPoolConfiguration.DEFAULT_PENDING_TRANSACTIONS_LAYER_MAX_CAPACITY_BYTES; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_MAX_PRIORITIZED}, |
||||
paramLabel = MANDATORY_INTEGER_FORMAT_HELP, |
||||
description = |
||||
"Max number of pending transactions that are prioritized and thus kept sorted (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
Integer txPoolMaxPrioritized = |
||||
TransactionPoolConfiguration.DEFAULT_MAX_PRIORITIZED_TRANSACTIONS; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_MAX_FUTURE_BY_SENDER}, |
||||
paramLabel = MANDATORY_INTEGER_FORMAT_HELP, |
||||
description = |
||||
"Max number of future pending transactions allowed for a single sender (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
Integer txPoolMaxFutureBySender = TransactionPoolConfiguration.DEFAULT_MAX_FUTURE_BY_SENDER; |
||||
} |
||||
|
||||
@CommandLine.ArgGroup( |
||||
validate = false, |
||||
heading = "@|bold Tx Pool Legacy Implementation Options|@%n") |
||||
private final Legacy legacyOptions = new Legacy(); |
||||
|
||||
static class Legacy { |
||||
private static final String TX_POOL_RETENTION_HOURS = "--tx-pool-retention-hours"; |
||||
private static final String TX_POOL_LIMIT_BY_ACCOUNT_PERCENTAGE = |
||||
"--tx-pool-limit-by-account-percentage"; |
||||
private static final String TX_POOL_MAX_SIZE = "--tx-pool-max-size"; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_RETENTION_HOURS}, |
||||
paramLabel = MANDATORY_INTEGER_FORMAT_HELP, |
||||
description = |
||||
"Maximum retention period of pending transactions in hours (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
Integer pendingTxRetentionPeriod = TransactionPoolConfiguration.DEFAULT_TX_RETENTION_HOURS; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_LIMIT_BY_ACCOUNT_PERCENTAGE}, |
||||
paramLabel = MANDATORY_DOUBLE_FORMAT_HELP, |
||||
converter = FractionConverter.class, |
||||
description = |
||||
"Maximum portion of the transaction pool which a single account may occupy with future transactions (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
Fraction txPoolLimitByAccountPercentage = |
||||
TransactionPoolConfiguration.DEFAULT_LIMIT_TX_POOL_BY_ACCOUNT_PERCENTAGE; |
||||
|
||||
@CommandLine.Option( |
||||
names = {TX_POOL_MAX_SIZE}, |
||||
paramLabel = MANDATORY_INTEGER_FORMAT_HELP, |
||||
description = |
||||
"Maximum number of pending transactions that will be kept in the transaction pool (default: ${DEFAULT-VALUE})", |
||||
arity = "1") |
||||
Integer txPoolMaxSize = TransactionPoolConfiguration.DEFAULT_MAX_PENDING_TRANSACTIONS; |
||||
} |
||||
|
||||
private TransactionPoolOptions() {} |
||||
|
||||
/** |
||||
* Create transaction pool options. |
||||
* |
||||
* @return the transaction pool options |
||||
*/ |
||||
public static TransactionPoolOptions create() { |
||||
return new TransactionPoolOptions(); |
||||
} |
||||
|
||||
/** |
||||
* Create Transaction Pool Options from Transaction Pool Configuration. |
||||
* |
||||
* @param config the Transaction Pool Configuration |
||||
* @return the transaction pool options |
||||
*/ |
||||
public static TransactionPoolOptions fromConfig(final TransactionPoolConfiguration config) { |
||||
final TransactionPoolOptions options = TransactionPoolOptions.create(); |
||||
options.txPoolImplementation = config.getTxPoolImplementation(); |
||||
options.saveRestoreEnabled = config.getEnableSaveRestore(); |
||||
options.disableLocalTxs = config.getDisableLocalTransactions(); |
||||
options.priceBump = config.getPriceBump(); |
||||
options.txFeeCap = config.getTxFeeCap(); |
||||
options.saveFile = config.getSaveFile(); |
||||
options.strictTxReplayProtectionEnabled = config.getStrictTransactionReplayProtectionEnabled(); |
||||
options.layeredOptions.txPoolLayerMaxCapacity = |
||||
config.getPendingTransactionsLayerMaxCapacityBytes(); |
||||
options.layeredOptions.txPoolMaxPrioritized = config.getMaxPrioritizedTransactions(); |
||||
options.layeredOptions.txPoolMaxFutureBySender = config.getMaxFutureBySender(); |
||||
options.legacyOptions.txPoolLimitByAccountPercentage = |
||||
config.getTxPoolLimitByAccountPercentage(); |
||||
options.legacyOptions.txPoolMaxSize = config.getTxPoolMaxSize(); |
||||
options.legacyOptions.pendingTxRetentionPeriod = config.getPendingTxRetentionPeriod(); |
||||
|
||||
return options; |
||||
} |
||||
|
||||
/** |
||||
* Validate that there are no inconsistencies in the specified options. For example that the |
||||
* options are valid for the selected implementation. |
||||
* |
||||
* @param commandLine the full commandLine to check all the options specified by the user |
||||
*/ |
||||
public void validate(final CommandLine commandLine) { |
||||
CommandLineUtils.failIfOptionDoesntMeetRequirement( |
||||
commandLine, |
||||
"Could not use legacy transaction pool options with layered implementation", |
||||
!txPoolImplementation.equals(LAYERED), |
||||
CommandLineUtils.getCLIOptionNames(Legacy.class)); |
||||
|
||||
CommandLineUtils.failIfOptionDoesntMeetRequirement( |
||||
commandLine, |
||||
"Could not use layered transaction pool options with legacy implementation", |
||||
!txPoolImplementation.equals(LEGACY), |
||||
CommandLineUtils.getCLIOptionNames(Layered.class)); |
||||
} |
||||
|
||||
@Override |
||||
public TransactionPoolConfiguration toDomainObject() { |
||||
return ImmutableTransactionPoolConfiguration.builder() |
||||
.txPoolImplementation(txPoolImplementation) |
||||
.enableSaveRestore(saveRestoreEnabled) |
||||
.disableLocalTransactions(disableLocalTxs) |
||||
.priceBump(priceBump) |
||||
.txFeeCap(txFeeCap) |
||||
.saveFile(saveFile) |
||||
.strictTransactionReplayProtectionEnabled(strictTxReplayProtectionEnabled) |
||||
.pendingTransactionsLayerMaxCapacityBytes(layeredOptions.txPoolLayerMaxCapacity) |
||||
.maxPrioritizedTransactions(layeredOptions.txPoolMaxPrioritized) |
||||
.maxFutureBySender(layeredOptions.txPoolMaxFutureBySender) |
||||
.txPoolLimitByAccountPercentage(legacyOptions.txPoolLimitByAccountPercentage) |
||||
.txPoolMaxSize(legacyOptions.txPoolMaxSize) |
||||
.pendingTxRetentionPeriod(legacyOptions.pendingTxRetentionPeriod) |
||||
.build(); |
||||
} |
||||
|
||||
@Override |
||||
public List<String> getCLIOptions() { |
||||
return CommandLineUtils.getCLIOptions(this, new TransactionPoolOptions()); |
||||
} |
||||
} |
@ -1,155 +0,0 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.cli.options; |
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8; |
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
import org.hyperledger.besu.cli.options.unstable.TransactionPoolOptions; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; |
||||
|
||||
import java.time.Duration; |
||||
|
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class TransactionPoolOptionsTest |
||||
extends AbstractCLIOptionsTest< |
||||
ImmutableTransactionPoolConfiguration.Builder, TransactionPoolOptions> { |
||||
|
||||
@Test |
||||
public void strictTxReplayProtection_enabled() { |
||||
final TestBesuCommand cmd = parseCommand("--strict-tx-replay-protection-enabled"); |
||||
|
||||
final TransactionPoolOptions options = getOptionsFromBesuCommand(cmd); |
||||
final TransactionPoolConfiguration config = options.toDomainObject().build(); |
||||
assertThat(config.getStrictTransactionReplayProtectionEnabled()).isTrue(); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void strictTxReplayProtection_enabledWithBooleanArg() { |
||||
final TestBesuCommand cmd = parseCommand("--strict-tx-replay-protection-enabled=true"); |
||||
|
||||
final TransactionPoolOptions options = getOptionsFromBesuCommand(cmd); |
||||
final TransactionPoolConfiguration config = options.toDomainObject().build(); |
||||
assertThat(config.getStrictTransactionReplayProtectionEnabled()).isTrue(); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void strictTxReplayProtection_disabled() { |
||||
final TestBesuCommand cmd = parseCommand("--strict-tx-replay-protection-enabled=false"); |
||||
|
||||
final TransactionPoolOptions options = getOptionsFromBesuCommand(cmd); |
||||
final TransactionPoolConfiguration config = options.toDomainObject().build(); |
||||
assertThat(config.getStrictTransactionReplayProtectionEnabled()).isFalse(); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void strictTxReplayProtection_default() { |
||||
final TestBesuCommand cmd = parseCommand(); |
||||
|
||||
final TransactionPoolOptions options = getOptionsFromBesuCommand(cmd); |
||||
final TransactionPoolConfiguration config = options.toDomainObject().build(); |
||||
assertThat(config.getStrictTransactionReplayProtectionEnabled()).isFalse(); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void txMessageKeepAliveSeconds() { |
||||
final int txMessageKeepAliveSeconds = 999; |
||||
final TestBesuCommand cmd = |
||||
parseCommand( |
||||
"--Xincoming-tx-messages-keep-alive-seconds", |
||||
String.valueOf(txMessageKeepAliveSeconds)); |
||||
|
||||
final TransactionPoolOptions options = getOptionsFromBesuCommand(cmd); |
||||
final TransactionPoolConfiguration config = options.toDomainObject().build(); |
||||
assertThat(config.getTxMessageKeepAliveSeconds()).isEqualTo(txMessageKeepAliveSeconds); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void eth65TrxAnnouncedBufferingPeriod() { |
||||
final long eth65TrxAnnouncedBufferingPeriod = 999; |
||||
final TestBesuCommand cmd = |
||||
parseCommand( |
||||
"--Xeth65-tx-announced-buffering-period-milliseconds", |
||||
String.valueOf(eth65TrxAnnouncedBufferingPeriod)); |
||||
|
||||
final TransactionPoolOptions options = getOptionsFromBesuCommand(cmd); |
||||
final TransactionPoolConfiguration config = options.toDomainObject().build(); |
||||
assertThat(config.getEth65TrxAnnouncedBufferingPeriod()) |
||||
.hasMillis(eth65TrxAnnouncedBufferingPeriod); |
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty(); |
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); |
||||
} |
||||
|
||||
@Override |
||||
ImmutableTransactionPoolConfiguration.Builder createDefaultDomainObject() { |
||||
final ImmutableTransactionPoolConfiguration defaultValue = |
||||
ImmutableTransactionPoolConfiguration.builder().build(); |
||||
return ImmutableTransactionPoolConfiguration.builder() |
||||
.strictTransactionReplayProtectionEnabled(false) |
||||
.txMessageKeepAliveSeconds(defaultValue.getTxMessageKeepAliveSeconds()) |
||||
.eth65TrxAnnouncedBufferingPeriod(defaultValue.getEth65TrxAnnouncedBufferingPeriod()) |
||||
.layeredTxPoolEnabled(defaultValue.getLayeredTxPoolEnabled()) |
||||
.pendingTransactionsLayerMaxCapacityBytes( |
||||
defaultValue.getPendingTransactionsLayerMaxCapacityBytes()) |
||||
.maxPrioritizedTransactions(defaultValue.getMaxPrioritizedTransactions()) |
||||
.maxFutureBySender(defaultValue.getMaxFutureBySender()); |
||||
} |
||||
|
||||
@Override |
||||
ImmutableTransactionPoolConfiguration.Builder createCustomizedDomainObject() { |
||||
return ImmutableTransactionPoolConfiguration.builder() |
||||
.strictTransactionReplayProtectionEnabled(true) |
||||
.txMessageKeepAliveSeconds(TransactionPoolConfiguration.DEFAULT_TX_MSG_KEEP_ALIVE + 1) |
||||
.eth65TrxAnnouncedBufferingPeriod( |
||||
TransactionPoolConfiguration.ETH65_TRX_ANNOUNCED_BUFFERING_PERIOD.plus( |
||||
Duration.ofMillis(100))) |
||||
.layeredTxPoolEnabled(true) |
||||
.pendingTransactionsLayerMaxCapacityBytes(1_000_000L) |
||||
.maxPrioritizedTransactions(1000) |
||||
.maxFutureBySender(10); |
||||
} |
||||
|
||||
@Override |
||||
TransactionPoolOptions optionsFromDomainObject( |
||||
final ImmutableTransactionPoolConfiguration.Builder domainObject) { |
||||
return TransactionPoolOptions.fromConfig(domainObject.build()); |
||||
} |
||||
|
||||
@Override |
||||
TransactionPoolOptions getOptionsFromBesuCommand(final TestBesuCommand besuCommand) { |
||||
return besuCommand.getTransactionPoolOptions(); |
||||
} |
||||
} |
@ -0,0 +1,243 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.cli.options.stable; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration.Implementation.LAYERED; |
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration.Implementation.LEGACY; |
||||
|
||||
import org.hyperledger.besu.cli.options.AbstractCLIOptionsTest; |
||||
import org.hyperledger.besu.cli.options.OptionParser; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; |
||||
import org.hyperledger.besu.util.number.Percentage; |
||||
|
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class TransactionPoolOptionsTest |
||||
extends AbstractCLIOptionsTest<TransactionPoolConfiguration, TransactionPoolOptions> { |
||||
|
||||
@Test |
||||
public void strictTxReplayProtection_enabled() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getStrictTransactionReplayProtectionEnabled()).isTrue(), |
||||
"--strict-tx-replay-protection-enabled"); |
||||
} |
||||
|
||||
@Test |
||||
public void strictTxReplayProtection_enabledWithBooleanArg() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getStrictTransactionReplayProtectionEnabled()).isTrue(), |
||||
"--strict-tx-replay-protection-enabled=true"); |
||||
} |
||||
|
||||
@Test |
||||
public void strictTxReplayProtection_disabled() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getStrictTransactionReplayProtectionEnabled()).isFalse(), |
||||
"--strict-tx-replay-protection-enabled=false"); |
||||
} |
||||
|
||||
@Test |
||||
public void strictTxReplayProtection_default() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getStrictTransactionReplayProtectionEnabled()).isFalse()); |
||||
} |
||||
|
||||
@Test |
||||
public void pendingTransactionRetentionPeriod() { |
||||
final int pendingTxRetentionHours = 999; |
||||
internalTestSuccess( |
||||
config -> |
||||
assertThat(config.getPendingTxRetentionPeriod()).isEqualTo(pendingTxRetentionHours), |
||||
"--tx-pool-retention-hours", |
||||
String.valueOf(pendingTxRetentionHours), |
||||
"--tx-pool=legacy"); |
||||
} |
||||
|
||||
@Test |
||||
public void disableLocalsDefault() { |
||||
internalTestSuccess(config -> assertThat(config.getDisableLocalTransactions()).isFalse()); |
||||
} |
||||
|
||||
@Test |
||||
public void disableLocalsOn() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getDisableLocalTransactions()).isTrue(), |
||||
"--tx-pool-disable-locals=true"); |
||||
} |
||||
|
||||
@Test |
||||
public void disableLocalsOff() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getDisableLocalTransactions()).isFalse(), |
||||
"--tx-pool-disable-locals=false"); |
||||
} |
||||
|
||||
@Test |
||||
public void saveToFileDisabledByDefault() { |
||||
internalTestSuccess(config -> assertThat(config.getEnableSaveRestore()).isFalse()); |
||||
} |
||||
|
||||
@Test |
||||
public void saveToFileEnabledDefaultPath() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getEnableSaveRestore()).isTrue(), |
||||
"--tx-pool-enable-save-restore=true"); |
||||
} |
||||
|
||||
@Test |
||||
public void saveToFileEnabledCustomPath() { |
||||
internalTestSuccess( |
||||
config -> { |
||||
assertThat(config.getEnableSaveRestore()).isTrue(); |
||||
assertThat(config.getSaveFile()).hasName("my.save.file"); |
||||
}, |
||||
"--tx-pool-enable-save-restore=true", |
||||
"--tx-pool-save-file=my.save.file"); |
||||
} |
||||
|
||||
@Test |
||||
public void senderLimited_derived() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getTxPoolMaxFutureTransactionByAccount()).isEqualTo(9), |
||||
"--tx-pool-limit-by-account-percentage=0.002", |
||||
"--tx-pool=legacy"); |
||||
} |
||||
|
||||
@Test |
||||
public void senderLimitedFloor_derived() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getTxPoolMaxFutureTransactionByAccount()).isEqualTo(1), |
||||
"--tx-pool-limit-by-account-percentage=0.0001", |
||||
"--tx-pool=legacy"); |
||||
} |
||||
|
||||
@Test |
||||
public void senderLimitedCeiling_violated() { |
||||
internalTestFailure( |
||||
"Invalid value for option '--tx-pool-limit-by-account-percentage'", |
||||
"--tx-pool-limit-by-account-percentage=1.00002341", |
||||
"--tx-pool=legacy"); |
||||
} |
||||
|
||||
@Test |
||||
public void priceBump() { |
||||
final Percentage priceBump = Percentage.fromInt(13); |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getPriceBump()).isEqualTo(priceBump), |
||||
"--tx-pool-price-bump", |
||||
priceBump.toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void invalidPriceBumpShouldFail() { |
||||
internalTestFailure( |
||||
"Invalid value: 101, should be a number between 0 and 100 inclusive", |
||||
"--tx-pool-price-bump", |
||||
"101"); |
||||
} |
||||
|
||||
@Test |
||||
public void txFeeCap() { |
||||
final Wei txFeeCap = Wei.fromEth(2); |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getTxFeeCap()).isEqualTo(txFeeCap), |
||||
"--rpc-tx-feecap", |
||||
OptionParser.format(txFeeCap)); |
||||
} |
||||
|
||||
@Test |
||||
public void invalidTxFeeCapShouldFail() { |
||||
internalTestFailure( |
||||
"Invalid value for option '--rpc-tx-feecap'", |
||||
"cannot convert 'abcd' to Wei", |
||||
"--rpc-tx-feecap", |
||||
"abcd"); |
||||
} |
||||
|
||||
@Test |
||||
public void selectLayeredImplementationByDefault() { |
||||
internalTestSuccess(config -> assertThat(config.getTxPoolImplementation()).isEqualTo(LAYERED)); |
||||
} |
||||
|
||||
@Test |
||||
public void selectLayeredImplementationByArg() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getTxPoolImplementation()).isEqualTo(LAYERED), |
||||
"--tx-pool=layered"); |
||||
} |
||||
|
||||
@Test |
||||
public void selectLegacyImplementationByArg() { |
||||
internalTestSuccess( |
||||
config -> assertThat(config.getTxPoolImplementation()).isEqualTo(LEGACY), |
||||
"--tx-pool=legacy"); |
||||
} |
||||
|
||||
@Test |
||||
public void failIfLegacyOptionsWhenLayeredSelectedByDefault() { |
||||
internalTestFailure( |
||||
"Could not use legacy transaction pool options with layered implementation", |
||||
"--tx-pool-max-size=1000"); |
||||
} |
||||
|
||||
@Test |
||||
public void failIfLegacyOptionsWhenLayeredSelectedByArg() { |
||||
internalTestFailure( |
||||
"Could not use legacy transaction pool options with layered implementation", |
||||
"--tx-pool=layered", |
||||
"--tx-pool-max-size=1000"); |
||||
} |
||||
|
||||
@Test |
||||
public void failIfLayeredOptionsWhenLegacySelectedByArg() { |
||||
internalTestFailure( |
||||
"Could not use layered transaction pool options with legacy implementation", |
||||
"--tx-pool=legacy", |
||||
"--tx-pool-max-prioritized=1000"); |
||||
} |
||||
|
||||
@Override |
||||
protected TransactionPoolConfiguration createDefaultDomainObject() { |
||||
return TransactionPoolConfiguration.DEFAULT; |
||||
} |
||||
|
||||
@Override |
||||
protected TransactionPoolConfiguration createCustomizedDomainObject() { |
||||
return ImmutableTransactionPoolConfiguration.builder() |
||||
.strictTransactionReplayProtectionEnabled(true) |
||||
.txPoolImplementation(LAYERED) |
||||
.pendingTransactionsLayerMaxCapacityBytes(1_000_000L) |
||||
.maxPrioritizedTransactions(1000) |
||||
.maxFutureBySender(10) |
||||
.build(); |
||||
} |
||||
|
||||
@Override |
||||
protected TransactionPoolOptions optionsFromDomainObject( |
||||
final TransactionPoolConfiguration domainObject) { |
||||
return TransactionPoolOptions.fromConfig(domainObject); |
||||
} |
||||
|
||||
@Override |
||||
protected TransactionPoolOptions getOptionsFromBesuCommand(final TestBesuCommand besuCommand) { |
||||
return besuCommand.getStableTransactionPoolOptions(); |
||||
} |
||||
} |
@ -0,0 +1,105 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.cli.options.unstable; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
import org.hyperledger.besu.cli.converter.DurationMillisConverter; |
||||
import org.hyperledger.besu.cli.options.AbstractCLIOptionsTest; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; |
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; |
||||
|
||||
import java.time.Duration; |
||||
|
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class TransactionPoolOptionsTest |
||||
extends AbstractCLIOptionsTest<TransactionPoolConfiguration.Unstable, TransactionPoolOptions> { |
||||
|
||||
@Test |
||||
public void txMessageKeepAliveSeconds() { |
||||
final int txMessageKeepAliveSeconds = 999; |
||||
internalTestSuccess( |
||||
config -> |
||||
assertThat(config.getTxMessageKeepAliveSeconds()).isEqualTo(txMessageKeepAliveSeconds), |
||||
"--Xincoming-tx-messages-keep-alive-seconds", |
||||
String.valueOf(txMessageKeepAliveSeconds)); |
||||
} |
||||
|
||||
@Test |
||||
public void txMessageKeepAliveSecondsWithInvalidInputShouldFail() { |
||||
internalTestFailure( |
||||
"Invalid value for option '--Xincoming-tx-messages-keep-alive-seconds': 'acbd' is not an int", |
||||
"--Xincoming-tx-messages-keep-alive-seconds", |
||||
"acbd"); |
||||
} |
||||
|
||||
@Test |
||||
public void eth65TrxAnnouncedBufferingPeriod() { |
||||
final Duration eth65TrxAnnouncedBufferingPeriod = Duration.ofMillis(999); |
||||
internalTestSuccess( |
||||
config -> |
||||
assertThat(config.getEth65TrxAnnouncedBufferingPeriod()) |
||||
.isEqualTo(eth65TrxAnnouncedBufferingPeriod), |
||||
"--Xeth65-tx-announced-buffering-period-milliseconds", |
||||
new DurationMillisConverter().format(eth65TrxAnnouncedBufferingPeriod)); |
||||
} |
||||
|
||||
@Test |
||||
public void eth65TrxAnnouncedBufferingPeriodWithInvalidInputShouldFail() { |
||||
internalTestFailure( |
||||
"Invalid value for option '--Xeth65-tx-announced-buffering-period-milliseconds': cannot convert 'acbd' to Duration (org.hyperledger.besu.cli.converter.exception.DurationConversionException: 'acbd' is not a long)", |
||||
"--Xeth65-tx-announced-buffering-period-milliseconds", |
||||
"acbd"); |
||||
} |
||||
|
||||
@Test |
||||
public void eth65TrxAnnouncedBufferingPeriodWithInvalidInputShouldFail2() { |
||||
internalTestFailure( |
||||
"Invalid value for option '--Xeth65-tx-announced-buffering-period-milliseconds': cannot convert '-1' to Duration (org.hyperledger.besu.cli.converter.exception.DurationConversionException: negative value '-1' is not allowed)", |
||||
"--Xeth65-tx-announced-buffering-period-milliseconds", |
||||
"-1"); |
||||
} |
||||
|
||||
@Override |
||||
protected TransactionPoolConfiguration.Unstable createDefaultDomainObject() { |
||||
return TransactionPoolConfiguration.Unstable.DEFAULT; |
||||
} |
||||
|
||||
@Override |
||||
protected TransactionPoolConfiguration.Unstable createCustomizedDomainObject() { |
||||
return ImmutableTransactionPoolConfiguration.Unstable.builder() |
||||
.txMessageKeepAliveSeconds( |
||||
TransactionPoolConfiguration.Unstable.DEFAULT_TX_MSG_KEEP_ALIVE + 1) |
||||
.eth65TrxAnnouncedBufferingPeriod( |
||||
TransactionPoolConfiguration.Unstable.ETH65_TRX_ANNOUNCED_BUFFERING_PERIOD.plus( |
||||
Duration.ofMillis(100))) |
||||
.build(); |
||||
} |
||||
|
||||
@Override |
||||
protected TransactionPoolOptions optionsFromDomainObject( |
||||
final TransactionPoolConfiguration.Unstable domainObject) { |
||||
return TransactionPoolOptions.fromConfig(domainObject); |
||||
} |
||||
|
||||
@Override |
||||
protected TransactionPoolOptions getOptionsFromBesuCommand(final TestBesuCommand besuCommand) { |
||||
return besuCommand.getUnstableTransactionPoolOptions(); |
||||
} |
||||
} |
@ -0,0 +1,211 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.services; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.datatypes.Transaction; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; |
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain; |
||||
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; |
||||
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat; |
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; |
||||
import org.hyperledger.besu.evm.log.Log; |
||||
import org.hyperledger.besu.evm.worldstate.WorldView; |
||||
import org.hyperledger.besu.plugin.services.TraceService; |
||||
import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
class TraceServiceImplTest { |
||||
|
||||
TraceService traceService; |
||||
private MutableBlockchain blockchain; |
||||
private WorldStateArchive worldStateArchive; |
||||
private BlockchainQueries blockchainQueries; |
||||
|
||||
/** |
||||
* The blockchain for testing has a height of 32 and the account |
||||
* 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b makes a transaction per block. So, in the head, the |
||||
* nonce of this account should be 32. |
||||
*/ |
||||
@BeforeEach |
||||
public void setup() { |
||||
final BlockchainSetupUtil blockchainSetupUtil = |
||||
BlockchainSetupUtil.forTesting(DataStorageFormat.BONSAI); |
||||
blockchainSetupUtil.importAllBlocks(); |
||||
blockchain = blockchainSetupUtil.getBlockchain(); |
||||
worldStateArchive = blockchainSetupUtil.getWorldArchive(); |
||||
blockchainQueries = new BlockchainQueries(blockchain, worldStateArchive); |
||||
traceService = |
||||
new TraceServiceImpl(blockchainQueries, blockchainSetupUtil.getProtocolSchedule()); |
||||
} |
||||
|
||||
@Test |
||||
void shouldRetrieveStateUpdatePostTracingForOneBlock() { |
||||
|
||||
final Address addressToVerify = |
||||
Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"); |
||||
|
||||
final long persistedNonceForAccount = |
||||
worldStateArchive.getMutable().get(addressToVerify).getNonce(); |
||||
|
||||
traceService.trace( |
||||
2, |
||||
2, |
||||
worldState -> { |
||||
assertThat(worldState.get(addressToVerify).getNonce()).isEqualTo(1); |
||||
}, |
||||
worldState -> { |
||||
assertThat(worldState.get(addressToVerify).getNonce()).isEqualTo(2); |
||||
}, |
||||
BlockAwareOperationTracer.NO_TRACING); |
||||
|
||||
assertThat(worldStateArchive.getMutable().get(addressToVerify).getNonce()) |
||||
.isEqualTo(persistedNonceForAccount); |
||||
} |
||||
|
||||
@Test |
||||
void shouldRetrieveStateUpdatePostTracingForAllBlocks() { |
||||
final Address addressToVerify = |
||||
Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"); |
||||
|
||||
final long persistedNonceForAccount = |
||||
worldStateArchive.getMutable().get(addressToVerify).getNonce(); |
||||
|
||||
traceService.trace( |
||||
0, |
||||
32, |
||||
worldState -> { |
||||
assertThat(worldState.get(addressToVerify).getNonce()).isEqualTo(0); |
||||
}, |
||||
worldState -> { |
||||
assertThat(worldState.get(addressToVerify).getNonce()) |
||||
.isEqualTo(persistedNonceForAccount); |
||||
}, |
||||
BlockAwareOperationTracer.NO_TRACING); |
||||
|
||||
assertThat(worldStateArchive.getMutable().get(addressToVerify).getNonce()) |
||||
.isEqualTo(persistedNonceForAccount); |
||||
} |
||||
|
||||
@Test |
||||
void shouldReturnTheCorrectWorldViewForTxStartEnd() { |
||||
final TxStartEndTracer txStartEndTracer = new TxStartEndTracer(); |
||||
|
||||
// block contains 1 transaction
|
||||
traceService.traceBlock(31, txStartEndTracer); |
||||
|
||||
assertThat(txStartEndTracer.txStartWorldView).isNotNull(); |
||||
assertThat(txStartEndTracer.txEndWorldView).isNotNull(); |
||||
|
||||
assertThat(txStartEndTracer.txStartTransaction.getNonce()) |
||||
.isEqualTo(txStartEndTracer.txEndTransaction.getNonce()) |
||||
.isEqualTo(30); |
||||
assertThat(txStartEndTracer.txStartTransaction.getGasLimit()) |
||||
.isEqualTo(txStartEndTracer.txEndTransaction.getGasLimit()) |
||||
.isEqualTo(314159); |
||||
assertThat(txStartEndTracer.txStartTransaction.getTo().get()) |
||||
.isEqualTo(txStartEndTracer.txEndTransaction.getTo().get()) |
||||
.isEqualTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")); |
||||
assertThat(txStartEndTracer.txStartTransaction.getValue()) |
||||
.isEqualTo(txStartEndTracer.txEndTransaction.getValue()) |
||||
.isEqualTo( |
||||
Wei.fromHexString( |
||||
"0x000000000000000000000000000000000000000000000000000000000000000a")); |
||||
assertThat(txStartEndTracer.txStartTransaction.getPayload()) |
||||
.isEqualTo(txStartEndTracer.txEndTransaction.getPayload()) |
||||
.isEqualTo(Bytes.fromHexString("0xfd408767")); |
||||
|
||||
assertThat(txStartEndTracer.txEndStatus).isTrue(); |
||||
assertThat(txStartEndTracer.txEndOutput).isEqualTo(Bytes.fromHexString("0x")); |
||||
assertThat(txStartEndTracer.txEndGasUsed).isEqualTo(24303); |
||||
assertThat(txStartEndTracer.txEndTimeNs).isNotNull(); |
||||
|
||||
assertThat(txStartEndTracer.txEndLogs).isNotEmpty(); |
||||
|
||||
final Log actualLog = txStartEndTracer.txEndLogs.get(0); |
||||
assertThat(actualLog.getLogger()) |
||||
.isEqualTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")); |
||||
assertThat(actualLog.getData()) |
||||
.isEqualTo( |
||||
Bytes.fromHexString( |
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9000000000000000000000000000000000000000000000000000000000000002a")); |
||||
assertThat(actualLog.getTopics()).hasSize(4); |
||||
assertThat(actualLog.getTopics().get(0)) |
||||
.isEqualTo( |
||||
Bytes.fromHexString( |
||||
"0xd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e")); |
||||
assertThat(actualLog.getTopics().get(1)) |
||||
.isEqualTo( |
||||
Bytes.fromHexString( |
||||
"0x0000000000000000000000000000000000000000000000000000000000000001")); |
||||
assertThat(actualLog.getTopics().get(2)) |
||||
.isEqualTo( |
||||
Bytes.fromHexString( |
||||
"0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b")); |
||||
assertThat(actualLog.getTopics().get(3)) |
||||
.isEqualTo( |
||||
Bytes.fromHexString( |
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); |
||||
} |
||||
|
||||
private static class TxStartEndTracer implements BlockAwareOperationTracer { |
||||
public WorldView txStartWorldView; |
||||
public WorldView txEndWorldView; |
||||
|
||||
public Transaction txStartTransaction; |
||||
public Transaction txEndTransaction; |
||||
|
||||
public boolean txEndStatus; |
||||
public Bytes txEndOutput; |
||||
public List<Log> txEndLogs; |
||||
public long txEndGasUsed; |
||||
public Long txEndTimeNs; |
||||
|
||||
@Override |
||||
public void traceStartTransaction(final WorldView worldView, final Transaction transaction) { |
||||
txStartWorldView = worldView; |
||||
txStartTransaction = transaction; |
||||
} |
||||
|
||||
@Override |
||||
public void traceEndTransaction( |
||||
final WorldView worldView, |
||||
final Transaction transaction, |
||||
final boolean status, |
||||
final Bytes output, |
||||
final List<Log> logs, |
||||
final long gasUsed, |
||||
final long timeNs) { |
||||
txEndWorldView = worldView; |
||||
txEndTransaction = transaction; |
||||
txEndStatus = status; |
||||
txEndOutput = output; |
||||
txEndLogs = logs; |
||||
txEndGasUsed = gasUsed; |
||||
txEndTimeNs = timeNs; |
||||
} |
||||
} |
||||
} |
@ -1,815 +0,0 @@ |
||||
{ |
||||
"config": { |
||||
"chainId": 6, |
||||
"ecip1041Block": 0, |
||||
"atlantisBlock": 716617, |
||||
"aghartaBlock": 1705549, |
||||
"phoenixBlock": 2200013, |
||||
"magnetoBlock": 4368634, |
||||
"mystiqueBlock": 5578000, |
||||
"clique":{ |
||||
"blockperiodseconds":15, |
||||
"epochlength":30000 |
||||
}, |
||||
"discovery": { |
||||
"bootnodes": [ |
||||
"enode://a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd@51.158.191.43:37956", |
||||
"enode://93c94e999be5dd854c5d82a7cf5c14822973b5d9badb56ad4974586ec4d4f1995c815af795c20bb6e0a6226d3ee55808435c4dc89baf94ee581141b064d19dfc@80.187.116.161:25720", |
||||
"enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303", |
||||
"enode://b477ca6d507a3f57070783eb62ba838847635f8b1a0cbffb8b7f8173f5894cf550f0225a5c279341e2d862a606e778b57180a4f1db3db78c51eadcfa4fdc6963@40.68.240.160:30303", |
||||
"enode://4956f6924335c951cb70cbc169a85c081f6ff0b374aa2815453b8a3132b49613f38a1a6b8e103f878dbec86364f60091e92a376d7cd3aca9d82d2f2554794e63@51.15.97.240:41235", |
||||
"enode://6c9a052c01bb9995fa53bebfcdbc17733fe90708270d0e6d8e38dc57b32e1dbe8c287590b634ee9753b94ba302f411c96519c7fa07df0df6a6848149d819b2c5@51.15.70.7:41235", |
||||
"enode://95a7302fd8f35d9ad716a591b90dfe839dbf2d3d6a6737ef39e07899f844ad82f1659dd6212492922dd36705fb0a1e984c1d5d5c42069d5bd329388831e820c1@51.15.97.240:45678", |
||||
"enode://8c5c4dec9a0728c7058d3c29698bae888adc244e443cebc21f3d708a20751511acbf98a52b5e5ea472f8715c658913e8084123461fd187a4980a0600420b0791@51.15.70.7:45678", |
||||
"enode://efd7391a3bed73ad74ae5760319bb48f9c9f1983ff22964422688cdb426c5d681004ece26c47121396653cf9bafe7104aa4ecff70e24cc5b11fd76be8e5afce0@51.158.191.43:45678", |
||||
"enode://93b12383c74c39b67afa99a7ff44ce250fe94295fa1fc087465cc4fe2d0b33b91a8d8cabe03b250104a9096aa0e06bcde5f95665a5bd9f890edd2ab33e16ae47@51.15.41.19:30303" |
||||
] |
||||
} |
||||
}, |
||||
"nonce": "0x0", |
||||
"timestamp": "0x5c2d2287", |
||||
"extraData": "0x000000000000000000000000000000000000000000000000000000000000000025b7955e43adf9c2a01a9475908702cce67f302a6aaf8cba3c9255a2b863415d4db7bae4f4bbca020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
||||
"gasLimit": "0xa00000", |
||||
"difficulty": "0x1", |
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", |
||||
"coinbase": "0x0000000000000000000000000000000000000000", |
||||
"alloc": { |
||||
"0000000000000000000000000000000000000000": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000001": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000002": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000003": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000004": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000005": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000006": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000007": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000008": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000009": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000000a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000000b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000000c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000000d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000000e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000000f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000010": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000011": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000012": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000013": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000014": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000015": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000016": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000017": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000018": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000019": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000001a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000001b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000001c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000001d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000001e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000001f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000020": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000021": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000022": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000023": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000024": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000025": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000026": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000027": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000028": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000029": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000002a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000002b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000002c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000002d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000002e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000002f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000030": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000031": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000032": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000033": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000034": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000035": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000036": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000037": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000038": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000039": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000003a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000003b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000003c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000003d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000003e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000003f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000040": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000041": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000042": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000043": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000044": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000045": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000046": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000047": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000048": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000049": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000004a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000004b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000004c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000004d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000004e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000004f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000050": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000051": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000052": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000053": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000054": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000055": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000056": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000057": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000058": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000059": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000005a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000005b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000005c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000005d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000005e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000005f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000060": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000061": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000062": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000063": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000064": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000065": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000066": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000067": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000068": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000069": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000006a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000006b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000006c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000006d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000006e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000006f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000070": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000071": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000072": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000073": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000074": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000075": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000076": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000077": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000078": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000079": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000007a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000007b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000007c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000007d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000007e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000007f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000080": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000081": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000082": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000083": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000084": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000085": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000086": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000087": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000088": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000089": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000008a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000008b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000008c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000008d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000008e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000008f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000090": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000091": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000092": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000093": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000094": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000095": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000096": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000097": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000098": { |
||||
"balance": "0x1" |
||||
}, |
||||
"0000000000000000000000000000000000000099": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000009a": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000009b": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000009c": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000009d": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000009e": { |
||||
"balance": "0x1" |
||||
}, |
||||
"000000000000000000000000000000000000009f": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a0": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a1": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a2": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a3": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a4": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a5": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a6": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a7": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a8": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000a9": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000aa": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ab": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ac": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ad": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ae": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000af": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b0": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b1": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b2": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b3": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b4": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b5": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b6": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b7": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b8": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000b9": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ba": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000bb": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000bc": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000bd": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000be": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000bf": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c0": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c1": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c2": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c3": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c4": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c5": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c6": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c7": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c8": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000c9": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ca": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000cb": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000cc": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000cd": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ce": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000cf": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d0": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d1": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d2": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d3": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d4": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d5": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d6": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d7": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d8": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000d9": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000da": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000db": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000dc": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000dd": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000de": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000df": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e0": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e1": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e2": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e3": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e4": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e5": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e6": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e7": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e8": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000e9": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ea": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000eb": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ec": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ed": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ee": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ef": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f0": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f1": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f2": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f3": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f4": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f5": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f6": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f7": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f8": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000f9": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000fa": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000fb": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000fc": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000fd": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000fe": { |
||||
"balance": "0x1" |
||||
}, |
||||
"00000000000000000000000000000000000000ff": { |
||||
"balance": "0x1" |
||||
}, |
||||
"25b7955e43adf9c2a01a9475908702cce67f302a": { |
||||
"balance": "0x84595161401484a000000" |
||||
}, |
||||
"6aaf8cba3c9255a2b863415d4db7bae4f4bbca02": { |
||||
"balance": "0x4a723dc6b40b8a9a000000" |
||||
} |
||||
}, |
||||
"number": "0x0", |
||||
"gasUsed": "0x0", |
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" |
||||
} |
@ -0,0 +1,68 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
* |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.bonsai.storage; |
||||
|
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.datatypes.Hash; |
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage; |
||||
|
||||
import java.util.Optional; |
||||
|
||||
import com.google.common.collect.BiMap; |
||||
import com.google.common.collect.HashBiMap; |
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.apache.tuweni.bytes.Bytes32; |
||||
import org.apache.tuweni.units.bigints.UInt256; |
||||
|
||||
/** Acts as both a Hasher and PreImageStorage for Bonsai storage format. */ |
||||
public interface BonsaiPreImageProxy extends WorldStatePreimageStorage { |
||||
/** |
||||
* If this value is not already present, save in preImage store and return the hash value. |
||||
* |
||||
* @param value value to hash |
||||
* @return Hash of value |
||||
*/ |
||||
Hash hashAndSavePreImage(Bytes value); |
||||
|
||||
/** |
||||
* A caching PreImageProxy suitable for ReferenceTestWorldState which saves hashes in an unbounded |
||||
* BiMap. |
||||
*/ |
||||
class BonsaiReferenceTestPreImageProxy implements BonsaiPreImageProxy { |
||||
BiMap<Hash, Bytes> preImageCache = HashBiMap.create(); |
||||
|
||||
@Override |
||||
public synchronized Hash hashAndSavePreImage(final Bytes value) { |
||||
return preImageCache.inverse().computeIfAbsent(value, Hash::hash); |
||||
} |
||||
|
||||
@Override |
||||
public Optional<UInt256> getStorageTrieKeyPreimage(final Bytes32 trieKey) { |
||||
return Optional.ofNullable(preImageCache.get(trieKey)).map(UInt256::fromBytes); |
||||
} |
||||
|
||||
@Override |
||||
public Optional<Address> getAccountTrieKeyPreimage(final Bytes32 trieKey) { |
||||
return Optional.ofNullable(preImageCache.get(trieKey)).map(Address::wrap); |
||||
} |
||||
|
||||
@Override |
||||
public Updater updater() { |
||||
throw new UnsupportedOperationException( |
||||
"BonsaiReferenceTestPreImageProxy does not implement an updater"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,74 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.core.encoding; |
||||
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm; |
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; |
||||
import org.hyperledger.besu.datatypes.AccessListEntry; |
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.datatypes.TransactionType; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.util.function.Supplier; |
||||
|
||||
import com.google.common.base.Suppliers; |
||||
|
||||
class AccessListTransactionDecoder { |
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM = |
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance); |
||||
|
||||
public static Transaction decode(final RLPInput rlpInput) { |
||||
rlpInput.enterList(); |
||||
final Transaction.Builder preSignatureTransactionBuilder = |
||||
Transaction.builder() |
||||
.type(TransactionType.ACCESS_LIST) |
||||
.chainId(BigInteger.valueOf(rlpInput.readLongScalar())) |
||||
.nonce(rlpInput.readLongScalar()) |
||||
.gasPrice(Wei.of(rlpInput.readUInt256Scalar())) |
||||
.gasLimit(rlpInput.readLongScalar()) |
||||
.to( |
||||
rlpInput.readBytes( |
||||
addressBytes -> addressBytes.size() == 0 ? null : Address.wrap(addressBytes))) |
||||
.value(Wei.of(rlpInput.readUInt256Scalar())) |
||||
.payload(rlpInput.readBytes()) |
||||
.accessList( |
||||
rlpInput.readList( |
||||
accessListEntryRLPInput -> { |
||||
accessListEntryRLPInput.enterList(); |
||||
final AccessListEntry accessListEntry = |
||||
new AccessListEntry( |
||||
Address.wrap(accessListEntryRLPInput.readBytes()), |
||||
accessListEntryRLPInput.readList(RLPInput::readBytes32)); |
||||
accessListEntryRLPInput.leaveList(); |
||||
return accessListEntry; |
||||
})); |
||||
final byte recId = (byte) rlpInput.readIntScalar(); |
||||
final Transaction transaction = |
||||
preSignatureTransactionBuilder |
||||
.signature( |
||||
SIGNATURE_ALGORITHM |
||||
.get() |
||||
.createSignature( |
||||
rlpInput.readUInt256Scalar().toUnsignedBigInteger(), |
||||
rlpInput.readUInt256Scalar().toUnsignedBigInteger(), |
||||
recId)) |
||||
.build(); |
||||
rlpInput.leaveList(); |
||||
return transaction; |
||||
} |
||||
} |
@ -0,0 +1,109 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.core.encoding; |
||||
|
||||
import static org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder.writeSignature; |
||||
|
||||
import org.hyperledger.besu.datatypes.AccessListEntry; |
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
|
||||
public class AccessListTransactionEncoder { |
||||
|
||||
public static void encode(final Transaction transaction, final RLPOutput rlpOutput) { |
||||
rlpOutput.startList(); |
||||
encodeAccessListInner( |
||||
transaction.getChainId(), |
||||
transaction.getNonce(), |
||||
transaction.getGasPrice().orElseThrow(), |
||||
transaction.getGasLimit(), |
||||
transaction.getTo(), |
||||
transaction.getValue(), |
||||
transaction.getPayload(), |
||||
transaction |
||||
.getAccessList() |
||||
.orElseThrow( |
||||
() -> |
||||
new IllegalStateException( |
||||
"Developer error: access list should be guaranteed to be present")), |
||||
rlpOutput); |
||||
rlpOutput.writeIntScalar(transaction.getSignature().getRecId()); |
||||
writeSignature(transaction, rlpOutput); |
||||
rlpOutput.endList(); |
||||
} |
||||
|
||||
public static void encodeAccessListInner( |
||||
final Optional<BigInteger> chainId, |
||||
final long nonce, |
||||
final Wei gasPrice, |
||||
final long gasLimit, |
||||
final Optional<Address> to, |
||||
final Wei value, |
||||
final Bytes payload, |
||||
final List<AccessListEntry> accessList, |
||||
final RLPOutput rlpOutput) { |
||||
rlpOutput.writeBigIntegerScalar(chainId.orElseThrow()); |
||||
rlpOutput.writeLongScalar(nonce); |
||||
rlpOutput.writeUInt256Scalar(gasPrice); |
||||
rlpOutput.writeLongScalar(gasLimit); |
||||
rlpOutput.writeBytes(to.map(Bytes::copy).orElse(Bytes.EMPTY)); |
||||
rlpOutput.writeUInt256Scalar(value); |
||||
rlpOutput.writeBytes(payload); |
||||
/* |
||||
Access List encoding should look like this |
||||
where hex strings represent raw bytes |
||||
[ |
||||
[ |
||||
"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae", |
||||
[ |
||||
"0x0000000000000000000000000000000000000000000000000000000000000003", |
||||
"0x0000000000000000000000000000000000000000000000000000000000000007" |
||||
] |
||||
], |
||||
[ |
||||
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413", |
||||
[] |
||||
] |
||||
] */ |
||||
writeAccessList(rlpOutput, Optional.of(accessList)); |
||||
} |
||||
|
||||
public static void writeAccessList( |
||||
final RLPOutput out, final Optional<List<AccessListEntry>> accessListEntries) { |
||||
if (accessListEntries.isEmpty()) { |
||||
out.writeEmptyList(); |
||||
} else { |
||||
out.writeList( |
||||
accessListEntries.get(), |
||||
(accessListEntry, accessListEntryRLPOutput) -> { |
||||
accessListEntryRLPOutput.startList(); |
||||
out.writeBytes(accessListEntry.address()); |
||||
out.writeList( |
||||
accessListEntry.storageKeys(), |
||||
(storageKeyBytes, storageKeyBytesRLPOutput) -> |
||||
storageKeyBytesRLPOutput.writeBytes(storageKeyBytes)); |
||||
accessListEntryRLPOutput.endList(); |
||||
}); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,50 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.core.encoding; |
||||
|
||||
import org.hyperledger.besu.datatypes.Blob; |
||||
import org.hyperledger.besu.datatypes.KZGCommitment; |
||||
import org.hyperledger.besu.datatypes.KZGProof; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Class responsible for decoding blob transactions from the transaction pool. Blob transactions |
||||
* have two network representations. During transaction gossip responses (PooledTransactions), the |
||||
* EIP-2718 TransactionPayload of the blob transaction is wrapped to become: rlp([tx_payload_body, |
||||
* blobs, commitments, proofs]). |
||||
*/ |
||||
public class BlobPooledTransactionDecoder { |
||||
|
||||
/** |
||||
* Decodes a blob transaction from the provided RLP input. |
||||
* |
||||
* @param input the RLP input to decode |
||||
* @return the decoded transaction |
||||
*/ |
||||
public static Transaction decode(final RLPInput input) { |
||||
input.enterList(); |
||||
final Transaction.Builder builder = Transaction.builder(); |
||||
BlobTransactionDecoder.readTransactionPayloadInner(builder, input); |
||||
List<Blob> blobs = input.readList(Blob::readFrom); |
||||
List<KZGCommitment> commitments = input.readList(KZGCommitment::readFrom); |
||||
List<KZGProof> proofs = input.readList(KZGProof::readFrom); |
||||
input.leaveList(); |
||||
builder.kzgBlobs(commitments, blobs, proofs); |
||||
return builder.build(); |
||||
} |
||||
} |
@ -0,0 +1,47 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.core.encoding; |
||||
|
||||
import static org.slf4j.LoggerFactory.getLogger; |
||||
|
||||
import org.hyperledger.besu.datatypes.Blob; |
||||
import org.hyperledger.besu.datatypes.KZGCommitment; |
||||
import org.hyperledger.besu.datatypes.KZGProof; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput; |
||||
|
||||
import java.security.InvalidParameterException; |
||||
|
||||
import org.slf4j.Logger; |
||||
|
||||
public class BlobPooledTransactionEncoder { |
||||
private static final Logger LOG = getLogger(BlobPooledTransactionEncoder.class); |
||||
static final String NO_BLOBS_ERROR = |
||||
"Transaction with no blobsWithCommitments cannot be encoded for Pooled Transaction"; |
||||
|
||||
public static void encode(final Transaction transaction, final RLPOutput out) { |
||||
LOG.trace("Encoding transaction with blobs {}", transaction); |
||||
var blobsWithCommitments = transaction.getBlobsWithCommitments(); |
||||
if (blobsWithCommitments.isEmpty() || blobsWithCommitments.get().getBlobs().isEmpty()) { |
||||
throw new InvalidParameterException(NO_BLOBS_ERROR); |
||||
} |
||||
out.startList(); |
||||
BlobTransactionEncoder.encode(transaction, out); |
||||
out.writeList(blobsWithCommitments.get().getBlobs(), Blob::writeTo); |
||||
out.writeList(blobsWithCommitments.get().getKzgCommitments(), KZGCommitment::writeTo); |
||||
out.writeList(blobsWithCommitments.get().getKzgProofs(), KZGProof::writeTo); |
||||
out.endList(); |
||||
} |
||||
} |
@ -0,0 +1,74 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.core.encoding; |
||||
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm; |
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; |
||||
import org.hyperledger.besu.datatypes.AccessListEntry; |
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.datatypes.TransactionType; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.util.function.Supplier; |
||||
|
||||
import com.google.common.base.Suppliers; |
||||
|
||||
public class EIP1559TransactionDecoder { |
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM = |
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance); |
||||
|
||||
public static Transaction decode(final RLPInput input) { |
||||
input.enterList(); |
||||
final BigInteger chainId = input.readBigIntegerScalar(); |
||||
final Transaction.Builder builder = |
||||
Transaction.builder() |
||||
.type(TransactionType.EIP1559) |
||||
.chainId(chainId) |
||||
.nonce(input.readLongScalar()) |
||||
.maxPriorityFeePerGas(Wei.of(input.readUInt256Scalar())) |
||||
.maxFeePerGas(Wei.of(input.readUInt256Scalar())) |
||||
.gasLimit(input.readLongScalar()) |
||||
.to(input.readBytes(v -> v.size() == 0 ? null : Address.wrap(v))) |
||||
.value(Wei.of(input.readUInt256Scalar())) |
||||
.payload(input.readBytes()) |
||||
.accessList( |
||||
input.readList( |
||||
accessListEntryRLPInput -> { |
||||
accessListEntryRLPInput.enterList(); |
||||
final AccessListEntry accessListEntry = |
||||
new AccessListEntry( |
||||
Address.wrap(accessListEntryRLPInput.readBytes()), |
||||
accessListEntryRLPInput.readList(RLPInput::readBytes32)); |
||||
accessListEntryRLPInput.leaveList(); |
||||
return accessListEntry; |
||||
})); |
||||
final byte recId = (byte) input.readIntScalar(); |
||||
final Transaction transaction = |
||||
builder |
||||
.signature( |
||||
SIGNATURE_ALGORITHM |
||||
.get() |
||||
.createSignature( |
||||
input.readUInt256Scalar().toUnsignedBigInteger(), |
||||
input.readUInt256Scalar().toUnsignedBigInteger(), |
||||
recId)) |
||||
.build(); |
||||
input.leaveList(); |
||||
return transaction; |
||||
} |
||||
} |
@ -0,0 +1,41 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.core.encoding; |
||||
|
||||
import static org.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder.writeAccessList; |
||||
import static org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder.writeSignatureAndRecoveryId; |
||||
|
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
|
||||
public class EIP1559TransactionEncoder { |
||||
|
||||
public static void encode(final Transaction transaction, final RLPOutput out) { |
||||
out.startList(); |
||||
out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); |
||||
out.writeLongScalar(transaction.getNonce()); |
||||
out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); |
||||
out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); |
||||
out.writeLongScalar(transaction.getGasLimit()); |
||||
out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); |
||||
out.writeUInt256Scalar(transaction.getValue()); |
||||
out.writeBytes(transaction.getPayload()); |
||||
writeAccessList(out, transaction.getAccessList()); |
||||
writeSignatureAndRecoveryId(transaction, out); |
||||
out.endList(); |
||||
} |
||||
} |
@ -0,0 +1,41 @@ |
||||
/* |
||||
* Copyright Hyperledger Besu Contributors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.core.encoding; |
||||
|
||||
/** |
||||
* Enum representing the context in which a transaction is being encoded. This context is used to |
||||
* determine the appropriate encoding strategy for a transaction. |
||||
* |
||||
* <p>The context can be one of the following: |
||||
* |
||||
* <ul> |
||||
* <li>{@link #BLOCK_BODY}: The transaction is part of a block body. This context is used when |
||||
* encoding transactions for inclusion in a block. |
||||
* <li>{@link #POOLED_TRANSACTION}: The transaction is part of a transaction pool. This context is |
||||
* used when encoding transactions that are currently in the transaction pool, waiting to be |
||||
* included in a block. It is also used when encoding transactions for RPC calls related to |
||||
* the transaction pool. |
||||
* </ul> |
||||
*/ |
||||
public enum EncodingContext { |
||||
/** Represents the context where the transaction is part of a block body. */ |
||||
BLOCK_BODY, |
||||
|
||||
/** |
||||
* Represents the context where the transaction is part of a transaction pool. This context is |
||||
* also used when encoding transactions for RPC calls related to the transaction pool. |
||||
*/ |
||||
POOLED_TRANSACTION, |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue