collect signature production and verificaiton in one place (#1179)
* collect signature production and verificaiton in one place Signatures are made over data and domain - here we collect all such activities in one place. Also: * security: fix cast-before-range-check * log block/attestation verification consistently * run block verification based on `getProposer` in its own history * clean up some unused stuff * import * missing raises
This commit is contained in:
parent
9335533503
commit
89e4819ce9
|
@ -9,10 +9,13 @@
|
|||
|
||||
import
|
||||
options, chronicles,
|
||||
./spec/[beaconstate, datatypes, crypto, digest, helpers, validator,
|
||||
state_transition_block],
|
||||
./spec/[
|
||||
beaconstate, datatypes, crypto, digest, helpers, validator, signatures],
|
||||
./block_pool, ./attestation_pool, ./beacon_node_types, ./ssz
|
||||
|
||||
logScope:
|
||||
topics = "att_aggr"
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregation-selection
|
||||
func is_aggregator(state: BeaconState, slot: Slot, index: CommitteeIndex,
|
||||
slot_signature: ValidatorSig): bool =
|
||||
|
@ -75,17 +78,20 @@ proc aggregate_attestations*(
|
|||
proc isValidAttestation*(
|
||||
pool: AttestationPool, attestation: Attestation, current_slot: Slot,
|
||||
topicCommitteeIndex: uint64): bool =
|
||||
logScope:
|
||||
topics = "att_aggr valid_att"
|
||||
received_attestation = shortLog(attestation)
|
||||
|
||||
# The attestation's committee index (attestation.data.index) is for the
|
||||
# correct subnet.
|
||||
if attestation.data.index != topicCommitteeIndex:
|
||||
debug "isValidAttestation: attestation's committee index not for the correct subnet",
|
||||
topicCommitteeIndex = topicCommitteeIndex,
|
||||
attestation_data_index = attestation.data.index
|
||||
debug "attestation's committee index not for the correct subnet",
|
||||
topicCommitteeIndex = topicCommitteeIndex
|
||||
return false
|
||||
|
||||
if not (attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >=
|
||||
current_slot and current_slot >= attestation.data.slot):
|
||||
debug "isValidAttestation: attestation.data.slot not within ATTESTATION_PROPAGATION_SLOT_RANGE"
|
||||
debug "attestation.data.slot not within ATTESTATION_PROPAGATION_SLOT_RANGE"
|
||||
return false
|
||||
|
||||
# The attestation is unaggregated -- that is, it has exactly one
|
||||
|
@ -100,11 +106,10 @@ proc isValidAttestation*(
|
|||
continue
|
||||
onesCount += 1
|
||||
if onesCount > 1:
|
||||
debug "isValidAttestation: attestation has too many aggregation bits",
|
||||
aggregation_bits = attestation.aggregation_bits
|
||||
debug "attestation has too many aggregation bits"
|
||||
return false
|
||||
if onesCount != 1:
|
||||
debug "isValidAttestation: attestation has too few aggregation bits"
|
||||
debug "attestation has too few aggregation bits"
|
||||
return false
|
||||
|
||||
# The attestation is the first valid attestation received for the
|
||||
|
@ -117,9 +122,7 @@ proc isValidAttestation*(
|
|||
# Attestations might be aggregated eagerly or lazily; allow for both.
|
||||
for validation in attestationEntry.validations:
|
||||
if attestation.aggregation_bits.isSubsetOf(validation.aggregation_bits):
|
||||
debug "isValidAttestation: attestation already exists at slot",
|
||||
attestation_data_slot = attestation.data.slot,
|
||||
attestation_aggregation_bits = attestation.aggregation_bits,
|
||||
debug "attestation already exists at slot",
|
||||
attestation_pool_validation = validation.aggregation_bits
|
||||
return false
|
||||
|
||||
|
@ -131,8 +134,7 @@ proc isValidAttestation*(
|
|||
# propagated - i.e. imagine that attestations are smaller than blocks and
|
||||
# therefore propagate faster, thus reordering their arrival in some nodes
|
||||
if pool.blockPool.get(attestation.data.beacon_block_root).isNone():
|
||||
debug "isValidAttestation: block doesn't exist in block pool",
|
||||
attestation_data_beacon_block_root = attestation.data.beacon_block_root
|
||||
debug "block doesn't exist in block pool"
|
||||
return false
|
||||
|
||||
# The signature of attestation is valid.
|
||||
|
@ -143,7 +145,7 @@ proc isValidAttestation*(
|
|||
pool.blockPool.headState.data.data,
|
||||
get_indexed_attestation(
|
||||
pool.blockPool.headState.data.data, attestation, cache), {}):
|
||||
debug "isValidAttestation: signature verification failed"
|
||||
debug "signature verification failed"
|
||||
return false
|
||||
|
||||
true
|
||||
|
|
|
@ -5,12 +5,13 @@
|
|||
# * 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: [Defect].}
|
||||
|
||||
import
|
||||
chronicles, sequtils, tables,
|
||||
metrics, stew/results,
|
||||
../ssz/merkleization, ../state_transition, ../extras,
|
||||
../spec/[crypto, datatypes, digest, helpers],
|
||||
|
||||
../spec/[crypto, datatypes, digest, helpers, signatures],
|
||||
block_pools_types, candidate_chains
|
||||
|
||||
export results
|
||||
|
@ -22,8 +23,8 @@ export results
|
|||
# "quarantined" network blocks
|
||||
# pass the firewall and be stored in the blockpool
|
||||
|
||||
logScope: topics = "clearblk"
|
||||
{.push raises: [Defect].}
|
||||
logScope:
|
||||
topics = "clearance"
|
||||
|
||||
func getOrResolve*(dag: CandidateChains, quarantine: var Quarantine, root: Eth2Digest): BlockRef =
|
||||
## Fetch a block ref, or nil if not found (will be added to list of
|
||||
|
@ -259,6 +260,10 @@ proc isValidBeaconBlock*(
|
|||
dag: CandidateChains, quarantine: var Quarantine,
|
||||
signed_beacon_block: SignedBeaconBlock, current_slot: Slot,
|
||||
flags: UpdateFlags): bool =
|
||||
logScope:
|
||||
topics = "clearance valid_blck"
|
||||
received_block = shortLog(signed_beacon_block.message)
|
||||
|
||||
# In general, checks are ordered from cheap to expensive. Especially, crypto
|
||||
# verification could be quite a bit more expensive than the rest. This is an
|
||||
# externally easy-to-invoke function by tossing network packets at the node.
|
||||
|
@ -269,9 +274,8 @@ proc isValidBeaconBlock*(
|
|||
# TODO using +1 here while this is being sorted - should queue these until
|
||||
# they're within the DISPARITY limit
|
||||
if not (signed_beacon_block.message.slot <= current_slot + 1):
|
||||
debug "isValidBeaconBlock: block is from a future slot",
|
||||
signed_beacon_block_message_slot = signed_beacon_block.message.slot,
|
||||
current_slot = current_slot
|
||||
debug "block is from a future slot",
|
||||
current_slot
|
||||
return false
|
||||
|
||||
# The block is from a slot greater than the latest finalized slot (with a
|
||||
|
@ -279,7 +283,7 @@ proc isValidBeaconBlock*(
|
|||
# signed_beacon_block.message.slot >
|
||||
# compute_start_slot_at_epoch(state.finalized_checkpoint.epoch)
|
||||
if not (signed_beacon_block.message.slot > dag.finalizedHead.slot):
|
||||
debug "isValidBeaconBlock: block is not from a slot greater than the latest finalized slot"
|
||||
debug "block is not from a slot greater than the latest finalized slot"
|
||||
return false
|
||||
|
||||
# The block is the first block with valid signature received for the proposer
|
||||
|
@ -317,11 +321,9 @@ proc isValidBeaconBlock*(
|
|||
signed_beacon_block.message.proposer_index and
|
||||
blck.message.slot == signed_beacon_block.message.slot and
|
||||
blck.signature.toRaw() != signed_beacon_block.signature.toRaw():
|
||||
debug "isValidBeaconBlock: block isn't first block with valid signature received for the proposer",
|
||||
signed_beacon_block_message_slot = signed_beacon_block.message.slot,
|
||||
debug "block isn't first block with valid signature received for the proposer",
|
||||
blckRef = slotBlockRef,
|
||||
received_block = shortLog(signed_beacon_block.message),
|
||||
existing_block = shortLog(dag.get(slotBlockRef).data.message)
|
||||
existing_block = shortLog(blck.message)
|
||||
return false
|
||||
|
||||
# If this block doesn't have a parent we know about, we can't/don't really
|
||||
|
@ -342,27 +344,36 @@ proc isValidBeaconBlock*(
|
|||
# CandidateChains.add(...) directly, with no additional validity checks. TODO,
|
||||
# not specific to this, but by the pending dag keying on the htr of the
|
||||
# BeaconBlock, not SignedBeaconBlock, opens up certain spoofing attacks.
|
||||
debug "parent unknown, putting block in quarantine"
|
||||
quarantine.pending[hash_tree_root(signed_beacon_block.message)] =
|
||||
signed_beacon_block
|
||||
return false
|
||||
|
||||
# The proposer signature, signed_beacon_block.signature, is valid with
|
||||
# respect to the proposer_index pubkey.
|
||||
let bs =
|
||||
BlockSlot(blck: parent_ref, slot: dag.get(parent_ref).data.message.slot)
|
||||
dag.withState(dag.tmpState, bs):
|
||||
let
|
||||
blockRoot = hash_tree_root(signed_beacon_block.message)
|
||||
domain = get_domain(dag.headState.data.data, DOMAIN_BEACON_PROPOSER,
|
||||
compute_epoch_at_slot(signed_beacon_block.message.slot))
|
||||
signing_root = compute_signing_root(blockRoot, domain)
|
||||
proposer_index = signed_beacon_block.message.proposer_index
|
||||
let
|
||||
proposer = getProposer(dag, parent_ref, signed_beacon_block.message.slot)
|
||||
|
||||
if proposer_index >= dag.headState.data.data.validators.len.uint64:
|
||||
return false
|
||||
if not blsVerify(dag.headState.data.data.validators[proposer_index].pubkey,
|
||||
signing_root.data, signed_beacon_block.signature):
|
||||
debug "isValidBeaconBlock: block failed signature verification"
|
||||
return false
|
||||
if proposer.isNone:
|
||||
notice "cannot compute proposer for message"
|
||||
return false
|
||||
|
||||
if proposer.get()[0] !=
|
||||
ValidatorIndex(signed_beacon_block.message.proposer_index):
|
||||
debug "block had unexpected proposer",
|
||||
expected_proposer = proposer.get()[0]
|
||||
return false
|
||||
|
||||
if not verify_block_signature(
|
||||
dag.headState.data.data.fork,
|
||||
dag.headState.data.data.genesis_validators_root,
|
||||
signed_beacon_block.message.slot,
|
||||
signed_beacon_block.message,
|
||||
proposer.get()[1],
|
||||
signed_beacon_block.signature):
|
||||
debug "block failed signature verification",
|
||||
signature = shortLog(signed_beacon_block.signature)
|
||||
|
||||
return false
|
||||
|
||||
true
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import
|
||||
stew/endians2, stint,
|
||||
./extras, ./ssz/merkleization,
|
||||
spec/[crypto, datatypes, digest, helpers, keystore]
|
||||
spec/[crypto, datatypes, digest, keystore, signatures]
|
||||
|
||||
func get_eth1data_stub*(deposit_count: uint64, current_epoch: Epoch): Eth1Data =
|
||||
# https://github.com/ethereum/eth2.0-pm/blob/e596c70a19e22c7def4fd3519e20ae4022349390/interop/mocked_eth1data/README.md
|
||||
|
@ -47,9 +47,6 @@ func makeDeposit*(
|
|||
withdrawal_credentials: makeWithdrawalCredentials(pubkey)))
|
||||
|
||||
if skipBLSValidation notin flags:
|
||||
let domain = compute_domain(DOMAIN_DEPOSIT)
|
||||
let signing_root = compute_signing_root(ret.getDepositMessage, domain)
|
||||
|
||||
ret.data.signature = bls_sign(privkey, signing_root.data)
|
||||
ret.data.signature = get_deposit_signature(ret.data, privkey)
|
||||
|
||||
ret
|
||||
|
|
|
@ -11,7 +11,7 @@ import
|
|||
tables, algorithm, math, sequtils, options,
|
||||
json_serialization/std/sets, chronicles,
|
||||
../extras, ../ssz/merkleization,
|
||||
./crypto, ./datatypes, ./digest, ./helpers, ./validator,
|
||||
./crypto, ./datatypes, ./digest, ./helpers, ./signatures, ./validator,
|
||||
../../nbench/bench_lab
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.3/specs/phase0/beacon-chain.md#is_valid_merkle_branch
|
||||
|
@ -79,19 +79,13 @@ proc process_deposit*(
|
|||
if index == -1:
|
||||
# Verify the deposit signature (proof of possession) which is not checked
|
||||
# by the deposit contract
|
||||
|
||||
# Fork-agnostic domain since deposits are valid across forks
|
||||
let domain = compute_domain(DOMAIN_DEPOSIT)
|
||||
|
||||
let signing_root = compute_signing_root(deposit.getDepositMessage, domain)
|
||||
if skipBLSValidation notin flags and not bls_verify(
|
||||
pubkey, signing_root.data,
|
||||
deposit.data.signature):
|
||||
# It's ok that deposits fail - they get included in blocks regardless
|
||||
# TODO spec test?
|
||||
debug "Skipping deposit with invalid signature",
|
||||
pubkey, signing_root, signature = deposit.data.signature
|
||||
return true
|
||||
if skipBLSValidation notin flags:
|
||||
if not verify_deposit_signature(deposit.data):
|
||||
# It's ok that deposits fail - they get included in blocks regardless
|
||||
# TODO spec test?
|
||||
debug "Skipping deposit with invalid signature",
|
||||
deposit = shortLog(deposit.data)
|
||||
return true
|
||||
|
||||
# Add validator and balance entries
|
||||
state.validators.add(Validator(
|
||||
|
@ -418,15 +412,14 @@ proc is_valid_indexed_attestation*(
|
|||
return false
|
||||
|
||||
# Verify aggregate signature
|
||||
let pubkeys = mapIt(indices, state.validators[it.int].pubkey) # TODO: fuse loops with blsFastAggregateVerify
|
||||
let domain = state.get_domain(DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch)
|
||||
let signing_root = compute_signing_root(indexed_attestation.data, domain)
|
||||
if skipBLSValidation notin flags and
|
||||
not blsFastAggregateVerify(
|
||||
pubkeys, signing_root.data, indexed_attestation.signature
|
||||
):
|
||||
notice "indexed attestation: signature verification failure"
|
||||
return false
|
||||
if skipBLSValidation notin flags:
|
||||
# TODO: fuse loops with blsFastAggregateVerify
|
||||
let pubkeys = mapIt(indices, state.validators[it.int].pubkey)
|
||||
if not verify_attestation_signature(
|
||||
state.fork, state.genesis_validators_root, indexed_attestation.data,
|
||||
pubkeys, indexed_attestation.signature):
|
||||
notice "indexed attestation: signature verification failure"
|
||||
return false
|
||||
|
||||
true
|
||||
|
||||
|
|
|
@ -99,16 +99,6 @@ func toPubKey*(privkey: ValidatorPrivKey): ValidatorPubKey =
|
|||
else:
|
||||
privkey.getKey
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.3/specs/phase0/beacon-chain.md#bls-signatures
|
||||
func aggregate*[T](values: openarray[ValidatorSig]): ValidatorSig =
|
||||
## Aggregate arrays of sequences of Validator Signatures
|
||||
## This assumes that they are real signatures
|
||||
|
||||
result = BlsValue[T](kind: Real, blsValue: values[0].BlsValue)
|
||||
|
||||
for i in 1 ..< values.len:
|
||||
result.blsValue.aggregate(values[i].blsValue)
|
||||
|
||||
func aggregate*(x: var ValidatorSig, other: ValidatorSig) =
|
||||
## Aggregate 2 Validator Signatures
|
||||
## This assumes that they are real signatures
|
||||
|
@ -143,13 +133,13 @@ func blsVerify*(
|
|||
# return true
|
||||
pubkey.blsValue.verify(message, signature.blsValue)
|
||||
|
||||
func blsSign*(privkey: ValidatorPrivKey, message: openarray[byte]): ValidatorSig =
|
||||
func blsSign*(privkey: ValidatorPrivKey, message: openArray[byte]): ValidatorSig =
|
||||
## Computes a signature from a secret key and a message
|
||||
ValidatorSig(kind: Real, blsValue: SecretKey(privkey).sign(message))
|
||||
|
||||
func blsFastAggregateVerify*[T: byte|char](
|
||||
publicKeys: openarray[ValidatorPubKey],
|
||||
message: openarray[T],
|
||||
func blsFastAggregateVerify*(
|
||||
publicKeys: openArray[ValidatorPubKey],
|
||||
message: openArray[byte],
|
||||
signature: ValidatorSig
|
||||
): bool =
|
||||
## Verify the aggregate of multiple signatures on the same message
|
||||
|
@ -177,7 +167,8 @@ func blsFastAggregateVerify*[T: byte|char](
|
|||
if pubkey.kind != Real:
|
||||
return false
|
||||
unwrapped.add pubkey.blsValue
|
||||
return fastAggregateVerify(unwrapped, message, signature.blsValue)
|
||||
|
||||
fastAggregateVerify(unwrapped, message, signature.blsValue)
|
||||
|
||||
proc newKeyPair*(): BlsResult[tuple[pub: ValidatorPubKey, priv: ValidatorPrivKey]] =
|
||||
## Generates a new public-private keypair
|
||||
|
@ -230,14 +221,14 @@ func toRaw*(x: BlsValue): auto =
|
|||
func toHex*(x: BlsCurveType): string =
|
||||
toHex(toRaw(x))
|
||||
|
||||
func fromRaw*(T: type ValidatorPrivKey, bytes: openarray[byte]): BlsResult[T] =
|
||||
func fromRaw*(T: type ValidatorPrivKey, bytes: openArray[byte]): BlsResult[T] =
|
||||
var val: SecretKey
|
||||
if val.fromBytes(bytes):
|
||||
ok ValidatorPrivKey(val)
|
||||
else:
|
||||
err "bls: invalid private key"
|
||||
|
||||
func fromRaw*[N, T](BT: type BlsValue[N, T], bytes: openarray[byte]): BlsResult[BT] =
|
||||
func fromRaw*[N, T](BT: type BlsValue[N, T], bytes: openArray[byte]): BlsResult[BT] =
|
||||
# This is a workaround, so that we can deserialize the serialization of a
|
||||
# default-initialized BlsValue without raising an exception
|
||||
when defined(ssz_testing):
|
||||
|
@ -294,7 +285,7 @@ proc readValue*(reader: var JsonReader, value: var ValidatorPrivKey) {.
|
|||
inline, raises: [Exception].} =
|
||||
value = ValidatorPrivKey.fromHex(reader.readValue(string)).tryGet()
|
||||
|
||||
template fromSszBytes*(T: type BlsValue, bytes: openarray[byte]): auto =
|
||||
template fromSszBytes*(T: type BlsValue, bytes: openArray[byte]): auto =
|
||||
let v = fromRaw(T, bytes)
|
||||
if v.isErr:
|
||||
raise newException(MalformedSszError, $v.error)
|
||||
|
@ -350,10 +341,9 @@ proc getRandomBytes*(n: Natural): seq[byte]
|
|||
if randomBytes(result) != result.len:
|
||||
raise newException(RandomSourceDepleted, "Failed to generate random bytes")
|
||||
|
||||
proc getRandomBytesOrPanic*(output: var openarray[byte]) =
|
||||
proc getRandomBytesOrPanic*(output: var openArray[byte]) =
|
||||
doAssert randomBytes(output) == output.len
|
||||
|
||||
proc getRandomBytesOrPanic*(n: Natural): seq[byte] =
|
||||
result = newSeq[byte](n)
|
||||
getRandomBytesOrPanic(result)
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ type
|
|||
DepositData* = object
|
||||
pubkey*: ValidatorPubKey
|
||||
withdrawal_credentials*: Eth2Digest
|
||||
amount*: uint64
|
||||
amount*: Gwei
|
||||
signature*: ValidatorSig # Signing over DepositMessage
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.3/specs/phase0/beacon-chain.md#voluntaryexit
|
||||
|
@ -622,6 +622,14 @@ func shortLog*(v: SignedBeaconBlock): auto =
|
|||
signature: shortLog(v.signature)
|
||||
)
|
||||
|
||||
func shortLog*(v: DepositData): auto =
|
||||
(
|
||||
pubkey: shortLog(v.pubkey),
|
||||
withdrawal_credentials: shortlog(v.withdrawal_credentials),
|
||||
amount: v.amount,
|
||||
signature: shortLog(v.signature)
|
||||
)
|
||||
|
||||
func shortLog*(v: AttestationData): auto =
|
||||
(
|
||||
slot: shortLog(v.slot),
|
||||
|
|
|
@ -10,7 +10,7 @@ import
|
|||
stew/[results, byteutils, bitseqs, bitops2], stew/shims/macros,
|
||||
eth/keyfile/uuid, blscurve,
|
||||
nimcrypto/[sha2, rijndael, pbkdf2, bcmode, hash, sysrand],
|
||||
datatypes, crypto, digest, helpers
|
||||
./datatypes, ./crypto, ./digest, ./signatures
|
||||
|
||||
export
|
||||
results
|
||||
|
@ -396,9 +396,6 @@ proc prepareDeposit*(credentials: Credentials,
|
|||
pubkey: signingPubKey,
|
||||
withdrawal_credentials: makeWithdrawalCredentials(withdrawalPubKey)))
|
||||
|
||||
let domain = compute_domain(DOMAIN_DEPOSIT)
|
||||
let signing_root = compute_signing_root(ret.getDepositMessage, domain)
|
||||
ret.data.signature = get_deposit_signature(ret.data, credentials.signingKey)
|
||||
|
||||
ret.data.signature = bls_sign(credentials.signingKey, signing_root.data)
|
||||
ret
|
||||
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2018-2020 Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
import
|
||||
./crypto, ./digest, ./datatypes, ./helpers, ../ssz/merkleization
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#aggregation-selection
|
||||
func get_slot_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
epoch = compute_epoch_at_slot(slot)
|
||||
domain = get_domain(
|
||||
fork, DOMAIN_SELECTION_PROOF, epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(slot, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#randao-reveal
|
||||
func get_epoch_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, epoch: Epoch,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
domain = get_domain(fork, DOMAIN_RANDAO, epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(epoch, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
func verify_epoch_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, epoch: Epoch,
|
||||
pubkey: ValidatorPubKey, signature: ValidatorSig): bool =
|
||||
let
|
||||
domain = get_domain(fork, DOMAIN_RANDAO, epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(epoch, domain)
|
||||
|
||||
blsVerify(pubkey, signing_root.data, signature)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#signature
|
||||
func get_block_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot,
|
||||
root: Eth2Digest, privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
epoch = compute_epoch_at_slot(slot)
|
||||
domain = get_domain(
|
||||
fork, DOMAIN_BEACON_PROPOSER, epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(root, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
func verify_block_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot,
|
||||
blck: Eth2Digest | BeaconBlock | BeaconBlockHeader, pubkey: ValidatorPubKey,
|
||||
signature: ValidatorSig): bool =
|
||||
let
|
||||
epoch = compute_epoch_at_slot(slot)
|
||||
domain = get_domain(
|
||||
fork, DOMAIN_BEACON_PROPOSER, epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(blck, domain)
|
||||
|
||||
blsVerify(pubKey, signing_root.data, signature)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#broadcast-aggregate
|
||||
func get_aggregate_and_proof_signature*(fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
aggregate_and_proof: AggregateAndProof,
|
||||
privKey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
epoch = compute_epoch_at_slot(aggregate_and_proof.aggregate.data.slot)
|
||||
domain = get_domain(
|
||||
fork, DOMAIN_AGGREGATE_AND_PROOF, epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(aggregate_and_proof, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#aggregate-signature
|
||||
func get_attestation_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
attestation_data: AttestationData,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
epoch = attestation_data.target.epoch
|
||||
domain = get_domain(
|
||||
fork, DOMAIN_BEACON_ATTESTER, epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(attestation_data, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
func verify_attestation_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
attestation_data: AttestationData,
|
||||
pubkeys: openArray[ValidatorPubKey],
|
||||
signature: ValidatorSig): bool =
|
||||
let
|
||||
epoch = attestation_data.target.epoch
|
||||
domain = get_domain(
|
||||
fork, DOMAIN_BEACON_ATTESTER, epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(attestation_data, domain)
|
||||
|
||||
blsFastAggregateVerify(pubkeys, signing_root.data, signature)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#deposits
|
||||
func get_deposit_signature*(
|
||||
deposit: DepositData,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
|
||||
let
|
||||
deposit_message = deposit.getDepositMessage()
|
||||
# Fork-agnostic domain since deposits are valid across forks
|
||||
domain = compute_domain(DOMAIN_DEPOSIT)
|
||||
signing_root = compute_signing_root(deposit_message, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
func verify_deposit_signature*(deposit: DepositData): bool =
|
||||
let
|
||||
deposit_message = deposit.getDepositMessage()
|
||||
# Fork-agnostic domain since deposits are valid across forks
|
||||
domain = compute_domain(DOMAIN_DEPOSIT)
|
||||
signing_root = compute_signing_root(deposit_message, domain)
|
||||
|
||||
blsVerify(deposit.pubkey, signing_root.data, deposit.signature)
|
||||
|
||||
func verify_voluntary_exit_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
voluntary_exit: VoluntaryExit,
|
||||
pubkey: ValidatorPubKey, signature: ValidatorSig): bool =
|
||||
let
|
||||
domain = get_domain(
|
||||
fork, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(voluntary_exit, domain)
|
||||
|
||||
blsVerify(pubkey, signing_root.data, signature)
|
|
@ -32,7 +32,8 @@
|
|||
import
|
||||
algorithm, collections/sets, chronicles, options, sequtils, sets,
|
||||
../extras, ../ssz/merkleization, metrics,
|
||||
beaconstate, crypto, datatypes, digest, helpers, validator,
|
||||
./beaconstate, ./crypto, ./datatypes, ./digest, ./helpers, ./validator,
|
||||
./signatures,
|
||||
../../nbench/bench_lab
|
||||
|
||||
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#additional-metrics
|
||||
|
@ -104,7 +105,6 @@ proc process_randao(
|
|||
state: var BeaconState, body: BeaconBlockBody, flags: UpdateFlags,
|
||||
stateCache: var StateCache): bool {.nbench.}=
|
||||
let
|
||||
epoch = state.get_current_epoch()
|
||||
proposer_index = get_beacon_proposer_index(state, stateCache)
|
||||
|
||||
if proposer_index.isNone:
|
||||
|
@ -112,14 +112,17 @@ proc process_randao(
|
|||
return false
|
||||
|
||||
# Verify RANDAO reveal
|
||||
let proposer = addr state.validators[proposer_index.get]
|
||||
let
|
||||
epoch = state.get_current_epoch()
|
||||
|
||||
let signing_root = compute_signing_root(
|
||||
epoch, get_domain(state, DOMAIN_RANDAO, get_current_epoch(state)))
|
||||
if skipBLSValidation notin flags:
|
||||
if not blsVerify(proposer.pubkey, signing_root.data, body.randao_reveal):
|
||||
notice "Randao mismatch", proposer_pubkey = shortLog(proposer.pubkey),
|
||||
message = epoch,
|
||||
let proposer_pubkey = state.validators[proposer_index.get].pubkey
|
||||
|
||||
if not verify_epoch_signature(
|
||||
state.fork, state.genesis_validators_root, epoch, proposer_pubkey,
|
||||
body.randao_reveal):
|
||||
notice "Randao mismatch", proposer_pubkey = shortLog(proposer_pubkey),
|
||||
epoch,
|
||||
signature = shortLog(body.randao_reveal),
|
||||
slot = state.slot
|
||||
return false
|
||||
|
@ -187,12 +190,9 @@ proc process_proposer_slashing*(
|
|||
if skipBlsValidation notin flags:
|
||||
for i, signed_header in [proposer_slashing.signed_header_1,
|
||||
proposer_slashing.signed_header_2]:
|
||||
let domain = get_domain(
|
||||
state, DOMAIN_BEACON_PROPOSER,
|
||||
compute_epoch_at_slot(signed_header.message.slot)
|
||||
)
|
||||
let signing_root = compute_signing_root(signed_header.message, domain)
|
||||
if not blsVerify(proposer.pubkey, signing_root.data, signed_header.signature):
|
||||
if not verify_block_signature(
|
||||
state.fork, state.genesis_validators_root, signed_header.message.slot,
|
||||
signed_header.message, proposer.pubkey, signed_header.signature):
|
||||
notice "Proposer slashing: invalid signature",
|
||||
signature_index = i
|
||||
return false
|
||||
|
@ -260,7 +260,7 @@ proc process_voluntary_exit*(
|
|||
let voluntary_exit = signed_voluntary_exit.message
|
||||
|
||||
# Not in spec. Check that validator_index is in range
|
||||
if voluntary_exit.validator_index.int >= state.validators.len:
|
||||
if voluntary_exit.validator_index >= state.validators.len.uint64:
|
||||
notice "Exit: invalid validator index",
|
||||
index = voluntary_exit.validator_index,
|
||||
num_validators = state.validators.len
|
||||
|
@ -298,9 +298,9 @@ proc process_voluntary_exit*(
|
|||
|
||||
# Verify signature
|
||||
if skipBlsValidation notin flags:
|
||||
let domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
|
||||
let signing_root = compute_signing_root(voluntary_exit, domain)
|
||||
if not bls_verify(validator.pubkey, signing_root.data, signed_voluntary_exit.signature):
|
||||
if not verify_voluntary_exit_signature(
|
||||
state.fork, state.genesis_validators_root, voluntary_exit,
|
||||
validator.pubkey, signed_voluntary_exit.signature):
|
||||
notice "Exit: invalid signature"
|
||||
return false
|
||||
|
||||
|
@ -393,61 +393,3 @@ proc process_block*(
|
|||
return false
|
||||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregation-selection
|
||||
func get_slot_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
domain = get_domain(fork, DOMAIN_SELECTION_PROOF,
|
||||
compute_epoch_at_slot(slot), genesis_validators_root)
|
||||
signing_root = compute_signing_root(slot, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#randao-reveal
|
||||
func get_epoch_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
domain = get_domain(fork, DOMAIN_RANDAO, compute_epoch_at_slot(slot),
|
||||
genesis_validators_root)
|
||||
signing_root = compute_signing_root(compute_epoch_at_slot(slot), domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#signature
|
||||
func get_block_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, slot: Slot,
|
||||
root: Eth2Digest, privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
domain = get_domain(fork, DOMAIN_BEACON_PROPOSER,
|
||||
compute_epoch_at_slot(slot), genesis_validators_root)
|
||||
signing_root = compute_signing_root(root, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#broadcast-aggregate
|
||||
func get_aggregate_and_proof_signature*(fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
aggregate_and_proof: AggregateAndProof,
|
||||
privKey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
aggregate = aggregate_and_proof.aggregate
|
||||
domain = get_domain(fork, DOMAIN_AGGREGATE_AND_PROOF,
|
||||
compute_epoch_at_slot(aggregate.data.slot),
|
||||
genesis_validators_root)
|
||||
signing_root = compute_signing_root(aggregate_and_proof, domain)
|
||||
|
||||
return blsSign(privKey, signing_root.data)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#aggregate-signature
|
||||
func get_attestation_signature*(
|
||||
fork: Fork, genesis_validators_root: Eth2Digest, attestation: AttestationData,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
attestationRoot = hash_tree_root(attestation)
|
||||
domain = get_domain(fork, DOMAIN_BEACON_ATTESTER,
|
||||
attestation.target.epoch, genesis_validators_root)
|
||||
signing_root = compute_signing_root(attestationRoot, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
|
|
@ -32,7 +32,7 @@ import
|
|||
chronicles,
|
||||
stew/results,
|
||||
./extras, ./ssz/merkleization, metrics,
|
||||
./spec/[datatypes, crypto, digest, helpers, validator],
|
||||
./spec/[datatypes, crypto, digest, helpers, signatures, validator],
|
||||
./spec/[state_transition_block, state_transition_epoch],
|
||||
../nbench/bench_lab
|
||||
|
||||
|
@ -64,23 +64,20 @@ func get_epoch_validator_count(state: BeaconState): int64 {.nbench.} =
|
|||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function
|
||||
proc verify_block_signature*(
|
||||
state: BeaconState, signedBlock: SignedBeaconBlock): bool {.nbench.} =
|
||||
if signedBlock.message.proposer_index >= state.validators.len.uint64:
|
||||
state: BeaconState, signed_block: SignedBeaconBlock): bool {.nbench.} =
|
||||
let
|
||||
proposer_index = signed_block.message.proposer_index
|
||||
if proposer_index >= state.validators.len.uint64:
|
||||
notice "Invalid proposer index in block",
|
||||
blck = shortLog(signedBlock.message)
|
||||
blck = shortLog(signed_block.message)
|
||||
return false
|
||||
|
||||
let
|
||||
proposer = state.validators[signedBlock.message.proposer_index]
|
||||
domain = get_domain(
|
||||
state, DOMAIN_BEACON_PROPOSER,
|
||||
compute_epoch_at_slot(signedBlock.message.slot))
|
||||
signing_root = compute_signing_root(signedBlock.message, domain)
|
||||
|
||||
if not bls_verify(proposer.pubKey, signing_root.data, signedBlock.signature):
|
||||
if not verify_block_signature(
|
||||
state.fork, state.genesis_validators_root, signed_block.message.slot,
|
||||
signed_block.message, state.validators[proposer_index].pubkey,
|
||||
signed_block.signature):
|
||||
notice "Block: signature verification failed",
|
||||
blck = shortLog(signedBlock),
|
||||
signingRoot = shortLog(signing_root)
|
||||
blck = shortLog(signedBlock)
|
||||
return false
|
||||
|
||||
true
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import
|
||||
tables,
|
||||
chronos, chronicles,
|
||||
spec/[datatypes, crypto, digest, state_transition_block],
|
||||
spec/[datatypes, crypto, digest, signatures, helpers],
|
||||
beacon_node_types
|
||||
|
||||
func init*(T: type ValidatorPool): T =
|
||||
|
@ -83,7 +83,8 @@ proc signAggregateAndProof*(v: AttachedValidator,
|
|||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#randao-reveal
|
||||
func genRandaoReveal*(k: ValidatorPrivKey, fork: Fork,
|
||||
genesis_validators_root: Eth2Digest, slot: Slot): ValidatorSig =
|
||||
get_epoch_signature(fork, genesis_validators_root, slot, k)
|
||||
get_epoch_signature(
|
||||
fork, genesis_validators_root, slot.compute_epoch_at_slot, k)
|
||||
|
||||
func genRandaoReveal*(v: AttachedValidator, fork: Fork,
|
||||
genesis_validators_root: Eth2Digest, slot: Slot): ValidatorSig =
|
||||
|
|
|
@ -20,8 +20,7 @@ import
|
|||
options, random, tables,
|
||||
../tests/[testblockutil],
|
||||
../beacon_chain/spec/[
|
||||
beaconstate, crypto, datatypes, digest, helpers, validator,
|
||||
state_transition_block],
|
||||
beaconstate, crypto, datatypes, digest, helpers, validator, signatures],
|
||||
../beacon_chain/[
|
||||
attestation_pool, block_pool, beacon_node_types, beacon_chain_db,
|
||||
interop, state_transition, validator_pool],
|
||||
|
|
|
@ -13,7 +13,7 @@ import
|
|||
sets,
|
||||
# Specs
|
||||
../../beacon_chain/spec/[datatypes, beaconstate, helpers, validator, crypto,
|
||||
state_transition_block],
|
||||
signatures],
|
||||
# Internals
|
||||
../../beacon_chain/[ssz, extras, state_transition],
|
||||
# Mocking procs
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import
|
||||
options,
|
||||
# Specs
|
||||
../../beacon_chain/spec/[datatypes, validator, state_transition_block],
|
||||
../../beacon_chain/spec/[datatypes, helpers, signatures, validator],
|
||||
# Internals
|
||||
../../beacon_chain/[ssz, extras],
|
||||
# Mock helpers
|
||||
|
@ -27,7 +27,8 @@ proc signMockBlockImpl(
|
|||
let privkey = MockPrivKeys[signedBlock.message.proposer_index]
|
||||
|
||||
signedBlock.message.body.randao_reveal = get_epoch_signature(
|
||||
state.fork, state.genesis_validators_root, block_slot, privkey)
|
||||
state.fork, state.genesis_validators_root, block_slot.compute_epoch_at_slot,
|
||||
privkey)
|
||||
signedBlock.signature = get_block_signature(
|
||||
state.fork, state.genesis_validators_root, block_slot,
|
||||
hash_tree_root(signedBlock.message), privkey)
|
||||
|
|
|
@ -12,88 +12,34 @@ import
|
|||
# Standard library
|
||||
math, random,
|
||||
# Specs
|
||||
../../beacon_chain/spec/[datatypes, crypto, helpers, digest],
|
||||
../../beacon_chain/spec/[datatypes, crypto, digest, keystore, signatures],
|
||||
# Internals
|
||||
../../beacon_chain/[ssz, extras, merkle_minimal],
|
||||
# Mocking procs
|
||||
./mock_validator_keys
|
||||
|
||||
func signMockDepositData(
|
||||
deposit_data: var DepositData,
|
||||
privkey: ValidatorPrivKey
|
||||
) =
|
||||
# No state --> Genesis
|
||||
let domain = compute_domain(
|
||||
DOMAIN_DEPOSIT,
|
||||
Version(GENESIS_FORK_VERSION)
|
||||
)
|
||||
let signing_root = compute_signing_root(
|
||||
deposit_data.getDepositMessage(),
|
||||
domain
|
||||
)
|
||||
deposit_data.signature = blsSign(
|
||||
privkey,
|
||||
signing_root.data
|
||||
)
|
||||
|
||||
func signMockDepositData(
|
||||
deposit_data: var DepositData,
|
||||
privkey: ValidatorPrivKey,
|
||||
state: BeaconState
|
||||
) =
|
||||
let domain = compute_domain(
|
||||
DOMAIN_DEPOSIT,
|
||||
Version(GENESIS_FORK_VERSION)
|
||||
)
|
||||
let signing_root = compute_signing_root(
|
||||
deposit_data.getDepositMessage(),
|
||||
domain
|
||||
)
|
||||
deposit_data.signature = blsSign(
|
||||
privkey,
|
||||
signing_root.data
|
||||
)
|
||||
|
||||
func mockDepositData(
|
||||
deposit_data: var DepositData,
|
||||
pubkey: ValidatorPubKey,
|
||||
amount: uint64,
|
||||
# withdrawal_credentials: Eth2Digest
|
||||
) =
|
||||
deposit_data.pubkey = pubkey
|
||||
deposit_data.amount = amount
|
||||
|
||||
): DepositData =
|
||||
# Insecurely use pubkey as withdrawal key
|
||||
deposit_data.withdrawal_credentials.data[0] = byte BLS_WITHDRAWAL_PREFIX
|
||||
deposit_data.withdrawal_credentials.data[1..^1] = pubkey.toRaw()
|
||||
.eth2hash()
|
||||
.data
|
||||
.toOpenArray(1, 31)
|
||||
DepositData(
|
||||
pubkey: pubkey,
|
||||
withdrawal_credentials: makeWithdrawalCredentials(pubkey),
|
||||
amount: amount,
|
||||
)
|
||||
|
||||
func mockDepositData(
|
||||
deposit_data: var DepositData,
|
||||
pubkey: ValidatorPubKey,
|
||||
privkey: ValidatorPrivKey,
|
||||
amount: uint64,
|
||||
# withdrawal_credentials: Eth2Digest,
|
||||
flags: UpdateFlags = {}
|
||||
) =
|
||||
mockDepositData(deposit_data, pubkey, amount)
|
||||
): DepositData =
|
||||
var ret = mockDepositData(pubkey, amount)
|
||||
if skipBlsValidation notin flags:
|
||||
signMockDepositData(deposit_data, privkey)
|
||||
|
||||
func mockDepositData(
|
||||
deposit_data: var DepositData,
|
||||
pubkey: ValidatorPubKey,
|
||||
privkey: ValidatorPrivKey,
|
||||
amount: uint64,
|
||||
# withdrawal_credentials: Eth2Digest,
|
||||
state: BeaconState,
|
||||
flags: UpdateFlags = {}
|
||||
) =
|
||||
mockDepositData(deposit_data, pubkey, amount)
|
||||
if skipBlsValidation notin flags:
|
||||
signMockDepositData(deposit_data, privkey, state)
|
||||
ret.signature = get_deposit_signature(ret, privkey)
|
||||
ret
|
||||
|
||||
template mockGenesisDepositsImpl(
|
||||
result: seq[Deposit],
|
||||
|
@ -115,11 +61,7 @@ template mockGenesisDepositsImpl(
|
|||
updateAmount
|
||||
|
||||
# DepositData
|
||||
mockDepositData(
|
||||
result[valIdx].data,
|
||||
MockPubKeys[valIdx],
|
||||
amount
|
||||
)
|
||||
result[valIdx].data = mockDepositData(MockPubKeys[valIdx], amount)
|
||||
else: # With signing
|
||||
var depositsDataHash: seq[Eth2Digest]
|
||||
var depositsData: seq[DepositData]
|
||||
|
@ -132,13 +74,8 @@ template mockGenesisDepositsImpl(
|
|||
updateAmount
|
||||
|
||||
# DepositData
|
||||
mockDepositData(
|
||||
result[valIdx].data,
|
||||
MockPubKeys[valIdx],
|
||||
MockPrivKeys[valIdx],
|
||||
amount,
|
||||
flags
|
||||
)
|
||||
result[valIdx].data = mockDepositData(
|
||||
MockPubKeys[valIdx], MockPrivKeys[valIdx], amount, flags)
|
||||
|
||||
depositsData.add result[valIdx].data
|
||||
depositsDataHash.add hash_tree_root(result[valIdx].data)
|
||||
|
@ -193,8 +130,7 @@ proc mockUpdateStateForNewDeposit*(
|
|||
|
||||
# TODO withdrawal credentials
|
||||
|
||||
mockDepositData(
|
||||
result.data,
|
||||
result.data = mockDepositData(
|
||||
MockPubKeys[validator_index],
|
||||
MockPrivKeys[validator_index],
|
||||
amount,
|
||||
|
|
|
@ -12,7 +12,7 @@ import
|
|||
../beacon_chain/ssz/merkleization,
|
||||
state_transition, validator_pool],
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest,
|
||||
helpers, validator, state_transition_block]
|
||||
helpers, validator, signatures]
|
||||
|
||||
func makeFakeValidatorPrivKey(i: int): ValidatorPrivKey =
|
||||
# 0 is not a valid BLS private key - 1000 helps interop with rust BLS library,
|
||||
|
@ -44,7 +44,6 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
|
|||
privkey = makeFakeValidatorPrivKey(i)
|
||||
pubkey = privkey.toPubKey()
|
||||
withdrawal_credentials = makeFakeHash(i)
|
||||
domain = compute_domain(DOMAIN_DEPOSIT, Version(GENESIS_FORK_VERSION))
|
||||
|
||||
result = Deposit(
|
||||
data: DepositData(
|
||||
|
@ -55,8 +54,7 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
|
|||
)
|
||||
|
||||
if skipBLSValidation notin flags:
|
||||
let signing_root = compute_signing_root(result.getDepositMessage, domain)
|
||||
result.data.signature = bls_sign(privkey, signing_root.data)
|
||||
result.data.signature = get_deposit_signature(result.data, privkey)
|
||||
|
||||
proc makeInitialDeposits*(
|
||||
n = SLOTS_PER_EPOCH, flags: UpdateFlags = {}): seq[Deposit] =
|
||||
|
|
Loading…
Reference in New Issue