MEV boost script for ropsten and sepolia builder network (#3851)

* MEV boost script for ropsten and sepolia builder network

* networkInfo not a global variable
This commit is contained in:
tersec 2022-07-12 17:50:12 +00:00 committed by GitHub
parent 8a9e6ab8a4
commit e0e7af7aff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 131 additions and 119 deletions

View File

@ -269,8 +269,8 @@ when not defined(gnosisChainBinary):
const const
mainnetMetadata* = eth2Network("shared/mainnet", mainnet) mainnetMetadata* = eth2Network("shared/mainnet", mainnet)
praterMetadata* = eth2Network("shared/prater", goerli) praterMetadata* = eth2Network("shared/prater", goerli)
ropstenMetadata = mergeTestnet("ropsten-beacon-chain", ropsten) ropstenMetadata* = mergeTestnet("ropsten-beacon-chain", ropsten)
sepoliaMetadata = mergeTestnet("sepolia", sepolia) sepoliaMetadata* = mergeTestnet("sepolia", sepolia)
static: static:
for network in [mainnetMetadata, praterMetadata, ropstenMetadata, sepoliaMetadata]: for network in [mainnetMetadata, praterMetadata, ropstenMetadata, sepoliaMetadata]:
checkForkConsistency(network.cfg) checkForkConsistency(network.cfg)

View File

@ -1397,8 +1397,9 @@ proc onSecond(node: BeaconNode, time: Moment) =
bnStatus = BeaconNodeStatus.Stopping bnStatus = BeaconNodeStatus.Stopping
proc runOnSecondLoop(node: BeaconNode) {.async.} = proc runOnSecondLoop(node: BeaconNode) {.async.} =
let sleepTime = chronos.seconds(1) const
const nanosecondsIn1s = float(chronos.seconds(1).nanoseconds) sleepTime = chronos.seconds(1)
nanosecondsIn1s = float(sleepTime.nanoseconds)
while true: while true:
let start = chronos.now(chronos.Moment) let start = chronos.now(chronos.Moment)
await chronos.sleepAsync(sleepTime) await chronos.sleepAsync(sleepTime)

View File

@ -98,6 +98,7 @@ type
seq[ValidatorIndex] | seq[ValidatorIndex] |
seq[Attestation] | seq[Attestation] |
seq[SignedAggregateAndProof] | seq[SignedAggregateAndProof] |
seq[SignedValidatorRegistrationV1] |
seq[RestCommitteeSubscription] | seq[RestCommitteeSubscription] |
seq[RestSyncCommitteeSubscription] | seq[RestSyncCommitteeSubscription] |
seq[RestSyncCommitteeMessage] | seq[RestSyncCommitteeMessage] |

View File

@ -129,6 +129,10 @@ func compute_domain*(
fork_version: Version, fork_version: Version,
genesis_validators_root: Eth2Digest = ZERO_HASH): Eth2Domain = genesis_validators_root: Eth2Digest = ZERO_HASH): Eth2Domain =
## Return the domain for the ``domain_type`` and ``fork_version``. ## Return the domain for the ``domain_type`` and ``fork_version``.
#
# TODO Can't be used as part of a const/static expression:
# https://github.com/nim-lang/Nim/issues/15952
# https://github.com/nim-lang/Nim/issues/19969
let fork_data_root = let fork_data_root =
compute_fork_data_root(fork_version, genesis_validators_root) compute_fork_data_root(fork_version, genesis_validators_root)
result[0..3] = domain_type.data result[0..3] = domain_type.data

View File

@ -10,30 +10,30 @@ import ".."/datatypes/[altair, bellatrix]
{.push raises: [Defect].} {.push raises: [Defect].}
type type
# https://github.com/ethereum/builder-specs/blob/v0.1.0/specs/README.md#validatorregistrationv1 # https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#validatorregistrationv1
ValidatorRegistrationV1 = object ValidatorRegistrationV1* = object
fee_recipient*: ExecutionAddress fee_recipient*: ExecutionAddress
gas_limit*: uint64 gas_limit*: uint64
timestamp*: uint64 timestamp*: uint64
pubkey*: ValidatorPubKey pubkey*: ValidatorPubKey
# https://github.com/ethereum/builder-specs/blob/v0.0.0/specs/README.md#signedvalidatorregistrationv1 # https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#signedvalidatorregistrationv1
SignedValidatorRegistrationV1* = object SignedValidatorRegistrationV1* = object
message*: ValidatorRegistrationV1 message*: ValidatorRegistrationV1
signature*: ValidatorSig signature*: ValidatorSig
# https://github.com/ethereum/builder-specs/blob/v0.1.0/specs/README.md#builderbid # https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#builderbid
BuilderBid = object BuilderBid = object
header*: ExecutionPayloadHeader header*: ExecutionPayloadHeader
value*: UInt256 value*: UInt256
pubkey*: ValidatorPubKey pubkey*: ValidatorPubKey
# https://github.com/ethereum/builder-specs/blob/v0.1.0/specs/README.md#signedbuilderbid # https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#signedbuilderbid
SignedBuilderBid* = object SignedBuilderBid* = object
message*: BuilderBid message*: BuilderBid
signature*: ValidatorSig signature*: ValidatorSig
# https://github.com/ethereum/builder-specs/blob/v0.1.0/specs/README.md#blindedbeaconblockbody # https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#blindedbeaconblockbody
BlindedBeaconBlockBody = object BlindedBeaconBlockBody = object
randao_reveal*: ValidatorSig randao_reveal*: ValidatorSig
eth1_data*: Eth1Data eth1_data*: Eth1Data
@ -46,7 +46,7 @@ type
sync_aggregate*: SyncAggregate sync_aggregate*: SyncAggregate
execution_payload_header*: ExecutionPayloadHeader execution_payload_header*: ExecutionPayloadHeader
# https://github.com/ethereum/builder-specs/blob/v0.1.0/specs/README.md#blindedbeaconblock # https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#blindedbeaconblock
BlindedBeaconBlock* = object BlindedBeaconBlock* = object
slot*: Slot slot*: Slot
proposer_index*: uint64 proposer_index*: uint64
@ -54,11 +54,15 @@ type
state_root*: Eth2Digest state_root*: Eth2Digest
body*: BlindedBeaconBlockBody body*: BlindedBeaconBlockBody
# https://github.com/ethereum/builder-specs/blob/v0.1.0/specs/README.md#signedblindedbeaconblock # https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#signedblindedbeaconblock
SignedBlindedBeaconBlock* = object SignedBlindedBeaconBlock* = object
message*: BlindedBeaconBlock message*: BlindedBeaconBlock
signature*: ValidatorSig signature*: ValidatorSig
const const
# https://github.com/ethereum/builder-specs/blob/v0.0.0/specs/README.md#signing # https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#domain-types
DOMAIN_MEV* = DomainType([byte 0x00, 0x00, 0x00, 0x01]) DOMAIN_APPLICATION_BUILDER* = DomainType([byte 0x00, 0x00, 0x00, 0x01])
# https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/validator.md#constants
EPOCHS_PER_VALIDATOR_REGISTRATION_SUBMISSION* = 1.Epoch
BUILDER_PROPOSAL_DELAY_TOLERANCE* = 1.seconds

View File

@ -12,12 +12,12 @@ import
export chronos, client, rest_types, eth2_rest_serialization export chronos, client, rest_types, eth2_rest_serialization
proc registerValidator*(body: SignedValidatorRegistrationV1 proc registerValidator*(body: seq[SignedValidatorRegistrationV1]
): RestPlainResponse {. ): RestPlainResponse {.
rest, endpoint: "/eth/v1/builder/validators", rest, endpoint: "/eth/v1/builder/validators",
meth: MethodPost.} meth: MethodPost.}
## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/validators.yaml
## https://github.com/ethereum/beacon-APIs/blob/master/apis/validator/register_validator.yaml ## https://github.com/ethereum/beacon-APIs/blob/master/apis/validator/register_validator.yaml
## https://github.com/ethereum/builder-specs/blob/v0.0.0/apis/builder/validators.yaml
proc getHeader*(slot: Slot, proc getHeader*(slot: Slot,
parent_hash: Eth2Digest, parent_hash: Eth2Digest,
@ -25,15 +25,16 @@ proc getHeader*(slot: Slot,
): RestResponse[GetHeaderResponse] {. ): RestResponse[GetHeaderResponse] {.
rest, endpoint: "/eth/v1/builder/header/{slot}/{parent_hash}/{pubkey}", rest, endpoint: "/eth/v1/builder/header/{slot}/{parent_hash}/{pubkey}",
meth: MethodGet.} meth: MethodGet.}
## https://github.com/ethereum/builder-specs/blob/v0.1.0/apis/builder/header.yaml ## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/header.yaml
proc submitBlindedBlock*(body: SignedBlindedBeaconBlock proc submitBlindedBlock*(body: SignedBlindedBeaconBlock
): RestResponse[SubmitBlindedBlockResponse] {. ): RestResponse[SubmitBlindedBlockResponse] {.
rest, endpoint: "/eth/v1/builder/blinded_blocks", rest, endpoint: "/eth/v1/builder/blinded_blocks",
meth: MethodPost.} meth: MethodPost.}
## https://github.com/ethereum/builder-specs/blob/v0.1.0/apis/builder/blinded_blocks.yaml ## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/blinded_blocks.yaml
proc checkBuilderStatus*(): RestPlainResponse {. proc checkBuilderStatus*(): RestPlainResponse {.
rest, endpoint: "/eth/v1/builder/status", rest, endpoint: "/eth/v1/builder/status",
meth: MethodGet.} meth: MethodGet.}
## https://github.com/ethereum/builder-specs/blob/v0.1.0/apis/builder/status.yaml ## https://github.com/ethereum/builder-specs/blob/v0.1.0/apis/builder/status.yaml
## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/status.yaml

View File

@ -1,66 +0,0 @@
# How to run and clone Merge Mock
- Clone and run Merge Mock using https://github.com/protolambda/mergemock#quick-start
```
$ git clone https://github.com/protolambda/mergemock # tested with commit 114c25ad2f07c9bc6c16d2223d3e84c3c512dc9e from 2022-05-25
$ cd mergemock
$ wget https://gist.githubusercontent.com/lightclient/799c727e826483a2804fc5013d0d3e3d/raw/2e8824fa8d9d9b040f351b86b75c66868fb9b115/genesis.json
$ openssl rand -hex 32 | tr -d "\n" > jwt.hex
$ go run . relay
INFO [2022-06-03T08:12:50Z] Loaded JWT secret val="5b63d4c3c389d43809553a3747bce72b13711db8f3501d3e4d6f18a312064eb0"
INFO [2022-06-03T08:12:50Z] Persisted trie from memory database fields.time="5.478µs" gcnodes="0" gcsize="0.00 B" gctime="0s" livenodes="1" livesize="0.00 B" nodes="1" size="151.00 B"
INFO [2022-06-03T08:12:50Z] Loaded most recent local header age="53y2mo6d" hash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" number="0" td="17179869184"
INFO [2022-06-03T08:12:50Z] Loaded most recent local full block age="53y2mo6d" hash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" number="0" td="17179869184"
INFO [2022-06-03T08:12:50Z] Loaded most recent local fast block age="53y2mo6d" hash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" number="0" td="17179869184"
WARNING[2022-06-03T08:12:50Z] Failed to load snapshot, regenerating err="missing or corrupted snapshot"
INFO [2022-06-03T08:12:50Z] Rebuilding state snapshot
INFO [2022-06-03T08:12:50Z] Resuming state snapshot generation accounts="0" elapsed="245.706µs" root="0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45" slots="0" storage="0.00 B"
INFO [2022-06-03T08:12:50Z] Generated state snapshot accounts="1" elapsed="400.253µs" slots="0" storage="50.00 B"
INFO [2022-06-03T08:12:50Z] Engine started listenAddr="127.0.0.1:8551"
INFO [2022-06-03T08:12:50Z] Relay started listenAddr="127.0.0.1:28545"
```
# Run Nimbus's MEV/Merge Mock test script
```
$ ./env nim c -r scripts/test_mev_vector
NOT 2022-06-03 08:15:06.648+00:00 New database from snapshot tid=1389294 file=blockchain_dag.nim:1800 genesisBlockRoot=9058609e genesisStateRoot=0fef5721 tailBlockRoot=9058609e tailStateRoot=0fef5721 fork="(previous_version: 00000000, current_version: 00000000, epoch: 0)" validators=64 tailStateSlot=0 genesisStateSlot=0
DBG 2022-06-03 08:15:06.649+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=1389294 file=httpclient.nim:104 address="ok((id: \"127.0.0.1:8551\", scheme: NonSecure, hostname: \"127.0.0.1\", port: 8551, path: \"\", query: \"\", anchor: \"\", username: \"\", password: \"\", addresses: @[127.0.0.1:8551]))" msg_len=79
DBG 2022-06-03 08:15:06.650+00:00 Message sent to RPC server topics="JSONRPC-HTTP-CLIENT" tid=1389294 file=httpclient.nim:104 address="ok((id: \"127.0.0.1:8551\", scheme: NonSecure, hostname: \"127.0.0.1\", port: 8551, path: \"\", query: \"\", anchor: \"\", username: \"\", password: \"\", addresses: @[127.0.0.1:8551]))" msg_len=506
DBG 2022-06-03 08:15:06.650+00:00 Sending REST request to remote server tid=1389294 file=client.nim:418 remote=127.0.0.1:28545 request=/eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7 http_method=GET
DBG 2022-06-03 08:15:06.651+00:00 Got REST response headers from remote server tid=1389294 file=client.nim:421 status=200 http_method=GET remote=127.0.0.1:28545 request=/eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7 connection=1
DBG 2022-06-03 08:15:06.652+00:00 Received REST response body from remote server tid=1389294 file=client.nim:462 status=200 http_method=GET remote=127.0.0.1:28545 request=/eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7 connection=1 contentType=application/json size=1672
DBG 2022-06-03 08:15:06.652+00:00 Sending REST request to remote server tid=1389294 file=client.nim:508 remote=127.0.0.1:28545 request=/eth/v1/builder/blinded_blocks http_method=POST
DBG 2022-06-03 08:15:06.653+00:00 Opened connection to remote server tid=1389294 file=client.nim:512 remote=127.0.0.1:28545 request=/eth/v1/builder/blinded_blocks http_method=POST connection=2
DBG 2022-06-03 08:15:06.653+00:00 REST request body has been sent tid=1389294 file=client.nim:521 remote=127.0.0.1:28545 request=/eth/v1/builder/blinded_blocks size=2734 http_method=POST connection=2
DBG 2022-06-03 08:15:06.655+00:00 Got REST response headers from remote server tid=1389294 file=client.nim:528 status=200 http_method=POST remote=127.0.0.1:28545 request=/eth/v1/builder/blinded_blocks connection=2
DBG 2022-06-03 08:15:06.655+00:00 Received REST response body from remote server tid=1389294 file=client.nim:567 contentType=application/json size=1247 remote=127.0.0.1:28545 request=/eth/v1/builder/blinded_blocks connection=2
[OK] forkchoiceUpdated, getHeader, and submitBlindedBlock
```
While on the Merge Mock side:
```
INFO [2022-06-03T08:14:57Z] Forkchoice updated attributes="&{12 0x0000000000000000000000000000000000000000000000000000000000000000 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B}" finalized="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" head="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" safe="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131"
INFO [2022-06-03T08:14:57Z] Preparing new payload payload_id="0x0000000000000001" prev_randao="0x0000000000000000000000000000000000000000000000000000000000000000" suggested_fee_recipient="0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B" timestamp="12"
INFO [2022-06-03T08:14:57Z] getHeader parentHash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" pubkey="0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" slot="1"
INFO [2022-06-03T08:14:57Z] Consensus client retrieved prepared payload header parentHash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" pubkey="0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" slot="1"
2022/06/03 08:14:57 http: superfluous response.WriteHeader call from main.(*responseWriter).WriteHeader (utils.go:34)
INFO [2022-06-03T08:14:57Z] http: GET /eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7 200 durationMs="0" method="GET" path="/eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" status="200"
INFO [2022-06-03T08:14:57Z] &{0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B 0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0x0000000000000000000000000000000000000000000000000000000000000000 1 10000000 0 12 [] 7 0x6bc31fed8860b9b4b907cc994f16ffa32f9b08d229cb1767f0d50c299eb137e2 []} method="getPayload"
INFO [2022-06-03T08:14:57Z] http: POST /eth/v1/builder/blinded_blocks 0 durationMs="1" method="POST" path="/eth/v1/builder/blinded_blocks" status="0"
INFO [2022-06-03T08:15:04Z] Forkchoice updated attributes="&{12 0x0000000000000000000000000000000000000000000000000000000000000000 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B}" finalized="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" head="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" safe="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131"
INFO [2022-06-03T08:15:04Z] Preparing new payload payload_id="0x0000000000000002" prev_randao="0x0000000000000000000000000000000000000000000000000000000000000000" suggested_fee_recipient="0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B" timestamp="12"
INFO [2022-06-03T08:15:04Z] getHeader parentHash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" pubkey="0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" slot="1"
INFO [2022-06-03T08:15:04Z] Consensus client retrieved prepared payload header parentHash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" pubkey="0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" slot="1"
2022/06/03 08:15:04 http: superfluous response.WriteHeader call from main.(*responseWriter).WriteHeader (utils.go:34)
INFO [2022-06-03T08:15:04Z] http: GET /eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7 200 durationMs="0" method="GET" path="/eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" status="200"
INFO [2022-06-03T08:15:04Z] &{0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B 0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0x0000000000000000000000000000000000000000000000000000000000000000 1 10000000 0 12 [] 7 0x6bc31fed8860b9b4b907cc994f16ffa32f9b08d229cb1767f0d50c299eb137e2 []} method="getPayload"
INFO [2022-06-03T08:15:04Z] http: POST /eth/v1/builder/blinded_blocks 0 durationMs="1" method="POST" path="/eth/v1/builder/blinded_blocks" status="0"
INFO [2022-06-03T08:15:06Z] Forkchoice updated attributes="&{12 0x0000000000000000000000000000000000000000000000000000000000000000 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B}" finalized="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" head="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" safe="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131"
INFO [2022-06-03T08:15:06Z] Preparing new payload payload_id="0x0000000000000003" prev_randao="0x0000000000000000000000000000000000000000000000000000000000000000" suggested_fee_recipient="0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B" timestamp="12"
INFO [2022-06-03T08:15:06Z] getHeader parentHash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" pubkey="0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" slot="1"
INFO [2022-06-03T08:15:06Z] Consensus client retrieved prepared payload header parentHash="0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131" pubkey="0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" slot="1"
2022/06/03 08:15:06 http: superfluous response.WriteHeader call from main.(*responseWriter).WriteHeader (utils.go:34)
INFO [2022-06-03T08:15:06Z] http: GET /eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7 200 durationMs="0" method="GET" path="/eth/v1/builder/header/1/0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131/0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7" status="200"
INFO [2022-06-03T08:15:06Z] &{0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B 0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0x0000000000000000000000000000000000000000000000000000000000000000 1 10000000 0 12 [] 7 0x6bc31fed8860b9b4b907cc994f16ffa32f9b08d229cb1767f0d50c299eb137e2 []} method="getPayload"
INFO [2022-06-03T08:15:06Z] http: POST /eth/v1/builder/blinded_blocks 0 durationMs="1" method="POST" path="/eth/v1/builder/blinded_blocks" status="0"
```

View File

@ -1,64 +1,131 @@
import import
std/macros, std/macros,
chronos, presto/client, web3/ethtypes, chronos, presto/client,
../beacon_chain/spec/mev/rest_bellatrix_mev_calls ../beacon_chain/spec/mev/rest_bellatrix_mev_calls
from ../beacon_chain/beacon_chain_db import DepositContractSnapshot from std/times import epochTime
from ../beacon_chain/eth1/eth1_monitor import from stew/byteutils import fromHex
Eth1Monitor, Web3DataProvider, asEth2Digest, ensureDataProvider, from ../beacon_chain/beacon_clock import BeaconClock, init, now
forkchoiceUpdated, getBlockByNumber, init, new from ../beacon_chain/networking/network_metadata import
from ../beacon_chain/networking/network_metadata import Eth1Network ropstenMetadata, sepoliaMetadata
from ../beacon_chain/spec/datatypes/bellatrix import SignedBeaconBlock from ../beacon_chain/spec/datatypes/bellatrix import SignedBeaconBlock
from ../beacon_chain/spec/eth2_apis/rest_beacon_calls import getBlockV2
from ../beacon_chain/spec/helpers import compute_domain, compute_signing_root from ../beacon_chain/spec/helpers import compute_domain, compute_signing_root
from ../tests/testdbutil import makeTestDB
type NetworkInfo = object
genesisTime: uint64
restUrl: string
runtimeConfig: RuntimeConfig
genesisValidatorsRoot: Eth2Digest
builderSigningDomain: Eth2Domain
proposerSigningDomain: Eth2Domain
const const
feeRecipient = feeRecipient =
Eth1Address.fromHex("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b") ExecutionAddress.fromHex("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")
web3Url = "http://127.0.0.1:8551" ropstenInfo = NetworkInfo(
restUrl = "http://127.0.0.1:28545" genesisTime: 1653922800,
restUrl: "https://builder-relay-ropsten.flashbots.net/",
runtimeConfig: ropstenMetadata.cfg,
genesisValidatorsRoot: Eth2Digest.fromHex(
"0x44f1e56283ca88b35c789f7f449e52339bc1fefe3a45913a43a6d16edcd33cf1"),
builderSigningDomain: Eth2Domain.fromHex(
"0x00000001d5531fd3f3906407da127817ef33c71868154c6021bdaac6866406d8"),
proposerSigningDomain: Eth2Domain.fromHex(
"0x000000003cfa3bacace47d41ee4e3e7f989ed9c7e3e10904d2d67b36f1fda0b5")
)
sepoliaInfo = NetworkInfo(
genesisTime: 1655733600,
restUrl: "https://builder-relay-sepolia.flashbots.net/",
runtimeConfig: sepoliaMetadata.cfg,
genesisValidatorsRoot: Eth2Digest.fromHex(
"0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"),
builderSigningDomain: Eth2Domain.fromHex(
"0x00000001d3010778cd08ee514b08fe67b6c503b510987a4ce43f42306d97c67c"),
proposerSigningDomain: Eth2Domain.fromHex(
"0x0000000036fa50131482fe2af396daf210839ea6dcaaaa6372e95478610d7e08")
)
proc main() {.async.} = proc getValidatorRegistration(
forkVersion: Version, builderSigningDomain: Eth2Domain, timestamp: uint64,
pubkey: ValidatorPubKey, privkey: ValidatorPrivKey):
SignedValidatorRegistrationV1 =
var validatorRegistration = SignedValidatorRegistrationV1(
message: ValidatorRegistrationV1(
fee_recipient: feeRecipient,
gas_limit: 20000000,
timestamp: timestamp,
pubkey: pubkey))
let domain = compute_domain(DOMAIN_APPLICATION_BUILDER, forkVersion)
doAssert domain == builderSigningDomain
let signingRoot = compute_signing_root(validatorRegistration.message, domain)
validatorRegistration.signature =
blsSign(privkey, signingRoot.data).toValidatorSig
validatorRegistration
proc main(networkInfo: NetworkInfo) {.async.} =
let let
db = makeTestDB(64) restClient = RestClientRef.new(networkInfo.restUrl).get
elMonitor = Eth1Monitor.init( localClient = RestClientRef.new("http://127.0.0.1:5052").get
defaultRuntimeConfig, db, nil, @[web3Url],
none(DepositContractSnapshot), none(Eth1Network), false, none(seq[byte]))
web3Provider = (await Web3DataProvider.new(
default(Eth1Address), web3Url, some(@[0xcdu8, 0xcau8, 0xe4u8, 0xecu8, 0x6au8, 0x3du8, 0x0bu8, 0x4bu8, 0x97u8, 0x00u8, 0x21u8, 0x21u8, 0xb0u8, 0x5bu8, 0x22u8, 0xe2u8, 0xd6u8, 0xd5u8, 0x7fu8, 0xaau8, 0x51u8, 0x53u8, 0x84u8, 0x5fu8, 0xe0u8, 0x4fu8, 0x06u8, 0xb5u8, 0xf3u8, 0xadu8, 0xc4u8, 0x0bu8]))).get
restClient = RestClientRef.new(restUrl).get
privKey = ValidatorPrivKey.init( privKey = ValidatorPrivKey.init(
"0x066e3bdc0415530e5c7fed6382d5c822c192b620203cf669903e1810a8c67d06") "0x066e3bdc0415530e5c7fed6382d5c822c192b620203cf669903e1810a8c67d06")
pubKey = privKey.toPubKey.toPubKey pubKey = privKey.toPubKey.toPubKey
await elMonitor.ensureDataProvider() # Builder status sanity check
doAssert (await restClient.checkBuilderStatus()).status == 200
# Validator registration
let validatorRegistration = getValidatorRegistration(
networkInfo.runtimeConfig.GENESIS_FORK_VERSION,
networkInfo.builderSigningDomain, epochTime().uint64, pubkey, privkey)
doAssert 200 ==
(await restClient.registerValidator(@[validatorRegistration])).status
# For getHeader, need previous block's hash, to build on
let let
existingBlock = await web3Provider.getBlockByNumber(0) beaconClock = BeaconClock.init(networkInfo.genesis_time)
payloadId = await elMonitor.forkchoiceUpdated( curSlot = beaconClock.now.toSlot.slot
existingBlock.hash.asEth2Digest,
existingBlock.hash.asEth2Digest, echo "curSlot = ", curSlot
existingBlock.timestamp.uint64 + 12, let latestBlock = await localClient.getBlockV2(
ZERO_HASH.data, # Random BlockIdent(kind: BlockQueryKind.Slot, slot: curSlot),
feeRecipient) networkInfo.runtimeConfig)
blindedHeader = await restClient.getHeader( doAssert latestBlock.isSome
1.Slot, existingBlock.hash.asEth2Digest, pubKey) let bh =
(latestBlock.get)[].bellatrixData.message.body.execution_payload.block_hash
doAssert bh != default(Eth2Digest)
# Get blinded execution header
let blindedHeader = await restClient.getHeader(curSlot + 1, bh, pubKey)
if blindedHeader.status != 200:
echo "blindedHeader = ", blindedHeader
doAssert blindedHeader.status == 200
var blck: SignedBlindedBeaconBlock var blck: SignedBlindedBeaconBlock
blck.message.slot = beaconClock.now.toSlot.slot + 1
blck.message.proposer_index = 100
blck.message.parent_root =
hash_tree_root((latestBlock.get)[].bellatrixData.message)
blck.message.state_root = blck.message.parent_root
blck.message.body.execution_payload_header = blck.message.body.execution_payload_header =
blindedHeader.data.data.message.header blindedHeader.data.data.message.header
# Can't be const: let proposerSigningDomain = compute_domain(
# https://github.com/nim-lang/Nim/issues/15952 DOMAIN_BEACON_PROPOSER, networkInfo.runtimeConfig.BELLATRIX_FORK_VERSION,
# https://github.com/nim-lang/Nim/issues/19969 genesis_validators_root = networkInfo.genesisValidatorsRoot)
let mergeMockDomain = compute_domain( doAssert proposerSigningDomain == networkInfo.proposerSigningDomain
DOMAIN_BEACON_PROPOSER, defaultRuntimeConfig.BELLATRIX_FORK_VERSION)
blck.signature = blsSign( blck.signature = blsSign(
privKey, compute_signing_root( privKey, compute_signing_root(
hash_tree_root(blck.message), mergeMockDomain).data).toValidatorSig hash_tree_root(blck.message), proposerSigningDomain).data).toValidatorSig
let submitBlindedBlockResponse = let submitBlindedBlockResponse =
await restClient.submitBlindedBlock(blck) await restClient.submitBlindedBlock(blck)
if submitBlindedBlockResponse.status != 200:
echo submitBlindedBlockResponse
doAssert submitBlindedBlockResponse.status == 200 doAssert submitBlindedBlockResponse.status == 200
doAssert submitBlindedBlockResponse.data.data is ExecutionPayload doAssert submitBlindedBlockResponse.data.data is ExecutionPayload
@ -83,4 +150,4 @@ proc main() {.async.} =
echo fullBlck.message.body.execution_payload echo fullBlck.message.body.execution_payload
echo submitBlindedBlockResponse.data.data echo submitBlindedBlockResponse.data.data
waitFor main() waitFor main(sepoliaInfo)