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:
parent
8a9e6ab8a4
commit
e0e7af7aff
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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] |
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
|
||||||
```
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue