document how to run merge local testnet with Nethermind (#3110)
This commit is contained in:
parent
c673525591
commit
39f6a6534e
|
@ -47,7 +47,7 @@ func compute_deltas(
|
|||
logScope:
|
||||
topics = "fork_choice"
|
||||
|
||||
proc init*(T: type ForkChoiceBackend,
|
||||
func init*(T: type ForkChoiceBackend,
|
||||
justified_epoch: Epoch,
|
||||
finalized_root: Eth2Digest,
|
||||
finalized_epoch: Epoch): T =
|
||||
|
@ -91,7 +91,7 @@ func extend[T](s: var seq[T], minLen: int) =
|
|||
if s.len < minLen:
|
||||
s.setLen(minLen)
|
||||
|
||||
proc compute_slots_since_epoch_start(slot: Slot): uint64 =
|
||||
func compute_slots_since_epoch_start(slot: Slot): uint64 =
|
||||
slot - slot.epoch().compute_start_slot_at_epoch()
|
||||
|
||||
proc on_tick(self: var Checkpoints, dag: ChainDAGRef, time: Slot): FcResult[void] =
|
||||
|
@ -116,7 +116,7 @@ proc on_tick(self: var Checkpoints, dag: ChainDAGRef, time: Slot): FcResult[void
|
|||
balances: epochRef.effective_balances)
|
||||
ok()
|
||||
|
||||
proc process_attestation_queue(self: var ForkChoice) {.gcsafe.}
|
||||
func process_attestation_queue(self: var ForkChoice) {.gcsafe.}
|
||||
|
||||
proc update_time(self: var ForkChoice, dag: ChainDAGRef, time: Slot): FcResult[void] =
|
||||
if time > self.checkpoints.time:
|
||||
|
@ -152,7 +152,7 @@ func process_attestation*(
|
|||
validator_index = validator_index,
|
||||
new_vote = shortLog(vote)
|
||||
|
||||
proc process_attestation_queue(self: var ForkChoice) =
|
||||
func process_attestation_queue(self: var ForkChoice) =
|
||||
self.queuedAttestations.keepItIf:
|
||||
if it.slot < self.checkpoints.time:
|
||||
for validator_index in it.attesting_indices:
|
||||
|
@ -199,7 +199,7 @@ proc on_attestation*(
|
|||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v0.12.1/specs/phase0/fork-choice.md#should_update_justified_checkpoint
|
||||
proc should_update_justified_checkpoint(
|
||||
func should_update_justified_checkpoint(
|
||||
self: var Checkpoints,
|
||||
dag: ChainDAGRef,
|
||||
epochRef: EpochRef): FcResult[bool] =
|
||||
|
@ -274,7 +274,7 @@ proc process_state(self: var Checkpoints,
|
|||
balances: justifiedEpoch.effective_balances)
|
||||
ok()
|
||||
|
||||
proc process_block*(self: var ForkChoiceBackend,
|
||||
func process_block*(self: var ForkChoiceBackend,
|
||||
block_root: Eth2Digest,
|
||||
parent_root: Eth2Digest,
|
||||
justified_epoch: Epoch,
|
||||
|
@ -329,7 +329,7 @@ proc process_block*(self: var ForkChoice,
|
|||
|
||||
ok()
|
||||
|
||||
proc find_head*(
|
||||
func find_head*(
|
||||
self: var ForkChoiceBackend,
|
||||
justified_epoch: Epoch,
|
||||
justified_root: Eth2Digest,
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 189 KiB |
|
@ -0,0 +1,83 @@
|
|||
# How to run Nethermind
|
||||
https://github.com/NethermindEth/nethermind/pull/3597 documents this aspect.
|
||||
|
||||
## Install dotnet:
|
||||
```
|
||||
https://dotnet.microsoft.com/download
|
||||
```
|
||||
|
||||
## Build Nethermind:
|
||||
```
|
||||
git clone https://github.com/NethermindEth/nethermind.git --recursive -b themerge_kintsugi
|
||||
cd src/Nethermind
|
||||
dotnet build Nethermind.sln -c Release
|
||||
# if src/Nethermind/Nethermind.Runner/bin/Release/net5.0/plugins has no Nethermind.Merge.Plugin.dll plugin then you may need to run the build again
|
||||
dotnet build Nethermind.sln -c Release
|
||||
cd Nethermind.Runner
|
||||
```
|
||||
|
||||
# Run Nethermind
|
||||
run Nethermind
|
||||
```
|
||||
rm -rf bin/Release/net5.0/nethermind_db
|
||||
dotnet run -c Release -- --config themerge_kintsugi_m2 --Merge.TerminalTotalDifficulty 100
|
||||
```
|
||||
|
||||
# Verify that Nimbus runs through test vectors
|
||||
|
||||
- Run `./env.sh nim c -r tests/test_merge_vectors.nim`. It should show output akin to:
|
||||
|
||||
```
|
||||
$ ./env.sh nim c -r tests/test_merge_vectors.nim
|
||||
[Suite] Merge test vectors
|
||||
DBG 2021-11-17 15:31:31.560+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=960621 file=httpclient.nim:191 address=127.0.0.1:9550 msg_len=79
|
||||
DBG 2021-11-17 15:31:31.576+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=960621 file=httpclient.nim:191 address=127.0.0.1:9550 msg_len=493
|
||||
DBG 2021-11-17 15:31:31.597+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=960621 file=httpclient.nim:191 address=127.0.0.1:9550 msg_len=87
|
||||
DBG 2021-11-17 15:31:31.619+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=960621 file=httpclient.nim:191 address=127.0.0.1:9550 msg_len=1196
|
||||
DBG 2021-11-17 15:31:31.634+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=960621 file=httpclient.nim:191 address=127.0.0.1:9550 msg_len=494
|
||||
DBG 2021-11-17 15:31:31.637+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=960621 file=httpclient.nim:191 address=127.0.0.1:9550 msg_len=87
|
||||
DBG 2021-11-17 15:31:31.640+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=960621 file=httpclient.nim:191 address=127.0.0.1:9550 msg_len=1197
|
||||
DBG 2021-11-17 15:31:31.644+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=960621 file=httpclient.nim:191 address=127.0.0.1:9550 msg_len=494
|
||||
[OK] getPayload, executePayload, and forkchoiceUpdated
|
||||
```
|
||||
|
||||
# How to run Nimbus local testnet with Nethermind
|
||||
|
||||
- Run Nethermind.
|
||||
- Check out `nimbus-eth2` branch `kintsugi`
|
||||
|
||||
- Run `./scripts/launch_local_testnet.sh --preset minimal --nodes 4 --disable-htop --stop-at-epoch 7 -- --verify-finalization --discv5:no`
|
||||
|
||||
This creates a 4-node local testnet with 128 validators.
|
||||
|
||||
The Nimbus console output will be similar to
|
||||
```
|
||||
nimbus-eth2$ N=0; while ./scripts/launch_local_testnet.sh --preset minimal --nodes 4 --disable-htop --stop-at-epoch 8 -- --verify-finalization --discv5:no; do N=$((N+1)); echo "That was run #${N}"; sleep 67; done
|
||||
Building: build/nimbus_beacon_node
|
||||
Building: build/nimbus_signing_process
|
||||
Building: build/deposit_contract
|
||||
Build completed successfully: build/nimbus_signing_process
|
||||
Build completed successfully: build/deposit_contract
|
||||
Build completed successfully: build/nimbus_beacon_node
|
||||
NOT 2021-11-17 15:40:11.894+01:00 Generating deposits tid=966934 file=keystore_management.nim:562 totalNewValidators=128 validatorsDir=local_testnet_data/validators secretsDir=local_testnet_data/secrets
|
||||
NOT 2021-11-17 15:40:51.434+01:00 Deposit data written tid=966934 file=deposit_contract.nim:222 filename=local_testnet_data/deposits.json
|
||||
Wrote local_testnet_data/genesis.ssz
|
||||
WRN 2021-11-17 15:40:51.443+01:00 Using insecure password to lock networking key key_path=local_testnet_data/network_key.json
|
||||
INF 2021-11-17 15:40:52.184+01:00 New network key storage was created topics="networking" key_path=local_testnet_data/network_key.json network_public_key=08021221029b0d9c63dc15335b6f1f73dc359a0bda88a84cc7e0346f12e64084673a35a915
|
||||
Wrote local_testnet_data/bootstrap_nodes.txt
|
||||
Wrote local_testnet_data/config.yaml:
|
||||
DEPOSIT_NETWORK_ID: 1
|
||||
PRESET_BASE: minimal
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 128
|
||||
MIN_GENESIS_TIME: 0
|
||||
GENESIS_DELAY: 10
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x0000000000000000000000000000000000000000
|
||||
ETH1_FOLLOW_DISTANCE: 1
|
||||
ALTAIR_FORK_EPOCH: 1
|
||||
MERGE_FORK_EPOCH: 2
|
||||
TERMINAL_TOTAL_DIFFICULTY: 0
|
||||
That was run #1
|
||||
```
|
||||
|
||||
Meanwhile, Nimbus is interacting with Nethermind in preparing, getting, and executing payloads:
|
||||
![./kintsugi_nethermind_logs.png](./kintsugi_nethermind_logs.png)
|
|
@ -13,7 +13,7 @@ set -Eeuo pipefail
|
|||
# eth/catalyst: remove headHash from payloadAttributes
|
||||
|
||||
# Prepare payload
|
||||
resp_prepare_payload=$(curl -sX POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"engine_forkchoiceUpdatedV1","params":[{"headBlockHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a", "safeBlockHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a", "finalizedBlockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}, {"timestamp":"0x5", "random":"0x0000000000000000000000000000000000000000000000000000000000000000", "feeRecipient":"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"}],"id":67}' http://localhost:8545)
|
||||
resp_prepare_payload=$(curl -sX POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"engine_forkchoiceUpdatedV1","params":[{"headBlockHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a", "safeBlockHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a", "finalizedBlockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}, {"timestamp":"0x5", "random":"0x0000000000000000000000000000000000000000000000000000000000000000", "feeRecipient":"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"}],"id":67}' http://localhost:8550)
|
||||
echo "engine_forkchoiceUpdatedV1 response: ${resp_prepare_payload}"
|
||||
|
||||
# Inconsistency in test vectors vs Geth behavior
|
||||
|
@ -22,14 +22,14 @@ empirical_resp_prepare_payload='{"jsonrpc":"2.0","id":67,"result":{"status":"SUC
|
|||
[[ ${resp_prepare_payload} == "${expected_resp_prepare_payload}" ]] || [[ ${resp_prepare_payload} == "${empirical_resp_prepare_payload}" ]] || (echo "Unexpected response to engine_forkchoiceUpdatedV1"; false)
|
||||
|
||||
# Get payload
|
||||
resp_get_payload=$(curl -sX POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"engine_getPayloadV1","params":["0xa247243752eb10b4"],"id":67}' http://localhost:8545)
|
||||
resp_get_payload=$(curl -sX POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"engine_getPayloadV1","params":["0xa247243752eb10b4"],"id":67}' http://localhost:8550)
|
||||
echo "engine_getPayloadV1 response: ${resp_get_payload}"
|
||||
|
||||
expected_resp_get_payload='{"jsonrpc":"2.0","id":67,"result":{"parentHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a","coinbase":"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b","stateRoot":"0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45","receiptRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","random":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","gasLimit":"0x1c9c380","gasUsed":"0x0","timestamp":"0x5","extraData":"0x","baseFeePerGas":"0x7","blockHash":"0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858","transactions":[]}}'
|
||||
[[ ${resp_get_payload} == "${expected_resp_get_payload}" ]] || (echo "Unexpected response to engine_getPayloadV1"; false)
|
||||
|
||||
# Execute payload
|
||||
resp_execute_payload=$(curl -sX POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"engine_executePayloadV1","params":[{"parentHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a","coinbase":"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b","stateRoot":"0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45","receiptRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","random":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","gasLimit":"0x1c9c380","gasUsed":"0x0","timestamp":"0x5","extraData":"0x","baseFeePerGas":"0x7","blockHash":"0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858","transactions":[]}],"id":67}' http://localhost:8545)
|
||||
resp_execute_payload=$(curl -sX POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"engine_executePayloadV1","params":[{"parentHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a","coinbase":"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b","stateRoot":"0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45","receiptRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","random":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","gasLimit":"0x1c9c380","gasUsed":"0x0","timestamp":"0x5","extraData":"0x","baseFeePerGas":"0x7","blockHash":"0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858","transactions":[]}],"id":67}' http://localhost:8550)
|
||||
echo "engine_executePayloadV1 response: ${resp_execute_payload}"
|
||||
|
||||
# SUCCESS vs VALID again, but in the other direction
|
||||
|
@ -38,7 +38,7 @@ empirical_resp_execute_payload='{"jsonrpc":"2.0","id":67,"result":{"status":"VAL
|
|||
[[ ${resp_execute_payload} == "${expected_resp_execute_payload}" ]] || [[ ${resp_execute_payload} == "${empirical_resp_execute_payload}" ]] || (echo "Unexpected response to engine_executePayloadV1"; false)
|
||||
|
||||
# Update the fork choice
|
||||
resp_update_forkchoice=$(curl -sX POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"engine_forkchoiceUpdatedV1","params":[{"headBlockHash":"0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", "safeBlockHash":"0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", "finalizedBlockHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a"}, null],"id":67}' http://localhost:8545)
|
||||
resp_update_forkchoice=$(curl -sX POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"engine_forkchoiceUpdatedV1","params":[{"headBlockHash":"0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", "safeBlockHash":"0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", "finalizedBlockHash":"0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a"}, null],"id":67}' http://localhost:8550)
|
||||
echo "engine_forkchoiceUpdatedV1 response: ${resp_update_forkchoice}"
|
||||
|
||||
expected_resp_update_forkchoice='{"jsonrpc":"2.0","id":67,"result":{"status":"SUCCESS","payloadId":null}}'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{.used.}
|
||||
|
||||
# https://notes.ethereum.org/@9AeMAlpyQYaAAyuj47BzRw/rkwW3ceVY
|
||||
# Monitor traffic: socat -v TCP-LISTEN:9545,fork TCP-CONNECT:127.0.0.1:8545
|
||||
# Monitor traffic: socat -v TCP-LISTEN:9550,fork TCP-CONNECT:127.0.0.1:8550
|
||||
|
||||
import
|
||||
unittest2,
|
||||
|
@ -12,13 +12,13 @@ import
|
|||
|
||||
suite "Merge test vectors":
|
||||
let web3Provider = (waitFor Web3DataProvider.new(
|
||||
default(Eth1Address), "ws://127.0.0.1:8546")).get
|
||||
default(Eth1Address), "http://127.0.0.1:8550")).get
|
||||
|
||||
test "getPayload, executePayload, and forkchoiceUpdated":
|
||||
const feeRecipient =
|
||||
Eth1Address.fromHex("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")
|
||||
let
|
||||
existingBlock = waitFor web3Provider.getBlockByNumber(1)
|
||||
existingBlock = waitFor web3Provider.getBlockByNumber(0)
|
||||
payloadId = waitFor web3Provider.forkchoiceUpdated(
|
||||
existingBlock.hash.asEth2Digest,
|
||||
existingBlock.hash.asEth2Digest,
|
||||
|
|
Loading…
Reference in New Issue