From 0a0a304e8e20667e067b4efa466a14be2e2836d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mamy=20Andr=C3=A9-Ratsimbazafy?= Date: Tue, 22 Dec 2020 10:57:33 +0100 Subject: [PATCH] Update spec types, use generics instead of static enums. TODO SSZ [skip CI] --- beacon_chain/spec/beaconstate.nim | 45 ++--- beacon_chain/spec/datatypes.nim | 172 ++++++++++--------- beacon_chain/spec/network.nim | 2 +- beacon_chain/spec/signatures.nim | 2 +- beacon_chain/spec/state_transition.nim | 40 +++-- beacon_chain/spec/state_transition_block.nim | 18 +- 6 files changed, 141 insertions(+), 138 deletions(-) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 41851855e..2efbf5486 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -250,7 +250,7 @@ proc initialize_beacon_state_from_eth1*( Eth1Data(block_hash: eth1_block_hash, deposit_count: uint64(len(deposits))), latest_block_header: BeaconBlockHeader( - body_root: hash_tree_root(BeaconBlockBody( + body_root: hash_tree_root(BeaconBlockBody[Unchecked]( # This differs from the spec intentionally. # We must specify the default value for `ValidatorSig` # in order to get a correct `hash_tree_root`. @@ -321,19 +321,19 @@ proc initialize_hashed_beacon_state_from_eth1*( preset, eth1_block_hash, eth1_timestamp, deposits, flags) HashedBeaconState(data: genesisState[], root: hash_tree_root(genesisState[])) -func emptyBeaconBlockBody(): BeaconBlockBody = +func emptyBeaconBlockBody(): BeaconBlockBody[Unchecked] = # TODO: This shouldn't be necessary if OpaqueBlob is the default - BeaconBlockBody(randao_reveal: ValidatorSig(kind: OpaqueBlob)) + BeaconBlockBody[Unchecked](randao_reveal: ValidatorSig(kind: OpaqueBlob)) # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#genesis-block -func get_initial_beacon_block*(state: BeaconState): SignedBeaconBlock = - let message = BeaconBlock( +func get_initial_beacon_block*(state: BeaconState): SignedBeaconBlock[Unchecked] = + let message = BeaconBlock[Unchecked]( slot: state.slot, state_root: hash_tree_root(state), body: emptyBeaconBlockBody()) # parent_root, randao_reveal, eth1_data, signature, and body automatically # initialized to default values. - SignedBeaconBlock(message: message, root: hash_tree_root(message)) + SignedBeaconBlock[Unchecked](message: message, root: hash_tree_root(message)) # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_block_root_at_slot func get_block_root_at_slot*(state: BeaconState, @@ -430,7 +430,8 @@ proc process_registry_updates*(state: var BeaconState, # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#is_valid_indexed_attestation proc is_valid_indexed_attestation*( - state: BeaconState, indexed_attestation: SomeIndexedAttestation, + state: BeaconState, + indexed_attestation: IndexedAttestation[Unchecked], flags: UpdateFlags): Result[void, cstring] = ## Check if ``indexed_attestation`` is not empty, has sorted and unique ## indices and has a valid aggregate signature. @@ -516,31 +517,15 @@ func get_attesting_indices*(state: BeaconState, result.incl index # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_indexed_attestation -func get_indexed_attestation(state: BeaconState, attestation: Attestation, - cache: var StateCache): IndexedAttestation = +func get_indexed_attestation[Trust](state: BeaconState, attestation: Attestation[Trust], + cache: var StateCache): IndexedAttestation[Trust] = ## Return the indexed attestation corresponding to ``attestation``. let attesting_indices = get_attesting_indices( state, attestation.data, attestation.aggregation_bits, cache) - IndexedAttestation( - attesting_indices: - List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE].init( - sorted(mapIt(attesting_indices.toSeq, it.uint64), system.cmp)), - data: attestation.data, - signature: attestation.signature - ) - -func get_indexed_attestation(state: BeaconState, attestation: TrustedAttestation, - cache: var StateCache): TrustedIndexedAttestation = - ## Return the indexed attestation corresponding to ``attestation``. - let - attesting_indices = - get_attesting_indices( - state, attestation.data, attestation.aggregation_bits, cache) - - TrustedIndexedAttestation( + IndexedAttestation[Trust]( attesting_indices: List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE].init( sorted(mapIt(attesting_indices.toSeq, it.uint64), system.cmp)), @@ -592,7 +577,7 @@ func check_attestation_index( # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#attestations proc check_attestation*( - state: BeaconState, attestation: SomeAttestation, flags: UpdateFlags, + state: BeaconState, attestation: Attestation, flags: UpdateFlags, cache: var StateCache): Result[void, cstring] = ## Check that an attestation follows the rules of being included in the state ## at the current slot. When acting as a proposer, the same rules need to @@ -621,13 +606,13 @@ proc check_attestation*( if not (data.source == state.previous_justified_checkpoint): return err("FFG data not matching previous justified epoch") - ? is_valid_indexed_attestation( - state, get_indexed_attestation(state, attestation, cache), flags) + let idx_att = get_indexed_attestation(state, attestation, cache) + ? is_valid_indexed_attestation(state, idx_att, flags) ok() proc process_attestation*( - state: var BeaconState, attestation: SomeAttestation, flags: UpdateFlags, + state: var BeaconState, attestation: Attestation, flags: UpdateFlags, cache: var StateCache): Result[void, cstring] {.nbench.} = # In the spec, attestation validation is mixed with state mutation, so here # we've split it into two functions so that the validation logic can be diff --git a/beacon_chain/spec/datatypes.nim b/beacon_chain/spec/datatypes.nim index 766de946e..275d3e1dd 100644 --- a/beacon_chain/spec/datatypes.nim +++ b/beacon_chain/spec/datatypes.nim @@ -78,6 +78,55 @@ const template maxSize*(n: int) {.pragma.} type + # The trust level of a block, attestation or signature + # + # When we receive blocks from outside sources, they are untrusted and go + # through several layers of validation. Blocks that have gone through + # validations can be trusted to be well-formed, with a correct signature, + # having a parent and applying cleanly to the state that their parent + # left them with. + # + # When loading such blocks from the database, to rewind states for example, + # it is expensive to redo the validations (in particular, the signature + # checks), thus `TrustedBlock` uses a `TrustedSig` type to mark that these + # checks can be skipped. + # + # docs/block_validation_flow.md + + Unchecked* = object # Object hasn't gone through any verification + SigVerified* = object # Object cryptographic signature has been verified + TransitionVerified* = object # Object is valid according to the protocol state transition logic + Trusted* = object # Object is fully verified both cryptographically and logically + + # We use dummy objects instead of static enum as static enum + # have cause issues with shortLog: + # - cannot use `auto`, need to use `tuple` as return value + # - overloading on Eth2Digest needed to be prefixed with the module digest.shortLog(_) + # They also required to reorder the type section. + # Generics are also better tested than static enums. + + # TODO: we might want to compile with deduplication on + # as the C code will be the same but we will have 1 duplicate per trust level + # https://stackoverflow.com/questions/15168924/gcc-clang-merging-functions-with-identical-instructions-comdat-folding + # linker: --icf (identical COMDAT folding) + # GCC: -ffunction-sections + + # Trust level aliases + # --------------------------------------------------------------- + TrustedSignedBeaconBlock* = SignedBeaconBlock[Trusted] + UntrustedSignedBeaconBlock* = SignedBeaconBlock[Unchecked] or + SignedBeaconBlock[SigVerified] or + SignedBeaconBlock[TransitionVerified] + TrustedBeaconBlock* = BeaconBlock[Trusted] + UntrustedBeaconBlock* = BeaconBlock[Unchecked] or + BeaconBlock[SigVerified] or + BeaconBlock[TransitionVerified] + + TrustedIndexedAttestation* = IndexedAttestation[Trusted] + UntrustedIndexedAttestation* = IndexedAttestation[Unchecked] or + IndexedAttestation[SigVerified] or + IndexedAttestation[TransitionVerified] + # Domains # --------------------------------------------------------------- # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#domain-types @@ -120,33 +169,29 @@ type signed_header_2*: SignedBeaconBlockHeader # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#attesterslashing - AttesterSlashing* = object - attestation_1*: IndexedAttestation - attestation_2*: IndexedAttestation + AttesterSlashing*[Trust] = object + attestation_1*: IndexedAttestation[Trust] + attestation_2*: IndexedAttestation[Trust] # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#indexedattestation - IndexedAttestation* = object + IndexedAttestation*[Trust] = object attesting_indices*: List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE] data*: AttestationData - signature*: ValidatorSig - - TrustedIndexedAttestation* = object - attesting_indices*: List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE] - data*: AttestationData - signature*: TrustedSig + when Trust is SigVerified|Trusted: + signature*: TrustedSig + else: + signature*: ValidatorSig CommitteeValidatorsBits* = BitList[Limit MAX_VALIDATORS_PER_COMMITTEE] # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#attestation - Attestation* = object + Attestation*[Trust] = object aggregation_bits*: CommitteeValidatorsBits data*: AttestationData - signature*: ValidatorSig - - TrustedAttestation* = object - aggregation_bits*: CommitteeValidatorsBits - data*: AttestationData - signature*: TrustedSig + when Trust is SigVerified|Trusted: + signature*: TrustedSig + else: + signature*: ValidatorSig ForkDigest* = distinct array[4, byte] @@ -203,7 +248,7 @@ type validator_index*: uint64 # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#beaconblock - BeaconBlock* = object + BeaconBlock*[Trust] = object ## For each slot, a proposer is chosen from the validator pool to propose ## a new block. Once the block as been proposed, it is transmitted to ## validators that will have a chance to vote on it through attestations. @@ -219,30 +264,7 @@ type state_root*: Eth2Digest ##\ ## The state root, _after_ this block has been processed - body*: BeaconBlockBody - - TrustedBeaconBlock* = object - ## When we receive blocks from outside sources, they are untrusted and go - ## through several layers of validation. Blocks that have gone through - ## validations can be trusted to be well-formed, with a correct signature, - ## having a parent and applying cleanly to the state that their parent - ## left them with. - ## - ## When loading such blocks from the database, to rewind states for example, - ## it is expensive to redo the validations (in particular, the signature - ## checks), thus `TrustedBlock` uses a `TrustedSig` type to mark that these - ## checks can be skipped. - ## - ## TODO this could probably be solved with some type trickery, but there - ## too many bugs in nim around generics handling, and we've used up - ## the trickery budget in the serialization library already. Until - ## then, the type must be manually kept compatible with its untrusted - ## cousin. - slot*: Slot - proposer_index*: uint64 - parent_root*: Eth2Digest ##\ - state_root*: Eth2Digest ##\ - body*: TrustedBeaconBlockBody + body*: BeaconBlockBody[Trust] # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#beaconblockheader BeaconBlockHeader* = object @@ -260,35 +282,20 @@ type GraffitiBytes* = distinct array[MAX_GRAFFITI_SIZE, byte] # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#beaconblockbody - BeaconBlockBody* = object - randao_reveal*: ValidatorSig + BeaconBlockBody*[Trust] = object + when Trust is SigVerified|Trusted: + randao_reveal*: TrustedSig + else: + randao_reveal*: ValidatorSig eth1_data*: Eth1Data graffiti*: GraffitiBytes # Operations proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS] - attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS] - attestations*: List[Attestation, Limit MAX_ATTESTATIONS] + attester_slashings*: List[AttesterSlashing[Trust], Limit MAX_ATTESTER_SLASHINGS] + attestations*: List[Attestation[Trust], Limit MAX_ATTESTATIONS] deposits*: List[Deposit, Limit MAX_DEPOSITS] - voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS] - - TrustedBeaconBlockBody* = object - randao_reveal*: TrustedSig - eth1_data*: Eth1Data - graffiti*: GraffitiBytes - - # Operations - proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS] - attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS] - attestations*: List[TrustedAttestation, Limit MAX_ATTESTATIONS] - deposits*: List[Deposit, Limit MAX_DEPOSITS] - voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS] - - SomeSignedBeaconBlock* = SignedBeaconBlock | TrustedSignedBeaconBlock - SomeBeaconBlock* = BeaconBlock | TrustedBeaconBlock - SomeBeaconBlockBody* = BeaconBlockBody | TrustedBeaconBlockBody - SomeAttestation* = Attestation | TrustedAttestation - SomeIndexedAttestation* = IndexedAttestation | TrustedIndexedAttestation + voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS] # TODO: trust system? # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#beaconstate BeaconState* = object @@ -417,15 +424,12 @@ type signature*: ValidatorSig # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#signedbeaconblock - SignedBeaconBlock* = object - message*: BeaconBlock - signature*: ValidatorSig - - root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block - - TrustedSignedBeaconBlock* = object - message*: TrustedBeaconBlock - signature*: TrustedSig + SignedBeaconBlock*[Trust] = object + message*: BeaconBlock[Trust] + when Trust is SigVerified|Trusted: + signature*: TrustedSig + else: + signature*: ValidatorSig root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block @@ -437,7 +441,7 @@ type # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/validator.md#aggregateandproof AggregateAndProof* = object aggregator_index*: uint64 - aggregate*: Attestation + aggregate*: Attestation[Trusted] selection_proof*: ValidatorSig # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/validator.md#signedaggregateandproof @@ -667,7 +671,7 @@ func shortLog*(s: Slot): uint64 = func shortLog*(e: Epoch): uint64 = e - GENESIS_EPOCH -func shortLog*(v: SomeBeaconBlock): auto = +func shortLog*(v: BeaconBlock): auto = ( slot: shortLog(v.slot), proposer_index: v.proposer_index, @@ -682,7 +686,7 @@ func shortLog*(v: SomeBeaconBlock): auto = voluntary_exits_len: v.body.voluntary_exits.len(), ) -func shortLog*(v: SomeSignedBeaconBlock): auto = +func shortLog*(v: SignedBeaconBlock): auto = ( blck: shortLog(v.message), signature: shortLog(v.signature) @@ -733,14 +737,14 @@ func shortLog*(v: PendingAttestation): auto = proposer_index: v.proposer_index ) -func shortLog*(v: SomeAttestation): auto = +func shortLog*(v: Attestation): auto = ( aggregation_bits: v.aggregation_bits, data: shortLog(v.data), signature: shortLog(v.signature) ) -func shortLog*(v: SomeIndexedAttestation): auto = +func shortLog*(v: IndexedAttestation): auto = ( attestating_indices: v.attesting_indices, data: shortLog(v.data), @@ -773,9 +777,15 @@ func shortLog*(v: SignedVoluntaryExit): auto = chronicles.formatIt Slot: it.shortLog chronicles.formatIt Epoch: it.shortLog -chronicles.formatIt BeaconBlock: it.shortLog +chronicles.formatIt BeaconBlock[Unchecked]: it.shortLog +chronicles.formatIt BeaconBlock[SigVerified]: it.shortLog +chronicles.formatIt BeaconBlock[TransitionVerified]: it.shortLog +chronicles.formatIt BeaconBlock[Trusted]: it.shortLog chronicles.formatIt AttestationData: it.shortLog -chronicles.formatIt Attestation: it.shortLog +chronicles.formatIt Attestation[Unchecked]: it.shortLog +chronicles.formatIt Attestation[SigVerified]: it.shortLog +chronicles.formatIt Attestation[TransitionVerified]: it.shortLog +chronicles.formatIt Attestation[Trusted]: it.shortLog chronicles.formatIt Checkpoint: it.shortLog import json_serialization diff --git a/beacon_chain/spec/network.nim b/beacon_chain/spec/network.nim index 64d6404b3..aaeb8f1db 100644 --- a/beacon_chain/spec/network.nim +++ b/beacon_chain/spec/network.nim @@ -90,7 +90,7 @@ func getAttestationTopic*(forkDigest: ForkDigest, subnetIndex: uint64): raiseAssert e.msg func getAttestationTopic*(forkDigest: ForkDigest, - attestation: Attestation, + attestation: Attestation[Unchecked], num_active_validators: uint64): string = getAttestationTopic( forkDigest, diff --git a/beacon_chain/spec/signatures.nim b/beacon_chain/spec/signatures.nim index f70d73930..cf33daada 100644 --- a/beacon_chain/spec/signatures.nim +++ b/beacon_chain/spec/signatures.nim @@ -84,7 +84,7 @@ func get_block_signature*( proc verify_block_signature*( fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot, - blck: Eth2Digest | SomeBeaconBlock | BeaconBlockHeader, + blck: Eth2Digest | BeaconBlock | BeaconBlockHeader, pubkey: ValidatorPubKey, signature: SomeSig): bool = withTrust(signature): diff --git a/beacon_chain/spec/state_transition.nim b/beacon_chain/spec/state_transition.nim index be6b919e2..a25062155 100644 --- a/beacon_chain/spec/state_transition.nim +++ b/beacon_chain/spec/state_transition.nim @@ -30,7 +30,7 @@ import # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function proc verify_block_signature*( - state: BeaconState, signed_block: SomeSignedBeaconBlock): bool {.nbench.} = + state: BeaconState, signed_block: SignedBeaconBlock): bool {.nbench.} = let proposer_index = signed_block.message.proposer_index if proposer_index >= state.validators.lenu64: @@ -49,7 +49,7 @@ proc verify_block_signature*( true # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function -proc verifyStateRoot(state: BeaconState, blck: BeaconBlock): bool = +proc verifyStateRoot(state: BeaconState, blck: UntrustedBeaconBlock): bool = # This is inlined in state_transition(...) in spec. let state_root = hash_tree_root(state) if state_root != blck.state_root: @@ -125,7 +125,7 @@ proc process_slots*(state: var HashedBeaconState, slot: Slot, if slotProcessed notin updateFlags or state.data.slot != slot: notice( "Unusual request for a slot in the past", - state_root = shortLog(state.root), + state_root = state.root, current_slot = state.data.slot, target_slot = slot ) @@ -142,7 +142,7 @@ proc noRollback*(state: var HashedBeaconState) = proc state_transition*( preset: RuntimePreset, - state: var HashedBeaconState, signedBlock: SomeSignedBeaconBlock, + state: var HashedBeaconState, signedBlock: SignedBeaconBlock, stateCache: var StateCache, flags: UpdateFlags, rollback: RollbackHashedProc): bool {.nbench.} = ## Time in the beacon chain moves by slots. Every time (haha.) that happens, @@ -175,8 +175,8 @@ proc state_transition*( verify_block_signature(state.data, signedBlock): trace "state_transition: processing block, signature passed", - signature = shortLog(signedBlock.signature), - blockRoot = shortLog(signedBlock.root) + signature = signedBlock.signature, + blockRoot = signedBlock.root let res = process_block(preset, state.data, signedBlock.message, flags, stateCache) if res.isOk: if skipStateRootValidation in flags or verifyStateRoot(state.data, signedBlock.message): @@ -193,10 +193,10 @@ proc state_transition*( return true else: debug "state_transition: process_block failed", - blck = shortLog(signedBlock.message), + blck = signedBlock.message, slot = state.data.slot, eth1_deposit_index = state.data.eth1_deposit_index, - deposit_root = shortLog(state.data.eth1_data.deposit_root), + deposit_root = state.data.eth1_data.deposit_root, error = res.error # Block processing failed, roll back changes @@ -213,13 +213,13 @@ proc makeBeaconBlock*( randao_reveal: ValidatorSig, eth1_data: Eth1Data, graffiti: GraffitiBytes, - attestations: seq[Attestation], + attestations: seq[Attestation[Unchecked]], deposits: seq[Deposit], proposerSlashings: seq[ProposerSlashing], - attesterSlashings: seq[AttesterSlashing], + attesterSlashings: seq[AttesterSlashing[Unchecked]], voluntaryExits: seq[SignedVoluntaryExit], rollback: RollbackHashedProc, - cache: var StateCache): Option[BeaconBlock] = + cache: var StateCache): Option[BeaconBlock[Unchecked]] = ## Create a block for the given state. The last block applied to it must be ## the one identified by parent_root and process_slots must be called up to ## the slot for which a block is to be created. @@ -227,31 +227,35 @@ proc makeBeaconBlock*( # To create a block, we'll first apply a partial block to the state, skipping # some validations. - var blck = BeaconBlock( + # TODO: finish the code refactoring + # the result should be TransitionVerified + var blck = BeaconBlock[Unchecked]( slot: state.data.slot, proposer_index: proposer_index.uint64, parent_root: parent_root, - body: BeaconBlockBody( + body: BeaconBlockBody[Unchecked]( randao_reveal: randao_reveal, eth1_data: eth1data, graffiti: graffiti, proposer_slashings: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]( proposerSlashings), - attester_slashings: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]( + attester_slashings: List[AttesterSlashing[Unchecked], Limit MAX_ATTESTER_SLASHINGS]( attesterSlashings), - attestations: List[Attestation, Limit MAX_ATTESTATIONS](attestations), + attestations: List[Attestation[Unchecked], Limit MAX_ATTESTATIONS](attestations), deposits: List[Deposit, Limit MAX_DEPOSITS](deposits), voluntary_exits: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS](voluntaryExits))) - let res = process_block(preset, state.data, blck, {skipBlsValidation}, cache) + let res = process_block( + preset, state.data, blck, + {skipBlsValidation}, cache) if res.isErr: warn "Unable to apply new block to state", - blck = shortLog(blck), + blck = blck, slot = state.data.slot, eth1_deposit_index = state.data.eth1_deposit_index, - deposit_root = shortLog(state.data.eth1_data.deposit_root), + deposit_root = state.data.eth1_data.deposit_root, error = res.error rollback(state) return diff --git a/beacon_chain/spec/state_transition_block.nim b/beacon_chain/spec/state_transition_block.nim index 972484f2d..b198f074d 100644 --- a/beacon_chain/spec/state_transition_block.nim +++ b/beacon_chain/spec/state_transition_block.nim @@ -27,9 +27,11 @@ import ./signatures, ./presets, ../../nbench/bench_lab +export sets # Generics visibility issue with toSeq(items(intersection(HashSet, HashSet))) + # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#block-header func process_block_header*( - state: var BeaconState, blck: SomeBeaconBlock, flags: UpdateFlags, + state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags, stateCache: var StateCache): Result[void, cstring] {.nbench.} = # Verify that the slots match if not (blck.slot == state.slot): @@ -72,7 +74,7 @@ func `xor`[T: array](a, b: T): T = # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#randao proc process_randao( - state: var BeaconState, body: SomeBeaconBlockBody, flags: UpdateFlags, + state: var BeaconState, body: BeaconBlockBody, flags: UpdateFlags, stateCache: var StateCache): bool {.nbench.} = let proposer_index = get_beacon_proposer_index(state, stateCache) @@ -108,7 +110,7 @@ proc process_randao( true # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#eth1-data -func process_eth1_data(state: var BeaconState, body: SomeBeaconBlockBody) {.nbench.}= +func process_eth1_data(state: var BeaconState, body: BeaconBlockBody) {.nbench.}= state.eth1_data_votes.add body.eth1_data if state.eth1_data_votes.asSeq.count(body.eth1_data).uint64 * 2 > @@ -189,9 +191,9 @@ func is_slashable_attestation_data*( data_2.target.epoch < data_1.target.epoch) # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#attester-slashings -proc check_attester_slashing*( +proc check_attester_slashing*[Trust]( state: var BeaconState, - attester_slashing: AttesterSlashing, + attester_slashing: AttesterSlashing[Trust], flags: UpdateFlags ): Result[seq[ValidatorIndex], cstring] {.nbench.} = let @@ -210,6 +212,8 @@ proc check_attester_slashing*( var slashed_indices: seq[ValidatorIndex] + # export sets otherwise + # generics visibility issue with toSeq(items(intersection(HashSet, HashSet))) for index in sorted(toSeq(intersection( toHashSet(attestation_1.attesting_indices.asSeq), toHashSet(attestation_2.attesting_indices.asSeq)).items), system.cmp): @@ -305,7 +309,7 @@ proc process_voluntary_exit*( # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#operations proc process_operations(preset: RuntimePreset, state: var BeaconState, - body: SomeBeaconBlockBody, + body: BeaconBlockBody, flags: UpdateFlags, cache: var StateCache): Result[void, cstring] {.nbench.} = # Verify that outstanding deposits are processed up to the maximum number of @@ -339,7 +343,7 @@ proc process_operations(preset: RuntimePreset, # https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#block-processing proc process_block*( preset: RuntimePreset, - state: var BeaconState, blck: SomeBeaconBlock, flags: UpdateFlags, + state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags, stateCache: var StateCache): Result[void, cstring] {.nbench.}= ## When there's a new block, we need to verify that the block is sane and ## update the state accordingly - the state is left in an unknown state when