Merge branch 'feat_eip-7688' into feat_eip-6493
This commit is contained in:
commit
176a8117eb
|
@ -213,7 +213,7 @@ jobs:
|
|||
|
||||
devbuild:
|
||||
name: "Developer builds"
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ['self-hosted','ubuntu-22.04']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
[submodule "vendor/mainnet"]
|
||||
path = vendor/mainnet
|
||||
url = https://github.com/eth-clients/mainnet.git
|
||||
ignore = untracked
|
||||
branch = main
|
||||
[submodule "vendor/nim-eth2-scenarios"]
|
||||
path = vendor/nim-eth2-scenarios
|
||||
url = https://github.com/status-im/nim-eth2-scenarios
|
||||
|
@ -170,11 +175,6 @@
|
|||
url = https://github.com/status-im/nim-presto.git
|
||||
ignore = untracked
|
||||
branch = master
|
||||
[submodule "vendor/eth2-networks"]
|
||||
path = vendor/eth2-networks
|
||||
url = https://github.com/eth-clients/eth2-networks.git
|
||||
ignore = untracked
|
||||
branch = master
|
||||
[submodule "vendor/nim-taskpools"]
|
||||
path = vendor/nim-taskpools
|
||||
url = https://github.com/status-im/nim-taskpools
|
||||
|
|
|
@ -907,12 +907,14 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
|||
+ getAggregatedAttestationDataScore() test vectors OK
|
||||
+ getAttestationDataScore() test vectors OK
|
||||
+ getLiveness() response deserialization test OK
|
||||
+ getProduceBlockResponseV3Score() default test OK
|
||||
+ getProduceBlockResponseV3Score() test vectors OK
|
||||
+ getSyncCommitteeContributionDataScore() test vectors OK
|
||||
+ getSyncCommitteeMessageDataScore() test vectors OK
|
||||
+ getUniqueVotes() test vectors OK
|
||||
+ normalizeUri() test vectors OK
|
||||
```
|
||||
OK: 12/12 Fail: 0/12 Skip: 0/12
|
||||
OK: 14/14 Fail: 0/14 Skip: 0/14
|
||||
## Validator change pool testing suite
|
||||
```diff
|
||||
+ addValidatorChangeMessage/getAttesterSlashingMessage OK
|
||||
|
|
2
Makefile
2
Makefile
|
@ -593,7 +593,7 @@ define MAKE_DEPOSIT
|
|||
|
||||
build/deposit_contract sendDeposits \
|
||||
$(2) \
|
||||
--deposit-contract=$$(cat vendor/eth2-networks/shared/$(1)/deposit_contract.txt) \
|
||||
--deposit-contract=$$(cat vendor/$(1)/metadata/deposit_contract.txt) \
|
||||
--deposits-file=nbc-$(1)-deposits.json \
|
||||
--min-delay=$(DEPOSITS_DELAY) \
|
||||
--max-delay=$(DEPOSITS_DELAY) \
|
||||
|
|
|
@ -73,7 +73,7 @@ proc initLightClient*(
|
|||
headBlockHash = blckPayload.block_hash,
|
||||
safeBlockHash = beaconHead.safeExecutionBlockHash,
|
||||
finalizedBlockHash = beaconHead.finalizedExecutionBlockHash,
|
||||
payloadAttributes = none attributes)
|
||||
payloadAttributes = Opt.none attributes)
|
||||
|
||||
case node.dag.cfg.consensusForkAtEpoch(
|
||||
forkyBlck.message.slot.epoch)
|
||||
|
|
|
@ -1047,7 +1047,7 @@ type
|
|||
|
||||
monitoringType* {.
|
||||
desc: "Enable block monitoring which are seen by beacon node (BETA)"
|
||||
defaultValue: BlockMonitoringType.Disabled
|
||||
defaultValue: BlockMonitoringType.Event
|
||||
name: "block-monitor-type".}: BlockMonitoringType
|
||||
|
||||
SigningNodeConf* = object
|
||||
|
|
|
@ -2408,7 +2408,7 @@ proc updateHead*(
|
|||
|
||||
if dag.headState.kind > lastHeadKind:
|
||||
case dag.headState.kind
|
||||
of ConsensusFork.Phase0 .. ConsensusFork.Bellatrix, ConsensusFork.Electra:
|
||||
of ConsensusFork.Phase0 .. ConsensusFork.Bellatrix:
|
||||
discard
|
||||
of ConsensusFork.Capella:
|
||||
if dag.vanityLogs.onUpgradeToCapella != nil:
|
||||
|
@ -2416,6 +2416,9 @@ proc updateHead*(
|
|||
of ConsensusFork.Deneb:
|
||||
if dag.vanityLogs.onUpgradeToDeneb != nil:
|
||||
dag.vanityLogs.onUpgradeToDeneb()
|
||||
of ConsensusFork.Electra:
|
||||
if dag.vanityLogs.onUpgradeToElectra != nil:
|
||||
dag.vanityLogs.onUpgradeToElectra()
|
||||
|
||||
if dag.vanityLogs.onKnownBlsToExecutionChange != nil and
|
||||
checkBlsToExecutionChanges(
|
||||
|
|
|
@ -184,7 +184,7 @@ proc updateExecutionClientHead*(
|
|||
headBlockHash = headExecutionBlockHash,
|
||||
safeBlockHash = newHead.safeExecutionBlockHash,
|
||||
finalizedBlockHash = newHead.finalizedExecutionBlockHash,
|
||||
payloadAttributes = none attributes)
|
||||
payloadAttributes = Opt.none attributes)
|
||||
|
||||
# Can't use dag.head here because it hasn't been updated yet
|
||||
let
|
||||
|
@ -374,7 +374,7 @@ proc runProposalForkchoiceUpdated*(
|
|||
let (status, _) = await self.elManager.forkchoiceUpdated(
|
||||
headBlockHash, safeBlockHash,
|
||||
beaconHead.finalizedExecutionBlockHash,
|
||||
payloadAttributes = some fcPayloadAttributes)
|
||||
payloadAttributes = Opt.some fcPayloadAttributes)
|
||||
debug "Fork-choice updated for proposal", status
|
||||
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
[0;40;37m[0;0;0;0t[1;171;171;171t
|
||||
[22C[33m[1;171;87;0t[8C..-|\_/|
|
||||
[37m[1;171;171;171t [32m[1;0;171;0t text [37m[1;171;171;171t[10C[33m[1;171;87;0t[9C.-'[37m[1;171;171;171t.[33m[1;171;87;0t.d [37m[1;171;171;171t:.:[33m[1;171;87;0t $
|
||||
[37m[1;171;171;171t[18C[33m[1;171;87;0t[8C(_[37m[1;171;171;171t:[33m[1;171;87;0t __. [37m[1;171;171;171t::[33m[1;171;87;0t:::$
|
||||
[37m[1;171;171;171t[18C[33m[1;171;87;0t[9C`-' ? ::[37m[1;171;171;171t::[33m[1;171;87;0t $
|
||||
[37m[1;171;171;171t[18C[33m[1;171;87;0t[16C\ [37m[1;171;171;171t::[33m[1;171;87;0t:: $
|
||||
[37m[1;171;171;171t[18C[33m[1;171;87;0t[17C\::[37m[1;171;171;171t::[33m[1;171;87;0t::$
|
||||
[37m[1;171;171;171t[8C[32m[1;0;171;0tarea[37m[1;171;171;171t[8C[33m[1;171;87;0t[16C\ :::[37m[1;171;171;171t::[33m[1;171;87;0t$
|
||||
[37m[1;171;171;171t[27C[33m[1;171;87;0t[10C|[37m[1;171;171;171t:[33m[1;171;87;0t.[37m[1;171;171;171t:[33m[1;171;87;0t:: $
|
||||
[37m[1;171;171;171t[33C[33m[1;171;87;0t `| [37m[1;171;171;171t::::[33m[1;171;87;0t $..__
|
||||
[37m[1;171;171;171t[33C[33m[1;171;87;0t[5C`.:::[37m[1;171;171;171t:[33m[1;171;87;0t:[37m[1;171;171;171t:.[33m[1;171;87;0t:[37m[1;171;171;171t:.[33m[1;171;87;0t`-.
|
||||
[37m[1;171;171;171t[33C[33m[1;171;87;0t[6C|::::[37m[1;171;171;171t:[33m[1;171;87;0t::[37m[1;171;171;171t:[33m[1;171;87;0t::[37m[1;171;171;171t:[33m[1;171;87;0t::`--.
|
||||
[37m[1;171;171;171t[14C[32m[1;0;171;0there[37m[1;171;171;171t[18C[33m[1;171;87;0t `.:::[37m[1;171;171;171t:.:[33m[1;171;87;0t:[37m[1;171;171;171t:::[33m[1;171;87;0t:[37m[1;171;171;171t::[33m[1;171;87;0t::[37m[1;171;171;171t:[33m[1;171;87;0t`---.....
|
||||
[37m[1;171;171;171t[28C[33m[1;171;87;0t [37m[1;171;171;171t [33m[1;171;87;0t[5C`.[37m[1;171;171;171t:[33m[1;171;87;0t:::[37m[1;171;171;171t::[33m[1;171;87;0t:::[37m[1;171;171;171t:::[33m[1;171;87;0t::::[37m[1;171;171;171t::[33m[1;171;87;0t:::[37m[1;171;171;171t::[33m[1;171;87;0t`\
|
||||
[37m[1;171;171;171t[28C[33m[1;171;87;0t[7C[37m[1;171;171;171t [33m[1;171;87;0t[6C|:[37m[1;171;171;171t:[33m[1;171;87;0t::[37m[1;171;171;171t:::::::[33m[1;171;87;0t:::[37m[1;171;171;171t::[33m[1;171;87;0t::[37m[1;171;171;171t::[33m[1;171;87;0t:[37m[1;171;171;171t::::[33m[1;171;87;0t|
|
||||
[37m[1;171;171;171t[28C[33m[1;171;87;0t[7C[37m[1;171;171;171t [33m[1;171;87;0t[6C|:[37m[1;171;171;171t:[33m[1;171;87;0t:::[37m[1;171;171;171t::[33m[1;171;87;0t:::[37m[1;171;171;171t::[33m[1;171;87;0t:[37m[1;171;171;171t:::[33m[1;171;87;0t:[37m[1;171;171;171t:[33m[1;171;87;0t:[37m[1;171;171;171t::[33m[1;171;87;0t:[37m[1;171;171;171t:[33m[1;171;87;0t|[37m[1;171;171;171t:[33m[1;171;87;0t|
|
||||
[37m[1;171;171;171t[31C[33m[1;171;87;0t [37m[1;171;171;171t [33m[1;171;87;0t[6C|[37m[1;171;171;171t::[33m[1;171;87;0t:[37m[1;171;171;171t::[33m[1;171;87;0t:[37m[1;171;171;171t:::::[33m[1;171;87;0t:|[37m[1;171;171;171t:[33m[1;171;87;0t::[37m[1;171;171;171t::[33m[1;171;87;0t:[37m[1;171;171;171t::::[33m[1;171;87;0t|[37m[1;171;171;171t:[33m[1;171;87;0t|
|
||||
[37m[1;171;171;171t[36C[33m[1;171;87;0t[6C':[37m[1;171;171;171t::[33m[1;171;87;0t)___..----\ [37m[1;171;171;171t:[33m[1;171;87;0t::[37m[1;171;171;171t:[33m[1;171;87;0t:| .`. \
|
||||
[37m[1;171;171;171t[37C[33m[1;171;87;0t[5C|:[37m[1;171;171;171t::[33m[1;171;87;0t| | :|[5C`.[37m[1;171;171;171t::[33m[1;171;87;0t::|: : `.`.
|
||||
[37m[1;171;171;171t[21C[32m[1;0;171;0t()[37m[1;171;171;171t [32m[1;0;171;0t()[33m[1;171;87;0t [36m[1;0;171;171tO[33m[1;171;87;0t [37m[1;171;171;171t [36m[1;0;171;171tO[33m[1;171;87;0t |[37m[1;171;171;171t:[33m[1;171;87;0t::| |. |[7C|:[37m[1;171;171;171t::[33m[1;171;87;0t| `.: |[37m[1;171;171;171t:[33m[1;171;87;0t|
|
||||
[37m[1;171;171;171t[23C[32m[1;0;171;0t\[37m[1;171;171;171t [32m[1;0;171;0t/[37m[1;171;171;171t [33m[1;171;87;0t[6C[36m[1;0;171;171t\[33m[1;171;87;0t [36m[1;0;171;171t/[33m[1;171;87;0t [37m[1;171;171;171t [33m[1;171;87;0t |:[37m[1;171;171;171t:[33m[1;171;87;0t:| | :|[7C`.[37m[1;171;171;171t:[33m[1;171;87;0t:[37m[1;171;171;171t:[33m[1;171;87;0t`. .:`.`.
|
||||
[37m[1;171;171;171t[11C[32m[1;0;171;0t()[37m[1;171;171;171t [32m[1;0;171;0t()() [37m[1;171;171;171t [32m[1;0;171;0t()[37m[1;171;171;171t [33m[1;171;87;0t [32m[1;0;171;0t()[33m[1;171;87;0t [36m[1;0;171;171tO[33m[1;171;87;0t [32m[1;0;171;0t()[33m[1;171;87;0t |:[37m[1;171;171;171t:[33m[1;171;87;0t:| |: |[9C:[37m[1;171;171;171t:[33m[1;171;87;0t:[37m[1;171;171;171t:[33m[1;171;87;0t| |::|`.`.
|
||||
[37m[1;171;171;171t[13C[32m[1;0;171;0t\[37m[1;171;171;171t [32m[1;0;171;0t /[37m[1;171;171;171t [32m[1;0;171;0t\ /[37m[1;171;171;171t[6C[32m[1;0;171;0t/[33m[1;171;87;0t [36m[1;0;171;171t/[33m[1;171;87;0t [32m[1;0;171;0t/[33m[1;171;87;0t |[37m[1;171;171;171t:[33m[1;171;87;0t:[37m[1;171;171;171t:[33m[1;171;87;0t| | :|[9C|:[37m[1;171;171;171t:[33m[1;171;87;0t:| | :| )))
|
||||
[37m[1;171;171;171t [32m[1;0;171;0t()[37m[1;171;171;171t [32m[1;0;171;0t()[37m[1;171;171;171t [36m[1;0;171;171t O[32m[1;0;171;0t()[37m[1;171;171;171t [36m[1;0;171;171tO[37m[1;171;171;171t [32m[1;0;171;0t() [37m[1;171;171;171t [32m[1;0;171;0t()[37m[1;171;171;171t [36m[1;0;171;171tO[37m[1;171;171;171t [33m[1;171;87;0t [32m[1;0;171;0t()[33m[1;171;87;0t |:::||.:.| [32m[1;0;171;0t()[33m[1;171;87;0t [32m[1;0;171;0t()[33m[1;171;87;0t:[37m[1;171;171;171t:[33m[1;171;87;0t| |:..;((( [32m[1;0;171;0t()
|
||||
[34m[1;0;0;171t.[37m[1;171;171;171t [32m[1;0;171;0t\[34m[1;0;0;171t.[32m[1;0;171;0t /[34m[1;0;0;171t.[37m[1;171;171;171t [36m[1;0;171;171t\[34m[1;0;0;171t.[36m[1;0;171;171t /[32m[1;0;171;0t/[37m[1;171;171;171t [36m[1;0;171;171tO[34m[1;0;0;171t.[37m[1;171;171;171t [36m[1;0;171;171t/[34m[1;0;0;171t.[37m[1;171;171;171t [34m[1;0;0;171t.[37m[1;171;171;171t [32m[1;0;171;0t\[34m[1;0;0;171t.[32m[1;0;171;0t /[34m[1;0;0;171t.[37m[1;171;171;171t [36m[1;0;171;171t\[37m[1;171;171;171t [36m[1;0;171;171t/[34m[1;0;0;171t.[37m[1;171;171;171t [34m[1;0;0;171t.[33m[1;171;87;0t [32m[1;0;171;0t\[33m[1;171;87;0t .'[37m[1;171;171;171t:[33m[1;171;87;0t:.'|::'|[34m[1;0;0;171t.[33m[1;171;87;0t [32m[1;0;171;0t/[34m[1;0;0;171t.[33m[1;171;87;0t [34m[1;0;0;171t.[33m[1;171;87;0t [32m[1;0;171;0t/[34m[1;0;0;171t.[33m[1;171;87;0t|[37m[1;171;171;171t:[33m[1;171;87;0t:|[34m[1;0;0;171t.[33m[1;171;87;0t ` :.\ `[32m[1;0;171;0t/[33m[1;171;87;0t [34m[1;0;0;171t.
|
||||
....[32m[1;0;171;0t()[36m[1;0;171;171tO[34m[1;0;0;171t...[36m[1;0;171;171tO[32m[1;0;171;0t()[34m[1;0;0;171t...[36m[1;0;171;171t\[32m[1;0;171;0t()()[34m[1;0;0;171t....[32m[1;0;171;0t()[36m[1;0;171;171tO[34m[1;0;0;171t...[36m[1;0;171;171tO[34m[1;0;0;171t.[32m[1;0;171;0t()[34m[1;0;0;171t....[32m[1;0;171;0t()[33m[1;171;87;0t|[37m[1;171;171;171t:[33m[1;171;87;0t:[37m[1;171;171;171t:[33m[1;171;87;0t| |_M[32m[1;0;171;0t()()[34m[1;0;0;171t....[32m[1;0;171;0t()[34m[1;0;0;171t.[33m[1;171;87;0t.::[37m[1;171;171;171t:[33m[1;171;87;0t|[34m[1;0;0;171t.[32m[1;0;171;0t()[33m[1;171;87;0t|: :[32m[1;0;171;0t()[34m[1;0;0;171t..[32m[1;0;171;0t()
|
||||
\[34m[1;0;0;171t..[32m[1;0;171;0t/[34m[1;0;0;171t...[36m[1;0;171;171t\[34m[1;0;0;171t.[36m[1;0;171;171t/[34m[1;0;0;171t...[32m[1;0;171;0t\[34m[1;0;0;171t..[32m[1;0;171;0t/[34m[1;0;0;171t....[32m[1;0;171;0t\[34m[1;0;0;171t..[32m[1;0;171;0t/[34m[1;0;0;171t...[36m[1;0;171;171t\[34m[1;0;0;171t.[36m[1;0;171;171t/[34m[1;0;0;171t....[32m[1;0;171;0t\[34m[1;0;0;171t..[32m[1;0;171;0t/[34m[1;0;0;171t..[33m[1;171;87;0t|:[37m[1;171;171;171t:[33m[1;171;87;0t:|[32m[1;0;171;0t\[34m[1;0;0;171t..[32m[1;0;171;0t/[34m[1;0;0;171t....[32m[1;0;171;0t\[34m[1;0;0;171t..[32m[1;0;171;0t/[34m[1;0;0;171t...[33m[1;171;87;0t|[37m[1;171;171;171t:[33m[1;171;87;0t::<[34m[1;0;0;171t...[32m[1;0;171;0t\[33m[1;171;87;0t_M[32m[1;0;171;0t/[33m[1;171;87;0t|[34m[1;0;0;171t.....
|
||||
[32m[1;0;171;0t ()[34m[1;0;0;171t:::::[36m[1;0;171;171tO[34m[1;0;0;171t:::::[32m[1;0;171;0t()[34m[1;0;0;171t::::::[32m[1;0;171;0t()[34m[1;0;0;171t:::::[36m[1;0;171;171tO[34m[1;0;0;171t::::::[32m[1;0;171;0t()[34m[1;0;0;171t:::[33m[1;171;87;0t|_N_|[34m[1;0;0;171t:[32m[1;0;171;0t()[34m[1;0;0;171t::::::[32m[1;0;171;0t()[34m[1;0;0;171t::::[33m[1;171;87;0t|_N_|[34m[1;0;0;171t::::[32m[1;0;171;0t()[34m[1;0;0;171t:::::::
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
..-|\_/|
|
||||
text .-'..d :.: $
|
||||
(_: __. :::::$
|
||||
`-' ? :::: $
|
||||
\ :::: $
|
||||
\::::::$
|
||||
area \ :::::$
|
||||
|:.::: $
|
||||
`| :::: $..__
|
||||
`.::::::.::.`-.
|
||||
|:::::::::::::`--.
|
||||
here `.::::.:::::::::::`---.....
|
||||
`.:::::::::::::::::::::::`\
|
||||
|:::::::::::::::::::::::::|
|
||||
|:::::::::::::::::::::::|:|
|
||||
|::::::::::::|::::::::::|:|
|
||||
':::)___..----\ :::::| .`. \
|
||||
|:::| | :| `.::::|: : `.`.
|
||||
() () O O |:::| |. | |:::| `.: |:|
|
||||
\ / \ / |:::| | :| `.:::`. .:`.`.
|
||||
() ()() () () O () |:::| |: | ::::| |::|`.`.
|
||||
\ / \ / / / / |:::| | :| |:::| | :| )))
|
||||
() () O() O () () O () |:::||.:.| () ()::| |:..;((( ()
|
||||
. \. /. \. // O. /. . \. /. \ /. . \ .'::.'|::'|. /. . /.|::|. ` :.\ `/ .
|
||||
....()O...O()...\()()....()O...O.()....()|:::| |_M()()....()..:::|.()|: :()..()
|
||||
\../...\./...\../....\../...\./....\../..|:::|\../....\../...|:::<...\_M/|.....
|
||||
():::::O:::::()::::::():::::O::::::():::|_N_|:()::::::()::::|_N_|::::():::::::
|
|
@ -34,6 +34,10 @@ type
|
|||
# in case of chain reorgs around the upgrade.
|
||||
onUpgradeToDeneb*: LogProc
|
||||
|
||||
# Gets displayed on upgrade to Electra. May be displayed multiple times
|
||||
# in case of chain reorgs around the upgrade.
|
||||
onUpgradeToElectra*: LogProc
|
||||
|
||||
# Created by http://beatscribe.com/ (beatscribe#1008 on Discord)
|
||||
# These need to be the main body of the log not to be reformatted or escaped.
|
||||
|
||||
|
@ -47,3 +51,6 @@ proc capellaBlink*() = notice "\n" & staticRead("capella" / "blink.ans")
|
|||
|
||||
proc denebMono*() = notice "\n" & staticRead("deneb" / "mono.txt")
|
||||
proc denebColor*() = notice "\n" & staticRead("deneb" / "color.ans")
|
||||
|
||||
proc electraMono*() = notice "\n" & staticRead("electra" / "mono.txt")
|
||||
proc electraColor*() = notice "\n" & staticRead("electra" / "color.ans")
|
||||
|
|
|
@ -123,25 +123,25 @@ contract(DepositContract):
|
|||
|
||||
proc deployContract*(web3: Web3, code: seq[byte]): Future[ReceiptObject] {.async.} =
|
||||
let tr = TransactionArgs(
|
||||
`from`: web3.defaultAccount.some,
|
||||
data: code.some,
|
||||
gas: Quantity(3000000).some,
|
||||
gasPrice: Quantity(1).some)
|
||||
`from`: Opt.some web3.defaultAccount,
|
||||
data: Opt.some code,
|
||||
gas: Opt.some Quantity(3000000),
|
||||
gasPrice: Opt.some Quantity(1))
|
||||
|
||||
let r = await web3.send(tr)
|
||||
result = await web3.getMinedTransactionReceipt(r)
|
||||
|
||||
proc sendEth(web3: Web3, to: Eth1Address, valueEth: int): Future[TxHash] =
|
||||
let tr = TransactionArgs(
|
||||
`from`: web3.defaultAccount.some,
|
||||
`from`: Opt.some web3.defaultAccount,
|
||||
# TODO: Force json-rpc to generate 'data' field
|
||||
# should not be needed anymore, new execution-api schema
|
||||
# is using `input` field
|
||||
data: some(newSeq[byte]()),
|
||||
gas: Quantity(3000000).some,
|
||||
gasPrice: Quantity(1).some,
|
||||
value: some(valueEth.u256 * 1000000000000000000.u256),
|
||||
to: some(to))
|
||||
data: Opt.some(newSeq[byte]()),
|
||||
gas: Opt.some Quantity(3000000),
|
||||
gasPrice: Opt.some Quantity(1),
|
||||
value: Opt.some(valueEth.u256 * 1000000000000000000.u256),
|
||||
to: Opt.some(to))
|
||||
web3.send(tr)
|
||||
|
||||
type
|
||||
|
@ -153,7 +153,7 @@ proc ethToWei(eth: UInt256): UInt256 =
|
|||
proc initWeb3(web3Url, privateKey: string): Future[Web3] {.async.} =
|
||||
result = await newWeb3(web3Url)
|
||||
if privateKey.len != 0:
|
||||
result.privateKey = some(PrivateKey.fromHex(privateKey)[])
|
||||
result.privateKey = Opt.some(PrivateKey.fromHex(privateKey)[])
|
||||
else:
|
||||
let accounts = await result.provider.eth_accounts()
|
||||
doAssert(accounts.len > 0)
|
||||
|
|
|
@ -106,7 +106,7 @@ type
|
|||
Running, Closing, Closed
|
||||
|
||||
ELManager* = ref object
|
||||
eth1Network: Option[Eth1Network]
|
||||
eth1Network: Opt[Eth1Network]
|
||||
## If this value is supplied the EL manager will check whether
|
||||
## all configured EL nodes are connected to the same network.
|
||||
|
||||
|
@ -133,7 +133,7 @@ type
|
|||
## also includes blocks without deposits because we must
|
||||
## vote for a block only if it's part of our known history.
|
||||
|
||||
syncTargetBlock: Option[Eth1BlockNumber]
|
||||
syncTargetBlock: Opt[Eth1BlockNumber]
|
||||
|
||||
chainSyncingLoopFut: Future[void]
|
||||
exchangeTransitionConfigurationLoopFut: Future[void]
|
||||
|
@ -177,7 +177,7 @@ type
|
|||
depositContractSyncStatus: DepositContractSyncStatus
|
||||
## Are we sure that this EL has synced the deposit contract?
|
||||
|
||||
lastPayloadId: Option[PayloadID]
|
||||
lastPayloadId: Opt[PayloadID]
|
||||
|
||||
FullBlockId* = object
|
||||
number: Eth1BlockNumber
|
||||
|
@ -419,7 +419,7 @@ func asConsensusType*(payloadWithValue: BellatrixExecutionPayloadWithValue):
|
|||
executionPayload: payloadWithValue.executionPayload.asConsensusType,
|
||||
blockValue: payloadWithValue.blockValue)
|
||||
|
||||
template maybeDeref[T](o: Option[T]): T = o.get
|
||||
template maybeDeref[T](o: Opt[T]): T = o.get
|
||||
template maybeDeref[V](v: V): V = v
|
||||
|
||||
func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV1OrV2|ExecutionPayloadV2):
|
||||
|
@ -584,12 +584,13 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4):
|
|||
blob_versioned_hashes:
|
||||
if tt.payload.blobVersionedHashes.isSome:
|
||||
Opt.some(
|
||||
List[deneb.VersionedHash, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
|
||||
List[stable.VersionedHash, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
|
||||
.init(tt.payload.blobVersionedHashes.get.mapIt(
|
||||
deneb.VersionedHash(it))))
|
||||
stable.VersionedHash(it))))
|
||||
else:
|
||||
Opt.none(
|
||||
List[deneb.VersionedHash, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK])),
|
||||
List[stable.VersionedHash,
|
||||
Limit MAX_BLOB_COMMITMENTS_PER_BLOCK])),
|
||||
signature: Eip6493TransactionSignature(
|
||||
`from`:
|
||||
if tt.signature.`from`.isSome:
|
||||
|
@ -751,97 +752,97 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload):
|
|||
payload: engine_api_types.TransactionPayload(
|
||||
`type`:
|
||||
if tt.payload.`type`.isSome:
|
||||
options.some(tt.payload.`type`.get.Quantity)
|
||||
Opt.some(tt.payload.`type`.get.Quantity)
|
||||
else:
|
||||
options.none(Quantity),
|
||||
Opt.none(Quantity),
|
||||
chainId:
|
||||
if tt.payload.chain_id.isSome:
|
||||
options.some(tt.payload.chain_id.get.Quantity)
|
||||
Opt.some(tt.payload.chain_id.get.Quantity)
|
||||
else:
|
||||
options.none(Quantity),
|
||||
Opt.none(Quantity),
|
||||
nonce:
|
||||
if tt.payload.nonce.isSome:
|
||||
options.some(tt.payload.nonce.get.Quantity)
|
||||
Opt.some(tt.payload.nonce.get.Quantity)
|
||||
else:
|
||||
options.none(Quantity),
|
||||
Opt.none(Quantity),
|
||||
maxFeesPerGas:
|
||||
if tt.payload.max_fees_per_gas.isSome:
|
||||
options.some(engine_api_types.TransactionFeesPerGas(
|
||||
Opt.some(engine_api_types.TransactionFeesPerGas(
|
||||
regular:
|
||||
if tt.payload.max_fees_per_gas.get.regular.isSome:
|
||||
options.some(tt.payload.max_fees_per_gas.get.regular.get)
|
||||
Opt.some(tt.payload.max_fees_per_gas.get.regular.get)
|
||||
else:
|
||||
options.none(UInt256),
|
||||
Opt.none(UInt256),
|
||||
blob:
|
||||
if tt.payload.max_fees_per_gas.get.blob.isSome:
|
||||
options.some(tt.payload.max_fees_per_gas.get.blob.get)
|
||||
Opt.some(tt.payload.max_fees_per_gas.get.blob.get)
|
||||
else:
|
||||
options.none(UInt256)))
|
||||
Opt.none(UInt256)))
|
||||
else:
|
||||
options.none(engine_api_types.TransactionFeesPerGas),
|
||||
Opt.none(engine_api_types.TransactionFeesPerGas),
|
||||
gas:
|
||||
if tt.payload.gas.isSome:
|
||||
options.some(tt.payload.gas.get.Quantity)
|
||||
Opt.some(tt.payload.gas.get.Quantity)
|
||||
else:
|
||||
options.none(Quantity),
|
||||
Opt.none(Quantity),
|
||||
to:
|
||||
if tt.payload.to.isSome:
|
||||
options.some(Address(tt.payload.to.get.data))
|
||||
Opt.some(Address(tt.payload.to.get.data))
|
||||
else:
|
||||
options.none(Address),
|
||||
Opt.none(Address),
|
||||
value:
|
||||
if tt.payload.value.isSome:
|
||||
options.some(tt.payload.value.get)
|
||||
Opt.some(tt.payload.value.get)
|
||||
else:
|
||||
options.none(UInt256),
|
||||
Opt.none(UInt256),
|
||||
input:
|
||||
if tt.payload.input.isSome:
|
||||
options.some(distinctBase(tt.payload.input.get))
|
||||
Opt.some(distinctBase(tt.payload.input.get))
|
||||
else:
|
||||
options.none(seq[byte]),
|
||||
Opt.none(seq[byte]),
|
||||
accessList:
|
||||
if tt.payload.access_list.isSome:
|
||||
options.some(distinctBase(tt.payload.access_list.get).mapIt(
|
||||
Opt.some(distinctBase(tt.payload.access_list.get).mapIt(
|
||||
AccessTuple(
|
||||
address: Address(it.address.data),
|
||||
storage_keys: distinctBase(it.storage_keys)
|
||||
.mapIt(FixedBytes[32](it.data)))))
|
||||
else:
|
||||
options.none(seq[AccessTuple]),
|
||||
Opt.none(seq[AccessTuple]),
|
||||
maxPriorityFeesPerGas:
|
||||
if tt.payload.max_priority_fees_per_gas.isSome:
|
||||
options.some(engine_api_types.TransactionFeesPerGas(
|
||||
Opt.some(engine_api_types.TransactionFeesPerGas(
|
||||
regular:
|
||||
if tt.payload.max_priority_fees_per_gas.get.regular.isSome:
|
||||
options.some(
|
||||
Opt.some(
|
||||
tt.payload.max_priority_fees_per_gas.get.regular.get)
|
||||
else:
|
||||
options.none(UInt256),
|
||||
Opt.none(UInt256),
|
||||
blob:
|
||||
if tt.payload.max_priority_fees_per_gas.get.blob.isSome:
|
||||
options.some(
|
||||
Opt.some(
|
||||
tt.payload.max_priority_fees_per_gas.get.blob.get)
|
||||
else:
|
||||
options.none(UInt256)))
|
||||
Opt.none(UInt256)))
|
||||
else:
|
||||
options.none(engine_api_types.TransactionFeesPerGas),
|
||||
Opt.none(engine_api_types.TransactionFeesPerGas),
|
||||
blobVersionedHashes:
|
||||
if tt.payload.blob_versioned_hashes.isSome:
|
||||
options.some(distinctBase(tt.payload.blob_versioned_hashes.get)
|
||||
Opt.some(distinctBase(tt.payload.blob_versioned_hashes.get)
|
||||
.mapIt(FixedBytes[32](it)))
|
||||
else:
|
||||
options.none(seq[FixedBytes[32]])),
|
||||
Opt.none(seq[FixedBytes[32]])),
|
||||
signature: engine_api_types.TransactionSignature(
|
||||
`from`:
|
||||
if tt.signature.`from`.isSome:
|
||||
options.some(Address(tt.signature.`from`.get.data))
|
||||
Opt.some(Address(tt.signature.`from`.get.data))
|
||||
else:
|
||||
options.none(Address),
|
||||
Opt.none(Address),
|
||||
ecdsaSignature:
|
||||
if tt.signature.ecdsa_signature.isSome:
|
||||
options.some(FixedBytes[65](tt.signature.ecdsa_signature.get))
|
||||
Opt.some(FixedBytes[65](tt.signature.ecdsa_signature.get))
|
||||
else:
|
||||
options.none(FixedBytes[65])))
|
||||
Opt.none(FixedBytes[65])))
|
||||
|
||||
template getDepositReceipt(dr: DepositReceipt): DepositReceiptV1 =
|
||||
DepositReceiptV1(
|
||||
|
@ -975,15 +976,15 @@ func areSameAs(expectedParams: Option[NextExpectedPayloadParams],
|
|||
|
||||
proc forkchoiceUpdated(rpcClient: RpcClient,
|
||||
state: ForkchoiceStateV1,
|
||||
payloadAttributes: Option[PayloadAttributesV1] |
|
||||
Option[PayloadAttributesV2] |
|
||||
Option[PayloadAttributesV3]):
|
||||
payloadAttributes: Opt[PayloadAttributesV1] |
|
||||
Opt[PayloadAttributesV2] |
|
||||
Opt[PayloadAttributesV3]):
|
||||
Future[ForkchoiceUpdatedResponse] =
|
||||
when payloadAttributes is Option[PayloadAttributesV1]:
|
||||
when payloadAttributes is Opt[PayloadAttributesV1]:
|
||||
rpcClient.engine_forkchoiceUpdatedV1(state, payloadAttributes)
|
||||
elif payloadAttributes is Option[PayloadAttributesV2]:
|
||||
elif payloadAttributes is Opt[PayloadAttributesV2]:
|
||||
rpcClient.engine_forkchoiceUpdatedV2(state, payloadAttributes)
|
||||
elif payloadAttributes is Option[PayloadAttributesV3]:
|
||||
elif payloadAttributes is Opt[PayloadAttributesV3]:
|
||||
rpcClient.engine_forkchoiceUpdatedV3(state, payloadAttributes)
|
||||
else:
|
||||
static: doAssert false
|
||||
|
@ -1013,7 +1014,7 @@ proc getPayloadFromSingleEL(
|
|||
headBlockHash: headBlock.asBlockHash,
|
||||
safeBlockHash: safeBlock.asBlockHash,
|
||||
finalizedBlockHash: finalizedBlock.asBlockHash),
|
||||
some PayloadAttributesV1(
|
||||
Opt.some PayloadAttributesV1(
|
||||
timestamp: Quantity timestamp,
|
||||
prevRandao: FixedBytes[32] randomData.data,
|
||||
suggestedFeeRecipient: suggestedFeeRecipient))
|
||||
|
@ -1023,7 +1024,7 @@ proc getPayloadFromSingleEL(
|
|||
headBlockHash: headBlock.asBlockHash,
|
||||
safeBlockHash: safeBlock.asBlockHash,
|
||||
finalizedBlockHash: finalizedBlock.asBlockHash),
|
||||
some PayloadAttributesV2(
|
||||
Opt.some PayloadAttributesV2(
|
||||
timestamp: Quantity timestamp,
|
||||
prevRandao: FixedBytes[32] randomData.data,
|
||||
suggestedFeeRecipient: suggestedFeeRecipient,
|
||||
|
@ -1037,7 +1038,7 @@ proc getPayloadFromSingleEL(
|
|||
headBlockHash: headBlock.asBlockHash,
|
||||
safeBlockHash: safeBlock.asBlockHash,
|
||||
finalizedBlockHash: finalizedBlock.asBlockHash),
|
||||
some PayloadAttributesV3(
|
||||
Opt.some PayloadAttributesV3(
|
||||
timestamp: Quantity timestamp,
|
||||
prevRandao: FixedBytes[32] randomData.data,
|
||||
suggestedFeeRecipient: suggestedFeeRecipient,
|
||||
|
@ -1537,9 +1538,9 @@ proc sendNewPayload*(
|
|||
proc forkchoiceUpdatedForSingleEL(
|
||||
connection: ELConnection,
|
||||
state: ref ForkchoiceStateV1,
|
||||
payloadAttributes: Option[PayloadAttributesV1] |
|
||||
Option[PayloadAttributesV2] |
|
||||
Option[PayloadAttributesV3]
|
||||
payloadAttributes: Opt[PayloadAttributesV1] |
|
||||
Opt[PayloadAttributesV2] |
|
||||
Opt[PayloadAttributesV3]
|
||||
): Future[PayloadStatusV1] {.async: (raises: [CatchableError]).} =
|
||||
let
|
||||
rpcClient = await connection.connectedRpcClient()
|
||||
|
@ -1559,10 +1560,10 @@ proc forkchoiceUpdatedForSingleEL(
|
|||
proc forkchoiceUpdated*(
|
||||
m: ELManager,
|
||||
headBlockHash, safeBlockHash, finalizedBlockHash: Eth2Digest,
|
||||
payloadAttributes: Option[PayloadAttributesV1] |
|
||||
Option[PayloadAttributesV2] |
|
||||
Option[PayloadAttributesV3]
|
||||
): Future[(PayloadExecutionStatus, Option[BlockHash])] {.
|
||||
payloadAttributes: Opt[PayloadAttributesV1] |
|
||||
Opt[PayloadAttributesV2] |
|
||||
Opt[PayloadAttributesV3]
|
||||
): Future[(PayloadExecutionStatus, Opt[BlockHash])] {.
|
||||
async: (raises: [CancelledError]).} =
|
||||
|
||||
doAssert not headBlockHash.isZero
|
||||
|
@ -1579,16 +1580,16 @@ proc forkchoiceUpdated*(
|
|||
# payload (`Hash32()` if none yet finalized)"
|
||||
|
||||
if m.elConnections.len == 0:
|
||||
return (PayloadExecutionStatus.syncing, none BlockHash)
|
||||
return (PayloadExecutionStatus.syncing, Opt.none BlockHash)
|
||||
|
||||
when payloadAttributes is Option[PayloadAttributesV3]:
|
||||
when payloadAttributes is Opt[PayloadAttributesV3]:
|
||||
template payloadAttributesV3(): auto =
|
||||
if payloadAttributes.isSome:
|
||||
payloadAttributes.get
|
||||
else:
|
||||
# As timestamp and prevRandao are both 0, won't false-positive match
|
||||
(static(default(PayloadAttributesV3)))
|
||||
elif payloadAttributes is Option[PayloadAttributesV2]:
|
||||
elif payloadAttributes is Opt[PayloadAttributesV2]:
|
||||
template payloadAttributesV3(): auto =
|
||||
if payloadAttributes.isSome:
|
||||
PayloadAttributesV3(
|
||||
|
@ -1600,7 +1601,7 @@ proc forkchoiceUpdated*(
|
|||
else:
|
||||
# As timestamp and prevRandao are both 0, won't false-positive match
|
||||
(static(default(PayloadAttributesV3)))
|
||||
elif payloadAttributes is Option[PayloadAttributesV1]:
|
||||
elif payloadAttributes is Opt[PayloadAttributesV1]:
|
||||
template payloadAttributesV3(): auto =
|
||||
if payloadAttributes.isSome:
|
||||
PayloadAttributesV3(
|
||||
|
@ -1685,7 +1686,7 @@ proc forkchoiceUpdated*(
|
|||
pendingRequests.filterIt(not(it.finished())).
|
||||
mapIt(it.cancelAndWait())
|
||||
await noCancel allFutures(pending)
|
||||
return (PayloadExecutionStatus.invalid, none BlockHash)
|
||||
return (PayloadExecutionStatus.invalid, Opt.none BlockHash)
|
||||
elif responseProcessor.selectedResponse.isSome:
|
||||
# We spawn task which will wait for all other responses which are
|
||||
# still pending, after 30.seconds all pending requests will be
|
||||
|
@ -1700,7 +1701,7 @@ proc forkchoiceUpdated*(
|
|||
pendingRequests.filterIt(not(it.finished())).
|
||||
mapIt(it.cancelAndWait())
|
||||
await noCancel allFutures(pending)
|
||||
return (PayloadExecutionStatus.syncing, none BlockHash)
|
||||
return (PayloadExecutionStatus.syncing, Opt.none BlockHash)
|
||||
|
||||
if len(pendingRequests) == 0:
|
||||
# All requests failed, we will continue our attempts until deadline
|
||||
|
@ -1958,7 +1959,7 @@ proc new*(T: type ELManager,
|
|||
depositContractBlockHash: Eth2Digest,
|
||||
db: BeaconChainDB,
|
||||
engineApiUrls: seq[EngineApiUrl],
|
||||
eth1Network: Option[Eth1Network]): T =
|
||||
eth1Network: Opt[Eth1Network]): T =
|
||||
let
|
||||
eth1Chain = Eth1Chain.init(
|
||||
cfg, db, depositContractBlockNumber, depositContractBlockHash)
|
||||
|
@ -2043,8 +2044,8 @@ proc syncBlockRange(
|
|||
await connection.engineApiRequest(
|
||||
depositContract.getJsonLogs(
|
||||
DepositEvent,
|
||||
fromBlock = some blockId(currentBlock),
|
||||
toBlock = some blockId(maxBlockNumberRequested)),
|
||||
fromBlock = Opt.some blockId(currentBlock),
|
||||
toBlock = Opt.some blockId(maxBlockNumberRequested)),
|
||||
"getLogs", Moment.now(), 30.seconds)
|
||||
except CancelledError as exc:
|
||||
debug "Request for deposit logs was interrupted"
|
||||
|
@ -2152,7 +2153,6 @@ proc startExchangeTransitionConfigurationLoop(
|
|||
|
||||
while true:
|
||||
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/paris.md#specification-3
|
||||
debug "Exchange transition configuration tick"
|
||||
await m.exchangeTransitionConfiguration()
|
||||
await sleepAsync(60.seconds)
|
||||
|
||||
|
@ -2286,7 +2286,7 @@ proc syncEth1Chain(
|
|||
|
||||
latestBlockNumber = latestBlock.number
|
||||
|
||||
m.syncTargetBlock = some(
|
||||
m.syncTargetBlock = Opt.some(
|
||||
if latestBlock.number > m.cfg.ETH1_FOLLOW_DISTANCE.Eth1BlockNumber:
|
||||
latestBlock.number - m.cfg.ETH1_FOLLOW_DISTANCE
|
||||
else:
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
{.push raises: [].}
|
||||
|
||||
import
|
||||
stew/results,
|
||||
chronicles, chronos, metrics,
|
||||
../spec/[forks, signatures, signatures_batch],
|
||||
../sszdump
|
||||
|
@ -243,7 +242,7 @@ proc expectValidForkchoiceUpdated(
|
|||
headBlockHash = headBlockHash,
|
||||
safeBlockHash = safeBlockHash,
|
||||
finalizedBlockHash = finalizedBlockHash,
|
||||
payloadAttributes = none headBlockPayloadAttributesType)
|
||||
payloadAttributes = Opt.none headBlockPayloadAttributesType)
|
||||
receivedExecutionBlockHash =
|
||||
when typeof(receivedBlock).kind >= ConsensusFork.Bellatrix:
|
||||
receivedBlock.message.body.execution_payload.block_hash
|
||||
|
@ -685,7 +684,7 @@ proc storeBlock(
|
|||
self.consensusManager[].optimisticExecutionBlockHash,
|
||||
safeBlockHash = newHead.get.safeExecutionBlockHash,
|
||||
finalizedBlockHash = newHead.get.finalizedExecutionBlockHash,
|
||||
payloadAttributes = none attributes)
|
||||
payloadAttributes = Opt.none attributes)
|
||||
|
||||
let consensusFork = self.consensusManager.dag.cfg.consensusForkAtEpoch(
|
||||
newHead.get.blck.bid.slot.epoch)
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
import
|
||||
std/tables,
|
||||
stew/results,
|
||||
chronicles, chronos, metrics, taskpools,
|
||||
chronicles, chronos, metrics,
|
||||
taskpools,
|
||||
../spec/[helpers, forks],
|
||||
../spec/datatypes/[altair, phase0, deneb],
|
||||
../consensus_object_pools/[
|
||||
|
@ -122,7 +122,7 @@ type
|
|||
# ----------------------------------------------------------------
|
||||
dag*: ChainDAGRef
|
||||
attestationPool*: ref AttestationPool
|
||||
validatorPool: ref ValidatorPool
|
||||
validatorPool*: ref ValidatorPool
|
||||
syncCommitteeMsgPool: ref SyncCommitteeMsgPool
|
||||
lightClientPool: ref LightClientPool
|
||||
|
||||
|
@ -366,7 +366,8 @@ proc checkForPotentialDoppelganger(
|
|||
proc processAttestation*(
|
||||
self: ref Eth2Processor, src: MsgSource,
|
||||
attestation: phase0.Attestation | electra.Attestation, subnet_id: SubnetId,
|
||||
checkSignature: bool = true): Future[ValidationRes] {.async: (raises: [CancelledError]).} =
|
||||
checkSignature, checkValidator: bool
|
||||
): Future[ValidationRes] {.async: (raises: [CancelledError]).} =
|
||||
var wallTime = self.getCurrentBeaconTime()
|
||||
let (afterGenesis, wallSlot) = wallTime.toSlot()
|
||||
|
||||
|
@ -393,19 +394,26 @@ proc processAttestation*(
|
|||
|
||||
let (attester_index, sig) = v.get()
|
||||
|
||||
self[].checkForPotentialDoppelganger(attestation, [attester_index])
|
||||
if checkValidator and (attester_index in self.validatorPool[]):
|
||||
warn "A validator client has attempted to send an attestation from " &
|
||||
"validator that is also managed by the beacon node",
|
||||
validator_index = attester_index
|
||||
errReject("An attestation could not be sent from a validator that is " &
|
||||
"also managed by the beacon node")
|
||||
else:
|
||||
self[].checkForPotentialDoppelganger(attestation, [attester_index])
|
||||
|
||||
trace "Attestation validated"
|
||||
self.attestationPool[].addAttestation(
|
||||
attestation, [attester_index], sig, wallTime)
|
||||
trace "Attestation validated"
|
||||
self.attestationPool[].addAttestation(
|
||||
attestation, [attester_index], sig, wallTime)
|
||||
|
||||
self.validatorMonitor[].registerAttestation(
|
||||
src, wallTime, attestation, attester_index)
|
||||
self.validatorMonitor[].registerAttestation(
|
||||
src, wallTime, attestation, attester_index)
|
||||
|
||||
beacon_attestations_received.inc()
|
||||
beacon_attestation_delay.observe(delay.toFloatSeconds())
|
||||
beacon_attestations_received.inc()
|
||||
beacon_attestation_delay.observe(delay.toFloatSeconds())
|
||||
|
||||
ok()
|
||||
ok()
|
||||
else:
|
||||
debug "Dropping attestation", reason = $v.error
|
||||
beacon_attestations_dropped.inc(1, [$v.error[0]])
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import
|
||||
std/[json, sequtils, times],
|
||||
stew/saturation_arith,
|
||||
eth/common/[eth_types_rlp, transaction],
|
||||
eth/keys,
|
||||
eth/p2p/discoveryv5/random2,
|
||||
|
@ -1254,37 +1253,37 @@ proc ETHExecutionBlockHeaderCreateFromJson(
|
|||
coinbase: distinctBase(data.miner),
|
||||
stateRoot: data.stateRoot.asEth2Digest,
|
||||
txRoot: data.transactionsRoot.asEth2Digest,
|
||||
receiptRoot: data.receiptsRoot.asEth2Digest,
|
||||
bloom: distinctBase(data.logsBloom),
|
||||
receiptsRoot: data.receiptsRoot.asEth2Digest,
|
||||
logsBloom: distinctBase(data.logsBloom),
|
||||
difficulty: data.difficulty,
|
||||
blockNumber: distinctBase(data.number).u256,
|
||||
gasLimit: cast[int64](data.gasLimit),
|
||||
gasUsed: cast[int64](data.gasUsed),
|
||||
timestamp: EthTime(int64.saturate distinctBase(data.timestamp)),
|
||||
number: distinctBase(data.number),
|
||||
gasLimit: distinctBase(data.gasLimit),
|
||||
gasUsed: distinctBase(data.gasUsed),
|
||||
timestamp: EthTime(distinctBase(data.timestamp)),
|
||||
extraData: distinctBase(data.extraData),
|
||||
mixDigest: data.mixHash.asEth2Digest,
|
||||
mixHash: data.mixHash.asEth2Digest,
|
||||
nonce: distinctBase(data.nonce.get),
|
||||
fee: data.baseFeePerGas,
|
||||
baseFeePerGas: data.baseFeePerGas,
|
||||
withdrawalsRoot:
|
||||
if data.withdrawalsRoot.isSome:
|
||||
some(data.withdrawalsRoot.get.asEth2Digest)
|
||||
Opt.some(data.withdrawalsRoot.get.asEth2Digest)
|
||||
else:
|
||||
none(ExecutionHash256),
|
||||
Opt.none(ExecutionHash256),
|
||||
blobGasUsed:
|
||||
if data.blobGasUsed.isSome:
|
||||
some distinctBase(data.blobGasUsed.get)
|
||||
Opt.some distinctBase(data.blobGasUsed.get)
|
||||
else:
|
||||
none(uint64),
|
||||
Opt.none(uint64),
|
||||
excessBlobGas:
|
||||
if data.excessBlobGas.isSome:
|
||||
some distinctBase(data.excessBlobGas.get)
|
||||
Opt.some distinctBase(data.excessBlobGas.get)
|
||||
else:
|
||||
none(uint64),
|
||||
Opt.none(uint64),
|
||||
parentBeaconBlockRoot:
|
||||
if data.parentBeaconBlockRoot.isSome:
|
||||
some distinctBase(data.parentBeaconBlockRoot.get.asEth2Digest)
|
||||
Opt.some distinctBase(data.parentBeaconBlockRoot.get.asEth2Digest)
|
||||
else:
|
||||
none(ExecutionHash256))
|
||||
Opt.none(ExecutionHash256))
|
||||
if rlpHash(blockHeader) != executionHash[]:
|
||||
return nil
|
||||
|
||||
|
@ -1529,15 +1528,15 @@ proc ETHTransactionsCreateFromJson(
|
|||
chainId: data.chainId.get(0.Quantity).ChainId,
|
||||
nonce: distinctBase(data.nonce),
|
||||
gasPrice: data.gasPrice.GasInt,
|
||||
maxPriorityFee:
|
||||
maxPriorityFeePerGas:
|
||||
distinctBase(data.maxPriorityFeePerGas.get(data.gasPrice)).GasInt,
|
||||
maxFee: distinctBase(data.maxFeePerGas.get(data.gasPrice)).GasInt,
|
||||
maxFeePerGas: distinctBase(data.maxFeePerGas.get(data.gasPrice)).GasInt,
|
||||
gasLimit: distinctBase(data.gas).GasInt,
|
||||
to:
|
||||
if data.to.isSome:
|
||||
some(distinctBase(data.to.get))
|
||||
Opt.some(distinctBase(data.to.get))
|
||||
else:
|
||||
none(EthAddress),
|
||||
Opt.none(EthAddress),
|
||||
value: data.value,
|
||||
payload: data.input,
|
||||
accessList:
|
||||
|
@ -1555,7 +1554,7 @@ proc ETHTransactionsCreateFromJson(
|
|||
ExecutionHash256(data: distinctBase(it)))
|
||||
else:
|
||||
@[],
|
||||
V: data.v.int64,
|
||||
V: data.v.uint64,
|
||||
R: data.r,
|
||||
S: data.s)
|
||||
rlpBytes =
|
||||
|
@ -1567,7 +1566,7 @@ proc ETHTransactionsCreateFromJson(
|
|||
if data.hash.asEth2Digest != hash:
|
||||
return nil
|
||||
|
||||
template isEven(x: int64): bool =
|
||||
template isEven(x: uint64): bool =
|
||||
(x and 1) == 0
|
||||
|
||||
# Compute from execution address
|
||||
|
@ -1614,9 +1613,9 @@ proc ETHTransactionsCreateFromJson(
|
|||
chainId: distinctBase(tx.chainId).u256,
|
||||
`from`: ExecutionAddress(data: fromAddress),
|
||||
nonce: tx.nonce,
|
||||
maxPriorityFeePerGas: tx.maxPriorityFee.uint64,
|
||||
maxFeePerGas: tx.maxFee.uint64,
|
||||
gas: tx.gasLimit.uint64,
|
||||
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
|
||||
maxFeePerGas: tx.maxFeePerGas,
|
||||
gas: tx.gasLimit,
|
||||
destinationType: destinationType,
|
||||
to: ExecutionAddress(data: toAddress),
|
||||
value: tx.value,
|
||||
|
@ -2178,7 +2177,7 @@ proc ETHReceiptsCreateFromJson(
|
|||
else:
|
||||
default(ExecutionHash256),
|
||||
cumulativeGasUsed: distinctBase(data.cumulativeGasUsed).GasInt,
|
||||
bloom: distinctBase(data.logsBloom),
|
||||
logsBloom: distinctBase(data.logsBloom),
|
||||
logs: data.logs.mapIt(Log(
|
||||
address: distinctBase(it.address),
|
||||
topics: it.topics.mapIt(distinctBase(it)),
|
||||
|
@ -2198,7 +2197,7 @@ proc ETHReceiptsCreateFromJson(
|
|||
root: rec.hash,
|
||||
status: rec.status,
|
||||
gasUsed: distinctBase(data.gasUsed), # Validated during sanity checks.
|
||||
logsBloom: BloomLogs(data: rec.bloom),
|
||||
logsBloom: BloomLogs(data: rec.logsBloom),
|
||||
logs: rec.logs.mapIt(ETHLog(
|
||||
address: ExecutionAddress(data: it.address),
|
||||
topics: it.topics.mapIt(Eth2Digest(data: it)),
|
||||
|
|
|
@ -1 +1 @@
|
|||
../../../vendor/eth2-networks/shared/mainnet/config.yaml
|
||||
../../../vendor/mainnet/metadata/config.yaml
|
|
@ -1 +1 @@
|
|||
../../../vendor/eth2-networks/shared/mainnet/genesis.ssz
|
||||
../../../vendor/mainnet/metadata/genesis.ssz
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import
|
||||
std/[algorithm, sequtils],
|
||||
chronos, chronicles, stew/results,
|
||||
chronos, chronicles,
|
||||
eth/p2p/discoveryv5/[enr, protocol, node, random2],
|
||||
../spec/datatypes/altair,
|
||||
../spec/eth2_ssz_serialization,
|
||||
|
@ -53,7 +53,7 @@ proc addBootstrapNode*(bootstrapAddr: string,
|
|||
return
|
||||
|
||||
# Ignore comments in
|
||||
# https://github.com/eth-clients/eth2-networks/blob/063f826a03676c33c95a66306916f18b690d35eb/shared/mainnet/bootstrap_nodes.txt
|
||||
# https://github.com/eth-clients/mainnet/blob/main/metadata/bootstrap_nodes.txt
|
||||
let enrRes = parseBootstrapAddress(bootstrapAddr.split(" # ")[0])
|
||||
if enrRes.isOk:
|
||||
bootstrapEnrs.add enrRes.value
|
||||
|
@ -127,7 +127,7 @@ proc queryRandom*(
|
|||
forkId: ENRForkID,
|
||||
wantedAttnets: AttnetBits,
|
||||
wantedSyncnets: SyncnetBits,
|
||||
minScore: int): Future[seq[Node]] {.async.} =
|
||||
minScore: int): Future[seq[Node]] {.async: (raises: [CancelledError]).} =
|
||||
## Perform a discovery query for a random target
|
||||
## (forkId) and matching at least one of the attestation subnets.
|
||||
|
||||
|
@ -143,7 +143,7 @@ proc queryRandom*(
|
|||
peerForkId =
|
||||
try:
|
||||
SSZ.decode(eth2FieldBytes, ENRForkID)
|
||||
except SszError as e:
|
||||
except SerializationError as e:
|
||||
debug "Could not decode the eth2 field of peer",
|
||||
peer = n.record.toURI(), exception = e.name, msg = e.msg
|
||||
continue
|
||||
|
@ -156,7 +156,7 @@ proc queryRandom*(
|
|||
let attnetsNode =
|
||||
try:
|
||||
SSZ.decode(attnetsBytes.get(), AttnetBits)
|
||||
except SszError as e:
|
||||
except SerializationError as e:
|
||||
debug "Could not decode the attnets ERN bitfield of peer",
|
||||
peer = n.record.toURI(), exception = e.name, msg = e.msg
|
||||
continue
|
||||
|
@ -170,7 +170,7 @@ proc queryRandom*(
|
|||
let syncnetsNode =
|
||||
try:
|
||||
SSZ.decode(syncnetsBytes.get(), SyncnetBits)
|
||||
except SszError as e:
|
||||
except SerializationError as e:
|
||||
debug "Could not decode the syncnets ENR bitfield of peer",
|
||||
peer = n.record.toURI(), exception = e.name, msg = e.msg
|
||||
continue
|
||||
|
|
|
@ -1550,7 +1550,7 @@ proc getLowSubnets(node: Eth2Node, epoch: Epoch): (AttnetBits, SyncnetBits) =
|
|||
default(SyncnetBits)
|
||||
)
|
||||
|
||||
proc runDiscoveryLoop(node: Eth2Node) {.async.} =
|
||||
proc runDiscoveryLoop(node: Eth2Node) {.async: (raises: [CancelledError]).} =
|
||||
debug "Starting discovery loop"
|
||||
|
||||
while true:
|
||||
|
|
|
@ -78,7 +78,7 @@ type
|
|||
# additional checks to ensure we are connecting to a web3 provider
|
||||
# serving data for the same network. The value can be set to `None`
|
||||
# for custom networks and testing purposes.
|
||||
eth1Network*: Option[Eth1Network]
|
||||
eth1Network*: Opt[Eth1Network]
|
||||
cfg*: RuntimeConfig
|
||||
|
||||
# Parsing `enr.Records` is still not possible at compile-time
|
||||
|
@ -112,13 +112,13 @@ proc readBootEnr*(path: string): seq[string] {.raises: [IOError].} =
|
|||
|
||||
proc loadEth2NetworkMetadata*(
|
||||
path: string,
|
||||
eth1Network = none(Eth1Network),
|
||||
eth1Network = Opt.none(Eth1Network),
|
||||
isCompileTime = false,
|
||||
downloadGenesisFrom = none(DownloadInfo),
|
||||
useBakedInGenesis = none(string)
|
||||
downloadGenesisFrom = Opt.none(DownloadInfo),
|
||||
useBakedInGenesis = Opt.none(string)
|
||||
): Result[Eth2NetworkMetadata, string] {.raises: [IOError, PresetFileError].} =
|
||||
# Load data in eth2-networks format
|
||||
# https://github.com/eth-clients/eth2-networks
|
||||
# Load data in mainnet format
|
||||
# https://github.com/eth-clients/mainnet
|
||||
|
||||
try:
|
||||
let
|
||||
|
@ -208,9 +208,9 @@ proc loadEth2NetworkMetadata*(
|
|||
|
||||
proc loadCompileTimeNetworkMetadata(
|
||||
path: string,
|
||||
eth1Network = none(Eth1Network),
|
||||
useBakedInGenesis = none(string),
|
||||
downloadGenesisFrom = none(DownloadInfo)): Eth2NetworkMetadata =
|
||||
eth1Network = Opt.none(Eth1Network),
|
||||
useBakedInGenesis = Opt.none(string),
|
||||
downloadGenesisFrom = Opt.none(DownloadInfo)): Eth2NetworkMetadata =
|
||||
if fileExists(path & "/config.yaml"):
|
||||
try:
|
||||
let res = loadEth2NetworkMetadata(
|
||||
|
@ -255,13 +255,13 @@ when const_preset == "gnosis":
|
|||
const
|
||||
gnosisMetadata = loadCompileTimeNetworkMetadata(
|
||||
vendorDir & "/gnosis-chain-configs/mainnet",
|
||||
none(Eth1Network),
|
||||
useBakedInGenesis = some "gnosis")
|
||||
Opt.none(Eth1Network),
|
||||
useBakedInGenesis = Opt.some "gnosis")
|
||||
|
||||
chiadoMetadata = loadCompileTimeNetworkMetadata(
|
||||
vendorDir & "/gnosis-chain-configs/chiado",
|
||||
none(Eth1Network),
|
||||
useBakedInGenesis = some "chiado")
|
||||
Opt.none(Eth1Network),
|
||||
useBakedInGenesis = Opt.some "chiado")
|
||||
|
||||
static:
|
||||
for network in [gnosisMetadata, chiadoMetadata]:
|
||||
|
@ -292,28 +292,28 @@ elif const_preset == "mainnet":
|
|||
else:
|
||||
const
|
||||
mainnetGenesis* = slurp(
|
||||
vendorDir & "/eth2-networks/shared/mainnet/genesis.ssz")
|
||||
vendorDir & "/mainnet/metadata/genesis.ssz")
|
||||
|
||||
sepoliaGenesis* = slurp(
|
||||
vendorDir & "/sepolia/bepolia/genesis.ssz")
|
||||
|
||||
const
|
||||
mainnetMetadata = loadCompileTimeNetworkMetadata(
|
||||
vendorDir & "/eth2-networks/shared/mainnet",
|
||||
some mainnet,
|
||||
useBakedInGenesis = some "mainnet")
|
||||
vendorDir & "/mainnet/metadata",
|
||||
Opt.some mainnet,
|
||||
useBakedInGenesis = Opt.some "mainnet")
|
||||
|
||||
holeskyMetadata = loadCompileTimeNetworkMetadata(
|
||||
vendorDir & "/holesky/custom_config_data",
|
||||
some holesky,
|
||||
downloadGenesisFrom = some DownloadInfo(
|
||||
Opt.some holesky,
|
||||
downloadGenesisFrom = Opt.some DownloadInfo(
|
||||
url: "https://github.com/status-im/nimbus-eth2/releases/download/v23.9.1/holesky-genesis.ssz.sz",
|
||||
digest: Eth2Digest.fromHex "0x0ea3f6f9515823b59c863454675fefcd1d8b4f2dbe454db166206a41fda060a0"))
|
||||
|
||||
sepoliaMetadata = loadCompileTimeNetworkMetadata(
|
||||
vendorDir & "/sepolia/bepolia",
|
||||
some sepolia,
|
||||
useBakedInGenesis = some "sepolia")
|
||||
Opt.some sepolia,
|
||||
useBakedInGenesis = Opt.some "sepolia")
|
||||
|
||||
static:
|
||||
for network in [mainnetMetadata, sepoliaMetadata, holeskyMetadata]:
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
# name_size = 64-bit length in bytes
|
||||
|
||||
eth2_mainnet_genesis_data:
|
||||
.incbin "eth2-networks/shared/mainnet/genesis.ssz"
|
||||
.incbin "mainnet/metadata/genesis.ssz"
|
||||
eth2_mainnet_genesis_end:
|
||||
.global cdecl(eth2_mainnet_genesis_size)
|
||||
.p2align 3
|
||||
|
|
|
@ -147,14 +147,16 @@ func getVanityLogs(stdoutKind: StdoutLogKind): VanityLogs =
|
|||
onFinalizedMergeTransitionBlock: bellatrixBlink,
|
||||
onUpgradeToCapella: capellaColor,
|
||||
onKnownBlsToExecutionChange: capellaBlink,
|
||||
onUpgradeToDeneb: denebColor)
|
||||
onUpgradeToDeneb: denebColor,
|
||||
onUpgradeToElectra: electraColor)
|
||||
of StdoutLogKind.NoColors:
|
||||
VanityLogs(
|
||||
onMergeTransitionBlock: bellatrixMono,
|
||||
onFinalizedMergeTransitionBlock: bellatrixMono,
|
||||
onUpgradeToCapella: capellaMono,
|
||||
onKnownBlsToExecutionChange: capellaMono,
|
||||
onUpgradeToDeneb: denebMono)
|
||||
onUpgradeToDeneb: denebMono,
|
||||
onUpgradeToElectra: electraMono)
|
||||
of StdoutLogKind.Json, StdoutLogKind.None:
|
||||
VanityLogs(
|
||||
onMergeTransitionBlock:
|
||||
|
@ -166,12 +168,14 @@ func getVanityLogs(stdoutKind: StdoutLogKind): VanityLogs =
|
|||
onKnownBlsToExecutionChange:
|
||||
(proc() = notice "🦉 BLS to execution changed 🦉"),
|
||||
onUpgradeToDeneb:
|
||||
(proc() = notice "🐟 Proto-Danksharding is ON 🐟"))
|
||||
(proc() = notice "🐟 Proto-Danksharding is ON 🐟"),
|
||||
onUpgradeToElectra:
|
||||
(proc() = notice "🦒 [PH] Electra 🦒"))
|
||||
|
||||
func getVanityMascot(consensusFork: ConsensusFork): string =
|
||||
case consensusFork
|
||||
of ConsensusFork.Electra:
|
||||
" "
|
||||
"🦒"
|
||||
of ConsensusFork.Deneb:
|
||||
"🐟"
|
||||
of ConsensusFork.Capella:
|
||||
|
@ -1767,7 +1771,8 @@ proc installMessageValidators(node: BeaconNode) =
|
|||
): Future[ValidationResult] {.async: (raises: [CancelledError]).} =
|
||||
return toValidationResult(
|
||||
await node.processor.processAttestation(
|
||||
MsgSource.gossip, attestation, subnet_id)))
|
||||
MsgSource.gossip, attestation, subnet_id,
|
||||
checkSignature = true, checkValidator = false)))
|
||||
else:
|
||||
for it in SubnetId:
|
||||
closureScope: # Needed for inner `proc`; don't lift it out of loop.
|
||||
|
@ -1778,7 +1783,8 @@ proc installMessageValidators(node: BeaconNode) =
|
|||
): Future[ValidationResult] {.async: (raises: [CancelledError]).} =
|
||||
return toValidationResult(
|
||||
await node.processor.processAttestation(
|
||||
MsgSource.gossip, attestation, subnet_id)))
|
||||
MsgSource.gossip, attestation, subnet_id,
|
||||
checkSignature = true, checkValidator = false)))
|
||||
|
||||
# beacon_aggregate_and_proof
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof
|
||||
|
|
|
@ -123,7 +123,7 @@ programMain:
|
|||
headBlockHash = payload.block_hash,
|
||||
safeBlockHash = payload.block_hash, # stub value
|
||||
finalizedBlockHash = ZERO_HASH,
|
||||
payloadAttributes = none(consensusFork.PayloadAttributes))
|
||||
payloadAttributes = Opt.none(consensusFork.PayloadAttributes))
|
||||
else: discard
|
||||
optimisticProcessor = initOptimisticProcessor(
|
||||
getBeaconTime, optimisticHandler)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import
|
||||
std/[typetraits, sequtils, sets],
|
||||
stew/[results, base10],
|
||||
stew/base10,
|
||||
chronicles, metrics,
|
||||
./rest_utils,
|
||||
./state_ttl_cache,
|
||||
|
@ -911,10 +911,12 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
when consensusFork >= ConsensusFork.Deneb:
|
||||
await node.router.routeSignedBeaconBlock(
|
||||
forkyBlck, Opt.some(
|
||||
forkyBlck.create_blob_sidecars(kzg_proofs, blobs)))
|
||||
forkyBlck.create_blob_sidecars(kzg_proofs, blobs)),
|
||||
checkValidator = true)
|
||||
else:
|
||||
await node.router.routeSignedBeaconBlock(
|
||||
forkyBlck, Opt.none(seq[BlobSidecar]))
|
||||
forkyBlck, Opt.none(seq[BlobSidecar]),
|
||||
checkValidator = true)
|
||||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
|
@ -966,10 +968,12 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
when consensusFork >= ConsensusFork.Deneb:
|
||||
await node.router.routeSignedBeaconBlock(
|
||||
forkyBlck, Opt.some(
|
||||
forkyBlck.create_blob_sidecars(kzg_proofs, blobs)))
|
||||
forkyBlck.create_blob_sidecars(kzg_proofs, blobs)),
|
||||
checkValidator = true)
|
||||
else:
|
||||
await node.router.routeSignedBeaconBlock(
|
||||
forkyBlck, Opt.none(seq[BlobSidecar]))
|
||||
forkyBlck, Opt.none(seq[BlobSidecar]),
|
||||
checkValidator = true)
|
||||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
|
@ -1087,7 +1091,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let res = withBlck(forked):
|
||||
forkyBlck.root = hash_tree_root(forkyBlck.message)
|
||||
await node.router.routeSignedBeaconBlock(
|
||||
forkyBlck, Opt.none(seq[BlobSidecar]))
|
||||
forkyBlck, Opt.none(seq[BlobSidecar]),
|
||||
checkValidator = true)
|
||||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import
|
||||
std/sequtils,
|
||||
stew/results,
|
||||
chronicles,
|
||||
chronos/apps/http/httpserver,
|
||||
./rest_utils,
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
std/[sequtils],
|
||||
stew/[results, base10],
|
||||
stew/base10,
|
||||
chronicles,
|
||||
chronos/apps/http/httpdebug,
|
||||
libp2p/[multiaddress, multicodec, peerstore],
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
stew/[byteutils, results],
|
||||
stew/byteutils,
|
||||
chronicles,
|
||||
eth/p2p/discoveryv5/enr,
|
||||
libp2p/[multiaddress, multicodec, peerstore],
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
{.push raises: [].}
|
||||
|
||||
import std/[typetraits, sets, sequtils]
|
||||
import stew/[results, base10], chronicles
|
||||
import stew/base10, chronicles
|
||||
import ".."/[beacon_chain_db, beacon_node],
|
||||
".."/networking/eth2_network,
|
||||
".."/consensus_object_pools/[blockchain_dag, spec_cache,
|
||||
|
|
|
@ -77,7 +77,7 @@ type
|
|||
BlsResult*[T] = Result[T, cstring]
|
||||
|
||||
TrustedSig* = object
|
||||
data* {.align: 16.}: array[RawSigSize, byte]
|
||||
blob* {.align: 16.}: array[RawSigSize, byte]
|
||||
|
||||
SomeSig* = TrustedSig | ValidatorSig
|
||||
|
||||
|
@ -390,12 +390,9 @@ func toRaw*(x: ValidatorPrivKey): array[32, byte] =
|
|||
# TODO: distinct type - see https://github.com/status-im/nim-blscurve/pull/67
|
||||
static: doAssert BLS_BACKEND == BLST
|
||||
result = SecretKey(x).exportRaw()
|
||||
|
||||
template toRaw*(x: ValidatorPubKey | ValidatorSig): auto =
|
||||
x.blob
|
||||
|
||||
template toRaw*(x: TrustedSig): auto =
|
||||
x.data
|
||||
template toRaw*(x: ValidatorPubKey | SomeSig): auto =
|
||||
x.blob
|
||||
|
||||
func toHex*(x: BlsCurveType): string =
|
||||
toHex(toRaw(x))
|
||||
|
@ -507,7 +504,7 @@ template fromSszBytes*(T: type[ValidatorPubKey | ValidatorSig], bytes: openArray
|
|||
# Logging
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
func shortLog*(x: ValidatorPubKey | ValidatorSig): string =
|
||||
func shortLog*(x: ValidatorPubKey | SomeSig): string =
|
||||
## Logging for wrapped BLS types
|
||||
## that may contain valid or non-validated data
|
||||
byteutils.toHex(x.blob.toOpenArray(0, 3))
|
||||
|
@ -520,9 +517,6 @@ func shortLog*(x: ValidatorPrivKey): string =
|
|||
## Logging for raw unwrapped BLS types
|
||||
"<private key>"
|
||||
|
||||
func shortLog*(x: TrustedSig): string =
|
||||
byteutils.toHex(x.data.toOpenArray(0, 3))
|
||||
|
||||
# Initialization
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -75,29 +75,6 @@ static: doAssert TIMELY_SOURCE_WEIGHT + TIMELY_TARGET_WEIGHT +
|
|||
type
|
||||
### New types
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#custom-types
|
||||
ParticipationFlags* = uint8
|
||||
|
||||
EpochParticipationFlags* =
|
||||
distinct List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
## Not a HashList because the list sees significant updates every block
|
||||
## effectively making the cost of clearing the cache higher than the typical
|
||||
## gains
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#syncaggregate
|
||||
SyncAggregate* = object
|
||||
sync_committee_bits*: BitArray[SYNC_COMMITTEE_SIZE]
|
||||
sync_committee_signature*: ValidatorSig
|
||||
|
||||
TrustedSyncAggregate* = object
|
||||
sync_committee_bits*: BitArray[SYNC_COMMITTEE_SIZE]
|
||||
sync_committee_signature*: TrustedSig
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#synccommittee
|
||||
SyncCommittee* = object
|
||||
pubkeys*: HashArray[Limit SYNC_COMMITTEE_SIZE, ValidatorPubKey]
|
||||
aggregate_pubkey*: ValidatorPubKey
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/altair/validator.md#synccommitteemessage
|
||||
SyncCommitteeMessage* = object
|
||||
slot*: Slot
|
||||
|
@ -255,8 +232,6 @@ type
|
|||
## (used to compute safety threshold)
|
||||
current_max_active_participants*: uint64
|
||||
|
||||
InactivityScores* = HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#beaconstate
|
||||
BeaconState* = object
|
||||
# Versioning
|
||||
|
@ -529,8 +504,6 @@ type
|
|||
SigVerifiedBeaconBlockBody |
|
||||
TrustedBeaconBlockBody
|
||||
|
||||
SomeSyncAggregate* = SyncAggregate | TrustedSyncAggregate
|
||||
|
||||
SyncSubcommitteeIndex* = distinct uint8
|
||||
IndexInSyncCommittee* = distinct uint16
|
||||
|
||||
|
@ -547,45 +520,6 @@ template `[]`*(arr: array[SYNC_COMMITTEE_SIZE, auto] | seq;
|
|||
makeLimitedU8(SyncSubcommitteeIndex, SYNC_COMMITTEE_SUBNET_COUNT)
|
||||
makeLimitedU16(IndexInSyncCommittee, SYNC_COMMITTEE_SIZE)
|
||||
|
||||
template asList*(epochFlags: EpochParticipationFlags): untyped =
|
||||
List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT] epochFlags
|
||||
template asList*(epochFlags: var EpochParticipationFlags): untyped =
|
||||
let tmp = cast[ptr List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]](addr epochFlags)
|
||||
tmp[]
|
||||
|
||||
template asSeq*(epochFlags: EpochParticipationFlags): untyped =
|
||||
seq[ParticipationFlags] asList(epochFlags)
|
||||
|
||||
template asSeq*(epochFlags: var EpochParticipationFlags): untyped =
|
||||
let tmp = cast[ptr seq[ParticipationFlags]](addr epochFlags)
|
||||
tmp[]
|
||||
|
||||
template item*(epochFlags: EpochParticipationFlags, idx: ValidatorIndex): ParticipationFlags =
|
||||
asList(epochFlags)[idx]
|
||||
|
||||
template `[]`*(epochFlags: EpochParticipationFlags, idx: ValidatorIndex|uint64|int): ParticipationFlags =
|
||||
asList(epochFlags)[idx]
|
||||
|
||||
template `[]=`*(epochFlags: EpochParticipationFlags, idx: ValidatorIndex, flags: ParticipationFlags) =
|
||||
asList(epochFlags)[idx] = flags
|
||||
|
||||
template add*(epochFlags: var EpochParticipationFlags, flags: ParticipationFlags): bool =
|
||||
asList(epochFlags).add flags
|
||||
|
||||
template len*(epochFlags: EpochParticipationFlags): int =
|
||||
asList(epochFlags).len
|
||||
|
||||
template low*(epochFlags: EpochParticipationFlags): int =
|
||||
asSeq(epochFlags).low
|
||||
template high*(epochFlags: EpochParticipationFlags): int =
|
||||
asSeq(epochFlags).high
|
||||
|
||||
template assign*(v: var EpochParticipationFlags, src: EpochParticipationFlags) =
|
||||
# TODO https://github.com/nim-lang/Nim/issues/21123
|
||||
mixin assign
|
||||
var tmp = cast[ptr seq[ParticipationFlags]](addr v)
|
||||
assign(tmp[], distinctBase src)
|
||||
|
||||
func shortLog*(v: SomeBeaconBlock): auto =
|
||||
(
|
||||
slot: shortLog(v.slot),
|
||||
|
@ -630,23 +564,6 @@ func shortLog*(v: SyncCommitteeMessage): auto =
|
|||
signature: shortLog(v.signature)
|
||||
)
|
||||
|
||||
func init*(T: type SyncAggregate): SyncAggregate =
|
||||
SyncAggregate(sync_committee_signature: ValidatorSig.infinity)
|
||||
|
||||
func num_active_participants*(v: SomeSyncAggregate): int =
|
||||
countOnes(v.sync_committee_bits)
|
||||
|
||||
func hasSupermajoritySyncParticipation*(
|
||||
num_active_participants: uint64): bool =
|
||||
const max_active_participants = SYNC_COMMITTEE_SIZE.uint64
|
||||
num_active_participants * 3 >= static(max_active_participants * 2)
|
||||
|
||||
func hasSupermajoritySyncParticipation*(v: SomeSyncAggregate): bool =
|
||||
hasSupermajoritySyncParticipation(v.num_active_participants.uint64)
|
||||
|
||||
func shortLog*(v: SyncAggregate): auto =
|
||||
$(v.sync_committee_bits)
|
||||
|
||||
func shortLog*(v: ContributionAndProof): auto =
|
||||
(
|
||||
aggregator_index: v.aggregator_index,
|
||||
|
@ -741,7 +658,3 @@ template asTrusted*(
|
|||
SigVerifiedSignedBeaconBlock |
|
||||
MsgTrustedSignedBeaconBlock): TrustedSignedBeaconBlock =
|
||||
isomorphicCast[TrustedSignedBeaconBlock](x)
|
||||
|
||||
template asTrusted*(
|
||||
x: SyncAggregate): TrustedSyncAggregate =
|
||||
isomorphicCast[TrustedSyncAggregate](x)
|
||||
|
|
|
@ -70,9 +70,11 @@ import
|
|||
../../version,
|
||||
".."/[beacon_time, crypto, digest, presets]
|
||||
|
||||
from kzg4844 import KzgCommitment
|
||||
|
||||
export
|
||||
tables, results, endians2, json_serialization, sszTypes, beacon_time, crypto,
|
||||
digest, presets
|
||||
digest, presets, kzg4844
|
||||
|
||||
const SPEC_VERSION* = "1.5.0-alpha.2"
|
||||
## Spec version we're aiming to be compatible with, right now
|
||||
|
@ -224,6 +226,11 @@ type
|
|||
|
||||
CommitteeValidatorsBits* = BitList[Limit MAX_VALIDATORS_PER_COMMITTEE]
|
||||
|
||||
ElectraCommitteeValidatorsBits* =
|
||||
BitList[Limit MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]
|
||||
|
||||
AttestationCommitteeBits* = BitArray[MAX_COMMITTEES_PER_SLOT.int]
|
||||
|
||||
ForkDigest* = distinct array[4, byte]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#forkdata
|
||||
|
@ -281,6 +288,7 @@ type
|
|||
SomeProposerSlashing* = ProposerSlashing | TrustedProposerSlashing
|
||||
SomeSignedBeaconBlockHeader* = SignedBeaconBlockHeader | TrustedSignedBeaconBlockHeader
|
||||
SomeSignedVoluntaryExit* = SignedVoluntaryExit | TrustedSignedVoluntaryExit
|
||||
SomeSyncAggregate* = SyncAggregate | TrustedSyncAggregate
|
||||
|
||||
# Legacy database type, see BeaconChainDB
|
||||
ImmutableValidatorData* = object
|
||||
|
@ -363,6 +371,116 @@ type
|
|||
message*: VoluntaryExit
|
||||
signature*: TrustedSig
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#syncaggregate
|
||||
SyncAggregate* = object
|
||||
sync_committee_bits*: BitArray[SYNC_COMMITTEE_SIZE]
|
||||
sync_committee_signature*: ValidatorSig
|
||||
|
||||
TrustedSyncAggregate* = object
|
||||
sync_committee_bits*: BitArray[SYNC_COMMITTEE_SIZE]
|
||||
sync_committee_signature*: TrustedSig
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#custom-types
|
||||
Transaction* = List[byte, Limit MAX_BYTES_PER_TRANSACTION]
|
||||
|
||||
ExecutionAddress* = object
|
||||
data*: array[20, byte] # TODO there's a network_metadata type, but the import hierarchy's inconvenient
|
||||
|
||||
BloomLogs* = object
|
||||
data*: array[BYTES_PER_LOGS_BLOOM, byte]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#withdrawal
|
||||
Withdrawal* = object
|
||||
index*: WithdrawalIndex
|
||||
validator_index*: uint64
|
||||
address*: ExecutionAddress
|
||||
amount*: Gwei
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/94a0b6c581f2809aa8aca4ef7ee6fbb63f9d74e9/specs/electra/beacon-chain.md#depositreceipt
|
||||
DepositReceipt* = object
|
||||
pubkey*: ValidatorPubKey
|
||||
withdrawal_credentials*: Eth2Digest
|
||||
amount*: Gwei
|
||||
signature*: ValidatorSig
|
||||
index*: uint64
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#executionlayerwithdrawalrequest
|
||||
ExecutionLayerWithdrawalRequest* = object
|
||||
source_address*: ExecutionAddress
|
||||
validator_pubkey*: ValidatorPubKey
|
||||
amount*: Gwei
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#blstoexecutionchange
|
||||
BLSToExecutionChange* = object
|
||||
validator_index*: uint64
|
||||
from_bls_pubkey*: ValidatorPubKey
|
||||
to_execution_address*: ExecutionAddress
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#signedblstoexecutionchange
|
||||
SignedBLSToExecutionChange* = object
|
||||
message*: BLSToExecutionChange
|
||||
signature*: ValidatorSig
|
||||
|
||||
SignedBLSToExecutionChangeList* =
|
||||
List[SignedBLSToExecutionChange, Limit MAX_BLS_TO_EXECUTION_CHANGES]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#beaconblockbody
|
||||
KzgCommitments* = List[KzgCommitment, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#consolidation
|
||||
Consolidation* = object
|
||||
source_index*: uint64
|
||||
target_index*: uint64
|
||||
epoch*: Epoch
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#signedconsolidation
|
||||
SignedConsolidation* = object
|
||||
message*: Consolidation
|
||||
signature*: ValidatorSig
|
||||
|
||||
TrustedSignedConsolidation* = object
|
||||
message*: Consolidation
|
||||
signature*: TrustedSig
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#historicalsummary
|
||||
HistoricalSummary* = object
|
||||
# `HistoricalSummary` matches the components of the phase0
|
||||
# `HistoricalBatch` making the two hash_tree_root-compatible.
|
||||
block_summary_root*: Eth2Digest
|
||||
state_summary_root*: Eth2Digest
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#depositreceipt
|
||||
PendingBalanceDeposit* = object
|
||||
index*: uint64
|
||||
amount*: Gwei
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#pendingpartialwithdrawal
|
||||
PendingPartialWithdrawal* = object
|
||||
index*: uint64
|
||||
amount*: Gwei
|
||||
withdrawable_epoch*: Epoch
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#pendingconsolidation
|
||||
PendingConsolidation* = object
|
||||
source_index*: uint64
|
||||
target_index*: uint64
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#custom-types
|
||||
ParticipationFlags* = uint8
|
||||
|
||||
EpochParticipationFlags* =
|
||||
distinct List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
## Not a HashList because the list sees significant updates every block
|
||||
## effectively making the cost of clearing the cache higher than the typical
|
||||
## gains
|
||||
|
||||
InactivityScores* = HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#synccommittee
|
||||
SyncCommittee* = object
|
||||
pubkeys*: HashArray[Limit SYNC_COMMITTEE_SIZE, ValidatorPubKey]
|
||||
aggregate_pubkey*: ValidatorPubKey
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#beaconblockheader
|
||||
BeaconBlockHeader* = object
|
||||
slot*: Slot
|
||||
|
@ -806,9 +924,106 @@ func shortLog*(v: SomeSignedVoluntaryExit): auto =
|
|||
signature: shortLog(v.signature)
|
||||
)
|
||||
|
||||
func shortLog*(v: SomeSyncAggregate): auto =
|
||||
$(v.sync_committee_bits)
|
||||
|
||||
func init*(T: type SyncAggregate): SyncAggregate =
|
||||
SyncAggregate(sync_committee_signature: ValidatorSig.infinity)
|
||||
|
||||
template asTrusted*(
|
||||
x: SyncAggregate): TrustedSyncAggregate =
|
||||
isomorphicCast[TrustedSyncAggregate](x)
|
||||
|
||||
func num_active_participants*(v: SomeSyncAggregate): int =
|
||||
countOnes(v.sync_committee_bits)
|
||||
|
||||
func hasSupermajoritySyncParticipation*(
|
||||
num_active_participants: uint64): bool =
|
||||
const max_active_participants = SYNC_COMMITTEE_SIZE.uint64
|
||||
num_active_participants * 3 >= static(max_active_participants * 2)
|
||||
|
||||
func hasSupermajoritySyncParticipation*(v: SomeSyncAggregate): bool =
|
||||
hasSupermajoritySyncParticipation(v.num_active_participants.uint64)
|
||||
|
||||
func fromHex*(
|
||||
T: typedesc[BloomLogs], s: string): T {.raises: [ValueError].} =
|
||||
hexToByteArray(s, result.data)
|
||||
|
||||
func fromHex*(
|
||||
T: typedesc[ExecutionAddress], s: string): T {.raises: [ValueError].} =
|
||||
hexToByteArray(s, result.data)
|
||||
|
||||
proc writeValue*(
|
||||
writer: var JsonWriter, value: ExecutionAddress) {.raises: [IOError].} =
|
||||
writer.writeValue to0xHex(value.data)
|
||||
|
||||
proc readValue*(
|
||||
reader: var JsonReader,
|
||||
value: var ExecutionAddress) {.raises: [IOError, SerializationError].} =
|
||||
try:
|
||||
hexToByteArray(reader.readValue(string), value.data)
|
||||
except ValueError:
|
||||
reader.raiseUnexpectedValue(
|
||||
"ExecutionAddress value should be a valid hex string")
|
||||
|
||||
func `$`*(v: ExecutionAddress): string =
|
||||
v.data.toHex()
|
||||
|
||||
func shortLog*(v: BLSToExecutionChange): auto =
|
||||
(
|
||||
validator_index: v.validator_index,
|
||||
from_bls_pubkey: shortLog(v.from_bls_pubkey),
|
||||
to_execution_address: $v.to_execution_address
|
||||
)
|
||||
|
||||
func shortLog*(v: SignedBLSToExecutionChange): auto =
|
||||
(
|
||||
bls_to_execution_change: shortLog(v.message),
|
||||
signature: shortLog(v.signature)
|
||||
)
|
||||
|
||||
chronicles.formatIt AttestationData: it.shortLog
|
||||
chronicles.formatIt Checkpoint: it.shortLog
|
||||
|
||||
template asList*(epochFlags: EpochParticipationFlags): untyped =
|
||||
List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT] epochFlags
|
||||
template asList*(epochFlags: var EpochParticipationFlags): untyped =
|
||||
let tmp = cast[ptr List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]](addr epochFlags)
|
||||
tmp[]
|
||||
|
||||
template asSeq*(epochFlags: EpochParticipationFlags): untyped =
|
||||
seq[ParticipationFlags] asList(epochFlags)
|
||||
|
||||
template asSeq*(epochFlags: var EpochParticipationFlags): untyped =
|
||||
let tmp = cast[ptr seq[ParticipationFlags]](addr epochFlags)
|
||||
tmp[]
|
||||
|
||||
template item*(epochFlags: EpochParticipationFlags, idx: ValidatorIndex): ParticipationFlags =
|
||||
asList(epochFlags)[idx]
|
||||
|
||||
template `[]`*(epochFlags: EpochParticipationFlags, idx: ValidatorIndex|uint64|int): ParticipationFlags =
|
||||
asList(epochFlags)[idx]
|
||||
|
||||
template `[]=`*(epochFlags: EpochParticipationFlags, idx: ValidatorIndex, flags: ParticipationFlags) =
|
||||
asList(epochFlags)[idx] = flags
|
||||
|
||||
template add*(epochFlags: var EpochParticipationFlags, flags: ParticipationFlags): bool =
|
||||
asList(epochFlags).add flags
|
||||
|
||||
template len*(epochFlags: EpochParticipationFlags): int =
|
||||
asList(epochFlags).len
|
||||
|
||||
template low*(epochFlags: EpochParticipationFlags): int =
|
||||
asSeq(epochFlags).low
|
||||
template high*(epochFlags: EpochParticipationFlags): int =
|
||||
asSeq(epochFlags).high
|
||||
|
||||
template assign*(v: var EpochParticipationFlags, src: EpochParticipationFlags) =
|
||||
# TODO https://github.com/nim-lang/Nim/issues/21123
|
||||
mixin assign
|
||||
var tmp = cast[ptr seq[ParticipationFlags]](addr v)
|
||||
assign(tmp[], distinctBase src)
|
||||
|
||||
const
|
||||
# http://facweb.cs.depaul.edu/sjost/it212/documents/ascii-pr.htm
|
||||
PrintableAsciiChars = {' '..'~'}
|
||||
|
|
|
@ -35,15 +35,6 @@ const
|
|||
NEWPAYLOAD_TIMEOUT* = 8.seconds
|
||||
|
||||
type
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#custom-types
|
||||
Transaction* = List[byte, Limit MAX_BYTES_PER_TRANSACTION]
|
||||
|
||||
ExecutionAddress* = object
|
||||
data*: array[20, byte] # TODO there's a network_metadata type, but the import hierarchy's inconvenient
|
||||
|
||||
BloomLogs* = object
|
||||
data*: array[BYTES_PER_LOGS_BLOOM, byte]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/beacon-chain.md#executionpayload
|
||||
ExecutionPayload* = object
|
||||
# Execution block header fields
|
||||
|
@ -361,29 +352,6 @@ type
|
|||
func initHashedBeaconState*(s: BeaconState): HashedBeaconState =
|
||||
HashedBeaconState(data: s)
|
||||
|
||||
func fromHex*(T: typedesc[BloomLogs], s: string): T {.
|
||||
raises: [ValueError].} =
|
||||
hexToByteArray(s, result.data)
|
||||
|
||||
func fromHex*(T: typedesc[ExecutionAddress], s: string): T {.
|
||||
raises: [ValueError].} =
|
||||
hexToByteArray(s, result.data)
|
||||
|
||||
proc writeValue*(
|
||||
writer: var JsonWriter, value: ExecutionAddress) {.raises: [IOError].} =
|
||||
writer.writeValue to0xHex(value.data)
|
||||
|
||||
proc readValue*(reader: var JsonReader, value: var ExecutionAddress) {.
|
||||
raises: [IOError, SerializationError].} =
|
||||
try:
|
||||
hexToByteArray(reader.readValue(string), value.data)
|
||||
except ValueError:
|
||||
raiseUnexpectedValue(reader,
|
||||
"ExecutionAddress value should be a valid hex string")
|
||||
|
||||
func `$`*(v: ExecutionAddress): string =
|
||||
v.data.toHex()
|
||||
|
||||
func shortLog*(v: SomeBeaconBlock): auto =
|
||||
(
|
||||
slot: shortLog(v.slot),
|
||||
|
|
|
@ -36,34 +36,6 @@ const
|
|||
EXECUTION_PAYLOAD_GINDEX* = 25.GeneralizedIndex # execution_payload
|
||||
|
||||
type
|
||||
SignedBLSToExecutionChangeList* =
|
||||
List[SignedBLSToExecutionChange, Limit MAX_BLS_TO_EXECUTION_CHANGES]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#withdrawal
|
||||
Withdrawal* = object
|
||||
index*: WithdrawalIndex
|
||||
validator_index*: uint64
|
||||
address*: ExecutionAddress
|
||||
amount*: Gwei
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#blstoexecutionchange
|
||||
BLSToExecutionChange* = object
|
||||
validator_index*: uint64
|
||||
from_bls_pubkey*: ValidatorPubKey
|
||||
to_execution_address*: ExecutionAddress
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#signedblstoexecutionchange
|
||||
SignedBLSToExecutionChange* = object
|
||||
message*: BLSToExecutionChange
|
||||
signature*: ValidatorSig
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/capella/beacon-chain.md#historicalsummary
|
||||
HistoricalSummary* = object
|
||||
# `HistoricalSummary` matches the components of the phase0
|
||||
# `HistoricalBatch` making the two hash_tree_root-compatible.
|
||||
block_summary_root*: Eth2Digest
|
||||
state_summary_root*: Eth2Digest
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#executionpayload
|
||||
ExecutionPayload* = object
|
||||
# Execution block header fields
|
||||
|
@ -644,19 +616,6 @@ func shortLog*(v: ExecutionPayload): auto =
|
|||
num_withdrawals: len(v.withdrawals)
|
||||
)
|
||||
|
||||
func shortLog*(v: BLSToExecutionChange): auto =
|
||||
(
|
||||
validator_index: v.validator_index,
|
||||
from_bls_pubkey: shortLog(v.from_bls_pubkey),
|
||||
to_execution_address: $v.to_execution_address
|
||||
)
|
||||
|
||||
func shortLog*(v: SignedBLSToExecutionChange): auto =
|
||||
(
|
||||
bls_to_execution_change: shortLog(v.message),
|
||||
signature: shortLog(v.signature)
|
||||
)
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/light-client/sync-protocol.md#get_lc_execution_root
|
||||
func get_lc_execution_root*(
|
||||
header: LightClientHeader, cfg: RuntimeConfig): Eth2Digest =
|
||||
|
|
|
@ -36,22 +36,12 @@ const
|
|||
BLS_MODULUS* = "52435875175126190479447740508185965837690552500527637822603658699938581184513".u256
|
||||
|
||||
type
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#beaconblockbody
|
||||
KzgCommitments* = List[KzgCommitment, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
|
||||
|
||||
# TODO this apparently is suppposed to be SSZ-equivalent to Bytes32, but
|
||||
# current spec doesn't ever SSZ-serialize it or hash_tree_root it
|
||||
# TODO make `distinct` then add a REST serialization for it specifically, via
|
||||
# basically to0xHex, then fix BlobSidecarInfoObject to use VersionedHash, not
|
||||
# string, and rely on REST serialization, rather than serialize VersionedHash
|
||||
# field manually
|
||||
VersionedHash* = array[32, byte]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#custom-types
|
||||
BlobIndex* = uint64
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/polynomial-commitments.md#custom-types
|
||||
Blob* = array[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB, byte]
|
||||
Blob* = array[
|
||||
BYTES_PER_FIELD_ELEMENT * deneb_preset.FIELD_ELEMENTS_PER_BLOB, byte]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/p2p-interface.md#blobsidecar
|
||||
BlobSidecar* = object
|
||||
|
@ -616,7 +606,7 @@ func kzg_commitment_inclusion_proof_gindex*(
|
|||
(BLOB_KZG_COMMITMENTS_GINDEX shl 1) + 0
|
||||
# List depth
|
||||
BLOB_KZG_COMMITMENTS_PROOF_DEPTH =
|
||||
log2trunc(nextPow2(deneb.KzgCommitments.maxLen.uint64))
|
||||
log2trunc(nextPow2(KzgCommitments.maxLen.uint64))
|
||||
# First item
|
||||
BLOB_KZG_COMMITMENTS_FIRST_GINDEX =
|
||||
(BLOB_KZG_COMMITMENTS_BASE_GINDEX shl BLOB_KZG_COMMITMENTS_PROOF_DEPTH)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
{.push raises: [].}
|
||||
|
||||
# Types specific to Deneb (i.e. known to have changed across hard forks) - see
|
||||
# Types specific to Electra (i.e. known to have changed across hard forks) - see
|
||||
# `base` for types and guidelines common across forks
|
||||
|
||||
# TODO Careful, not nil analysis is broken / incomplete and the semantics will
|
||||
|
@ -22,7 +22,7 @@ import
|
|||
ssz_serialization/[merkleization, proofs],
|
||||
ssz_serialization/types as sszTypes,
|
||||
../digest,
|
||||
"."/[base, phase0]
|
||||
"."/[stable, phase0]
|
||||
|
||||
from kzg4844 import KzgCommitment, KzgProof
|
||||
from stew/bitops2 import log2trunc
|
||||
|
@ -35,7 +35,7 @@ from ./capella import
|
|||
HistoricalSummary, SignedBLSToExecutionChangeList, Withdrawal
|
||||
from ./deneb import Blobs, BlobsBundle, KzgCommitments, KzgProofs
|
||||
|
||||
export json_serialization, base, kzg4844
|
||||
export json_serialization, stable, kzg4844
|
||||
|
||||
const
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#constants
|
||||
|
@ -48,72 +48,17 @@ const
|
|||
CURRENT_SYNC_COMMITTEE_GINDEX = 86.GeneralizedIndex # current_sync_committee
|
||||
NEXT_SYNC_COMMITTEE_GINDEX = 87.GeneralizedIndex # next_sync_committee
|
||||
|
||||
# https://eips.ethereum.org/EIPS/eip-6493
|
||||
MAX_CALLDATA_SIZE* = 16_777_216
|
||||
MAX_ACCESS_LIST_STORAGE_KEYS* = 524_288
|
||||
MAX_ACCESS_LIST_SIZE* = 524_288
|
||||
|
||||
type
|
||||
ChainId* = uint64
|
||||
|
||||
Eip6493FeesPerGas* {.sszStableContainer: 16.} = object
|
||||
regular*: Opt[UInt256]
|
||||
|
||||
# EIP-4844
|
||||
blob*: Opt[UInt256]
|
||||
|
||||
Eip6493AccessTuple* = object
|
||||
address*: ExecutionAddress
|
||||
storage_keys*: List[Eth2Digest, Limit MAX_ACCESS_LIST_STORAGE_KEYS]
|
||||
|
||||
Eip6493TransactionPayload* {.sszStableContainer: 32.} = object
|
||||
# EIP-2718
|
||||
`type`*: Opt[uint8]
|
||||
|
||||
# EIP-155
|
||||
chain_id*: Opt[ChainId]
|
||||
|
||||
nonce*: Opt[uint64]
|
||||
max_fees_per_gas*: Opt[Eip6493FeesPerGas]
|
||||
gas*: Opt[uint64]
|
||||
to*: Opt[ExecutionAddress]
|
||||
value*: Opt[UInt256]
|
||||
input*: Opt[List[byte, Limit MAX_CALLDATA_SIZE]]
|
||||
|
||||
# EIP-2930
|
||||
access_list*: Opt[List[Eip6493AccessTuple, Limit MAX_ACCESS_LIST_SIZE]]
|
||||
|
||||
# EIP-1559
|
||||
max_priority_fees_per_gas*: Opt[Eip6493FeesPerGas]
|
||||
|
||||
# EIP-4844
|
||||
blob_versioned_hashes*:
|
||||
Opt[List[deneb.VersionedHash, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]]
|
||||
|
||||
Eip6493TransactionSignature* {.sszStableContainer: 16.} = object
|
||||
`from`*: Opt[ExecutionAddress]
|
||||
ecdsa_signature*: Opt[array[65, byte]]
|
||||
|
||||
Eip6493Transaction* = object
|
||||
payload*: Eip6493TransactionPayload
|
||||
signature*: Eip6493TransactionSignature
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/94a0b6c581f2809aa8aca4ef7ee6fbb63f9d74e9/specs/electra/beacon-chain.md#depositreceipt
|
||||
DepositReceipt* = object
|
||||
pubkey*: ValidatorPubKey
|
||||
withdrawal_credentials*: Eth2Digest
|
||||
amount*: Gwei
|
||||
signature*: ValidatorSig
|
||||
index*: uint64
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#indexedattestation
|
||||
IndexedAttestation* = object
|
||||
IndexedAttestation* {.
|
||||
sszProfile: StableIndexedAttestation.} = object
|
||||
attesting_indices*:
|
||||
List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]
|
||||
data*: AttestationData
|
||||
signature*: ValidatorSig
|
||||
|
||||
TrustedIndexedAttestation* = object
|
||||
TrustedIndexedAttestation* {.
|
||||
sszProfile: StableIndexedAttestation.} = object
|
||||
# The Trusted version, at the moment, implies that the cryptographic signature was checked.
|
||||
# It DOES NOT imply that the state transition was verified.
|
||||
# Currently the code MUST verify the state transition as soon as the signature is verified
|
||||
|
@ -135,7 +80,8 @@ type
|
|||
attestation_2*: TrustedIndexedAttestation # Modified in Electra:EIP7549]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#executionpayload
|
||||
ExecutionPayload* = object
|
||||
ExecutionPayload* {.
|
||||
sszProfile: StableExecutionPayload.} = object
|
||||
# Execution block header fields
|
||||
parent_hash*: Eth2Digest
|
||||
fee_recipient*: ExecutionAddress
|
||||
|
@ -171,7 +117,8 @@ type
|
|||
blobsBundle*: BlobsBundle
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#executionpayloadheader
|
||||
ExecutionPayloadHeader* = object
|
||||
ExecutionPayloadHeader* {.
|
||||
sszProfile: StableExecutionPayloadHeader.} = object
|
||||
# Execution block header fields
|
||||
parent_hash*: Eth2Digest
|
||||
fee_recipient*: ExecutionAddress
|
||||
|
@ -199,43 +146,6 @@ type
|
|||
ExecutePayload* = proc(
|
||||
execution_payload: ExecutionPayload): bool {.gcsafe, raises: [].}
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#depositreceipt
|
||||
PendingBalanceDeposit* = object
|
||||
index*: uint64
|
||||
amount*: Gwei
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#pendingpartialwithdrawal
|
||||
PendingPartialWithdrawal* = object
|
||||
index*: uint64
|
||||
amount*: Gwei
|
||||
withdrawable_epoch*: Epoch
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#executionlayerwithdrawalrequest
|
||||
ExecutionLayerWithdrawalRequest* = object
|
||||
source_address*: ExecutionAddress
|
||||
validator_pubkey*: ValidatorPubKey
|
||||
amount*: Gwei
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#consolidation
|
||||
Consolidation* = object
|
||||
source_index*: uint64
|
||||
target_index*: uint64
|
||||
epoch*: Epoch
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#signedconsolidation
|
||||
SignedConsolidation* = object
|
||||
message*: Consolidation
|
||||
signature*: ValidatorSig
|
||||
|
||||
TrustedSignedConsolidation* = object
|
||||
message*: Consolidation
|
||||
signature*: TrustedSig
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#pendingconsolidation
|
||||
PendingConsolidation* = object
|
||||
source_index*: uint64
|
||||
target_index*: uint64
|
||||
|
||||
FinalityBranch =
|
||||
array[log2trunc(FINALIZED_ROOT_GINDEX), Eth2Digest]
|
||||
|
||||
|
@ -355,7 +265,8 @@ type
|
|||
current_max_active_participants*: uint64
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#beaconstate
|
||||
BeaconState* = object
|
||||
BeaconState* {.
|
||||
sszProfile: StableBeaconState.}= object
|
||||
# Versioning
|
||||
genesis_time*: uint64
|
||||
genesis_validators_root*: Eth2Digest
|
||||
|
@ -507,7 +418,8 @@ type
|
|||
body*: TrustedBeaconBlockBody
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#beaconblockbody
|
||||
BeaconBlockBody* = object
|
||||
BeaconBlockBody* {.
|
||||
sszProfile: StableBeaconBlockBody.} = object
|
||||
randao_reveal*: ValidatorSig
|
||||
eth1_data*: Eth1Data
|
||||
## Eth1 data vote
|
||||
|
@ -534,7 +446,8 @@ type
|
|||
consolidations*: List[SignedConsolidation, Limit MAX_CONSOLIDATIONS]
|
||||
## [New in Electra:EIP7251]
|
||||
|
||||
SigVerifiedBeaconBlockBody* = object
|
||||
SigVerifiedBeaconBlockBody* {.
|
||||
sszProfile: StableBeaconBlockBody.} = object
|
||||
## A BeaconBlock body with signatures verified
|
||||
## including:
|
||||
## - Randao reveal
|
||||
|
@ -575,7 +488,8 @@ type
|
|||
consolidations*: List[TrustedSignedConsolidation, Limit MAX_CONSOLIDATIONS]
|
||||
## [New in Electra:EIP7251]
|
||||
|
||||
TrustedBeaconBlockBody* = object
|
||||
TrustedBeaconBlockBody* {.
|
||||
sszProfile: StableBeaconBlockBody.} = object
|
||||
## A full verified block
|
||||
randao_reveal*: TrustedSig
|
||||
eth1_data*: Eth1Data
|
||||
|
@ -642,26 +556,23 @@ type
|
|||
|
||||
root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block
|
||||
|
||||
ElectraCommitteeValidatorsBits* =
|
||||
BitList[Limit MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]
|
||||
|
||||
AttestationCommitteeBits* = BitArray[MAX_COMMITTEES_PER_SLOT.int]
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#attestation
|
||||
Attestation* = object
|
||||
Attestation* {.
|
||||
sszProfile: StableAttestation.} = object
|
||||
aggregation_bits*: ElectraCommitteeValidatorsBits
|
||||
data*: AttestationData
|
||||
committee_bits*: AttestationCommitteeBits # [New in Electra:EIP7549]
|
||||
signature*: ValidatorSig
|
||||
committee_bits*: AttestationCommitteeBits # [New in Electra:EIP7549]
|
||||
|
||||
TrustedAttestation* = object
|
||||
TrustedAttestation* {.
|
||||
sszProfile: StableAttestation.} = object
|
||||
# The Trusted version, at the moment, implies that the cryptographic signature was checked.
|
||||
# It DOES NOT imply that the state transition was verified.
|
||||
# Currently the code MUST verify the state transition as soon as the signature is verified
|
||||
aggregation_bits*: ElectraCommitteeValidatorsBits
|
||||
data*: AttestationData
|
||||
committee_bits*: AttestationCommitteeBits # [New in Electra:EIP7549]
|
||||
signature*: TrustedSig
|
||||
committee_bits*: AttestationCommitteeBits # [New in Electra:EIP7549]
|
||||
|
||||
SomeSignedBeaconBlock* =
|
||||
SignedBeaconBlock |
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2024 Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
ssz_serialization,
|
||||
./base
|
||||
|
||||
export base
|
||||
|
||||
const
|
||||
# https://eips.ethereum.org/EIPS/eip-7688
|
||||
MAX_ATTESTATION_FIELDS* = 8
|
||||
MAX_INDEXED_ATTESTATION_FIELDS* = 8
|
||||
MAX_EXECUTION_PAYLOAD_FIELDS* = 64
|
||||
MAX_BEACON_BLOCK_BODY_FIELDS* = 64
|
||||
MAX_BEACON_STATE_FIELDS* = 128
|
||||
|
||||
# https://eips.ethereum.org/EIPS/eip-6493
|
||||
MAX_CALLDATA_SIZE* = 16_777_216
|
||||
MAX_ACCESS_LIST_STORAGE_KEYS* = 524_288
|
||||
MAX_ACCESS_LIST_SIZE* = 524_288
|
||||
|
||||
type
|
||||
# TODO this apparently is suppposed to be SSZ-equivalent to Bytes32, but
|
||||
# current spec doesn't ever SSZ-serialize it or hash_tree_root it
|
||||
# TODO make `distinct` then add a REST serialization for it specifically, via
|
||||
# basically to0xHex, then fix BlobSidecarInfoObject to use VersionedHash, not
|
||||
# string, and rely on REST serialization, rather than serialize VersionedHash
|
||||
# field manually
|
||||
VersionedHash* = array[32, byte]
|
||||
|
||||
ChainId* = uint64
|
||||
|
||||
Eip6493FeesPerGas* {.sszStableContainer: 16.} = object
|
||||
regular*: Opt[UInt256]
|
||||
|
||||
# EIP-4844
|
||||
blob*: Opt[UInt256]
|
||||
|
||||
Eip6493AccessTuple* = object
|
||||
address*: ExecutionAddress
|
||||
storage_keys*: List[Eth2Digest, Limit MAX_ACCESS_LIST_STORAGE_KEYS]
|
||||
|
||||
Eip6493TransactionPayload* {.sszStableContainer: 32.} = object
|
||||
# EIP-2718
|
||||
`type`*: Opt[uint8]
|
||||
|
||||
# EIP-155
|
||||
chain_id*: Opt[ChainId]
|
||||
|
||||
nonce*: Opt[uint64]
|
||||
max_fees_per_gas*: Opt[Eip6493FeesPerGas]
|
||||
gas*: Opt[uint64]
|
||||
to*: Opt[ExecutionAddress]
|
||||
value*: Opt[UInt256]
|
||||
input*: Opt[List[byte, Limit MAX_CALLDATA_SIZE]]
|
||||
|
||||
# EIP-2930
|
||||
access_list*: Opt[List[Eip6493AccessTuple, Limit MAX_ACCESS_LIST_SIZE]]
|
||||
|
||||
# EIP-1559
|
||||
max_priority_fees_per_gas*: Opt[Eip6493FeesPerGas]
|
||||
|
||||
# EIP-4844
|
||||
blob_versioned_hashes*:
|
||||
Opt[List[VersionedHash, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]]
|
||||
|
||||
Eip6493TransactionSignature* {.sszStableContainer: 16.} = object
|
||||
`from`*: Opt[ExecutionAddress]
|
||||
ecdsa_signature*: Opt[array[65, byte]]
|
||||
|
||||
Eip6493Transaction* = object
|
||||
payload*: Eip6493TransactionPayload
|
||||
signature*: Eip6493TransactionSignature
|
||||
|
||||
# https://eips.ethereum.org/EIPS/eip-7688
|
||||
StableAttestation* {.
|
||||
sszStableContainer: MAX_ATTESTATION_FIELDS.} = object
|
||||
aggregation_bits*: Opt[ElectraCommitteeValidatorsBits]
|
||||
data*: Opt[AttestationData]
|
||||
signature*: Opt[ValidatorSig]
|
||||
committee_bits*: Opt[AttestationCommitteeBits]
|
||||
|
||||
StableIndexedAttestation* {.
|
||||
sszStableContainer: MAX_INDEXED_ATTESTATION_FIELDS.} = object
|
||||
attesting_indices*: Opt[List[uint64,
|
||||
Limit MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]]
|
||||
data*: Opt[AttestationData]
|
||||
signature*: Opt[ValidatorSig]
|
||||
|
||||
StableAttesterSlashing* = object
|
||||
attestation_1*: StableIndexedAttestation
|
||||
attestation_2*: StableIndexedAttestation
|
||||
|
||||
StableExecutionPayload* {.
|
||||
sszStableContainer: MAX_EXECUTION_PAYLOAD_FIELDS.} = object
|
||||
# Execution block header fields
|
||||
parent_hash*: Opt[Eth2Digest]
|
||||
fee_recipient*: Opt[ExecutionAddress]
|
||||
## 'beneficiary' in the yellow paper
|
||||
state_root*: Opt[Eth2Digest]
|
||||
receipts_root*: Opt[Eth2Digest]
|
||||
logs_bloom*: Opt[BloomLogs]
|
||||
prev_randao*: Opt[Eth2Digest]
|
||||
## 'difficulty' in the yellow paper
|
||||
block_number*: Opt[uint64]
|
||||
## 'number' in the yellow paper
|
||||
gas_limit*: Opt[uint64]
|
||||
gas_used*: Opt[uint64]
|
||||
timestamp*: Opt[uint64]
|
||||
extra_data*: Opt[List[byte, MAX_EXTRA_DATA_BYTES]]
|
||||
base_fee_per_gas*: Opt[UInt256]
|
||||
|
||||
# Extra payload fields
|
||||
block_hash*: Opt[Eth2Digest] # Hash of execution block
|
||||
transactions*: Opt[List[Eip6493Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]]
|
||||
withdrawals*: Opt[List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]]
|
||||
blob_gas_used*: Opt[uint64]
|
||||
excess_blob_gas*: Opt[uint64]
|
||||
deposit_receipts*: Opt[List[DepositReceipt,
|
||||
MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD]]
|
||||
withdrawal_requests*: Opt[List[ExecutionLayerWithdrawalRequest,
|
||||
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD]]
|
||||
|
||||
StableExecutionPayloadHeader* {.
|
||||
sszStableContainer: MAX_EXECUTION_PAYLOAD_FIELDS.} = object
|
||||
# Execution block header fields
|
||||
parent_hash*: Opt[Eth2Digest]
|
||||
fee_recipient*: Opt[ExecutionAddress]
|
||||
state_root*: Opt[Eth2Digest]
|
||||
receipts_root*: Opt[Eth2Digest]
|
||||
logs_bloom*: Opt[BloomLogs]
|
||||
prev_randao*: Opt[Eth2Digest]
|
||||
block_number*: Opt[uint64]
|
||||
gas_limit*: Opt[uint64]
|
||||
gas_used*: Opt[uint64]
|
||||
timestamp*: Opt[uint64]
|
||||
extra_data*: Opt[List[byte, MAX_EXTRA_DATA_BYTES]]
|
||||
base_fee_per_gas*: Opt[UInt256]
|
||||
|
||||
# Extra payload fields
|
||||
block_hash*: Opt[Eth2Digest]
|
||||
## Hash of execution block
|
||||
transactions_root*: Opt[Eth2Digest]
|
||||
withdrawals_root*: Opt[Eth2Digest]
|
||||
blob_gas_used*: Opt[uint64]
|
||||
excess_blob_gas*: Opt[uint64]
|
||||
deposit_receipts_root*: Opt[Eth2Digest]
|
||||
withdrawal_requests_root*: Opt[Eth2Digest]
|
||||
|
||||
StableBeaconBlockBody* {.
|
||||
sszStableContainer: MAX_BEACON_BLOCK_BODY_FIELDS.} = object
|
||||
randao_reveal*: Opt[ValidatorSig]
|
||||
eth1_data*: Opt[Eth1Data]
|
||||
## Eth1 data vote
|
||||
|
||||
graffiti*: Opt[GraffitiBytes]
|
||||
## Arbitrary data
|
||||
|
||||
# Operations
|
||||
proposer_slashings*: Opt[List[ProposerSlashing,
|
||||
Limit MAX_PROPOSER_SLASHINGS]]
|
||||
attester_slashings*: Opt[List[StableAttesterSlashing,
|
||||
Limit MAX_ATTESTER_SLASHINGS_ELECTRA]]
|
||||
attestations*: Opt[List[StableAttestation, Limit MAX_ATTESTATIONS_ELECTRA]]
|
||||
deposits*: Opt[List[Deposit, Limit MAX_DEPOSITS]]
|
||||
voluntary_exits*: Opt[List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]]
|
||||
|
||||
sync_aggregate*: Opt[SyncAggregate]
|
||||
|
||||
# Execution
|
||||
execution_payload*: Opt[StableExecutionPayload]
|
||||
bls_to_execution_changes*: Opt[SignedBLSToExecutionChangeList]
|
||||
blob_kzg_commitments*: Opt[KzgCommitments]
|
||||
consolidations*: Opt[List[SignedConsolidation, Limit MAX_CONSOLIDATIONS]]
|
||||
|
||||
StableBeaconState* {.sszStableContainer: MAX_BEACON_STATE_FIELDS.} = object
|
||||
# Versioning
|
||||
genesis_time*: Opt[uint64]
|
||||
genesis_validators_root*: Opt[Eth2Digest]
|
||||
slot*: Opt[Slot]
|
||||
fork*: Opt[Fork]
|
||||
|
||||
# History
|
||||
latest_block_header*: Opt[BeaconBlockHeader]
|
||||
## `latest_block_header.state_root == ZERO_HASH` temporarily
|
||||
|
||||
block_roots*: Opt[HashArray[Limit SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]]
|
||||
## Needed to process attestations, older to newer
|
||||
|
||||
state_roots*: Opt[HashArray[Limit SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]]
|
||||
historical_roots*: Opt[HashList[Eth2Digest, Limit HISTORICAL_ROOTS_LIMIT]]
|
||||
## Frozen in Capella, replaced by historical_summaries
|
||||
|
||||
# Eth1
|
||||
eth1_data*: Opt[Eth1Data]
|
||||
eth1_data_votes*: Opt[HashList[Eth1Data,
|
||||
Limit(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH)]]
|
||||
eth1_deposit_index*: Opt[uint64]
|
||||
|
||||
# Registry
|
||||
validators*: Opt[HashList[Validator, Limit VALIDATOR_REGISTRY_LIMIT]]
|
||||
balances*: Opt[HashList[Gwei, Limit VALIDATOR_REGISTRY_LIMIT]]
|
||||
|
||||
# Randomness
|
||||
randao_mixes*: Opt[HashArray[
|
||||
Limit EPOCHS_PER_HISTORICAL_VECTOR, Eth2Digest]]
|
||||
|
||||
# Slashings
|
||||
slashings*: Opt[HashArray[Limit EPOCHS_PER_SLASHINGS_VECTOR, Gwei]]
|
||||
## Per-epoch sums of slashed effective balances
|
||||
|
||||
# Participation
|
||||
previous_epoch_participation*: Opt[EpochParticipationFlags]
|
||||
current_epoch_participation*: Opt[EpochParticipationFlags]
|
||||
|
||||
# Finality
|
||||
justification_bits*: Opt[JustificationBits]
|
||||
## Bit set for every recent justified epoch
|
||||
|
||||
previous_justified_checkpoint*: Opt[Checkpoint]
|
||||
current_justified_checkpoint*: Opt[Checkpoint]
|
||||
finalized_checkpoint*: Opt[Checkpoint]
|
||||
|
||||
# Inactivity
|
||||
inactivity_scores*: Opt[InactivityScores]
|
||||
|
||||
# Light client sync committees
|
||||
current_sync_committee*: Opt[SyncCommittee]
|
||||
next_sync_committee*: Opt[SyncCommittee]
|
||||
|
||||
# Execution
|
||||
latest_execution_payload_header*: Opt[StableExecutionPayloadHeader]
|
||||
|
||||
# Withdrawals
|
||||
next_withdrawal_index*: Opt[WithdrawalIndex]
|
||||
next_withdrawal_validator_index*: Opt[uint64]
|
||||
|
||||
# Deep history valid from Capella onwards
|
||||
historical_summaries*:
|
||||
Opt[HashList[HistoricalSummary, Limit HISTORICAL_ROOTS_LIMIT]]
|
||||
|
||||
deposit_receipts_start_index*: Opt[uint64]
|
||||
deposit_balance_to_consume*: Opt[Gwei]
|
||||
exit_balance_to_consume*: Opt[Gwei]
|
||||
earliest_exit_epoch*: Opt[Epoch]
|
||||
consolidation_balance_to_consume*: Opt[Gwei]
|
||||
earliest_consolidation_epoch*: Opt[Epoch]
|
||||
pending_balance_deposits*: Opt[HashList[PendingBalanceDeposit,
|
||||
Limit PENDING_BALANCE_DEPOSITS_LIMIT]]
|
||||
|
||||
pending_partial_withdrawals*: Opt[HashList[PendingPartialWithdrawal,
|
||||
Limit PENDING_PARTIAL_WITHDRAWALS_LIMIT]]
|
||||
pending_consolidations*: Opt[HashList[PendingConsolidation,
|
||||
Limit PENDING_CONSOLIDATIONS_LIMIT]]
|
|
@ -1173,6 +1173,16 @@ template withForkyMaybeBlindedBlck*(
|
|||
template forkyMaybeBlindedBlck: untyped {.inject, used.} = b.phase0Data
|
||||
body
|
||||
|
||||
template shortLog*(x: ForkedMaybeBlindedBeaconBlock): auto =
|
||||
withForkyMaybeBlindedBlck(x):
|
||||
when consensusFork >= ConsensusFork.Deneb:
|
||||
when isBlinded == true:
|
||||
shortLog(forkyMaybeBlindedBlck)
|
||||
else:
|
||||
shortLog(forkyMaybeBlindedBlck.`block`)
|
||||
else:
|
||||
shortLog(forkyMaybeBlindedBlck)
|
||||
|
||||
template withStateAndBlck*(
|
||||
s: ForkedHashedBeaconState,
|
||||
b: ForkedBeaconBlock | ForkedSignedBeaconBlock |
|
||||
|
@ -1360,19 +1370,19 @@ func readSszForkedHashedBeaconState*(cfg: RuntimeConfig, data: openArray[byte]):
|
|||
ForkedHashedBeaconState {.raises: [SerializationError].} =
|
||||
## Read a state picking the right fork by first reading the slot from the byte
|
||||
## source
|
||||
if data.len() < sizeof(BeaconStateHeader):
|
||||
raise (ref MalformedSszError)(msg: "Not enough data for BeaconState header")
|
||||
const numHeaderBytes = fixedPortionSize(BeaconStateHeader)
|
||||
if data.len() < numHeaderBytes:
|
||||
raise (ref MalformedSszError)(msg: "Incomplete BeaconState header")
|
||||
let header = SSZ.decode(
|
||||
data.toOpenArray(0, sizeof(BeaconStateHeader) - 1),
|
||||
BeaconStateHeader)
|
||||
data.toOpenArray(0, numHeaderBytes - 1), BeaconStateHeader)
|
||||
|
||||
# TODO https://github.com/nim-lang/Nim/issues/19357
|
||||
result = readSszForkedHashedBeaconState(cfg, header.slot, data)
|
||||
|
||||
type
|
||||
ForkedBeaconBlockHeader = object
|
||||
message*: uint32 # message offset
|
||||
signature*: ValidatorSig
|
||||
message: uint32 # message offset
|
||||
signature: ValidatorSig
|
||||
slot: Slot # start of BeaconBlock
|
||||
|
||||
func readSszForkedSignedBeaconBlock*(
|
||||
|
@ -1380,11 +1390,11 @@ func readSszForkedSignedBeaconBlock*(
|
|||
ForkedSignedBeaconBlock {.raises: [SerializationError].} =
|
||||
## Helper to read a header from bytes when it's not certain what kind of block
|
||||
## it is
|
||||
if data.len() < sizeof(ForkedBeaconBlockHeader):
|
||||
raise (ref MalformedSszError)(msg: "Not enough data for SignedBeaconBlock header")
|
||||
const numHeaderBytes = fixedPortionSize(ForkedBeaconBlockHeader)
|
||||
if data.len() < numHeaderBytes:
|
||||
raise (ref MalformedSszError)(msg: "Incomplete SignedBeaconBlock header")
|
||||
let header = SSZ.decode(
|
||||
data.toOpenArray(0, sizeof(ForkedBeaconBlockHeader) - 1),
|
||||
ForkedBeaconBlockHeader)
|
||||
data.toOpenArray(0, numHeaderBytes - 1), ForkedBeaconBlockHeader)
|
||||
|
||||
# TODO https://github.com/nim-lang/Nim/issues/19357
|
||||
result = ForkedSignedBeaconBlock(
|
||||
|
|
|
@ -487,24 +487,24 @@ proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader =
|
|||
txRoot = payload.computeTransactionsTrieRoot()
|
||||
withdrawalsRoot =
|
||||
when typeof(payload).kind >= ConsensusFork.Capella:
|
||||
some payload.computeWithdrawalsTrieRoot()
|
||||
Opt.some payload.computeWithdrawalsTrieRoot()
|
||||
else:
|
||||
none(ExecutionHash256)
|
||||
Opt.none(ExecutionHash256)
|
||||
blobGasUsed =
|
||||
when typeof(payload).kind >= ConsensusFork.Deneb:
|
||||
some payload.blob_gas_used
|
||||
Opt.some payload.blob_gas_used
|
||||
else:
|
||||
none(uint64)
|
||||
Opt.none(uint64)
|
||||
excessBlobGas =
|
||||
when typeof(payload).kind >= ConsensusFork.Deneb:
|
||||
some payload.excess_blob_gas
|
||||
Opt.some payload.excess_blob_gas
|
||||
else:
|
||||
none(uint64)
|
||||
Opt.none(uint64)
|
||||
parentBeaconBlockRoot =
|
||||
when typeof(payload).kind >= ConsensusFork.Deneb:
|
||||
some ExecutionHash256(data: blck.parent_root.data)
|
||||
Opt.some ExecutionHash256(data: blck.parent_root.data)
|
||||
else:
|
||||
none(ExecutionHash256)
|
||||
Opt.none(ExecutionHash256)
|
||||
|
||||
ExecutionBlockHeader(
|
||||
parentHash : payload.parent_hash,
|
||||
|
@ -512,17 +512,17 @@ proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader =
|
|||
coinbase : EthAddress payload.fee_recipient.data,
|
||||
stateRoot : payload.state_root,
|
||||
txRoot : txRoot,
|
||||
receiptRoot : payload.receipts_root,
|
||||
bloom : payload.logs_bloom.data,
|
||||
receiptsRoot : payload.receipts_root,
|
||||
logsBloom : payload.logs_bloom.data,
|
||||
difficulty : default(DifficultyInt),
|
||||
blockNumber : payload.block_number.u256,
|
||||
number : payload.block_number,
|
||||
gasLimit : cast[GasInt](payload.gas_limit),
|
||||
gasUsed : cast[GasInt](payload.gas_used),
|
||||
timestamp : EthTime(int64.saturate payload.timestamp),
|
||||
extraData : payload.extra_data.asSeq,
|
||||
mixDigest : payload.prev_randao, # EIP-4399 `mixDigest` -> `prevRandao`
|
||||
mixHash : payload.prev_randao, # EIP-4399 `mixHash` -> `prevRandao`
|
||||
nonce : default(BlockNonce),
|
||||
fee : some payload.base_fee_per_gas,
|
||||
baseFeePerGas : Opt.some payload.base_fee_per_gas,
|
||||
withdrawalsRoot : withdrawalsRoot,
|
||||
blobGasUsed : blobGasUsed, # EIP-4844
|
||||
excessBlobGas : excessBlobGas, # EIP-4844
|
||||
|
|
|
@ -421,3 +421,23 @@ proc verify_bls_to_execution_change_signature*(
|
|||
let signing_root = compute_bls_to_execution_change_signing_root(
|
||||
genesisFork, genesis_validators_root, msg.message)
|
||||
blsVerify(pubkey, signing_root.data, signature)
|
||||
|
||||
func compute_consolidation_signing_root(
|
||||
genesisFork: Fork, genesis_validators_root: Eth2Digest,
|
||||
msg: Consolidation): Eth2Digest =
|
||||
# Uses genesis fork version regardless
|
||||
doAssert genesisFork.current_version == genesisFork.previous_version
|
||||
|
||||
let domain = compute_domain(
|
||||
DOMAIN_CONSOLIDATION, genesisFork.current_version,
|
||||
genesis_validators_root=genesis_validators_root)
|
||||
compute_signing_root(msg, domain)
|
||||
|
||||
proc verify_consolidation_signature*(
|
||||
genesisFork: Fork, genesis_validators_root: Eth2Digest,
|
||||
msg: SignedConsolidation | TrustedSignedConsolidation,
|
||||
pubkeys: openArray[ValidatorPubKey]): bool =
|
||||
withTrust(msg.signature):
|
||||
let signing_root = compute_consolidation_signing_root(
|
||||
genesisFork, genesis_validators_root, msg.message)
|
||||
blsFastAggregateVerify(pubkeys, signing_root.data, msg.signature)
|
||||
|
|
|
@ -361,7 +361,8 @@ func partialBeaconBlock*(
|
|||
deposits: seq[Deposit],
|
||||
validator_changes: BeaconBlockValidatorChanges,
|
||||
sync_aggregate: SyncAggregate,
|
||||
execution_payload: ForkyExecutionPayloadForSigning
|
||||
execution_payload: ForkyExecutionPayloadForSigning,
|
||||
consolidations: openArray[SignedConsolidation]
|
||||
): auto =
|
||||
const consensusFork = typeof(state).kind
|
||||
|
||||
|
@ -411,12 +412,14 @@ func partialBeaconBlock*(
|
|||
deposits: seq[Deposit],
|
||||
validator_changes: BeaconBlockValidatorChanges,
|
||||
sync_aggregate: SyncAggregate,
|
||||
execution_payload: ForkyExecutionPayloadForSigning
|
||||
execution_payload: ForkyExecutionPayloadForSigning,
|
||||
consolidations: seq[SignedConsolidation],
|
||||
): auto =
|
||||
const consensusFork = typeof(state).kind
|
||||
|
||||
debugComment "re-enable attester slashing packing in electra"
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/validator.md#preparing-for-a-beaconblock
|
||||
var res = consensusFork.BeaconBlock(
|
||||
consensusFork.BeaconBlock(
|
||||
slot: state.data.slot,
|
||||
proposer_index: proposer_index.uint64,
|
||||
parent_root: state.latest_block_root,
|
||||
|
@ -429,28 +432,14 @@ func partialBeaconBlock*(
|
|||
attestations:
|
||||
List[electra.Attestation, Limit MAX_ATTESTATIONS_ELECTRA](attestations),
|
||||
deposits: List[Deposit, Limit MAX_DEPOSITS](deposits),
|
||||
voluntary_exits: validator_changes.voluntary_exits))
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/altair/validator.md#preparing-a-beaconblock
|
||||
when consensusFork >= ConsensusFork.Altair:
|
||||
res.body.sync_aggregate = sync_aggregate
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/bellatrix/validator.md#block-proposal
|
||||
when consensusFork >= ConsensusFork.Bellatrix:
|
||||
res.body.execution_payload = execution_payload.executionPayload
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/capella/validator.md#block-proposal
|
||||
when consensusFork >= ConsensusFork.Capella:
|
||||
res.body.bls_to_execution_changes =
|
||||
validator_changes.bls_to_execution_changes
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/validator.md#constructing-the-beaconblockbody
|
||||
when consensusFork >= ConsensusFork.Deneb:
|
||||
res.body.blob_kzg_commitments = execution_payload.blobsBundle.commitments
|
||||
|
||||
debugComment "either consolidate this within separate function or recombine, re when consensusFork >= foo and atts/attslashings; here to allow noninterference with pre-pectra"
|
||||
|
||||
res
|
||||
voluntary_exits: validator_changes.voluntary_exits,
|
||||
sync_aggregate: sync_aggregate,
|
||||
execution_payload: execution_payload.executionPayload,
|
||||
bls_to_execution_changes: validator_changes.bls_to_execution_changes,
|
||||
blob_kzg_commitments: execution_payload.blobsBundle.commitments,
|
||||
consolidations:
|
||||
List[SignedConsolidation, Limit MAX_CONSOLIDATIONS].init(
|
||||
consolidations)))
|
||||
|
||||
proc makeBeaconBlockWithRewards*(
|
||||
cfg: RuntimeConfig,
|
||||
|
@ -464,6 +453,7 @@ proc makeBeaconBlockWithRewards*(
|
|||
validator_changes: BeaconBlockValidatorChanges,
|
||||
sync_aggregate: SyncAggregate,
|
||||
executionPayload: ForkyExecutionPayloadForSigning,
|
||||
consolidations: seq[SignedConsolidation],
|
||||
rollback: RollbackForkedHashedProc,
|
||||
cache: var StateCache,
|
||||
# TODO:
|
||||
|
@ -490,7 +480,7 @@ proc makeBeaconBlockWithRewards*(
|
|||
partialBeaconBlock(
|
||||
cfg, state.`kind Data`, proposer_index, randao_reveal, eth1_data,
|
||||
graffiti, attestations, deposits, validator_changes, sync_aggregate,
|
||||
executionPayload))
|
||||
executionPayload, consolidations))
|
||||
|
||||
let res = process_block(
|
||||
cfg, state.`kind Data`.data, blck.`kind Data`.asSigVerified(),
|
||||
|
@ -533,9 +523,8 @@ proc makeBeaconBlockWithRewards*(
|
|||
forkyState.data.latest_execution_payload_header.transactions_root =
|
||||
transactions_root.get
|
||||
|
||||
debugComment "makeBeaconBlock doesn't support Electra (i.e. check for missing beaconblock body fields)"
|
||||
when executionPayload is electra.ExecutionPayloadForSigning:
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#beaconblockbody
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#beaconblockbody
|
||||
forkyState.data.latest_block_header.body_root = hash_tree_root(
|
||||
[hash_tree_root(randao_reveal),
|
||||
hash_tree_root(eth1_data),
|
||||
|
@ -550,7 +539,9 @@ proc makeBeaconBlockWithRewards*(
|
|||
hash_tree_root(sync_aggregate),
|
||||
execution_payload_root.get,
|
||||
hash_tree_root(validator_changes.bls_to_execution_changes),
|
||||
hash_tree_root(kzg_commitments.get)
|
||||
hash_tree_root(kzg_commitments.get),
|
||||
hash_tree_root(List[SignedConsolidation, Limit MAX_CONSOLIDATIONS].init(
|
||||
consolidations))
|
||||
])
|
||||
else:
|
||||
raiseAssert "Attempt to use non-Electra payload with post-Deneb state"
|
||||
|
@ -593,6 +584,7 @@ proc makeBeaconBlock*(
|
|||
validator_changes: BeaconBlockValidatorChanges,
|
||||
sync_aggregate: SyncAggregate,
|
||||
executionPayload: ForkyExecutionPayloadForSigning,
|
||||
consolidations: seq[SignedConsolidation],
|
||||
rollback: RollbackForkedHashedProc, cache: var StateCache,
|
||||
verificationFlags: UpdateFlags,
|
||||
transactions_root: Opt[Eth2Digest],
|
||||
|
@ -603,8 +595,8 @@ proc makeBeaconBlock*(
|
|||
? makeBeaconBlockWithRewards(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, validator_changes, sync_aggregate,
|
||||
executionPayload, rollback, cache, verificationFlags, transactions_root,
|
||||
execution_payload_root, kzg_commitments)
|
||||
executionPayload, consolidations, rollback, cache, verificationFlags,
|
||||
transactions_root, execution_payload_root, kzg_commitments)
|
||||
ok(blockAndRewards.blck)
|
||||
|
||||
proc makeBeaconBlock*(
|
||||
|
@ -616,12 +608,13 @@ proc makeBeaconBlock*(
|
|||
validator_changes: BeaconBlockValidatorChanges,
|
||||
sync_aggregate: SyncAggregate,
|
||||
executionPayload: ForkyExecutionPayloadForSigning,
|
||||
consolidations: seq[SignedConsolidation],
|
||||
rollback: RollbackForkedHashedProc, cache: var StateCache):
|
||||
Result[ForkedBeaconBlock, cstring] =
|
||||
makeBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, validator_changes, sync_aggregate,
|
||||
executionPayload, rollback, cache,
|
||||
executionPayload, consolidations, rollback, cache,
|
||||
verificationFlags = {}, transactions_root = Opt.none Eth2Digest,
|
||||
execution_payload_root = Opt.none Eth2Digest,
|
||||
kzg_commitments = Opt.none KzgCommitments)
|
||||
|
@ -635,13 +628,14 @@ proc makeBeaconBlock*(
|
|||
validator_changes: BeaconBlockValidatorChanges,
|
||||
sync_aggregate: SyncAggregate,
|
||||
executionPayload: ForkyExecutionPayloadForSigning,
|
||||
consolidations: seq[SignedConsolidation],
|
||||
rollback: RollbackForkedHashedProc,
|
||||
cache: var StateCache, verificationFlags: UpdateFlags):
|
||||
Result[ForkedBeaconBlock, cstring] =
|
||||
makeBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, validator_changes, sync_aggregate,
|
||||
executionPayload, rollback, cache,
|
||||
executionPayload, consolidations, rollback, cache,
|
||||
verificationFlags = verificationFlags,
|
||||
transactions_root = Opt.none Eth2Digest,
|
||||
execution_payload_root = Opt.none Eth2Digest,
|
||||
|
|
|
@ -644,20 +644,11 @@ proc process_consolidation*(
|
|||
target_validator.withdrawal_credentials.data.toOpenArray(12, 31)):
|
||||
return err("Consolidation: source and target don't have same withdrawal address")
|
||||
|
||||
debugComment "this is per spec, near-verbatim, but Nimbus generally factors this out into spec/signatures.nim. so, create verify_consolidation_signature infra there, call here"
|
||||
# Verify consolidation is signed by the source and the target
|
||||
let
|
||||
domain = compute_domain(
|
||||
DOMAIN_CONSOLIDATION, cfg.GENESIS_FORK_VERSION,
|
||||
genesis_validators_root=state.genesis_validators_root)
|
||||
signing_root = compute_signing_root(consolidation, domain)
|
||||
pubkeys = [source_validator[].pubkey, target_validator.pubkey]
|
||||
|
||||
debugComment "as a good example, this trustedsig hack typically/should live in spec/signatures.nim"
|
||||
when not (signed_consolidation.signature is TrustedSig):
|
||||
if not blsFastAggregateVerify(
|
||||
pubkeys, signing_root.data, signed_consolidation.signature):
|
||||
return err("Consolidation: invalid signature")
|
||||
if not verify_consolidation_signature(
|
||||
cfg.genesisFork, state.genesis_validators_root, signed_consolidation,
|
||||
[source_validator[].pubkey, target_validator.pubkey]):
|
||||
return err("Consolidation: invalid signature")
|
||||
|
||||
# Initiate source validator exit and append pending consolidation
|
||||
source_validator[].exit_epoch = compute_consolidation_epoch_and_update_churn(
|
||||
|
@ -667,8 +658,7 @@ proc process_consolidation*(
|
|||
debugComment "check HashList add return value"
|
||||
discard state.pending_consolidations.add(PendingConsolidation(
|
||||
source_index: consolidation.source_index,
|
||||
target_index: consolidation.target_index
|
||||
))
|
||||
target_index: consolidation.target_index))
|
||||
|
||||
ok()
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{.push raises: [].}
|
||||
|
||||
import std/[strutils, sequtils, algorithm]
|
||||
import stew/[results, base10], chronos, chronicles
|
||||
import stew/base10, chronos, chronicles
|
||||
import
|
||||
../spec/datatypes/[phase0, altair],
|
||||
../spec/eth2_apis/rest_types,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{.push raises: [].}
|
||||
|
||||
import std/[heapqueue, tables, strutils, sequtils, math]
|
||||
import stew/[results, base10], chronos, chronicles
|
||||
import stew/base10, chronos, chronicles
|
||||
import
|
||||
../spec/datatypes/[base, phase0, altair],
|
||||
../spec/[helpers, forks],
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{.push raises: [].}
|
||||
|
||||
import
|
||||
stew/[base10, results],
|
||||
stew/base10,
|
||||
chronicles, chronos, eth/async_utils,
|
||||
./sync/[light_client_sync_helpers, sync_manager],
|
||||
./consensus_object_pools/[block_clearance, blockchain_dag],
|
||||
|
|
|
@ -39,14 +39,14 @@ type
|
|||
status*: ApiOperation
|
||||
data*: seq[ApiNodeResponse[T]]
|
||||
|
||||
ApiScore* = object
|
||||
ApiScore*[T] = object
|
||||
index*: int
|
||||
score*: Opt[float64]
|
||||
score*: Opt[T]
|
||||
|
||||
BestNodeResponse*[T] = object
|
||||
BestNodeResponse*[T, X] = object
|
||||
node*: BeaconNodeServerRef
|
||||
data*: ApiResponse[T]
|
||||
score*: float64
|
||||
score*: X
|
||||
|
||||
const
|
||||
ViableNodeStatus* = {
|
||||
|
@ -56,7 +56,7 @@ const
|
|||
RestBeaconNodeStatus.Synced
|
||||
}
|
||||
|
||||
proc `$`*(s: ApiScore): string =
|
||||
proc `$`*[T](s: ApiScore[T]): string =
|
||||
var res = Base10.toString(uint64(s.index))
|
||||
res.add(": ")
|
||||
if s.score.isSome():
|
||||
|
@ -65,22 +65,27 @@ proc `$`*(s: ApiScore): string =
|
|||
res.add("<n/a>")
|
||||
res
|
||||
|
||||
proc `$`*(ss: openArray[ApiScore]): string =
|
||||
proc `$`*[T](ss: openArray[ApiScore[T]]): string =
|
||||
"[" & ss.mapIt($it).join(",") & "]"
|
||||
|
||||
chronicles.formatIt(seq[ApiScore]):
|
||||
$it
|
||||
|
||||
func init*(t: typedesc[ApiScore], node: BeaconNodeServerRef,
|
||||
score: float64): ApiScore =
|
||||
ApiScore(index: node.index, score: Opt.some(score))
|
||||
score: float64): ApiScore[float64] =
|
||||
ApiScore[float64](index: node.index, score: Opt.some(score))
|
||||
|
||||
func init*(t: typedesc[ApiScore], node: BeaconNodeServerRef): ApiScore =
|
||||
ApiScore(index: node.index, score: Opt.none(float64))
|
||||
func init*(t: typedesc[ApiScore], node: BeaconNodeServerRef,
|
||||
score: UInt256): ApiScore[UInt256] =
|
||||
ApiScore[UInt256](index: node.index, score: Opt.some(score))
|
||||
|
||||
func init*[T](t: typedesc[BestNodeResponse], node: BeaconNodeServerRef,
|
||||
data: ApiResponse[T], score: float64): BestNodeResponse[T] =
|
||||
BestNodeResponse[T](node: node, data: data, score: score)
|
||||
func init*(tt: typedesc[ApiScore],
|
||||
node: BeaconNodeServerRef, T: typedesc): ApiScore[T] =
|
||||
ApiScore[T](index: node.index, score: Opt.none(T))
|
||||
|
||||
func init*[T, X](t: typedesc[BestNodeResponse], node: BeaconNodeServerRef,
|
||||
data: ApiResponse[T], score: X): BestNodeResponse[T, X] =
|
||||
BestNodeResponse[T, X](node: node, data: data, score: score)
|
||||
|
||||
proc lazyWaiter(node: BeaconNodeServerRef, request: FutureBase,
|
||||
requestName: string, strategy: ApiStrategyKind) {.async.} =
|
||||
|
@ -234,7 +239,7 @@ template firstSuccessParallel*(
|
|||
pendingNodes.del(index)
|
||||
|
||||
let
|
||||
node {.inject.} = beaconNode
|
||||
node {.inject, used.} = beaconNode
|
||||
apiResponse {.inject.} =
|
||||
apiResponseOr[responseType](requestFut, timerFut,
|
||||
"Timeout exceeded while awaiting for the response")
|
||||
|
@ -283,6 +288,7 @@ template bestSuccess*(
|
|||
vc: ValidatorClientRef,
|
||||
responseType: typedesc,
|
||||
handlerType: typedesc,
|
||||
scoreType: typedesc,
|
||||
timeout: Duration,
|
||||
statuses: set[RestBeaconNodeStatus],
|
||||
roles: set[BeaconNodeRole],
|
||||
|
@ -301,8 +307,8 @@ template bestSuccess*(
|
|||
|
||||
var
|
||||
retRes: ApiResponse[handlerType]
|
||||
scores: seq[ApiScore]
|
||||
bestResponse: Opt[BestNodeResponse[handlerType]]
|
||||
scores: seq[ApiScore[scoreType]]
|
||||
bestResponse: Opt[BestNodeResponse[handlerType, scoreType]]
|
||||
|
||||
block mainLoop:
|
||||
while true:
|
||||
|
@ -395,7 +401,7 @@ template bestSuccess*(
|
|||
perfectScoreFound = true
|
||||
break
|
||||
else:
|
||||
scores.add(ApiScore.init(node))
|
||||
scores.add(ApiScore.init(node, scoreType))
|
||||
|
||||
if perfectScoreFound:
|
||||
# lazyWait will cancel `pendingRequests` on timeout.
|
||||
|
@ -714,16 +720,30 @@ template firstSuccessSequential*(
|
|||
break
|
||||
|
||||
proc getErrorMessage*(response: RestPlainResponse): string =
|
||||
let res = decodeBytes(RestErrorMessage, response.data,
|
||||
response.contentType)
|
||||
if res.isOk():
|
||||
let errorObj = res.get()
|
||||
if errorObj.stacktraces.isSome():
|
||||
errorObj.message & ": [" & errorObj.stacktraces.get().join("; ") & "]"
|
||||
else:
|
||||
errorObj.message
|
||||
let res =
|
||||
decodeBytes(RestErrorMessage, response.data, response.contentType).valueOr:
|
||||
return "Unable to decode error response: [" & $error & "]"
|
||||
|
||||
if res.stacktraces.isSome():
|
||||
res.message & ": [" & res.stacktraces.get().join("; ") & "]"
|
||||
else:
|
||||
"Unable to decode error response: [" & $res.error & "]"
|
||||
res.message
|
||||
|
||||
proc unpackErrorMessage*(response: RestPlainResponse): RestIndexedErrorMessage =
|
||||
decodeBytes(RestIndexedErrorMessage, response.data,
|
||||
response.contentType).valueOr:
|
||||
let message = "Unable to decode error response: [" & $error & "]"
|
||||
return RestIndexedErrorMessage(
|
||||
code: -1,
|
||||
message: message,
|
||||
failures: default(seq[RestIndexedErrorMessageItem]))
|
||||
|
||||
proc getErrorMessage*(msg: RestIndexedErrorMessage): string =
|
||||
if len(msg.failures) > 0:
|
||||
msg.message & ": [" &
|
||||
msg.failures.mapIt($it.index & ":" & it.message).join("; ") & "]"
|
||||
else:
|
||||
msg.message
|
||||
|
||||
template handleCommunicationError(): untyped {.dirty.} =
|
||||
let failure = ApiNodeFailure.init(ApiFailure.Communication, RequestName,
|
||||
|
@ -755,6 +775,13 @@ template handle400(): untyped {.dirty.} =
|
|||
node.updateStatus(RestBeaconNodeStatus.Incompatible, failure)
|
||||
failures.add(failure)
|
||||
|
||||
template handle400Indexed(): untyped {.dirty.} =
|
||||
let failure = ApiNodeFailure.init(ApiFailure.Invalid, RequestName,
|
||||
strategy, node, response.status,
|
||||
response.unpackErrorMessage().getErrorMessage())
|
||||
node.updateStatus(RestBeaconNodeStatus.Incompatible, failure)
|
||||
failures.add(failure)
|
||||
|
||||
template handle404(): untyped {.dirty.} =
|
||||
let failure = ApiNodeFailure.init(ApiFailure.NotFound, RequestName,
|
||||
strategy, node, response.status, response.getErrorMessage())
|
||||
|
@ -1181,6 +1208,7 @@ proc getHeadBlockRoot*(
|
|||
let res = vc.bestSuccess(
|
||||
RestPlainResponse,
|
||||
GetBlockRootResponse,
|
||||
float64,
|
||||
SlotDuration,
|
||||
ViableNodeStatus,
|
||||
{BeaconNodeRole.SyncCommitteeData},
|
||||
|
@ -1413,6 +1441,7 @@ proc produceAttestationData*(
|
|||
let res = vc.bestSuccess(
|
||||
RestPlainResponse,
|
||||
ProduceAttestationDataResponse,
|
||||
float64,
|
||||
OneThirdDuration,
|
||||
ViableNodeStatus,
|
||||
{BeaconNodeRole.AttestationData},
|
||||
|
@ -1514,7 +1543,7 @@ proc submitPoolAttestations*(
|
|||
of 200:
|
||||
ApiResponse[bool].ok(true)
|
||||
of 400:
|
||||
handle400()
|
||||
handle400Indexed()
|
||||
ApiResponse[bool].err(ResponseInvalidError)
|
||||
of 500:
|
||||
handle500()
|
||||
|
@ -1542,7 +1571,7 @@ proc submitPoolAttestations*(
|
|||
of 200:
|
||||
return true
|
||||
of 400:
|
||||
handle400()
|
||||
handle400Indexed()
|
||||
false
|
||||
of 500:
|
||||
handle500()
|
||||
|
@ -1589,7 +1618,7 @@ proc submitPoolSyncCommitteeSignature*(
|
|||
of 200:
|
||||
ApiResponse[bool].ok(true)
|
||||
of 400:
|
||||
handle400()
|
||||
handle400Indexed()
|
||||
ApiResponse[bool].err(ResponseInvalidError)
|
||||
of 500:
|
||||
handle500()
|
||||
|
@ -1618,7 +1647,7 @@ proc submitPoolSyncCommitteeSignature*(
|
|||
of 200:
|
||||
return true
|
||||
of 400:
|
||||
handle400()
|
||||
handle400Indexed()
|
||||
false
|
||||
of 500:
|
||||
handle500()
|
||||
|
@ -1685,6 +1714,7 @@ proc getAggregatedAttestation*(
|
|||
let res = vc.bestSuccess(
|
||||
RestPlainResponse,
|
||||
GetAggregatedAttestationResponse,
|
||||
float64,
|
||||
OneThirdDuration,
|
||||
ViableNodeStatus,
|
||||
{BeaconNodeRole.AggregatedData},
|
||||
|
@ -1818,6 +1848,7 @@ proc produceSyncCommitteeContribution*(
|
|||
let res = vc.bestSuccess(
|
||||
RestPlainResponse,
|
||||
ProduceSyncCommitteeContributionResponse,
|
||||
float64,
|
||||
OneThirdDuration,
|
||||
ViableNodeStatus,
|
||||
{BeaconNodeRole.SyncCommitteeData},
|
||||
|
@ -2036,7 +2067,59 @@ proc produceBlockV3*(
|
|||
var failures: seq[ApiNodeFailure]
|
||||
|
||||
case strategy
|
||||
of ApiStrategyKind.First, ApiStrategyKind.Best:
|
||||
of ApiStrategyKind.Best:
|
||||
let res = vc.bestSuccess(
|
||||
RestPlainResponse,
|
||||
ProduceBlockResponseV3,
|
||||
UInt256,
|
||||
SlotDuration,
|
||||
ViableNodeStatus,
|
||||
{BeaconNodeRole.BlockProposalData},
|
||||
produceBlockV3Plain(it, slot, randao_reveal, graffiti,
|
||||
builder_boost_factor),
|
||||
getProduceBlockResponseV3Score(itresponse)):
|
||||
if apiResponse.isErr():
|
||||
handleCommunicationError()
|
||||
ApiResponse[ProduceBlockResponseV3].err(apiResponse.error)
|
||||
else:
|
||||
let response = apiResponse.get()
|
||||
case response.status
|
||||
of 200:
|
||||
let
|
||||
version = response.headers.getString("eth-consensus-version")
|
||||
blinded =
|
||||
response.headers.getString("eth-execution-payload-blinded")
|
||||
executionValue =
|
||||
response.headers.getString("eth-execution-payload-value")
|
||||
consensusValue =
|
||||
response.headers.getString("eth-consensus-block-value")
|
||||
res = decodeBytes(ProduceBlockResponseV3, response.data,
|
||||
response.contentType, version, blinded,
|
||||
executionValue, consensusValue)
|
||||
if res.isErr():
|
||||
handleUnexpectedData()
|
||||
ApiResponse[ProduceBlockResponseV3].err($res.error)
|
||||
else:
|
||||
ApiResponse[ProduceBlockResponseV3].ok(res.get())
|
||||
of 400:
|
||||
handle400()
|
||||
ApiResponse[ProduceBlockResponseV3].err(ResponseInvalidError)
|
||||
of 500:
|
||||
handle500()
|
||||
ApiResponse[ProduceBlockResponseV3].err(ResponseInternalError)
|
||||
of 503:
|
||||
handle503()
|
||||
ApiResponse[ProduceBlockResponseV3].err(
|
||||
ResponseNoSyncError)
|
||||
else:
|
||||
handleUnexpectedCode()
|
||||
ApiResponse[ProduceBlockResponseV3].err(
|
||||
ResponseUnexpectedError)
|
||||
if res.isErr():
|
||||
raise (ref ValidatorApiError)(msg: res.error, data: failures)
|
||||
return res.get()
|
||||
|
||||
of ApiStrategyKind.First:
|
||||
let res = vc.firstSuccessParallel(
|
||||
RestPlainResponse,
|
||||
ProduceBlockResponseV3,
|
||||
|
@ -2222,7 +2305,7 @@ proc publishBlock*(
|
|||
return true
|
||||
of 202:
|
||||
debug BlockBroadcasted, node = node,
|
||||
blck = shortLog(ForkedSignedBeaconBlock.init(data))
|
||||
blck = shortLog(ForkedSignedBeaconBlock.init(data))
|
||||
return true
|
||||
of 400:
|
||||
handle400()
|
||||
|
|
|
@ -87,9 +87,9 @@ proc pollForValidatorIndices*(service: DutiesServiceRef) {.async.} =
|
|||
if validator.isNone():
|
||||
missing.add(validatorLog(item.validator.pubkey, item.index))
|
||||
else:
|
||||
validator.get().updateValidator(Opt.some ValidatorAndIndex(
|
||||
index: item.index,
|
||||
validator: item.validator))
|
||||
vc.attachedValidators[].updateValidator(validator.get(),
|
||||
Opt.some ValidatorAndIndex(index: item.index,
|
||||
validator: item.validator))
|
||||
updated.add(validatorLog(item.validator.pubkey, item.index))
|
||||
list.add(validator.get())
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
import std/strutils
|
||||
import ssz_serialization/[types, bitseqs]
|
||||
import stew/endians2
|
||||
import stint
|
||||
import nimcrypto/hash
|
||||
import "."/common
|
||||
|
||||
|
@ -24,6 +25,9 @@ const
|
|||
func perfectScore*(score: float64): bool =
|
||||
score == Inf
|
||||
|
||||
func perfectScore*(score: UInt256): bool =
|
||||
score == high(UInt256)
|
||||
|
||||
proc shortScore*(score: float64): string =
|
||||
if score == Inf:
|
||||
"<perfect>"
|
||||
|
@ -32,6 +36,9 @@ proc shortScore*(score: float64): string =
|
|||
else:
|
||||
formatFloat(score, ffDecimal, 4)
|
||||
|
||||
proc shortScore*(score: UInt256): string =
|
||||
$score
|
||||
|
||||
func getLexicographicScore(digest: Eth2Digest): float64 =
|
||||
# We calculate score on first 8 bytes of digest.
|
||||
let
|
||||
|
@ -183,3 +190,28 @@ proc getUniqueVotes*(attestations: openArray[phase0.Attestation]): int =
|
|||
processVotes(attestation)
|
||||
res += count
|
||||
res
|
||||
|
||||
proc getProduceBlockResponseV3Score*(blck: ProduceBlockResponseV3): UInt256 =
|
||||
let (res, cv, ev) =
|
||||
block:
|
||||
var score256 = UInt256.zero
|
||||
let
|
||||
cvalue =
|
||||
if blck.consensusValue.isSome():
|
||||
let value = blck.consensusValue.get()
|
||||
score256 = score256 + value
|
||||
$value
|
||||
else:
|
||||
"<missing>"
|
||||
evalue =
|
||||
if blck.executionValue.isSome():
|
||||
let value = blck.executionValue.get()
|
||||
score256 = score256 + value
|
||||
$value
|
||||
else:
|
||||
"<missing>"
|
||||
(score256, cvalue, evalue)
|
||||
|
||||
debug "Block score", blck = shortLog(blck), consensus_value = cv,
|
||||
execution_value = ev, score = shortScore(res)
|
||||
res
|
||||
|
|
|
@ -152,7 +152,7 @@ proc addValidatorsFromWeb3Signer(
|
|||
gasLimit = node.consensusManager[].getGasLimit(keystore.pubkey)
|
||||
v = node.attachedValidators[].addValidator(keystore, feeRecipient,
|
||||
gasLimit)
|
||||
v.updateValidator(data)
|
||||
node.attachedValidators[].updateValidator(v, data)
|
||||
|
||||
proc addValidators*(node: BeaconNode) {.async: (raises: [CancelledError]).} =
|
||||
info "Loading validators", validatorsDir = node.config.validatorsDir(),
|
||||
|
@ -174,7 +174,7 @@ proc addValidators*(node: BeaconNode) {.async: (raises: [CancelledError]).} =
|
|||
|
||||
v = node.attachedValidators[].addValidator(keystore, feeRecipient,
|
||||
gasLimit)
|
||||
v.updateValidator(data)
|
||||
node.attachedValidators[].updateValidator(v, data)
|
||||
|
||||
# We use `allFutures` because all failures are already reported as
|
||||
# user-visible warnings in `queryValidatorsSource`.
|
||||
|
@ -363,10 +363,12 @@ proc createAndSendAttestation(node: BeaconNode,
|
|||
res =
|
||||
if consensusFork >= ConsensusFork.Electra:
|
||||
await node.router.routeAttestation(
|
||||
registered.toElectraAttestation(signature), subnet_id, checkSignature = false)
|
||||
registered.toElectraAttestation(signature), subnet_id,
|
||||
checkSignature = false, checkValidator = false)
|
||||
else:
|
||||
await node.router.routeAttestation(
|
||||
registered.toAttestation(signature), subnet_id, checkSignature = false)
|
||||
registered.toAttestation(signature), subnet_id,
|
||||
checkSignature = false, checkValidator = false)
|
||||
if not res.isOk():
|
||||
return
|
||||
|
||||
|
@ -537,6 +539,7 @@ proc makeBeaconBlockForHeadAndSlot*(
|
|||
slot, validator_index
|
||||
return err("Unable to get execution payload")
|
||||
|
||||
debugComment "flesh out consolidations"
|
||||
let res = makeBeaconBlockWithRewards(
|
||||
node.dag.cfg,
|
||||
state[],
|
||||
|
@ -549,6 +552,7 @@ proc makeBeaconBlockForHeadAndSlot*(
|
|||
exits,
|
||||
node.syncCommitteeMsgPool[].produceSyncAggregate(head.bid, slot),
|
||||
payload,
|
||||
@[], # consolidations
|
||||
noRollback, # Temporary state - no need for rollback
|
||||
cache,
|
||||
verificationFlags = {},
|
||||
|
@ -1292,7 +1296,8 @@ proc proposeBlockAux(
|
|||
else:
|
||||
Opt.none(seq[BlobSidecar])
|
||||
newBlockRef = (
|
||||
await node.router.routeSignedBeaconBlock(signedBlock, blobsOpt)
|
||||
await node.router.routeSignedBeaconBlock(signedBlock, blobsOpt,
|
||||
checkValidator = false)
|
||||
).valueOr:
|
||||
return head # Errors logged in router
|
||||
|
||||
|
@ -1853,7 +1858,7 @@ proc updateValidators(
|
|||
let
|
||||
v = node.attachedValidators[].getValidator(validators[i].pubkey).valueOr:
|
||||
continue
|
||||
v.index = Opt.some ValidatorIndex(i)
|
||||
node.attachedValidators[].setValidatorIndex(v, ValidatorIndex(i))
|
||||
|
||||
node.dutyValidatorCount = validators.len
|
||||
|
||||
|
@ -1863,10 +1868,12 @@ proc updateValidators(
|
|||
# Activation epoch can change after index is assigned..
|
||||
let index = validator.index.get()
|
||||
if index < validators.lenu64:
|
||||
validator.updateValidator(
|
||||
node.attachedValidators[].updateValidator(
|
||||
validator,
|
||||
Opt.some(ValidatorAndIndex(
|
||||
index: index, validator: validators[int index]
|
||||
)))
|
||||
))
|
||||
)
|
||||
|
||||
proc handleFallbackAttestations(node: BeaconNode, lastSlot, slot: Slot) =
|
||||
# Neither block proposal nor sync committee duties can be done in this
|
||||
|
|
|
@ -1607,7 +1607,7 @@ proc addValidator*(
|
|||
|
||||
if not isNil(host.getValidatorAndIdxFn):
|
||||
let data = host.getValidatorAndIdxFn(keystore.pubkey)
|
||||
v.updateValidator(data)
|
||||
host.validatorPool[].updateValidator(v, data)
|
||||
|
||||
proc generateDeposits*(cfg: RuntimeConfig,
|
||||
rng: var HmacDrbgContext,
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
{.push raises: [].}
|
||||
|
||||
import
|
||||
stew/results,
|
||||
std/sequtils,
|
||||
chronicles,
|
||||
metrics,
|
||||
|
@ -85,13 +84,22 @@ template getCurrentBeaconTime(router: MessageRouter): BeaconTime =
|
|||
type RouteBlockResult = Result[Opt[BlockRef], string]
|
||||
proc routeSignedBeaconBlock*(
|
||||
router: ref MessageRouter, blck: ForkySignedBeaconBlock,
|
||||
blobsOpt: Opt[seq[BlobSidecar]]):
|
||||
blobsOpt: Opt[seq[BlobSidecar]], checkValidator: bool):
|
||||
Future[RouteBlockResult] {.async: (raises: [CancelledError]).} =
|
||||
## Validate and broadcast beacon block, then add it to the block database
|
||||
## Returns the new Head when block is added successfully to dag, none when
|
||||
## block passes validation but is not added, and error otherwise
|
||||
let wallTime = router[].getCurrentBeaconTime()
|
||||
|
||||
block:
|
||||
let vindex = ValidatorIndex(blck.message.proposer_index)
|
||||
if checkValidator and (vindex in router.processor.validatorPool[]):
|
||||
warn "A validator client attempts to send a block from " &
|
||||
"validator that is also manager by beacon node",
|
||||
validator_index = vindex
|
||||
return err("Block could not be sent from validator that is also " &
|
||||
"managed by the beacon node")
|
||||
|
||||
# Start with a quick gossip validation check such that broadcasting the
|
||||
# block doesn't get the node into trouble
|
||||
block:
|
||||
|
@ -193,13 +201,14 @@ proc routeSignedBeaconBlock*(
|
|||
proc routeAttestation*(
|
||||
router: ref MessageRouter,
|
||||
attestation: phase0.Attestation | electra.Attestation,
|
||||
subnet_id: SubnetId, checkSignature: bool):
|
||||
subnet_id: SubnetId, checkSignature, checkValidator: bool):
|
||||
Future[SendResult] {.async: (raises: [CancelledError]).} =
|
||||
## Process and broadcast attestation - processing will register the it with
|
||||
## the attestation pool
|
||||
block:
|
||||
let res = await router[].processor.processAttestation(
|
||||
MsgSource.api, attestation, subnet_id, checkSignature)
|
||||
MsgSource.api, attestation, subnet_id,
|
||||
checkSignature = checkSignature, checkValidator = checkValidator)
|
||||
|
||||
if not res.isGoodForSending:
|
||||
warn "Attestation failed validation",
|
||||
|
@ -250,7 +259,7 @@ proc routeAttestation*(
|
|||
committee_index)
|
||||
|
||||
return await router.routeAttestation(
|
||||
attestation, subnet_id, checkSignature = true)
|
||||
attestation, subnet_id, checkSignature = true, checkValidator = true)
|
||||
|
||||
proc routeSignedAggregateAndProof*(
|
||||
router: ref MessageRouter, proof: phase0.SignedAggregateAndProof,
|
||||
|
|
|
@ -144,7 +144,8 @@ proc unblindAndRouteBlockMEV*(
|
|||
blck = shortLog(signedBlock)
|
||||
|
||||
let newBlockRef =
|
||||
(await node.router.routeSignedBeaconBlock(signedBlock, blobsOpt)).valueOr:
|
||||
(await node.router.routeSignedBeaconBlock(
|
||||
signedBlock, blobsOpt, checkValidator = false)).valueOr:
|
||||
# submitBlindedBlock has run, so don't allow fallback to run
|
||||
return err("routeSignedBeaconBlock error") # Errors logged in router
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{.push raises: [].}
|
||||
|
||||
import
|
||||
std/[tables, json, streams, sequtils, uri],
|
||||
std/[tables, json, streams, sequtils, uri, sets],
|
||||
chronos, chronicles, metrics,
|
||||
json_serialization/std/net,
|
||||
presto/client,
|
||||
|
@ -93,6 +93,7 @@ type
|
|||
|
||||
ValidatorPool* = object
|
||||
validators*: Table[ValidatorPubKey, AttachedValidator]
|
||||
indexSet*: HashSet[ValidatorIndex]
|
||||
slashingProtection*: SlashingProtectionDB
|
||||
doppelgangerDetectionEnabled*: bool
|
||||
|
||||
|
@ -223,10 +224,24 @@ func contains*(pool: ValidatorPool, pubkey: ValidatorPubKey): bool =
|
|||
## Returns ``true`` if validator with key ``pubkey`` present in ``pool``.
|
||||
pool.validators.contains(pubkey)
|
||||
|
||||
proc contains*(pool: ValidatorPool, index: ValidatorIndex): bool =
|
||||
## Returns ``true`` if validator with index ``index`` present in ``pool``.
|
||||
pool.indexSet.contains(index)
|
||||
|
||||
proc setValidatorIndex*(pool: var ValidatorPool, validator: AttachedValidator,
|
||||
index: ValidatorIndex) =
|
||||
pool.indexSet.incl(index)
|
||||
validator.index = Opt.some(index)
|
||||
|
||||
proc removeValidatorIndex(pool: var ValidatorPool, index: ValidatorIndex) =
|
||||
pool.indexSet.excl(index)
|
||||
|
||||
proc removeValidator*(pool: var ValidatorPool, pubkey: ValidatorPubKey) =
|
||||
## Delete validator with public key ``pubkey`` from ``pool``.
|
||||
let validator = pool.validators.getOrDefault(pubkey)
|
||||
if not(isNil(validator)):
|
||||
if validator.index.isSome():
|
||||
pool.removeValidatorIndex(validator.index.get)
|
||||
pool.validators.del(pubkey)
|
||||
case validator.kind
|
||||
of ValidatorKind.Local:
|
||||
|
@ -243,8 +258,9 @@ proc removeValidator*(pool: var ValidatorPool, pubkey: ValidatorPubKey) =
|
|||
func needsUpdate*(validator: AttachedValidator): bool =
|
||||
validator.index.isNone() or validator.activationEpoch == FAR_FUTURE_EPOCH
|
||||
|
||||
proc updateValidator*(
|
||||
validator: AttachedValidator, validatorData: Opt[ValidatorAndIndex]) =
|
||||
proc updateValidator*(pool: var ValidatorPool,
|
||||
validator: AttachedValidator,
|
||||
validatorData: Opt[ValidatorAndIndex]) =
|
||||
defer: validator.updated = true
|
||||
|
||||
let
|
||||
|
@ -259,6 +275,7 @@ proc updateValidator*(
|
|||
|
||||
## Update activation information for a validator
|
||||
if validator.index != Opt.some data.index:
|
||||
pool.setValidatorIndex(validator, data.index)
|
||||
validator.index = Opt.some data.index
|
||||
validator.validator = Opt.some data.validator
|
||||
|
||||
|
|
|
@ -289,7 +289,7 @@ template `as`(address: Eth1Address, T: type bellatrix.ExecutionAddress): T =
|
|||
template `as`(address: BlockHash, T: type Eth2Digest): T =
|
||||
asEth2Digest(address)
|
||||
|
||||
func getOrDefault[T](x: Option[T]): T =
|
||||
func getOrDefault[T](x: Opt[T]): T =
|
||||
if x.isSome:
|
||||
x.get
|
||||
else:
|
||||
|
@ -505,25 +505,25 @@ proc doCreateTestnet*(config: CliConfig,
|
|||
|
||||
proc deployContract(web3: Web3, code: seq[byte]): Future[ReceiptObject] {.async.} =
|
||||
let tr = TransactionArgs(
|
||||
`from`: web3.defaultAccount.some,
|
||||
data: code.some,
|
||||
gas: Quantity(3000000).some,
|
||||
gasPrice: Quantity(1).some)
|
||||
`from`: Opt.some web3.defaultAccount,
|
||||
data: Opt.some code,
|
||||
gas: Opt.some Quantity(3000000),
|
||||
gasPrice: Opt.some Quantity(1))
|
||||
|
||||
let r = await web3.send(tr)
|
||||
result = await web3.getMinedTransactionReceipt(r)
|
||||
|
||||
proc sendEth(web3: Web3, to: Eth1Address, valueEth: int): Future[TxHash] =
|
||||
let tr = TransactionArgs(
|
||||
`from`: web3.defaultAccount.some,
|
||||
`from`: Opt.some web3.defaultAccount,
|
||||
# TODO: Force json-rpc to generate 'data' field
|
||||
# should not be needed anymore, new execution-api schema
|
||||
# is using `input` field
|
||||
data: some(newSeq[byte]()),
|
||||
gas: Quantity(3000000).some,
|
||||
gasPrice: Quantity(1).some,
|
||||
value: some(valueEth.u256 * 1000000000000000000.u256),
|
||||
to: some(to))
|
||||
data: Opt.some(newSeq[byte]()),
|
||||
gas: Opt.some Quantity(3000000),
|
||||
gasPrice: Opt.some Quantity(1),
|
||||
value: Opt.some(valueEth.u256 * 1000000000000000000.u256),
|
||||
to: Opt.some(to))
|
||||
web3.send(tr)
|
||||
|
||||
type
|
||||
|
@ -535,7 +535,7 @@ func ethToWei(eth: UInt256): UInt256 =
|
|||
proc initWeb3(web3Url, privateKey: string): Future[Web3] {.async.} =
|
||||
result = await newWeb3(web3Url)
|
||||
if privateKey.len != 0:
|
||||
result.privateKey = some(keys.PrivateKey.fromHex(privateKey)[])
|
||||
result.privateKey = Opt.some(keys.PrivateKey.fromHex(privateKey)[])
|
||||
else:
|
||||
let accounts = await result.provider.eth_accounts()
|
||||
doAssert(accounts.len > 0)
|
||||
|
|
|
@ -79,7 +79,7 @@ stack-data==0.1.4
|
|||
terminado==0.12.1
|
||||
testpath==0.5.0
|
||||
tomli==1.2.3
|
||||
tornado==6.3.3
|
||||
tornado==6.4.1
|
||||
traitlets==5.1.1
|
||||
typing_extensions==4.0.1
|
||||
wcwidth==0.2.5
|
||||
|
|
|
@ -85,7 +85,7 @@ proc makeSimulationBlock(
|
|||
|
||||
var blck = partialBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload)
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload, @[])
|
||||
|
||||
let res = process_block(
|
||||
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
|
||||
|
@ -128,7 +128,7 @@ proc makeSimulationBlock(
|
|||
|
||||
var blck = partialBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload)
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload, @[])
|
||||
|
||||
let res = process_block(
|
||||
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
|
||||
|
|
|
@ -57,7 +57,7 @@ proc setupEngineAPI*(server: RpcServer) =
|
|||
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/paris.md#engine_forkchoiceupdatedv1
|
||||
server.rpc("engine_forkchoiceUpdatedV1") do(
|
||||
update: ForkchoiceStateV1,
|
||||
payloadAttributes: Option[PayloadAttributesV1]) -> ForkchoiceUpdatedResponse:
|
||||
payloadAttributes: Opt[PayloadAttributesV1]) -> ForkchoiceUpdatedResponse:
|
||||
info "engine_forkchoiceUpdatedV1",
|
||||
update,
|
||||
payloadAttributes
|
||||
|
@ -68,7 +68,7 @@ proc setupEngineAPI*(server: RpcServer) =
|
|||
|
||||
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/shanghai.md#engine_forkchoiceupdatedv2
|
||||
server.rpc("engine_forkchoiceUpdatedV2") do(
|
||||
forkchoiceState: ForkchoiceStateV1, payloadAttributes: Option[PayloadAttributesV2]) -> ForkchoiceUpdatedResponse:
|
||||
forkchoiceState: ForkchoiceStateV1, payloadAttributes: Opt[PayloadAttributesV2]) -> ForkchoiceUpdatedResponse:
|
||||
info "engine_forkchoiceUpdatedV2",
|
||||
forkchoiceState, payloadAttributes
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ cli do(validatorsDir: string, secretsDir: string,
|
|||
headBlockHash = payload.block_hash,
|
||||
safeBlockHash = payload.block_hash,
|
||||
finalizedBlockHash = ZERO_HASH,
|
||||
payloadAttributes = none(consensusFork.PayloadAttributes))
|
||||
payloadAttributes = Opt.none(consensusFork.PayloadAttributes))
|
||||
if status != PayloadExecutionStatus.valid:
|
||||
continue
|
||||
|
||||
|
@ -295,6 +295,7 @@ cli do(validatorsDir: string, secretsDir: string,
|
|||
BeaconBlockValidatorChanges(),
|
||||
syncAggregate,
|
||||
payload,
|
||||
@[], # consolidations
|
||||
noRollback,
|
||||
cache).get()
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ source "${SCRIPTS_DIR}/bash_utils.sh"
|
|||
|
||||
download_geth_stable() {
|
||||
if [[ ! -e "${STABLE_GETH_BINARY}" ]]; then
|
||||
GETH_VERSION="1.14.0-87246f3c" # https://geth.ethereum.org/downloads
|
||||
GETH_VERSION="1.14.5-0dd173a7" # https://geth.ethereum.org/downloads
|
||||
GETH_URL="https://gethstore.blob.core.windows.net/builds/"
|
||||
|
||||
case "${OS}-${ARCH}" in
|
||||
|
|
|
@ -12,7 +12,6 @@ import
|
|||
# Utilities
|
||||
chronicles,
|
||||
unittest2,
|
||||
stew/results,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/[beaconstate, state_transition_block],
|
||||
../../../beacon_chain/spec/datatypes/altair,
|
||||
|
|
|
@ -12,7 +12,6 @@ import
|
|||
# Utilities
|
||||
chronicles,
|
||||
unittest2,
|
||||
stew/results,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/state_transition_block,
|
||||
../../../beacon_chain/spec/datatypes/bellatrix,
|
||||
|
|
|
@ -12,7 +12,6 @@ import
|
|||
# Utilities
|
||||
chronicles,
|
||||
unittest2,
|
||||
stew/results,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/state_transition_block,
|
||||
../../../beacon_chain/spec/datatypes/capella,
|
||||
|
|
|
@ -12,7 +12,6 @@ import
|
|||
# Utilities
|
||||
chronicles,
|
||||
unittest2,
|
||||
stew/results,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/state_transition_block,
|
||||
../../../beacon_chain/spec/datatypes/deneb,
|
||||
|
|
|
@ -12,7 +12,6 @@ import
|
|||
# Utilities
|
||||
chronicles,
|
||||
unittest2,
|
||||
stew/results,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/state_transition_block,
|
||||
../../../beacon_chain/spec/datatypes/electra,
|
||||
|
|
|
@ -12,7 +12,6 @@ import
|
|||
# Utilities
|
||||
chronicles,
|
||||
unittest2,
|
||||
stew/results,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/[beaconstate, state_transition_block],
|
||||
../../../beacon_chain/spec/datatypes/phase0,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
import
|
||||
# Status libraries
|
||||
stew/[byteutils, results], chronicles,
|
||||
stew/byteutils, chronicles,
|
||||
taskpools,
|
||||
# Internals
|
||||
../../beacon_chain/spec/[helpers, forks, state_transition_block],
|
||||
|
|
|
@ -12,7 +12,7 @@ import
|
|||
std/json,
|
||||
yaml,
|
||||
kzg4844/kzg_ex,
|
||||
stew/[byteutils, results],
|
||||
stew/byteutils,
|
||||
../testutil,
|
||||
./fixtures_utils, ./os_ops
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
import
|
||||
# Status lib
|
||||
stew/results,
|
||||
chronicles,
|
||||
# Internal
|
||||
../../beacon_chain/validators/[slashing_protection, slashing_protection_v2],
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
|
||||
import
|
||||
# Standard library
|
||||
std/[os],
|
||||
std/os,
|
||||
# Status lib
|
||||
eth/db/[kvstore, kvstore_sqlite3],
|
||||
stew/[results, endians2],
|
||||
stew/endians2,
|
||||
# Internal
|
||||
../../beacon_chain/validators/slashing_protection,
|
||||
../../beacon_chain/spec/[helpers],
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
|
||||
import
|
||||
std/[json, os, random, sequtils, strutils, times],
|
||||
chronos, stew/[base10, results], chronicles, unittest2,
|
||||
chronos,
|
||||
stew/base10, chronicles, unittest2,
|
||||
yaml,
|
||||
../beacon_chain/beacon_chain_db,
|
||||
../beacon_chain/spec/deposit_snapshots,
|
||||
|
@ -39,7 +40,7 @@ proc ifNecessaryMigrateDCS(db: BeaconChainDB,
|
|||
db.putDepositContractSnapshot upgradeProc(oldSnapshot.get)
|
||||
|
||||
# Hexlified copy of
|
||||
# eth2-networks/shared/mainnet/genesis_deposit_contract_snapshot.ssz
|
||||
# mainnet/metadata/genesis_deposit_contract_snapshot.ssz
|
||||
let ds1: seq[byte] = hexToSeqByte(
|
||||
"""
|
||||
eeea1373d4aa9e099d7c9deddb694db9aeb4577755ef83f9b6345ce4357d9abfca3bfce2c
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{.used.}
|
||||
|
||||
import
|
||||
stew/results, presto/client,
|
||||
presto/client,
|
||||
testutils/unittests, chronicles,
|
||||
../beacon_chain/spec/eth2_apis/[eth2_rest_serialization, rest_types],
|
||||
./testutil
|
||||
|
|
|
@ -389,6 +389,7 @@ const
|
|||
("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01", "0.9995"),
|
||||
("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101", "0.0005"),
|
||||
]
|
||||
|
||||
ContributionDataVectors = [
|
||||
("0xffffffffffffffffffffffffffff7f7f", "0.9844"),
|
||||
("0xffffffffffffffffffffffff7f7f7f7f", "0.9688"),
|
||||
|
@ -446,6 +447,15 @@ const
|
|||
([("0xff01", Slot(0), 0'u64), ("0xff01", Slot(0), 1'u64)], 16)
|
||||
]
|
||||
|
||||
UInt256ScoreVectors = [
|
||||
("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"0"),
|
||||
("0x10",
|
||||
"0x10",
|
||||
"32")
|
||||
]
|
||||
|
||||
proc init(t: typedesc[Eth2Digest], data: string): Eth2Digest =
|
||||
let length = len(data)
|
||||
var dst = Eth2Digest()
|
||||
|
@ -755,6 +765,25 @@ suite "Validator Client test suite":
|
|||
score == "0.0000"
|
||||
isLowestScoreAggregatedAttestation(adata.data) == true
|
||||
|
||||
test "getProduceBlockResponseV3Score() default test":
|
||||
let
|
||||
bdata1 = ProduceBlockResponseV3()
|
||||
bdata2 = ProduceBlockResponseV3(
|
||||
consensusValue: Opt.some(UInt256.zero)
|
||||
)
|
||||
bdata3 = ProduceBlockResponseV3(
|
||||
executionValue: Opt.some(UInt256.zero),
|
||||
)
|
||||
bdata4 = ProduceBlockResponseV3(
|
||||
consensusValue: Opt.some(UInt256.zero),
|
||||
executionValue: Opt.some(UInt256.zero)
|
||||
)
|
||||
check:
|
||||
shortScore(getProduceBlockResponseV3Score(bdata1)) == "0"
|
||||
shortScore(getProduceBlockResponseV3Score(bdata2)) == "0"
|
||||
shortScore(getProduceBlockResponseV3Score(bdata3)) == "0"
|
||||
shortScore(getProduceBlockResponseV3Score(bdata4)) == "0"
|
||||
|
||||
test "getSyncCommitteeContributionDataScore() test vectors":
|
||||
for vector in ContributionDataVectors:
|
||||
let
|
||||
|
@ -773,11 +802,24 @@ suite "Validator Client test suite":
|
|||
check:
|
||||
score == vector[5]
|
||||
|
||||
test "getProduceBlockResponseV3Score() test vectors":
|
||||
for vector in UInt256ScoreVectors:
|
||||
let
|
||||
value1 = strictParse(vector[0], UInt256, 16).get()
|
||||
value2 = strictParse(vector[1], UInt256, 16).get()
|
||||
bdata = ProduceBlockResponseV3(
|
||||
executionValue: Opt.some(value1),
|
||||
consensusValue: Opt.some(value2)
|
||||
)
|
||||
check shortScore(getProduceBlockResponseV3Score(bdata)) == vector[2]
|
||||
|
||||
test "getUniqueVotes() test vectors":
|
||||
for vector in AttestationBitsVectors:
|
||||
let
|
||||
a1 = phase0.Attestation.init(vector[0][0][0], vector[0][0][1], vector[0][0][2])
|
||||
a2 = phase0.Attestation.init(vector[0][1][0], vector[0][1][1], vector[0][1][2])
|
||||
a1 = phase0.Attestation.init(vector[0][0][0], vector[0][0][1],
|
||||
vector[0][0][2])
|
||||
a2 = phase0.Attestation.init(vector[0][1][0], vector[0][1][1],
|
||||
vector[0][1][2])
|
||||
check getUniqueVotes([a1, a2]) == vector[1]
|
||||
|
||||
asyncTest "firstSuccessParallel() API timeout test":
|
||||
|
@ -850,6 +892,7 @@ suite "Validator Client test suite":
|
|||
let response = vc.bestSuccess(
|
||||
RestPlainResponse,
|
||||
uint64,
|
||||
float64,
|
||||
100.milliseconds,
|
||||
AllBeaconNodeStatuses,
|
||||
{BeaconNodeRole.Duties},
|
||||
|
|
|
@ -71,13 +71,14 @@ func checkResponse(a, b: openArray[KeystoreData]): bool =
|
|||
suite "Validator pool":
|
||||
test "Doppelganger for genesis validator":
|
||||
let
|
||||
pool = newClone(ValidatorPool())
|
||||
v = AttachedValidator(activationEpoch: FAR_FUTURE_EPOCH)
|
||||
|
||||
check:
|
||||
not v.triggersDoppelganger(GENESIS_EPOCH) # no check
|
||||
not v.doppelgangerReady(GENESIS_EPOCH.start_slot) # no activation
|
||||
|
||||
v.updateValidator(makeValidatorAndIndex(ValidatorIndex(1), GENESIS_EPOCH))
|
||||
pool[].updateValidator(v, makeValidatorAndIndex(ValidatorIndex(1), GENESIS_EPOCH))
|
||||
|
||||
check:
|
||||
not v.triggersDoppelganger(GENESIS_EPOCH) # no check
|
||||
|
@ -94,6 +95,7 @@ suite "Validator pool":
|
|||
|
||||
test "Doppelganger for validator that activates in same epoch as check":
|
||||
let
|
||||
pool = newClone(ValidatorPool())
|
||||
v = AttachedValidator(activationEpoch: FAR_FUTURE_EPOCH)
|
||||
now = Epoch(10).start_slot()
|
||||
|
||||
|
@ -104,7 +106,7 @@ suite "Validator pool":
|
|||
not v.doppelgangerReady(GENESIS_EPOCH.start_slot)
|
||||
not v.doppelgangerReady(now)
|
||||
|
||||
v.updateValidator(makeValidatorAndIndex(ValidatorIndex(5), FAR_FUTURE_EPOCH))
|
||||
pool[].updateValidator(v, makeValidatorAndIndex(ValidatorIndex(5), FAR_FUTURE_EPOCH))
|
||||
|
||||
check: # We still don't know when validator activates so we wouldn't trigger
|
||||
not v.triggersDoppelganger(GENESIS_EPOCH)
|
||||
|
@ -113,7 +115,7 @@ suite "Validator pool":
|
|||
not v.doppelgangerReady(GENESIS_EPOCH.start_slot)
|
||||
not v.doppelgangerReady(now)
|
||||
|
||||
v.updateValidator(makeValidatorAndIndex(ValidatorIndex(5), now.epoch()))
|
||||
pool[].updateValidator(v, makeValidatorAndIndex(ValidatorIndex(5), now.epoch()))
|
||||
|
||||
check: # No check done yet
|
||||
not v.triggersDoppelganger(GENESIS_EPOCH)
|
||||
|
|
|
@ -118,8 +118,6 @@ proc build_empty_merge_execution_payload(state: bellatrix.BeaconState):
|
|||
bellatrix.ExecutionPayloadForSigning(executionPayload: payload,
|
||||
blockValue: Wei.zero)
|
||||
|
||||
from stew/saturating_arith import saturate
|
||||
|
||||
proc build_empty_execution_payload(
|
||||
state: bellatrix.BeaconState,
|
||||
feeRecipient: Eth1Address): bellatrix.ExecutionPayloadForSigning =
|
||||
|
@ -129,8 +127,8 @@ proc build_empty_execution_payload(
|
|||
latest = state.latest_execution_payload_header
|
||||
timestamp = compute_timestamp_at_slot(state, state.slot)
|
||||
randao_mix = get_randao_mix(state, get_current_epoch(state))
|
||||
base_fee = calcEip1599BaseFee(GasInt.saturate latest.gas_limit,
|
||||
GasInt.saturate latest.gas_used,
|
||||
base_fee = calcEip1599BaseFee(latest.gas_limit,
|
||||
latest.gas_used,
|
||||
latest.base_fee_per_gas)
|
||||
|
||||
var payload = bellatrix.ExecutionPayloadForSigning(
|
||||
|
@ -172,6 +170,8 @@ proc addTestBlock*(
|
|||
cfg, state, getStateField(state, slot) + 1, cache, info, flags).expect(
|
||||
"can advance 1")
|
||||
|
||||
debugComment "add consolidations support to addTestBlock"
|
||||
|
||||
let
|
||||
proposer_index = get_beacon_proposer_index(
|
||||
state, cache, getStateField(state, slot)).expect("valid proposer index")
|
||||
|
@ -208,8 +208,6 @@ proc addTestBlock*(
|
|||
else:
|
||||
default(bellatrix.ExecutionPayloadForSigning)
|
||||
|
||||
debugComment "addTestBlock Electra attestation support"
|
||||
|
||||
makeBeaconBlock(
|
||||
cfg,
|
||||
state,
|
||||
|
@ -229,6 +227,7 @@ proc addTestBlock*(
|
|||
BeaconBlockValidatorChanges(),
|
||||
sync_aggregate,
|
||||
execution_payload,
|
||||
@[],
|
||||
noRollback,
|
||||
cache,
|
||||
verificationFlags = {skipBlsValidation})
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit ab581251bcda11e3cc120cc9e9ad1ad679340949
|
|
@ -1 +1 @@
|
|||
Subproject commit c115f3688c19eb6153e22c1e76477db4ed27fae3
|
||||
Subproject commit 9ed6c63314899d17e2c3f669adbe2bc915610982
|
|
@ -0,0 +1 @@
|
|||
Subproject commit f6b7882618a5ad2c1d2731ae35e5d16a660d5bb7
|
|
@ -1 +1 @@
|
|||
Subproject commit d091a579a2e7c4668140e675a6fb2c78b8c6dc57
|
||||
Subproject commit f29698d2e9a59453d99db7315a5af58add3c8715
|
|
@ -1 +1 @@
|
|||
Subproject commit c482b4c5b658a77cc96b49d4a397aa6d98472ac7
|
||||
Subproject commit 9b6497ed8a05ba25ee47142f3fc1f61742b51a6c
|
|
@ -1 +1 @@
|
|||
Subproject commit 1ac1d69f9512d55d15e8218a9dbdff129bf96ddb
|
||||
Subproject commit 4d0b0662ed960ab2c5a1ddbd08f77048bac13ae7
|
|
@ -1 +1 @@
|
|||
Subproject commit 4fbcfbe4c452313bd440936318a87ed708987d8b
|
||||
Subproject commit f12616d0675d9f6346141ca95f0840ab227eb213
|
|
@ -1 +1 @@
|
|||
Subproject commit 21cbe3a91a70811522554e89e6a791172cebfef2
|
||||
Subproject commit 2fa2c4425f4bb835c0517efc03009925dcd28239
|
|
@ -1 +1 @@
|
|||
Subproject commit 4c4fc6f1436b5e0468a6b3a7929bb603f0b43f33
|
||||
Subproject commit 9c7dc8c58ff9c3dfb11c2d333171b47659ed824c
|
|
@ -1 +1 @@
|
|||
Subproject commit 2bc945cc9ebfae1b688f72ea59f78fd23873d1d4
|
||||
Subproject commit 194b715b16766e383b5aef92dd779fb182faf45d
|
|
@ -1 +1 @@
|
|||
Subproject commit afae13adac25b6fa98bacf4b9f38458dc64317b0
|
||||
Subproject commit 005ee90cb6aa563cdd690910455ea05f916ead3f
|
|
@ -1 +1 @@
|
|||
Subproject commit aaef74113cadaaca690c6144eae0cf2c2a10db28
|
||||
Subproject commit 913c426d571cf82601452642e01cd11ea26f7ac6
|
|
@ -1 +1 @@
|
|||
Subproject commit 695d1c9dbec4fa0f746a15df259a19fed49e075e
|
||||
Subproject commit 9f6fc631e24bb49e6afa2bdd708e6efc840d240c
|
|
@ -1 +1 @@
|
|||
Subproject commit 104132fd0217e846b04dd26a5fbe3e43a4929a05
|
||||
Subproject commit a0a53c911606cace989074f6b806eb0546a64ef6
|
|
@ -1 +1 @@
|
|||
Subproject commit 3c238df6cd4b9c1f37a9f103383e7d2bbd420c13
|
||||
Subproject commit 9d2b382c5dc34f0d6bbd93b2a5d65dde85067e0f
|
|
@ -1 +1 @@
|
|||
Subproject commit 2e4c259d1bc6debc80ceff611e1ff6071af89ea9
|
||||
Subproject commit 6e551d737a91ecaac09f485502185e7e20e4042d
|
Loading…
Reference in New Issue