avoid stack allocations in some tests (#1079)
This commit is contained in:
parent
21131e629b
commit
18eca263b1
|
@ -259,7 +259,7 @@ func sszSize*(value: auto): int {.gcsafe, raises: [Defect].} =
|
|||
|
||||
elif T is object|tuple:
|
||||
result = anonConst fixedPortionSize(T)
|
||||
enumInstanceSerializedFields(value, _, field):
|
||||
enumInstanceSerializedFields(value, _{.used.}, field):
|
||||
type FieldType = type toSszType(field)
|
||||
when not isFixedSize(FieldType):
|
||||
result += sszSize(toSszType field)
|
||||
|
|
|
@ -31,8 +31,6 @@ import # Unit test
|
|||
./fork_choice/tests_fork_choice
|
||||
|
||||
import # Refactor state transition unit tests
|
||||
# TODO re-enable when useful
|
||||
# ./spec_block_processing/test_genesis,
|
||||
# In mainnet these take 2 minutes and are empty TODOs
|
||||
./spec_block_processing/test_process_deposits,
|
||||
./spec_block_processing/test_process_attestation,
|
||||
|
|
|
@ -37,7 +37,7 @@ proc runTest(identifier: string) =
|
|||
var
|
||||
preState = newClone(parseTest(testDir/"pre.ssz", SSZ, BeaconState))
|
||||
hasPostState = existsFile(testDir/"post.ssz")
|
||||
hashedPreState = HashedBeaconState(
|
||||
hashedPreState = (ref HashedBeaconState)(
|
||||
data: preState[], root: hash_tree_root(preState[]))
|
||||
|
||||
# In test cases with more than 10 blocks the first 10 aren't 0-prefixed,
|
||||
|
@ -48,11 +48,11 @@ proc runTest(identifier: string) =
|
|||
|
||||
if hasPostState:
|
||||
let success = state_transition(
|
||||
hashedPreState, blck, flags = {}, noRollback)
|
||||
hashedPreState[], blck, flags = {}, noRollback)
|
||||
doAssert success, "Failure when applying block " & $i
|
||||
else:
|
||||
let success = state_transition(
|
||||
hashedPreState, blck, flags = {}, noRollback)
|
||||
hashedPreState[], blck, flags = {}, noRollback)
|
||||
doAssert (i + 1 < numBlocks) or not success,
|
||||
"We didn't expect these invalid blocks to be processed"
|
||||
|
||||
|
|
|
@ -33,13 +33,13 @@ proc runTest(identifier: string) =
|
|||
timedTest "Slots - " & identifier:
|
||||
var
|
||||
preState = newClone(parseTest(testDir/"pre.ssz", SSZ, BeaconState))
|
||||
hashedPreState = HashedBeaconState(
|
||||
hashedPreState = (ref HashedBeaconState)(
|
||||
data: preState[], root: hash_tree_root(preState[]))
|
||||
let postState = newClone(parseTest(testDir/"post.ssz", SSZ, BeaconState))
|
||||
|
||||
check:
|
||||
process_slots(
|
||||
hashedPreState, hashedPreState.data.slot + num_slots)
|
||||
hashedPreState[], hashedPreState.data.slot + num_slots)
|
||||
|
||||
hashedPreState.root == postState[].hash_tree_root()
|
||||
let newPreState = newClone(hashedPreState.data)
|
||||
|
|
|
@ -44,7 +44,7 @@ setDefaultValue(SSZHashTreeRoot, signing_root, "")
|
|||
proc checkSSZ(T: type SignedBeaconBlock, dir: string, expectedHash: SSZHashTreeRoot) =
|
||||
# Deserialize into a ref object to not fill Nim stack
|
||||
let encoded = readFileBytes(dir/"serialized.ssz")
|
||||
var deserialized = newClone sszDecodeEntireInput(encoded, T)
|
||||
var deserialized = newClone(sszDecodeEntireInput(encoded, T))
|
||||
|
||||
# SignedBeaconBlocks usually not hashed because they're identified by
|
||||
# htr(BeaconBlock), so do it manually
|
||||
|
@ -60,7 +60,7 @@ proc checkSSZ(T: type SignedBeaconBlock, dir: string, expectedHash: SSZHashTreeR
|
|||
proc checkSSZ(T: type, dir: string, expectedHash: SSZHashTreeRoot) =
|
||||
# Deserialize into a ref object to not fill Nim stack
|
||||
let encoded = readFileBytes(dir/"serialized.ssz")
|
||||
var deserialized = newClone sszDecodeEntireInput(encoded, T)
|
||||
var deserialized = newClone(sszDecodeEntireInput(encoded, T))
|
||||
|
||||
check: expectedHash.root == "0x" & toLowerASCII($hash_tree_root(deserialized[]))
|
||||
|
||||
|
|
|
@ -77,13 +77,13 @@ proc checkBasic(T: typedesc,
|
|||
dir: string,
|
||||
expectedHash: SSZHashTreeRoot) =
|
||||
var fileContents = readFileBytes(dir/"serialized.ssz")
|
||||
var deserialized = sszDecodeEntireInput(fileContents, T)
|
||||
var deserialized = newClone(sszDecodeEntireInput(fileContents, T))
|
||||
|
||||
let expectedHash = expectedHash.root
|
||||
let actualHash = "0x" & toLowerASCII($deserialized.hashTreeRoot())
|
||||
let actualHash = "0x" & toLowerASCII($hash_tree_root(deserialized[]))
|
||||
|
||||
check expectedHash == actualHash
|
||||
check sszSize(deserialized) == fileContents.len
|
||||
check sszSize(deserialized[]) == fileContents.len
|
||||
|
||||
# TODO check the value
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
# 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.
|
||||
|
||||
|
||||
# initialize_beacon_state_from_eth1 (beaconstate.nim)
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.3/specs/phase0/beacon-chain.md#genesis
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
{.used.}
|
||||
|
||||
import
|
||||
# Standard library
|
||||
unittest,
|
||||
# Specs
|
||||
../../beacon_chain/spec/datatypes,
|
||||
# Mock helpers
|
||||
../mocking/mock_genesis,
|
||||
../testutil
|
||||
|
||||
|
||||
# TODO:
|
||||
# - MIN_GENESIS_ACTIVE_VALIDATOR_COUNT is not implemented
|
||||
# - MIN_GENESIS_TIME is not implemented
|
||||
# - is_valid_genesis_state is not implemented
|
||||
|
||||
suiteReport "[Unit - Spec - Genesis] Genesis block checks " & preset():
|
||||
timedTest "is_valid_genesis_state for a valid state":
|
||||
discard initGenesisState(
|
||||
num_validators = MIN_GENESIS_ACTIVE_VALIDATOR_COUNT,
|
||||
genesis_time = MIN_GENESIS_TIME
|
||||
)
|
||||
discard "TODO"
|
||||
|
||||
timedTest "Invalid genesis time":
|
||||
discard initGenesisState(
|
||||
num_validators = MIN_GENESIS_ACTIVE_VALIDATOR_COUNT,
|
||||
genesis_time = MIN_GENESIS_TIME.uint64 - 1
|
||||
)
|
||||
discard "TODO"
|
||||
|
||||
timedTest "Validators with more than 32 ETH":
|
||||
discard "TODO"
|
||||
|
||||
timedTest "More validators than minimum":
|
||||
discard "TODO"
|
||||
|
||||
when false:
|
||||
# TODO causes possible stack overflow in mainnet
|
||||
timedTest "Not enough validators":
|
||||
discard initGenesisState(
|
||||
num_validators = MIN_GENESIS_ACTIVE_VALIDATOR_COUNT.uint64 - 1,
|
||||
genesis_time = MIN_GENESIS_TIME.uint64 - 1
|
||||
)
|
||||
discard "TODO"
|
|
@ -23,7 +23,7 @@ import
|
|||
suiteReport "[Unit - Spec - Block processing] Attestations " & preset():
|
||||
|
||||
const NumValidators = uint64(8) * SLOTS_PER_EPOCH
|
||||
let genesisState = initGenesisState(NumValidators)
|
||||
let genesisState = newClone(initGenesisState(NumValidators))
|
||||
doAssert genesisState.data.validators.len == int NumValidators
|
||||
|
||||
template valid_attestation(name: string, body: untyped): untyped {.dirty.}=
|
||||
|
@ -33,7 +33,7 @@ suiteReport "[Unit - Spec - Block processing] Attestations " & preset():
|
|||
# The attestation to process must be named "attestation" in the calling context
|
||||
|
||||
timedTest name:
|
||||
var state {.inject.} = newClone(genesisState)
|
||||
var state {.inject.} = newClone(genesisState[])
|
||||
|
||||
# Attestation setup body
|
||||
# ----------------------------------------
|
||||
|
|
|
@ -26,14 +26,14 @@ import
|
|||
suiteReport "[Unit - Spec - Block processing] Deposits " & preset():
|
||||
|
||||
const NumValidators = uint64 5 * SLOTS_PER_EPOCH
|
||||
let genesisState = initGenesisState(NumValidators)
|
||||
let genesisState = newClone(initGenesisState(NumValidators))
|
||||
doAssert genesisState.data.validators.len == int NumValidators
|
||||
|
||||
template valid_deposit(deposit_amount: uint64, name: string): untyped =
|
||||
# TODO: BLS signature
|
||||
timedTest "Deposit " & name & " MAX_EFFECTIVE_BALANCE balance (" &
|
||||
$(MAX_EFFECTIVE_BALANCE div 10'u64^9) & " ETH)":
|
||||
var state = newClone(genesisState)
|
||||
var state = newClone(genesisState[])
|
||||
|
||||
# Test configuration
|
||||
# ----------------------------------------
|
||||
|
|
|
@ -217,11 +217,11 @@ proc payload =
|
|||
echo " Finalization rules are detailed at https://github.com/protolambda/eth2-docs#justification-and-finalization"
|
||||
|
||||
const NumValidators = uint64(8) * SLOTS_PER_EPOCH
|
||||
let genesisState = initGenesisState(NumValidators)
|
||||
let genesisState = newClone(initGenesisState(NumValidators))
|
||||
doAssert genesisState.data.validators.len == int NumValidators
|
||||
|
||||
setup:
|
||||
var state = newClone(genesisState)
|
||||
var state = newClone(genesisState[])
|
||||
|
||||
timedTest " Rule I - 234 finalization with enough support":
|
||||
finalizeOn234(state[], Epoch 5, sufficient_support = true)
|
||||
|
|
|
@ -21,7 +21,7 @@ proc getStateRef(db: BeaconChainDB, root: Eth2Digest): NilableBeaconStateRef =
|
|||
return res
|
||||
|
||||
template wrappedTimedTest(name: string, body: untyped) =
|
||||
## Workaround for stack overflow
|
||||
# `check` macro takes a copy of whatever it's checking, on the stack!
|
||||
block: # Symbol namespacing
|
||||
proc wrappedTest() =
|
||||
timedTest name:
|
||||
|
@ -66,7 +66,7 @@ suiteReport "Beacon chain DB" & preset():
|
|||
|
||||
check:
|
||||
db.containsState(root)
|
||||
db.getStateRef(root)[] == state[]
|
||||
hash_tree_root(db.getStateRef(root)[]) == root
|
||||
|
||||
wrappedTimedTest "find ancestors" & preset():
|
||||
var
|
||||
|
@ -115,6 +115,8 @@ suiteReport "Beacon chain DB" & preset():
|
|||
|
||||
db.putState(state[])
|
||||
|
||||
check db.containsState(root)
|
||||
let state2 = db.getStateRef(root)
|
||||
|
||||
check:
|
||||
db.containsState(root)
|
||||
db.getStateRef(root)[] == state[]
|
||||
hash_tree_root(state2[]) == root
|
||||
|
|
|
@ -20,13 +20,13 @@ suiteReport "Block processing" & preset():
|
|||
let
|
||||
# Genesis state with minimal number of deposits
|
||||
# TODO bls verification is a bit of a bottleneck here
|
||||
genesisState = initialize_hashed_beacon_state_from_eth1(
|
||||
Eth2Digest(), 0, makeInitialDeposits(), {})
|
||||
genesisState = newClone(initialize_hashed_beacon_state_from_eth1(
|
||||
Eth2Digest(), 0, makeInitialDeposits(), {}))
|
||||
genesisBlock = get_initial_beacon_block(genesisState.data)
|
||||
genesisRoot = hash_tree_root(genesisBlock.message)
|
||||
|
||||
setup:
|
||||
var state = newClone(genesisState)
|
||||
var state = newClone(genesisState[])
|
||||
|
||||
timedTest "Passes from genesis state, no block" & preset():
|
||||
check:
|
||||
|
|
Loading…
Reference in New Issue