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:
Etan Kissling 2021-09-30 17:14:03 +02:00 committed by GitHub
parent 2e9fa87f8b
commit 9ee6c3e7ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 87 deletions

View File

@ -16,9 +16,9 @@ import
# Specs
../../beacon_chain/spec/datatypes/phase0,
../../beacon_chain/spec/[beaconstate, forks, helpers, validator, signatures],
# Mocking procs
# Test utilities
./mock_blocks,
./mock_validator_keys
../testblockutil
proc mockAttestationData(
state: phase0.BeaconState,

View File

@ -8,8 +8,8 @@
import
# Beacon chain internals
../../beacon_chain/spec/[forks, helpers, signatures, state_transition],
# Mock helpers
./mock_validator_keys
# Test utilities
../testblockutil
# Routines for mocking blocks
# ---------------------------------------------------------------
@ -19,7 +19,7 @@ proc applyRandaoReveal(state: ForkedHashedBeaconState, b: var ForkedSignedBeacon
withBlck(b):
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]
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
proc signMockBlock*(state: ForkedHashedBeaconState, b: var ForkedSignedBeaconBlock) =
withBlck(b):
let proposer_index = blck.message.proposer_index
let proposer_index = blck.message.proposer_index.ValidatorIndex
let privkey = MockPrivKeys[proposer_index]
blck.root = blck.message.hash_tree_root()

View File

@ -20,8 +20,8 @@ import
../../beacon_chain/extras,
../../beacon_chain/eth1/merkle_minimal,
# Mocking procs
./mock_validator_keys
# Test utilities
../testblockutil
func mockDepositData(
pubkey: ValidatorPubKey,
@ -66,7 +66,8 @@ template mockGenesisDepositsImpl(
updateAmount
# DepositData
result[valIdx] = mockDepositData(MockPubKeys[valIdx], amount)
result[valIdx] =
mockDepositData(MockPubKeys[valIdx.ValidatorIndex], amount)
else: # With signing
var depositsDataHash: seq[Eth2Digest]
var depositsData: seq[DepositData]
@ -79,8 +80,11 @@ template mockGenesisDepositsImpl(
updateAmount
# DepositData
result[valIdx] = mockDepositData(
MockPubKeys[valIdx], MockPrivKeys[valIdx], amount, flags)
result[valIdx] =
mockDepositData(
MockPubKeys[valIdx.ValidatorIndex],
MockPrivKeys[valIdx.ValidatorIndex],
amount, flags)
depositsData.add result[valIdx]
depositsDataHash.add hash_tree_root(result[valIdx])
@ -114,8 +118,8 @@ proc mockUpdateStateForNewDeposit*[T](
# TODO withdrawal credentials
result.data = mockDepositData(
MockPubKeys[validator_index],
MockPrivKeys[validator_index],
MockPubKeys[validator_index.ValidatorIndex],
MockPrivKeys[validator_index.ValidatorIndex],
amount,
# withdrawal_credentials: Eth2Digest
flags

View File

@ -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]

View File

@ -8,11 +8,13 @@
{.used.}
import
std/random,
unittest2,
../beacon_chain/spec/[crypto, signatures],
./mocking/mock_validator_keys
./testblockutil
suite "Message signatures":
var rnd = initRand(123)
let
fork0 = Fork(current_version: Version [byte 0x40, 0x21, 0x8c, 0xe8])
fork1 = Fork(current_version: Version [byte 0x3b, 0x4e, 0xf6, 0x1d])
@ -20,9 +22,11 @@ suite "Message signatures":
"0x8fbd3b999e4873fb182569b20fb090400332849240da5ceb925db7ff7a8d984b")
genesis_validators_root1 = Eth2Digest.fromHex(
"0x78fb3f89983b990a841b98bab7951dccc73a757d2394f496e318db3c4826654e")
pubkey0 = MockPubKeys[0]
privkey0 = MockPrivKeys[0]
privkey1 = MockPrivKeys[1]
index0 = cast[ValidatorIndex](rnd.next)
index1 = cast[ValidatorIndex](rnd.next)
pubkey0 = MockPubKeys[index0]
privkey0 = MockPrivKeys[index0]
privkey1 = MockPrivKeys[index1]
test "Slot signatures":
let

View File

@ -14,12 +14,26 @@ import
../beacon_chain/spec/[helpers, signatures, state_transition, forks],
../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,
# lighthouse.
# TODO: switch to https://github.com/ethereum/eth2.0-pm/issues/60
var bytes = uint64(i + 1000).toBytesLE()
copyMem(addr result, addr bytes[0], sizeof(bytes))
# lighthouse. EF tests use 1 instead of 1000.
var bytes = (index.uint64 + 1000'u64).toBytesLE()
static: doAssert sizeof(bytes) <= sizeof(result)
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 =
var bytes = uint64(i).toBytesLE()