always use static keys in tests (#2928)
There are multiple ways how states can be processed during tests. One is through tests/mocking, the other through tests/xxxutil. Both methods can create genesis states with a set of deposits from mock validators. The private keys for those validators are created differently, though. While tests/mocking generates random keys, testblockutil generates fixed keys. This is a problem when mixing both tests/mocking and testblockutil in a single test case, as they assume that the deposits were generated using the same method. This patch aligns the key generation across tests.
This commit is contained in:
parent
2e9fa87f8b
commit
9ee6c3e7ef
|
@ -16,9 +16,9 @@ import
|
||||||
# Specs
|
# Specs
|
||||||
../../beacon_chain/spec/datatypes/phase0,
|
../../beacon_chain/spec/datatypes/phase0,
|
||||||
../../beacon_chain/spec/[beaconstate, forks, helpers, validator, signatures],
|
../../beacon_chain/spec/[beaconstate, forks, helpers, validator, signatures],
|
||||||
# Mocking procs
|
# Test utilities
|
||||||
./mock_blocks,
|
./mock_blocks,
|
||||||
./mock_validator_keys
|
../testblockutil
|
||||||
|
|
||||||
proc mockAttestationData(
|
proc mockAttestationData(
|
||||||
state: phase0.BeaconState,
|
state: phase0.BeaconState,
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
import
|
import
|
||||||
# Beacon chain internals
|
# Beacon chain internals
|
||||||
../../beacon_chain/spec/[forks, helpers, signatures, state_transition],
|
../../beacon_chain/spec/[forks, helpers, signatures, state_transition],
|
||||||
# Mock helpers
|
# Test utilities
|
||||||
./mock_validator_keys
|
../testblockutil
|
||||||
|
|
||||||
# Routines for mocking blocks
|
# Routines for mocking blocks
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
|
@ -19,7 +19,7 @@ proc applyRandaoReveal(state: ForkedHashedBeaconState, b: var ForkedSignedBeacon
|
||||||
withBlck(b):
|
withBlck(b):
|
||||||
doAssert getStateField(state, slot) <= blck.message.slot
|
doAssert getStateField(state, slot) <= blck.message.slot
|
||||||
|
|
||||||
let proposer_index = blck.message.proposer_index
|
let proposer_index = blck.message.proposer_index.ValidatorIndex
|
||||||
let privkey = MockPrivKeys[proposer_index]
|
let privkey = MockPrivKeys[proposer_index]
|
||||||
|
|
||||||
blck.message.body.randao_reveal =
|
blck.message.body.randao_reveal =
|
||||||
|
@ -32,7 +32,7 @@ proc applyRandaoReveal(state: ForkedHashedBeaconState, b: var ForkedSignedBeacon
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/tests/core/pyspec/eth2spec/test/helpers/block.py#L38-L54
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.4/tests/core/pyspec/eth2spec/test/helpers/block.py#L38-L54
|
||||||
proc signMockBlock*(state: ForkedHashedBeaconState, b: var ForkedSignedBeaconBlock) =
|
proc signMockBlock*(state: ForkedHashedBeaconState, b: var ForkedSignedBeaconBlock) =
|
||||||
withBlck(b):
|
withBlck(b):
|
||||||
let proposer_index = blck.message.proposer_index
|
let proposer_index = blck.message.proposer_index.ValidatorIndex
|
||||||
let privkey = MockPrivKeys[proposer_index]
|
let privkey = MockPrivKeys[proposer_index]
|
||||||
|
|
||||||
blck.root = blck.message.hash_tree_root()
|
blck.root = blck.message.hash_tree_root()
|
||||||
|
|
|
@ -20,8 +20,8 @@ import
|
||||||
../../beacon_chain/extras,
|
../../beacon_chain/extras,
|
||||||
../../beacon_chain/eth1/merkle_minimal,
|
../../beacon_chain/eth1/merkle_minimal,
|
||||||
|
|
||||||
# Mocking procs
|
# Test utilities
|
||||||
./mock_validator_keys
|
../testblockutil
|
||||||
|
|
||||||
func mockDepositData(
|
func mockDepositData(
|
||||||
pubkey: ValidatorPubKey,
|
pubkey: ValidatorPubKey,
|
||||||
|
@ -66,7 +66,8 @@ template mockGenesisDepositsImpl(
|
||||||
updateAmount
|
updateAmount
|
||||||
|
|
||||||
# DepositData
|
# DepositData
|
||||||
result[valIdx] = mockDepositData(MockPubKeys[valIdx], amount)
|
result[valIdx] =
|
||||||
|
mockDepositData(MockPubKeys[valIdx.ValidatorIndex], amount)
|
||||||
else: # With signing
|
else: # With signing
|
||||||
var depositsDataHash: seq[Eth2Digest]
|
var depositsDataHash: seq[Eth2Digest]
|
||||||
var depositsData: seq[DepositData]
|
var depositsData: seq[DepositData]
|
||||||
|
@ -79,8 +80,11 @@ template mockGenesisDepositsImpl(
|
||||||
updateAmount
|
updateAmount
|
||||||
|
|
||||||
# DepositData
|
# DepositData
|
||||||
result[valIdx] = mockDepositData(
|
result[valIdx] =
|
||||||
MockPubKeys[valIdx], MockPrivKeys[valIdx], amount, flags)
|
mockDepositData(
|
||||||
|
MockPubKeys[valIdx.ValidatorIndex],
|
||||||
|
MockPrivKeys[valIdx.ValidatorIndex],
|
||||||
|
amount, flags)
|
||||||
|
|
||||||
depositsData.add result[valIdx]
|
depositsData.add result[valIdx]
|
||||||
depositsDataHash.add hash_tree_root(result[valIdx])
|
depositsDataHash.add hash_tree_root(result[valIdx])
|
||||||
|
@ -114,8 +118,8 @@ proc mockUpdateStateForNewDeposit*[T](
|
||||||
# TODO withdrawal credentials
|
# TODO withdrawal credentials
|
||||||
|
|
||||||
result.data = mockDepositData(
|
result.data = mockDepositData(
|
||||||
MockPubKeys[validator_index],
|
MockPubKeys[validator_index.ValidatorIndex],
|
||||||
MockPrivKeys[validator_index],
|
MockPrivKeys[validator_index.ValidatorIndex],
|
||||||
amount,
|
amount,
|
||||||
# withdrawal_credentials: Eth2Digest
|
# withdrawal_credentials: Eth2Digest
|
||||||
flags
|
flags
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
# beacon_chain
|
|
||||||
# Copyright (c) 2018-2021 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.
|
|
||||||
|
|
||||||
# Mocking validator public and private keys
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
|
|
||||||
import
|
|
||||||
bearssl, eth/keys,
|
|
||||||
blscurve,
|
|
||||||
../../beacon_chain/spec/datatypes/base
|
|
||||||
|
|
||||||
func newKeyPair(rng: var BrHmacDrbgContext): BlsResult[tuple[pub: ValidatorPubKey, priv: ValidatorPrivKey]] =
|
|
||||||
## Generates a new public-private keypair
|
|
||||||
## This requires entropy on the system
|
|
||||||
# The input-keying-material requires 32 bytes at least for security
|
|
||||||
# The generation is deterministic and the input-keying-material
|
|
||||||
# must be protected against side-channel attacks
|
|
||||||
|
|
||||||
var ikm: array[32, byte]
|
|
||||||
brHmacDrbgGenerate(rng, ikm)
|
|
||||||
|
|
||||||
var
|
|
||||||
sk: SecretKey
|
|
||||||
pk: blscurve.PublicKey
|
|
||||||
if keyGen(ikm, pk, sk):
|
|
||||||
ok((ValidatorPubKey(blob: pk.exportRaw()), ValidatorPrivKey(sk)))
|
|
||||||
else:
|
|
||||||
err "bls: cannot generate keypair"
|
|
||||||
|
|
||||||
# this is being indexed inside "mock_deposits.nim" by a value up to `validatorCount`
|
|
||||||
# which is `num_validators` which is `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT`
|
|
||||||
proc genMockPrivKeys(privkeys: var openArray[ValidatorPrivKey]) =
|
|
||||||
let rng = newRng()
|
|
||||||
for i in 0 ..< privkeys.len:
|
|
||||||
let pair = newKeyPair(rng[])[]
|
|
||||||
privkeys[i] = pair.priv
|
|
||||||
|
|
||||||
func genMockPubKeys(pubkeys: var openArray[ValidatorPubKey],
|
|
||||||
privkeys: openArray[ValidatorPrivKey]) =
|
|
||||||
for i in 0 ..< privkeys.len:
|
|
||||||
pubkeys[i] = toPubKey(privkeys[i]).toPubKey()
|
|
||||||
|
|
||||||
# Ref array necessary to limit stack usage / binary size
|
|
||||||
var MockPrivKeys* = newSeq[ValidatorPrivKey](defaultRuntimeConfig.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT)
|
|
||||||
genMockPrivKeys(MockPrivKeys)
|
|
||||||
|
|
||||||
var MockPubKeys* = newSeq[ValidatorPubKey](defaultRuntimeConfig.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT)
|
|
||||||
genMockPubKeys(MockPubKeys, MockPrivKeys)
|
|
||||||
|
|
||||||
type MockKey = ValidatorPrivKey or ValidatorPubKey
|
|
||||||
|
|
||||||
template `[]`*[N: static int](a: array[N, MockKey], idx: ValidatorIndex): MockKey =
|
|
||||||
a[idx.int]
|
|
||||||
|
|
||||||
when isMainModule:
|
|
||||||
echo "========================================"
|
|
||||||
echo "Mock keys"
|
|
||||||
for i in 0 ..< defaultRuntimeConfig.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
|
|
||||||
echo " validator ", i
|
|
||||||
echo " seckey: ", MockPrivKeys[i].toHex()
|
|
||||||
echo " pubkey: ", MockPubKeys[i]
|
|
|
@ -8,11 +8,13 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import
|
import
|
||||||
|
std/random,
|
||||||
unittest2,
|
unittest2,
|
||||||
../beacon_chain/spec/[crypto, signatures],
|
../beacon_chain/spec/[crypto, signatures],
|
||||||
./mocking/mock_validator_keys
|
./testblockutil
|
||||||
|
|
||||||
suite "Message signatures":
|
suite "Message signatures":
|
||||||
|
var rnd = initRand(123)
|
||||||
let
|
let
|
||||||
fork0 = Fork(current_version: Version [byte 0x40, 0x21, 0x8c, 0xe8])
|
fork0 = Fork(current_version: Version [byte 0x40, 0x21, 0x8c, 0xe8])
|
||||||
fork1 = Fork(current_version: Version [byte 0x3b, 0x4e, 0xf6, 0x1d])
|
fork1 = Fork(current_version: Version [byte 0x3b, 0x4e, 0xf6, 0x1d])
|
||||||
|
@ -20,9 +22,11 @@ suite "Message signatures":
|
||||||
"0x8fbd3b999e4873fb182569b20fb090400332849240da5ceb925db7ff7a8d984b")
|
"0x8fbd3b999e4873fb182569b20fb090400332849240da5ceb925db7ff7a8d984b")
|
||||||
genesis_validators_root1 = Eth2Digest.fromHex(
|
genesis_validators_root1 = Eth2Digest.fromHex(
|
||||||
"0x78fb3f89983b990a841b98bab7951dccc73a757d2394f496e318db3c4826654e")
|
"0x78fb3f89983b990a841b98bab7951dccc73a757d2394f496e318db3c4826654e")
|
||||||
pubkey0 = MockPubKeys[0]
|
index0 = cast[ValidatorIndex](rnd.next)
|
||||||
privkey0 = MockPrivKeys[0]
|
index1 = cast[ValidatorIndex](rnd.next)
|
||||||
privkey1 = MockPrivKeys[1]
|
pubkey0 = MockPubKeys[index0]
|
||||||
|
privkey0 = MockPrivKeys[index0]
|
||||||
|
privkey1 = MockPrivKeys[index1]
|
||||||
|
|
||||||
test "Slot signatures":
|
test "Slot signatures":
|
||||||
let
|
let
|
||||||
|
|
|
@ -14,12 +14,26 @@ import
|
||||||
../beacon_chain/spec/[helpers, signatures, state_transition, forks],
|
../beacon_chain/spec/[helpers, signatures, state_transition, forks],
|
||||||
../beacon_chain/consensus_object_pools/attestation_pool
|
../beacon_chain/consensus_object_pools/attestation_pool
|
||||||
|
|
||||||
func makeFakeValidatorPrivKey*(i: int): ValidatorPrivKey =
|
type
|
||||||
|
MockPrivKeysT = object
|
||||||
|
MockPubKeysT = object
|
||||||
|
const
|
||||||
|
MockPrivKeys* = MockPrivKeysT()
|
||||||
|
MockPubKeys* = MockPubKeysT()
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0/tests/core/pyspec/eth2spec/test/helpers/keys.py
|
||||||
|
func `[]`*(_: MockPrivKeysT, index: ValidatorIndex): ValidatorPrivKey =
|
||||||
# 0 is not a valid BLS private key - 1000 helps interop with rust BLS library,
|
# 0 is not a valid BLS private key - 1000 helps interop with rust BLS library,
|
||||||
# lighthouse.
|
# lighthouse. EF tests use 1 instead of 1000.
|
||||||
# TODO: switch to https://github.com/ethereum/eth2.0-pm/issues/60
|
var bytes = (index.uint64 + 1000'u64).toBytesLE()
|
||||||
var bytes = uint64(i + 1000).toBytesLE()
|
static: doAssert sizeof(bytes) <= sizeof(result)
|
||||||
copyMem(addr result, addr bytes[0], sizeof(bytes))
|
copyMem(addr result, addr bytes, sizeof(bytes))
|
||||||
|
|
||||||
|
func `[]`*(_: MockPubKeysT, index: ValidatorIndex): ValidatorPubKey =
|
||||||
|
MockPrivKeys[index].toPubKey().toPubKey()
|
||||||
|
|
||||||
|
func makeFakeValidatorPrivKey*(i: int): ValidatorPrivKey =
|
||||||
|
MockPrivKeys[i.ValidatorIndex]
|
||||||
|
|
||||||
func makeFakeHash*(i: int): Eth2Digest =
|
func makeFakeHash*(i: int): Eth2Digest =
|
||||||
var bytes = uint64(i).toBytesLE()
|
var bytes = uint64(i).toBytesLE()
|
||||||
|
|
Loading…
Reference in New Issue