Merge branch 'feat/eip-7495' into feat_eip-6493
This commit is contained in:
commit
d221cd5a6b
|
@ -431,20 +431,22 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
|
|||
OK: 253/253 Fail: 0/253 Skip: 0/253
|
||||
## EF - SSZ generic types
|
||||
```diff
|
||||
Testing basic_vector inputs - invalid Skip
|
||||
+ Testing basic_vector inputs - valid OK
|
||||
+ Testing bitlist inputs - invalid OK
|
||||
+ Testing bitlist inputs - valid OK
|
||||
Testing bitvector inputs - invalid Skip
|
||||
+ Testing bitvector inputs - valid OK
|
||||
+ Testing boolean inputs - invalid OK
|
||||
+ Testing boolean inputs - valid OK
|
||||
+ Testing containers inputs - invalid - skipping BitsStruct OK
|
||||
+ Testing containers inputs - valid - skipping BitsStruct OK
|
||||
+ Testing uints inputs - invalid OK
|
||||
+ Testing uints inputs - valid OK
|
||||
Testing basic_vector inputs - invalid Skip
|
||||
+ Testing basic_vector inputs - valid OK
|
||||
+ Testing bitlist inputs - invalid OK
|
||||
+ Testing bitlist inputs - valid OK
|
||||
Testing bitvector inputs - invalid Skip
|
||||
+ Testing bitvector inputs - valid OK
|
||||
+ Testing boolean inputs - invalid OK
|
||||
+ Testing boolean inputs - valid OK
|
||||
+ Testing containers inputs - invalid - skipping BitsStruct OK
|
||||
+ Testing containers inputs - valid - skipping BitsStruct OK
|
||||
+ Testing profiles inputs - valid OK
|
||||
+ Testing stablecontainers inputs - valid OK
|
||||
+ Testing uints inputs - invalid OK
|
||||
+ Testing uints inputs - valid OK
|
||||
```
|
||||
OK: 10/12 Fail: 0/12 Skip: 2/12
|
||||
OK: 12/14 Fail: 0/14 Skip: 2/14
|
||||
## EIP-4881
|
||||
```diff
|
||||
+ deposit_cases OK
|
||||
|
@ -1030,4 +1032,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
|
|||
OK: 9/9 Fail: 0/9 Skip: 0/9
|
||||
|
||||
---TOTAL---
|
||||
OK: 686/691 Fail: 0/691 Skip: 5/691
|
||||
OK: 689/694 Fail: 0/694 Skip: 5/694
|
||||
|
|
|
@ -9,12 +9,8 @@
|
|||
|
||||
import
|
||||
chronicles,
|
||||
../spec/datatypes/[phase0, altair, bellatrix],
|
||||
../spec/forks
|
||||
|
||||
from ../spec/datatypes/capella import SomeBeaconBlock, TrustedBeaconBlock
|
||||
from ../spec/datatypes/deneb import SomeBeaconBlock, TrustedBeaconBlock
|
||||
|
||||
export chronicles, forks
|
||||
|
||||
type
|
||||
|
@ -76,7 +72,7 @@ func init*(
|
|||
deneb.SomeBeaconBlock | deneb.TrustedBeaconBlock |
|
||||
electra.SomeBeaconBlock | electra.TrustedBeaconBlock): BlockRef =
|
||||
BlockRef.init(
|
||||
root, Opt.some Eth2Digest(blck.body.execution_payload.block_hash),
|
||||
root, Opt.some blck.body.execution_payload.block_hash,
|
||||
executionValid =
|
||||
executionValid or blck.body.execution_payload.block_hash == ZERO_HASH,
|
||||
blck.slot)
|
||||
|
|
|
@ -16,8 +16,7 @@ import
|
|||
../spec/datatypes/base,
|
||||
./block_pools_types, blockchain_dag
|
||||
|
||||
debugComment "probably just need Electra shortLog here"
|
||||
import ../spec/forks # prune this, it's for electra attestation logging
|
||||
from ../spec/datatypes/electra import shortLog
|
||||
|
||||
export
|
||||
base, extras, block_pools_types, results
|
||||
|
|
|
@ -137,7 +137,7 @@ proc sendEth(web3: Web3, to: Eth1Address, valueEth: int): Future[TxHash] =
|
|||
# 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]()),
|
||||
data: some(newSeq[byte]()),
|
||||
gas: Quantity(3000000).some,
|
||||
gasPrice: Quantity(1).some,
|
||||
value: some(valueEth.u256 * 1000000000000000000.u256),
|
||||
|
@ -273,7 +273,7 @@ proc main() {.async.} =
|
|||
error "Failed to read an Eth1 private key from standard input"
|
||||
|
||||
if privateKey.len > 0:
|
||||
conf.privateKey = privateKey.string
|
||||
conf.privateKey = privateKey
|
||||
|
||||
let web3 = await initWeb3(conf.web3Url, conf.privateKey)
|
||||
|
||||
|
|
|
@ -366,8 +366,6 @@ proc updateGossipStatus*(
|
|||
lightClient: LightClient, slot: Slot, dagIsBehind = default(Option[bool])) =
|
||||
template cfg(): auto = lightClient.cfg
|
||||
|
||||
debugComment "when LC on electra works, add cfg.ELECTRA_FORK_EPOCH"
|
||||
|
||||
let
|
||||
epoch = slot.epoch
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@ type
|
|||
|
||||
func parseBootstrapAddress*(address: string):
|
||||
Result[enr.Record, cstring] =
|
||||
let lowerCaseAddress = toLowerAscii(string address)
|
||||
let lowerCaseAddress = toLowerAscii(address)
|
||||
if lowerCaseAddress.startsWith("enr:"):
|
||||
var enrRec: enr.Record
|
||||
if enrRec.fromURI(string address):
|
||||
if enrRec.fromURI(address):
|
||||
return ok enrRec
|
||||
return err "Invalid ENR bootstrap record"
|
||||
elif lowerCaseAddress.startsWith("enode:"):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2021-2023 Status Research & Development GmbH
|
||||
# Copyright (c) 2021-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).
|
||||
|
@ -10,5 +10,4 @@
|
|||
|
||||
--styleCheck:usages
|
||||
--styleCheck:hint
|
||||
--hint[ConvFromXtoItselfNotNeeded]:off
|
||||
--hint[Processing]:off
|
||||
|
|
|
@ -46,7 +46,7 @@ proc listRemoteValidators*(
|
|||
if item.kind == ValidatorKind.Remote and item.data.remotes.len == 1:
|
||||
validators.add RemoteKeystoreInfo(
|
||||
pubkey: item.pubkey,
|
||||
url: HttpHostUri(item.data.remotes[0].url)
|
||||
url: item.data.remotes[0].url
|
||||
)
|
||||
validators
|
||||
|
||||
|
|
|
@ -688,8 +688,8 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
message = (await PayloadType.makeBeaconBlockForHeadAndSlot(
|
||||
node, qrandao, proposer, qgraffiti, qhead, qslot)).valueOr:
|
||||
return RestApiResponse.jsonError(Http500, error)
|
||||
executionValue = Opt.some(UInt256(message.executionPayloadValue))
|
||||
consensusValue = Opt.some(UInt256(message.consensusBlockValue))
|
||||
executionValue = Opt.some(message.executionPayloadValue)
|
||||
consensusValue = Opt.some(message.consensusBlockValue)
|
||||
headers = consensusFork.getMaybeBlindedHeaders(
|
||||
isBlinded = false, executionValue, consensusValue)
|
||||
|
||||
|
@ -914,7 +914,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
request.validator_index).pubkey
|
||||
|
||||
node.validatorMonitor[].addAutoMonitor(
|
||||
validator_pubkey, ValidatorIndex(request.validator_index))
|
||||
validator_pubkey, request.validator_index)
|
||||
|
||||
RestApiResponse.jsonMsgResponse(BeaconCommitteeSubscriptionSuccess)
|
||||
|
||||
|
@ -955,7 +955,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
validator_pubkey, item.until_epoch)
|
||||
|
||||
node.validatorMonitor[].addAutoMonitor(
|
||||
validator_pubkey, ValidatorIndex(item.validator_index))
|
||||
validator_pubkey, item.validator_index)
|
||||
|
||||
RestApiResponse.jsonMsgResponse(SyncCommitteeSubscriptionSuccess)
|
||||
|
||||
|
|
|
@ -289,7 +289,7 @@ func initiate_validator_exit*(
|
|||
# Set validator exit epoch and withdrawable epoch
|
||||
validator.exit_epoch = exit_queue_epoch
|
||||
validator.withdrawable_epoch =
|
||||
Epoch(validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
|
||||
validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
||||
if validator.withdrawable_epoch < validator.exit_epoch:
|
||||
return err("Invalid large withdrawable epoch")
|
||||
state.validators.mitem(index) = validator
|
||||
|
|
|
@ -986,4 +986,3 @@ func ofLen*[T, N](ListType: type List[T, N], n: int): ListType =
|
|||
raise newException(SszSizeMismatchError)
|
||||
|
||||
template debugComment*(s: string) = discard
|
||||
template debugRaiseAssert*(s: string) = discard
|
||||
|
|
|
@ -408,8 +408,7 @@ type
|
|||
RestNimbusTimestamp2 |
|
||||
GetGraffitiResponse
|
||||
|
||||
DecodeConsensysTypes* =
|
||||
ProduceBlockResponseV2 | ProduceBlindedBlockResponse
|
||||
DecodeConsensysTypes* = ProduceBlindedBlockResponse
|
||||
|
||||
RestVersioned*[T] = object
|
||||
data*: T
|
||||
|
@ -1443,8 +1442,7 @@ template prepareForkedBlockReading(blockType: typedesc,
|
|||
if version.isNone():
|
||||
reader.raiseUnexpectedValue("Incorrect version field value")
|
||||
of "data":
|
||||
when (blockType is ProduceBlockResponseV2) or
|
||||
(blockType is ForkedBlindedBeaconBlock) or
|
||||
when (blockType is ForkedBlindedBeaconBlock) or
|
||||
(blockType is ProduceBlockResponseV3):
|
||||
if data.isSome():
|
||||
reader.raiseUnexpectedField(
|
||||
|
@ -1492,92 +1490,6 @@ template prepareForkedBlockReading(blockType: typedesc,
|
|||
if data.isNone():
|
||||
reader.raiseUnexpectedValue("Field `data` is missing")
|
||||
|
||||
proc readValue*[BlockType: ProduceBlockResponseV2](
|
||||
reader: var JsonReader[RestJson],
|
||||
value: var BlockType) {.raises: [IOError, SerializationError].} =
|
||||
var
|
||||
version: Opt[ConsensusFork]
|
||||
data: Opt[JsonString]
|
||||
blinded: Opt[bool]
|
||||
payloadValue: Opt[Uint256]
|
||||
blockValue: Opt[Uint256]
|
||||
|
||||
prepareForkedBlockReading(BlockType, reader, version, data, blinded,
|
||||
payloadValue, blockValue)
|
||||
|
||||
case version.get():
|
||||
of ConsensusFork.Phase0:
|
||||
let res =
|
||||
try:
|
||||
RestJson.decode(string(data.get()),
|
||||
phase0.BeaconBlock,
|
||||
requireAllFields = true,
|
||||
allowUnknownFields = true)
|
||||
except SerializationError:
|
||||
reader.raiseUnexpectedValue("Incorrect phase0 block format")
|
||||
value = ProduceBlockResponseV2(kind: ConsensusFork.Phase0,
|
||||
phase0Data: res)
|
||||
of ConsensusFork.Altair:
|
||||
let res =
|
||||
try:
|
||||
RestJson.decode(string(data.get()),
|
||||
altair.BeaconBlock,
|
||||
requireAllFields = true,
|
||||
allowUnknownFields = true)
|
||||
except SerializationError:
|
||||
reader.raiseUnexpectedValue("Incorrect altair block format")
|
||||
|
||||
value = ProduceBlockResponseV2(kind: ConsensusFork.Altair,
|
||||
altairData: res)
|
||||
of ConsensusFork.Bellatrix:
|
||||
let res =
|
||||
try:
|
||||
RestJson.decode(string(data.get()),
|
||||
bellatrix.BeaconBlock,
|
||||
requireAllFields = true,
|
||||
allowUnknownFields = true)
|
||||
except SerializationError:
|
||||
reader.raiseUnexpectedValue("Incorrect bellatrix block format")
|
||||
|
||||
value = ProduceBlockResponseV2(kind: ConsensusFork.Bellatrix,
|
||||
bellatrixData: res)
|
||||
of ConsensusFork.Capella:
|
||||
let res =
|
||||
try:
|
||||
RestJson.decode(string(data.get()),
|
||||
capella.BeaconBlock,
|
||||
requireAllFields = true,
|
||||
allowUnknownFields = true)
|
||||
except SerializationError:
|
||||
reader.raiseUnexpectedValue("Incorrect capella block format")
|
||||
|
||||
value = ProduceBlockResponseV2(kind: ConsensusFork.Capella,
|
||||
capellaData: res)
|
||||
of ConsensusFork.Deneb:
|
||||
let res =
|
||||
try:
|
||||
RestJson.decode(string(data.get()),
|
||||
deneb.BlockContents,
|
||||
requireAllFields = true,
|
||||
allowUnknownFields = true)
|
||||
except SerializationError:
|
||||
reader.raiseUnexpectedValue("Incorrect deneb block format")
|
||||
|
||||
value = ProduceBlockResponseV2(kind: ConsensusFork.Deneb,
|
||||
denebData: res)
|
||||
of ConsensusFork.Electra:
|
||||
let res =
|
||||
try:
|
||||
RestJson.decode(string(data.get()),
|
||||
electra.BlockContents,
|
||||
requireAllFields = true,
|
||||
allowUnknownFields = true)
|
||||
except SerializationError:
|
||||
reader.raiseUnexpectedValue("Incorrect electra block format")
|
||||
|
||||
value = ProduceBlockResponseV2(kind: ConsensusFork.Electra,
|
||||
electraData: res)
|
||||
|
||||
proc readValue*[BlockType: ForkedBlindedBeaconBlock](
|
||||
reader: var JsonReader[RestJson],
|
||||
value: var BlockType
|
||||
|
@ -3777,35 +3689,7 @@ proc decodeBytes*[T: DecodeConsensysTypes](
|
|||
data = string.fromBytes(value)
|
||||
return err("Serialization error")
|
||||
elif mediaType == OctetStreamMediaType:
|
||||
when t is ProduceBlockResponseV2:
|
||||
let fork = ConsensusFork.decodeString(consensusVersion).valueOr:
|
||||
return err("Invalid or Unsupported consensus version")
|
||||
case fork
|
||||
of ConsensusFork.Electra:
|
||||
let blckContents = ? readSszResBytes(electra.BlockContents, value)
|
||||
ok(ProduceBlockResponseV2(kind: ConsensusFork.Electra,
|
||||
electraData: blckContents))
|
||||
of ConsensusFork.Deneb:
|
||||
let blckContents = ? readSszResBytes(deneb.BlockContents, value)
|
||||
ok(ProduceBlockResponseV2(kind: ConsensusFork.Deneb,
|
||||
denebData: blckContents))
|
||||
of ConsensusFork.Capella:
|
||||
let blck = ? readSszResBytes(capella.BeaconBlock, value)
|
||||
ok(ProduceBlockResponseV2(kind: ConsensusFork.Capella,
|
||||
capellaData: blck))
|
||||
of ConsensusFork.Bellatrix:
|
||||
let blck = ? readSszResBytes(bellatrix.BeaconBlock, value)
|
||||
ok(ProduceBlockResponseV2(kind: ConsensusFork.Bellatrix,
|
||||
bellatrixData: blck))
|
||||
of ConsensusFork.Altair:
|
||||
let blck = ? readSszResBytes(altair.BeaconBlock, value)
|
||||
ok(ProduceBlockResponseV2(kind: ConsensusFork.Altair,
|
||||
altairData: blck))
|
||||
of ConsensusFork.Phase0:
|
||||
let blck = ? readSszResBytes(phase0.BeaconBlock, value)
|
||||
ok(ProduceBlockResponseV2(kind: ConsensusFork.Phase0,
|
||||
phase0Data: blck))
|
||||
elif t is ProduceBlindedBlockResponse:
|
||||
when t is ProduceBlindedBlockResponse:
|
||||
let fork = ConsensusFork.decodeString(consensusVersion).valueOr:
|
||||
return err("Invalid or Unsupported consensus version")
|
||||
case fork
|
||||
|
|
|
@ -212,7 +212,7 @@ proc getLightClientBootstrap*(
|
|||
let consensusForkRes = ConsensusFork.decodeString(
|
||||
resp.headers.getString("eth-consensus-version"))
|
||||
if consensusForkRes.isErr:
|
||||
raiseRestDecodingBytesError(cstring(consensusForkRes.error))
|
||||
raiseRestDecodingBytesError(consensusForkRes.error)
|
||||
ForkedLightClientBootstrap.decodeHttpLightClientObject(
|
||||
data, resp.contentType, consensusForkRes.get, cfg)
|
||||
of 404:
|
||||
|
@ -294,7 +294,7 @@ proc getLightClientFinalityUpdate*(
|
|||
let consensusForkRes = ConsensusFork.decodeString(
|
||||
resp.headers.getString("eth-consensus-version"))
|
||||
if consensusForkRes.isErr:
|
||||
raiseRestDecodingBytesError(cstring(consensusForkRes.error))
|
||||
raiseRestDecodingBytesError(consensusForkRes.error)
|
||||
ForkedLightClientFinalityUpdate.decodeHttpLightClientObject(
|
||||
data, resp.contentType, consensusForkRes.get, cfg)
|
||||
of 404:
|
||||
|
@ -336,7 +336,7 @@ proc getLightClientOptimisticUpdate*(
|
|||
let consensusForkRes = ConsensusFork.decodeString(
|
||||
resp.headers.getString("eth-consensus-version"))
|
||||
if consensusForkRes.isErr:
|
||||
raiseRestDecodingBytesError(cstring(consensusForkRes.error))
|
||||
raiseRestDecodingBytesError(consensusForkRes.error)
|
||||
ForkedLightClientOptimisticUpdate.decodeHttpLightClientObject(
|
||||
data, resp.contentType, consensusForkRes.get, cfg)
|
||||
of 404:
|
||||
|
|
|
@ -370,15 +370,6 @@ type
|
|||
of ConsensusFork.Deneb: denebBody*: deneb.BeaconBlockBody
|
||||
of ConsensusFork.Electra: electraBody*: electra.BeaconBlockBody
|
||||
|
||||
ProduceBlockResponseV2* = object
|
||||
case kind*: ConsensusFork
|
||||
of ConsensusFork.Phase0: phase0Data*: phase0.BeaconBlock
|
||||
of ConsensusFork.Altair: altairData*: altair.BeaconBlock
|
||||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.BeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella.BeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb.BlockContents
|
||||
of ConsensusFork.Electra: electraData*: electra.BlockContents
|
||||
|
||||
ProduceBlockResponseV3* = ForkedMaybeBlindedBeaconBlock
|
||||
|
||||
VCRuntimeConfig* = Table[string, string]
|
||||
|
@ -1113,27 +1104,3 @@ func toValidatorIndex*(value: RestValidatorIndex): Result[ValidatorIndex,
|
|||
err(ValidatorIndexError.TooHighValue)
|
||||
else:
|
||||
doAssert(false, "ValidatorIndex type size is incorrect")
|
||||
|
||||
template withBlck*(x: ProduceBlockResponseV2,
|
||||
body: untyped): untyped =
|
||||
case x.kind
|
||||
of ConsensusFork.Phase0:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Phase0
|
||||
template blck: untyped {.inject.} = x.phase0Data
|
||||
body
|
||||
of ConsensusFork.Altair:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Altair
|
||||
template blck: untyped {.inject.} = x.altairData
|
||||
body
|
||||
of ConsensusFork.Bellatrix:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Bellatrix
|
||||
template blck: untyped {.inject.} = x.bellatrixData
|
||||
body
|
||||
of ConsensusFork.Capella:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Capella
|
||||
template blck: untyped {.inject.} = x.capellaData
|
||||
body
|
||||
of ConsensusFork.Deneb:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
template blck: untyped {.inject.} = x.denebData.blck
|
||||
body
|
||||
|
|
|
@ -36,15 +36,6 @@ proc getSyncCommitteeDutiesPlain*(
|
|||
meth: MethodPost.}
|
||||
## https://ethereum.github.io/beacon-APIs/#/Validator/getSyncCommitteeDuties
|
||||
|
||||
proc produceBlockV2Plain*(
|
||||
slot: Slot,
|
||||
randao_reveal: ValidatorSig,
|
||||
graffiti: GraffitiBytes
|
||||
): RestPlainResponse {.
|
||||
rest, endpoint: "/eth/v2/validator/blocks/{slot}",
|
||||
accept: preferSSZ, meth: MethodGet.}
|
||||
## https://ethereum.github.io/beacon-APIs/#/Validator/produceBlockV2
|
||||
|
||||
proc produceBlockV3Plain*(
|
||||
slot: Slot,
|
||||
randao_reveal: ValidatorSig,
|
||||
|
|
|
@ -291,7 +291,7 @@ template `$`*(x: WalletName): string =
|
|||
# TODO: `burnMem` in nimcrypto could use distinctBase
|
||||
# to make its usage less error-prone.
|
||||
template burnMem*(m: var (Mnemonic|string)) =
|
||||
ncrutils.burnMem(string m)
|
||||
ncrutils.burnMem(distinctBase m)
|
||||
|
||||
template burnMem*(m: var KeySeed) =
|
||||
ncrutils.burnMem(distinctBase m)
|
||||
|
@ -324,7 +324,7 @@ const
|
|||
englishWordsDigest =
|
||||
"AD90BF3BEB7B0EB7E5ACD74727DC0DA96E0A280A258354E7293FB7E211AC03DB".toDigest
|
||||
|
||||
proc checkEnglishWords(): bool =
|
||||
func checkEnglishWords(): bool =
|
||||
if len(englishWords) != wordListLen:
|
||||
false
|
||||
else:
|
||||
|
@ -341,7 +341,7 @@ func validateKeyPath*(path: string): Result[KeyPath, cstring] =
|
|||
var digitCount: int
|
||||
var number: BiggestUInt
|
||||
try:
|
||||
for elem in path.string.split("/"):
|
||||
for elem in path.split("/"):
|
||||
# TODO: doesn't "m" have to be the first character and is it the only
|
||||
# place where it is valid?
|
||||
if elem == "m":
|
||||
|
@ -382,7 +382,7 @@ func isControlRune(r: Rune): bool =
|
|||
let r = int r
|
||||
(r >= 0 and r < 0x20) or (r >= 0x7F and r < 0xA0)
|
||||
|
||||
proc init*(T: type KeystorePass, input: string): T =
|
||||
func init*(T: type KeystorePass, input: string): T =
|
||||
for rune in toNFKD(input):
|
||||
if not isControlRune(rune):
|
||||
result.str.add rune
|
||||
|
@ -395,7 +395,7 @@ func getSeed*(mnemonic: Mnemonic, password: KeystorePass): KeySeed =
|
|||
template add(m: var Mnemonic, s: cstring) =
|
||||
m.string.add s
|
||||
|
||||
proc generateMnemonic*(
|
||||
func generateMnemonic*(
|
||||
rng: var HmacDrbgContext,
|
||||
words: openArray[cstring] = englishWords,
|
||||
entropyParam: openArray[byte] = @[]): Mnemonic =
|
||||
|
@ -429,12 +429,12 @@ proc generateMnemonic*(
|
|||
result.add " "
|
||||
result.add words[entropy.getBitsBE(firstBit..lastBit)]
|
||||
|
||||
proc cmpIgnoreCase(lhs: cstring, rhs: string): int =
|
||||
func cmpIgnoreCase(lhs: cstring, rhs: string): int =
|
||||
# TODO: This is a bit silly.
|
||||
# Nim should have a `cmp` function for C strings.
|
||||
cmpIgnoreCase($lhs, rhs)
|
||||
|
||||
proc validateMnemonic*(inputWords: string,
|
||||
func validateMnemonic*(inputWords: string,
|
||||
outputMnemonic: var Mnemonic): bool =
|
||||
## Accept a case-insensitive input string and returns `true`
|
||||
## if it represents a valid mnenomic. The `outputMnemonic`
|
||||
|
@ -465,7 +465,7 @@ proc validateMnemonic*(inputWords: string,
|
|||
|
||||
return true
|
||||
|
||||
proc deriveChildKey*(parentKey: ValidatorPrivKey,
|
||||
func deriveChildKey*(parentKey: ValidatorPrivKey,
|
||||
index: Natural): ValidatorPrivKey =
|
||||
let success = derive_child_secretKey(SecretKey result,
|
||||
SecretKey parentKey,
|
||||
|
@ -475,7 +475,7 @@ proc deriveChildKey*(parentKey: ValidatorPrivKey,
|
|||
# into asserts inside the function.
|
||||
doAssert success
|
||||
|
||||
proc deriveMasterKey*(seed: KeySeed): ValidatorPrivKey =
|
||||
func deriveMasterKey*(seed: KeySeed): ValidatorPrivKey =
|
||||
let success = derive_master_secretKey(SecretKey result,
|
||||
seq[byte] seed)
|
||||
# TODO `derive_master_secretKey` is reporting pre-condition
|
||||
|
@ -483,17 +483,17 @@ proc deriveMasterKey*(seed: KeySeed): ValidatorPrivKey =
|
|||
# into asserts inside the function.
|
||||
doAssert success
|
||||
|
||||
proc deriveMasterKey*(mnemonic: Mnemonic,
|
||||
func deriveMasterKey*(mnemonic: Mnemonic,
|
||||
password: KeystorePass): ValidatorPrivKey =
|
||||
deriveMasterKey(getSeed(mnemonic, password))
|
||||
|
||||
proc deriveChildKey*(masterKey: ValidatorPrivKey,
|
||||
func deriveChildKey*(masterKey: ValidatorPrivKey,
|
||||
path: KeyPath): ValidatorPrivKey =
|
||||
result = masterKey
|
||||
for idx in pathNodes(path):
|
||||
result = deriveChildKey(result, idx)
|
||||
|
||||
proc deriveChildKey*(masterKey: ValidatorPrivKey,
|
||||
func deriveChildKey*(masterKey: ValidatorPrivKey,
|
||||
path: openArray[Natural]): ValidatorPrivKey =
|
||||
result = masterKey
|
||||
for idx in path:
|
||||
|
@ -503,12 +503,12 @@ proc deriveChildKey*(masterKey: ValidatorPrivKey,
|
|||
# if we fail we want to scrub secrets from memory
|
||||
result = deriveChildKey(result, idx)
|
||||
|
||||
proc keyFromPath*(mnemonic: Mnemonic,
|
||||
func keyFromPath*(mnemonic: Mnemonic,
|
||||
password: KeystorePass,
|
||||
path: KeyPath): ValidatorPrivKey =
|
||||
deriveChildKey(deriveMasterKey(mnemonic, password), path)
|
||||
|
||||
proc shaChecksum(key, cipher: openArray[byte]): Sha256Digest =
|
||||
func shaChecksum(key, cipher: openArray[byte]): Sha256Digest =
|
||||
var ctx: sha256
|
||||
ctx.init()
|
||||
ctx.update(key)
|
||||
|
@ -681,7 +681,7 @@ proc readValue*(r: var JsonReader[DefaultFlavor], value: var Kdf)
|
|||
readValueImpl(r, value)
|
||||
{.pop.}
|
||||
|
||||
proc readValue*(r: var JsonReader, value: var (Checksum|Cipher|Kdf)) =
|
||||
func readValue*(r: var JsonReader, value: var (Checksum|Cipher|Kdf)) =
|
||||
static: raiseAssert "Unknown flavor `JsonReader[" & $typeof(r).Flavor &
|
||||
"]` for `readValue` of `" & $typeof(value) & "`"
|
||||
|
||||
|
@ -951,7 +951,7 @@ func areValid(params: ScryptParams): bool =
|
|||
params.p == scryptParams.p and
|
||||
params.salt.bytes.len > 0
|
||||
|
||||
proc decryptCryptoField*(crypto: Crypto, decKey: openArray[byte],
|
||||
func decryptCryptoField*(crypto: Crypto, decKey: openArray[byte],
|
||||
outSecret: var seq[byte]): DecryptionStatus =
|
||||
if crypto.cipher.message.bytes.len == 0:
|
||||
return DecryptionStatus.InvalidKeystore
|
||||
|
@ -977,7 +977,7 @@ proc decryptCryptoField*(crypto: Crypto, decKey: openArray[byte],
|
|||
aesCipher.clear()
|
||||
DecryptionStatus.Success
|
||||
|
||||
proc getDecryptionKey*(crypto: Crypto, password: KeystorePass,
|
||||
func getDecryptionKey*(crypto: Crypto, password: KeystorePass,
|
||||
decKey: var seq[byte]): DecryptionStatus =
|
||||
let res =
|
||||
case crypto.kdf.function
|
||||
|
@ -996,7 +996,7 @@ proc getDecryptionKey*(crypto: Crypto, password: KeystorePass,
|
|||
decKey = res
|
||||
DecryptionStatus.Success
|
||||
|
||||
proc decryptCryptoField*(crypto: Crypto,
|
||||
func decryptCryptoField*(crypto: Crypto,
|
||||
password: KeystorePass,
|
||||
outSecret: var seq[byte]): DecryptionStatus =
|
||||
# https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
|
||||
|
@ -1027,7 +1027,7 @@ template parseRemoteKeystore*(jsonContent: string): RemoteKeystore =
|
|||
requireAllFields = false,
|
||||
allowUnknownFields = true)
|
||||
|
||||
proc getSaltKey(keystore: Keystore, password: KeystorePass): KdfSaltKey =
|
||||
func getSaltKey(keystore: Keystore, password: KeystorePass): KdfSaltKey =
|
||||
let digest =
|
||||
case keystore.crypto.kdf.function
|
||||
of kdfPbkdf2:
|
||||
|
@ -1050,8 +1050,8 @@ proc getSaltKey(keystore: Keystore, password: KeystorePass): KdfSaltKey =
|
|||
h.update(toBytesLE(uint64(params.r)))
|
||||
KdfSaltKey(digest.data)
|
||||
|
||||
proc `==`*(a, b: KdfSaltKey): bool {.borrow.}
|
||||
proc hash*(salt: KdfSaltKey): Hash {.borrow.}
|
||||
func `==`*(a, b: KdfSaltKey): bool {.borrow.}
|
||||
func hash*(salt: KdfSaltKey): Hash {.borrow.}
|
||||
|
||||
{.push warning[ProveField]:off.}
|
||||
func `==`*(a, b: Kdf): bool =
|
||||
|
@ -1089,7 +1089,7 @@ func init*(t: typedesc[KeystoreCacheRef],
|
|||
expireTime: expireTime
|
||||
)
|
||||
|
||||
proc clear*(cache: KeystoreCacheRef) =
|
||||
func clear*(cache: KeystoreCacheRef) =
|
||||
cache.table.clear()
|
||||
|
||||
proc pruneExpiredKeys*(cache: KeystoreCacheRef) =
|
||||
|
@ -1110,7 +1110,7 @@ proc init*(t: typedesc[KeystoreCacheItem], keystore: Keystore,
|
|||
cipher: keystore.crypto.cipher, decryptionKey: @key,
|
||||
timestamp: Moment.now())
|
||||
|
||||
proc getCachedKey*(cache: KeystoreCacheRef,
|
||||
func getCachedKey*(cache: KeystoreCacheRef,
|
||||
keystore: Keystore, password: KeystorePass): Opt[seq[byte]] =
|
||||
if isNil(cache): return Opt.none(seq[byte])
|
||||
let
|
||||
|
@ -1132,7 +1132,7 @@ proc setCachedKey*(cache: KeystoreCacheRef, keystore: Keystore,
|
|||
let saltKey = keystore.getSaltKey(password)
|
||||
cache.table[saltKey] = KeystoreCacheItem.init(keystore, key)
|
||||
|
||||
proc destroyCacheKey*(cache: KeystoreCacheRef,
|
||||
func destroyCacheKey*(cache: KeystoreCacheRef,
|
||||
keystore: Keystore, password: KeystorePass) =
|
||||
if isNil(cache): return
|
||||
let saltKey = keystore.getSaltKey(password)
|
||||
|
@ -1206,7 +1206,7 @@ proc readValue*(reader: var JsonReader, value: var lcrypto.PublicKey) {.
|
|||
# TODO: Can we provide better diagnostic?
|
||||
raiseUnexpectedValue(reader, "Valid hex-encoded public key expected")
|
||||
|
||||
proc decryptNetKeystore*(nkeystore: NetKeystore,
|
||||
func decryptNetKeystore*(nkeystore: NetKeystore,
|
||||
password: KeystorePass): KsResult[lcrypto.PrivateKey] =
|
||||
var secret: seq[byte]
|
||||
defer: burnMem(secret)
|
||||
|
@ -1221,7 +1221,7 @@ proc decryptNetKeystore*(nkeystore: NetKeystore,
|
|||
else:
|
||||
err $status
|
||||
|
||||
proc decryptNetKeystore*(nkeystore: JsonString,
|
||||
func decryptNetKeystore*(nkeystore: JsonString,
|
||||
password: KeystorePass): KsResult[lcrypto.PrivateKey] =
|
||||
try:
|
||||
let keystore = parseNetKeystore(string nkeystore)
|
||||
|
@ -1229,10 +1229,10 @@ proc decryptNetKeystore*(nkeystore: JsonString,
|
|||
except SerializationError as exc:
|
||||
return err(exc.formatMsg("<keystore>"))
|
||||
|
||||
proc generateKeystoreSalt*(rng: var HmacDrbgContext): seq[byte] =
|
||||
func generateKeystoreSalt*(rng: var HmacDrbgContext): seq[byte] =
|
||||
rng.generateBytes(keyLen)
|
||||
|
||||
proc createCryptoField(kdfKind: KdfKind,
|
||||
func createCryptoField(kdfKind: KdfKind,
|
||||
rng: var HmacDrbgContext,
|
||||
secret: openArray[byte],
|
||||
password = KeystorePass.init "",
|
||||
|
@ -1339,7 +1339,7 @@ proc createKeystore*(kdfKind: KdfKind,
|
|||
uuid: $uuid,
|
||||
version: 4)
|
||||
|
||||
proc createRemoteKeystore*(pubKey: ValidatorPubKey, remoteUri: HttpHostUri,
|
||||
func createRemoteKeystore*(pubKey: ValidatorPubKey, remoteUri: HttpHostUri,
|
||||
version = 1'u64, description = "",
|
||||
remoteType = RemoteSignerType.Web3Signer,
|
||||
flags: set[RemoteKeystoreFlag] = {}): RemoteKeystore =
|
||||
|
@ -1387,10 +1387,10 @@ func makeWithdrawalCredentials*(k: ValidatorPubKey): Eth2Digest =
|
|||
bytes
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/phase0/deposit-contract.md#withdrawal-credentials
|
||||
proc makeWithdrawalCredentials*(k: CookedPubKey): Eth2Digest =
|
||||
func makeWithdrawalCredentials*(k: CookedPubKey): Eth2Digest =
|
||||
makeWithdrawalCredentials(k.toPubKey())
|
||||
|
||||
proc prepareDeposit*(cfg: RuntimeConfig,
|
||||
func prepareDeposit*(cfg: RuntimeConfig,
|
||||
withdrawalPubKey: CookedPubKey,
|
||||
signingKey: ValidatorPrivKey, signingPubKey: CookedPubKey,
|
||||
amount = MAX_EFFECTIVE_BALANCE.Gwei): DepositData =
|
||||
|
|
|
@ -507,43 +507,86 @@ proc process_bls_to_execution_change*(
|
|||
|
||||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/94a0b6c581f2809aa8aca4ef7ee6fbb63f9d74e9/specs/electra/beacon-chain.md#new-process_execution_layer_exit
|
||||
func process_execution_layer_withdrawal_request(
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#new-process_execution_layer_withdrawal_request
|
||||
func process_execution_layer_withdrawal_request*(
|
||||
cfg: RuntimeConfig, state: var electra.BeaconState,
|
||||
execution_layer_withdrawal_request: ExecutionLayerWithdrawalRequest,
|
||||
exit_queue_info: ExitQueueInfo, cache: var StateCache):
|
||||
Result[ExitQueueInfo, cstring] =
|
||||
# Verify pubkey exists
|
||||
cache: var StateCache) =
|
||||
let
|
||||
pubkey_to_exit = execution_layer_withdrawal_request.validator_pubkey
|
||||
validator_index = findValidatorIndex(state, pubkey_to_exit).valueOr:
|
||||
return err("process_execution_layer_withdrawal_request: unknown index for validator pubkey")
|
||||
validator = state.validators.item(validator_index)
|
||||
amount = execution_layer_withdrawal_request.amount
|
||||
is_full_exit_request = amount == static(FULL_EXIT_REQUEST_AMOUNT.Gwei)
|
||||
|
||||
# If partial withdrawal queue is full, only full exits are processed
|
||||
if lenu64(state.pending_partial_withdrawals) ==
|
||||
PENDING_PARTIAL_WITHDRAWALS_LIMIT and not is_full_exit_request:
|
||||
return
|
||||
|
||||
let
|
||||
request_pubkey = execution_layer_withdrawal_request.validator_pubkey
|
||||
index = findValidatorIndex(state, request_pubkey).valueOr:
|
||||
return
|
||||
validator = state.validators.item(index)
|
||||
|
||||
# Verify withdrawal credentials
|
||||
let
|
||||
is_execution_address = validator.has_eth1_withdrawal_credential
|
||||
has_correct_credential = has_execution_withdrawal_credential(validator)
|
||||
is_correct_source_address =
|
||||
validator.withdrawal_credentials.data.toOpenArray(12, 31) ==
|
||||
execution_layer_withdrawal_request.source_address.data
|
||||
if not (is_execution_address and is_correct_source_address):
|
||||
return err("process_execution_layer_withdrawal_request: not both execution address and correct source address")
|
||||
|
||||
if not (has_correct_credential and is_correct_source_address):
|
||||
return
|
||||
|
||||
# Verify the validator is active
|
||||
if not is_active_validator(validator, get_current_epoch(state)):
|
||||
return err("process_execution_layer_withdrawal_request: not active validator")
|
||||
return
|
||||
|
||||
# Verify exit has not been initiated
|
||||
if validator.exit_epoch != FAR_FUTURE_EPOCH:
|
||||
return err("process_execution_layer_withdrawal_request: validator exit already initiated")
|
||||
return
|
||||
|
||||
# Verify the validator has been active long enough
|
||||
if get_current_epoch(state) < validator.activation_epoch + cfg.SHARD_COMMITTEE_PERIOD:
|
||||
return err("process_execution_layer_withdrawal_request: validator not active long enough")
|
||||
if get_current_epoch(state) <
|
||||
validator.activation_epoch + cfg.SHARD_COMMITTEE_PERIOD:
|
||||
return
|
||||
|
||||
# Initiate exit
|
||||
ok(? initiate_validator_exit(
|
||||
cfg, state, validator_index, exit_queue_info, cache))
|
||||
let pending_balance_to_withdraw =
|
||||
get_pending_balance_to_withdraw(state, index)
|
||||
|
||||
if is_full_exit_request:
|
||||
# Only exit validator if it has no pending withdrawals in the queue
|
||||
if pending_balance_to_withdraw == 0.Gwei:
|
||||
if initiate_validator_exit(cfg, state, index, default(ExitQueueInfo),
|
||||
cache).isErr():
|
||||
return
|
||||
return
|
||||
|
||||
let
|
||||
has_sufficient_effective_balance =
|
||||
validator.effective_balance >= static(MIN_ACTIVATION_BALANCE.Gwei)
|
||||
has_excess_balance = state.balances.item(index) >
|
||||
static(MIN_ACTIVATION_BALANCE.Gwei) + pending_balance_to_withdraw
|
||||
|
||||
# Only allow partial withdrawals with compounding withdrawal credentials
|
||||
if has_compounding_withdrawal_credential(validator) and
|
||||
has_sufficient_effective_balance and has_excess_balance:
|
||||
let
|
||||
to_withdraw = min(
|
||||
state.balances.item(index) - static(MIN_ACTIVATION_BALANCE.Gwei) -
|
||||
pending_balance_to_withdraw,
|
||||
amount
|
||||
)
|
||||
exit_queue_epoch =
|
||||
compute_exit_epoch_and_update_churn(cfg, state, to_withdraw, cache)
|
||||
withdrawable_epoch =
|
||||
exit_queue_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
||||
|
||||
# In theory can fail, but failing/early returning here is indistinguishable
|
||||
discard state.pending_partial_withdrawals.add(PendingPartialWithdrawal(
|
||||
index: index.uint64,
|
||||
amount: to_withdraw,
|
||||
withdrawable_epoch: withdrawable_epoch,
|
||||
))
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#consolidations
|
||||
proc process_consolidation*(
|
||||
|
@ -703,8 +746,8 @@ proc process_operations(
|
|||
# [New in Electra:EIP7002:EIP7251]
|
||||
when typeof(body).kind >= ConsensusFork.Electra:
|
||||
for op in body.execution_payload.withdrawal_requests:
|
||||
discard ? process_execution_layer_withdrawal_request(
|
||||
cfg, state, op, default(ExitQueueInfo), cache)
|
||||
process_execution_layer_withdrawal_request(
|
||||
cfg, state, op, cache)
|
||||
for op in body.execution_payload.deposit_receipts:
|
||||
debugComment "combine with previous bloom filter construction"
|
||||
let bloom_filter = constructBloomFilter(state.validators.asSeq)
|
||||
|
@ -1035,87 +1078,6 @@ func process_withdrawals*(
|
|||
|
||||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_execution_layer_withdrawal_request
|
||||
func process_execution_layer_withdrawal_request*(
|
||||
cfg: RuntimeConfig, state: var electra.BeaconState,
|
||||
execution_layer_withdrawal_request: ExecutionLayerWithdrawalRequest,
|
||||
cache: var StateCache) =
|
||||
let
|
||||
amount = execution_layer_withdrawal_request.amount
|
||||
is_full_exit_request = amount == static(FULL_EXIT_REQUEST_AMOUNT.Gwei)
|
||||
|
||||
# If partial withdrawal queue is full, only full exits are processed
|
||||
if lenu64(state.pending_partial_withdrawals) ==
|
||||
PENDING_PARTIAL_WITHDRAWALS_LIMIT and not is_full_exit_request:
|
||||
return
|
||||
|
||||
let
|
||||
request_pubkey = execution_layer_withdrawal_request.validator_pubkey
|
||||
index = findValidatorIndex(state, request_pubkey).valueOr:
|
||||
return
|
||||
validator = state.validators.item(index)
|
||||
|
||||
# Verify withdrawal credentials
|
||||
let
|
||||
has_correct_credential = has_execution_withdrawal_credential(validator)
|
||||
is_correct_source_address =
|
||||
validator.withdrawal_credentials.data.toOpenArray(12, 31) ==
|
||||
execution_layer_withdrawal_request.source_address.data
|
||||
|
||||
if not (has_correct_credential and is_correct_source_address):
|
||||
return
|
||||
|
||||
# Verify the validator is active
|
||||
if not is_active_validator(validator, get_current_epoch(state)):
|
||||
return
|
||||
|
||||
# Verify exit has not been initiated
|
||||
if validator.exit_epoch != FAR_FUTURE_EPOCH:
|
||||
return
|
||||
|
||||
# Verify the validator has been active long enough
|
||||
if get_current_epoch(state) <
|
||||
validator.activation_epoch + cfg.SHARD_COMMITTEE_PERIOD:
|
||||
return
|
||||
|
||||
let pending_balance_to_withdraw =
|
||||
get_pending_balance_to_withdraw(state, index)
|
||||
|
||||
if is_full_exit_request:
|
||||
# Only exit validator if it has no pending withdrawals in the queue
|
||||
if pending_balance_to_withdraw == 0.Gwei:
|
||||
if initiate_validator_exit(cfg, state, index, default(ExitQueueInfo),
|
||||
cache).isErr():
|
||||
return
|
||||
return
|
||||
|
||||
let
|
||||
has_sufficient_effective_balance =
|
||||
validator.effective_balance >= static(MIN_ACTIVATION_BALANCE.Gwei)
|
||||
has_excess_balance = state.balances.item(index) >
|
||||
static(MIN_ACTIVATION_BALANCE.Gwei) + pending_balance_to_withdraw
|
||||
|
||||
# Only allow partial withdrawals with compounding withdrawal credentials
|
||||
if has_compounding_withdrawal_credential(validator) and
|
||||
has_sufficient_effective_balance and has_excess_balance:
|
||||
let
|
||||
to_withdraw = min(
|
||||
state.balances.item(index) - static(MIN_ACTIVATION_BALANCE.Gwei) -
|
||||
pending_balance_to_withdraw,
|
||||
amount
|
||||
)
|
||||
exit_queue_epoch =
|
||||
compute_exit_epoch_and_update_churn(cfg, state, to_withdraw, cache)
|
||||
withdrawable_epoch =
|
||||
Epoch(exit_queue_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
|
||||
|
||||
# In theory can fail, but failing/early returning here is indistinguishable
|
||||
discard state.pending_partial_withdrawals.add(PendingPartialWithdrawal(
|
||||
index: index.uint64,
|
||||
amount: to_withdraw,
|
||||
withdrawable_epoch: withdrawable_epoch,
|
||||
))
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#kzg_commitment_to_versioned_hash
|
||||
func kzg_commitment_to_versioned_hash*(
|
||||
kzg_commitment: KzgCommitment): VersionedHash =
|
||||
|
|
|
@ -1221,7 +1221,7 @@ func process_historical_summaries_update*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_pending_balance_deposits
|
||||
func process_pending_balance_deposits*(
|
||||
cfg: RuntimeConfig, state: var electra.BeaconState,
|
||||
cache: var StateCache) =
|
||||
cache: var StateCache): Result[void, cstring] =
|
||||
let
|
||||
available_for_processing = state.deposit_balance_to_consume +
|
||||
get_activation_exit_churn_limit(cfg, state, cache)
|
||||
|
@ -1232,8 +1232,9 @@ func process_pending_balance_deposits*(
|
|||
for deposit in state.pending_balance_deposits:
|
||||
if processed_amount + deposit.amount > available_for_processing:
|
||||
break
|
||||
debugComment "do this validatorindex check properly (it truncates)"
|
||||
increase_balance(state, deposit.index.ValidatorIndex, deposit.amount)
|
||||
let deposit_validator_index = ValidatorIndex.init(deposit.index).valueOr:
|
||||
return err("process_pending_balance_deposits: deposit index out of range")
|
||||
increase_balance(state, deposit_validator_index, deposit.amount)
|
||||
processed_amount += deposit.amount
|
||||
inc next_deposit_index
|
||||
|
||||
|
@ -1247,8 +1248,12 @@ func process_pending_balance_deposits*(
|
|||
state.deposit_balance_to_consume =
|
||||
available_for_processing - processed_amount
|
||||
|
||||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_pending_consolidations
|
||||
func process_pending_consolidations*(cfg: RuntimeConfig, state: var electra.BeaconState) =
|
||||
func process_pending_consolidations*(
|
||||
cfg: RuntimeConfig, state: var electra.BeaconState):
|
||||
Result[void, cstring] =
|
||||
var next_pending_consolidation = 0
|
||||
for pending_consolidation in state.pending_consolidations:
|
||||
let source_validator =
|
||||
|
@ -1259,25 +1264,29 @@ func process_pending_consolidations*(cfg: RuntimeConfig, state: var electra.Beac
|
|||
if source_validator.withdrawable_epoch > get_current_epoch(state):
|
||||
break
|
||||
|
||||
let
|
||||
source_validator_index = ValidatorIndex.init(
|
||||
pending_consolidation.source_index).valueOr:
|
||||
return err("process_pending_consolidations: source index out of range")
|
||||
target_validator_index = ValidatorIndex.init(
|
||||
pending_consolidation.target_index).valueOr:
|
||||
return err("process_pending_consolidations: target index out of range")
|
||||
|
||||
# Churn any target excess active balance of target and raise its max
|
||||
debugComment "truncating integer conversion"
|
||||
switch_to_compounding_validator(
|
||||
state, pending_consolidation.target_index.ValidatorIndex)
|
||||
switch_to_compounding_validator(state, target_validator_index)
|
||||
|
||||
# Move active balance to target. Excess balance is withdrawable.
|
||||
debugComment "Truncating"
|
||||
let active_balance = get_active_balance(
|
||||
state, pending_consolidation.source_index.ValidatorIndex)
|
||||
decrease_balance(
|
||||
state, pending_consolidation.source_index.ValidatorIndex, active_balance)
|
||||
increase_balance(
|
||||
state, pending_consolidation.target_index.ValidatorIndex, active_balance)
|
||||
let active_balance = get_active_balance(state, source_validator_index)
|
||||
decrease_balance(state, source_validator_index, active_balance)
|
||||
increase_balance(state, target_validator_index, active_balance)
|
||||
inc next_pending_consolidation
|
||||
|
||||
state.pending_consolidations =
|
||||
HashList[PendingConsolidation, Limit PENDING_CONSOLIDATIONS_LIMIT].init(
|
||||
state.pending_consolidations.asSeq[next_pending_consolidation..^1])
|
||||
|
||||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#epoch-processing
|
||||
proc process_epoch*(
|
||||
cfg: RuntimeConfig, state: var phase0.BeaconState, flags: UpdateFlags,
|
||||
|
@ -1464,8 +1473,8 @@ proc process_epoch*(
|
|||
process_slashings(state, info.balances.current_epoch)
|
||||
|
||||
process_eth1_data_reset(state)
|
||||
process_pending_balance_deposits(cfg, state, cache) # [New in Electra:EIP7251]
|
||||
process_pending_consolidations(cfg, state) # [New in Electra:EIP7251]
|
||||
? process_pending_balance_deposits(cfg, state, cache) # [New in Electra:EIP7251]
|
||||
? process_pending_consolidations(cfg, state) # [New in Electra:EIP7251]
|
||||
process_effective_balance_updates(state) # [Modified in Electra:EIP7251]
|
||||
process_slashings_reset(state)
|
||||
process_randao_mixes_reset(state)
|
||||
|
|
|
@ -110,7 +110,7 @@ proc initQueue[A, B](man: SyncManager[A, B]) =
|
|||
# there is present check `needsBackfill().
|
||||
firstSlot
|
||||
else:
|
||||
Slot(firstSlot - 1'u64)
|
||||
firstSlot - 1'u64
|
||||
man.queue = SyncQueue.init(A, man.direction, startSlot, lastSlot,
|
||||
man.chunkSize, man.getSafeSlot,
|
||||
man.blockVerifier, 1, man.ident)
|
||||
|
|
|
@ -2022,97 +2022,6 @@ proc publishContributionAndProofs*(
|
|||
raise (ref ValidatorApiError)(
|
||||
msg: "Failed to publish sync committee contribution", data: failures)
|
||||
|
||||
proc produceBlockV2*(
|
||||
vc: ValidatorClientRef,
|
||||
slot: Slot,
|
||||
randao_reveal: ValidatorSig,
|
||||
graffiti: GraffitiBytes,
|
||||
strategy: ApiStrategyKind
|
||||
): Future[ProduceBlockResponseV2] {.async.} =
|
||||
const
|
||||
RequestName = "produceBlockV2"
|
||||
|
||||
var failures: seq[ApiNodeFailure]
|
||||
|
||||
case strategy
|
||||
of ApiStrategyKind.First, ApiStrategyKind.Best:
|
||||
let res = vc.firstSuccessParallel(
|
||||
RestPlainResponse,
|
||||
ProduceBlockResponseV2,
|
||||
SlotDuration,
|
||||
ViableNodeStatus,
|
||||
{BeaconNodeRole.BlockProposalData},
|
||||
produceBlockV2Plain(it, slot, randao_reveal, graffiti)):
|
||||
if apiResponse.isErr():
|
||||
handleCommunicationError()
|
||||
ApiResponse[ProduceBlockResponseV2].err(apiResponse.error)
|
||||
else:
|
||||
let response = apiResponse.get()
|
||||
case response.status:
|
||||
of 200:
|
||||
let
|
||||
version = response.headers.getString("eth-consensus-version")
|
||||
res = decodeBytes(ProduceBlockResponseV2, response.data,
|
||||
response.contentType, version)
|
||||
if res.isErr():
|
||||
handleUnexpectedData()
|
||||
ApiResponse[ProduceBlockResponseV2].err($res.error)
|
||||
else:
|
||||
ApiResponse[ProduceBlockResponseV2].ok(res.get())
|
||||
of 400:
|
||||
handle400()
|
||||
ApiResponse[ProduceBlockResponseV2].err(ResponseInvalidError)
|
||||
of 500:
|
||||
handle500()
|
||||
ApiResponse[ProduceBlockResponseV2].err(ResponseInternalError)
|
||||
of 503:
|
||||
handle503()
|
||||
ApiResponse[ProduceBlockResponseV2].err(ResponseNoSyncError)
|
||||
else:
|
||||
handleUnexpectedCode()
|
||||
ApiResponse[ProduceBlockResponseV2].err(ResponseUnexpectedError)
|
||||
|
||||
if res.isErr():
|
||||
raise (ref ValidatorApiError)(msg: res.error, data: failures)
|
||||
return res.get()
|
||||
|
||||
of ApiStrategyKind.Priority:
|
||||
vc.firstSuccessSequential(
|
||||
RestPlainResponse,
|
||||
SlotDuration,
|
||||
ViableNodeStatus,
|
||||
{BeaconNodeRole.BlockProposalData},
|
||||
produceBlockV2Plain(it, slot, randao_reveal, graffiti)):
|
||||
if apiResponse.isErr():
|
||||
handleCommunicationError()
|
||||
false
|
||||
else:
|
||||
let response = apiResponse.get()
|
||||
case response.status:
|
||||
of 200:
|
||||
let
|
||||
version = response.headers.getString("eth-consensus-version")
|
||||
res = decodeBytes(ProduceBlockResponseV2, response.data,
|
||||
response.contentType, version)
|
||||
if res.isOk(): return res.get()
|
||||
handleUnexpectedData()
|
||||
false
|
||||
of 400:
|
||||
handle400()
|
||||
false
|
||||
of 500:
|
||||
handle500()
|
||||
false
|
||||
of 503:
|
||||
handle503()
|
||||
false
|
||||
else:
|
||||
handleUnexpectedCode()
|
||||
false
|
||||
|
||||
raise (ref ValidatorApiError)(
|
||||
msg: "Failed to produce block", data: failures)
|
||||
|
||||
proc produceBlockV3*(
|
||||
vc: ValidatorClientRef,
|
||||
slot: Slot,
|
||||
|
@ -2161,24 +2070,15 @@ proc produceBlockV3*(
|
|||
ApiResponse[ProduceBlockResponseV3].ok(res.get())
|
||||
of 400:
|
||||
handle400()
|
||||
node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3)
|
||||
ApiResponse[ProduceBlockResponseV3].err(ResponseInvalidError)
|
||||
of 404:
|
||||
# TODO (cheatfate): Remove this handler when produceBlockV2 support
|
||||
# will be dropped.
|
||||
handle400()
|
||||
node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3)
|
||||
ApiResponse[ProduceBlockResponseV3].err(ResponseInvalidError)
|
||||
of 500:
|
||||
handle500()
|
||||
node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3)
|
||||
ApiResponse[ProduceBlockResponseV3].err(ResponseInternalError)
|
||||
of 503:
|
||||
handle503()
|
||||
ApiResponse[ProduceBlockResponseV3].err(ResponseNoSyncError)
|
||||
else:
|
||||
handleUnexpectedCode()
|
||||
node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3)
|
||||
ApiResponse[ProduceBlockResponseV3].err(ResponseUnexpectedError)
|
||||
|
||||
if res.isErr():
|
||||
|
@ -2216,24 +2116,15 @@ proc produceBlockV3*(
|
|||
false
|
||||
of 400:
|
||||
handle400()
|
||||
node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3)
|
||||
false
|
||||
of 404:
|
||||
# TODO (cheatfate): Remove this handler when produceBlockV2 support
|
||||
# will be dropped.
|
||||
handle400()
|
||||
node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3)
|
||||
false
|
||||
of 500:
|
||||
handle500()
|
||||
node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3)
|
||||
false
|
||||
of 503:
|
||||
handle503()
|
||||
false
|
||||
else:
|
||||
handleUnexpectedCode()
|
||||
node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3)
|
||||
false
|
||||
|
||||
raise (ref ValidatorApiError)(
|
||||
|
|
|
@ -49,114 +49,6 @@ func shortLog(v: ForkedMaybeBlindedBeaconBlock): auto =
|
|||
proc proposeBlock(vc: ValidatorClientRef, slot: Slot,
|
||||
proposerKey: ValidatorPubKey) {.async.}
|
||||
|
||||
proc produceBlock(
|
||||
vc: ValidatorClientRef,
|
||||
currentSlot, slot: Slot,
|
||||
randao_reveal: ValidatorSig,
|
||||
graffiti: GraffitiBytes,
|
||||
validator: AttachedValidator
|
||||
): Future[Opt[PreparedBeaconBlock]] {.async.} =
|
||||
logScope:
|
||||
slot = slot
|
||||
wall_slot = currentSlot
|
||||
validator = validatorLog(validator)
|
||||
let
|
||||
produceBlockResponse =
|
||||
try:
|
||||
await vc.produceBlockV2(slot, randao_reveal, graffiti,
|
||||
ApiStrategyKind.Best)
|
||||
except ValidatorApiError as exc:
|
||||
warn "Unable to retrieve block data", reason = exc.getFailureReason()
|
||||
return Opt.none(PreparedBeaconBlock)
|
||||
except CancelledError as exc:
|
||||
debug "Block data production has been interrupted"
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while getting block data",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return Opt.none(PreparedBeaconBlock)
|
||||
case produceBlockResponse.kind
|
||||
of ConsensusFork.Phase0:
|
||||
let blck = produceBlockResponse.phase0Data
|
||||
return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck),
|
||||
data: ForkedBeaconBlock.init(blck),
|
||||
kzgProofsOpt: Opt.none(deneb.KzgProofs),
|
||||
blobsOpt: Opt.none(deneb.Blobs)))
|
||||
of ConsensusFork.Altair:
|
||||
let blck = produceBlockResponse.altairData
|
||||
return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck),
|
||||
data: ForkedBeaconBlock.init(blck),
|
||||
kzgProofsOpt: Opt.none(deneb.KzgProofs),
|
||||
blobsOpt: Opt.none(deneb.Blobs)))
|
||||
of ConsensusFork.Bellatrix:
|
||||
let blck = produceBlockResponse.bellatrixData
|
||||
return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck),
|
||||
data: ForkedBeaconBlock.init(blck),
|
||||
kzgProofsOpt: Opt.none(deneb.KzgProofs),
|
||||
blobsOpt: Opt.none(deneb.Blobs)))
|
||||
of ConsensusFork.Capella:
|
||||
let blck = produceBlockResponse.capellaData
|
||||
return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck),
|
||||
data: ForkedBeaconBlock.init(blck),
|
||||
kzgProofsOpt: Opt.none(deneb.KzgProofs),
|
||||
blobsOpt: Opt.none(deneb.Blobs)))
|
||||
of ConsensusFork.Deneb:
|
||||
let
|
||||
blck = produceBlockResponse.denebData.`block`
|
||||
kzgProofs = produceBlockResponse.denebData.kzg_proofs
|
||||
blobs = produceBlockResponse.denebData.blobs
|
||||
return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck),
|
||||
data: ForkedBeaconBlock.init(blck),
|
||||
kzgProofsOpt: Opt.some(kzgProofs),
|
||||
blobsOpt: Opt.some(blobs)))
|
||||
of ConsensusFork.Electra:
|
||||
let
|
||||
blck = produceBlockResponse.electraData.`block`
|
||||
kzgProofs = produceBlockResponse.electraData.kzg_proofs
|
||||
blobs = produceBlockResponse.electraData.blobs
|
||||
return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck),
|
||||
data: ForkedBeaconBlock.init(blck),
|
||||
kzgProofsOpt: Opt.some(kzgProofs),
|
||||
blobsOpt: Opt.some(blobs)))
|
||||
|
||||
proc produceBlindedBlock(
|
||||
vc: ValidatorClientRef,
|
||||
currentSlot, slot: Slot,
|
||||
randao_reveal: ValidatorSig,
|
||||
graffiti: GraffitiBytes,
|
||||
validator: AttachedValidator
|
||||
): Future[Opt[PreparedBlindedBeaconBlock]] {.async.} =
|
||||
logScope:
|
||||
slot = slot
|
||||
wall_slot = currentSlot
|
||||
validator = validatorLog(validator)
|
||||
let
|
||||
beaconBlock =
|
||||
try:
|
||||
await vc.produceBlindedBlock(slot, randao_reveal, graffiti,
|
||||
ApiStrategyKind.Best)
|
||||
except ValidatorApiError as exc:
|
||||
warn "Unable to retrieve blinded block data", error_msg = exc.msg,
|
||||
reason = exc.getFailureReason()
|
||||
return Opt.none(PreparedBlindedBeaconBlock)
|
||||
except CancelledError as exc:
|
||||
debug "Blinded block data production has been interrupted"
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while getting blinded block data",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return Opt.none(PreparedBlindedBeaconBlock)
|
||||
blockRoot = withBlck(beaconBlock): hash_tree_root(forkyBlck)
|
||||
|
||||
return Opt.some(
|
||||
PreparedBlindedBeaconBlock(blockRoot: blockRoot, data: beaconBlock))
|
||||
|
||||
proc lazyWait[T](fut: Future[T]) {.async.} =
|
||||
try:
|
||||
discard await fut
|
||||
except CatchableError:
|
||||
discard
|
||||
|
||||
proc prepareRandao(vc: ValidatorClientRef, slot: Slot,
|
||||
proposerKey: ValidatorPubKey) {.async.} =
|
||||
if slot == GENESIS_SLOT:
|
||||
|
@ -209,21 +101,9 @@ proc spawnProposalTask(vc: ValidatorClientRef,
|
|||
duty: duty
|
||||
)
|
||||
|
||||
proc isProduceBlockV3Supported(vc: ValidatorClientRef): bool =
|
||||
let
|
||||
# Both `statuses` and `roles` should be set to values which are used in
|
||||
# api.produceBlockV3() call.
|
||||
statuses = ViableNodeStatus
|
||||
roles = {BeaconNodeRole.BlockProposalData}
|
||||
|
||||
for node in vc.filterNodes(statuses, roles):
|
||||
if RestBeaconNodeFeature.NoProduceBlockV3 notin node.features:
|
||||
return true
|
||||
false
|
||||
|
||||
proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
||||
fork: Fork, randaoReveal: ValidatorSig,
|
||||
validator: AttachedValidator): Future[bool] {.async.} =
|
||||
validator: AttachedValidator) {.async.} =
|
||||
let
|
||||
genesisRoot = vc.beaconGenesis.genesis_validators_root
|
||||
graffiti =
|
||||
|
@ -247,14 +127,14 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
ApiStrategyKind.Best)
|
||||
except ValidatorApiError as exc:
|
||||
warn "Unable to retrieve block data", reason = exc.getFailureReason()
|
||||
return false
|
||||
return
|
||||
except CancelledError as exc:
|
||||
debug "Block data production has been interrupted"
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while getting block data",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return false
|
||||
return
|
||||
|
||||
withForkyMaybeBlindedBlck(maybeBlock):
|
||||
when isBlinded:
|
||||
|
@ -282,7 +162,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
|
||||
if notSlashable.isErr():
|
||||
warn "Slashing protection activated for blinded block proposal"
|
||||
return false
|
||||
return
|
||||
|
||||
let signature =
|
||||
try:
|
||||
|
@ -292,7 +172,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
if res.isErr():
|
||||
warn "Unable to sign blinded block proposal using remote signer",
|
||||
reason = res.error()
|
||||
return false
|
||||
return
|
||||
res.get()
|
||||
except CancelledError as exc:
|
||||
debug "Blinded block signature process has been interrupted"
|
||||
|
@ -300,7 +180,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while signing blinded block",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return false
|
||||
return
|
||||
|
||||
let
|
||||
signedBlock =
|
||||
|
@ -313,7 +193,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
except ValidatorApiError as exc:
|
||||
warn "Unable to publish blinded block",
|
||||
reason = exc.getFailureReason()
|
||||
return false
|
||||
return
|
||||
except CancelledError as exc:
|
||||
debug "Blinded block publication has been interrupted"
|
||||
raise exc
|
||||
|
@ -321,17 +201,15 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
error "An unexpected error occurred while publishing blinded " &
|
||||
"block",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return false
|
||||
return
|
||||
|
||||
if res:
|
||||
let delay = vc.getDelay(slot.block_deadline())
|
||||
beacon_blocks_sent.inc()
|
||||
beacon_blocks_sent_delay.observe(delay.toFloatSeconds())
|
||||
notice "Blinded block published", delay = delay
|
||||
true
|
||||
else:
|
||||
warn "Blinded block was not accepted by beacon node"
|
||||
false
|
||||
else:
|
||||
let
|
||||
blockRoot = hash_tree_root(
|
||||
|
@ -367,7 +245,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
|
||||
if notSlashable.isErr():
|
||||
warn "Slashing protection activated for block proposal"
|
||||
return false
|
||||
return
|
||||
|
||||
let
|
||||
signature =
|
||||
|
@ -377,7 +255,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
if res.isErr():
|
||||
warn "Unable to sign block proposal using remote signer",
|
||||
reason = res.error()
|
||||
return false
|
||||
return
|
||||
res.get()
|
||||
except CancelledError as exc:
|
||||
debug "Block signature process has been interrupted"
|
||||
|
@ -385,240 +263,12 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while signing block",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return false
|
||||
return
|
||||
|
||||
signedBlockContents =
|
||||
RestPublishedSignedBlockContents.init(
|
||||
forkyMaybeBlindedBlck, blockRoot, signature)
|
||||
|
||||
res =
|
||||
try:
|
||||
debug "Sending block"
|
||||
await vc.publishBlock(signedBlockContents, ApiStrategyKind.First)
|
||||
except ValidatorApiError as exc:
|
||||
warn "Unable to publish block", reason = exc.getFailureReason()
|
||||
return false
|
||||
except CancelledError as exc:
|
||||
debug "Block publication has been interrupted"
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while publishing block",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return false
|
||||
|
||||
if res:
|
||||
let delay = vc.getDelay(slot.block_deadline())
|
||||
beacon_blocks_sent.inc()
|
||||
beacon_blocks_sent_delay.observe(delay.toFloatSeconds())
|
||||
notice "Block published", delay = delay
|
||||
true
|
||||
else:
|
||||
warn "Block was not accepted by beacon node"
|
||||
false
|
||||
|
||||
proc publishBlockV2(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
||||
fork: Fork, randaoReveal: ValidatorSig,
|
||||
validator: AttachedValidator) {.async.} =
|
||||
let
|
||||
genesisRoot = vc.beaconGenesis.genesis_validators_root
|
||||
graffiti = vc.getGraffitiBytes(validator)
|
||||
vindex = validator.index.get()
|
||||
|
||||
logScope:
|
||||
validator = validatorLog(validator)
|
||||
validator_index = vindex
|
||||
slot = slot
|
||||
wall_slot = currentSlot
|
||||
|
||||
var beaconBlocks =
|
||||
block:
|
||||
let blindedBlockFut =
|
||||
if vc.config.payloadBuilderEnable:
|
||||
vc.produceBlindedBlock(currentSlot, slot, randaoReveal, graffiti,
|
||||
validator)
|
||||
else:
|
||||
nil
|
||||
let normalBlockFut = vc.produceBlock(currentSlot, slot, randaoReveal,
|
||||
graffiti, validator)
|
||||
let blindedBlock =
|
||||
if isNil(blindedBlockFut):
|
||||
Opt.none(PreparedBlindedBeaconBlock)
|
||||
else:
|
||||
try:
|
||||
await blindedBlockFut
|
||||
except CancelledError as exc:
|
||||
if not(normalBlockFut.finished()):
|
||||
await normalBlockFut.cancelAndWait()
|
||||
raise exc
|
||||
except CatchableError:
|
||||
# This should not happen, because all the exceptions are handled.
|
||||
Opt.none(PreparedBlindedBeaconBlock)
|
||||
|
||||
let normalBlock =
|
||||
if blindedBlock.isNone():
|
||||
try:
|
||||
await normalBlockFut
|
||||
except CancelledError as exc:
|
||||
raise exc
|
||||
except CatchableError:
|
||||
# This should not happen, because all the exceptions are handled.
|
||||
Opt.none(PreparedBeaconBlock)
|
||||
else:
|
||||
if not(normalBlockFut.finished()):
|
||||
asyncSpawn lazyWait(normalBlockFut)
|
||||
Opt.none(PreparedBeaconBlock)
|
||||
|
||||
if blindedBlock.isNone() and normalBlock.isNone():
|
||||
return
|
||||
|
||||
(blindedBlock: blindedBlock, normalBlock: normalBlock)
|
||||
|
||||
if beaconBlocks.blindedBlock.isSome():
|
||||
let
|
||||
preparedBlock = beaconBlocks.blindedBlock.get()
|
||||
signingRoot = compute_block_signing_root(fork, genesisRoot, slot,
|
||||
preparedBlock.blockRoot)
|
||||
notSlashable = vc.attachedValidators[]
|
||||
.slashingProtection
|
||||
.registerBlock(vindex, validator.pubkey, slot, signingRoot)
|
||||
|
||||
logScope:
|
||||
blck = shortLog(preparedBlock.data)
|
||||
block_root = shortLog(preparedBlock.blockRoot)
|
||||
signing_root = shortLog(signingRoot)
|
||||
|
||||
if notSlashable.isOk():
|
||||
let
|
||||
signature =
|
||||
try:
|
||||
let res = await validator.getBlockSignature(fork, genesisRoot,
|
||||
slot,
|
||||
preparedBlock.blockRoot,
|
||||
preparedBlock.data)
|
||||
if res.isErr():
|
||||
warn "Unable to sign blinded block proposal using remote signer",
|
||||
reason = res.error()
|
||||
return
|
||||
res.get()
|
||||
except CancelledError as exc:
|
||||
debug "Blinded block signature process has been interrupted"
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while signing blinded block",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return
|
||||
|
||||
logScope:
|
||||
signature = shortLog(signature)
|
||||
|
||||
let
|
||||
signedBlock = ForkedSignedBlindedBeaconBlock.init(preparedBlock.data,
|
||||
preparedBlock.blockRoot, signature)
|
||||
res =
|
||||
try:
|
||||
debug "Sending blinded block"
|
||||
await vc.publishBlindedBlock(signedBlock, ApiStrategyKind.First)
|
||||
except ValidatorApiError as exc:
|
||||
warn "Unable to publish blinded block",
|
||||
reason = exc.getFailureReason()
|
||||
return
|
||||
except CancelledError as exc:
|
||||
debug "Blinded block publication has been interrupted"
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while publishing blinded block",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return
|
||||
|
||||
if res:
|
||||
let delay = vc.getDelay(slot.block_deadline())
|
||||
beacon_blocks_sent.inc()
|
||||
beacon_blocks_sent_delay.observe(delay.toFloatSeconds())
|
||||
notice "Blinded block published", delay = delay
|
||||
else:
|
||||
warn "Blinded block was not accepted by beacon node"
|
||||
else:
|
||||
warn "Slashing protection activated for blinded block proposal"
|
||||
else:
|
||||
let
|
||||
preparedBlock = beaconBlocks.normalBlock.get()
|
||||
signingRoot = compute_block_signing_root(fork, genesisRoot, slot,
|
||||
preparedBlock.blockRoot)
|
||||
notSlashable = vc.attachedValidators[]
|
||||
.slashingProtection
|
||||
.registerBlock(vindex, validator.pubkey, slot, signingRoot)
|
||||
|
||||
logScope:
|
||||
blck = shortLog(preparedBlock.data)
|
||||
block_root = shortLog(preparedBlock.blockRoot)
|
||||
signing_root = shortLog(signingRoot)
|
||||
|
||||
if notSlashable.isOk():
|
||||
let
|
||||
signature =
|
||||
try:
|
||||
let res = await validator.getBlockSignature(fork,
|
||||
genesisRoot, slot,
|
||||
preparedBlock.blockRoot,
|
||||
preparedBlock.data)
|
||||
if res.isErr():
|
||||
warn "Unable to sign block proposal using remote signer",
|
||||
reason = res.error()
|
||||
return
|
||||
res.get()
|
||||
except CancelledError as exc:
|
||||
debug "Block signature process has been interrupted"
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
error "An unexpected error occurred while signing block",
|
||||
error_name = exc.name, error_msg = exc.msg
|
||||
return
|
||||
|
||||
signedBlockContents =
|
||||
case preparedBlock.data.kind
|
||||
of ConsensusFork.Phase0:
|
||||
RestPublishedSignedBlockContents(kind: ConsensusFork.Phase0,
|
||||
phase0Data: phase0.SignedBeaconBlock(
|
||||
message: preparedBlock.data.phase0Data,
|
||||
root: preparedBlock.blockRoot,
|
||||
signature: signature))
|
||||
of ConsensusFork.Altair:
|
||||
RestPublishedSignedBlockContents(kind: ConsensusFork.Altair,
|
||||
altairData: altair.SignedBeaconBlock(
|
||||
message: preparedBlock.data.altairData,
|
||||
root: preparedBlock.blockRoot,
|
||||
signature: signature))
|
||||
of ConsensusFork.Bellatrix:
|
||||
RestPublishedSignedBlockContents(kind: ConsensusFork.Bellatrix,
|
||||
bellatrixData: bellatrix.SignedBeaconBlock(
|
||||
message: preparedBlock.data.bellatrixData,
|
||||
root: preparedBlock.blockRoot,
|
||||
signature: signature))
|
||||
of ConsensusFork.Capella:
|
||||
RestPublishedSignedBlockContents(kind: ConsensusFork.Capella,
|
||||
capellaData: capella.SignedBeaconBlock(
|
||||
message: preparedBlock.data.capellaData,
|
||||
root: preparedBlock.blockRoot,
|
||||
signature: signature))
|
||||
of ConsensusFork.Deneb:
|
||||
RestPublishedSignedBlockContents(kind: ConsensusFork.Deneb,
|
||||
denebData: DenebSignedBlockContents(
|
||||
signed_block: deneb.SignedBeaconBlock(
|
||||
message: preparedBlock.data.denebData,
|
||||
root: preparedBlock.blockRoot,
|
||||
signature: signature),
|
||||
kzg_proofs: preparedBlock.kzgProofsOpt.get,
|
||||
blobs: preparedBlock.blobsOpt.get))
|
||||
of ConsensusFork.Electra:
|
||||
RestPublishedSignedBlockContents(kind: ConsensusFork.Electra,
|
||||
electraData: ElectraSignedBlockContents(
|
||||
signed_block: electra.SignedBeaconBlock(
|
||||
message: preparedBlock.data.electraData,
|
||||
root: preparedBlock.blockRoot,
|
||||
signature: signature),
|
||||
kzg_proofs: preparedBlock.kzgProofsOpt.get,
|
||||
blobs: preparedBlock.blobsOpt.get))
|
||||
|
||||
res =
|
||||
try:
|
||||
debug "Sending block"
|
||||
|
@ -641,8 +291,6 @@ proc publishBlockV2(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
notice "Block published", delay = delay
|
||||
else:
|
||||
warn "Block was not accepted by beacon node"
|
||||
else:
|
||||
warn "Slashing protection activated for block proposal"
|
||||
|
||||
proc publishBlock(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
||||
validator: AttachedValidator) {.async.} =
|
||||
|
@ -677,18 +325,7 @@ proc publishBlock(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
error_name = exc.name, error_msg = exc.msg
|
||||
return
|
||||
|
||||
# TODO (cheatfate): This branch should be removed as soon as `produceBlockV2`
|
||||
# call will be fully deprecated.
|
||||
if vc.isProduceBlockV3Supported():
|
||||
# We call `V3` first, if call fails and `isProduceBlockV3Supported()`
|
||||
# did not find any nodes which support `V3` we try to call `V2`.
|
||||
let res =
|
||||
await vc.publishBlockV3(currentSlot, slot, fork, randaoReveal, validator)
|
||||
if not(res) and not(vc.isProduceBlockV3Supported()):
|
||||
notice "Block production using V3 failed, trying V2"
|
||||
await vc.publishBlockV2(currentSlot, slot, fork, randaoReveal, validator)
|
||||
else:
|
||||
await vc.publishBlockV2(currentSlot, slot, fork, randaoReveal, validator)
|
||||
await vc.publishBlockV3(currentSlot, slot, fork, randaoReveal, validator)
|
||||
|
||||
proc proposeBlock(vc: ValidatorClientRef, slot: Slot,
|
||||
proposerKey: ValidatorPubKey) {.async.} =
|
||||
|
|
|
@ -117,7 +117,6 @@ type
|
|||
|
||||
RestBeaconNodeFeature* {.pure.} = enum
|
||||
NoNimbusExtensions, ## BN does not support Nimbus Extensions
|
||||
NoProduceBlockV3 ## BN does not support produceBlockV3 call
|
||||
|
||||
TimeOffset* = object
|
||||
value: int64
|
||||
|
@ -1512,7 +1511,7 @@ proc `+`*(slot: Slot, epochs: Epoch): Slot =
|
|||
|
||||
func finish_slot*(epoch: Epoch): Slot =
|
||||
## Return the last slot of ``epoch``.
|
||||
Slot((epoch + 1).start_slot() - 1)
|
||||
(epoch + 1).start_slot() - 1
|
||||
|
||||
proc getGraffitiBytes*(vc: ValidatorClientRef,
|
||||
validator: AttachedValidator): GraffitiBytes =
|
||||
|
|
34
ncli/era.nim
34
ncli/era.nim
|
@ -92,41 +92,43 @@ proc appendRecord(f: IoHandle, index: Index): Result[int64, string] =
|
|||
f.appendIndex(index.startSlot, index.offsets)
|
||||
|
||||
proc readIndex*(f: IoHandle): Result[Index, string] =
|
||||
var
|
||||
buf: seq[byte]
|
||||
pos: int
|
||||
|
||||
let
|
||||
startPos = ? f.getFilePos().mapErr(toString)
|
||||
fileSize = ? f.getFileSize().mapErr(toString)
|
||||
header = ? f.readHeader()
|
||||
header = ? f.readRecord(buf)
|
||||
|
||||
if header.typ != E2Index: return err("not an index")
|
||||
if header.len < 16: return err("index entry too small")
|
||||
if header.len mod 8 != 0: return err("index length invalid")
|
||||
if buf.len < 16: return err("index entry too small")
|
||||
if buf.len mod 8 != 0: return err("index length invalid")
|
||||
|
||||
var buf: array[8, byte]
|
||||
? f.readFileExact(buf)
|
||||
let
|
||||
slot = uint64.fromBytesLE(buf)
|
||||
count = header.len div 8 - 2
|
||||
slot = uint64.fromBytesLE(buf.toOpenArray(pos, pos + 7))
|
||||
count = buf.len div 8 - 2
|
||||
pos += 8
|
||||
|
||||
# technically not an error, but we'll throw this sanity check in here..
|
||||
if slot > int32.high().uint64: return err("fishy slot")
|
||||
|
||||
var offsets = newSeqUninitialized[int64](count)
|
||||
for i in 0..<count:
|
||||
? f.readFileExact(buf)
|
||||
|
||||
let
|
||||
offset = uint64.fromBytesLE(buf)
|
||||
offset = uint64.fromBytesLE(buf.toOpenArray(pos, pos + 7))
|
||||
absolute =
|
||||
if offset == 0: 0'i64
|
||||
else:
|
||||
# Wrapping math is actually convenient here
|
||||
cast[int64](cast[uint64](startPos) + offset)
|
||||
|
||||
if absolute < 0 or absolute > fileSize: return err("Invalid offset")
|
||||
if absolute < 0 or absolute > fileSize: return err("invalid offset")
|
||||
offsets[i] = absolute
|
||||
pos += 8
|
||||
|
||||
? f.readFileExact(buf)
|
||||
if uint64(count) != uint64.fromBytesLE(buf): return err("invalid count")
|
||||
|
||||
# technically not an error, but we'll throw this sanity check in here..
|
||||
if slot > int32.high().uint64: return err("fishy slot")
|
||||
if uint64(count) != uint64.fromBytesLE(buf.toOpenArray(pos, pos + 7)):
|
||||
return err("invalid count")
|
||||
|
||||
ok(Index(startSlot: Slot(slot), offsets: offsets))
|
||||
|
||||
|
|
|
@ -239,16 +239,19 @@ proc doSSZ(conf: NcliConf) =
|
|||
of "bellatrix_signed_block": printit(bellatrix.SignedBeaconBlock)
|
||||
of "capella_signed_block": printit(capella.SignedBeaconBlock)
|
||||
of "deneb_signed_block": printit(deneb.SignedBeaconBlock)
|
||||
of "electra_signed_block": printit(electra.SignedBeaconBlock)
|
||||
of "phase0_block": printit(phase0.BeaconBlock)
|
||||
of "altair_block": printit(altair.BeaconBlock)
|
||||
of "bellatrix_block": printit(bellatrix.BeaconBlock)
|
||||
of "capella_block": printit(capella.BeaconBlock)
|
||||
of "deneb_block": printit(deneb.BeaconBlock)
|
||||
of "electra_block": printit(electra.BeaconBlock)
|
||||
of "phase0_block_body": printit(phase0.BeaconBlockBody)
|
||||
of "altair_block_body": printit(altair.BeaconBlockBody)
|
||||
of "bellatrix_block_body": printit(bellatrix.BeaconBlockBody)
|
||||
of "capella_block_body": printit(capella.BeaconBlockBody)
|
||||
of "deneb_block_body": printit(deneb.BeaconBlockBody)
|
||||
of "electra_block_body": printit(electra.BeaconBlockBody)
|
||||
of "block_header": printit(BeaconBlockHeader)
|
||||
of "deposit": printit(Deposit)
|
||||
of "deposit_data": printit(DepositData)
|
||||
|
@ -258,6 +261,7 @@ proc doSSZ(conf: NcliConf) =
|
|||
of "bellatrix_state": printit(bellatrix.BeaconState)
|
||||
of "capella_state": printit(capella.BeaconState)
|
||||
of "deneb_state": printit(deneb.BeaconState)
|
||||
of "electra_state": printit(electra.BeaconState)
|
||||
of "proposer_slashing": printit(ProposerSlashing)
|
||||
of "voluntary_exit": printit(VoluntaryExit)
|
||||
|
||||
|
|
|
@ -126,14 +126,13 @@ static:
|
|||
"15227487_86601706.echop"]: # Wrong extension
|
||||
doAssert not filename.matchFilenameAggregatedFiles
|
||||
|
||||
proc getUnaggregatedFilesEpochRange*(
|
||||
dir: string
|
||||
): tuple[firstEpoch, lastEpoch: Epoch] {.raises: [OSError, ValueError].} =
|
||||
proc getUnaggregatedFilesEpochRange*(dir: string):
|
||||
tuple[firstEpoch, lastEpoch: Epoch] {.raises: [OSError, ValueError].} =
|
||||
var smallestEpochFileName =
|
||||
'9'.repeat(epochInfoFileNameDigitsCount) & epochFileNameExtension
|
||||
var largestEpochFileName =
|
||||
'0'.repeat(epochInfoFileNameDigitsCount) & epochFileNameExtension
|
||||
for (_, fn) in walkDir(dir.string, relative = true):
|
||||
for (_, fn) in walkDir(dir, relative = true):
|
||||
if fn.matchFilenameUnaggregatedFiles:
|
||||
if fn < smallestEpochFileName:
|
||||
smallestEpochFileName = fn
|
||||
|
@ -151,7 +150,7 @@ proc getUnaggregatedFilesLastEpoch*(
|
|||
proc getAggregatedFilesLastEpoch*(
|
||||
dir: string): Epoch {.raises: [OSError, ValueError].}=
|
||||
var largestEpochInFileName = 0'u
|
||||
for (_, fn) in walkDir(dir.string, relative = true):
|
||||
for (_, fn) in walkDir(dir, relative = true):
|
||||
if fn.matchFilenameAggregatedFiles:
|
||||
let fileLastEpoch = parseUInt(
|
||||
fn[epochInfoFileNameDigitsCount + 1 .. 2 * epochInfoFileNameDigitsCount])
|
||||
|
|
|
@ -553,8 +553,8 @@ proc sendDeposits(deposits: seq[LaunchPadDeposit],
|
|||
|
||||
var web3 = await initWeb3(web3Url, privateKey)
|
||||
let gasPrice = int(await web3.provider.eth_gasPrice()) * 2
|
||||
let depositContract = web3.contractSender(DepositContract,
|
||||
Eth1Address depositContractAddress)
|
||||
let depositContract = web3.contractSender(
|
||||
DepositContract, depositContractAddress)
|
||||
for i in 4200 ..< deposits.len:
|
||||
let dp = deposits[i] as DepositData
|
||||
|
||||
|
@ -656,7 +656,7 @@ when isMainModule:
|
|||
error "Failed to read an Eth1 private key from standard input"
|
||||
|
||||
if privateKey.len > 0:
|
||||
conf.privateKey = privateKey.string
|
||||
conf.privateKey = privateKey
|
||||
|
||||
case conf.cmd
|
||||
of StartUpCommand.createTestnet:
|
||||
|
|
|
@ -11,5 +11,4 @@
|
|||
|
||||
--styleCheck:usages
|
||||
--styleCheck:error
|
||||
--hint[ConvFromXtoItselfNotNeeded]:off
|
||||
--hint[Processing]:off
|
||||
|
|
|
@ -326,8 +326,7 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
|
|||
contribution: contribution,
|
||||
selection_proof: aggregator.selectionProof)
|
||||
|
||||
validatorPrivKey =
|
||||
MockPrivKeys[aggregator.validatorIdx.ValidatorIndex]
|
||||
validatorPrivKey = MockPrivKeys[aggregator.validatorIdx]
|
||||
|
||||
signedContributionAndProof = SignedContributionAndProof(
|
||||
message: contributionAndProof,
|
||||
|
|
|
@ -11,5 +11,4 @@
|
|||
|
||||
--styleCheck:usages
|
||||
--styleCheck:error
|
||||
--hint[ConvFromXtoItselfNotNeeded]:off
|
||||
--hint[Processing]:off
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import
|
||||
# Beacon chain internals
|
||||
chronicles,
|
||||
../../../beacon_chain/spec/[beaconstate, presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/[presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/datatypes/altair,
|
||||
# Test utilities
|
||||
../../testutil,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
import
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/[beaconstate, presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/[presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/datatypes/[altair, bellatrix],
|
||||
# Test utilities
|
||||
../../testutil,
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
# * 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: [].}
|
||||
{.used.}
|
||||
|
||||
import
|
||||
# Status internals
|
||||
chronicles,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/[beaconstate, presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/[presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/datatypes/[altair, capella],
|
||||
# Test utilities
|
||||
../../testutil,
|
||||
|
|
|
@ -12,7 +12,7 @@ import
|
|||
# Status internals
|
||||
chronicles,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/[beaconstate, presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/[presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/datatypes/[altair, deneb],
|
||||
# Test utilities
|
||||
../../testutil,
|
||||
|
|
|
@ -12,7 +12,7 @@ import
|
|||
# Status internals
|
||||
chronicles,
|
||||
# Beacon chain internals
|
||||
../../../beacon_chain/spec/[beaconstate, presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/[presets, state_transition_epoch],
|
||||
../../../beacon_chain/spec/datatypes/[altair, electra],
|
||||
# Test utilities
|
||||
../../testutil,
|
||||
|
@ -146,13 +146,11 @@ runSuite(ParticipationFlagDir, "Participation flag updates"):
|
|||
# ---------------------------------------------------------------
|
||||
runSuite(PendingBalanceDepositsDir, "Pending balance deposits"):
|
||||
process_pending_balance_deposits(cfg, state, cache)
|
||||
Result[void, cstring].ok()
|
||||
|
||||
# Pending consolidations
|
||||
# ---------------------------------------------------------------
|
||||
runSuite(PendingConsolidationsDir, "Pending consolidations"):
|
||||
process_pending_consolidations(cfg, state)
|
||||
Result[void, cstring].ok()
|
||||
|
||||
# Sync committee updates
|
||||
# ---------------------------------------------------------------
|
||||
|
|
|
@ -80,6 +80,132 @@ type
|
|||
D: BitList[6]
|
||||
E: BitArray[8]
|
||||
|
||||
# https://github.com/wemeetagain/consensus-specs/blob/eip-7495/tests/generators/ssz_generic/ssz_stablecontainer.py
|
||||
SingleFieldTestStableStruct {.sszStableContainer: 4.} = object
|
||||
A: Opt[byte]
|
||||
|
||||
SmallTestStableStruct {.sszStableContainer: 4.} = object
|
||||
A: Opt[uint16]
|
||||
B: Opt[uint16]
|
||||
|
||||
FixedTestStableStruct {.sszStableContainer: 4.} = object
|
||||
A: Opt[uint8]
|
||||
B: Opt[uint64]
|
||||
C: Opt[uint32]
|
||||
|
||||
VarTestStableStruct {.sszStableContainer: 4.} = object
|
||||
A: Opt[uint16]
|
||||
B: Opt[List[uint16, 1024]]
|
||||
C: Opt[uint8]
|
||||
|
||||
ComplexTestStableStruct {.sszStableContainer: 8.} = object
|
||||
A: Opt[uint16]
|
||||
B: Opt[List[uint16, 128]]
|
||||
C: Opt[uint8]
|
||||
D: Opt[List[byte, 256]]
|
||||
E: Opt[VarTestStableStruct]
|
||||
F: Opt[array[4, FixedTestStableStruct]]
|
||||
G: Opt[array[2, VarTestStableStruct]]
|
||||
|
||||
BitsStableStruct {.sszStableContainer: 8.} = object
|
||||
A: Opt[BitList[5]]
|
||||
B: Opt[BitArray[2]]
|
||||
C: Opt[BitArray[1]]
|
||||
D: Opt[BitList[6]]
|
||||
E: Opt[BitArray[8]]
|
||||
|
||||
# https://github.com/wemeetagain/consensus-specs/blob/eip-7495/tests/generators/ssz_generic/ssz_profile.py
|
||||
SingleFieldTestProfile {.sszProfile: SingleFieldTestStableStruct.} = object
|
||||
A: byte
|
||||
|
||||
SmallTestProfile1 {.sszProfile: SmallTestStableStruct.} = object
|
||||
A: uint16
|
||||
B: uint16
|
||||
|
||||
SmallTestProfile2 {.sszProfile: SmallTestStableStruct.} = object
|
||||
A: uint16
|
||||
|
||||
SmallTestProfile3 {.sszProfile: SmallTestStableStruct.} = object
|
||||
B: uint16
|
||||
|
||||
FixedTestProfile1 {.sszProfile: FixedTestStableStruct.} = object
|
||||
A: uint8
|
||||
B: uint64
|
||||
C: uint32
|
||||
|
||||
FixedTestProfile2 {.sszProfile: FixedTestStableStruct.} = object
|
||||
A: uint8
|
||||
B: uint64
|
||||
|
||||
FixedTestProfile3 {.sszProfile: FixedTestStableStruct.} = object
|
||||
A: uint8
|
||||
C: uint32
|
||||
|
||||
FixedTestProfile4 {.sszProfile: FixedTestStableStruct.} = object
|
||||
C: uint32
|
||||
|
||||
VarTestProfile1 {.sszProfile: VarTestStableStruct.} = object
|
||||
A: uint16
|
||||
B: List[uint16, 1024]
|
||||
C: uint8
|
||||
|
||||
VarTestProfile2 {.sszProfile: VarTestStableStruct.} = object
|
||||
B: List[uint16, 1024]
|
||||
C: uint8
|
||||
|
||||
VarTestProfile3 {.sszProfile: VarTestStableStruct.} = object
|
||||
B: List[uint16, 1024]
|
||||
|
||||
ComplexTestProfile1 {.sszProfile: ComplexTestStableStruct.} = object
|
||||
A: uint16
|
||||
B: List[uint16, 128]
|
||||
C: uint8
|
||||
D: List[byte, 256]
|
||||
E: VarTestStableStruct
|
||||
F: array[4, FixedTestStableStruct]
|
||||
G: array[2, VarTestStableStruct]
|
||||
|
||||
ComplexTestProfile2 {.sszProfile: ComplexTestStableStruct.} = object
|
||||
A: uint16
|
||||
B: List[uint16, 128]
|
||||
C: uint8
|
||||
D: List[byte, 256]
|
||||
E: VarTestStableStruct
|
||||
|
||||
ComplexTestProfile3 {.sszProfile: ComplexTestStableStruct.} = object
|
||||
A: uint16
|
||||
C: uint8
|
||||
E: VarTestStableStruct
|
||||
G: array[2, VarTestStableStruct]
|
||||
|
||||
ComplexTestProfile4 {.sszProfile: ComplexTestStableStruct.} = object
|
||||
B: List[uint16, 128]
|
||||
D: List[byte, 256]
|
||||
F: array[4, FixedTestStableStruct]
|
||||
|
||||
ComplexTestProfile5 {.sszProfile: ComplexTestStableStruct.} = object
|
||||
E: VarTestStableStruct
|
||||
F: array[4, FixedTestStableStruct]
|
||||
G: array[2, VarTestStableStruct]
|
||||
|
||||
BitsProfile1 {.sszProfile: BitsStableStruct.} = object
|
||||
A: BitList[5]
|
||||
B: BitArray[2]
|
||||
C: BitArray[1]
|
||||
D: BitList[6]
|
||||
E: BitArray[8]
|
||||
|
||||
BitsProfile2 {.sszProfile: BitsStableStruct.} = object
|
||||
A: BitList[5]
|
||||
B: BitArray[2]
|
||||
C: BitArray[1]
|
||||
D: BitList[6]
|
||||
|
||||
BitsProfile3 {.sszProfile: BitsStableStruct.} = object
|
||||
A: BitList[5]
|
||||
D: BitList[6]
|
||||
E: BitArray[8]
|
||||
|
||||
# Type specific checks
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
|
@ -285,6 +411,71 @@ proc sszCheck(
|
|||
of "BitsStruct": checkBasic(BitsStruct, dir, expectedHash)
|
||||
else:
|
||||
raise newException(ValueError, "unknown container in test: " & sszSubType)
|
||||
of "profiles":
|
||||
var name: string
|
||||
let wasMatched = scanf(sszSubType, "$+_", name)
|
||||
doAssert wasMatched
|
||||
case name
|
||||
of "BitsProfile1":
|
||||
checkBasic(BitsProfile1, dir, expectedHash)
|
||||
of "BitsProfile2":
|
||||
checkBasic(BitsProfile2, dir, expectedHash)
|
||||
of "BitsProfile3":
|
||||
checkBasic(BitsProfile3, dir, expectedHash)
|
||||
of "ComplexTestProfile1":
|
||||
checkBasic(ComplexTestProfile1, dir, expectedHash)
|
||||
of "ComplexTestProfile2":
|
||||
checkBasic(ComplexTestProfile2, dir, expectedHash)
|
||||
of "ComplexTestProfile3":
|
||||
checkBasic(ComplexTestProfile3, dir, expectedHash)
|
||||
of "ComplexTestProfile4":
|
||||
checkBasic(ComplexTestProfile4, dir, expectedHash)
|
||||
of "ComplexTestProfile5":
|
||||
checkBasic(ComplexTestProfile5, dir, expectedHash)
|
||||
of "FixedTestProfile1":
|
||||
checkBasic(FixedTestProfile1, dir, expectedHash)
|
||||
of "FixedTestProfile2":
|
||||
checkBasic(FixedTestProfile2, dir, expectedHash)
|
||||
of "FixedTestProfile3":
|
||||
checkBasic(FixedTestProfile3, dir, expectedHash)
|
||||
of "FixedTestProfile4":
|
||||
checkBasic(FixedTestProfile4, dir, expectedHash)
|
||||
of "SingleFieldTestProfile":
|
||||
checkBasic(SingleFieldTestProfile, dir, expectedHash)
|
||||
of "SmallTestProfile1":
|
||||
checkBasic(SmallTestProfile1, dir, expectedHash)
|
||||
of "SmallTestProfile2":
|
||||
checkBasic(SmallTestProfile2, dir, expectedHash)
|
||||
of "SmallTestProfile3":
|
||||
checkBasic(SmallTestProfile3, dir, expectedHash)
|
||||
of "VarTestProfile1":
|
||||
checkBasic(VarTestProfile1, dir, expectedHash)
|
||||
of "VarTestProfile2":
|
||||
checkBasic(VarTestProfile2, dir, expectedHash)
|
||||
of "VarTestProfile3":
|
||||
checkBasic(VarTestProfile3, dir, expectedHash)
|
||||
else:
|
||||
raise newException(ValueError, "unknown profile in test: " & sszSubType)
|
||||
of "stablecontainers":
|
||||
var name: string
|
||||
let wasMatched = scanf(sszSubType, "$+_", name)
|
||||
doAssert wasMatched
|
||||
case name
|
||||
of "BitsStableStruct":
|
||||
checkBasic(BitsStableStruct, dir, expectedHash)
|
||||
of "ComplexTestStableStruct":
|
||||
checkBasic(ComplexTestStableStruct, dir, expectedHash)
|
||||
of "FixedTestStableStruct":
|
||||
checkBasic(FixedTestStableStruct, dir, expectedHash)
|
||||
of "SingleFieldTestStableStruct":
|
||||
checkBasic(SingleFieldTestStableStruct, dir, expectedHash)
|
||||
of "SmallTestStableStruct":
|
||||
checkBasic(SmallTestStableStruct, dir, expectedHash)
|
||||
of "VarTestStableStruct":
|
||||
checkBasic(VarTestStableStruct, dir, expectedHash)
|
||||
else:
|
||||
raise newException(ValueError,
|
||||
"unknown stablecontainer in test: " & sszSubType)
|
||||
else:
|
||||
raise newException(ValueError, "unknown ssz type in test: " & sszType)
|
||||
|
||||
|
@ -306,26 +497,27 @@ suite "EF - SSZ generic types":
|
|||
of "containers":
|
||||
skipped = " - skipping BitsStruct"
|
||||
|
||||
test &"Testing {sszType:12} inputs - valid" & skipped:
|
||||
test &"Testing {sszType:16} inputs - valid" & skipped:
|
||||
let path = SSZDir/sszType/"valid"
|
||||
for pathKind, sszSubType in walkDir(
|
||||
path, relative = true, checkDir = true):
|
||||
if pathKind != pcDir: continue
|
||||
sszCheck(path, sszType, sszSubType)
|
||||
|
||||
test &"Testing {sszType:12} inputs - invalid" & skipped:
|
||||
let path = SSZDir/sszType/"invalid"
|
||||
for pathKind, sszSubType in walkDir(
|
||||
path, relative = true, checkDir = true):
|
||||
if pathKind != pcDir: continue
|
||||
try:
|
||||
sszCheck(path, sszType, sszSubType)
|
||||
except SszError, UnconsumedInput:
|
||||
discard
|
||||
except TestSizeError as err:
|
||||
echo err.msg
|
||||
skip()
|
||||
except:
|
||||
checkpoint getStackTrace(getCurrentException())
|
||||
checkpoint getCurrentExceptionMsg()
|
||||
check false
|
||||
template invalidPath: untyped = SSZDir/sszType/"invalid"
|
||||
if os_ops.dirExists(invalidPath):
|
||||
test &"Testing {sszType:16} inputs - invalid" & skipped:
|
||||
for pathKind, sszSubType in walkDir(
|
||||
invalidPath, relative = true, checkDir = true):
|
||||
if pathKind != pcDir: continue
|
||||
try:
|
||||
sszCheck(invalidPath, sszType, sszSubType)
|
||||
except SszError, UnconsumedInput:
|
||||
discard
|
||||
except TestSizeError as err:
|
||||
echo err.msg
|
||||
skip()
|
||||
except:
|
||||
checkpoint getStackTrace(getCurrentException())
|
||||
checkpoint getCurrentExceptionMsg()
|
||||
check false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2019-2023 Status Research & Development GmbH
|
||||
# Copyright (c) 2019-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).
|
||||
|
@ -11,5 +11,4 @@
|
|||
|
||||
--styleCheck:usages
|
||||
--styleCheck:hint
|
||||
--hint[ConvFromXtoItselfNotNeeded]:off
|
||||
--hint[Processing]:off
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
{.push raises: [].}
|
||||
{.used.}
|
||||
|
||||
import unittest2, results, chronos, stint
|
||||
import ../beacon_chain/validators/beacon_validators,
|
||||
|
|
|
@ -1336,8 +1336,7 @@ suite "State history":
|
|||
res = process_slots(cfg, dag.headState, 5.Slot, cache, info, flags = {})
|
||||
check res.isOk
|
||||
for i in 0.Slot .. 5.Slot:
|
||||
check state.getBlockIdAtSlot(i) ==
|
||||
Opt.some BlockSlotId.init(gen, i.Slot)
|
||||
check state.getBlockIdAtSlot(i) == Opt.some BlockSlotId.init(gen, i)
|
||||
check state.getBlockIdAtSlot(6.Slot).isNone
|
||||
|
||||
# Fill 5 slots
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
{.push raises: [].}
|
||||
{.used.}
|
||||
|
||||
import
|
||||
std/algorithm,
|
||||
unittest2, chronicles, stew/[results, byteutils, io2],
|
||||
unittest2, chronicles, results, stew/[byteutils, io2],
|
||||
chronos/asyncproc,
|
||||
chronos/unittest2/asynctests,
|
||||
../beacon_chain/spec/[signatures, crypto],
|
||||
|
@ -19,8 +19,6 @@ import
|
|||
|
||||
from std/os import getEnv, osErrorMsg
|
||||
|
||||
{.used.}
|
||||
|
||||
const
|
||||
TestDirectoryName = "test-signing-node"
|
||||
TestDirectoryNameVerifyingWeb3Signer = "test-signing-node-verifying-web3signer"
|
||||
|
@ -63,8 +61,8 @@ const
|
|||
|
||||
AgAttestation = "{\"data\":{\"aggregation_bits\":\"0x01\",\"signature\":\"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\"data\":{\"slot\":\"1\",\"index\":\"1\",\"beacon_block_root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\"source\":{\"epoch\":\"1\",\"root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"},\"target\":{\"epoch\":\"1\",\"root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"}}}}"
|
||||
|
||||
CapellaBlock = "{\"version\":\"capella\",\"data\":{\"slot\":\"5297696\",\"proposer_index\":\"153094\",\"parent_root\":\"0xe6106533af9be918120ead7440a8006c7f123cc3cb7daf1f11d951864abea014\",\"state_root\":\"0xf86196d34500ca25d1f4e7431d4d52f6f85540bcaf97dd0d2ad9ecdb3eebcdf0\",\"body\":{\"randao_reveal\":\"0xa7efee3d5ddceb60810b23e3b5d39734696418f41dfd13a0851c7be7a72acbdceaa61e1db27513801917d72519d1c1040ccfed829faf06abe06d9964949554bf4369134b66de715ea49eb4fecf3e2b7e646f1764a1993e31e53dbc6557929c12\",\"eth1_data\":{\"deposit_root\":\"0x8ec87d7219a3c873fff3bfe206b4f923d1b471ce4ff9d6d6ecc162ef07825e14\",\"deposit_count\":\"259476\",\"block_hash\":\"0x877b6f8332c7397251ff3f0c5cecec105ff7d4cb78251b47f91fd15a86a565ab\"},\"graffiti\":\"\",\"proposer_slashings\":[],\"attester_slashings\":[],\"attestations\":[],\"deposits\":[],\"voluntary_exits\":[],\"sync_aggregate\":{\"sync_committee_bits\":\"0x733dfda7f5ffde5ade73367fcbf7fffeef7fe43777ffdffab9dbad6f7eed5fff9bfec4affdefbfaddf35bf5efbff9ffff9dfd7dbf97fbfcdfaddfeffbf95f75f\",\"sync_committee_signature\":\"0x81fdf76e797f81b0116a1c1ae5200b613c8041115223cd89e8bd5477aab13de6097a9ebf42b130c59527bbb4c96811b809353a17c717549f82d4bd336068ef0b99b1feebd4d2432a69fa77fac12b78f1fcc9d7b59edbeb381adf10b15bc4a520\"},\"execution_payload\":{\"parent_hash\":\"0x14c2242a8cfbce559e84c391f5f16d10d7719751b8558873012dc88ae5a193e8\",\"fee_recipient\":\"$1\",\"state_root\":\"0xdf8d96b2c292736d39e72e25802c2744d34d3d3c616de5b362425cab01f72fa5\",\"receipts_root\":\"0x4938a2bf640846d213b156a1a853548b369cd02917fa63d8766ab665d7930bac\",\"logs_bloom\":\"0x298610600038408c201080013832408850a00bc8f801920121840030a015310010e2a0e0108628110552062811441c84802f43825c4fc82140b036c58025a28800054c80a44025c052090a0f2c209a0400058040019ea0008e589084078048050880930113a2894082e0112408b088382402a851621042212aa40018a408d07e178c68691486411aa9a2809043b000a04c040000065a030028018540b04b1820271d00821b00c29059095022322c10a530060223240416140190056608200063c82248274ba8f0098e402041cd9f451031481a1010b8220824833520490221071898802d206348449116812280014a10a2d1c210100a30010802490f0a221849\",\"prev_randao\":\"0xc061711e135cd40531ec3ee29d17d3824c0e5f80d07f721e792ab83240aa0ab5\",\"block_number\":\"8737497\",\"gas_limit\":\"30000000\",\"gas_used\":\"16367052\",\"timestamp\":\"1680080352\",\"extra_data\":\"0xd883010b05846765746888676f312e32302e32856c696e7578\",\"base_fee_per_gas\":\"231613172261\",\"block_hash\":\"0x5aa9fd22a9238925adb2b038fd6eafc77adabf554051db5bc16ae5168a52eff6\",\"transactions\":[],\"withdrawals\":[]},\"bls_to_execution_changes\":[]}}}"
|
||||
DenebBlockContents = "{\"version\":\"deneb\",\"data\":{\"block\":{\"slot\":\"5297696\",\"proposer_index\":\"153094\",\"parent_root\":\"0xe6106533af9be918120ead7440a8006c7f123cc3cb7daf1f11d951864abea014\",\"state_root\":\"0xf86196d34500ca25d1f4e7431d4d52f6f85540bcaf97dd0d2ad9ecdb3eebcdf0\",\"body\":{\"randao_reveal\":\"0xa7efee3d5ddceb60810b23e3b5d39734696418f41dfd13a0851c7be7a72acbdceaa61e1db27513801917d72519d1c1040ccfed829faf06abe06d9964949554bf4369134b66de715ea49eb4fecf3e2b7e646f1764a1993e31e53dbc6557929c12\",\"eth1_data\":{\"deposit_root\":\"0x8ec87d7219a3c873fff3bfe206b4f923d1b471ce4ff9d6d6ecc162ef07825e14\",\"deposit_count\":\"259476\",\"block_hash\":\"0x877b6f8332c7397251ff3f0c5cecec105ff7d4cb78251b47f91fd15a86a565ab\"},\"graffiti\":\"\",\"proposer_slashings\":[],\"attester_slashings\":[],\"attestations\":[],\"deposits\":[],\"voluntary_exits\":[],\"sync_aggregate\":{\"sync_committee_bits\":\"0x733dfda7f5ffde5ade73367fcbf7fffeef7fe43777ffdffab9dbad6f7eed5fff9bfec4affdefbfaddf35bf5efbff9ffff9dfd7dbf97fbfcdfaddfeffbf95f75f\",\"sync_committee_signature\":\"0x81fdf76e797f81b0116a1c1ae5200b613c8041115223cd89e8bd5477aab13de6097a9ebf42b130c59527bbb4c96811b809353a17c717549f82d4bd336068ef0b99b1feebd4d2432a69fa77fac12b78f1fcc9d7b59edbeb381adf10b15bc4a520\"},\"execution_payload\":{\"parent_hash\":\"0x14c2242a8cfbce559e84c391f5f16d10d7719751b8558873012dc88ae5a193e8\",\"fee_recipient\":\"$1\",\"state_root\":\"0xdf8d96b2c292736d39e72e25802c2744d34d3d3c616de5b362425cab01f72fa5\",\"receipts_root\":\"0x4938a2bf640846d213b156a1a853548b369cd02917fa63d8766ab665d7930bac\",\"logs_bloom\":\"0x298610600038408c201080013832408850a00bc8f801920121840030a015310010e2a0e0108628110552062811441c84802f43825c4fc82140b036c58025a28800054c80a44025c052090a0f2c209a0400058040019ea0008e589084078048050880930113a2894082e0112408b088382402a851621042212aa40018a408d07e178c68691486411aa9a2809043b000a04c040000065a030028018540b04b1820271d00821b00c29059095022322c10a530060223240416140190056608200063c82248274ba8f0098e402041cd9f451031481a1010b8220824833520490221071898802d206348449116812280014a10a2d1c210100a30010802490f0a221849\",\"prev_randao\":\"0xc061711e135cd40531ec3ee29d17d3824c0e5f80d07f721e792ab83240aa0ab5\",\"block_number\":\"8737497\",\"gas_limit\":\"30000000\",\"gas_used\":\"16367052\",\"timestamp\":\"1680080352\",\"extra_data\":\"0xd883010b05846765746888676f312e32302e32856c696e7578\",\"base_fee_per_gas\":\"231613172261\",\"block_hash\":\"0x5aa9fd22a9238925adb2b038fd6eafc77adabf554051db5bc16ae5168a52eff6\",\"transactions\":[],\"withdrawals\":[],\"blob_gas_used\":\"2316131761\",\"excess_blob_gas\":\"231613172261\"},\"bls_to_execution_changes\":[],\"blob_kzg_commitments\":[]}},\"kzg_proofs\":[],\"blobs\":[]}}"
|
||||
CapellaBlock = "{\"message\":{\"slot\":\"5297696\",\"proposer_index\":\"153094\",\"parent_root\":\"0xe6106533af9be918120ead7440a8006c7f123cc3cb7daf1f11d951864abea014\",\"state_root\":\"0xf86196d34500ca25d1f4e7431d4d52f6f85540bcaf97dd0d2ad9ecdb3eebcdf0\",\"body\":{\"randao_reveal\":\"0xa7efee3d5ddceb60810b23e3b5d39734696418f41dfd13a0851c7be7a72acbdceaa61e1db27513801917d72519d1c1040ccfed829faf06abe06d9964949554bf4369134b66de715ea49eb4fecf3e2b7e646f1764a1993e31e53dbc6557929c12\",\"eth1_data\":{\"deposit_root\":\"0x8ec87d7219a3c873fff3bfe206b4f923d1b471ce4ff9d6d6ecc162ef07825e14\",\"deposit_count\":\"259476\",\"block_hash\":\"0x877b6f8332c7397251ff3f0c5cecec105ff7d4cb78251b47f91fd15a86a565ab\"},\"graffiti\":\"\",\"proposer_slashings\":[],\"attester_slashings\":[],\"attestations\":[],\"deposits\":[],\"voluntary_exits\":[],\"sync_aggregate\":{\"sync_committee_bits\":\"0x733dfda7f5ffde5ade73367fcbf7fffeef7fe43777ffdffab9dbad6f7eed5fff9bfec4affdefbfaddf35bf5efbff9ffff9dfd7dbf97fbfcdfaddfeffbf95f75f\",\"sync_committee_signature\":\"0x81fdf76e797f81b0116a1c1ae5200b613c8041115223cd89e8bd5477aab13de6097a9ebf42b130c59527bbb4c96811b809353a17c717549f82d4bd336068ef0b99b1feebd4d2432a69fa77fac12b78f1fcc9d7b59edbeb381adf10b15bc4a520\"},\"execution_payload\":{\"parent_hash\":\"0x14c2242a8cfbce559e84c391f5f16d10d7719751b8558873012dc88ae5a193e8\",\"fee_recipient\":\"$1\",\"state_root\":\"0xdf8d96b2c292736d39e72e25802c2744d34d3d3c616de5b362425cab01f72fa5\",\"receipts_root\":\"0x4938a2bf640846d213b156a1a853548b369cd02917fa63d8766ab665d7930bac\",\"logs_bloom\":\"0x298610600038408c201080013832408850a00bc8f801920121840030a015310010e2a0e0108628110552062811441c84802f43825c4fc82140b036c58025a28800054c80a44025c052090a0f2c209a0400058040019ea0008e589084078048050880930113a2894082e0112408b088382402a851621042212aa40018a408d07e178c68691486411aa9a2809043b000a04c040000065a030028018540b04b1820271d00821b00c29059095022322c10a530060223240416140190056608200063c82248274ba8f0098e402041cd9f451031481a1010b8220824833520490221071898802d206348449116812280014a10a2d1c210100a30010802490f0a221849\",\"prev_randao\":\"0xc061711e135cd40531ec3ee29d17d3824c0e5f80d07f721e792ab83240aa0ab5\",\"block_number\":\"8737497\",\"gas_limit\":\"30000000\",\"gas_used\":\"16367052\",\"timestamp\":\"1680080352\",\"extra_data\":\"0xd883010b05846765746888676f312e32302e32856c696e7578\",\"base_fee_per_gas\":\"231613172261\",\"block_hash\":\"0x5aa9fd22a9238925adb2b038fd6eafc77adabf554051db5bc16ae5168a52eff6\",\"transactions\":[],\"withdrawals\":[]},\"bls_to_execution_changes\":[]}},\"signature\":\"$2\"}"
|
||||
DenebBlockContents = "{\"signed_block\":{\"message\":{\"slot\":\"5297696\",\"proposer_index\":\"153094\",\"parent_root\":\"0xe6106533af9be918120ead7440a8006c7f123cc3cb7daf1f11d951864abea014\",\"state_root\":\"0xf86196d34500ca25d1f4e7431d4d52f6f85540bcaf97dd0d2ad9ecdb3eebcdf0\",\"body\":{\"randao_reveal\":\"0xa7efee3d5ddceb60810b23e3b5d39734696418f41dfd13a0851c7be7a72acbdceaa61e1db27513801917d72519d1c1040ccfed829faf06abe06d9964949554bf4369134b66de715ea49eb4fecf3e2b7e646f1764a1993e31e53dbc6557929c12\",\"eth1_data\":{\"deposit_root\":\"0x8ec87d7219a3c873fff3bfe206b4f923d1b471ce4ff9d6d6ecc162ef07825e14\",\"deposit_count\":\"259476\",\"block_hash\":\"0x877b6f8332c7397251ff3f0c5cecec105ff7d4cb78251b47f91fd15a86a565ab\"},\"graffiti\":\"\",\"proposer_slashings\":[],\"attester_slashings\":[],\"attestations\":[],\"deposits\":[],\"voluntary_exits\":[],\"sync_aggregate\":{\"sync_committee_bits\":\"0x733dfda7f5ffde5ade73367fcbf7fffeef7fe43777ffdffab9dbad6f7eed5fff9bfec4affdefbfaddf35bf5efbff9ffff9dfd7dbf97fbfcdfaddfeffbf95f75f\",\"sync_committee_signature\":\"0x81fdf76e797f81b0116a1c1ae5200b613c8041115223cd89e8bd5477aab13de6097a9ebf42b130c59527bbb4c96811b809353a17c717549f82d4bd336068ef0b99b1feebd4d2432a69fa77fac12b78f1fcc9d7b59edbeb381adf10b15bc4a520\"},\"execution_payload\":{\"parent_hash\":\"0x14c2242a8cfbce559e84c391f5f16d10d7719751b8558873012dc88ae5a193e8\",\"fee_recipient\":\"$1\",\"state_root\":\"0xdf8d96b2c292736d39e72e25802c2744d34d3d3c616de5b362425cab01f72fa5\",\"receipts_root\":\"0x4938a2bf640846d213b156a1a853548b369cd02917fa63d8766ab665d7930bac\",\"logs_bloom\":\"0x298610600038408c201080013832408850a00bc8f801920121840030a015310010e2a0e0108628110552062811441c84802f43825c4fc82140b036c58025a28800054c80a44025c052090a0f2c209a0400058040019ea0008e589084078048050880930113a2894082e0112408b088382402a851621042212aa40018a408d07e178c68691486411aa9a2809043b000a04c040000065a030028018540b04b1820271d00821b00c29059095022322c10a530060223240416140190056608200063c82248274ba8f0098e402041cd9f451031481a1010b8220824833520490221071898802d206348449116812280014a10a2d1c210100a30010802490f0a221849\",\"prev_randao\":\"0xc061711e135cd40531ec3ee29d17d3824c0e5f80d07f721e792ab83240aa0ab5\",\"block_number\":\"8737497\",\"gas_limit\":\"30000000\",\"gas_used\":\"16367052\",\"timestamp\":\"1680080352\",\"extra_data\":\"0xd883010b05846765746888676f312e32302e32856c696e7578\",\"base_fee_per_gas\":\"231613172261\",\"block_hash\":\"0x5aa9fd22a9238925adb2b038fd6eafc77adabf554051db5bc16ae5168a52eff6\",\"transactions\":[],\"withdrawals\":[],\"blob_gas_used\":\"2316131761\",\"excess_blob_gas\":\"231613172261\"},\"bls_to_execution_changes\":[],\"blob_kzg_commitments\":[]}},\"signature\":\"$2\"},\"kzg_proofs\":[],\"blobs\":[]}"
|
||||
|
||||
SigningNodeAddress = "127.0.0.1"
|
||||
defaultSigningNodePort = 35333
|
||||
|
@ -84,43 +82,42 @@ func getNodePort(basePort: int, rt: RemoteSignerType): int =
|
|||
of RemoteSignerType.VerifyingWeb3Signer:
|
||||
basePort + 1
|
||||
|
||||
func init(T: type ForkedBeaconBlock, contents: ProduceBlockResponseV2): T =
|
||||
func init(
|
||||
T: type ForkedBeaconBlock, contents: RestPublishedSignedBlockContents): T =
|
||||
case contents.kind
|
||||
of ConsensusFork.Phase0 .. ConsensusFork.Bellatrix:
|
||||
raiseAssert "Unsupported fork"
|
||||
of ConsensusFork.Capella:
|
||||
return ForkedBeaconBlock.init(contents.capellaData)
|
||||
return ForkedBeaconBlock.init(contents.capellaData.message)
|
||||
of ConsensusFork.Deneb:
|
||||
return ForkedBeaconBlock.init(contents.denebData.`block`)
|
||||
return ForkedBeaconBlock.init(contents.denebData.signed_block.message)
|
||||
of ConsensusFork.Electra:
|
||||
debugComment "probably like the deneb case"
|
||||
return default(T)
|
||||
return ForkedBeaconBlock.init(contents.electraData.signed_block.message)
|
||||
|
||||
proc getBlock(
|
||||
fork: ConsensusFork,
|
||||
feeRecipient = SigningExpectedFeeRecipient
|
||||
): ForkedBeaconBlock {.raises: [ResultError[cstring]].} =
|
||||
let
|
||||
blckData =
|
||||
try:
|
||||
case fork
|
||||
of ConsensusFork.Phase0 .. ConsensusFork.Bellatrix: raiseAssert "Unsupported fork"
|
||||
of ConsensusFork.Capella: CapellaBlock % [feeRecipient]
|
||||
of ConsensusFork.Deneb: DenebBlockContents % [feeRecipient]
|
||||
of ConsensusFork.Electra:
|
||||
debugComment "electra test signing node getblock"
|
||||
raiseAssert "electra unsupported"
|
||||
except ValueError:
|
||||
# https://github.com/nim-lang/Nim/pull/23356
|
||||
raiseAssert "Arguments match the format string"
|
||||
contentType = ContentTypeData(
|
||||
mediaType: MediaType.init("application/json"))
|
||||
let blckData =
|
||||
try:
|
||||
case fork
|
||||
of ConsensusFork.Phase0 .. ConsensusFork.Bellatrix:
|
||||
raiseAssert "Unsupported fork"
|
||||
of ConsensusFork.Capella: CapellaBlock % [feeRecipient, SomeSignature]
|
||||
of ConsensusFork.Deneb:
|
||||
DenebBlockContents % [feeRecipient, SomeSignature]
|
||||
of ConsensusFork.Electra:
|
||||
debugComment "electra test signing node getblock"
|
||||
raiseAssert "electra unsupported"
|
||||
except ValueError:
|
||||
# https://github.com/nim-lang/Nim/pull/23356
|
||||
raiseAssert "Arguments match the format string"
|
||||
|
||||
let b = decodeBytes(ProduceBlockResponseV2,
|
||||
blckData.toOpenArrayByte(0, len(blckData) - 1),
|
||||
Opt.some(contentType),
|
||||
$fork).tryGet()
|
||||
ForkedBeaconBlock.init(b)
|
||||
try:
|
||||
ForkedBeaconBlock.init(RestJson.decode(
|
||||
blckData, RestPublishedSignedBlockContents))
|
||||
except SerializationError:
|
||||
raiseAssert "malformed block contents"
|
||||
|
||||
func init(t: typedesc[Web3SignerForkedBeaconBlock],
|
||||
forked: ForkedBeaconBlock): Web3SignerForkedBeaconBlock =
|
||||
|
@ -371,6 +368,8 @@ let
|
|||
fatal "Invalid base port arg", basePort = basePortStr, exc = exc.msg
|
||||
quit 1
|
||||
|
||||
from std/algorithm import sorted
|
||||
|
||||
block:
|
||||
let res = createTestDir(RemoteSignerType.Web3Signer)
|
||||
doAssert(res.isOk())
|
||||
|
|
|
@ -103,7 +103,7 @@ suite "Sync committee pool":
|
|||
privkey2 = MockPrivKeys[1.ValidatorIndex]
|
||||
|
||||
bid1 = BlockId(
|
||||
slot: Slot(cfg.BELLATRIX_FORK_EPOCH.start_slot - 1),
|
||||
slot: cfg.BELLATRIX_FORK_EPOCH.start_slot - 1,
|
||||
root: eth2digest(@[1.byte]))
|
||||
|
||||
sig1 = get_sync_committee_message_signature(
|
||||
|
|
|
@ -369,7 +369,7 @@ suite "SyncManager test suite":
|
|||
aq = newAsyncQueue[BlockEntry]()
|
||||
chunkSize = 3'u64
|
||||
numberOfChunks = 3'u64
|
||||
finishSlot = Slot(startSlot + numberOfChunks * chunkSize - 1'u64)
|
||||
finishSlot = startSlot + numberOfChunks * chunkSize - 1'u64
|
||||
queueSize = 1
|
||||
|
||||
var counter =
|
||||
|
@ -734,7 +734,7 @@ suite "SyncManager test suite":
|
|||
startSlot = Slot(0)
|
||||
chunkSize = SLOTS_PER_EPOCH
|
||||
numberOfChunks = 4'u64
|
||||
finishSlot = Slot(startSlot + numberOfChunks * chunkSize - 1'u64)
|
||||
finishSlot = startSlot + numberOfChunks * chunkSize - 1'u64
|
||||
queueSize = 1
|
||||
|
||||
var counter = int(startSlot)
|
||||
|
@ -855,7 +855,7 @@ suite "SyncManager test suite":
|
|||
startSlot = Slot(0)
|
||||
chunkSize = SLOTS_PER_EPOCH
|
||||
numberOfChunks = 1'u64
|
||||
finishSlot = Slot(startSlot + numberOfChunks * chunkSize - 1'u64)
|
||||
finishSlot = startSlot + numberOfChunks * chunkSize - 1'u64
|
||||
queueSize = 1
|
||||
|
||||
var counter = int(startSlot)
|
||||
|
@ -902,7 +902,7 @@ suite "SyncManager test suite":
|
|||
startSlot = Slot(0)
|
||||
chunkSize = SLOTS_PER_EPOCH
|
||||
numberOfChunks = 4'u64
|
||||
finishSlot = Slot(startSlot + numberOfChunks * chunkSize - 1'u64)
|
||||
finishSlot = startSlot + numberOfChunks * chunkSize - 1'u64
|
||||
queueSize = 1
|
||||
|
||||
var
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5de55bab8c4e161d3ae1c39f284c26262b5ebf82
|
||||
Subproject commit 695d1c9dbec4fa0f746a15df259a19fed49e075e
|
Loading…
Reference in New Issue