mirror of https://github.com/hyperledger/besu
Release 23.7.3-RC2 - Holesky Hotfix (#5938)
* Revert "Burn in candidate for 23.7.3 (#5906)"
This reverts commit ed9d80e10e
.
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
* Update holesky with fixed extraData, genesis time, shanghaiTime (#5890)
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
* 23.7.3-RC2 version bump and 23.7.2 release SHAs
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
* updated gradle verification metadata (#5870)
* removed old artefacts
* 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>
* Add rocksdbjni-8.0.0 gradle verification back in
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
---------
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
release-23.7.x
parent
ed9d80e10e
commit
7cb1dda986
@ -1,44 +0,0 @@ |
|||||||
/* |
|
||||||
* 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()); |
|
||||||
} |
|
||||||
} |
|
@ -1,39 +0,0 @@ |
|||||||
/* |
|
||||||
* 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)); |
|
||||||
} |
|
||||||
} |
|
@ -1,263 +0,0 @@ |
|||||||
/* |
|
||||||
* 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()); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,155 @@ |
|||||||
|
/* |
||||||
|
* 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(); |
||||||
|
} |
||||||
|
} |
@ -1,243 +0,0 @@ |
|||||||
/* |
|
||||||
* 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(); |
|
||||||
} |
|
||||||
} |
|
@ -1,105 +0,0 @@ |
|||||||
/* |
|
||||||
* 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(); |
|
||||||
} |
|
||||||
} |
|
@ -1,211 +0,0 @@ |
|||||||
/* |
|
||||||
* 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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,815 @@ |
|||||||
|
{ |
||||||
|
"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" |
||||||
|
} |
@ -1,68 +0,0 @@ |
|||||||
/* |
|
||||||
* 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"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,74 +0,0 @@ |
|||||||
/* |
|
||||||
* 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; |
|
||||||
} |
|
||||||
} |
|
@ -1,109 +0,0 @@ |
|||||||
/* |
|
||||||
* 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(); |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,50 +0,0 @@ |
|||||||
/* |
|
||||||
* 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(); |
|
||||||
} |
|
||||||
} |
|
@ -1,47 +0,0 @@ |
|||||||
/* |
|
||||||
* 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(); |
|
||||||
} |
|
||||||
} |
|
@ -1,74 +0,0 @@ |
|||||||
/* |
|
||||||
* 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; |
|
||||||
} |
|
||||||
} |
|
@ -1,41 +0,0 @@ |
|||||||
/* |
|
||||||
* 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(); |
|
||||||
} |
|
||||||
} |
|
@ -1,41 +0,0 @@ |
|||||||
/* |
|
||||||
* 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, |
|
||||||
} |
|
@ -1,76 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.Transaction.REPLAY_PROTECTED_V_BASE; |
|
||||||
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_PROTECTED_V_MIN; |
|
||||||
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_UNPROTECTED_V_BASE; |
|
||||||
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_UNPROTECTED_V_BASE_PLUS_1; |
|
||||||
import static org.hyperledger.besu.ethereum.core.Transaction.TWO; |
|
||||||
|
|
||||||
import org.hyperledger.besu.crypto.SECPSignature; |
|
||||||
import org.hyperledger.besu.crypto.SignatureAlgorithm; |
|
||||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; |
|
||||||
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.Optional; |
|
||||||
import java.util.function.Supplier; |
|
||||||
|
|
||||||
import com.google.common.base.Suppliers; |
|
||||||
|
|
||||||
public class FrontierTransactionDecoder { |
|
||||||
// Supplier for the signature algorithm
|
|
||||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM = |
|
||||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance); |
|
||||||
|
|
||||||
public static Transaction decode(final RLPInput input) { |
|
||||||
input.enterList(); |
|
||||||
final Transaction.Builder builder = |
|
||||||
Transaction.builder() |
|
||||||
.type(TransactionType.FRONTIER) |
|
||||||
.nonce(input.readLongScalar()) |
|
||||||
.gasPrice(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()); |
|
||||||
|
|
||||||
final BigInteger v = input.readBigIntegerScalar(); |
|
||||||
final byte recId; |
|
||||||
Optional<BigInteger> chainId = Optional.empty(); |
|
||||||
if (v.equals(REPLAY_UNPROTECTED_V_BASE) || v.equals(REPLAY_UNPROTECTED_V_BASE_PLUS_1)) { |
|
||||||
recId = v.subtract(REPLAY_UNPROTECTED_V_BASE).byteValueExact(); |
|
||||||
} else if (v.compareTo(REPLAY_PROTECTED_V_MIN) > 0) { |
|
||||||
chainId = Optional.of(v.subtract(REPLAY_PROTECTED_V_BASE).divide(TWO)); |
|
||||||
recId = v.subtract(TWO.multiply(chainId.get()).add(REPLAY_PROTECTED_V_BASE)).byteValueExact(); |
|
||||||
} else { |
|
||||||
throw new RuntimeException( |
|
||||||
String.format("An unsupported encoded `v` value of %s was found", v)); |
|
||||||
} |
|
||||||
final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); |
|
||||||
final BigInteger s = input.readUInt256Scalar().toUnsignedBigInteger(); |
|
||||||
final SECPSignature signature = SIGNATURE_ALGORITHM.get().createSignature(r, s, recId); |
|
||||||
|
|
||||||
input.leaveList(); |
|
||||||
|
|
||||||
chainId.ifPresent(builder::chainId); |
|
||||||
return builder.signature(signature).build(); |
|
||||||
} |
|
||||||
} |
|
@ -1,36 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.writeSignatureAndV; |
|
||||||
|
|
||||||
import org.hyperledger.besu.ethereum.core.Transaction; |
|
||||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput; |
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes; |
|
||||||
|
|
||||||
public class FrontierTransactionEncoder { |
|
||||||
public static void encode(final Transaction transaction, final RLPOutput out) { |
|
||||||
out.startList(); |
|
||||||
out.writeLongScalar(transaction.getNonce()); |
|
||||||
out.writeUInt256Scalar(transaction.getGasPrice().orElseThrow()); |
|
||||||
out.writeLongScalar(transaction.getGasLimit()); |
|
||||||
out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); |
|
||||||
out.writeUInt256Scalar(transaction.getValue()); |
|
||||||
out.writeBytes(transaction.getPayload()); |
|
||||||
writeSignatureAndV(transaction, out); |
|
||||||
out.endList(); |
|
||||||
} |
|
||||||
} |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue