diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml
index 210889592d7..5b152ec6ee7 100644
--- a/.github/workflows/publish-packages.yml
+++ b/.github/workflows/publish-packages.yml
@@ -26,7 +26,7 @@ jobs:
echo "Import GPG owner trust"
echo ${{ secrets.GPG_OWNERTRUST }} | base64 --decode | gpg --import-ownertrust
- name: Install PPA dependencies
- run: sudo apt-get update && sudo apt-get install debhelper devscripts -y
+ run: sudo apt-get update && sudo apt-get install build-essential debhelper devscripts -y
- name: Submit package
env:
PPA_GPG_KEYID: ${{ secrets.PPA_GPG_KEYID }}
@@ -65,6 +65,8 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install debhelper devscripts ubuntu-dev-tools -y
+ - name: Set up Python
+ uses: actions/setup-python@v5
- name: Install launchpadlib
run: pip install launchpadlib --upgrade
- name: Copy to other series
diff --git a/.github/workflows/sync-supported-chains.yml b/.github/workflows/sync-supported-chains.yml
index 3ca8427a262..4e7047b9298 100644
--- a/.github/workflows/sync-supported-chains.yml
+++ b/.github/workflows/sync-supported-chains.yml
@@ -35,6 +35,7 @@ jobs:
needs: [setup-matrix]
strategy:
fail-fast: false
+ max-parallel: 5
matrix:
config: ${{fromJson(needs.setup-matrix.outputs.matrix)}}
runs-on: ubuntu-latest
@@ -52,13 +53,14 @@ jobs:
linode_token: ${{ secrets.LINODE_TOKEN }}
github_token: "${{ secrets.REPOSITORY_DISPATCH_TOKEN }}"
action: "create"
- runner_label: ${{ matrix.config.network }}-${{ matrix.config.cl }}-${{ github.run_id }}
+ runner_label: t-${{ github.run_id }}-${{ matrix.config.network }}
root_password: ${{ secrets.LINODE_ROOT_PASSWORD }}
machine_type: "${{ matrix.config.agent }}"
image: "linode/ubuntu24.04"
tags: "core, self-hosted, dynamic"
organization: "NethermindEth"
repo_name: "nethermind"
+ blocked_ports: "8545,8546,8551,8552"
sync-chain:
needs: [setup-matrix, create_a_runner]
@@ -68,7 +70,7 @@ jobs:
config: ${{fromJson(needs.setup-matrix.outputs.matrix)}}
name: "Run sync of ${{ matrix.config.network }} chain"
- runs-on: ${{ matrix.config.network }}-${{ matrix.config.cl }}-${{ github.run_id }}
+ runs-on: t-${{ github.run_id }}-${{ matrix.config.network }}
timeout-minutes: ${{ matrix.config.timeout }}
steps:
@@ -102,6 +104,7 @@ jobs:
working-directory: sedge
run: |
docker_image=""
+ network="${{ matrix.config.network }}"
if [ -z "${{ inputs.nethermind_image }}" ]; then
REF_NAME=${{ github.ref }}
@@ -117,37 +120,89 @@ jobs:
echo 'Generating sedge docker...'
./build/sedge deps install
- ./build/sedge generate --logging none -p $GITHUB_WORKSPACE/sedge \
- full-node --map-all --no-mev-boost --no-validator --network ${{ matrix.config.network }} \
- -c ${{ matrix.config.cl }}:${{ matrix.config.cl_image }} -e nethermind:$docker_image \
- --el-extra-flag Sync.NonValidatorNode=true --el-extra-flag Sync.DownloadBodiesInFastSync=false \
- --el-extra-flag Sync.DownloadReceiptsInFastSync=false \
- --el-extra-flag JsonRpc.EnabledModules=[Eth,Subscribe,Trace,TxPool,Web3,Personal,Proof,Net,Parity,Health,Rpc,Debug] \
- --el-extra-flag Sync.SnapSync=true \
- --checkpoint-sync-url=${{ matrix.config.checkpoint-sync-url }}
+
+ if [[ "$network" == base-* || "$network" == op-* ]]; then
+ if [[ "$network" == *mainnet* ]]; then
+ CONSENSUS_URL="${{ secrets.MAINNET_CONSENSUS_URL }}"
+ EXECUTION_URL="${{ secrets.MAINNET_EXECUTION_URL }}"
+ elif [[ "$network" == *sepolia* ]]; then
+ CONSENSUS_URL="${{ secrets.SEPOLIA_CONSENSUS_URL }}"
+ EXECUTION_URL="${{ secrets.SEPOLIA_EXECUTION_URL }}"
+ else
+ echo "Unknown network"
+ exit 1
+ fi
+
+ if [[ "$network" == base-* ]]; then
+ extra_param="--base"
+ fi
+
+ stripped_network="${network#base-}"
+ stripped_network="${stripped_network#op-}"
+
+ ./build/sedge generate \
+ --logging none \
+ -p $GITHUB_WORKSPACE/sedge \
+ op-full-node \
+ --op-execution opnethermind:$docker_image \
+ --op-image op-node:us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:latest \
+ --map-all \
+ --network $stripped_network \
+ --consensus-url $CONSENSUS_URL \
+ --execution-api-url $EXECUTION_URL \
+ $extra_param
+ else
+ ./build/sedge generate \
+ --logging none \
+ -p $GITHUB_WORKSPACE/sedge \
+ full-node \
+ -c ${{ matrix.config.cl }}:${{ matrix.config.cl_image }} \
+ -e nethermind:$docker_image \
+ --map-all \
+ --no-mev-boost \
+ --no-validator \
+ --network ${{ matrix.config.network }} \
+ --el-extra-flag Sync.NonValidatorNode=true \
+ --el-extra-flag Sync.DownloadBodiesInFastSync=false \
+ --el-extra-flag Sync.DownloadReceiptsInFastSync=false \
+ --el-extra-flag JsonRpc.EnabledModules=[Eth,Subscribe,Trace,TxPool,Web3,Personal,Proof,Net,Parity,Health,Rpc,Debug] \
+ --el-extra-flag Sync.SnapSync=true \
+ --checkpoint-sync-url=${{ matrix.config.checkpoint-sync-url }}
+ fi
+
echo 'Running sedge...'
./build/sedge run -p $GITHUB_WORKSPACE/sedge
- name: Wait for ${{ matrix.config.network }} to sync
id: wait
- timeout-minutes: 180
run: |
declare -A bad_logs
+ declare -A good_logs
+ declare -A required_count
+
bad_logs["Corrupt"]=1
bad_logs["Exception"]=1
-
- declare -A good_logs
- good_logs["Synced Chain Head"]=0
+
good_logs["Processed"]=0
-
- declare -A required_count
- required_count["Synced Chain Head"]=20
- required_count["Processed"]=20
+
+ required_count["Processed"]=20
+
+ network="${{ matrix.config.network }}"
+ if [[ "$network" != "joc-mainnet" && "$network" != "joc-testnet" ]]; then
+ good_logs["Synced Chain Head"]=0
+ required_count["Synced Chain Head"]=20
+ fi
counter=0
found_bad_log=false
-
- docker logs -f sedge-execution-client | while read -r line; do
+
+ if [[ "$network" == base-* || "$network" == op-* ]]; then
+ container_name="sedge-execution-op-l2-client"
+ else
+ container_name="sedge-execution-client"
+ fi
+
+ docker logs -f "$container_name" | while read -r line; do
echo "$line"
if [[ "$line" == *"All done"* ]]; then
@@ -195,9 +250,32 @@ jobs:
done
- name: Get Consensus Logs
- if: always()
+ if: always() && matrix.config.network != 'joc-mainnet' && matrix.config.network != 'joc-testnet'
run: |
- docker logs sedge-consensus-client
+ network="${{ matrix.config.network }}"
+ if [[ "$network" == base-* || "$network" == op-* ]]; then
+ docker logs sedge-consensus-op-l2-client
+ else
+ docker logs sedge-consensus-client
+ fi
+
+ - name: Check size of DB
+ run: |
+ du -h $GITHUB_WORKSPACE/sedge
+
+ - name: Destroy VM
+ if: always()
+ id: run-linode-action
+ uses: kamilchodola/linode-github-runner/.github/actions/linode-machine-manager@main
+ with:
+ linode_token: ${{ secrets.LINODE_TOKEN }}
+ github_token: "${{ secrets.REPOSITORY_DISPATCH_TOKEN }}"
+ action: "destroy-machine"
+ runner_label: t-${{ github.run_id }}-${{ matrix.config.network }}
+ search_phrase: t-${{ github.run_id }}-${{ matrix.config.network }}
+ root_password: ${{ secrets.LINODE_ROOT_PASSWORD }}
+ organization: "NethermindEth"
+ repo_name: "nethermind"
destroy_runner:
needs: [setup-matrix, create_a_runner, sync-chain]
@@ -208,19 +286,30 @@ jobs:
config: ${{fromJson(needs.setup-matrix.outputs.matrix)}}
runs-on: ubuntu-latest
steps:
- - name: Destroy a Runner
- id: run-linode-action
+ - name: Destroy VM (make sure is removed if by any unexpected reason it did not removed it on )
+ continue-on-error: true
+ uses: kamilchodola/linode-github-runner/.github/actions/linode-machine-manager@main
+ with:
+ linode_token: ${{ secrets.LINODE_TOKEN }}
+ github_token: "${{ secrets.REPOSITORY_DISPATCH_TOKEN }}"
+ action: "destroy-machine"
+ runner_label: t-${{ github.run_id }}-${{ matrix.config.network }}
+ search_phrase: t-${{ github.run_id }}-${{ matrix.config.network }}
+ root_password: ${{ secrets.LINODE_ROOT_PASSWORD }}
+ organization: "NethermindEth"
+ repo_name: "nethermind"
+
+ - name: Destroy Runner
uses: kamilchodola/linode-github-runner/.github/actions/linode-machine-manager@main
with:
linode_token: ${{ secrets.LINODE_TOKEN }}
github_token: "${{ secrets.REPOSITORY_DISPATCH_TOKEN }}"
- action: "destroy"
- runner_label: ${{ matrix.config.network }}-${{ matrix.config.cl }}-${{ github.run_id }}
- search_phrase: ${{ matrix.config.network }}-${{ matrix.config.cl }}-${{ github.run_id }}
+ action: "destroy-runner"
+ runner_label: t-${{ github.run_id }}-${{ matrix.config.network }}
+ search_phrase: t-${{ github.run_id }}-${{ matrix.config.network }}
root_password: ${{ secrets.LINODE_ROOT_PASSWORD }}
organization: "NethermindEth"
repo_name: "nethermind"
-
trigger_tests:
needs: [setup-matrix, create_a_runner, sync-chain, destroy_runner]
if: success()
diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml
new file mode 100644
index 00000000000..b5c7b5616f1
--- /dev/null
+++ b/.github/workflows/trivy.yml
@@ -0,0 +1,46 @@
+name: Trivy scanner
+
+on:
+ pull_request:
+ branches: [master]
+ push:
+ branches: [master]
+ schedule:
+ - cron: '29 19 * * 4'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ security-events: write
+ actions: read
+ env:
+ IMAGE_TAG: nethermind:${{ github.sha }}
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
+
+ - name: Build Docker image
+ run: docker build -t $IMAGE_TAG .
+
+ - name: Scan
+ uses: aquasecurity/trivy-action@915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2 #v0.28.0
+ with:
+ image-ref: ${{ env.IMAGE_TAG }}
+ format: template
+ template: '@/contrib/sarif.tpl'
+ output: trivy-results.sarif
+ severity: CRITICAL,HIGH
+ env:
+ TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
+
+ - name: Upload scan results
+ uses: github/codeql-action/upload-sarif@cf5b0a9041d3c1d336516f1944c96d96598193cc #v2.19.1
+ with:
+ sarif_file: trivy-results.sarif
diff --git a/.github/workflows/update-fast-sync.yml b/.github/workflows/update-fast-sync.yml
index f3755e04ea1..577cafe9fb6 100644
--- a/.github/workflows/update-fast-sync.yml
+++ b/.github/workflows/update-fast-sync.yml
@@ -16,10 +16,12 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
- name: Install dependencies
run: |
- pip3 install setuptools
- pip3 install emoji
+ pip install setuptools
+ pip install emoji
- name: Update config files
run: python3 scripts/syncSettings.py ${{ secrets.ETHERSCAN_API_KEY }}
- name: Create GitHub app token
diff --git a/scripts/workflow_config/sync_testnets_matrix.json b/scripts/workflow_config/sync_testnets_matrix.json
index 08a19888e01..758c25f29a7 100644
--- a/scripts/workflow_config/sync_testnets_matrix.json
+++ b/scripts/workflow_config/sync_testnets_matrix.json
@@ -19,7 +19,7 @@
"network": "sepolia",
"cl": "prysm",
"cl_image": "prysmaticlabs/prysm-beacon-chain:stable",
- "checkpoint-sync-url": "https://beaconstate-sepolia.chainsafe.io",
+ "checkpoint-sync-url": "https://checkpoint-sync.sepolia.ethpandaops.io/",
"timeout": 180,
"agent": "g6-standard-6"
},
@@ -35,8 +35,56 @@
"network": "mainnet",
"cl": "lodestar",
"cl_image": "chainsafe/lodestar:latest",
- "checkpoint-sync-url": "https://mainnet.checkpoint.sigp.io",
+ "checkpoint-sync-url": "https://mainnet-checkpoint-sync.attestant.io/",
"timeout": 180,
"agent": "g6-standard-16"
+ },
+ {
+ "network": "op-sepolia",
+ "cl": "",
+ "cl_image": "",
+ "checkpoint-sync-url": "",
+ "timeout": 180,
+ "agent": "g6-standard-8"
+ },
+ {
+ "network": "base-sepolia",
+ "cl": "",
+ "cl_image": "",
+ "checkpoint-sync-url": "",
+ "timeout": 180,
+ "agent": "g6-standard-8"
+ },
+ {
+ "network": "op-mainnet",
+ "cl": "",
+ "cl_image": "",
+ "checkpoint-sync-url": "",
+ "timeout": 600,
+ "agent": "g6-standard-16"
+ },
+ {
+ "network": "base-mainnet",
+ "cl": "",
+ "cl_image": "",
+ "checkpoint-sync-url": "",
+ "timeout": 600,
+ "agent": "g6-standard-16"
+ },
+ {
+ "network": "joc-mainnet",
+ "cl": "",
+ "cl_image": "",
+ "checkpoint-sync-url": "",
+ "timeout": 180,
+ "agent": "g6-standard-6"
+ },
+ {
+ "network": "joc-testnet",
+ "cl": "",
+ "cl_image": "",
+ "checkpoint-sync-url": "",
+ "timeout": 180,
+ "agent": "g6-standard-6"
}
]
diff --git a/src/Nethermind/Chains/op-mainnet.json b/src/Nethermind/Chains/op-mainnet.json
index ee17aa826f7..7f6a7765ef3 100644
--- a/src/Nethermind/Chains/op-mainnet.json
+++ b/src/Nethermind/Chains/op-mainnet.json
@@ -73,7 +73,7 @@
"rip7212TransitionTimestamp": "0x668eb001",
"opGraniteTransitionTimestamp": "0x66e1be81",
- "terminalTotalDifficulty": "0"
+ "terminalTotalDifficulty": "210470125"
},
"genesis": {
"seal": {
@@ -93,6 +93,11 @@
"stateRoot": "0xeddb4c1786789419153a27c4c80ff44a2226b6eda04f7e22ce5bae892ea568eb"
},
"nodes": [
+ "enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301",
+ "enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301",
+ "enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301",
+ "enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301",
+ "enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301",
"enode://ca2774c3c401325850b2477fd7d0f27911efbf79b1e8b335066516e2bd8c4c9e0ba9696a94b1cb030a88eac582305ff55e905e64fb77fe0edcd70a4e5296d3ec@34.65.175.185:30305",
"enode://dd751a9ef8912be1bfa7a5e34e2c3785cc5253110bd929f385e07ba7ac19929fb0e0c5d93f77827291f4da02b2232240fbc47ea7ce04c46e333e452f8656b667@34.65.107.0:30305",
"enode://c5d289b56a77b6a2342ca29956dfd07aadf45364dde8ab20d1dc4efd4d1bc6b4655d902501daea308f4d8950737a4e93a4dfedd17b49cd5760ffd127837ca965@34.65.202.239:30305",
diff --git a/src/Nethermind/Directory.Packages.props b/src/Nethermind/Directory.Packages.props
index 253c598a39d..b7fae1de28d 100644
--- a/src/Nethermind/Directory.Packages.props
+++ b/src/Nethermind/Directory.Packages.props
@@ -6,6 +6,8 @@
+
+
@@ -36,6 +38,7 @@
+
diff --git a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
index 6f8afe58043..fe5fb25c019 100644
--- a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
+++ b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
@@ -326,12 +326,8 @@ private void InitializeTestState(BlockchainTest test, IWorldState stateProvider,
stateProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value);
}
- stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance);
+ stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, accountState.Value.Nonce);
stateProvider.InsertCode(accountState.Key, accountState.Value.Code, specProvider.GenesisSpec);
- for (int i = 0; i < accountState.Value.Nonce; i++)
- {
- stateProvider.IncrementNonce(accountState.Key);
- }
}
stateProvider.Commit(specProvider.GenesisSpec);
diff --git a/src/Nethermind/Ethereum.Trie.Test/TrieTests.cs b/src/Nethermind/Ethereum.Trie.Test/TrieTests.cs
index ab7f94d6220..aedee4459aa 100644
--- a/src/Nethermind/Ethereum.Trie.Test/TrieTests.cs
+++ b/src/Nethermind/Ethereum.Trie.Test/TrieTests.cs
@@ -307,7 +307,7 @@ public void Delete_on_empty()
{
PatriciaTree patriciaTree = new PatriciaTree(_db, Keccak.EmptyTreeHash, false, true, NullLogManager.Instance);
patriciaTree.Set(Keccak.Compute("1").Bytes, new byte[0]);
- patriciaTree.Commit(0);
+ patriciaTree.Commit();
Assert.That(patriciaTree.RootHash, Is.EqualTo(PatriciaTree.EmptyTreeHash));
}
diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs
index 61bceb25ae4..da24eaa918b 100644
--- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs
+++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
#nullable enable
+using Autofac;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Filters;
using Nethermind.Blockchain.FullPruning;
@@ -100,5 +101,12 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory
INodeStorageFactory NodeStorageFactory { get; set; }
BackgroundTaskScheduler BackgroundTaskScheduler { get; set; }
CensorshipDetector CensorshipDetector { get; set; }
+
+ public ContainerBuilder ConfigureContainerBuilderFromApiWithBlockchain(ContainerBuilder builder)
+ {
+ return ConfigureContainerBuilderFromApiWithStores(builder)
+ .AddPropertiesFrom(this)
+ .AddSingleton(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb));
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs
index 0f5d2262535..0b0e05e2a6d 100644
--- a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs
+++ b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs
@@ -2,7 +2,9 @@
// SPDX-License-Identifier: LGPL-3.0-only
using System.Collections.Generic;
+using Autofac;
using Nethermind.Consensus;
+using Nethermind.Core;
using Nethermind.Core.PubSub;
using Nethermind.Grpc;
using Nethermind.JsonRpc;
@@ -16,6 +18,7 @@
using Nethermind.Synchronization;
using Nethermind.Synchronization.Peers;
using Nethermind.Sockets;
+using Nethermind.Synchronization.ParallelSync;
namespace Nethermind.Api
{
@@ -41,12 +44,22 @@ public interface IApiWithNetwork : IApiWithBlockchain
IJsonRpcLocalStats? JsonRpcLocalStats { get; set; }
ISessionMonitor? SessionMonitor { get; set; }
IStaticNodesManager? StaticNodesManager { get; set; }
- ISynchronizer? Synchronizer { get; set; }
+ ISynchronizer? Synchronizer { get; }
+ ISyncModeSelector SyncModeSelector { get; }
+ ISyncProgressResolver? SyncProgressResolver { get; }
IPivot? Pivot { get; set; }
ISyncPeerPool? SyncPeerPool { get; set; }
IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool { get; set; }
ISyncServer? SyncServer { get; set; }
IWebSocketsManager WebSocketsManager { get; set; }
ISubscriptionFactory? SubscriptionFactory { get; set; }
+
+ IContainer? ApiWithNetworkServiceContainer { get; set; }
+
+ public ContainerBuilder ConfigureContainerBuilderFromApiWithNetwork(ContainerBuilder builder)
+ {
+ return ConfigureContainerBuilderFromApiWithBlockchain(builder)
+ .AddPropertiesFrom(this);
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Api/IApiWithStores.cs b/src/Nethermind/Nethermind.Api/IApiWithStores.cs
index fa2911c2ebe..eed8ed62430 100644
--- a/src/Nethermind/Nethermind.Api/IApiWithStores.cs
+++ b/src/Nethermind/Nethermind.Api/IApiWithStores.cs
@@ -1,11 +1,13 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
+using Autofac;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Receipts;
using Nethermind.Consensus;
+using Nethermind.Core;
using Nethermind.Crypto;
using Nethermind.Db.Blooms;
using Nethermind.Facade.Find;
@@ -30,5 +32,11 @@ public interface IApiWithStores : IBasicApi
IReceiptMonitor? ReceiptMonitor { get; set; }
IWallet? Wallet { get; set; }
IBlockStore? BadBlocksStore { get; set; }
+
+ public ContainerBuilder ConfigureContainerBuilderFromApiWithStores(ContainerBuilder builder)
+ {
+ return ConfigureContainerBuilderFromBasicApi(builder)
+ .AddPropertiesFrom(this);
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs
index 3b78f16a865..1ba0adb91f9 100644
--- a/src/Nethermind/Nethermind.Api/IBasicApi.cs
+++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs
@@ -1,11 +1,14 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
+using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
+using Autofac;
using Nethermind.Abi;
using Nethermind.Api.Extensions;
+using Nethermind.Blockchain.Synchronization;
using Nethermind.Config;
using Nethermind.Core;
using Nethermind.Core.Specs;
@@ -17,7 +20,6 @@
using Nethermind.Serialization.Json;
using Nethermind.Specs.ChainSpecStyle;
using Nethermind.Synchronization;
-using Nethermind.Synchronization.ParallelSync;
namespace Nethermind.Api
{
@@ -38,10 +40,9 @@ public interface IBasicApi
ILogManager LogManager { get; set; }
ProtectedPrivateKey? OriginalSignerKey { get; set; }
IReadOnlyList Plugins { get; }
+ [SkipServiceCollection]
string SealEngineType { get; set; }
ISpecProvider? SpecProvider { get; set; }
- ISyncModeSelector SyncModeSelector { get; set; }
- ISyncProgressResolver? SyncProgressResolver { get; set; }
IBetterPeerStrategy? BetterPeerStrategy { get; set; }
ITimestamper Timestamper { get; }
ITimerFactory TimerFactory { get; }
@@ -57,5 +58,16 @@ public IEnumerable GetConsensusWrapperPlugins() =>
public IEnumerable GetSynchronizationPlugins() =>
Plugins.OfType();
+
+ public ContainerBuilder ConfigureContainerBuilderFromBasicApi(ContainerBuilder builder)
+ {
+ builder
+ .AddPropertiesFrom(this)
+ .AddSingleton(ConfigProvider.GetConfig());
+
+ DbProvider!.ConfigureServiceCollection(builder);
+
+ return builder;
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Api/INethermindApi.cs b/src/Nethermind/Nethermind.Api/INethermindApi.cs
index fff51021393..7c600b9f056 100644
--- a/src/Nethermind/Nethermind.Api/INethermindApi.cs
+++ b/src/Nethermind/Nethermind.Api/INethermindApi.cs
@@ -5,6 +5,8 @@
using System;
using Nethermind.Config;
using Nethermind.Core;
+using Nethermind.Facade.Eth;
+using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Serialization.Rlp;
using Nethermind.Serialization.Rlp.TxDecoders;
using Nethermind.TxPool;
@@ -23,12 +25,14 @@ public T Config() where T : IConfig
public static class NethermindApiExtensions
{
- public static void RegisterTxType(this INethermindApi api, TxType type, ITxDecoder decoder, ITxValidator validator)
+ public static void RegisterTxType(this INethermindApi api, ITxDecoder decoder, ITxValidator validator) where T : TransactionForRpc, IFromTransaction
{
ArgumentNullException.ThrowIfNull(api.TxValidator);
+ if (decoder.Type != T.TxType) throw new ArgumentException($"TxType mismatch decoder: {decoder.Type}, RPC: {T.TxType}");
- api.TxValidator.RegisterValidator(type, validator);
+ api.TxValidator.RegisterValidator(T.TxType, validator);
TxDecoder.Instance.RegisterDecoder(decoder);
+ TransactionForRpc.RegisterTransactionType();
}
}
}
diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs
index 56193492d01..566a094eaa0 100644
--- a/src/Nethermind/Nethermind.Api/NethermindApi.cs
+++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO.Abstractions;
+using Autofac;
using Nethermind.Abi;
using Nethermind.Api.Extensions;
using Nethermind.Blockchain;
@@ -186,14 +187,14 @@ public ISealEngine SealEngine
public ISessionMonitor? SessionMonitor { get; set; }
public ISpecProvider? SpecProvider { get; set; }
public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance;
- public ISyncModeSelector SyncModeSelector { get; set; } = null!;
+ public ISyncModeSelector SyncModeSelector => ApiWithNetworkServiceContainer?.Resolve()!;
- public ISyncProgressResolver? SyncProgressResolver { get; set; }
+ public ISyncProgressResolver? SyncProgressResolver => ApiWithNetworkServiceContainer?.Resolve();
public IBetterPeerStrategy? BetterPeerStrategy { get; set; }
public IPivot? Pivot { get; set; }
public ISyncPeerPool? SyncPeerPool { get; set; }
public IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool { get; set; }
- public ISynchronizer? Synchronizer { get; set; }
+ public ISynchronizer? Synchronizer => ApiWithNetworkServiceContainer?.Resolve();
public ISyncServer? SyncServer { get; set; }
public IWorldState? WorldState { get; set; }
public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; }
@@ -243,5 +244,7 @@ public ISealEngine SealEngine
public CompositePruningTrigger PruningTrigger { get; } = new();
public IProcessExitSource? ProcessExit { get; set; }
public CompositeTxGossipPolicy TxGossipPolicy { get; } = new();
+
+ public IContainer? ApiWithNetworkServiceContainer { get; set; }
}
}
diff --git a/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs b/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs
index 5d568377914..07d700e9352 100644
--- a/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs
+++ b/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs
@@ -56,14 +56,14 @@ public class PatriciaTreeBenchmarks
tree.Set(TestItem.AddressA, _account0);
tree.Set(TestItem.AddressB, _account0);
tree.Set(TestItem.AddressC, _account0);
- tree.Commit(1);
+ tree.Commit();
}),
("set_3_via_hash", tree =>
{
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb00000000"), _account0);
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb0"), _account0);
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb1"), _account0);
- tree.Commit(1);
+ tree.Commit();
}),
("set_3_delete_1", tree =>
{
@@ -71,7 +71,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb0"), _account0);
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb1"), _account0);
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb1"), null);
- tree.Commit(1);
+ tree.Commit();
}),
("set_3_delete_2", tree =>
{
@@ -80,7 +80,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb1"), _account0);
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb0"), null);
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb1"), null);
- tree.Commit(1);
+ tree.Commit();
}),
("set_3_delete_all", tree =>
{
@@ -90,7 +90,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb0"), null);
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb1eeeeeb1"), null);
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb00000000"), null);
- tree.Commit(1);
+ tree.Commit();
}),
("extension_read_full_match", tree =>
{
@@ -99,7 +99,7 @@ public class PatriciaTreeBenchmarks
Account account = tree.Get(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb11111111"));
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("extension_read_missing", tree =>
{
@@ -108,7 +108,7 @@ public class PatriciaTreeBenchmarks
Account account = tree.Get(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeedddddddddddddddddddddddd"));
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("extension_new_branch", tree =>
{
@@ -117,7 +117,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeedddddddddddddddddddddddd"), _account2);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("extension_delete_missing", tree =>
{
@@ -126,7 +126,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeddddddddddddddddddddddddd"), null);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("extenson_create_new_extension", tree =>
{
@@ -136,7 +136,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaab11111111"), _account3);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("leaf_new_value", tree =>
{
@@ -144,7 +144,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("1111111111111111111111111111111111111111111111111111111111111111"), _account1);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("leaf_no_change", tree =>
{
@@ -152,7 +152,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("1111111111111111111111111111111111111111111111111111111111111111"), _account0);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("leaf_delete", tree =>
{
@@ -160,7 +160,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("1111111111111111111111111111111111111111111111111111111111111111"), null);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("leaf_delete_missing", tree =>
{
@@ -168,7 +168,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("1111111111111111111111111111111ddddddddddddddddddddddddddddddddd"), null);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("leaf_update_extension", tree =>
{
@@ -176,7 +176,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb00000000000000000000000000000000"), _account1);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("leaf_read", tree =>
{
@@ -184,7 +184,7 @@ public class PatriciaTreeBenchmarks
Account account = tree.Get(new Hash256("1111111111111111111111111111111111111111111111111111111111111111"));
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("leaf_update_missing", tree =>
{
@@ -192,7 +192,7 @@ public class PatriciaTreeBenchmarks
Account account = tree.Get(new Hash256("111111111111111111111111111111111111111111111111111111111ddddddd"));
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("branch_update_missing", tree =>
{
@@ -201,7 +201,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb22222"), _account2);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("branch_read_missing", tree =>
{
@@ -210,7 +210,7 @@ public class PatriciaTreeBenchmarks
Account account = tree.Get(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb22222"));
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
("branch_delete_missing", tree =>
{
@@ -219,7 +219,7 @@ public class PatriciaTreeBenchmarks
tree.Set(new Hash256("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb22222"), null);
tree.UpdateRootHash();
Hash256 rootHash = tree.RootHash;
- tree.Commit(1);
+ tree.Commit();
}),
};
@@ -247,7 +247,7 @@ public void Setup()
{
tempTree.Set(_entries[i].Item1, _entries[i].Item2);
}
- tempTree.Commit(0);
+ tempTree.Commit();
_rootHash = tempTree.RootHash;
_fullTree = new StateTree();
@@ -255,7 +255,7 @@ public void Setup()
{
_fullTree.Set(_entries[i].Item1, _entries[i].Item2);
}
- _fullTree.Commit(0);
+ _fullTree.Commit();
_uncommittedFullTree = new StateTree();
for (int i = 0; i < _entryCount; i++)
@@ -330,23 +330,23 @@ public void InsertAndCommit()
{
tempTree.Set(_entries[i].Item1, _entries[i].Item2);
}
- tempTree.Commit(0);
+ tempTree.Commit();
}
[Benchmark]
public void InsertAndCommitRepeatedlyTimes()
{
- StateTree tempTree = new StateTree(
- new TrieStore(new MemDb(),
+ TrieStore trieStore = new TrieStore(new MemDb(),
Prune.WhenCacheReaches(1.MiB()),
- Persist.IfBlockOlderThan(2),
- NullLogManager.Instance), NullLogManager.Instance);
+ Persist.IfBlockOlderThan(2), NullLogManager.Instance);
+ StateTree tempTree = new StateTree(trieStore, NullLogManager.Instance);
for (int i = 0; i < _largerEntryCount; i++)
{
if (i % 2000 == 0)
{
- tempTree.Commit(i / 2000);
+ using IBlockCommitter _ = trieStore.BeginBlockCommit(i / 2000);
+ tempTree.Commit();
}
(bool isWrite, Hash256 address, Account value) = _largerEntriesAccess[i];
diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs
index 35c6c3fc1ac..cfee2a225fd 100644
--- a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs
+++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs
@@ -143,4 +143,7 @@ public interface ISyncConfig : IConfig
[ConfigItem(Description = "_Technical._ MultiSyncModeSelector sync mode timer loop interval. Used for testing.", DefaultValue = "1000", HiddenFromDocs = true)]
int MultiSyncModeSelectorLoopTimerMs { get; set; }
+
+ [ConfigItem(Description = "_Technical._ MultiSyncModeSelector will wait for header to completely sync first.", DefaultValue = "false", HiddenFromDocs = true)]
+ bool NeedToWaitForHeader { get; set; }
}
diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs
index d2645336586..c467650ca7a 100644
--- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs
+++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs
@@ -65,6 +65,7 @@ public string? PivotHash
public int MallocTrimIntervalSec { get; set; } = 300;
public bool? SnapServingEnabled { get; set; } = null;
public int MultiSyncModeSelectorLoopTimerMs { get; set; } = 1000;
+ public bool NeedToWaitForHeader { get; set; }
public bool TrieHealing { get; set; } = true;
public override string ToString()
diff --git a/src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs b/src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs
index 3eac4d9207c..8f2f30409a8 100644
--- a/src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs
+++ b/src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs
@@ -7,10 +7,9 @@
using Nethermind.Cli.Modules;
using Nethermind.Core.Crypto;
using Nethermind.Core.Test.Builders;
-using Nethermind.Facade.Eth;
+using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.JsonRpc;
using Nethermind.JsonRpc.Client;
-using Nethermind.JsonRpc.Data;
using Nethermind.Logging;
using Nethermind.Serialization.Json;
using NSubstitute;
@@ -81,7 +80,7 @@ public void Get_transaction_receipt(bool includeHeader)
public void Call()
{
Hash256 blockHash = TestItem.KeccakA;
- TransactionForRpc tx = new()
+ LegacyTransactionForRpc tx = new()
{
From = TestItem.AddressA,
To = TestItem.AddressB
diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs
index 961ce37bfe9..94640022b6d 100644
--- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs
+++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs
@@ -7,9 +7,8 @@
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
-using Nethermind.Facade.Eth;
+using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Int256;
-using Nethermind.JsonRpc.Data;
namespace Nethermind.Cli.Modules
{
@@ -20,13 +19,15 @@ public class EthCliModule : CliModuleBase
{
long blockNumber = NodeManager.Post("eth_blockNumber").Result;
- TransactionForRpc tx = new();
- tx.Value = amountInWei;
- tx.Gas = Transaction.BaseTxGasCost;
- tx.GasPrice = (UInt256)Engine.JintEngine.GetValue("gasPrice").AsNumber();
- tx.To = address;
- tx.Nonce = (ulong)NodeManager.Post("eth_getTransactionCount", from, blockNumber).Result;
- tx.From = from;
+ LegacyTransactionForRpc tx = new()
+ {
+ Value = amountInWei,
+ Gas = Transaction.BaseTxGasCost,
+ GasPrice = (UInt256)Engine.JintEngine.GetValue("gasPrice").AsNumber(),
+ To = address,
+ Nonce = (ulong)NodeManager.Post("eth_getTransactionCount", from, blockNumber).Result,
+ From = from
+ };
Hash256? keccak = NodeManager.Post("eth_sendTransaction", tx).Result;
return keccak?.Bytes.ToHexString();
diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs
index 368524c6bb1..3acd55ff4f2 100644
--- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs
+++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs
@@ -136,7 +136,7 @@ private bool ValidateGasUsed(BlockHeader header, ref string? error)
return true;
}
- private bool ValidateParent(BlockHeader header, BlockHeader? parent, ref string? error)
+ protected bool ValidateParent(BlockHeader header, BlockHeader? parent, ref string? error)
{
if (parent is null)
{
diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.Tree.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.Tree.cs
index aa440794481..64b9d22d833 100644
--- a/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.Tree.cs
+++ b/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.Tree.cs
@@ -66,7 +66,7 @@ public static void FillStateTreeWithTestAccounts(StateTree stateTree)
stateTree.Set(AccountsWithPaths[3].Path, AccountsWithPaths[3].Account);
stateTree.Set(AccountsWithPaths[4].Path, AccountsWithPaths[4].Account);
stateTree.Set(AccountsWithPaths[5].Path, AccountsWithPaths[5].Account);
- stateTree.Commit(0);
+ stateTree.Commit();
}
public static void FillStateTreeMultipleAccount(StateTree stateTree, int accountNumber)
@@ -76,7 +76,7 @@ public static void FillStateTreeMultipleAccount(StateTree stateTree, int account
Account acc = Build.An.Account.WithBalance((UInt256)i).TestObject;
stateTree.Set(Keccak.Compute(i.ToBigEndianByteArray()), acc);
}
- stateTree.Commit(0);
+ stateTree.Commit();
}
public static (StateTree stateTree, StorageTree storageTree, Hash256 accountAddr) GetTrees(ITrieStore? store)
@@ -92,13 +92,13 @@ public static (StateTree stateTree, StorageTree storageTree, Hash256 accountAddr
storageTree.Set(SlotsWithPaths[4].Path, SlotsWithPaths[4].SlotRlpValue, false);
storageTree.Set(SlotsWithPaths[5].Path, SlotsWithPaths[5].SlotRlpValue, false);
- storageTree.Commit(0);
+ storageTree.Commit();
var account = Build.An.Account.WithBalance(1).WithStorageRoot(storageTree.RootHash).TestObject;
var stateTree = new StateTree(store.GetTrieStore(null), LimboLogs.Instance);
stateTree.Set(AccountAddress0, account);
- stateTree.Commit(0);
+ stateTree.Commit();
return (stateTree, storageTree, AccountAddress0);
}
@@ -117,13 +117,13 @@ public static (StateTree stateTree, StorageTree storageTree, Hash256 accountAddr
false);
}
- storageTree.Commit(0);
+ storageTree.Commit();
var account = Build.An.Account.WithBalance(1).WithStorageRoot(storageTree.RootHash).TestObject;
var stateTree = new StateTree(store, LimboLogs.Instance);
stateTree.Set(AccountAddress0, account);
- stateTree.Commit(0);
+ stateTree.Commit();
return (stateTree, storageTree, AccountAddress0);
}
diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs
index ac8cf8e0313..65cd94de826 100644
--- a/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs
+++ b/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs
@@ -39,6 +39,13 @@ static TestItem()
Keccaks[i - 1] = Keccak.Compute(PublicKeys[i - 1].Bytes);
ValueKeccaks[i - 1] = Keccaks[i - 1];
}
+
+ byte[] r = new byte[32];
+ byte[] s = new byte[32];
+ r[1] = 1;
+ s[2] = 2;
+ RandomSignatureA = new Signature(r, s, 27);
+ RandomSignatureB = new Signature(r, s, 28);
}
public static Hash256 KeccakFromNumber(int i)
@@ -93,6 +100,9 @@ public static Hash256 KeccakFromNumber(int i)
public static Address AddressE = PublicKeyE.Address;
public static Address AddressF = PublicKeyF.Address;
+ public static readonly Signature RandomSignatureA;
+ public static readonly Signature RandomSignatureB;
+
public static Withdrawal WithdrawalA_1Eth = new() { Address = AddressA, Index = 1, ValidatorIndex = 2001, AmountInGwei = 1_000_000_000 };
public static Withdrawal WithdrawalB_2Eth = new() { Address = AddressB, Index = 2, ValidatorIndex = 2002, AmountInGwei = 2_000_000_000 };
public static Withdrawal WithdrawalC_3Eth = new() { Address = AddressC, Index = 3, ValidatorIndex = 2003, AmountInGwei = 3_000_000_000 };
diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs
index cf81f10a348..2246e7c319d 100644
--- a/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs
+++ b/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs
@@ -63,7 +63,7 @@ public TransactionBuilder WithCode(byte[] data)
return this;
}
- public TransactionBuilder WithChainId(ulong chainId)
+ public TransactionBuilder WithChainId(ulong? chainId)
{
TestObjectInternal.ChainId = chainId;
return this;
@@ -298,6 +298,12 @@ public TransactionBuilder WithIsServiceTransaction(bool isServiceTransaction)
return this;
}
+ public TransactionBuilder WithSourceHash(Hash256? sourceHash)
+ {
+ TestObjectInternal.SourceHash = sourceHash;
+ return this;
+ }
+
public TransactionBuilder From(T item)
{
TestObjectInternal = item;
diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs
index 691f2debad1..3f2bdcf9688 100644
--- a/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs
+++ b/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs
@@ -36,7 +36,7 @@ public TrieBuilder WithAccountsByIndex(int start, int count)
TestObjectInternal.Set(key.Bytes, value);
}
- TestObjectInternal.Commit(0);
+ TestObjectInternal.Commit();
TestObjectInternal.UpdateRootHash();
return this;
diff --git a/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs b/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs
new file mode 100644
index 00000000000..28e890c8499
--- /dev/null
+++ b/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs
@@ -0,0 +1,113 @@
+// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-License-Identifier: LGPL-3.0-only
+
+using System;
+using Autofac;
+using FluentAssertions;
+using NUnit.Framework;
+
+namespace Nethermind.Core.Test;
+
+public class ContainerBuilderExtensionsTests
+{
+ [Test]
+ public void AddPropertiesFrom_CanAddProperties()
+ {
+ ITestInterface interfaceImplementation = new InterfaceImplementation();
+ IContainer sp = new ContainerBuilder()
+ .AddPropertiesFrom(interfaceImplementation)
+ .Build();
+
+ sp.ResolveOptional().Should().NotBeNull();
+ sp.ResolveOptional().Should().BeNull();
+ sp.ResolveOptional().Should().BeNull();
+ sp.ResolveOptional().Should().BeNull();
+ }
+
+ [Test]
+ public void TestRegisterNamedComponent()
+ {
+ IContainer sp = new ContainerBuilder()
+ .AddScoped()
+ .AddScoped()
+ .RegisterNamedComponentInItsOwnLifetime("custom", cfg =>
+ {
+ // Override it in custom
+ cfg.AddScoped();
+ })
+ .Build();
+
+ using (ILifetimeScope scope = sp.BeginLifetimeScope())
+ {
+ scope.Resolve().Property.Should().BeOfType();
+ }
+
+ MainComponentDependency customMainComponentDependency = sp.ResolveNamed("custom").Property;
+ sp.ResolveNamed("custom").Property.Should().BeOfType();
+
+ sp.Dispose();
+
+ customMainComponentDependency.WasDisposed.Should().BeTrue();
+ }
+
+ private class MainComponent(MainComponentDependency mainComponentDependency, ILifetimeScope scope) : IDisposable
+ {
+ public MainComponentDependency Property => mainComponentDependency;
+
+ public void Dispose()
+ {
+ scope.Dispose();
+ }
+ }
+
+ private class MainComponentDependency : IDisposable
+ {
+ public bool WasDisposed { get; set; }
+
+ public void Dispose()
+ {
+ WasDisposed = true;
+ }
+ }
+
+ private class MainComponentDependencySubClass : MainComponentDependency
+ {
+ }
+
+ private class InterfaceImplementation : ITestInterface
+ {
+ public DeclaredService TheService { get; set; } = new DeclaredService();
+ public DeclaredButNullService? NullService { get; set; } = null;
+ public Ignored IgnoredService { get; set; } = new Ignored();
+ public DeclaredInBase BaseService { get; set; } = new DeclaredInBase();
+ }
+
+ private interface ITestInterface : ITestInterfaceBase
+ {
+ DeclaredService TheService { get; set; }
+ DeclaredButNullService? NullService { get; set; }
+
+ [SkipServiceCollection]
+ Ignored IgnoredService { get; set; }
+ }
+
+ private interface ITestInterfaceBase
+ {
+ DeclaredInBase BaseService { get; set; }
+ }
+
+ private class DeclaredInBase { }
+ private class DeclaredService { }
+ private class DeclaredButNullService { }
+ private class Ignored { }
+
+ private class DisposableService : IDisposable
+ {
+ public bool WasDisposed { get; set; } = false;
+
+ public void Dispose()
+ {
+ WasDisposed = true;
+ }
+ }
+}
diff --git a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs
new file mode 100644
index 00000000000..1c30a830b55
--- /dev/null
+++ b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs
@@ -0,0 +1,125 @@
+// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-License-Identifier: LGPL-3.0-only
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Autofac;
+using Autofac.Features.AttributeFilters;
+
+namespace Nethermind.Core;
+
+public static class ContainerBuilderExtensions
+{
+ ///
+ /// Add all properties as singleton. It get them ahead of time instead of lazily to prevent the final service provider
+ /// from disposing it. To prevent a property from being included, use .
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static ContainerBuilder AddPropertiesFrom(this ContainerBuilder configuration, T source) where T : class
+ {
+ Type t = typeof(T);
+
+ IEnumerable properties = t
+ .GetProperties(BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
+ .Where(p => p.GetCustomAttribute() == null);
+
+ foreach (PropertyInfo propertyInfo in properties)
+ {
+ object? val = propertyInfo.GetValue(source);
+ if (val != null)
+ {
+ configuration.RegisterInstance(val).As(propertyInfo.PropertyType);
+ }
+ }
+
+ return configuration;
+ }
+
+ public static ContainerBuilder AddSingleton(this ContainerBuilder builder) where T : notnull
+ {
+ builder.RegisterType()
+ .As()
+ .WithAttributeFiltering()
+ .SingleInstance();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddSingleton(this ContainerBuilder builder, T instance) where T : class
+ {
+ builder.RegisterInstance(instance)
+ .As()
+ .SingleInstance();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddSingleton(this ContainerBuilder builder) where TImpl : notnull where T : notnull
+ {
+ builder.RegisterType()
+ .As()
+ .AsSelf()
+ .WithAttributeFiltering()
+ .SingleInstance();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddKeyedSingleton(this ContainerBuilder builder, string key, T instance) where T : class
+ {
+ builder.RegisterInstance(instance)
+ .Named(key)
+ .SingleInstance();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddScoped(this ContainerBuilder builder) where T : notnull
+ {
+ builder.RegisterType()
+ .As()
+ .AsSelf()
+ .WithAttributeFiltering()
+ .InstancePerLifetimeScope();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddScoped(this ContainerBuilder builder) where TImpl : notnull where T : notnull
+ {
+ builder.RegisterType()
+ .As()
+ .WithAttributeFiltering()
+ .InstancePerLifetimeScope();
+
+ return builder;
+ }
+
+ ///
+ /// A convenient way of creating a service whose member can be configured indipendent of other instance of the same
+ /// type (assuming the type is of lifetime scope). This is useful for same type with multiple configuration
+ /// or a graph of multiple same type. The T is expected to be of a main container of sort that contains the
+ /// main service of interest.
+ /// Note: The T should dispose an injected ILifetimeScope on dispose as ILifetimeScope is not automatically disposed
+ /// when parent scope is disposed.
+ ///
+ public static ContainerBuilder RegisterNamedComponentInItsOwnLifetime(this ContainerBuilder builder, string name, Action configurator) where T : notnull
+ {
+ builder.Register(ctx => ctx.BeginLifetimeScope(configurator).Resolve())
+ .Named(name);
+
+ return builder;
+ }
+}
+
+///
+/// Mark a property so that it is not picked up by `AddPropertiesFrom`.
+///
+public class SkipServiceCollectionAttribute : Attribute
+{
+}
diff --git a/src/Nethermind/Nethermind.Core/Extensions/UInt256Extensions.cs b/src/Nethermind/Nethermind.Core/Extensions/UInt256Extensions.cs
new file mode 100644
index 00000000000..b0f06b73cd1
--- /dev/null
+++ b/src/Nethermind/Nethermind.Core/Extensions/UInt256Extensions.cs
@@ -0,0 +1,13 @@
+// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-License-Identifier: LGPL-3.0-only
+
+using System;
+using Nethermind.Int256;
+
+namespace Nethermind.Core.Extensions;
+
+public static class UInt256Extensions
+{
+ // value?.IsZero == false <=> x > 0
+ public static bool IsPositive(this UInt256? @this) => @this?.IsZero == false;
+}
diff --git a/src/Nethermind/Nethermind.Core/Nethermind.Core.csproj b/src/Nethermind/Nethermind.Core/Nethermind.Core.csproj
index de2832e6ea5..930e96abe48 100644
--- a/src/Nethermind/Nethermind.Core/Nethermind.Core.csproj
+++ b/src/Nethermind/Nethermind.Core/Nethermind.Core.csproj
@@ -5,7 +5,10 @@
+
+
+
diff --git a/src/Nethermind/Nethermind.Db/IDbProvider.cs b/src/Nethermind/Nethermind.Db/IDbProvider.cs
index 7786271bc74..6a0380b0446 100644
--- a/src/Nethermind/Nethermind.Db/IDbProvider.cs
+++ b/src/Nethermind/Nethermind.Db/IDbProvider.cs
@@ -3,6 +3,9 @@
using System;
using System.Collections.Generic;
+using Autofac;
+using Microsoft.Extensions.DependencyInjection;
+using Nethermind.Core;
namespace Nethermind.Db
{
@@ -30,5 +33,34 @@ public interface IDbProvider : IDisposable
void RegisterDb(string dbName, T db) where T : class, IDb;
void RegisterColumnDb(string dbName, IColumnsDb db);
IEnumerable> GetAllDbMeta();
+
+ void ConfigureServiceCollection(ContainerBuilder sc)
+ {
+ sc.AddSingleton(this);
+
+ // TODO: Have hooks that automatically get these
+ string[] dbNames = [
+ DbNames.State,
+ DbNames.Code,
+ DbNames.Metadata,
+ DbNames.Blocks,
+ DbNames.Headers,
+ DbNames.BlockInfos,
+ DbNames.BadBlocks,
+ DbNames.Bloom,
+ DbNames.Metadata,
+ ];
+ foreach (string dbName in dbNames)
+ {
+ var db = GetDb(dbName);
+ sc.AddKeyedSingleton(dbName, db);
+ sc.AddKeyedSingleton(dbName, db);
+ sc.AddKeyedSingleton(dbName, db as ITunableDb ?? new NoopTunableDb());
+ }
+
+ IColumnsDb receiptColumnDb = GetColumnDb(DbNames.Receipts);
+ sc.AddSingleton>(receiptColumnDb);
+ sc.AddKeyedSingleton(DbNames.Receipts, receiptColumnDb as ITunableDb ?? new NoopTunableDb());
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Db/ITunableDb.cs b/src/Nethermind/Nethermind.Db/ITunableDb.cs
index 7584364badd..00b0edf0f0c 100644
--- a/src/Nethermind/Nethermind.Db/ITunableDb.cs
+++ b/src/Nethermind/Nethermind.Db/ITunableDb.cs
@@ -3,7 +3,7 @@
namespace Nethermind.Db;
-public interface ITunableDb : IDb
+public interface ITunableDb
{
public void Tune(TuneType type);
@@ -18,3 +18,10 @@ enum TuneType
HashDb
}
}
+
+public class NoopTunableDb : ITunableDb
+{
+ public void Tune(ITunableDb.TuneType type)
+ {
+ }
+}
diff --git a/src/Nethermind/Nethermind.Facade/Eth/AccessListItemForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/AccessListItemForRpc.cs
deleted file mode 100644
index 0269aeeb0e6..00000000000
--- a/src/Nethermind/Nethermind.Facade/Eth/AccessListItemForRpc.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
-// SPDX-License-Identifier: LGPL-3.0-only
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Nethermind.Core;
-using Nethermind.Core.Collections;
-using Nethermind.Core.Eip2930;
-using Nethermind.Int256;
-using Nethermind.Serialization.Json;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-
-namespace Nethermind.Facade.Eth
-{
- public struct AccessListItemForRpc : IEquatable
- {
- [JsonConstructor]
- public AccessListItemForRpc() { }
-
- public AccessListItemForRpc(Address address, IEnumerable? storageKeys)
- {
- Address = address;
- StorageKeys = storageKeys;
- }
-
- public Address Address { get; set; }
- [JsonConverter(typeof(StorageCellIndexConverter))]
- public IEnumerable? StorageKeys { get; set; }
-
- public static IEnumerable FromAccessList(AccessList accessList) =>
- accessList.Select(tuple => new AccessListItemForRpc(tuple.Address, tuple.StorageKeys));
-
- public static AccessList ToAccessList(IEnumerable accessList)
- {
- AccessList.Builder builder = new();
- foreach (AccessListItemForRpc accessListItem in accessList)
- {
- builder.AddAddress(accessListItem.Address);
- if (accessListItem.StorageKeys is not null)
- {
- foreach (UInt256 index in accessListItem.StorageKeys)
- {
- builder.AddStorage(index);
- }
- }
- }
-
- return builder.Build();
- }
-
- public readonly bool Equals(AccessListItemForRpc other) => Equals(Address, other.Address) && StorageKeys.NullableSequenceEqual(other.StorageKeys);
- public override readonly bool Equals(object? obj) => obj is AccessListItemForRpc other && Equals(other);
- public override readonly int GetHashCode() => HashCode.Combine(Address, StorageKeys);
- }
-}
diff --git a/src/Nethermind/Nethermind.Facade/Eth/AuthorizationTupleForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/AuthorizationTupleForRpc.cs
deleted file mode 100644
index c35c97b1d56..00000000000
--- a/src/Nethermind/Nethermind.Facade/Eth/AuthorizationTupleForRpc.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
-// SPDX-License-Identifier: LGPL-3.0-only
-
-using Nethermind.Core;
-using Nethermind.Int256;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.Json.Serialization;
-
-namespace Nethermind.Facade.Eth
-{
- public struct AuthorizationTupleForRpc
- {
- [JsonConstructor]
- public AuthorizationTupleForRpc()
- {
- }
- public AuthorizationTupleForRpc(UInt256 chainId, ulong nonce, Address address, UInt256? yParity, UInt256? s, UInt256? r)
- {
- ChainId = chainId;
- Nonce = nonce;
- Address = address;
- YParity = yParity;
- S = s;
- R = r;
- }
-
- public UInt256 ChainId { get; set; }
- public ulong Nonce { get; set; }
- public Address Address { get; set; }
- public UInt256? YParity { get; set; }
- public UInt256? S { get; set; }
- public UInt256? R { get; set; }
-
- public static IEnumerable FromAuthorizationList(AuthorizationTuple[] authorizationList) =>
- authorizationList.Select(tuple => new AuthorizationTupleForRpc(tuple.ChainId,
- tuple.Nonce,
- tuple.CodeAddress,
- tuple.AuthoritySignature.RecoveryId,
- new UInt256(tuple.AuthoritySignature.S),
- new UInt256(tuple.AuthoritySignature.R)));
- }
-}
diff --git a/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs
index b0904d5552f..c194e214615 100644
--- a/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs
+++ b/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs
@@ -12,6 +12,7 @@
using Nethermind.Serialization.Rlp;
using System.Text.Json.Serialization;
using System.Runtime.CompilerServices;
+using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Core.ConsensusRequests;
namespace Nethermind.Facade.Eth;
@@ -78,7 +79,10 @@ public BlockForRpc(Block block, bool includeFullTransactionData, ISpecProvider s
StateRoot = block.StateRoot;
Timestamp = block.Timestamp;
TotalDifficulty = block.TotalDifficulty ?? 0;
- Transactions = includeFullTransactionData ? block.Transactions.Select((t, idx) => new TransactionForRpc(block.Hash, block.Number, idx, t, block.BaseFeePerGas)).ToArray() : block.Transactions.Select(t => t.Hash).OfType