avoid stack allocations in some tests (#1079)

This commit is contained in:
Jacek Sieka 2020-05-28 10:28:14 +02:00 committed by GitHub
parent 21131e629b
commit 18eca263b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 26 additions and 84 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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