mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-09 13:58:02 -05:00
Merge branch 'main' into zkbesu
# Conflicts: # .github/workflows/reference-tests.yml # .github/workflows/splitList.sh
This commit is contained in:
121
.github/workflows/develop.yml
vendored
121
.github/workflows/develop.yml
vendored
@@ -1,121 +0,0 @@
|
||||
name: docker develop
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
env:
|
||||
registry: docker.io
|
||||
|
||||
jobs:
|
||||
hadolint:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
- name: setup gradle
|
||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
|
||||
with:
|
||||
cache-disabled: true
|
||||
|
||||
- name: hadoLint
|
||||
run: docker run --rm -i hadolint/hadolint < docker/Dockerfile
|
||||
buildDocker:
|
||||
needs: hadolint
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- ubuntu-22.04
|
||||
- [self-hosted, ARM64]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
if [ "$platform" = 'ubuntu-22.04' ]; then
|
||||
echo "PLATFORM_PAIR=linux-amd64" >> $GITHUB_OUTPUT
|
||||
echo "ARCH=amd64" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "PLATFORM_PAIR=linux-arm64" >> $GITHUB_OUTPUT
|
||||
echo "ARCH=arm64" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Get the current date and time in the format YY.MM
|
||||
DATE_TIME=$(date +"%y.%-m")
|
||||
# Get the short SHA of the merge commit
|
||||
SHORT_SHA=${GITHUB_SHA::7}
|
||||
# Construct the build target name
|
||||
BUILD_TARGET_NAME="${DATE_TIME}-develop-${SHORT_SHA}"
|
||||
echo "Build Target Name: $BUILD_TARGET_NAME"
|
||||
# Set the build target name as an environment variable
|
||||
echo "BUILD_TARGET_NAME=${BUILD_TARGET_NAME}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
- name: setup gradle
|
||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
|
||||
with:
|
||||
cache-disabled: true
|
||||
- name: install goss
|
||||
run: |
|
||||
mkdir -p docker/reports
|
||||
curl -L https://github.com/aelsabbahy/goss/releases/download/v0.4.4/goss-${{ steps.prep.outputs.PLATFORM_PAIR }} -o ./docker/tests/goss-${{ steps.prep.outputs.PLATFORM_PAIR }}
|
||||
- name: login to ${{ env.registry }}
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
|
||||
with:
|
||||
registry: ${{ env.registry }}
|
||||
username: ${{ secrets.DOCKER_USER_RW }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD_RW }}
|
||||
- name: build and test docker
|
||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
|
||||
env:
|
||||
architecture: ${{ steps.prep.outputs.ARCH }}
|
||||
with:
|
||||
cache-disabled: true
|
||||
arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{ env.BUILD_TARGET_NAME}} -Prelease.releaseVersion=develop
|
||||
- name: publish
|
||||
env:
|
||||
architecture: ${{ steps.prep.outputs.ARCH }}
|
||||
run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{ env.BUILD_TARGET_NAME }} -Prelease.releaseVersion=develop
|
||||
multiArch:
|
||||
needs: buildDocker
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
- name: setup gradle
|
||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
|
||||
with:
|
||||
cache-disabled: true
|
||||
- name: login to ${{ env.registry }}
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
|
||||
with:
|
||||
registry: ${{ env.registry }}
|
||||
username: ${{ secrets.DOCKER_USER_RW }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD_RW }}
|
||||
- name: multi-arch docker
|
||||
run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{ env.BUILD_TARGET_NAME }} -Prelease.releaseVersion=develop
|
||||
69
.github/workflows/splitTestsByTime.sh
vendored
69
.github/workflows/splitTestsByTime.sh
vendored
@@ -1,69 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
REPORTS_DIR="$1"
|
||||
SPLIT_COUNT=$2
|
||||
SPLIT_INDEX=$3
|
||||
|
||||
# extract tests time from Junit XML reports
|
||||
find "$REPORTS_DIR" -type f -name TEST-*.xml | xargs -I{} bash -c "xmlstarlet sel -t -v 'sum(//testcase/@time)' '{}'; echo '{}' | sed 's/.*TEST\-\(.*\)\.xml/ \1/'" > tmp/timing.tsv
|
||||
|
||||
# Sort times in descending order
|
||||
IFS=$'\n' sorted=($(sort -nr tmp/timing.tsv))
|
||||
unset IFS
|
||||
|
||||
sums=()
|
||||
tests=()
|
||||
|
||||
# Initialize sums
|
||||
for ((i=0; i<SPLIT_COUNT; i++))
|
||||
do
|
||||
sums[$i]=0
|
||||
done
|
||||
|
||||
# add tests to groups trying to balance the sum of execution time of each group
|
||||
for line in "${sorted[@]}"; do
|
||||
line_parts=( $line )
|
||||
test_time=${line_parts[0]//./} # convert to millis
|
||||
test_time=${test_time##0} # remove leading zeros
|
||||
test_name=${line_parts[1]}
|
||||
|
||||
# Does the test still exists?
|
||||
if grep -F -q --line-regexp "$test_name" tmp/currentTests.list
|
||||
then
|
||||
# Find index of min sum
|
||||
idx_min_sum=0
|
||||
min_sum=${sums[0]}
|
||||
for ((i=0; i<SPLIT_COUNT; i++))
|
||||
do
|
||||
if [[ ${sums[$i]} -lt $min_sum ]]
|
||||
then
|
||||
idx_min_sum=$i
|
||||
min_sum=${sums[$i]}
|
||||
fi
|
||||
done
|
||||
|
||||
# Add the test to the min sum list
|
||||
min_sum_tests=${tests[$idx_min_sum]}
|
||||
tests[$idx_min_sum]="${min_sum_tests}${test_name},"
|
||||
|
||||
# Update the sums
|
||||
((sums[idx_min_sum]+=test_time))
|
||||
|
||||
echo "$test_name" >> tmp/processedTests.list
|
||||
fi
|
||||
done
|
||||
|
||||
# Any new test?
|
||||
grep -F --line-regexp -v -f tmp/processedTests.list tmp/currentTests.list > tmp/newTests.list
|
||||
idx_new_test=0
|
||||
while read -r new_test_name
|
||||
do
|
||||
idx_group=$(( idx_new_test % SPLIT_COUNT ))
|
||||
group=${tests[$idx_group]}
|
||||
tests[$idx_group]="${group}${new_test_name},"
|
||||
idx_new_test=$(( idx_new_test + 1 ))
|
||||
done < tmp/newTests.list
|
||||
|
||||
|
||||
# return the requests index, without quotes to drop the last trailing space
|
||||
echo ${tests[$SPLIT_INDEX]//,/ }
|
||||
@@ -5,7 +5,8 @@
|
||||
### Breaking Changes
|
||||
- RocksDB database metadata format has changed to be more expressive, the migration of an existing metadata file to the new format is automatic at startup. Before performing a downgrade to a previous version it is mandatory to revert to the original format using the subcommand `besu --data-path=/path/to/besu/datadir storage revert-metadata v2-to-v1`.
|
||||
- BFT networks won't start with SNAP or CHECKPOINT sync (previously Besu would start with this config but quietly fail to sync, so it's now more obvious that it won't work) [#6625](https://github.com/hyperledger/besu/pull/6625), [#6667](https://github.com/hyperledger/besu/pull/6667)
|
||||
- Forest pruning has been removed, it was deprecated since 24.1.0. In case you are still using it you must now remove any of the following options: `pruning-enabled`, `pruning-blocks-retained` and `pruning-block-confirmations`, from your configuration, and you may want to consider switching to Bonsai.
|
||||
- Forest pruning has been removed, it was deprecated since 24.1.0. In case you are still using it you must now remove any of the following options: `pruning-enabled`, `pruning-blocks-retained` and `pruning-block-confirmations`, from your configuration, and you may want to consider switching to Bonsai.
|
||||
- Deprecated Goerli testnet has been removed.
|
||||
|
||||
### Upcoming Breaking Changes
|
||||
- Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version.
|
||||
@@ -45,6 +46,8 @@
|
||||
- Allow users to specify which plugins are registered [#6700](https://github.com/hyperledger/besu/pull/6700)
|
||||
- Layered txpool tuning for blob transactions [#6940](https://github.com/hyperledger/besu/pull/6940)
|
||||
- Update Gradle to 7.6.4 [#7030](https://github.com/hyperledger/besu/pull/7030)
|
||||
- Remove deprecated Goerli testnet [#7049](https://github.com/hyperledger/besu/pull/7049)
|
||||
- Default bonsai to use full-flat db and code-storage-by-code-hash [#6984](https://github.com/hyperledger/besu/pull/6894)
|
||||
|
||||
### Bug fixes
|
||||
- Fix txpool dump/restore race condition [#6665](https://github.com/hyperledger/besu/pull/6665)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'org.web3j' version '4.11.1'
|
||||
id 'org.web3j' version '4.11.3'
|
||||
id 'org.web3j.solidity' version '0.4.1'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
#! /bin/sh
|
||||
##
|
||||
## Copyright contributors to Hyperledger Besu.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
@@ -1706,8 +1706,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
|
||||
CommandLineUtils.failIfOptionDoesntMeetRequirement(
|
||||
commandLine,
|
||||
"--Xsnapsync-synchronizer-flat option can only be used when -Xsnapsync-synchronizer-flat-db-healing-enabled is true",
|
||||
unstableSynchronizerOptions.isSnapsyncFlatDbHealingEnabled(),
|
||||
"--Xsnapsync-synchronizer-flat option can only be used when --Xbonsai-full-flat-db-enabled is true",
|
||||
dataStorageOptions.toDomainObject().getUnstable().getBonsaiFullFlatDbEnabled(),
|
||||
asList(
|
||||
"--Xsnapsync-synchronizer-flat-account-healed-count-per-request",
|
||||
"--Xsnapsync-synchronizer-flat-slot-healed-count-per-request"));
|
||||
|
||||
@@ -26,8 +26,6 @@ public enum NetworkName {
|
||||
MAINNET("/mainnet.json", BigInteger.valueOf(1)),
|
||||
/** Sepolia network name. */
|
||||
SEPOLIA("/sepolia.json", BigInteger.valueOf(11155111)),
|
||||
/** Goerli network name. */
|
||||
GOERLI("/goerli.json", BigInteger.valueOf(5)),
|
||||
/** Holešky network name. */
|
||||
HOLESKY("/holesky.json", BigInteger.valueOf(17000)),
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.hyperledger.besu.cli.options.stable;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_RECEIPT_COMPACTION_ENABLED;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT;
|
||||
@@ -93,6 +94,18 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
|
||||
"The max number of blocks to load and prune trie logs for at startup. (default: ${DEFAULT-VALUE})")
|
||||
private int bonsaiTrieLogPruningWindowSize = DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE;
|
||||
|
||||
// TODO: --Xsnapsync-synchronizer-flat-db-healing-enabled is deprecated, remove it in a future
|
||||
// release
|
||||
@CommandLine.Option(
|
||||
hidden = true,
|
||||
names = {
|
||||
"--Xbonsai-full-flat-db-enabled",
|
||||
"--Xsnapsync-synchronizer-flat-db-healing-enabled"
|
||||
},
|
||||
arity = "1",
|
||||
description = "Enables bonsai full flat database strategy. (default: ${DEFAULT-VALUE})")
|
||||
private Boolean bonsaiFullFlatDbEnabled = DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED;
|
||||
|
||||
@CommandLine.Option(
|
||||
hidden = true,
|
||||
names = {"--Xbonsai-code-using-code-hash-enabled"},
|
||||
@@ -161,6 +174,8 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
|
||||
domainObject.getUnstable().getBonsaiLimitTrieLogsEnabled();
|
||||
dataStorageOptions.unstableOptions.bonsaiTrieLogPruningWindowSize =
|
||||
domainObject.getUnstable().getBonsaiTrieLogPruningWindowSize();
|
||||
dataStorageOptions.unstableOptions.bonsaiFullFlatDbEnabled =
|
||||
domainObject.getUnstable().getBonsaiFullFlatDbEnabled();
|
||||
dataStorageOptions.unstableOptions.bonsaiCodeUsingCodeHashEnabled =
|
||||
domainObject.getUnstable().getBonsaiCodeStoredByCodeHashEnabled();
|
||||
|
||||
@@ -177,6 +192,7 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
|
||||
ImmutableDataStorageConfiguration.Unstable.builder()
|
||||
.bonsaiLimitTrieLogsEnabled(unstableOptions.bonsaiLimitTrieLogsEnabled)
|
||||
.bonsaiTrieLogPruningWindowSize(unstableOptions.bonsaiTrieLogPruningWindowSize)
|
||||
.bonsaiFullFlatDbEnabled(unstableOptions.bonsaiFullFlatDbEnabled)
|
||||
.bonsaiCodeStoredByCodeHashEnabled(unstableOptions.bonsaiCodeUsingCodeHashEnabled)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
@@ -81,9 +81,6 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
|
||||
private static final String SNAP_FLAT_STORAGE_HEALED_COUNT_PER_REQUEST_FLAG =
|
||||
"--Xsnapsync-synchronizer-flat-slot-healed-count-per-request";
|
||||
|
||||
private static final String SNAP_FLAT_DB_HEALING_ENABLED_FLAG =
|
||||
"--Xsnapsync-synchronizer-flat-db-healing-enabled";
|
||||
|
||||
private static final String SNAP_SERVER_ENABLED_FLAG = "--Xsnapsync-server-enabled";
|
||||
|
||||
private static final String CHECKPOINT_POST_MERGE_FLAG = "--Xcheckpoint-post-merge-enabled";
|
||||
@@ -292,18 +289,11 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
|
||||
private int snapsyncFlatStorageHealedCountPerRequest =
|
||||
SnapSyncConfiguration.DEFAULT_LOCAL_FLAT_STORAGE_COUNT_TO_HEAL_PER_REQUEST;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = SNAP_FLAT_DB_HEALING_ENABLED_FLAG,
|
||||
hidden = true,
|
||||
paramLabel = "<Boolean>",
|
||||
description = "Snap sync flat db healing enabled (default: ${DEFAULT-VALUE})")
|
||||
private Boolean snapsyncFlatDbHealingEnabled =
|
||||
SnapSyncConfiguration.DEFAULT_IS_FLAT_DB_HEALING_ENABLED;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = SNAP_SERVER_ENABLED_FLAG,
|
||||
hidden = true,
|
||||
paramLabel = "<Boolean>",
|
||||
arity = "0..1",
|
||||
description = "Snap sync server enabled (default: ${DEFAULT-VALUE})")
|
||||
private Boolean snapsyncServerEnabled = SnapSyncConfiguration.DEFAULT_SNAP_SERVER_ENABLED;
|
||||
|
||||
@@ -316,15 +306,6 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
|
||||
|
||||
private SynchronizerOptions() {}
|
||||
|
||||
/**
|
||||
* Flag to know whether the flat db healing feature is enabled or disabled.
|
||||
*
|
||||
* @return true is the flat db healing is enabled
|
||||
*/
|
||||
public boolean isSnapsyncFlatDbHealingEnabled() {
|
||||
return snapsyncFlatDbHealingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to know whether the Snap sync server feature is enabled or disabled.
|
||||
*
|
||||
@@ -382,9 +363,8 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
|
||||
config.getSnapSyncConfiguration().getLocalFlatAccountCountToHealPerRequest();
|
||||
options.snapsyncFlatStorageHealedCountPerRequest =
|
||||
config.getSnapSyncConfiguration().getLocalFlatStorageCountToHealPerRequest();
|
||||
options.snapsyncFlatDbHealingEnabled =
|
||||
config.getSnapSyncConfiguration().isFlatDbHealingEnabled();
|
||||
options.checkpointPostMergeSyncEnabled = config.isCheckpointPostMergeEnabled();
|
||||
options.snapsyncServerEnabled = config.getSnapSyncConfiguration().isSnapServerEnabled();
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -416,7 +396,6 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
|
||||
.trienodeCountPerRequest(snapsyncTrieNodeCountPerRequest)
|
||||
.localFlatAccountCountToHealPerRequest(snapsyncFlatAccountHealedCountPerRequest)
|
||||
.localFlatStorageCountToHealPerRequest(snapsyncFlatStorageHealedCountPerRequest)
|
||||
.isFlatDbHealingEnabled(snapsyncFlatDbHealingEnabled)
|
||||
.isSnapServerEnabled(snapsyncServerEnabled)
|
||||
.build());
|
||||
builder.checkpointPostMergeEnabled(checkpointPostMergeSyncEnabled);
|
||||
@@ -469,17 +448,13 @@ public class SynchronizerOptions implements CLIOptions<SynchronizerConfiguration
|
||||
SNAP_BYTECODE_COUNT_PER_REQUEST_FLAG,
|
||||
OptionParser.format(snapsyncBytecodeCountPerRequest),
|
||||
SNAP_TRIENODE_COUNT_PER_REQUEST_FLAG,
|
||||
OptionParser.format(snapsyncTrieNodeCountPerRequest));
|
||||
if (isSnapsyncFlatDbHealingEnabled()) {
|
||||
value.addAll(
|
||||
Arrays.asList(
|
||||
SNAP_FLAT_ACCOUNT_HEALED_COUNT_PER_REQUEST_FLAG,
|
||||
OptionParser.format(snapsyncFlatAccountHealedCountPerRequest),
|
||||
SNAP_FLAT_STORAGE_HEALED_COUNT_PER_REQUEST_FLAG,
|
||||
OptionParser.format(snapsyncFlatStorageHealedCountPerRequest),
|
||||
SNAP_SERVER_ENABLED_FLAG,
|
||||
OptionParser.format(snapsyncServerEnabled)));
|
||||
}
|
||||
OptionParser.format(snapsyncTrieNodeCountPerRequest),
|
||||
SNAP_FLAT_ACCOUNT_HEALED_COUNT_PER_REQUEST_FLAG,
|
||||
OptionParser.format(snapsyncFlatAccountHealedCountPerRequest),
|
||||
SNAP_FLAT_STORAGE_HEALED_COUNT_PER_REQUEST_FLAG,
|
||||
OptionParser.format(snapsyncFlatStorageHealedCountPerRequest),
|
||||
SNAP_SERVER_ENABLED_FLAG,
|
||||
OptionParser.format(snapsyncServerEnabled));
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider {
|
||||
private final CommandLine commandLine;
|
||||
private final InputStream configurationInputStream;
|
||||
private TomlParseResult result;
|
||||
private boolean isUnknownOptionsChecked;
|
||||
|
||||
/**
|
||||
* Instantiates a new Toml config file default value provider.
|
||||
@@ -230,6 +231,11 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider {
|
||||
throw new ParameterException(
|
||||
commandLine,
|
||||
String.format("Unable to read TOML configuration file %s", configurationInputStream));
|
||||
|
||||
if (!isUnknownOptionsChecked && !commandLine.isUnmatchedArgumentsAllowed()) {
|
||||
checkUnknownOptions(result);
|
||||
isUnknownOptionsChecked = true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Load configuration from file. */
|
||||
@@ -249,8 +255,6 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider {
|
||||
commandLine, String.format("Invalid TOML configuration: %s", errors));
|
||||
}
|
||||
|
||||
checkUnknownOptions(result);
|
||||
|
||||
this.result = result;
|
||||
|
||||
} catch (final IOException e) {
|
||||
|
||||
@@ -78,17 +78,6 @@ public class ForkIdsNetworkConfigTest {
|
||||
new ForkId(Bytes.ofUnsignedInt(0x9b192ad0L), 0L),
|
||||
new ForkId(Bytes.ofUnsignedInt(0x9b192ad0L), 0L))
|
||||
},
|
||||
new Object[] {
|
||||
NetworkName.GOERLI,
|
||||
List.of(
|
||||
new ForkId(Bytes.ofUnsignedInt(0xa3f5ab08L), 1561651L),
|
||||
new ForkId(Bytes.ofUnsignedInt(0xc25efa5cL), 4460644L),
|
||||
new ForkId(Bytes.ofUnsignedInt(0x757a1c47L), 5062605L),
|
||||
new ForkId(Bytes.ofUnsignedInt(0xb8c6299dL), 1678832736L),
|
||||
new ForkId(Bytes.ofUnsignedInt(0xf9843abfL), 1705473120),
|
||||
new ForkId(Bytes.ofUnsignedInt(0x70cc14e2L), 0L),
|
||||
new ForkId(Bytes.ofUnsignedInt(0x70cc14e2L), 0L))
|
||||
},
|
||||
new Object[] {
|
||||
NetworkName.MAINNET,
|
||||
List.of(
|
||||
|
||||
@@ -21,16 +21,15 @@ import static org.hyperledger.besu.cli.config.NetworkName.CLASSIC;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.DEV;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.EXPERIMENTAL_EIPS;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.FUTURE_EIPS;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.GOERLI;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.HOLESKY;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.MAINNET;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.MORDOR;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.SEPOLIA;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ENGINE;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.GOERLI_BOOTSTRAP_NODES;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.GOERLI_DISCOVERY_URL;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_BOOTSTRAP_NODES;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_DISCOVERY_URL;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_BOOTSTRAP_NODES;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_DISCOVERY_URL;
|
||||
import static org.hyperledger.besu.plugin.services.storage.DataStorageFormat.BONSAI;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -456,19 +455,19 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenesisPathGoerliEthConfig() {
|
||||
public void testGenesisPathSepoliaEthConfig() {
|
||||
final ArgumentCaptor<EthNetworkConfig> networkArg =
|
||||
ArgumentCaptor.forClass(EthNetworkConfig.class);
|
||||
|
||||
parseCommand("--network", "goerli");
|
||||
parseCommand("--network", "sepolia");
|
||||
|
||||
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
|
||||
verify(mockControllerBuilder).build();
|
||||
|
||||
final EthNetworkConfig config = networkArg.getValue();
|
||||
assertThat(config.bootNodes()).isEqualTo(GOERLI_BOOTSTRAP_NODES);
|
||||
assertThat(config.dnsDiscoveryUrl()).isEqualTo(GOERLI_DISCOVERY_URL);
|
||||
assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(5));
|
||||
assertThat(config.bootNodes()).isEqualTo(SEPOLIA_BOOTSTRAP_NODES);
|
||||
assertThat(config.dnsDiscoveryUrl()).isEqualTo(SEPOLIA_DISCOVERY_URL);
|
||||
assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(11155111));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1628,24 +1627,6 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void goerliValuesAreUsed() {
|
||||
parseCommand("--network", "goerli");
|
||||
|
||||
final ArgumentCaptor<EthNetworkConfig> networkArg =
|
||||
ArgumentCaptor.forClass(EthNetworkConfig.class);
|
||||
|
||||
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
|
||||
verify(mockControllerBuilder).build();
|
||||
|
||||
assertThat(networkArg.getValue()).isEqualTo(EthNetworkConfig.getNetworkConfig(GOERLI));
|
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty();
|
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
|
||||
|
||||
verify(mockLogger, never()).warn(contains("Goerli is deprecated and will be shutdown"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void futureEipsValuesAreUsed() {
|
||||
parseCommand("--network", "future_eips");
|
||||
@@ -1748,8 +1729,8 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void goerliValuesCanBeOverridden() {
|
||||
networkValuesCanBeOverridden("goerli");
|
||||
public void sepoliaValuesCanBeOverridden() {
|
||||
networkValuesCanBeOverridden("sepolia");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2338,29 +2319,48 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void snapsyncHealingOptionShouldBeDisabledByDefault() {
|
||||
public void bonsaiFlatDbShouldBeEnabledByDefault() {
|
||||
final TestBesuCommand besuCommand = parseCommand();
|
||||
assertThat(besuCommand.unstableSynchronizerOptions.isSnapsyncFlatDbHealingEnabled()).isFalse();
|
||||
assertThat(
|
||||
besuCommand
|
||||
.getDataStorageOptions()
|
||||
.toDomainObject()
|
||||
.getUnstable()
|
||||
.getBonsaiFullFlatDbEnabled())
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void snapsyncHealingOptionShouldWork() {
|
||||
final TestBesuCommand besuCommand =
|
||||
parseCommand("--Xsnapsync-synchronizer-flat-db-healing-enabled", "true");
|
||||
assertThat(besuCommand.unstableSynchronizerOptions.isSnapsyncFlatDbHealingEnabled()).isTrue();
|
||||
final TestBesuCommand besuCommand = parseCommand("--Xbonsai-full-flat-db-enabled", "false");
|
||||
assertThat(
|
||||
besuCommand
|
||||
.dataStorageOptions
|
||||
.toDomainObject()
|
||||
.getUnstable()
|
||||
.getBonsaiFullFlatDbEnabled())
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void snapsyncForHealingFeaturesShouldFailWhenHealingIsNotEnabled() {
|
||||
parseCommand("--Xsnapsync-synchronizer-flat-account-healed-count-per-request", "100");
|
||||
parseCommand(
|
||||
"--Xbonsai-full-flat-db-enabled",
|
||||
"false",
|
||||
"--Xsnapsync-synchronizer-flat-account-healed-count-per-request",
|
||||
"100");
|
||||
assertThat(commandErrorOutput.toString(UTF_8))
|
||||
.contains(
|
||||
"--Xsnapsync-synchronizer-flat option can only be used when -Xsnapsync-synchronizer-flat-db-healing-enabled is true");
|
||||
"--Xsnapsync-synchronizer-flat option can only be used when --Xbonsai-full-flat-db-enabled is true");
|
||||
|
||||
parseCommand("--Xsnapsync-synchronizer-flat-slot-healed-count-per-request", "100");
|
||||
parseCommand(
|
||||
"--Xbonsai-full-flat-db-enabled",
|
||||
"false",
|
||||
"--Xsnapsync-synchronizer-flat-slot-healed-count-per-request",
|
||||
"100");
|
||||
assertThat(commandErrorOutput.toString(UTF_8))
|
||||
.contains(
|
||||
"--Xsnapsync-synchronizer-flat option can only be used when -Xsnapsync-synchronizer-flat-db-healing-enabled is true");
|
||||
"--Xsnapsync-synchronizer-flat option can only be used when --Xbonsai-full-flat-db-enabled is true");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -39,7 +39,7 @@ class NetworkDeprecationMessageTest {
|
||||
@EnumSource(
|
||||
value = NetworkName.class,
|
||||
names = {
|
||||
"MAINNET", "SEPOLIA", "GOERLI", "DEV", "CLASSIC", "MORDOR", "HOLESKY",
|
||||
"MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY",
|
||||
})
|
||||
void shouldThrowErrorForNonDeprecatedNetworks(final NetworkName network) {
|
||||
assertThatThrownBy(() -> NetworkDeprecationMessage.generate(network))
|
||||
|
||||
@@ -16,10 +16,10 @@ package org.hyperledger.besu.cli.config;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.MAINNET;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.GOERLI_BOOTSTRAP_NODES;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.GOERLI_DISCOVERY_URL;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_BOOTSTRAP_NODES;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_DISCOVERY_URL;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_BOOTSTRAP_NODES;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_DISCOVERY_URL;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
|
||||
@@ -41,11 +41,11 @@ public class EthNetworkConfigTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultGoerliConfig() {
|
||||
EthNetworkConfig config = EthNetworkConfig.getNetworkConfig(NetworkName.GOERLI);
|
||||
assertThat(config.dnsDiscoveryUrl()).isEqualTo(GOERLI_DISCOVERY_URL);
|
||||
assertThat(config.bootNodes()).isEqualTo(GOERLI_BOOTSTRAP_NODES);
|
||||
assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(5));
|
||||
public void testDefaultSepoliaConfig() {
|
||||
EthNetworkConfig config = EthNetworkConfig.getNetworkConfig(NetworkName.SEPOLIA);
|
||||
assertThat(config.dnsDiscoveryUrl()).isEqualTo(SEPOLIA_DISCOVERY_URL);
|
||||
assertThat(config.bootNodes()).isEqualTo(SEPOLIA_BOOTSTRAP_NODES);
|
||||
assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(11155111));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -78,6 +78,7 @@ public class SynchronizerOptionsTest
|
||||
.storageCountPerRequest(SnapSyncConfiguration.DEFAULT_STORAGE_COUNT_PER_REQUEST + 2)
|
||||
.bytecodeCountPerRequest(
|
||||
SnapSyncConfiguration.DEFAULT_BYTECODE_COUNT_PER_REQUEST + 2)
|
||||
.isSnapServerEnabled(Boolean.TRUE)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class DefaultDiscoveryConfiguration {
|
||||
public static final String GOERLI_DISCOVERY_URL =
|
||||
"enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.goerli.ethdisco.net";
|
||||
public static final String SEPOLIA_DISCOVERY_URL =
|
||||
"enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.sepolia.ethdisco.net";
|
||||
public static final String MAINNET_DISCOVERY_URL =
|
||||
"enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.mainnet.ethdisco.net";
|
||||
|
||||
@@ -40,22 +40,6 @@ public class DefaultDiscoveryConfiguration {
|
||||
)
|
||||
.map(EnodeURLImpl::fromString)
|
||||
.collect(toList()));
|
||||
public static final List<EnodeURL> GOERLI_BOOTSTRAP_NODES =
|
||||
Collections.unmodifiableList(
|
||||
Stream.of(
|
||||
"enode://011f758e6552d105183b1761c5e2dea0111bc20fd5f6422bc7f91e0fabbec9a6595caf6239b37feb773dddd3f87240d99d859431891e4a642cf2a0a9e6cbb98a@51.141.78.53:30303",
|
||||
"enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303",
|
||||
"enode://46add44b9f13965f7b9875ac6b85f016f341012d84f975377573800a863526f4da19ae2c620ec73d11591fa9510e992ecc03ad0751f53cc02f7c7ed6d55c7291@94.237.54.114:30313",
|
||||
"enode://b5948a2d3e9d486c4d75bf32713221c2bd6cf86463302339299bd227dc2e276cd5a1c7ca4f43a0e9122fe9af884efed563bd2a1fd28661f3b5f5ad7bf1de5949@18.218.250.66:30303",
|
||||
|
||||
// Ethereum Foundation bootnode
|
||||
"enode://a61215641fb8714a373c80edbfa0ea8878243193f57c96eeb44d0bc019ef295abd4e044fd619bfc4c59731a73fb79afe84e9ab6da0c743ceb479cbb6d263fa91@3.11.147.67:30303",
|
||||
|
||||
// Goerli Initiative bootnodes
|
||||
"enode://d4f764a48ec2a8ecf883735776fdefe0a3949eb0ca476bd7bc8d0954a9defe8fea15ae5da7d40b5d2d59ce9524a99daedadf6da6283fca492cc80b53689fb3b3@46.4.99.122:32109",
|
||||
"enode://d2b720352e8216c9efc470091aa91ddafc53e222b32780f505c817ceef69e01d5b0b0797b69db254c586f493872352f5a022b4d8479a00fc92ec55f9ad46a27e@88.99.70.182:30303")
|
||||
.map(EnodeURLImpl::fromString)
|
||||
.collect(toList()));
|
||||
public static final List<EnodeURL> SEPOLIA_BOOTSTRAP_NODES =
|
||||
Collections.unmodifiableList(
|
||||
Stream.of(
|
||||
|
||||
@@ -218,6 +218,8 @@ receipt-compaction-enabled=true
|
||||
# feature flags
|
||||
Xsecp256k1-native-enabled=false
|
||||
Xaltbn128-native-enabled=false
|
||||
Xsnapsync-server-enabled=true
|
||||
Xbonsai-full-flat-db-enabled=true
|
||||
|
||||
# compatibility flags
|
||||
compatibility-eth64-forkid-enabled=false
|
||||
|
||||
11
build.gradle
11
build.gradle
@@ -204,7 +204,14 @@ allprojects {
|
||||
endWithNewline()
|
||||
}
|
||||
// Below this line are currently only license header tasks
|
||||
format 'bash', { target '**/*.sh' }
|
||||
format 'ShellScripts', {
|
||||
target '**/*.sh'
|
||||
targetExclude '**/src/reference-test/**', '**/src/main/generated/**', '**/src/test/generated/**', '**/src/jmh/generated/**'
|
||||
trimTrailingWhitespace()
|
||||
endWithNewline()
|
||||
|
||||
licenseHeaderFile("${rootDir}/gradle/spotless/sh.license","^(?!##).+").skipLinesMatching("^#!.+?\$")
|
||||
}
|
||||
format 'Solidity', {
|
||||
target '**/*.sol'
|
||||
targetExclude '**/src/reference-test/**', '**/src/main/generated/**', '**/src/test/generated/**', '**/src/jmh/generated/**'
|
||||
@@ -1001,7 +1008,7 @@ distributions {
|
||||
from("build/reports/license/license-dependency.html") { into "." }
|
||||
from("./docs/GettingStartedBinaries.md") { into "." }
|
||||
from("./docs/DocsArchive0.8.0.html") { into "." }
|
||||
from("build/besu.autocomplete.sh") { into "." }
|
||||
from(autocomplete) { into "." }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,823 +0,0 @@
|
||||
{
|
||||
"config":{
|
||||
"chainId":5,
|
||||
"petersburgBlock":0,
|
||||
"istanbulBlock":1561651,
|
||||
"berlinBlock":4460644,
|
||||
"londonBlock":5062605,
|
||||
"terminalTotalDifficulty": 10790000,
|
||||
"shanghaiTime": 1678832736,
|
||||
"cancunTime": 1705473120,
|
||||
"clique":{
|
||||
"blockperiodseconds":15,
|
||||
"epochlength":30000
|
||||
},
|
||||
"discovery": {
|
||||
"dns": "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.goerli.ethdisco.net",
|
||||
"bootnodes": [
|
||||
"enode://011f758e6552d105183b1761c5e2dea0111bc20fd5f6422bc7f91e0fabbec9a6595caf6239b37feb773dddd3f87240d99d859431891e4a642cf2a0a9e6cbb98a@51.141.78.53:30303",
|
||||
"enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303",
|
||||
"enode://46add44b9f13965f7b9875ac6b85f016f341012d84f975377573800a863526f4da19ae2c620ec73d11591fa9510e992ecc03ad0751f53cc02f7c7ed6d55c7291@94.237.54.114:30313",
|
||||
"enode://b5948a2d3e9d486c4d75bf32713221c2bd6cf86463302339299bd227dc2e276cd5a1c7ca4f43a0e9122fe9af884efed563bd2a1fd28661f3b5f5ad7bf1de5949@18.218.250.66:30303",
|
||||
"enode://a61215641fb8714a373c80edbfa0ea8878243193f57c96eeb44d0bc019ef295abd4e044fd619bfc4c59731a73fb79afe84e9ab6da0c743ceb479cbb6d263fa91@3.11.147.67:30303",
|
||||
"enode://d4f764a48ec2a8ecf883735776fdefe0a3949eb0ca476bd7bc8d0954a9defe8fea15ae5da7d40b5d2d59ce9524a99daedadf6da6283fca492cc80b53689fb3b3@46.4.99.122:32109",
|
||||
"enode://d2b720352e8216c9efc470091aa91ddafc53e222b32780f505c817ceef69e01d5b0b0797b69db254c586f493872352f5a022b4d8479a00fc92ec55f9ad46a27e@88.99.70.182:30303"
|
||||
]
|
||||
},
|
||||
"checkpoint": {
|
||||
"hash": "0x50e55c39a725f062af438c5332a5c5bec9a36d02c829ee6ac2cc27d1db719446",
|
||||
"number": 4350000,
|
||||
"totalDifficulty": "0x61DBBF",
|
||||
"_comment": "must be the beginning of a clique epoch"
|
||||
}
|
||||
},
|
||||
"coinbase":"0x0000000000000000000000000000000000000000",
|
||||
"difficulty":"0x1",
|
||||
"extraData":"0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit":"0xa00000",
|
||||
"mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"nonce":"0x0",
|
||||
"timestamp":"0x5c51a607",
|
||||
"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"
|
||||
},
|
||||
"4c2ae482593505f0163cdefc073e81c63cda4107": {
|
||||
"balance": "0x152d02c7e14af6800000"
|
||||
},
|
||||
"a8e8f14732658e4b51e8711931053a8a69baf2b1": {
|
||||
"balance": "0x152d02c7e14af6800000"
|
||||
},
|
||||
"d9a5179f091d85051d3c982785efd1455cec8699": {
|
||||
"balance": "0x84595161401484a000000"
|
||||
},
|
||||
"e0a2bd4258d2768837baa26a28fe71dc079f84c7": {
|
||||
"balance": "0x4a47e3c12448f4ad000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,16 +205,6 @@ class GenesisConfigFileTest {
|
||||
.contains(UInt256.valueOf(new BigInteger("17000000000000000")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void assertGoerliTerminalTotalDifficulty() {
|
||||
GenesisConfigOptions goerliOptions =
|
||||
GenesisConfigFile.fromResource("/goerli.json").getConfigOptions();
|
||||
|
||||
assertThat(goerliOptions.getTerminalTotalDifficulty()).isPresent();
|
||||
assertThat(goerliOptions.getTerminalTotalDifficulty())
|
||||
.contains(UInt256.valueOf(new BigInteger("10790000")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void assertMainnetTerminalTotalDifficulty() {
|
||||
GenesisConfigOptions mainnetOptions =
|
||||
|
||||
@@ -30,6 +30,7 @@ jar {
|
||||
|
||||
dependencies {
|
||||
compileOnly 'com.fasterxml.jackson.core:jackson-databind'
|
||||
compileOnly 'io.vertx:vertx-core'
|
||||
|
||||
implementation project(':crypto:algorithms')
|
||||
implementation project(':ethereum:rlp')
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
#!/bin/bash
|
||||
##
|
||||
## Copyright contributors to Hyperledger Besu.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
||||
export TEST_PATH=./tests
|
||||
export GOSS_PATH=$TEST_PATH/goss-linux-${architecture}
|
||||
|
||||
@@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat;
|
||||
|
||||
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.CODE_STORAGE;
|
||||
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE;
|
||||
import static org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage.WORLD_ROOT_HASH_KEY;
|
||||
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.FullFlatDbStrategy;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.PartialFlatDbStrategy;
|
||||
@@ -70,12 +71,36 @@ public class FlatDbStrategyProvider {
|
||||
|
||||
@VisibleForTesting
|
||||
FlatDbMode deriveFlatDbStrategy(final SegmentedKeyValueStorage composedWorldStateStorage) {
|
||||
final FlatDbMode requestedFlatDbMode =
|
||||
dataStorageConfiguration.getUnstable().getBonsaiFullFlatDbEnabled()
|
||||
? FlatDbMode.FULL
|
||||
: FlatDbMode.PARTIAL;
|
||||
|
||||
final var existingTrieData =
|
||||
composedWorldStateStorage.get(TRIE_BRANCH_STORAGE, WORLD_ROOT_HASH_KEY).isPresent();
|
||||
|
||||
var flatDbMode =
|
||||
FlatDbMode.fromVersion(
|
||||
composedWorldStateStorage
|
||||
.get(TRIE_BRANCH_STORAGE, FLAT_DB_MODE)
|
||||
.map(Bytes::wrap)
|
||||
.orElse(FlatDbMode.PARTIAL.getVersion()));
|
||||
.orElseGet(
|
||||
() -> {
|
||||
// if we do not have a db-supplied config for flatdb, derive it:
|
||||
// default to partial if trie data exists, but the flat config does not,
|
||||
// and default to the storage config otherwise
|
||||
var flatDbModeVal =
|
||||
existingTrieData
|
||||
? FlatDbMode.PARTIAL.getVersion()
|
||||
: requestedFlatDbMode.getVersion();
|
||||
// persist this config in the db
|
||||
var setDbModeTx = composedWorldStateStorage.startTransaction();
|
||||
setDbModeTx.put(
|
||||
TRIE_BRANCH_STORAGE, FLAT_DB_MODE, flatDbModeVal.toArrayUnsafe());
|
||||
setDbModeTx.commit();
|
||||
|
||||
return flatDbModeVal;
|
||||
}));
|
||||
LOG.info("Bonsai flat db mode found {}", flatDbMode);
|
||||
|
||||
return flatDbMode;
|
||||
@@ -123,7 +148,7 @@ public class FlatDbStrategyProvider {
|
||||
public void upgradeToFullFlatDbMode(final SegmentedKeyValueStorage composedWorldStateStorage) {
|
||||
final SegmentedKeyValueStorageTransaction transaction =
|
||||
composedWorldStateStorage.startTransaction();
|
||||
// TODO: consider ARCHIVE mode
|
||||
LOG.info("setting FlatDbStrategy to FULL");
|
||||
transaction.put(
|
||||
TRIE_BRANCH_STORAGE, FLAT_DB_MODE, FlatDbMode.FULL.getVersion().toArrayUnsafe());
|
||||
transaction.commit();
|
||||
@@ -134,6 +159,7 @@ public class FlatDbStrategyProvider {
|
||||
final SegmentedKeyValueStorage composedWorldStateStorage) {
|
||||
final SegmentedKeyValueStorageTransaction transaction =
|
||||
composedWorldStateStorage.startTransaction();
|
||||
LOG.info("setting FlatDbStrategy to PARTIAL");
|
||||
transaction.put(
|
||||
TRIE_BRANCH_STORAGE, FLAT_DB_MODE, FlatDbMode.PARTIAL.getVersion().toArrayUnsafe());
|
||||
transaction.commit();
|
||||
|
||||
@@ -38,6 +38,13 @@ public interface DataStorageConfiguration {
|
||||
.bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD)
|
||||
.build();
|
||||
|
||||
DataStorageConfiguration DEFAULT_BONSAI_PARTIAL_DB_CONFIG =
|
||||
ImmutableDataStorageConfiguration.builder()
|
||||
.dataStorageFormat(DataStorageFormat.BONSAI)
|
||||
.bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD)
|
||||
.unstable(Unstable.DEFAULT_PARTIAL)
|
||||
.build();
|
||||
|
||||
DataStorageConfiguration DEFAULT_FOREST_CONFIG =
|
||||
ImmutableDataStorageConfiguration.builder()
|
||||
.dataStorageFormat(DataStorageFormat.FOREST)
|
||||
@@ -65,11 +72,15 @@ public interface DataStorageConfiguration {
|
||||
boolean DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED = false;
|
||||
long MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT = DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD;
|
||||
int DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE = 30_000;
|
||||
boolean DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED = false;
|
||||
boolean DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED = true;
|
||||
boolean DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED = true;
|
||||
|
||||
DataStorageConfiguration.Unstable DEFAULT =
|
||||
ImmutableDataStorageConfiguration.Unstable.builder().build();
|
||||
|
||||
DataStorageConfiguration.Unstable DEFAULT_PARTIAL =
|
||||
ImmutableDataStorageConfiguration.Unstable.builder().bonsaiFullFlatDbEnabled(false).build();
|
||||
|
||||
@Value.Default
|
||||
default boolean getBonsaiLimitTrieLogsEnabled() {
|
||||
return DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED;
|
||||
@@ -80,6 +91,11 @@ public interface DataStorageConfiguration {
|
||||
return DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE;
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
default boolean getBonsaiFullFlatDbEnabled() {
|
||||
return DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED;
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
default boolean getBonsaiCodeStoredByCodeHashEnabled() {
|
||||
return DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED;
|
||||
|
||||
@@ -297,39 +297,6 @@ public class ForkIdTest {
|
||||
ForkIdTestUtil.wantForkId("0xf7f9bc08", 0L),
|
||||
Optional.of(ForkIds.SEPOLIA),
|
||||
empty()),
|
||||
// goerli
|
||||
Arguments.of(
|
||||
"Goerli // Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople and first Petersburg block",
|
||||
Network.GOERLI,
|
||||
0L,
|
||||
0L,
|
||||
ForkIdTestUtil.wantForkId("0xa3f5ab08", 1561651L),
|
||||
Optional.of(ForkIds.GOERLI),
|
||||
empty()),
|
||||
Arguments.of(
|
||||
"Goerli // Last Petersburg block",
|
||||
Network.GOERLI,
|
||||
1561650L,
|
||||
0L,
|
||||
ForkIdTestUtil.wantForkId("0xa3f5ab08", 1561651L),
|
||||
Optional.of(ForkIds.GOERLI),
|
||||
empty()),
|
||||
Arguments.of(
|
||||
"Goerli // First Istanbul block",
|
||||
Network.GOERLI,
|
||||
1561651L,
|
||||
0L,
|
||||
ForkIdTestUtil.wantForkId("0xc25efa5c", 0L),
|
||||
Optional.of(ForkIds.GOERLI),
|
||||
empty()),
|
||||
Arguments.of(
|
||||
"Goerli // Future Istanbul block",
|
||||
Network.GOERLI,
|
||||
2000000L,
|
||||
0L,
|
||||
ForkIdTestUtil.wantForkId("0xc25efa5c", 0L),
|
||||
Optional.of(ForkIds.GOERLI),
|
||||
empty()),
|
||||
// private
|
||||
Arguments.of(
|
||||
"Private // Unsynced",
|
||||
|
||||
@@ -64,8 +64,6 @@ public class ForkIdTestUtil {
|
||||
"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3";
|
||||
public static final String SEPOLIA =
|
||||
"0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9";
|
||||
public static final String GOERLI =
|
||||
"0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a";
|
||||
public static final String PRIVATE =
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000";
|
||||
}
|
||||
@@ -80,7 +78,6 @@ public class ForkIdTestUtil {
|
||||
|
||||
public static final List<Long> SEPOLIA_TIMESTAMPS = Arrays.asList(1677557088L);
|
||||
|
||||
public static final List<Long> GOERLI = Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1561651L);
|
||||
public static final List<Long> PRIVATE = Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
|
||||
|
||||
public static final List<Long> MAINNET_WITH_SHANGHAI_BLOCKS =
|
||||
@@ -111,10 +108,6 @@ public class ForkIdTestUtil {
|
||||
new ForkId(Bytes.fromHexString("0xfe3366e7"), 1735371L),
|
||||
new ForkId(Bytes.fromHexString("0xb96cbd13"), 1677557088L),
|
||||
new ForkId(Bytes.fromHexString("0xf7f9bc08"), 0L)); // First Shanghai block (timestamp)
|
||||
public static final List<ForkId> GOERLI =
|
||||
Arrays.asList(
|
||||
new ForkId(Bytes.fromHexString("0xa3f5ab08"), 1561651L),
|
||||
new ForkId(Bytes.fromHexString("0xc25efa5c"), 0L));
|
||||
|
||||
public static final List<ForkId> WITHDRAWALS =
|
||||
Arrays.asList(
|
||||
@@ -141,7 +134,6 @@ public class ForkIdTestUtil {
|
||||
public static final Network MAINNET = network(GenesisHash.MAINNET, Forks.MAINNET, emptyList());
|
||||
public static final Network SEPOLIA =
|
||||
network(GenesisHash.SEPOLIA, Forks.SEPOLIA_BLOCKNUMBERS, Forks.SEPOLIA_TIMESTAMPS);
|
||||
public static final Network GOERLI = network(GenesisHash.GOERLI, Forks.GOERLI, emptyList());
|
||||
public static final Network PRIVATE = network(GenesisHash.PRIVATE, Forks.PRIVATE, emptyList());
|
||||
|
||||
public static final Network MAINNET_WITH_SHANGHAI =
|
||||
|
||||
@@ -123,26 +123,6 @@ public class MainnetProtocolScheduleTest {
|
||||
new BadBlockManager()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateGoerliConfig() {
|
||||
final ProtocolSchedule sched =
|
||||
MainnetProtocolSchedule.fromConfig(
|
||||
GenesisConfigFile.fromResource("/goerli.json").getConfigOptions(),
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningParameters.MINING_DISABLED,
|
||||
new BadBlockManager());
|
||||
Assertions.assertThat(sched.getByBlockHeader(blockHeader(0L)).getName())
|
||||
.isEqualTo("Petersburg");
|
||||
Assertions.assertThat(sched.getByBlockHeader(blockHeader(1_561_651L)).getName())
|
||||
.isEqualTo("Istanbul");
|
||||
Assertions.assertThat(sched.getByBlockHeader(blockHeader(4_460_644L)).getName())
|
||||
.isEqualTo("Berlin");
|
||||
Assertions.assertThat(sched.getByBlockHeader(blockHeader(5_062_605L)).getName())
|
||||
.isEqualTo("London");
|
||||
Assertions.assertThat(sched.getByBlockHeader(blockHeader(Long.MAX_VALUE)).getName())
|
||||
.isEqualTo("London");
|
||||
}
|
||||
|
||||
private BlockHeader blockHeader(final long number) {
|
||||
return new BlockHeaderTestFixture().number(number).buildHeader();
|
||||
}
|
||||
|
||||
@@ -152,8 +152,11 @@ public abstract class AbstractIsolationTests {
|
||||
@BeforeEach
|
||||
public void createStorage() {
|
||||
worldStateKeyValueStorage =
|
||||
// FYI: BonsaiSnapshoIsolationTests work with frozen/cached worldstates, using PARTIAL
|
||||
// flat db strategy allows the tests to make account assertions based on trie
|
||||
// (whereas a full db strategy will not, since the worldstates are frozen/cached)
|
||||
createKeyValueStorageProvider()
|
||||
.createWorldStateStorage(DataStorageConfiguration.DEFAULT_BONSAI_CONFIG);
|
||||
.createWorldStateStorage(DataStorageConfiguration.DEFAULT_BONSAI_PARTIAL_DB_CONFIG);
|
||||
archive =
|
||||
new BonsaiWorldStateProvider(
|
||||
(BonsaiWorldStateKeyValueStorage) worldStateKeyValueStorage,
|
||||
|
||||
@@ -45,7 +45,6 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage;
|
||||
import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -79,18 +78,19 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
|
||||
BonsaiWorldStateKeyValueStorage storage;
|
||||
|
||||
public void setUp(final FlatDbMode flatDbMode) {
|
||||
storage = emptyStorage();
|
||||
if (flatDbMode.equals(FlatDbMode.FULL)) {
|
||||
storage.upgradeToFullFlatDbMode();
|
||||
}
|
||||
public BonsaiWorldStateKeyValueStorage setUp(final FlatDbMode flatDbMode) {
|
||||
return setUp(flatDbMode, false);
|
||||
}
|
||||
|
||||
public void setUp(final FlatDbMode flatDbMode, final boolean useCodeHashStorage) {
|
||||
public BonsaiWorldStateKeyValueStorage setUp(
|
||||
final FlatDbMode flatDbMode, final boolean useCodeHashStorage) {
|
||||
storage = emptyStorage(useCodeHashStorage);
|
||||
if (flatDbMode.equals(FlatDbMode.FULL)) {
|
||||
storage.upgradeToFullFlatDbMode();
|
||||
} else if (flatDbMode.equals(FlatDbMode.PARTIAL)) {
|
||||
storage.downgradeToPartialFlatDbMode();
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -215,9 +215,8 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
@ParameterizedTest
|
||||
@MethodSource("flatDbMode")
|
||||
void getAccount_notLoadFromTrieWhenEmptyAndFlatDbFullMode(final FlatDbMode flatDbMode) {
|
||||
setUp(flatDbMode);
|
||||
Assumptions.assumeTrue(flatDbMode == FlatDbMode.FULL);
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(emptyStorage());
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(setUp(flatDbMode));
|
||||
final WorldStateStorageCoordinator coordinator = new WorldStateStorageCoordinator(storage);
|
||||
final MerkleTrie<Bytes, Bytes> trie = TrieGenerator.generateTrie(coordinator, 1);
|
||||
|
||||
@@ -233,8 +232,8 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
updater.commit();
|
||||
|
||||
// remove flat database
|
||||
storage.downgradeToPartialFlatDbMode();
|
||||
storage.clearFlatDatabase();
|
||||
|
||||
storage.upgradeToFullFlatDbMode();
|
||||
|
||||
Mockito.reset(storage);
|
||||
@@ -247,9 +246,8 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
@ParameterizedTest
|
||||
@MethodSource("flatDbMode")
|
||||
void getAccount_loadFromTrieWhenEmptyAndFlatDbPartialMode(final FlatDbMode flatDbMode) {
|
||||
setUp(flatDbMode);
|
||||
Assumptions.assumeTrue(flatDbMode == FlatDbMode.PARTIAL);
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(emptyStorage());
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(setUp(flatDbMode));
|
||||
final WorldStateStorageCoordinator coordinator = new WorldStateStorageCoordinator(storage);
|
||||
final MerkleTrie<Bytes, Bytes> trie = TrieGenerator.generateTrie(coordinator, 1);
|
||||
final TreeMap<Bytes32, Bytes> accounts =
|
||||
@@ -277,9 +275,8 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
@ParameterizedTest
|
||||
@MethodSource("flatDbMode")
|
||||
void shouldUsePartialDBStrategyAfterDowngradingMode(final FlatDbMode flatDbMode) {
|
||||
setUp(flatDbMode);
|
||||
Assumptions.assumeTrue(flatDbMode == FlatDbMode.PARTIAL);
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(emptyStorage());
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(setUp(flatDbMode));
|
||||
final WorldStateStorageCoordinator coordinator = new WorldStateStorageCoordinator(storage);
|
||||
final MerkleTrie<Bytes, Bytes> trie = TrieGenerator.generateTrie(coordinator, 1);
|
||||
final TreeMap<Bytes32, Bytes> accounts =
|
||||
@@ -309,9 +306,9 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
@ParameterizedTest
|
||||
@MethodSource("flatDbMode")
|
||||
void getStorage_loadFromTrieWhenEmptyWithPartialMode(final FlatDbMode flatDbMode) {
|
||||
setUp(flatDbMode);
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(setUp(flatDbMode));
|
||||
Assumptions.assumeTrue(flatDbMode == FlatDbMode.PARTIAL);
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(emptyStorage());
|
||||
|
||||
final WorldStateStorageCoordinator coordinator = new WorldStateStorageCoordinator(storage);
|
||||
final MerkleTrie<Bytes, Bytes> trie = TrieGenerator.generateTrie(coordinator, 1);
|
||||
final TreeMap<Bytes32, Bytes> accounts =
|
||||
@@ -359,9 +356,8 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
@ParameterizedTest
|
||||
@MethodSource("flatDbMode")
|
||||
void getStorage_loadFromTrieWhenEmptyWithFullMode(final FlatDbMode flatDbMode) {
|
||||
setUp(flatDbMode);
|
||||
Assumptions.assumeTrue(flatDbMode == FlatDbMode.FULL);
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(emptyStorage());
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(setUp(flatDbMode));
|
||||
storage.upgradeToFullFlatDbMode();
|
||||
final WorldStateStorageCoordinator coordinator = new WorldStateStorageCoordinator(storage);
|
||||
final MerkleTrie<Bytes, Bytes> trie = TrieGenerator.generateTrie(coordinator, 1);
|
||||
@@ -380,8 +376,7 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
@ParameterizedTest
|
||||
@MethodSource("flatDbMode")
|
||||
void clear_reloadFlatDbStrategy(final FlatDbMode flatDbMode) {
|
||||
setUp(flatDbMode);
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(emptyStorage());
|
||||
final BonsaiWorldStateKeyValueStorage storage = spy(setUp(flatDbMode));
|
||||
|
||||
// save world state root hash
|
||||
final BonsaiWorldStateKeyValueStorage.Updater updater = storage.updater();
|
||||
@@ -489,7 +484,7 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
void successfulPruneReturnsTrue() {
|
||||
final KeyValueStorage mockTrieLogStorage = mock(KeyValueStorage.class);
|
||||
when(mockTrieLogStorage.tryDelete(any())).thenReturn(true);
|
||||
final BonsaiWorldStateKeyValueStorage storage = setupMockStorage(mockTrieLogStorage);
|
||||
final BonsaiWorldStateKeyValueStorage storage = setupSpyStorage(mockTrieLogStorage);
|
||||
assertThat(storage.pruneTrieLog(Hash.ZERO)).isTrue();
|
||||
}
|
||||
|
||||
@@ -497,7 +492,7 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
void failedPruneReturnsFalse() {
|
||||
final KeyValueStorage mockTrieLogStorage = mock(KeyValueStorage.class);
|
||||
when(mockTrieLogStorage.tryDelete(any())).thenReturn(false);
|
||||
final BonsaiWorldStateKeyValueStorage storage = setupMockStorage(mockTrieLogStorage);
|
||||
final BonsaiWorldStateKeyValueStorage storage = setupSpyStorage(mockTrieLogStorage);
|
||||
assertThat(storage.pruneTrieLog(Hash.ZERO)).isFalse();
|
||||
}
|
||||
|
||||
@@ -505,18 +500,17 @@ public class BonsaiWorldStateKeyValueStorageTest {
|
||||
void exceptionalPruneReturnsFalse() {
|
||||
final KeyValueStorage mockTrieLogStorage = mock(KeyValueStorage.class);
|
||||
when(mockTrieLogStorage.tryDelete(any())).thenThrow(new RuntimeException("test exception"));
|
||||
final BonsaiWorldStateKeyValueStorage storage = setupMockStorage(mockTrieLogStorage);
|
||||
final BonsaiWorldStateKeyValueStorage storage = setupSpyStorage(mockTrieLogStorage);
|
||||
assertThat(storage.pruneTrieLog(Hash.ZERO)).isFalse();
|
||||
}
|
||||
|
||||
private BonsaiWorldStateKeyValueStorage setupMockStorage(
|
||||
private BonsaiWorldStateKeyValueStorage setupSpyStorage(
|
||||
final KeyValueStorage mockTrieLogStorage) {
|
||||
final StorageProvider mockStorageProvider = mock(StorageProvider.class);
|
||||
final StorageProvider mockStorageProvider = spy(new InMemoryKeyValueStorageProvider());
|
||||
when(mockStorageProvider.getStorageBySegmentIdentifier(
|
||||
KeyValueSegmentIdentifier.TRIE_LOG_STORAGE))
|
||||
.thenReturn(mockTrieLogStorage);
|
||||
when(mockStorageProvider.getStorageBySegmentIdentifiers(any()))
|
||||
.thenReturn(mock(SegmentedKeyValueStorage.class));
|
||||
|
||||
return new BonsaiWorldStateKeyValueStorage(
|
||||
mockStorageProvider,
|
||||
new NoOpMetricsSystem(),
|
||||
|
||||
@@ -63,7 +63,7 @@ class FlatDbStrategyProviderTest {
|
||||
@Test
|
||||
void loadsPartialFlatDbStrategyWhenNoFlatDbModeStored() {
|
||||
flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage);
|
||||
assertThat(flatDbStrategyProvider.getFlatDbMode()).isEqualTo(FlatDbMode.PARTIAL);
|
||||
assertThat(flatDbStrategyProvider.getFlatDbMode()).isEqualTo(FlatDbMode.FULL);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,7 +76,7 @@ class FlatDbStrategyProviderTest {
|
||||
assertThat(flatDbStrategyProvider.getFlatDbStrategy(composedWorldStateStorage))
|
||||
.isInstanceOf(FullFlatDbStrategy.class);
|
||||
assertThat(flatDbStrategyProvider.flatDbStrategy.codeStorageStrategy)
|
||||
.isInstanceOf(AccountHashCodeStorageStrategy.class);
|
||||
.isInstanceOf(CodeHashCodeStorageStrategy.class);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -99,7 +99,7 @@ class FlatDbStrategyProviderTest {
|
||||
codeByHashEnabled
|
||||
? CodeHashCodeStorageStrategy.class
|
||||
: AccountHashCodeStorageStrategy.class;
|
||||
assertThat(flatDbStrategyProvider.flatDbMode).isEqualTo(FlatDbMode.PARTIAL);
|
||||
assertThat(flatDbStrategyProvider.flatDbMode).isEqualTo(FlatDbMode.FULL);
|
||||
assertThat(flatDbStrategyProvider.flatDbStrategy.codeStorageStrategy)
|
||||
.isInstanceOf(expectedCodeStorageClass);
|
||||
}
|
||||
@@ -129,7 +129,7 @@ class FlatDbStrategyProviderTest {
|
||||
transaction.commit();
|
||||
|
||||
flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage);
|
||||
assertThat(flatDbStrategyProvider.flatDbMode).isEqualTo(FlatDbMode.PARTIAL);
|
||||
assertThat(flatDbStrategyProvider.flatDbMode).isEqualTo(FlatDbMode.FULL);
|
||||
assertThat(flatDbStrategyProvider.flatDbStrategy.codeStorageStrategy)
|
||||
.isInstanceOf(AccountHashCodeStorageStrategy.class);
|
||||
}
|
||||
@@ -158,7 +158,7 @@ class FlatDbStrategyProviderTest {
|
||||
transaction.commit();
|
||||
|
||||
flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage);
|
||||
assertThat(flatDbStrategyProvider.flatDbMode).isEqualTo(FlatDbMode.PARTIAL);
|
||||
assertThat(flatDbStrategyProvider.flatDbMode).isEqualTo(FlatDbMode.FULL);
|
||||
assertThat(flatDbStrategyProvider.flatDbStrategy.codeStorageStrategy)
|
||||
.isInstanceOf(CodeHashCodeStorageStrategy.class);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ public class SnapSyncConfiguration {
|
||||
public static final int DEFAULT_LOCAL_FLAT_STORAGE_COUNT_TO_HEAL_PER_REQUEST =
|
||||
1024; // The default number of flat slots entries to verify and heal per request.
|
||||
|
||||
public static final Boolean DEFAULT_IS_FLAT_DB_HEALING_ENABLED = Boolean.FALSE;
|
||||
|
||||
public static final Boolean DEFAULT_SNAP_SERVER_ENABLED = Boolean.FALSE;
|
||||
|
||||
public static SnapSyncConfiguration getDefault() {
|
||||
@@ -79,11 +77,6 @@ public class SnapSyncConfiguration {
|
||||
return DEFAULT_LOCAL_FLAT_STORAGE_COUNT_TO_HEAL_PER_REQUEST;
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
public Boolean isFlatDbHealingEnabled() {
|
||||
return DEFAULT_IS_FLAT_DB_HEALING_ENABLED;
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
public Boolean isSnapServerEnabled() {
|
||||
return DEFAULT_SNAP_SERVER_ENABLED;
|
||||
|
||||
@@ -184,16 +184,6 @@ public class SnapWorldStateDownloader implements WorldStateDownloader {
|
||||
} else {
|
||||
// start from scratch
|
||||
worldStateStorageCoordinator.clear();
|
||||
// we have to upgrade to full flat db mode if we are in bonsai mode
|
||||
if (snapSyncConfiguration.isFlatDbHealingEnabled()) {
|
||||
worldStateStorageCoordinator.applyOnMatchingStrategy(
|
||||
DataStorageFormat.BONSAI,
|
||||
strategy -> {
|
||||
BonsaiWorldStateKeyValueStorage onBonsai =
|
||||
(BonsaiWorldStateKeyValueStorage) strategy;
|
||||
onBonsai.upgradeToFullFlatDbMode();
|
||||
});
|
||||
}
|
||||
ranges.forEach(
|
||||
(key, value) ->
|
||||
newDownloadState.enqueueRequest(
|
||||
|
||||
@@ -118,7 +118,7 @@ public class SnapWorldDownloadStateTest {
|
||||
new BonsaiWorldStateKeyValueStorage(
|
||||
new InMemoryKeyValueStorageProvider(),
|
||||
new NoOpMetricsSystem(),
|
||||
DataStorageConfiguration.DEFAULT_BONSAI_CONFIG);
|
||||
DataStorageConfiguration.DEFAULT_BONSAI_PARTIAL_DB_CONFIG);
|
||||
} else {
|
||||
worldStateKeyValueStorage =
|
||||
new ForestWorldStateKeyValueStorage(new InMemoryKeyValueStorage());
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
#!/usr/bin/env sh
|
||||
##
|
||||
## Copyright contributors to Hyperledger Besu.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
||||
# open
|
||||
../../../build/install/evmtool/bin/evm \
|
||||
--code=0x608060405234801561001057600080fd5b50600436106100415760003560e01c80631de45b10146100465780637c261929146101a25780639064129314610271575b600080fd5b6101a06004803603606081101561005c57600080fd5b810190808035906020019064010000000081111561007957600080fd5b82018360208201111561008b57600080fd5b803590602001918460018302840111640100000000831117156100ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561011057600080fd5b82018360208201111561012257600080fd5b8035906020019184600183028401116401000000008311171561014457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050610336565b005b61025b600480360360208110156101b857600080fd5b81019080803590602001906401000000008111156101d557600080fd5b8201836020820111156101e757600080fd5b8035906020019184600183028401116401000000008311171561020957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610429565b6040518082815260200191505060405180910390f35b6103346004803603604081101561028757600080fd5b81019080803590602001906401000000008111156102a457600080fd5b8201836020820111156102b657600080fd5b803590602001918460018302840111640100000000831117156102d857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919050505061049b565b005b806000846040518082805190602001908083835b6020831061036d578051825260208201915060208101905060208303925061034a565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060008282540392505081905550806000836040518082805190602001908083835b602083106103e457805182526020820191506020810190506020830392506103c1565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060008282540192505081905550505050565b600080826040518082805190602001908083835b60208310610460578051825260208201915060208101905060208303925061043d565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b806000836040518082805190602001908083835b602083106104d257805182526020820191506020810190506020830392506104af565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902081905550505056fea265627a7a72315820f89fa48c6c4d5d7df165b5e3dba04cbe258ce57a3a4ef3bab1377546b84b699f64736f6c634300050b0032 \
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
#!/usr/bin/env sh
|
||||
##
|
||||
## Copyright contributors to Hyperledger Besu.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
||||
# divadd
|
||||
../../../build/install/evmtool/bin/evm \
|
||||
--code=0x606060405263ffffffff60e060020a60003504166315d42327811461004257806359e3e1ea14610070578063c4f8b9fb1461009e578063e01330bb146100c9575bfe5b341561004a57fe5b61005e6004356024356044356064356100f4565b60408051918252519081900360200190f35b341561007857fe5b61005e60043560243560443560643561011e565b60408051918252519081900360200190f35b34156100a657fe5b61005e600435602435604435610152565b60408051918252519081900360200190f35b34156100d157fe5b61005e600435602435604435610179565b60408051918252519081900360200190f35b600084815b83811015610110578486830991505b6001016100f9565b8192505b5050949350505050565b600084815b8381101561011057858281151561013657fe5b04850191505b600101610123565b8192505b5050949350505050565b600083815b8381101561016c57908401905b600101610157565b8192505b50509392505050565b600083815b8381101561016c57908402905b60010161017e565b8192505b505093925050505600a165627a7a72305820065081bd1e9fdffccd251332523241eaabd0fb1881a06529599a9c67d0a568e50029 \
|
||||
@@ -17,4 +33,3 @@
|
||||
--genesis=evmtool-genesis.json \
|
||||
--gas 1000000000 \
|
||||
--repeat=10
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,19 @@
|
||||
#!/usr/bin/env sh
|
||||
##
|
||||
## Copyright contributors to Hyperledger Besu.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
||||
# call
|
||||
../../../build/install/evmtool/bin/evm \
|
||||
--code=5B600080808060045AFA50600056 \
|
||||
|
||||
@@ -80,13 +80,22 @@ def executionSpecTests = tasks.register("executionSpecTests") {
|
||||
|
||||
inputs.files fileTree(referenceTestsPath), fileTree(generatedTestsPath)
|
||||
outputs.files generatedTestsPath
|
||||
// generate blockchain_tests:
|
||||
generateTestFiles(
|
||||
fileTree(referenceTestsPath + "/fixtures"),
|
||||
file("src/reference-test/templates/BlockchainReferenceTest.java.template"),
|
||||
fileTree(referenceTestsPath + "/fixtures/blockchain_tests"),
|
||||
file("src/reference-test/templates/ExecutionSpecTest.java.template"),
|
||||
"fixtures",
|
||||
"$generatedTestsPath/org/hyperledger/besu/ethereum/vm/executionspec",
|
||||
"ExecutionSpecTest",
|
||||
("fixtures/example/example") // exclude test for test filling tool
|
||||
"ExecutionSpecBlockchainTest"
|
||||
)
|
||||
|
||||
// generate state_tests:
|
||||
generateTestFiles(
|
||||
fileTree(referenceTestsPath + "/fixtures/state_tests"),
|
||||
file("src/reference-test/templates/ExecutionSpecStateTest.java.template"),
|
||||
"fixtures",
|
||||
"$generatedTestsPath/org/hyperledger/besu/ethereum/vm/executionspec",
|
||||
"ExecutionSpecStateTest"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -170,7 +179,7 @@ dependencies {
|
||||
referenceTestImplementation project(path: ':testutil')
|
||||
referenceTestImplementation project(path: ':util')
|
||||
// the following will be resolved via custom ivy repository declared in root build.gradle
|
||||
referenceTestImplementation 'ethereum:execution-spec-tests:0.2.5:fixtures@tar.gz'
|
||||
referenceTestImplementation 'ethereum:execution-spec-tests:2.1.1:fixtures@tar.gz'
|
||||
referenceTestImplementation 'com.fasterxml.jackson.core:jackson-databind'
|
||||
referenceTestImplementation 'com.google.guava:guava'
|
||||
referenceTestImplementation 'io.tmio:tuweni-bytes'
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.hyperledger.besu.ethereum.vm.executionspec;
|
||||
|
||||
import static org.hyperledger.besu.ethereum.vm.GeneralStateReferenceTestTools.executeTest;
|
||||
import static org.hyperledger.besu.ethereum.vm.GeneralStateReferenceTestTools.generateTestParametersForConfig;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
import org.hyperledger.besu.ethereum.referencetests.GeneralStateTestCaseEipSpec;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
/** The general state test operation testing framework entry point. */
|
||||
public class %%TESTS_NAME%% {
|
||||
|
||||
private static final String[] TEST_CONFIG_FILE_DIR_PATH = new String[] {%%TESTS_FILE%%};
|
||||
|
||||
public static Stream<Arguments> getTestParametersForConfig() {
|
||||
return generateTestParametersForConfig(TEST_CONFIG_FILE_DIR_PATH).stream().map(params ->
|
||||
Arguments.of(params[0], params[1], params[2])
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "Name: {0}")
|
||||
@MethodSource("getTestParametersForConfig")
|
||||
public void execution(
|
||||
final String name,
|
||||
final GeneralStateTestCaseEipSpec spec,
|
||||
final boolean runTest) {
|
||||
assumeTrue(runTest, "Test " + name + " was ignored");
|
||||
executeTest(spec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.hyperledger.besu.ethereum.vm.executionspec;
|
||||
|
||||
import static org.hyperledger.besu.ethereum.vm.BlockchainReferenceTestTools.executeTest;
|
||||
import static org.hyperledger.besu.ethereum.vm.BlockchainReferenceTestTools.generateTestParametersForConfig;
|
||||
|
||||
import org.hyperledger.besu.ethereum.referencetests.BlockchainReferenceTestCaseSpec;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
/** The blockchain test operation testing framework entry point. */
|
||||
public class %%TESTS_NAME%% {
|
||||
|
||||
private static final String[] TEST_CONFIG_FILE_DIR_PATH = new String[] {%%TESTS_FILE%%};
|
||||
|
||||
public static Stream<Arguments> getTestParametersForConfig() {
|
||||
return generateTestParametersForConfig(TEST_CONFIG_FILE_DIR_PATH).stream().map(params ->
|
||||
Arguments.of(params[0], params[1], params[2])
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "Name: {0}")
|
||||
@MethodSource("getTestParametersForConfig")
|
||||
public void execution(
|
||||
final String name,
|
||||
final BlockchainReferenceTestCaseSpec spec,
|
||||
final boolean runTest) {
|
||||
assumeTrue(runTest, "Test " + name + " was ignored");
|
||||
executeTest(spec);
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ dependencies {
|
||||
implementation 'tech.pegasys:jc-kzg-4844'
|
||||
|
||||
compileOnly 'com.fasterxml.jackson.core:jackson-databind'
|
||||
compileOnly 'io.vertx:vertx-core'
|
||||
|
||||
testImplementation 'com.fasterxml.jackson.core:jackson-databind'
|
||||
testImplementation 'info.picocli:picocli'
|
||||
|
||||
@@ -33,6 +33,8 @@ import org.hyperledger.besu.evm.operation.AddModOperation;
|
||||
import org.hyperledger.besu.evm.operation.AddOperation;
|
||||
import org.hyperledger.besu.evm.operation.AddressOperation;
|
||||
import org.hyperledger.besu.evm.operation.AndOperation;
|
||||
import org.hyperledger.besu.evm.operation.AuthCallOperation;
|
||||
import org.hyperledger.besu.evm.operation.AuthOperation;
|
||||
import org.hyperledger.besu.evm.operation.BalanceOperation;
|
||||
import org.hyperledger.besu.evm.operation.BaseFeeOperation;
|
||||
import org.hyperledger.besu.evm.operation.BlobBaseFeeOperation;
|
||||
@@ -1012,6 +1014,10 @@ public class MainnetEVMs {
|
||||
final GasCalculator gasCalculator,
|
||||
final BigInteger chainID) {
|
||||
registerCancunOperations(registry, gasCalculator, chainID);
|
||||
|
||||
// EIP-3074 AUTH and AUTHCALL
|
||||
registry.put(new AuthOperation(gasCalculator));
|
||||
registry.put(new AuthCallOperation(gasCalculator));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -247,6 +247,9 @@ public class MessageFrame {
|
||||
/** The mark of the undoable collections at the creation of this message frame */
|
||||
private final long undoMark;
|
||||
|
||||
/** mutated by AUTH operation */
|
||||
private Address authorizedBy = null;
|
||||
|
||||
/**
|
||||
* Builder builder.
|
||||
*
|
||||
@@ -1371,6 +1374,24 @@ public class MessageFrame {
|
||||
return txValues.versionedHashes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for address that authorized future AUTHCALLs.
|
||||
*
|
||||
* @return the revert reason
|
||||
*/
|
||||
public Address getAuthorizedBy() {
|
||||
return authorizedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutator for address that authorizes future AUTHCALLs, set by AUTH opcode
|
||||
*
|
||||
* @param authorizedBy the address that authorizes future AUTHCALLs
|
||||
*/
|
||||
public void setAuthorizedBy(final Address authorizedBy) {
|
||||
this.authorizedBy = authorizedBy;
|
||||
}
|
||||
|
||||
/** Reset. */
|
||||
public void reset() {
|
||||
maybeUpdatedMemory = Optional.empty();
|
||||
|
||||
@@ -210,6 +210,35 @@ public interface GasCalculator {
|
||||
Address contract,
|
||||
boolean accountIsWarm);
|
||||
|
||||
/**
|
||||
* Returns the gas cost for AUTHCALL.
|
||||
*
|
||||
* @param frame The current frame
|
||||
* @param stipend The gas stipend being provided by the CALL caller
|
||||
* @param inputDataOffset The offset in memory to retrieve the CALL input data
|
||||
* @param inputDataLength The CALL input data length
|
||||
* @param outputDataOffset The offset in memory to place the CALL output data
|
||||
* @param outputDataLength The CALL output data length
|
||||
* @param transferValue The wei being transferred
|
||||
* @param invoker The contract calling out on behalf of the authority
|
||||
* @param invokee The address of the recipient (never null)
|
||||
* @param accountIsWarm The address of the contract is "warm" as per EIP-2929
|
||||
* @return The gas cost for the CALL operation
|
||||
*/
|
||||
default long authCallOperationGasCost(
|
||||
final MessageFrame frame,
|
||||
final long stipend,
|
||||
final long inputDataOffset,
|
||||
final long inputDataLength,
|
||||
final long outputDataOffset,
|
||||
final long outputDataLength,
|
||||
final Wei transferValue,
|
||||
final Account invoker,
|
||||
final Address invokee,
|
||||
final boolean accountIsWarm) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets additional call stipend.
|
||||
*
|
||||
@@ -617,4 +646,18 @@ public interface GasCalculator {
|
||||
default long computeExcessBlobGas(final long parentExcessBlobGas, final long blobGasUsed) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gas cost of validating an auth commitment for an AUTHCALL
|
||||
*
|
||||
* @param frame the current frame, with memory to be read from
|
||||
* @param offset start of memory read
|
||||
* @param length amount of memory read
|
||||
* @param authority address to check for warmup
|
||||
* @return total gas cost for the operation
|
||||
*/
|
||||
default long authOperationGasCost(
|
||||
final MessageFrame frame, final long offset, final long length, final Address authority) {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,11 @@ package org.hyperledger.besu.evm.gascalculator;
|
||||
|
||||
import static org.hyperledger.besu.datatypes.Address.KZG_POINT_EVAL;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
|
||||
/**
|
||||
* Gas Calculator for Prague
|
||||
*
|
||||
@@ -27,6 +32,8 @@ import static org.hyperledger.besu.datatypes.Address.KZG_POINT_EVAL;
|
||||
* </UL>
|
||||
*/
|
||||
public class PragueGasCalculator extends CancunGasCalculator {
|
||||
private final int AUTH_OP_FIXED_FEE = 3100;
|
||||
private final long AUTH_CALL_VALUE_TRANSFER_GAS_COST = 6700;
|
||||
|
||||
/** Instantiates a new Prague Gas Calculator. */
|
||||
public PragueGasCalculator() {
|
||||
@@ -41,4 +48,55 @@ public class PragueGasCalculator extends CancunGasCalculator {
|
||||
protected PragueGasCalculator(final int maxPrecompile) {
|
||||
super(maxPrecompile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long authOperationGasCost(
|
||||
final MessageFrame frame, final long offset, final long length, final Address authority) {
|
||||
final long memoryExpansionGasCost = memoryExpansionGasCost(frame, offset, length);
|
||||
final long accessFee = frame.isAddressWarm(authority) ? 100 : 2600;
|
||||
final long gasCost = AUTH_OP_FIXED_FEE + memoryExpansionGasCost + accessFee;
|
||||
return gasCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gas cost to call another contract on behalf of an authority
|
||||
*
|
||||
* @return the gas cost to call another contract on behalf of an authority
|
||||
*/
|
||||
@Override
|
||||
public long authCallOperationGasCost(
|
||||
final MessageFrame frame,
|
||||
final long stipend,
|
||||
final long inputDataOffset,
|
||||
final long inputDataLength,
|
||||
final long outputDataOffset,
|
||||
final long outputDataLength,
|
||||
final Wei transferValue,
|
||||
final Account invoker,
|
||||
final Address invokee,
|
||||
final boolean accountIsWarm) {
|
||||
|
||||
final long inputDataMemoryExpansionCost =
|
||||
memoryExpansionGasCost(frame, inputDataOffset, inputDataLength);
|
||||
final long outputDataMemoryExpansionCost =
|
||||
memoryExpansionGasCost(frame, outputDataOffset, outputDataLength);
|
||||
final long memoryExpansionCost =
|
||||
Math.max(inputDataMemoryExpansionCost, outputDataMemoryExpansionCost);
|
||||
|
||||
final long staticGasCost = getWarmStorageReadCost();
|
||||
|
||||
long dynamicGasCost = accountIsWarm ? 0 : getColdAccountAccessCost() - getWarmStorageReadCost();
|
||||
|
||||
if (!transferValue.isZero()) {
|
||||
dynamicGasCost += AUTH_CALL_VALUE_TRANSFER_GAS_COST;
|
||||
}
|
||||
|
||||
if ((invoker == null || invoker.isEmpty()) && !transferValue.isZero()) {
|
||||
dynamicGasCost += newAccountGasCost();
|
||||
}
|
||||
|
||||
long cost = staticGasCost + memoryExpansionCost + dynamicGasCost;
|
||||
|
||||
return cost;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* 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.evm.operation;
|
||||
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedToLong;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.evm.EVM;
|
||||
import org.hyperledger.besu.evm.frame.ExceptionalHaltReason;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
import org.hyperledger.besu.evm.internal.Words;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
|
||||
/** Introduced via EIP-3074 to call another contract with a different authorization context. */
|
||||
public class AuthCallOperation extends AbstractCallOperation {
|
||||
|
||||
/**
|
||||
* Instantiates a new AuthCallOperation.
|
||||
*
|
||||
* @param gasCalculator a Prague or later gas calculator
|
||||
*/
|
||||
public AuthCallOperation(final GasCalculator gasCalculator) {
|
||||
super(0xF7, "AUTHCALL", 7, 1, gasCalculator);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Address to(final MessageFrame frame) {
|
||||
return Words.toAddress(frame.getStackItem(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Wei value(final MessageFrame frame) {
|
||||
return Wei.wrap(frame.getStackItem(2));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Wei apparentValue(final MessageFrame frame) {
|
||||
return value(frame);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long inputDataOffset(final MessageFrame frame) {
|
||||
return clampedToLong(frame.getStackItem(3));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long inputDataLength(final MessageFrame frame) {
|
||||
return clampedToLong(frame.getStackItem(4));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long outputDataOffset(final MessageFrame frame) {
|
||||
return clampedToLong(frame.getStackItem(5));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long outputDataLength(final MessageFrame frame) {
|
||||
return clampedToLong(frame.getStackItem(6));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Address address(final MessageFrame frame) {
|
||||
return to(frame);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Address sender(final MessageFrame frame) {
|
||||
return frame.getAuthorizedBy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long gasAvailableForChildCall(final MessageFrame frame) {
|
||||
return gasCalculator().gasAvailableForChildCall(frame, gas(frame), !value(frame).isZero());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationResult execute(final MessageFrame frame, final EVM evm) {
|
||||
if (frame.isStatic() && !value(frame).isZero()) {
|
||||
return new OperationResult(cost(frame, true), ExceptionalHaltReason.ILLEGAL_STATE_CHANGE);
|
||||
} else if (frame.getAuthorizedBy() != null) {
|
||||
return super.execute(frame, evm);
|
||||
} else {
|
||||
frame.pushStackItem(Bytes32.ZERO);
|
||||
return new OperationResult(cost(frame, true), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* 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.evm.operation;
|
||||
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedToLong;
|
||||
|
||||
import org.hyperledger.besu.crypto.Hash;
|
||||
import org.hyperledger.besu.crypto.SECPPublicKey;
|
||||
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.evm.EVM;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
import org.hyperledger.besu.evm.internal.Words;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** The AUTH operation. */
|
||||
public class AuthOperation extends AbstractOperation {
|
||||
|
||||
/** The constant MAGIC defined by EIP-3074 */
|
||||
public static final byte MAGIC = 0x4;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuthOperation.class);
|
||||
|
||||
private static final SignatureAlgorithm signatureAlgorithm =
|
||||
SignatureAlgorithmFactory.getInstance();
|
||||
|
||||
/**
|
||||
* Instantiates a new AuthOperation.
|
||||
*
|
||||
* @param gasCalculator a Prague or later gas calculator
|
||||
*/
|
||||
public AuthOperation(final GasCalculator gasCalculator) {
|
||||
super(0xF6, "AUTH", 3, 1, gasCalculator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationResult execute(final MessageFrame frame, final EVM evm) {
|
||||
// create authority from stack
|
||||
Address authority = Words.toAddress(frame.getStackItem(0));
|
||||
long offset = clampedToLong(frame.getStackItem(1));
|
||||
long length = clampedToLong(frame.getStackItem(2));
|
||||
|
||||
byte yParity = frame.readMemory(offset, 1).get(0);
|
||||
Bytes32 r = Bytes32.wrap(frame.readMemory(offset + 1, 32));
|
||||
Bytes32 s = Bytes32.wrap(frame.readMemory(offset + 33, 32));
|
||||
Bytes32 commit = Bytes32.wrap(frame.readMemory(offset + 65, 32));
|
||||
Bytes32 invoker = Bytes32.leftPad(frame.getContractAddress());
|
||||
Bytes32 senderNonce =
|
||||
Bytes32.leftPad(
|
||||
Bytes.ofUnsignedLong(frame.getWorldUpdater().getAccount(authority).getNonce()));
|
||||
if (evm.getChainId().isEmpty()) {
|
||||
frame.pushStackItem(UInt256.ZERO);
|
||||
LOG.error("ChainId is not set");
|
||||
return new OperationResult(0, null);
|
||||
}
|
||||
Bytes authPreImage =
|
||||
Bytes.concatenate(
|
||||
Bytes.ofUnsignedShort(MAGIC), evm.getChainId().get(), senderNonce, invoker, commit);
|
||||
Bytes32 messageHash = Hash.keccak256(authPreImage);
|
||||
|
||||
final long gasCost =
|
||||
super.gasCalculator().authOperationGasCost(frame, offset, length, authority);
|
||||
Optional<SECPPublicKey> publicKey;
|
||||
try {
|
||||
SECPSignature signature =
|
||||
signatureAlgorithm.createSignature(
|
||||
r.toUnsignedBigInteger(), s.toUnsignedBigInteger(), yParity);
|
||||
publicKey = signatureAlgorithm.recoverPublicKeyFromSignature(messageHash, signature);
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
||||
frame.pushStackItem(UInt256.ZERO);
|
||||
return new OperationResult(gasCost, null);
|
||||
}
|
||||
if (publicKey.isPresent()) {
|
||||
Address signerAddress = Address.extract(publicKey.get());
|
||||
if (signerAddress.equals(authority)) {
|
||||
frame.setAuthorizedBy(authority);
|
||||
frame.pushStackItem(UInt256.ONE);
|
||||
} else {
|
||||
frame.pushStackItem(UInt256.ZERO);
|
||||
}
|
||||
} else {
|
||||
frame.pushStackItem(UInt256.ZERO);
|
||||
}
|
||||
return new OperationResult(gasCost, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* 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.evm.gascalculator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.account.MutableAccount;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class PragueGasCalculatorTest {
|
||||
@Test
|
||||
public void testAuthOperationGasCost() {
|
||||
PragueGasCalculator pragueGasCalculator = new PragueGasCalculator();
|
||||
MessageFrame runningIn = mock(MessageFrame.class);
|
||||
Address authority = Address.fromHexString("0xdeadbeef");
|
||||
when(runningIn.isAddressWarm(authority)).thenReturn(true);
|
||||
long gasSpent = pragueGasCalculator.authOperationGasCost(runningIn, 0, 97, authority);
|
||||
assertEquals(
|
||||
3100 + 100 + pragueGasCalculator.memoryExpansionGasCost(runningIn, 0, 97), gasSpent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthCallOperationGasCostWithTransfer() {
|
||||
PragueGasCalculator pragueGasCalculator = new PragueGasCalculator();
|
||||
MessageFrame runningIn = mock(MessageFrame.class);
|
||||
Account invoker = mock(MutableAccount.class);
|
||||
when(invoker.getAddress()).thenReturn(Address.fromHexString("0xCafeBabe"));
|
||||
Address invokee = Address.fromHexString("0xdeadbeef");
|
||||
when(runningIn.isAddressWarm(invokee)).thenReturn(true);
|
||||
long gasSpentInAuthCall =
|
||||
pragueGasCalculator.authCallOperationGasCost(
|
||||
runningIn, 63, 0, 97, 100, 97, Wei.ONE, invoker, invokee, true);
|
||||
long gasSpentInCall =
|
||||
pragueGasCalculator.callOperationGasCost(
|
||||
runningIn, 63, 0, 97, 100, 97, Wei.ONE, invoker, invokee, true);
|
||||
assertEquals(gasSpentInCall - 2300, gasSpentInAuthCall);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthCallOperationGasCostNoTransfer() {
|
||||
PragueGasCalculator pragueGasCalculator = new PragueGasCalculator();
|
||||
MessageFrame runningIn = mock(MessageFrame.class);
|
||||
Account invoker = mock(MutableAccount.class);
|
||||
when(invoker.getAddress()).thenReturn(Address.fromHexString("0xCafeBabe"));
|
||||
Address invokee = Address.fromHexString("0xdeadbeef");
|
||||
when(runningIn.isAddressWarm(invokee)).thenReturn(true);
|
||||
long gasSpentInAuthCall =
|
||||
pragueGasCalculator.authCallOperationGasCost(
|
||||
runningIn, 63, 0, 97, 100, 97, Wei.ZERO, invoker, invokee, true);
|
||||
long gasSpentInCall =
|
||||
pragueGasCalculator.callOperationGasCost(
|
||||
runningIn, 63, 0, 97, 100, 97, Wei.ZERO, invoker, invokee, true);
|
||||
assertEquals(gasSpentInCall, gasSpentInAuthCall);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* 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.evm.operations;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.crypto.Hash;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
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.evm.EVM;
|
||||
import org.hyperledger.besu.evm.account.MutableAccount;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
|
||||
import org.hyperledger.besu.evm.operation.AuthOperation;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class AuthOperationTest {
|
||||
|
||||
@Test
|
||||
public void testAuthOperation() {
|
||||
SignatureAlgorithm algo = SignatureAlgorithmFactory.getInstance();
|
||||
KeyPair keys = algo.generateKeyPair();
|
||||
Address authingAddress = Address.extract(keys.getPublicKey());
|
||||
EVM fakeEVM = mock(EVM.class);
|
||||
|
||||
Optional<Bytes> chainId = Optional.of(Bytes.of(1));
|
||||
when(fakeEVM.getChainId()).thenReturn(chainId);
|
||||
long senderNonce = 0;
|
||||
Address invokerAddress = Address.fromHexString("0xdeadbeef");
|
||||
Bytes32 invoker = Bytes32.leftPad(invokerAddress);
|
||||
Bytes32 contractCommitment = Bytes32.leftPad(Bytes.fromHexString("0x1234"));
|
||||
Bytes authPreImage =
|
||||
Bytes.concatenate(
|
||||
Bytes.ofUnsignedShort(AuthOperation.MAGIC),
|
||||
chainId.get(),
|
||||
Bytes32.leftPad(Bytes.ofUnsignedLong(senderNonce)),
|
||||
invoker,
|
||||
contractCommitment);
|
||||
Bytes32 messageHash = Hash.keccak256(authPreImage);
|
||||
SECPSignature signature = algo.sign(messageHash, keys);
|
||||
|
||||
MessageFrame frame = mock(MessageFrame.class);
|
||||
when(frame.getContractAddress()).thenReturn(invokerAddress);
|
||||
MutableAccount authingAccount = mock(MutableAccount.class);
|
||||
when(authingAccount.getAddress()).thenReturn(authingAddress);
|
||||
when(authingAccount.getNonce()).thenReturn(senderNonce);
|
||||
|
||||
WorldUpdater state = mock(WorldUpdater.class);
|
||||
|
||||
when(state.getAccount(authingAddress)).thenReturn(authingAccount);
|
||||
|
||||
when(frame.getWorldUpdater()).thenReturn(state);
|
||||
|
||||
when(frame.getSenderAddress()).thenReturn(authingAddress);
|
||||
when(state.getSenderAccount(frame)).thenReturn(authingAccount);
|
||||
when(frame.getStackItem(0)).thenReturn(authingAddress);
|
||||
when(frame.getStackItem(1)).thenReturn(Bytes.of(0));
|
||||
when(frame.getStackItem(2)).thenReturn(Bytes.of(97));
|
||||
Bytes encodedSignature = signature.encodedBytes();
|
||||
when(frame.readMemory(0, 1)).thenReturn(encodedSignature.slice(64, 1));
|
||||
when(frame.readMemory(1, 32)).thenReturn(Bytes32.wrap(encodedSignature.slice(0, 32).toArray()));
|
||||
when(frame.readMemory(33, 32))
|
||||
.thenReturn(Bytes32.wrap(encodedSignature.slice(32, 32).toArray()));
|
||||
when(frame.readMemory(65, 32)).thenReturn(contractCommitment);
|
||||
|
||||
AuthOperation authOperation = new AuthOperation(new PragueGasCalculator());
|
||||
authOperation.execute(frame, fakeEVM);
|
||||
verify(frame).setAuthorizedBy(authingAddress);
|
||||
verify(frame).pushStackItem(UInt256.ONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthOperationNegative() {
|
||||
SignatureAlgorithm algo = SignatureAlgorithmFactory.getInstance();
|
||||
KeyPair keys = algo.generateKeyPair();
|
||||
Address authingAddress = Address.extract(keys.getPublicKey());
|
||||
EVM fakeEVM = mock(EVM.class);
|
||||
|
||||
Optional<Bytes> chainId = Optional.of(Bytes.of(1));
|
||||
when(fakeEVM.getChainId()).thenReturn(chainId);
|
||||
long senderNonce = 0;
|
||||
Address invokerAddress = Address.fromHexString("0xdeadbeef");
|
||||
Bytes32 invoker = Bytes32.leftPad(invokerAddress);
|
||||
Bytes32 contractCommitment = Bytes32.leftPad(Bytes.fromHexString("0x1234"));
|
||||
Bytes authPreImage =
|
||||
Bytes.concatenate(
|
||||
Bytes.ofUnsignedShort(AuthOperation.MAGIC),
|
||||
chainId.get(),
|
||||
Bytes32.leftPad(Bytes.ofUnsignedLong(senderNonce)),
|
||||
invoker,
|
||||
contractCommitment);
|
||||
Bytes32 messageHash = Hash.keccak256(authPreImage);
|
||||
|
||||
// Generate a new key pair to create an incorrect signature
|
||||
KeyPair wrongKeys = algo.generateKeyPair();
|
||||
SECPSignature wrongSignature = algo.sign(messageHash, wrongKeys);
|
||||
|
||||
MessageFrame frame = mock(MessageFrame.class);
|
||||
when(frame.getContractAddress()).thenReturn(invokerAddress);
|
||||
MutableAccount authingAccount = mock(MutableAccount.class);
|
||||
when(authingAccount.getAddress()).thenReturn(authingAddress);
|
||||
when(authingAccount.getNonce()).thenReturn(senderNonce);
|
||||
|
||||
WorldUpdater state = mock(WorldUpdater.class);
|
||||
|
||||
when(state.getAccount(authingAddress)).thenReturn(authingAccount);
|
||||
|
||||
when(frame.getWorldUpdater()).thenReturn(state);
|
||||
|
||||
when(frame.getSenderAddress()).thenReturn(authingAddress);
|
||||
when(state.getSenderAccount(frame)).thenReturn(authingAccount);
|
||||
when(frame.getStackItem(0)).thenReturn(authingAddress);
|
||||
when(frame.getStackItem(1)).thenReturn(Bytes.of(0));
|
||||
when(frame.getStackItem(2)).thenReturn(Bytes.of(97));
|
||||
Bytes encodedSignature = wrongSignature.encodedBytes(); // Use the wrong signature
|
||||
when(frame.readMemory(0, 1)).thenReturn(encodedSignature.slice(64, 1));
|
||||
when(frame.readMemory(1, 32)).thenReturn(Bytes32.wrap(encodedSignature.slice(0, 32).toArray()));
|
||||
when(frame.readMemory(33, 32))
|
||||
.thenReturn(Bytes32.wrap(encodedSignature.slice(32, 32).toArray()));
|
||||
when(frame.readMemory(65, 32)).thenReturn(contractCommitment);
|
||||
|
||||
AuthOperation authOperation = new AuthOperation(new PragueGasCalculator());
|
||||
authOperation.execute(frame, fakeEVM);
|
||||
verify(frame, never()).setAuthorizedBy(authingAddress); // The address should not be authorized
|
||||
verify(frame).pushStackItem(UInt256.ZERO); // The stack should contain UInt256.ZERO
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* 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.evm.processor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.hyperledger.besu.crypto.Hash;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
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.Wei;
|
||||
import org.hyperledger.besu.evm.EVM;
|
||||
import org.hyperledger.besu.evm.MainnetEVMs;
|
||||
import org.hyperledger.besu.evm.fluent.EVMExecutor;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.evm.operation.AuthOperation;
|
||||
import org.hyperledger.besu.evm.toy.ToyWorld;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
public class AuthCallProcessorTest extends MessageCallProcessorTest {
|
||||
|
||||
MessageCallProcessor spyingMessageCallProcessor;
|
||||
ArgumentCaptor<MessageFrame> frameCaptor = ArgumentCaptor.forClass(MessageFrame.class);
|
||||
|
||||
WorldUpdater toyWorld = new ToyWorld();
|
||||
|
||||
@Test
|
||||
public void authCallHappyPath() {
|
||||
final EVM pragueEVM =
|
||||
MainnetEVMs.prague(new PragueGasCalculator(), BigInteger.ONE, EvmConfiguration.DEFAULT);
|
||||
final EVMExecutor executor = EVMExecutor.evm(pragueEVM);
|
||||
this.spyingMessageCallProcessor =
|
||||
spy(new MessageCallProcessor(pragueEVM, precompileContractRegistry));
|
||||
executor.messageCallProcessor(this.spyingMessageCallProcessor);
|
||||
|
||||
executor.worldUpdater(toyWorld);
|
||||
executor.gas(10_000_000_000L);
|
||||
|
||||
SignatureAlgorithm algo = SignatureAlgorithmFactory.getInstance();
|
||||
KeyPair keys = algo.generateKeyPair();
|
||||
Optional<Bytes> chainId = Optional.of(Bytes.of(1));
|
||||
long senderNonce = 0;
|
||||
Address invokerAddress = Address.fromHexString("0xdeadbeef");
|
||||
Bytes32 invoker = Bytes32.leftPad(invokerAddress);
|
||||
Bytes32 contractCommitment = Bytes32.leftPad(Bytes.fromHexString("0x1234"));
|
||||
Bytes authPreImage =
|
||||
Bytes.concatenate(
|
||||
Bytes.ofUnsignedShort(AuthOperation.MAGIC),
|
||||
Bytes32.leftPad(chainId.get()),
|
||||
Bytes32.leftPad(Bytes.ofUnsignedLong(senderNonce)),
|
||||
invoker,
|
||||
contractCommitment);
|
||||
Bytes32 messageHash = Hash.keccak256(authPreImage);
|
||||
SECPSignature signature = algo.sign(messageHash, keys);
|
||||
Bytes encodedSignature = signature.encodedBytes();
|
||||
|
||||
Bytes authParam =
|
||||
Bytes.concatenate(
|
||||
encodedSignature.slice(64, 1), // y parity
|
||||
encodedSignature.slice(0, 32), // r
|
||||
encodedSignature.slice(32, 32), // s
|
||||
contractCommitment);
|
||||
|
||||
toyWorld.createAccount(
|
||||
Address.extract(keys.getPublicKey()), 0, Wei.MAX_WEI); // initialize authority account
|
||||
toyWorld.createAccount(invokerAddress, 0, Wei.MAX_WEI); // initialize invoker account
|
||||
final Bytes codeBytes =
|
||||
Bytes.fromHexString(
|
||||
"0x"
|
||||
+ "6061" // push 97 the calldata length
|
||||
+ "6000" // push 0 the offset
|
||||
+ "6000" // push 0 the destination offset
|
||||
+ "37" // calldatacopy 97 bytes of the auth param to mem 0
|
||||
+ "6061" // param is 97 bytes (0x61)
|
||||
+ "6000" // push 0 where in mem to find auth param
|
||||
+ "73" // push next 20 bytes for the authority address
|
||||
+ Address.extract(keys.getPublicKey())
|
||||
.toUnprefixedHexString() // push authority address
|
||||
+ "F6" // AUTH call, should work and set authorizedBy on the frame
|
||||
+ "6000" // push 0 for return length, we don't care about the return
|
||||
+ "6000" // push 0 for return offset, we don't care about the return
|
||||
+ "6000" // push 0 for input length
|
||||
+ "6000" // push 0 for input offset
|
||||
+ "60FF" // push 255 for the value being sent
|
||||
+ "73deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" // push20 the invokee address
|
||||
+ "60FF" // push 255 gas
|
||||
+ "F7"); // AUTHCALL, should work
|
||||
executor.contract(invokerAddress);
|
||||
executor.execute(codeBytes, authParam, Wei.ZERO, invokerAddress);
|
||||
verify(this.spyingMessageCallProcessor, times(2))
|
||||
.start(frameCaptor.capture(), any()); // one for parent frame, one for child
|
||||
List<MessageFrame> frames = frameCaptor.getAllValues();
|
||||
assertThat(frames.get(0).getStackItem(0)).isEqualTo((Bytes.of(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unauthorizedAuthCall() {
|
||||
final EVM pragueEVM =
|
||||
MainnetEVMs.prague(new PragueGasCalculator(), BigInteger.ONE, EvmConfiguration.DEFAULT);
|
||||
final EVMExecutor executor = EVMExecutor.evm(pragueEVM);
|
||||
this.spyingMessageCallProcessor =
|
||||
spy(new MessageCallProcessor(pragueEVM, precompileContractRegistry));
|
||||
executor.messageCallProcessor(this.spyingMessageCallProcessor);
|
||||
|
||||
executor.gas(10_000_000_000L);
|
||||
|
||||
final Bytes codeBytes =
|
||||
Bytes.fromHexString(
|
||||
"0x"
|
||||
+ "6000" // push 0 for return length
|
||||
+ "6000" // push 0 for return offset
|
||||
+ "6000" // push 0 for input length
|
||||
+ "6000" // push 0 for input offset
|
||||
+ "60FF" // push 255 for the value being sent
|
||||
+ "73deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" // push20 the invokee address
|
||||
+ "60FF" // push 255 gas
|
||||
+ "F7"); // AUTHCALL without prior AUTH, should fail
|
||||
|
||||
executor.execute(codeBytes, Bytes.EMPTY, Wei.ZERO, Address.ZERO);
|
||||
verify(this.spyingMessageCallProcessor).start(frameCaptor.capture(), any());
|
||||
assertThat(frameCaptor.getValue().getStackItem(0)).isEqualTo(Bytes32.ZERO);
|
||||
}
|
||||
}
|
||||
15
gradle/spotless/sh.license
Normal file
15
gradle/spotless/sh.license
Normal file
@@ -0,0 +1,15 @@
|
||||
##
|
||||
## Copyright contributors to Hyperledger Besu.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<verification-metadata xmlns="https://schema.gradle.org/dependency-verification" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://schema.gradle.org/dependency-verification https://schema.gradle.org/dependency-verification/dependency-verification-1.1.xsd">
|
||||
<verification-metadata xmlns="https://schema.gradle.org/dependency-verification" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://schema.gradle.org/dependency-verification https://schema.gradle.org/dependency-verification/dependency-verification-1.3.xsd">
|
||||
<configuration>
|
||||
<verify-metadata>true</verify-metadata>
|
||||
<verify-signatures>false</verify-signatures>
|
||||
@@ -1417,6 +1417,11 @@
|
||||
<sha256 value="1c67818ff9ad052f2da636c1f2e99fbb801191e56af9f1ee1ebe3997039d8186" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="ethereum" name="execution-spec-tests" version="2.1.1">
|
||||
<artifact name="execution-spec-tests-2.1.1-fixtures.tar.gz">
|
||||
<sha256 value="817ca59a93dae2cd6458f015dfbc604d234bcbeca63ffe763bd5b5e27ff3c1a1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="info.picocli" name="picocli" version="3.0.0">
|
||||
<artifact name="picocli-3.0.0.jar">
|
||||
<sha256 value="22dbbe287dd0ab9d4d519ac9f2dd909537b6daf279ac5962a3bad8c9dae61032" origin="Generated by Gradle"/>
|
||||
@@ -6729,6 +6734,14 @@
|
||||
<sha256 value="431e29ab42454963fbd96489bbf17f94ae04ed88c0dd42fb131eb0cd18d8d45f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="abi" version="4.11.3">
|
||||
<artifact name="abi-4.11.3.jar">
|
||||
<sha256 value="75d38eaaee59a15c8d214558773e26434dce762a20bbe39509dbd1de060056d8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="abi-4.11.3.module">
|
||||
<sha256 value="2741e515b00b70f4fdb34cc5b6a14e00fe910dcdc499d83e62a1c73451273a8f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="besu" version="4.11.1">
|
||||
<artifact name="besu-4.11.1.jar">
|
||||
<sha256 value="8eacd74876424b43217b0960ac5eb8c7ade08c9db87ed0e397db4dc343d5905e" origin="Generated by Gradle"/>
|
||||
@@ -6748,6 +6761,14 @@
|
||||
<sha256 value="124e7f9b57bc3f089fa87955263bb59fbf7c4f8f982134ee5ef23ecf6f59d1d9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="codegen" version="4.11.3">
|
||||
<artifact name="codegen-4.11.3.jar">
|
||||
<sha256 value="405c75be4512e0cfee6ecc2f6f6dcd81cca4150d54ac327adcacc7548859dcad" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="codegen-4.11.3.module">
|
||||
<sha256 value="aad7c74e8152c70ce82919c04d8150183c9d1ee9f71494ad6c8fc002ecac0d6e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="core" version="4.11.1">
|
||||
<artifact name="core-4.11.1.jar">
|
||||
<sha256 value="ed1ce6473363c9cf12a4348b25f82a5f483008554c1b4b1d08927d00418b46ad" origin="Generated by Gradle"/>
|
||||
@@ -6759,6 +6780,17 @@
|
||||
<sha256 value="88cc978e3b25e50205a9c1bebee59853055c9a69a92603ed8e48deb36110b146" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="core" version="4.11.3">
|
||||
<artifact name="core-4.11.3.jar">
|
||||
<sha256 value="bfb9fa4b9e3b2cf00ab7ffcddae8f49c03f688c17cbb1ae244938a77df89cf69" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="core-4.11.3.module">
|
||||
<sha256 value="cb1fe9e0c07512b073b8622b55fa4d5788c7a9e3cd641ddc8b0031d813188d6a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="core-4.11.3.pom">
|
||||
<sha256 value="26355b7e2b607ce39b7e760a54752af532299d36476fccdb477f783d28b3e012" origin="Manually calculated"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="crypto" version="4.11.1">
|
||||
<artifact name="crypto-4.11.1.jar">
|
||||
<sha256 value="a9a1dfaf939f3edbc54e4bdfdac1c01ef348e030931693e80588a759d736d34d" origin="Generated by Gradle"/>
|
||||
@@ -6770,6 +6802,14 @@
|
||||
<sha256 value="5b3e74fad58249cadc85d59f20671fb4e72e8b5f879ca600a54ac97ae1d6d32f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="crypto" version="4.11.3">
|
||||
<artifact name="crypto-4.11.3.jar">
|
||||
<sha256 value="56d1a73e4c86b1761197c47ee454c0ef21277a724326cc82b880362afd6ec649" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="crypto-4.11.3.module">
|
||||
<sha256 value="b523302e3162b2b684c23e8be2e4dc01bfda02daafe076580e82f276658cf321" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="eea" version="4.11.1">
|
||||
<artifact name="eea-4.11.1.jar">
|
||||
<sha256 value="225ba6fec472713b3a244f000e0f546ac91cded024e15100fdceae1ef1e6302c" origin="Generated by Gradle"/>
|
||||
@@ -6786,6 +6826,11 @@
|
||||
<sha256 value="69362036600d0c7af500d32df8112feb37a7bd7708d595850f7187819ddebc12" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="org.web3j.gradle.plugin" version="4.11.3">
|
||||
<artifact name="org.web3j.gradle.plugin-4.11.3.pom">
|
||||
<sha256 value="a065f1d06d08b17f47b36477c81d648fcdd3c0f0d90c83165d5651519fcf2f00" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="rlp" version="4.11.1">
|
||||
<artifact name="rlp-4.11.1.jar">
|
||||
<sha256 value="e593c5db565ca15b91b9fab32bdf11146473f84f71ef51d5e41b8df907db613b" origin="Generated by Gradle"/>
|
||||
@@ -6797,6 +6842,14 @@
|
||||
<sha256 value="035584ab1c92fe7eb3a7552f564439df92f193e087cd7410411f15d2dacf036e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="rlp" version="4.11.3">
|
||||
<artifact name="rlp-4.11.3.jar">
|
||||
<sha256 value="aaf641af237b46811e9738c93fb6fb8102050c535673c91f5b59c5f840f04b29" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="rlp-4.11.3.module">
|
||||
<sha256 value="91a596e4f435c2376c302099292245ddc2a118e2844854f4d3c3d774e5bdb0c5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="tuples" version="4.11.1">
|
||||
<artifact name="tuples-4.11.1.jar">
|
||||
<sha256 value="6bee10ad2ffe1a8cf9d44eabec8fa8ec43cff667de9cc394c37d239823c714cf" origin="Generated by Gradle"/>
|
||||
@@ -6808,6 +6861,17 @@
|
||||
<sha256 value="802662432f85fc7bbb40270a5ac93b998f524554fd085907b1b7cf94b231354c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="tuples" version="4.11.3">
|
||||
<artifact name="tuples-4.11.3.jar">
|
||||
<sha256 value="76bc028e5f57fc92dbf4b971300efd10b32b0b903cf3ccc797a5e62c72bee949" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tuples-4.11.3.module">
|
||||
<sha256 value="9670d5a4e06ed4052ca5b1d4c8f0032c1fd5f7606cfb957e72e124525023b181" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tuples-4.11.3.pom">
|
||||
<sha256 value="cd6bd89a0ea18317caa9bcb29f0e9a6cdb86a39a6eab13732a90c8a5fc26cb06" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="utils" version="4.11.1">
|
||||
<artifact name="utils-4.11.1.jar">
|
||||
<sha256 value="25021db422200ed6e8f7322c02fa1dba5351969ae0e280f069df05d0975b7cde" origin="Generated by Gradle"/>
|
||||
@@ -6819,6 +6883,14 @@
|
||||
<sha256 value="ad937074428d53ee55dd6676bb48021f354f49e61b40f1f8ab88c0e79e5eb774" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="utils" version="4.11.3">
|
||||
<artifact name="utils-4.11.3.jar">
|
||||
<sha256 value="cad81abe5db663f6832a3dde093a545864c39be5a17f22794e61583ff7da4948" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="utils-4.11.3.module">
|
||||
<sha256 value="3e1d9b495dfbc407d0a9b22e7e46953b97d7d71b235409b9cb96531e0b3eb891" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="web3j-gradle-plugin" version="4.11.1">
|
||||
<artifact name="web3j-gradle-plugin-4.11.1.jar">
|
||||
<sha256 value="2a856dbf0350083e8a38eb37cbee8377d4f353a0f5ee64d441593d91637caaa3" origin="Generated by Gradle"/>
|
||||
@@ -6827,6 +6899,14 @@
|
||||
<sha256 value="b276d674bd4c5081bf4918dd2960e1b6a40463d06a9aaf9184c8af11328acc72" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="web3j-gradle-plugin" version="4.11.3">
|
||||
<artifact name="web3j-gradle-plugin-4.11.3.jar">
|
||||
<sha256 value="0d5854f24b1e49e7e3bcead0a5e04d762a2b68fd2a5240414df014d82779fb9e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="web3j-gradle-plugin-4.11.3.module">
|
||||
<sha256 value="2cae6602ee458be8c6d5eb0f474a7069523e3b273c9abe77523041887504e064" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.web3j" name="web3j-sokt" version="0.2.4">
|
||||
<artifact name="web3j-sokt-0.2.4.jar">
|
||||
<sha256 value="45b96e0a5e3dd3fc02bb2e6d9183f825dd31cbb853f120a06b284fd3966db080" origin="Generated by Gradle"/>
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
29
gradlew
vendored
29
gradlew
vendored
@@ -83,10 +83,8 @@ done
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -133,10 +131,13 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
@@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
|
||||
20
gradlew.bat
vendored
20
gradlew.bat
vendored
@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ dependencies {
|
||||
api 'io.tmio:tuweni-units'
|
||||
implementation 'com.google.guava:guava'
|
||||
implementation project(':evm')
|
||||
compileOnly 'io.vertx:vertx-core'
|
||||
}
|
||||
|
||||
configurations { testArtifacts }
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
## Copyright contributors to Hyperledger Besu.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
||||
targets="
|
||||
FlexiblePrivacyGroupManagementInterface
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
#!/bin/bash
|
||||
##
|
||||
## Copyright contributors to Hyperledger Besu.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
||||
status=0
|
||||
while IFS= read -r -a line; do
|
||||
|
||||
Reference in New Issue
Block a user