refactor some Merkle proof generation code outside tests; remove unused variables/functions
This commit is contained in:
parent
8eafa6e094
commit
f49dbf68e6
|
@ -614,7 +614,6 @@ proc broadcastAggregatedAttestations(
|
|||
# the corresponding one -- whatver they are, they match.
|
||||
|
||||
let
|
||||
bs = BlockSlot(blck: head, slot: slot)
|
||||
committees_per_slot = get_committee_count_at_slot(state, slot)
|
||||
var cache = get_empty_per_epoch_cache()
|
||||
for committee_index in 0'u64..<committees_per_slot:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2018 Status Research & Development GmbH
|
||||
# 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).
|
||||
|
@ -20,14 +20,7 @@ type
|
|||
UpdateFlag* = enum
|
||||
skipMerkleValidation ##\
|
||||
## When processing deposits, skip verifying the Merkle proof trees of each
|
||||
## deposit. This is a holdover from both interop issues with the malformed
|
||||
## proofs and, more currently, nim-beacon-chain's creation of proofs which
|
||||
## are inconsistent with the current specification. Furthermore several of
|
||||
## the mocking interfaces deliberately do not create Merkle proofs. Whilst
|
||||
## this seems less than entirely justifiable, for now enable keeping those
|
||||
## in place while minimizing the tech debt they create. One, in principle,
|
||||
## should be able to remove this flag entirely. It is not intrinsically an
|
||||
## expensive operation to perform.
|
||||
## deposit.
|
||||
skipBlsValidation ##\
|
||||
## Skip verification of BLS signatures in block processing.
|
||||
## Predominantly intended for use in testing, e.g. to allow extra coverage.
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
# ---------------------------------------------------------------
|
||||
|
||||
import
|
||||
strutils, macros, bitops,
|
||||
sequtils, strutils, macros, bitops,
|
||||
# Specs
|
||||
../../beacon_chain/spec/[beaconstate, datatypes, digest],
|
||||
../../beacon_chain/spec/[beaconstate, datatypes, digest, helpers],
|
||||
../../beacon_chain/ssz
|
||||
|
||||
func round_step_down*(x: Natural, step: static Natural): int {.inline.} =
|
||||
|
@ -85,6 +85,24 @@ proc getMerkleProof*[Depth: static int](
|
|||
else:
|
||||
result[depth] = ZeroHashes[depth]
|
||||
|
||||
proc attachMerkleProofs*(deposits: var seq[Deposit]) =
|
||||
let deposit_data_roots = mapIt(deposits, it.data.hash_tree_root)
|
||||
var
|
||||
deposit_data_sums: seq[Eth2Digest]
|
||||
for prefix_root in hash_tree_roots_prefix(
|
||||
deposit_data_roots, 1'i64 shl DEPOSIT_CONTRACT_TREE_DEPTH):
|
||||
deposit_data_sums.add prefix_root
|
||||
|
||||
for val_idx in 0 ..< deposits.len:
|
||||
let merkle_tree = merkleTreeFromLeaves(deposit_data_roots[0..val_idx])
|
||||
deposits[val_idx].proof[0..31] = merkle_tree.getMerkleProof(val_idx)
|
||||
deposits[val_idx].proof[32].data[0..7] = int_to_bytes8((val_idx + 1).uint64)
|
||||
|
||||
doAssert is_valid_merkle_branch(
|
||||
deposit_data_roots[val_idx], deposits[val_idx].proof,
|
||||
DEPOSIT_CONTRACT_TREE_DEPTH + 1, val_idx.uint64,
|
||||
deposit_data_sums[val_idx])
|
||||
|
||||
proc testMerkleMinimal*(): bool =
|
||||
proc toDigest[N: static int](x: array[N, byte]): Eth2Digest =
|
||||
result.data[0 .. N-1] = x
|
||||
|
@ -126,9 +144,6 @@ proc testMerkleMinimal*(): bool =
|
|||
macro roundTrips(): untyped =
|
||||
result = newStmtList()
|
||||
|
||||
# Unsure why sszList ident is undeclared in "quote do"
|
||||
let list = bindSym"sszList"
|
||||
|
||||
# compile-time unrolled test
|
||||
for nleaves in [3, 4, 5, 7, 8, 1 shl 10, 1 shl 32]:
|
||||
let depth = fastLog2(nleaves-1) + 1
|
||||
|
@ -144,8 +159,6 @@ proc testMerkleMinimal*(): bool =
|
|||
|
||||
block: # proof for a
|
||||
let index = 0
|
||||
let proof = getMerkleProof(tree, index)
|
||||
#echo "Proof: ", proof
|
||||
|
||||
doAssert is_valid_merkle_branch(
|
||||
a, get_merkle_proof(tree, index = index),
|
||||
|
@ -157,7 +170,6 @@ proc testMerkleMinimal*(): bool =
|
|||
|
||||
block: # proof for b
|
||||
let index = 1
|
||||
let proof = getMerkleProof(tree, index)
|
||||
|
||||
doAssert is_valid_merkle_branch(
|
||||
b, get_merkle_proof(tree, index = index),
|
||||
|
@ -169,7 +181,6 @@ proc testMerkleMinimal*(): bool =
|
|||
|
||||
block: # proof for c
|
||||
let index = 2
|
||||
let proof = getMerkleProof(tree, index)
|
||||
|
||||
doAssert is_valid_merkle_branch(
|
||||
c, get_merkle_proof(tree, index = index),
|
|
@ -126,16 +126,6 @@ func compute_fork_data_root(current_version: array[4, byte],
|
|||
genesis_validators_root: genesis_validators_root
|
||||
))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#compute_fork_digest
|
||||
func compute_fork_digest(current_version: array[4, byte],
|
||||
genesis_validators_root: Eth2Digest): array[4, byte] =
|
||||
# Return the 4-byte fork digest for the ``current_version`` and
|
||||
# ``genesis_validators_root``.
|
||||
# This is a digest primarily used for domain separation on the p2p layer.
|
||||
# 4-bytes suffices for practical separation of forks/chains.
|
||||
result[0..3] =
|
||||
compute_fork_data_root(current_version, genesis_validators_root).data[0..3]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#compute_domain
|
||||
func compute_domain*(
|
||||
domain_type: DomainType,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import
|
||||
chronos,
|
||||
spec/[datatypes]
|
||||
spec/datatypes
|
||||
|
||||
from times import Time, getTime, fromUnix, `<`, `-`
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import
|
|||
os, strutils,
|
||||
chronicles, chronos, blscurve, nimcrypto, json_serialization, serialization,
|
||||
web3, stint, eth/keys,
|
||||
spec/[datatypes, digest, crypto], conf, ssz, interop
|
||||
spec/[datatypes, digest, crypto], conf, ssz, interop, merkle_minimal
|
||||
|
||||
contract(DepositContract):
|
||||
proc deposit(pubkey: Bytes48, withdrawalCredentials: Bytes32, signature: Bytes96, deposit_data_root: FixedBytes[32])
|
||||
|
@ -49,11 +49,17 @@ proc generateDeposits*(totalValidators: int,
|
|||
|
||||
let dp = makeDeposit(pubKey, privKey)
|
||||
|
||||
writeTextFile(privKeyFn, privKey.toHex())
|
||||
writeFile(depositFn, dp)
|
||||
|
||||
result.add(dp)
|
||||
|
||||
# Does quadratic additional work, but fast enough, and otherwise more
|
||||
# cleanly allows free intermixing of pre-existing and newly generated
|
||||
# deposit and private key files. TODO: only generate new Merkle proof
|
||||
# for the most recent deposit if this becomes bottleneck.
|
||||
attachMerkleProofs(result)
|
||||
|
||||
writeTextFile(privKeyFn, privKey.toHex())
|
||||
writeFile(depositFn, result[result.len - 1])
|
||||
|
||||
proc sendDeposits*(
|
||||
deposits: seq[Deposit],
|
||||
depositWeb3Url, depositContractAddress, privateKey: string) {.async.} =
|
||||
|
|
|
@ -14,11 +14,9 @@ import
|
|||
# Specs
|
||||
../../beacon_chain/spec/[datatypes, crypto, helpers, digest],
|
||||
# Internals
|
||||
../../beacon_chain/[ssz, extras],
|
||||
../../beacon_chain/[ssz, extras, merkle_minimal],
|
||||
# Mocking procs
|
||||
./mock_validator_keys,
|
||||
# Other test utilities, for attachMerkleProofs()
|
||||
../testblockutil
|
||||
./mock_validator_keys
|
||||
|
||||
func signMockDepositData(
|
||||
deposit_data: var DepositData,
|
||||
|
|
|
@ -80,10 +80,12 @@ macro parseNumConsts(file: static string): untyped =
|
|||
|
||||
result = quote do: `constsToCheck`
|
||||
|
||||
const
|
||||
datatypesConsts = @(parseNumConsts(SpecDir/"datatypes.nim"))
|
||||
mainnetConsts = @(parseNumConsts(SpecDir/"presets"/"mainnet.nim"))
|
||||
minimalConsts = @(parseNumConsts(SpecDir/"presets"/"minimal.nim"))
|
||||
const datatypesConsts = @(parseNumConsts(SpecDir/"datatypes.nim"))
|
||||
|
||||
when const_preset == "minimal":
|
||||
const minimalConsts = @(parseNumConsts(SpecDir/"presets"/"minimal.nim"))
|
||||
else:
|
||||
const mainnetConsts = @(parseNumConsts(SpecDir/"presets"/"mainnet.nim"))
|
||||
|
||||
const IgnoreKeys = [
|
||||
# Ignore all non-numeric types
|
||||
|
|
|
@ -198,7 +198,6 @@ when const_preset == "minimal": # Too much stack space used on mainnet
|
|||
b2Add = pool.add(b2Root, b2)
|
||||
bs1 = BlockSlot(blck: b1Add, slot: b1.message.slot)
|
||||
bs1_3 = b1Add.atSlot(3.Slot)
|
||||
bs2 = BlockSlot(blck: b2Add, slot: b2.message.slot)
|
||||
bs2_3 = b2Add.atSlot(3.Slot)
|
||||
|
||||
var tmpState = pool.headState
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{.used.}
|
||||
|
||||
import
|
||||
unittest, ./testutil, ./mocking/merkle_minimal
|
||||
unittest, ./testutil, ../beacon_chain/merkle_minimal
|
||||
|
||||
suiteReport "Mocking utilities":
|
||||
timedTest "merkle_minimal":
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
# 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.
|
||||
|
||||
import
|
||||
options, sequtils, stew/endians2,
|
||||
options, stew/endians2,
|
||||
chronicles, eth/trie/[db],
|
||||
./mocking/merkle_minimal,
|
||||
../beacon_chain/[beacon_chain_db, block_pool, extras, ssz, state_transition,
|
||||
validator_pool],
|
||||
../beacon_chain/[beacon_chain_db, block_pool, extras, merkle_minimal, ssz,
|
||||
state_transition, validator_pool],
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest,
|
||||
helpers, validator, state_transition_block]
|
||||
|
||||
|
@ -58,24 +57,6 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
|
|||
let signing_root = compute_signing_root(result.getDepositMessage, domain)
|
||||
result.data.signature = bls_sign(privkey, signing_root.data)
|
||||
|
||||
proc attachMerkleProofs*(deposits: var seq[Deposit]) =
|
||||
let deposit_data_roots = mapIt(deposits, it.data.hash_tree_root)
|
||||
var
|
||||
deposit_data_sums: seq[Eth2Digest]
|
||||
for prefix_root in hash_tree_roots_prefix(
|
||||
deposit_data_roots, 1'i64 shl DEPOSIT_CONTRACT_TREE_DEPTH):
|
||||
deposit_data_sums.add prefix_root
|
||||
|
||||
for val_idx in 0 ..< deposits.len:
|
||||
let merkle_tree = merkleTreeFromLeaves(deposit_data_roots[0..val_idx])
|
||||
deposits[val_idx].proof[0..31] = merkle_tree.getMerkleProof(val_idx)
|
||||
deposits[val_idx].proof[32].data[0..7] = int_to_bytes8((val_idx + 1).uint64)
|
||||
|
||||
doAssert is_valid_merkle_branch(
|
||||
deposit_data_roots[val_idx], deposits[val_idx].proof,
|
||||
DEPOSIT_CONTRACT_TREE_DEPTH + 1, val_idx.uint64,
|
||||
deposit_data_sums[val_idx])
|
||||
|
||||
proc makeInitialDeposits*(
|
||||
n = SLOTS_PER_EPOCH, flags: UpdateFlags = {}): seq[Deposit] =
|
||||
for i in 0..<n.int:
|
||||
|
|
Loading…
Reference in New Issue