mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-11 14:54:12 +00:00
Working test suite with run-time presets
This commit is contained in:
parent
441ae9b58c
commit
c4af4e2f35
@ -106,7 +106,7 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||
+ BASE_REWARD_FACTOR 64 [Preset: mainnet] OK
|
||||
+ BLS_WITHDRAWAL_PREFIX "0x00" [Preset: mainnet] OK
|
||||
+ CHURN_LIMIT_QUOTIENT 65536 [Preset: mainnet] OK
|
||||
+ CUSTODY_PERIOD_TO_RANDAO_PADDING 2048 [Preset: mainnet] OK
|
||||
CUSTODY_PERIOD_TO_RANDAO_PADDING 2048 [Preset: mainnet] Skip
|
||||
DEPOSIT_CONTRACT_ADDRESS "0x1234567890123456789012345678901234567 Skip
|
||||
+ DOMAIN_AGGREGATE_AND_PROOF "0x06000000" [Preset: mainnet] OK
|
||||
+ DOMAIN_BEACON_ATTESTER "0x01000000" [Preset: mainnet] OK
|
||||
@ -119,7 +119,7 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||
+ DOMAIN_SHARD_COMMITTEE "0x81000000" [Preset: mainnet] OK
|
||||
+ DOMAIN_SHARD_PROPOSAL "0x80000000" [Preset: mainnet] OK
|
||||
+ DOMAIN_VOLUNTARY_EXIT "0x04000000" [Preset: mainnet] OK
|
||||
+ EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS 16384 [Preset: mainnet] OK
|
||||
EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS 16384 [Preset: mainnet] Skip
|
||||
+ EARLY_DERIVED_SECRET_REVEAL_SLOT_REWARD_MULTIPLE 2 [Preset: mainnet] OK
|
||||
+ EFFECTIVE_BALANCE_INCREMENT 1000000000 [Preset: mainnet] OK
|
||||
+ EJECTION_BALANCE 16000000000 [Preset: mainnet] OK
|
||||
@ -130,7 +130,7 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||
+ EPOCHS_PER_SLASHINGS_VECTOR 8192 [Preset: mainnet] OK
|
||||
+ ETH1_FOLLOW_DISTANCE 1024 [Preset: mainnet] OK
|
||||
+ GASPRICE_ADJUSTMENT_COEFFICIENT 8 [Preset: mainnet] OK
|
||||
+ GENESIS_DELAY 172800 [Preset: mainnet] OK
|
||||
GENESIS_DELAY 172800 [Preset: mainnet] Skip
|
||||
GENESIS_FORK_VERSION "0x00000000" [Preset: mainnet] Skip
|
||||
+ HISTORICAL_ROOTS_LIMIT 16777216 [Preset: mainnet] OK
|
||||
+ HYSTERESIS_DOWNWARD_MULTIPLIER 1 [Preset: mainnet] OK
|
||||
@ -163,8 +163,8 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||
+ MIN_DEPOSIT_AMOUNT 1000000000 [Preset: mainnet] OK
|
||||
+ MIN_EPOCHS_TO_INACTIVITY_PENALTY 4 [Preset: mainnet] OK
|
||||
+ MIN_GASPRICE 8 [Preset: mainnet] OK
|
||||
+ MIN_GENESIS_ACTIVE_VALIDATOR_COUNT 16384 [Preset: mainnet] OK
|
||||
+ MIN_GENESIS_TIME 1578009600 [Preset: mainnet] OK
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT 16384 [Preset: mainnet] Skip
|
||||
MIN_GENESIS_TIME 1578009600 [Preset: mainnet] Skip
|
||||
+ MIN_PER_EPOCH_CHURN_LIMIT 4 [Preset: mainnet] OK
|
||||
+ MIN_SEED_LOOKAHEAD 1 [Preset: mainnet] OK
|
||||
+ MIN_SLASHING_PENALTY_QUOTIENT 32 [Preset: mainnet] OK
|
||||
@ -190,7 +190,7 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||
+ VALIDATOR_REGISTRY_LIMIT 1099511627776 [Preset: mainnet] OK
|
||||
+ WHISTLEBLOWER_REWARD_QUOTIENT 512 [Preset: mainnet] OK
|
||||
```
|
||||
OK: 83/86 Fail: 0/86 Skip: 3/86
|
||||
OK: 78/86 Fail: 0/86 Skip: 8/86
|
||||
## PeerPool testing suite
|
||||
```diff
|
||||
+ Access peers by key test OK
|
||||
@ -265,4 +265,4 @@ OK: 8/8 Fail: 0/8 Skip: 0/8
|
||||
OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||
|
||||
---TOTAL---
|
||||
OK: 160/163 Fail: 0/163 Skip: 3/163
|
||||
OK: 155/163 Fail: 0/163 Skip: 8/163
|
||||
|
@ -10,7 +10,7 @@ import
|
||||
algorithm, os, tables, strutils, times, math, terminal, random,
|
||||
|
||||
# Nimble packages
|
||||
stew/[objects, byteutils], stew/shims/macros,
|
||||
stew/[objects, byteutils, endians2], stew/shims/macros,
|
||||
chronos, confutils, metrics, json_rpc/[rpcserver, jsonmarshal],
|
||||
chronicles,
|
||||
json_serialization/std/[options, sets, net], serialization/errors,
|
||||
@ -18,8 +18,8 @@ import
|
||||
eth/p2p/enode, eth/[keys, async_utils], eth/p2p/discoveryv5/[protocol, enr],
|
||||
|
||||
# Local modules
|
||||
spec/[datatypes, digest, crypto, beaconstate, helpers, network],
|
||||
spec/state_transition, spec/presets/custom,
|
||||
spec/[datatypes, digest, crypto, beaconstate, helpers, network, presets],
|
||||
spec/state_transition,
|
||||
conf, time, beacon_chain_db, validator_pool, extras,
|
||||
attestation_pool, block_pool, eth2_network, eth2_discovery,
|
||||
beacon_node_common, beacon_node_types, block_pools/block_pools_types,
|
||||
@ -163,6 +163,7 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
|
||||
# TODO Could move this to a separate "GenesisMonitor" process or task
|
||||
# that would do only this - see Paul's proposal for this.
|
||||
mainchainMonitor = MainchainMonitor.init(
|
||||
conf.runtimePreset,
|
||||
web3Provider(conf.web3Url),
|
||||
conf.depositContractAddress.get,
|
||||
Eth1Data(block_hash: conf.depositContractDeployedAt.get, deposit_count: 0))
|
||||
@ -200,17 +201,16 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
|
||||
conf.stateSnapshotContents[] = ""
|
||||
|
||||
# TODO check that genesis given on command line (if any) matches database
|
||||
let blockPool = BlockPool.init(
|
||||
db,
|
||||
if conf.verifyFinalization:
|
||||
{verifyFinalization}
|
||||
else:
|
||||
{})
|
||||
let
|
||||
blockPoolFlags = if conf.verifyFinalization: {verifyFinalization}
|
||||
else: {}
|
||||
blockPool = BlockPool.init(conf.runtimePreset, db, blockPoolFlags)
|
||||
|
||||
if mainchainMonitor.isNil and
|
||||
conf.web3Url.len > 0 and
|
||||
conf.depositContractAddress.isSome:
|
||||
mainchainMonitor = MainchainMonitor.init(
|
||||
conf.runtimePreset,
|
||||
web3Provider(conf.web3Url),
|
||||
conf.depositContractAddress.get,
|
||||
blockPool.headState.data.data.eth1_data)
|
||||
@ -707,13 +707,19 @@ proc installDebugApiHandlers(rpcServer: RpcServer, node: BeaconNode) =
|
||||
|
||||
rpcServer.rpc("getSpecPreset") do () -> JsonNode:
|
||||
var res = newJObject()
|
||||
genCode:
|
||||
for setting in BeaconChainConstants:
|
||||
let
|
||||
settingSym = ident($setting)
|
||||
settingKey = newLit(toLowerAscii($setting))
|
||||
yield quote do:
|
||||
res[`settingKey`] = %`settingSym`
|
||||
genStmtList:
|
||||
for presetValue in PresetValue:
|
||||
if presetValue notin ignoredValues + runtimeValues:
|
||||
let
|
||||
settingSym = ident($presetValue)
|
||||
settingKey = newLit(toLowerAscii($presetValue))
|
||||
let f = quote do:
|
||||
res[`settingKey`] = %`settingSym`
|
||||
yield f
|
||||
|
||||
for field, value in fieldPairs(node.config.runtimePreset):
|
||||
res[field] = when value isnot Version: %value
|
||||
else: %value.toUInt64
|
||||
|
||||
return res
|
||||
|
||||
@ -1139,6 +1145,8 @@ programMain:
|
||||
fatal "Unrecognized network name", networkName
|
||||
quit 1
|
||||
|
||||
config.runtimePreset = metadata.runtimePreset
|
||||
|
||||
if config.cmd == noCommand:
|
||||
for node in metadata.bootstrapNodes:
|
||||
config.bootstrapNodes.add node
|
||||
@ -1161,6 +1169,8 @@ programMain:
|
||||
|
||||
config.depositContractAddress = some metadata.depositContractAddress
|
||||
config.depositContractDeployedAt = some metadata.depositContractDeployedAt
|
||||
else:
|
||||
config.runtimePreset = defaultRuntimePreset
|
||||
|
||||
case config.cmd
|
||||
of createTestnet:
|
||||
@ -1198,7 +1208,7 @@ programMain:
|
||||
else: waitFor getLatestEth1BlockHash(config.web3Url)
|
||||
var
|
||||
initialState = initialize_beacon_state_from_eth1(
|
||||
eth1Hash, startTime, deposits, {skipBlsValidation})
|
||||
defaultRuntimePreset, eth1Hash, startTime, deposits, {skipBlsValidation})
|
||||
|
||||
# https://github.com/ethereum/eth2.0-pm/tree/6e41fcf383ebeb5125938850d8e9b4e9888389b4/interop/mocked_start#create-genesis-state
|
||||
initialState.genesis_time = startTime
|
||||
@ -1267,6 +1277,7 @@ programMain:
|
||||
createDir(config.outSecretsDir)
|
||||
|
||||
let deposits = generateDeposits(
|
||||
config.runtimePreset,
|
||||
config.totalDeposits,
|
||||
config.outValidatorsDir,
|
||||
config.outSecretsDir)
|
||||
|
@ -8,7 +8,7 @@
|
||||
import
|
||||
extras, beacon_chain_db,
|
||||
stew/results,
|
||||
spec/[crypto, datatypes, digest]
|
||||
spec/[crypto, datatypes, digest, presets]
|
||||
|
||||
|
||||
import
|
||||
@ -64,9 +64,11 @@ export get_ancestor # func get_ancestor*(blck: BlockRef, slot: Slot): BlockRef
|
||||
export atSlot # func atSlot*(blck: BlockRef, slot: Slot): BlockSlot
|
||||
|
||||
|
||||
proc init*(T: type BlockPools, db: BeaconChainDB,
|
||||
updateFlags: UpdateFlags = {}): BlockPools =
|
||||
result.dag = init(CandidateChains, db, updateFlags)
|
||||
proc init*(T: type BlockPools,
|
||||
preset: RuntimePreset,
|
||||
db: BeaconChainDB,
|
||||
updateFlags: UpdateFlags = {}): BlockPools =
|
||||
result.dag = init(CandidateChains, preset, db, updateFlags)
|
||||
|
||||
export init # func init*(T: type BlockRef, root: Eth2Digest, blck: BeaconBlock): BlockRef
|
||||
|
||||
|
@ -123,6 +123,8 @@ type
|
||||
|
||||
updateFlags*: UpdateFlags
|
||||
|
||||
runtimePreset*: RuntimePreset
|
||||
|
||||
EpochRef* = ref object
|
||||
shuffled_active_validator_indices*: seq[ValidatorIndex]
|
||||
epoch*: Epoch
|
||||
|
@ -189,8 +189,10 @@ func init(T: type BlockRef, root: Eth2Digest, slot: Slot): BlockRef =
|
||||
func init*(T: type BlockRef, root: Eth2Digest, blck: SomeBeaconBlock): BlockRef =
|
||||
BlockRef.init(root, blck.slot)
|
||||
|
||||
proc init*(T: type CandidateChains, db: BeaconChainDB,
|
||||
updateFlags: UpdateFlags = {}): CandidateChains =
|
||||
proc init*(T: type CandidateChains,
|
||||
preset: RuntimePreset,
|
||||
db: BeaconChainDB,
|
||||
updateFlags: UpdateFlags = {}): CandidateChains =
|
||||
# TODO we require that the db contains both a head and a tail block -
|
||||
# asserting here doesn't seem like the right way to go about it however..
|
||||
|
||||
@ -291,7 +293,8 @@ proc init*(T: type CandidateChains, db: BeaconChainDB,
|
||||
|
||||
# The only allowed flag right now is verifyFinalization, as the others all
|
||||
# allow skipping some validation.
|
||||
updateFlags: {verifyFinalization} * updateFlags
|
||||
updateFlags: {verifyFinalization} * updateFlags,
|
||||
runtimePreset: preset,
|
||||
)
|
||||
|
||||
doAssert res.updateFlags in [{}, {verifyFinalization}]
|
||||
@ -501,7 +504,8 @@ proc skipAndUpdateState(
|
||||
|
||||
var stateCache = getEpochCache(blck.refs, state.data.data)
|
||||
let ok = state_transition(
|
||||
state.data, blck.data, stateCache, flags + dag.updateFlags, restore)
|
||||
dag.runtimePreset, state.data, blck.data,
|
||||
stateCache, flags + dag.updateFlags, restore)
|
||||
|
||||
if ok and save:
|
||||
dag.putState(state.data, blck.refs)
|
||||
|
@ -207,8 +207,8 @@ proc add*(
|
||||
assign(poolPtr.tmpState, poolPtr.headState)
|
||||
|
||||
var stateCache = getEpochCache(parent, dag.tmpState.data.data)
|
||||
if not state_transition(
|
||||
dag.tmpState.data, signedBlock, stateCache, dag.updateFlags, restore):
|
||||
if not state_transition(dag.runtimePreset, dag.tmpState.data, signedBlock,
|
||||
stateCache, dag.updateFlags, restore):
|
||||
# TODO find a better way to log all this block data
|
||||
notice "Invalid block",
|
||||
blck = shortLog(blck),
|
||||
|
@ -134,6 +134,8 @@ type
|
||||
stateSnapshotContents* {.hidden.}: ref string
|
||||
# This is ref so we can mutate it (to erase it) after the initial loading.
|
||||
|
||||
runtimePreset* {.hidden.}: RuntimePreset
|
||||
|
||||
nodeName* {.
|
||||
defaultValue: ""
|
||||
desc: "A name for this node that will appear in the logs. " &
|
||||
|
@ -36,6 +36,7 @@ const eth1BlockHash* = block:
|
||||
x
|
||||
|
||||
func makeDeposit*(
|
||||
preset: RuntimePreset,
|
||||
pubkey: ValidatorPubKey, privkey: ValidatorPrivKey, epoch = 0.Epoch,
|
||||
amount: Gwei = MAX_EFFECTIVE_BALANCE.Gwei,
|
||||
flags: UpdateFlags = {}): Deposit =
|
||||
@ -47,6 +48,6 @@ func makeDeposit*(
|
||||
withdrawal_credentials: makeWithdrawalCredentials(pubkey)))
|
||||
|
||||
if skipBLSValidation notin flags:
|
||||
ret.data.signature = get_deposit_signature(ret.data, privkey)
|
||||
ret.data.signature = preset.get_deposit_signature(ret.data, privkey)
|
||||
|
||||
ret
|
||||
|
@ -102,7 +102,8 @@ type
|
||||
FailedToCreateKeystoreFile
|
||||
FailedToCreateDepositFile
|
||||
|
||||
proc generateDeposits*(totalValidators: int,
|
||||
proc generateDeposits*(preset: RuntimePreset,
|
||||
totalValidators: int,
|
||||
validatorsDir: string,
|
||||
secretsDir: string): Result[seq[Deposit], GenerateDepositsError] =
|
||||
var deposits: seq[Deposit]
|
||||
@ -131,7 +132,7 @@ proc generateDeposits*(totalValidators: int,
|
||||
try: writeFile(keystoreFile, credentials.keyStore.string)
|
||||
except IOError: return err FailedToCreateKeystoreFile
|
||||
|
||||
deposits.add credentials.prepareDeposit()
|
||||
deposits.add credentials.prepareDeposit(preset)
|
||||
|
||||
# Does quadratic additional work, but fast enough, and otherwise more
|
||||
# cleanly allows free intermixing of pre-existing and newly generated
|
||||
|
@ -50,6 +50,7 @@ type
|
||||
allDeposits*: seq[Deposit]
|
||||
|
||||
MainchainMonitor* = ref object
|
||||
preset: RuntimePreset
|
||||
depositContractAddress: Address
|
||||
dataProviderFactory*: DataProviderFactory
|
||||
|
||||
@ -95,19 +96,16 @@ const
|
||||
reorgDepthLimit = 1000
|
||||
web3Timeouts = 5.seconds
|
||||
followDistanceInSeconds = uint64(SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE)
|
||||
totalDepositsNeededForGenesis = uint64 max(SLOTS_PER_EPOCH,
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT)
|
||||
|
||||
# TODO: Add preset validation
|
||||
# MIN_GENESIS_ACTIVE_VALIDATOR_COUNT should be larger than SLOTS_PER_EPOCH
|
||||
# doAssert SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE < GENESIS_DELAY,
|
||||
# "Invalid configuration: GENESIS_DELAY is set too low"
|
||||
|
||||
# TODO Nim's analysis on the lock level of the methods in this
|
||||
# module seems broken. Investigate and file this as an issue.
|
||||
{.push warning[LockLevel]: off.}
|
||||
|
||||
static:
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#genesis
|
||||
when SPEC_VERSION == "0.12.1":
|
||||
doAssert SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE < GENESIS_DELAY,
|
||||
"Invalid configuration: GENESIS_DELAY is set too low"
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#get_eth1_data
|
||||
func compute_time_at_slot(state: BeaconState, slot: Slot): uint64 =
|
||||
state.genesis_time + slot * SECONDS_PER_SLOT
|
||||
@ -460,56 +458,63 @@ template getBlockProposalData*(m: MainchainMonitor, state: BeaconState): untyped
|
||||
getBlockProposalData(m.eth1Chain, state)
|
||||
|
||||
proc init*(T: type MainchainMonitor,
|
||||
preset: RuntimePreset,
|
||||
dataProviderFactory: DataProviderFactory,
|
||||
depositContractAddress: Eth1Address,
|
||||
startPosition: Eth1Data): T =
|
||||
T(depositQueue: newAsyncQueue[Eth1BlockHeader](),
|
||||
T(preset: preset,
|
||||
depositQueue: newAsyncQueue[Eth1BlockHeader](),
|
||||
dataProviderFactory: dataProviderFactory,
|
||||
depositContractAddress: Address depositContractAddress,
|
||||
eth1Chain: Eth1Chain(knownStart: startPosition))
|
||||
|
||||
proc isCandidateForGenesis(timeNow: float, blk: Eth1Block): bool =
|
||||
proc isCandidateForGenesis(preset: RuntimePreset,
|
||||
timeNow: float,
|
||||
blk: Eth1Block): bool =
|
||||
if float(blk.timestamp + followDistanceInSeconds) > timeNow:
|
||||
return false
|
||||
|
||||
if genesis_time_from_eth1_timestamp(blk.timestamp) < MIN_GENESIS_TIME:
|
||||
if genesis_time_from_eth1_timestamp(preset, blk.timestamp) < preset.MIN_GENESIS_TIME:
|
||||
return false
|
||||
|
||||
if blk.knownGoodDepositsCount.isSome:
|
||||
blk.knownGoodDepositsCount.get >= totalDepositsNeededForGenesis
|
||||
blk.knownGoodDepositsCount.get >= preset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||
else:
|
||||
blk.voteData.deposit_count >= totalDepositsNeededForGenesis
|
||||
blk.voteData.deposit_count >= preset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||
|
||||
proc minGenesisCandidateBlockIdx(eth1Chain: Eth1Chain): Option[int]
|
||||
proc minGenesisCandidateBlockIdx(m: MainchainMonitor): Option[int]
|
||||
{.raises: [Defect].} =
|
||||
if eth1Chain.blocks.len == 0:
|
||||
if m.eth1Chain.blocks.len == 0:
|
||||
return
|
||||
|
||||
let now = epochTime()
|
||||
if not isCandidateForGenesis(now, eth1Chain.blocks.peekLast):
|
||||
if not isCandidateForGenesis(m.preset, now, m.eth1Chain.blocks.peekLast):
|
||||
return
|
||||
|
||||
var candidatePos = eth1Chain.blocks.len - 1
|
||||
var candidatePos = m.eth1Chain.blocks.len - 1
|
||||
while candidatePos > 1:
|
||||
if not isCandidateForGenesis(now, eth1Chain.blocks[candidatePos - 1]):
|
||||
if not isCandidateForGenesis(m.preset, now, m.eth1Chain.blocks[candidatePos - 1]):
|
||||
break
|
||||
dec candidatePos
|
||||
|
||||
return some(candidatePos)
|
||||
|
||||
proc createBeaconStateAux(eth1Block: Eth1Block,
|
||||
proc createBeaconStateAux(preset: RuntimePreset,
|
||||
eth1Block: Eth1Block,
|
||||
deposits: var openarray[Deposit]): BeaconStateRef =
|
||||
attachMerkleProofs deposits
|
||||
result = initialize_beacon_state_from_eth1(eth1Block.voteData.block_hash,
|
||||
result = initialize_beacon_state_from_eth1(preset,
|
||||
eth1Block.voteData.block_hash,
|
||||
eth1Block.timestamp.uint64,
|
||||
deposits, {})
|
||||
let activeValidators = get_active_validator_indices(result[], GENESIS_EPOCH)
|
||||
eth1Block.knownGoodDepositsCount = some len(activeValidators).uint64
|
||||
|
||||
proc createBeaconState(eth1Chain: var Eth1Chain, eth1Block: Eth1Block): BeaconStateRef =
|
||||
proc createBeaconState(m: MainchainMonitor, eth1Block: Eth1Block): BeaconStateRef =
|
||||
createBeaconStateAux(
|
||||
m.preset,
|
||||
eth1Block,
|
||||
eth1Chain.allDeposits.toOpenArray(0, int(eth1Block.voteData.deposit_count - 1)))
|
||||
m.eth1Chain.allDeposits.toOpenArray(0, int(eth1Block.voteData.deposit_count - 1)))
|
||||
|
||||
proc signalGenesis(m: MainchainMonitor, genesisState: BeaconStateRef) =
|
||||
m.genesisState = genesisState
|
||||
@ -534,7 +539,8 @@ proc findGenesisBlockInRange(m: MainchainMonitor,
|
||||
|
||||
while startBlock.number + 1 < endBlock.number:
|
||||
let
|
||||
startBlockTime = genesis_time_from_eth1_timestamp(startBlock.timestamp)
|
||||
MIN_GENESIS_TIME = m.preset.MIN_GENESIS_TIME
|
||||
startBlockTime = genesis_time_from_eth1_timestamp(m.preset, startBlock.timestamp)
|
||||
secondsPerBlock = float(endBlock.timestamp - startBlock.timestamp) /
|
||||
float(endBlock.number - startBlock.number)
|
||||
blocksToJump = max(float(MIN_GENESIS_TIME - startBlockTime) / secondsPerBlock, 1.0)
|
||||
@ -546,11 +552,14 @@ proc findGenesisBlockInRange(m: MainchainMonitor,
|
||||
voteData: depositData)
|
||||
candidateAsEth1Block.voteData.block_hash = candidateBlock.hash.asEth2Digest
|
||||
|
||||
let candidateGenesisTime = genesis_time_from_eth1_timestamp(
|
||||
m.preset, candidateBlock.timestamp.uint64)
|
||||
|
||||
info "Probing possible genesis block",
|
||||
`block` = candidateBlock.number.uint64,
|
||||
timestamp = genesis_time_from_eth1_timestamp(candidateBlock.timestamp.uint64)
|
||||
candidateGenesisTime
|
||||
|
||||
if genesis_time_from_eth1_timestamp(candidateBlock.timestamp.uint64) < MIN_GENESIS_TIME:
|
||||
if candidateGenesisTime < MIN_GENESIS_TIME:
|
||||
startBlock = candidateAsEth1Block
|
||||
else:
|
||||
endBlock = candidateAsEth1Block
|
||||
@ -563,14 +572,14 @@ proc checkForGenesisLoop(m: MainchainMonitor) {.async.} =
|
||||
return
|
||||
|
||||
try:
|
||||
let genesisCandidateIdx = m.eth1Chain.minGenesisCandidateBlockIdx
|
||||
let genesisCandidateIdx = m.minGenesisCandidateBlockIdx
|
||||
if genesisCandidateIdx.isSome:
|
||||
let
|
||||
genesisCandidateIdx = genesisCandidateIdx.get
|
||||
genesisCandidate = m.eth1Chain.blocks[genesisCandidateIdx]
|
||||
candidateState = m.eth1Chain.createBeaconState(genesisCandidate)
|
||||
candidateState = m.createBeaconState(genesisCandidate)
|
||||
|
||||
if genesisCandidate.knownGoodDepositsCount.get >= totalDepositsNeededForGenesis:
|
||||
if genesisCandidate.knownGoodDepositsCount.get >= m.preset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
|
||||
# We have a candidate state on our hands, but our current Eth1Chain
|
||||
# may consist only of blocks that have deposits attached to them
|
||||
# while the real genesis may have happened in a block without any
|
||||
@ -589,13 +598,13 @@ proc checkForGenesisLoop(m: MainchainMonitor) {.async.} =
|
||||
if preceedingEth1Block.voteData.deposit_root == genesisCandidate.voteData.deposit_root:
|
||||
preceedingEth1Block.knownGoodDepositsCount = genesisCandidate.knownGoodDepositsCount
|
||||
else:
|
||||
discard m.eth1Chain.createBeaconState(preceedingEth1Block)
|
||||
discard m.createBeaconState(preceedingEth1Block)
|
||||
|
||||
if preceedingEth1Block.knownGoodDepositsCount.get >= totalDepositsNeededForGenesis and
|
||||
if preceedingEth1Block.knownGoodDepositsCount.get >= m.preset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT and
|
||||
genesisCandidate.number - preceedingEth1Block.number > 1:
|
||||
let genesisBlock = await m.findGenesisBlockInRange(preceedingEth1Block, genesisCandidate)
|
||||
if genesisBlock.number != genesisCandidate.number:
|
||||
m.signalGenesis m.eth1Chain.createBeaconState(genesisBlock)
|
||||
m.signalGenesis m.createBeaconState(genesisBlock)
|
||||
return
|
||||
|
||||
m.signalGenesis candidateState
|
||||
@ -604,7 +613,7 @@ proc checkForGenesisLoop(m: MainchainMonitor) {.async.} =
|
||||
info "Eth2 genesis candidate block rejected",
|
||||
`block` = shortLog(genesisCandidate),
|
||||
validDeposits = genesisCandidate.knownGoodDepositsCount.get,
|
||||
needed = totalDepositsNeededForGenesis
|
||||
needed = m.preset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||
else:
|
||||
# TODO: check for a stale monitor
|
||||
discard
|
||||
@ -678,7 +687,7 @@ proc processDeposits(m: MainchainMonitor,
|
||||
let eth1Blocks = await dataProvider.fetchDepositData(latestKnownBlock + 1,
|
||||
Eth1BlockNumber blk.number)
|
||||
if eth1Blocks.len == 0:
|
||||
if m.eth1Chain.maxValidDeposits > totalDepositsNeededForGenesis and
|
||||
if m.eth1Chain.maxValidDeposits > m.preset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT and
|
||||
m.eth1Chain.knownStart.deposit_count == 0:
|
||||
let latestEth1Data = m.eth1Chain.latestEth1Data
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import
|
||||
os, strutils,
|
||||
tables, strutils, os,
|
||||
stew/byteutils, stew/shims/macros, nimcrypto/hash,
|
||||
eth/common/[eth_types, eth_types_json_serialization],
|
||||
spec/presets/custom
|
||||
spec/presets
|
||||
|
||||
# ATTENTION! This file will produce a large C file, because we are inlining
|
||||
# genesis states as C literals in the generated code (and blobs in the final
|
||||
@ -15,7 +15,7 @@ import
|
||||
{.push raises: [Defect].}
|
||||
|
||||
export
|
||||
eth_types_json_serialization
|
||||
eth_types_json_serialization, RuntimePreset
|
||||
|
||||
type
|
||||
Eth1Address* = eth_types.EthAddress
|
||||
@ -56,37 +56,46 @@ type
|
||||
# unknown genesis state.
|
||||
genesisData*: string
|
||||
|
||||
const presetValueLoaders = genCode(nnkBracket):
|
||||
const presetValueLoaders = genExpr(nnkBracket):
|
||||
for constName in PresetValue:
|
||||
let
|
||||
constNameIdent = ident $constName
|
||||
constType = ident getType(constName)
|
||||
|
||||
yield quote do:
|
||||
proc (preset: RuntimePreset, presetValue: string): bool
|
||||
{.gcsafe, noSideEffect, raises: [Defect].} =
|
||||
try:
|
||||
when `constNameIdent` in runtimeValues:
|
||||
preset.`constNameIdent` = parse(`constType`, presetValue)
|
||||
true
|
||||
else:
|
||||
`constNameIdent` == parse(`constType`, presetValue)
|
||||
except CatchableError:
|
||||
false
|
||||
(
|
||||
proc (preset: var RuntimePreset, presetValue: string): bool
|
||||
{.gcsafe, noSideEffect, raises: [Defect].} =
|
||||
try:
|
||||
when PresetValue.`constNameIdent` in runtimeValues:
|
||||
preset.`constNameIdent` = parse(`constType`, presetValue)
|
||||
true
|
||||
elif PresetValue.`constNameIdent` in ignoredValues:
|
||||
true
|
||||
else:
|
||||
`constType`(`constNameIdent`) == parse(`constType`, presetValue)
|
||||
except CatchableError as err:
|
||||
false
|
||||
)
|
||||
|
||||
proc extractRuntimePreset*(configPath: string, configData: PresetFile): RuntimePreset
|
||||
{.raises: [PresetIncompatible, Defect].} =
|
||||
result = RuntimePreset()
|
||||
|
||||
for name, value in configData.values:
|
||||
if name notin runtimeValues:
|
||||
if not presetValueLoaders[name.int](result, value):
|
||||
let errMsg = "The preset '" & configPath & "'is not compatible with " &
|
||||
"the current build due to an incompatible value " &
|
||||
$name & " = " & value.string
|
||||
raise newException(PresetIncompatible, errMsg)
|
||||
|
||||
proc loadEth2NetworkMetadata*(path: string): Eth2NetworkMetadata
|
||||
{.raises: [CatchableError, Defect].} =
|
||||
let
|
||||
genesisPath = path / "genesis.ssz"
|
||||
config = readPresetFile(path / "config.yaml")
|
||||
|
||||
var runtimePreset = RuntimePreset()
|
||||
|
||||
for name, value in config.values:
|
||||
if name notin runtimeValues:
|
||||
if not presetValueLoaders[name](runtimePreset, value):
|
||||
raise newException(PresetIncompatible,
|
||||
"The preset '{path}' is not compatible with the current build due to an incompatible value {name} = {value}")
|
||||
configPath = path / "config.yaml"
|
||||
runtimePreset = extractRuntimePreset(configPath, readPresetFile(configPath))
|
||||
|
||||
Eth2NetworkMetadata(
|
||||
eth1Network: goerli,
|
||||
@ -96,20 +105,17 @@ proc loadEth2NetworkMetadata*(path: string): Eth2NetworkMetadata
|
||||
depositContractDeployedAt: Eth1BlockHash.fromHex readFile(path / "deposit_contract_block.txt").strip,
|
||||
genesisData: if fileExists(genesisPath): readFile(genesisPath) else: "")
|
||||
|
||||
const
|
||||
mainnetMetadata* = Eth2NetworkMetadata(
|
||||
eth1Network: mainnet,
|
||||
runtimePreset: RuntimePreset(
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384,
|
||||
MIN_GENESIS_TIME: 1578009600,
|
||||
GENESIS_FORK_VERSION: [byte 0, 0, 0, 0],
|
||||
GENESIS_DELAY: 172800),
|
||||
# TODO The values below are just placeholders for now
|
||||
bootstrapNodes: @[],
|
||||
depositContractAddress: "0x1234567890123456789012345678901234567890",
|
||||
depositContractDeployedAt: "",
|
||||
genesisData: "")
|
||||
when const_preset == "mainnet":
|
||||
const
|
||||
mainnetMetadata* = Eth2NetworkMetadata(
|
||||
eth1Network: mainnet,
|
||||
runtimePreset: mainnetRuntimePreset,
|
||||
# TODO The values below are just placeholders for now
|
||||
bootstrapNodes: @[],
|
||||
depositContractAddress: Eth1Address.fromHex "0x1234567890123456789012345678901234567890",
|
||||
depositContractDeployedAt: Eth1BlockHash.fromHex "0x73056f16a59bf70abad5b4365438e8a7d646aa0d7f56d22c3d9e4c6000d8e176",
|
||||
genesisData: "")
|
||||
|
||||
altonaMetadata* = loadEth2NetworkMetadata(
|
||||
currentSourcePath.parentDir / ".." / "vendor" / "eth2-testnets" / "shared" / "altona")
|
||||
altonaMetadata* = loadEth2NetworkMetadata(
|
||||
currentSourcePath.parentDir / ".." / "vendor" / "eth2-testnets" / "shared" / "altona")
|
||||
|
||||
|
@ -50,8 +50,10 @@ func decrease_balance*(
|
||||
state.balances[index] - delta
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#deposits
|
||||
proc process_deposit*(
|
||||
state: var BeaconState, deposit: Deposit, flags: UpdateFlags = {}): bool {.nbench.}=
|
||||
proc process_deposit*(preset: RuntimePreset,
|
||||
state: var BeaconState,
|
||||
deposit: Deposit,
|
||||
flags: UpdateFlags = {}): bool {.nbench.}=
|
||||
# Process an Eth1 deposit, registering a validator or increasing its balance.
|
||||
|
||||
# Verify the Merkle branch
|
||||
@ -80,7 +82,7 @@ proc process_deposit*(
|
||||
# Verify the deposit signature (proof of possession) which is not checked
|
||||
# by the deposit contract
|
||||
if skipBLSValidation notin flags:
|
||||
if not verify_deposit_signature(deposit.data):
|
||||
if not verify_deposit_signature(preset, deposit.data):
|
||||
# It's ok that deposits fail - they get included in blocks regardless
|
||||
# TODO spec test?
|
||||
# TODO: This is temporary set to trace level in order to deal with the
|
||||
@ -194,16 +196,17 @@ proc slash_validator*(state: var BeaconState, slashed_index: ValidatorIndex,
|
||||
increase_balance(
|
||||
state, whistleblower_index, whistleblowing_reward - proposer_reward)
|
||||
|
||||
func genesis_time_from_eth1_timestamp*(eth1_timestamp: uint64): uint64 =
|
||||
func genesis_time_from_eth1_timestamp*(preset: RuntimePreset, eth1_timestamp: uint64): uint64 =
|
||||
# TODO: remove once we switch completely to v0.12.1
|
||||
when SPEC_VERSION == "0.12.1":
|
||||
eth1_timestamp + GENESIS_DELAY
|
||||
eth1_timestamp + preset.GENESIS_DELAY
|
||||
else:
|
||||
const SECONDS_PER_DAY = uint64(60*60*24)
|
||||
eth1_timestamp + 2'u64 * SECONDS_PER_DAY - (eth1_timestamp mod SECONDS_PER_DAY)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#genesis
|
||||
proc initialize_beacon_state_from_eth1*(
|
||||
preset: RuntimePreset,
|
||||
eth1_block_hash: Eth2Digest,
|
||||
eth1_timestamp: uint64,
|
||||
deposits: openArray[Deposit],
|
||||
@ -226,10 +229,10 @@ proc initialize_beacon_state_from_eth1*(
|
||||
|
||||
var state = BeaconStateRef(
|
||||
fork: Fork(
|
||||
previous_version: GENESIS_FORK_VERSION,
|
||||
current_version: GENESIS_FORK_VERSION,
|
||||
previous_version: preset.GENESIS_FORK_VERSION,
|
||||
current_version: preset.GENESIS_FORK_VERSION,
|
||||
epoch: GENESIS_EPOCH),
|
||||
genesis_time: genesis_time_from_eth1_timestamp(eth1_timestamp),
|
||||
genesis_time: genesis_time_from_eth1_timestamp(preset, eth1_timestamp),
|
||||
eth1_data:
|
||||
Eth1Data(block_hash: eth1_block_hash, deposit_count: uint64(len(deposits))),
|
||||
latest_block_header:
|
||||
@ -253,7 +256,7 @@ proc initialize_beacon_state_from_eth1*(
|
||||
for prefix_root in hash_tree_roots_prefix(
|
||||
leaves, 2'i64^DEPOSIT_CONTRACT_TREE_DEPTH):
|
||||
state.eth1_data.deposit_root = prefix_root
|
||||
discard process_deposit(state[], deposits[i], flags)
|
||||
discard process_deposit(preset, state[], deposits[i], flags)
|
||||
i += 1
|
||||
|
||||
# Process activations
|
||||
@ -275,19 +278,22 @@ proc initialize_beacon_state_from_eth1*(
|
||||
state
|
||||
|
||||
proc initialize_hashed_beacon_state_from_eth1*(
|
||||
preset: RuntimePreset,
|
||||
eth1_block_hash: Eth2Digest,
|
||||
eth1_timestamp: uint64,
|
||||
deposits: openArray[Deposit],
|
||||
flags: UpdateFlags = {}): HashedBeaconState =
|
||||
let genesisState = initialize_beacon_state_from_eth1(
|
||||
eth1_block_hash, eth1_timestamp, deposits, flags)
|
||||
preset, eth1_block_hash, eth1_timestamp, deposits, flags)
|
||||
HashedBeaconState(data: genesisState[], root: hash_tree_root(genesisState[]))
|
||||
|
||||
func is_valid_genesis_state*(state: BeaconState, active_validator_indices: seq[ValidatorIndex]): bool =
|
||||
if state.genesis_time < MIN_GENESIS_TIME:
|
||||
func is_valid_genesis_state*(preset: RuntimePreset,
|
||||
state: BeaconState,
|
||||
active_validator_indices: seq[ValidatorIndex]): bool =
|
||||
if state.genesis_time < preset.MIN_GENESIS_TIME:
|
||||
return false
|
||||
# This is an okay get_active_validator_indices(...) for the time being.
|
||||
if len(active_validator_indices) < MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
|
||||
if active_validator_indices.len.uint64 < preset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
|
||||
return false
|
||||
return true
|
||||
|
||||
|
@ -25,10 +25,10 @@ import
|
||||
macros, hashes, json, strutils, tables, typetraits,
|
||||
stew/[byteutils], chronicles,
|
||||
json_serialization/types as jsonTypes,
|
||||
../ssz/types as sszTypes, ./crypto, ./digest
|
||||
../ssz/types as sszTypes, ./crypto, ./digest, ./presets
|
||||
|
||||
export
|
||||
sszTypes
|
||||
sszTypes, presets
|
||||
|
||||
# TODO Data types:
|
||||
# Presently, we're reusing the data types from the serialization (uint64) in the
|
||||
@ -46,23 +46,6 @@ export
|
||||
# Eventually, we could also differentiate between user/tainted data and
|
||||
# internal state that's gone through sanity checks already.
|
||||
|
||||
# Constant presets
|
||||
const const_preset* {.strdefine.} = "mainnet"
|
||||
|
||||
when const_preset == "mainnet":
|
||||
import ./presets/v0_12_1/mainnet
|
||||
export mainnet
|
||||
elif const_preset == "minimal":
|
||||
import ./presets/v0_12_1/minimal
|
||||
export minimal
|
||||
else:
|
||||
type
|
||||
Slot* = distinct uint64
|
||||
Epoch* = distinct uint64
|
||||
|
||||
import ./presets/custom
|
||||
createConstantsFromPreset const_preset
|
||||
|
||||
const
|
||||
SPEC_VERSION* = "0.12.1" ## \
|
||||
## Spec version we're aiming to be compatible with, right now
|
||||
|
@ -158,7 +158,7 @@ func compute_fork_digest*(current_version: Version,
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#compute_domain
|
||||
func compute_domain*(
|
||||
domain_type: DomainType,
|
||||
fork_version = GENESIS_FORK_VERSION,
|
||||
fork_version: Version,
|
||||
genesis_validators_root: Eth2Digest = ZERO_HASH): Domain =
|
||||
# Return the domain for the ``domain_type`` and ``fork_version``.
|
||||
let fork_data_root =
|
||||
|
@ -459,6 +459,7 @@ proc makeWithdrawalCredentials*(k: ValidatorPubKey): Eth2Digest =
|
||||
bytes
|
||||
|
||||
proc prepareDeposit*(credentials: Credentials,
|
||||
preset: RuntimePreset,
|
||||
amount = MAX_EFFECTIVE_BALANCE.Gwei): Deposit =
|
||||
let
|
||||
withdrawalPubKey = credentials.withdrawalKey.toPubKey
|
||||
@ -471,6 +472,6 @@ proc prepareDeposit*(credentials: Credentials,
|
||||
pubkey: signingPubKey,
|
||||
withdrawal_credentials: makeWithdrawalCredentials(withdrawalPubKey)))
|
||||
|
||||
ret.data.signature = get_deposit_signature(ret.data, credentials.signingKey)
|
||||
|
||||
ret.data.signature = preset.get_deposit_signature(ret.data,
|
||||
credentials.signingKey)
|
||||
ret
|
||||
|
@ -2,10 +2,16 @@ import
|
||||
macros, strutils, parseutils, tables,
|
||||
stew/endians2
|
||||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
export
|
||||
toBytesBE
|
||||
|
||||
type
|
||||
Slot* = distinct uint64
|
||||
Epoch* = distinct uint64
|
||||
Version* = distinct array[4, byte]
|
||||
|
||||
PresetValue* {.pure.} = enum
|
||||
BASE_REWARD_FACTOR
|
||||
BLS_WITHDRAWAL_PREFIX
|
||||
@ -66,22 +72,35 @@ type
|
||||
VALIDATOR_REGISTRY_LIMIT
|
||||
WHISTLEBLOWER_REWARD_QUOTIENT
|
||||
|
||||
RuntimePreset* = object
|
||||
GENESIS_FORK_VERSION*: Version
|
||||
GENESIS_DELAY*: uint64
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT*: uint64
|
||||
MIN_GENESIS_TIME*: uint64
|
||||
|
||||
PresetFile* = object
|
||||
values*: Table[PresetValue, TaintedString]
|
||||
missingValues*: set[PresetValue]
|
||||
|
||||
PresetFileError* = object of CatchableError
|
||||
|
||||
const
|
||||
const_preset* {.strdefine.} = "mainnet"
|
||||
|
||||
runtimeValues* = {
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT,
|
||||
MIN_GENESIS_TIME,
|
||||
DEPOSIT_CONTRACT_ADDRESS,
|
||||
GENESIS_FORK_VERSION,
|
||||
GENESIS_DELAY,
|
||||
}
|
||||
|
||||
# These constants cannot really be overriden in a preset.
|
||||
# If we encounter them, we'll just ignore the preset value.
|
||||
ignoredValues = {
|
||||
ignoredValues* = {
|
||||
# The deposit contract address is loaded through a dedicated
|
||||
# metadata file. It would break the property we are exploiting
|
||||
# right now that all preset values can be parsed as uint64
|
||||
DEPOSIT_CONTRACT_ADDRESS
|
||||
DEPOSIT_CONTRACT_ADDRESS,
|
||||
|
||||
# These are defined as an enum in datatypes.nim:
|
||||
DOMAIN_BEACON_PROPOSER,
|
||||
@ -91,7 +110,6 @@ const
|
||||
DOMAIN_VOLUNTARY_EXIT,
|
||||
DOMAIN_SELECTION_PROOF,
|
||||
DOMAIN_AGGREGATE_AND_PROOF,
|
||||
DOMAIN_CUSTODY_BIT_SLASHING,
|
||||
}
|
||||
|
||||
presetValueTypes* = {
|
||||
@ -100,12 +118,14 @@ const
|
||||
EFFECTIVE_BALANCE_INCREMENT: "uint64",
|
||||
EJECTION_BALANCE: "uint64",
|
||||
EPOCHS_PER_SLASHINGS_VECTOR: "uint64",
|
||||
GENESIS_DELAY: "uint64",
|
||||
GENESIS_FORK_VERSION: "Version",
|
||||
GENESIS_SLOT: "Slot",
|
||||
INACTIVITY_PENALTY_QUOTIENT: "uint64",
|
||||
MAX_EFFECTIVE_BALANCE: "uint64",
|
||||
MIN_DEPOSIT_AMOUNT: "uint64",
|
||||
MIN_EPOCHS_TO_INACTIVITY_PENALTY: "uint64",
|
||||
MIN_GENESIS_TIME: "uint64",
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: "uint64",
|
||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: "uint64",
|
||||
PROPOSER_REWARD_QUOTIENT: "uint64",
|
||||
SECONDS_PER_SLOT: "uint64",
|
||||
@ -114,16 +134,26 @@ const
|
||||
|
||||
func parse*(T: type uint64, input: string): T
|
||||
{.raises: [ValueError, Defect].} =
|
||||
var res: BiggestUInt
|
||||
if input.len > 2 and input[0] == '0' and input[1] == 'x':
|
||||
parseHex(input, result)
|
||||
if parseHex(input, res) != input.len:
|
||||
raise newException(ValueError, "The constant value should be a valid hex integer")
|
||||
else:
|
||||
parseInt(input, result)
|
||||
if parseBiggestUInt(input, res) != input.len:
|
||||
raise newException(ValueError, "The constant value should be a valid unsigned integer")
|
||||
|
||||
result = uint64(res)
|
||||
|
||||
template parse*(T: type byte, input: string): T =
|
||||
byte parse(uint64, input)
|
||||
|
||||
proc parse*(T: type Version, input: string): T =
|
||||
toBytesBE(uint32 parse(uint64, input))
|
||||
template parse*(T: type int, input: string): T =
|
||||
# TODO: remove this
|
||||
int parse(uint64, input)
|
||||
|
||||
proc parse*(T: type Version, input: string): T
|
||||
{.raises: [ValueError, Defect].} =
|
||||
Version toBytesBE(uint32 parse(uint64, input))
|
||||
|
||||
template parse*(T: type Slot, input: string): T =
|
||||
Slot parse(uint64, input)
|
||||
@ -131,44 +161,24 @@ template parse*(T: type Slot, input: string): T =
|
||||
template getType*(presetValue: PresetValue): string =
|
||||
presetValueTypes.getOrDefault(presetValue, "int")
|
||||
|
||||
template toUInt64*(v: Version): uint64 =
|
||||
fromBytesBE(uint64, array[4, byte](v))
|
||||
|
||||
template entireSet(T: type enum): untyped =
|
||||
{low(T) .. high(T)}
|
||||
|
||||
macro genRuntimePresetType: untyped =
|
||||
var fields = newTree(nnkRecList)
|
||||
|
||||
for field in runtimeValues:
|
||||
fields.add newTree(nnkIdentDefs,
|
||||
ident $field,
|
||||
ident getType(field),
|
||||
newEmptyNode()) # default value
|
||||
|
||||
result = newTree(nnkObjectTy,
|
||||
newEmptyNode(), # pragmas
|
||||
newEmptyNode(), # base type
|
||||
fields)
|
||||
|
||||
type
|
||||
RuntimePresetObj* = genRuntimePresetType()
|
||||
RuntimePreset* = ref RuntimePresetObj
|
||||
|
||||
PresetFile = object
|
||||
values*: Table[PresetValue, TaintedString]
|
||||
missingValues*: set[PresetValue]
|
||||
|
||||
PresetFileError = object of CatchableError
|
||||
|
||||
proc readPresetFile(path: string): PresetFile
|
||||
{.raises: [IOError, PresetFileError, Defect].} =
|
||||
proc readPresetFile*(path: string): PresetFile
|
||||
{.raises: [IOError, PresetFileError, Defect].} =
|
||||
var
|
||||
lineNum = 0
|
||||
presetValues = ignoredValues
|
||||
|
||||
template lineinfo: string =
|
||||
"$1($2) " % [path, $lineNum]
|
||||
try: "$1($2) " % [path, $lineNum]
|
||||
except ValueError: path
|
||||
|
||||
template fail(msg) =
|
||||
raise newException(PresetFileError, lineinfo & msg)
|
||||
raise newException(PresetFileError, lineinfo() & msg)
|
||||
|
||||
for line in splitLines(readFile(path)):
|
||||
inc lineNum
|
||||
@ -183,24 +193,58 @@ proc readPresetFile(path: string): PresetFile
|
||||
|
||||
if value in ignoredValues: continue
|
||||
presetValues.incl value
|
||||
result.add value, lineParts[1]
|
||||
result.values.add value, lineParts[1].strip
|
||||
|
||||
result.missingValues = PresetValue.entireSet - presetValues
|
||||
|
||||
macro createConstantsFromPreset*(path: static string): untyped =
|
||||
result = newStmtList()
|
||||
const
|
||||
mainnetRuntimePreset* = RuntimePreset(
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384,
|
||||
MIN_GENESIS_TIME: 1578009600,
|
||||
GENESIS_FORK_VERSION: Version [byte 0, 0, 0, 0],
|
||||
GENESIS_DELAY: 172800)
|
||||
|
||||
let preset = try: loadPreset(path)
|
||||
except PresetError as err: error err.msg
|
||||
minimalRuntimePreset* = RuntimePreset(
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 64,
|
||||
MIN_GENESIS_TIME: 1578009600,
|
||||
GENESIS_FORK_VERSION: Version [byte 0, 0, 0, 1],
|
||||
GENESIS_DELAY: 300)
|
||||
|
||||
for name, value in preset:
|
||||
var value = value
|
||||
if presetValueTypes.hasKey(name):
|
||||
let typ = presetValueTypes[name]
|
||||
value = typ & "(" & value & ")"
|
||||
when const_preset == "mainnet":
|
||||
template defaultRuntimePreset*: auto = mainnetRuntimePreset
|
||||
import ./presets/v0_12_1/mainnet
|
||||
export mainnet
|
||||
|
||||
result.add parseStmt("const $1* {.intdefine.} = $2" % [name, value])
|
||||
elif const_preset == "minimal":
|
||||
template defaultRuntimePreset*: auto = minimalRuntimePreset
|
||||
import ./presets/v0_12_1/minimal
|
||||
export minimal
|
||||
|
||||
if preset.missingValues.card > 0:
|
||||
warning "Missing constants in preset: " & $preset.missingValues
|
||||
else:
|
||||
macro createConstantsFromPreset*(path: static string): untyped =
|
||||
result = newStmtList()
|
||||
|
||||
let preset = try: readPresetFile(path)
|
||||
except CatchableError as err:
|
||||
error err.msg # TODO: This should be marked as noReturn
|
||||
return
|
||||
|
||||
for name, value in preset.values:
|
||||
var value = string value
|
||||
if presetValueTypes.hasKey(name):
|
||||
let typ = presetValueTypes[name]
|
||||
value = typ & "(" & value & ")"
|
||||
|
||||
result.add parseStmt("const $1* {.intdefine.} = $2" % [$name, value])
|
||||
|
||||
if preset.missingValues.card > 0:
|
||||
warning "Missing constants in preset: " & $preset.missingValues
|
||||
|
||||
createConstantsFromPreset const_preset
|
||||
|
||||
const defaultRuntimePreset* = RuntimePreset(
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: MIN_GENESIS_ACTIVE_VALIDATOR_COUNT,
|
||||
MIN_GENESIS_TIME: MIN_GENESIS_TIME,
|
||||
GENESIS_FORK_VERSION: GENESIS_FORK_VERSION,
|
||||
GENESIS_DELAY: GENESIS_DELAY)
|
||||
|
@ -11,11 +11,6 @@
|
||||
import
|
||||
math
|
||||
|
||||
type
|
||||
Slot* = distinct uint64
|
||||
Epoch* = distinct uint64
|
||||
Version* = distinct array[4, byte]
|
||||
|
||||
{.experimental: "codeReordering".} # SLOTS_PER_EPOCH is use before being defined in spec
|
||||
|
||||
const
|
||||
|
@ -11,11 +11,6 @@
|
||||
import
|
||||
math
|
||||
|
||||
type
|
||||
Slot* = distinct uint64
|
||||
Epoch* = distinct uint64
|
||||
Version* = distinct array[4, byte]
|
||||
|
||||
{.experimental: "codeReordering".} # SLOTS_PER_EPOCH is use before being defined in spec
|
||||
|
||||
const
|
||||
|
@ -8,7 +8,8 @@
|
||||
{.push raises: [Defect].}
|
||||
|
||||
import
|
||||
./crypto, ./digest, ./datatypes, ./helpers, ../ssz/merkleization
|
||||
../ssz/merkleization,
|
||||
./crypto, ./digest, ./datatypes, ./helpers, ./presets
|
||||
|
||||
template withTrust(sig: SomeSig, body: untyped): bool =
|
||||
when sig is TrustedSig:
|
||||
@ -114,23 +115,23 @@ func verify_attestation_signature*(
|
||||
blsFastAggregateVerify(pubkeys, signing_root.data, signature)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#deposits
|
||||
func get_deposit_signature*(
|
||||
deposit: DepositData,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
|
||||
func get_deposit_signature*(preset: RuntimePreset,
|
||||
deposit: DepositData,
|
||||
privkey: ValidatorPrivKey): ValidatorSig =
|
||||
let
|
||||
deposit_message = deposit.getDepositMessage()
|
||||
# Fork-agnostic domain since deposits are valid across forks
|
||||
domain = compute_domain(DOMAIN_DEPOSIT)
|
||||
domain = compute_domain(DOMAIN_DEPOSIT, preset.GENESIS_FORK_VERSION)
|
||||
signing_root = compute_signing_root(deposit_message, domain)
|
||||
|
||||
blsSign(privKey, signing_root.data)
|
||||
|
||||
func verify_deposit_signature*(deposit: DepositData): bool =
|
||||
func verify_deposit_signature*(preset: RuntimePreset,
|
||||
deposit: DepositData): bool =
|
||||
let
|
||||
deposit_message = deposit.getDepositMessage()
|
||||
# Fork-agnostic domain since deposits are valid across forks
|
||||
domain = compute_domain(DOMAIN_DEPOSIT)
|
||||
domain = compute_domain(DOMAIN_DEPOSIT, preset.GENESIS_FORK_VERSION)
|
||||
signing_root = compute_signing_root(deposit_message, domain)
|
||||
|
||||
blsVerify(deposit.pubkey, signing_root.data, deposit.signature)
|
||||
|
@ -174,6 +174,7 @@ proc noRollback*(state: var HashedBeaconState) =
|
||||
trace "Skipping rollback of broken state"
|
||||
|
||||
proc state_transition*(
|
||||
preset: RuntimePreset,
|
||||
state: var HashedBeaconState, signedBlock: SomeSignedBeaconBlock,
|
||||
# TODO this is ... okay, but not perfect; align with EpochRef
|
||||
stateCache: var StateCache,
|
||||
@ -229,7 +230,7 @@ proc state_transition*(
|
||||
trace "in state_transition: processing block, signature passed",
|
||||
signature = signedBlock.signature,
|
||||
blockRoot = hash_tree_root(signedBlock.message)
|
||||
if process_block(state.data, signedBlock.message, flags, stateCache):
|
||||
if process_block(preset, state.data, signedBlock.message, flags, stateCache):
|
||||
if skipStateRootValidation in flags or verifyStateRoot(state.data, signedBlock.message):
|
||||
# State root is what it should be - we're done!
|
||||
|
||||
@ -249,6 +250,7 @@ proc state_transition*(
|
||||
false
|
||||
|
||||
proc state_transition*(
|
||||
preset: RuntimePreset,
|
||||
state: var HashedBeaconState, signedBlock: SomeSignedBeaconBlock,
|
||||
flags: UpdateFlags, rollback: RollbackHashedProc): bool {.nbench.} =
|
||||
# TODO consider moving this to testutils or similar, since non-testing
|
||||
@ -260,12 +262,13 @@ proc state_transition*(
|
||||
cache.shuffled_active_validator_indices[state.data.slot.compute_epoch_at_slot] =
|
||||
get_shuffled_active_validator_indices(
|
||||
state.data, state.data.slot.compute_epoch_at_slot)
|
||||
state_transition(state, signedBlock, cache, flags, rollback)
|
||||
state_transition(preset, state, signedBlock, cache, flags, rollback)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md
|
||||
# TODO There's more to do here - the spec has helpers that deal set up some of
|
||||
# the fields in here!
|
||||
proc makeBeaconBlock*(
|
||||
preset: RuntimePreset,
|
||||
state: var HashedBeaconState,
|
||||
proposer_index: ValidatorIndex,
|
||||
parent_root: Eth2Digest,
|
||||
@ -294,7 +297,7 @@ proc makeBeaconBlock*(
|
||||
attestations: List[Attestation, MAX_ATTESTATIONS](attestations),
|
||||
deposits: List[Deposit, MAX_DEPOSITS](deposits)))
|
||||
|
||||
let ok = process_block(state.data, blck, {skipBlsValidation}, cache)
|
||||
let ok = process_block(preset, state.data, blck, {skipBlsValidation}, cache)
|
||||
|
||||
if not ok:
|
||||
warn "Unable to apply new block to state", blck = shortLog(blck)
|
||||
|
@ -33,7 +33,7 @@ import
|
||||
algorithm, collections/sets, chronicles, options, sequtils, sets,
|
||||
../extras, ../ssz/merkleization, metrics,
|
||||
./beaconstate, ./crypto, ./datatypes, ./digest, ./helpers, ./validator,
|
||||
./signatures,
|
||||
./signatures, ./presets,
|
||||
../../nbench/bench_lab
|
||||
|
||||
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#additional-metrics
|
||||
@ -313,8 +313,11 @@ proc process_voluntary_exit*(
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#operations
|
||||
proc process_operations(state: var BeaconState, body: SomeBeaconBlockBody,
|
||||
flags: UpdateFlags, stateCache: var StateCache): bool {.nbench.} =
|
||||
proc process_operations(preset: RuntimePreset,
|
||||
state: var BeaconState,
|
||||
body: SomeBeaconBlockBody,
|
||||
flags: UpdateFlags,
|
||||
stateCache: var StateCache): bool {.nbench.} =
|
||||
# Verify that outstanding deposits are processed up to the maximum number of
|
||||
# deposits
|
||||
let
|
||||
@ -342,13 +345,18 @@ proc process_operations(state: var BeaconState, body: SomeBeaconBlockBody,
|
||||
for_ops_cached(body.proposer_slashings, process_proposer_slashing)
|
||||
for_ops_cached(body.attester_slashings, process_attester_slashing)
|
||||
for_ops_cached(body.attestations, process_attestation)
|
||||
for_ops(body.deposits, process_deposit)
|
||||
|
||||
for deposit in body.deposits:
|
||||
if not process_deposit(preset, state, deposit, flags):
|
||||
return false
|
||||
|
||||
for_ops(body.voluntary_exits, process_voluntary_exit)
|
||||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#block-processing
|
||||
proc process_block*(
|
||||
preset: RuntimePreset,
|
||||
state: var BeaconState, blck: SomeBeaconBlock, flags: UpdateFlags,
|
||||
stateCache: var StateCache): bool {.nbench.}=
|
||||
## When there's a new block, we need to verify that the block is sane and
|
||||
@ -380,7 +388,7 @@ proc process_block*(
|
||||
return false
|
||||
|
||||
process_eth1_data(state, blck.body)
|
||||
if not process_operations(state, blck.body, flags, stateCache):
|
||||
if not process_operations(preset, state, blck.body, flags, stateCache):
|
||||
# One could combine this and the default-true, but that's a bit implicit
|
||||
return false
|
||||
|
||||
|
@ -31,6 +31,8 @@ logScope: topics = "valapi"
|
||||
|
||||
proc installValidatorApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
|
||||
|
||||
let GENESIS_FORK_VERSION = node.config.runtimePreset.GENESIS_FORK_VERSION
|
||||
|
||||
template withStateForSlot(stateId: string, body: untyped): untyped =
|
||||
var res: BiggestInt
|
||||
if parseBiggestInt(stateId, res) == stateId.len:
|
||||
@ -132,7 +134,7 @@ proc installValidatorApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
|
||||
cat = "fastforward"
|
||||
raise newException(CatchableError,
|
||||
"Proposal is for a past slot: " & $body.message.slot)
|
||||
if head == await proposeSignedBlock(node, head, AttachedValidator(),
|
||||
if head == await proposeSignedBlock(node, head, AttachedValidator(),
|
||||
body, hash_tree_root(body.message)):
|
||||
raise newException(CatchableError, "Could not propose block")
|
||||
return true
|
||||
|
@ -198,6 +198,7 @@ proc makeBeaconBlockForHeadAndSlot*(node: BeaconNode,
|
||||
|
||||
var cache = get_empty_per_epoch_cache()
|
||||
let message = makeBeaconBlock(
|
||||
node.config.runtimePreset,
|
||||
hashedState,
|
||||
validator_index,
|
||||
head.root,
|
||||
|
@ -12,7 +12,7 @@ import
|
||||
confutils/defs, serialization, chronicles,
|
||||
# Beacon-chain
|
||||
../beacon_chain/spec/[
|
||||
datatypes, crypto, helpers, beaconstate, validator,
|
||||
datatypes, crypto, helpers, beaconstate, validator, helpers,
|
||||
state_transition_block, state_transition_epoch, state_transition],
|
||||
../beacon_chain/extras,
|
||||
../beacon_chain/ssz/[merkleization, ssz_serialization]
|
||||
@ -159,7 +159,7 @@ proc runFullTransition*(dir, preState, blocksPrefix: string, blocksQty: int, ski
|
||||
let flags = if skipBLS: {skipBlsValidation}
|
||||
else: {}
|
||||
let success = state_transition(
|
||||
state[], signedBlock, flags, noRollback)
|
||||
defaultRuntimePreset, state[], signedBlock, flags, noRollback)
|
||||
echo "State transition status: ", if success: "SUCCESS ✓" else: "FAILURE ⚠️"
|
||||
|
||||
proc runProcessSlots*(dir, preState: string, numSlots: uint64) =
|
||||
@ -204,6 +204,10 @@ template genProcessEpochScenario(name, transitionFn: untyped, needCache: static
|
||||
proc `name`*(dir, preState: string) =
|
||||
processEpochScenarioImpl(dir, preState, transitionFn, needCache)
|
||||
|
||||
proc process_deposit(state: var BeaconState; deposit: Deposit;
|
||||
flags: UpdateFlags = {}): bool =
|
||||
process_deposit(defaultRuntimePreset, state, deposit, flags)
|
||||
|
||||
template processBlockScenarioImpl(
|
||||
dir, preState: string, skipBLS: bool,
|
||||
transitionFn, paramName: untyped,
|
||||
|
@ -2,7 +2,8 @@
|
||||
confutils, stats, chronicles, strformat, tables,
|
||||
stew/byteutils,
|
||||
../beacon_chain/[beacon_chain_db, block_pool, extras],
|
||||
../beacon_chain/spec/[crypto, datatypes, digest, helpers, state_transition, validator],
|
||||
../beacon_chain/spec/[crypto, datatypes, digest, helpers,
|
||||
state_transition, validator, presets],
|
||||
../beacon_chain/sszdump, ../beacon_chain/ssz/merkleization,
|
||||
../research/simutils,
|
||||
eth/db/[kvstore, kvstore_sqlite3]
|
||||
@ -21,6 +22,8 @@ type
|
||||
dumpBlock
|
||||
rewindState
|
||||
|
||||
# TODO:
|
||||
# This should probably allow specifying a run-time preset
|
||||
DbConf = object
|
||||
databaseDir* {.
|
||||
defaultValue: ""
|
||||
@ -70,7 +73,7 @@ proc cmdBench(conf: DbConf) =
|
||||
|
||||
echo "Initializing block pool..."
|
||||
let pool = withTimerRet(timers[tInit]):
|
||||
CandidateChains.init(db, {})
|
||||
CandidateChains.init(defaultRuntimePreset, db, {})
|
||||
|
||||
echo &"Loaded {pool.blocks.len} blocks, head slot {pool.head.blck.slot}"
|
||||
|
||||
@ -102,7 +105,7 @@ proc cmdBench(conf: DbConf) =
|
||||
isEpoch = state[].data.slot.compute_epoch_at_slot !=
|
||||
b.message.slot.compute_epoch_at_slot
|
||||
withTimer(timers[if isEpoch: tApplyEpochBlock else: tApplyBlock]):
|
||||
if not state_transition(state[], b, {}, noRollback):
|
||||
if not state_transition(defaultRuntimePreset, state[], b, {}, noRollback):
|
||||
dump("./", b, hash_tree_root(b.message))
|
||||
echo "State transition failed (!)"
|
||||
quit 1
|
||||
@ -151,7 +154,7 @@ proc cmdRewindState(conf: DbConf) =
|
||||
quit 1
|
||||
|
||||
echo "Initializing block pool..."
|
||||
let pool = BlockPool.init(db, {})
|
||||
let pool = BlockPool.init(defaultRuntimePreset, db, {})
|
||||
|
||||
let blckRef = pool.getRef(fromHex(Eth2Digest, conf.blockRoot))
|
||||
if blckRef == nil:
|
||||
|
@ -1,6 +1,6 @@
|
||||
import
|
||||
confutils, chronicles,
|
||||
../beacon_chain/spec/[crypto, datatypes, state_transition],
|
||||
../beacon_chain/spec/[crypto, datatypes, state_transition, presets],
|
||||
../beacon_chain/extras,
|
||||
../beacon_chain/ssz/[merkleization, ssz_serialization]
|
||||
|
||||
@ -14,7 +14,7 @@ cli do(pre: string, blck: string, post: string, verifyStateRoot = true):
|
||||
|
||||
stateY.root = hash_tree_root(stateY.data)
|
||||
|
||||
if not state_transition(stateY[], blckX, flags, noRollback):
|
||||
if not state_transition(defaultRuntimePreset, stateY[], blckX, flags, noRollback):
|
||||
error "State transition failed"
|
||||
quit 1
|
||||
else:
|
||||
|
@ -5,7 +5,7 @@ import
|
||||
stew/ptrops, stew/ranges/ptr_arith, chronicles,
|
||||
../beacon_chain/extras,
|
||||
../beacon_chain/spec/[crypto, datatypes, digest, validator, beaconstate,
|
||||
state_transition_block, state_transition],
|
||||
state_transition_block, state_transition, presets],
|
||||
../beacon_chain/ssz/[merkleization, ssz_serialization]
|
||||
|
||||
type
|
||||
@ -110,15 +110,15 @@ proc nfuzz_block(input: openArray[byte], xoutput: ptr byte,
|
||||
# and requiring HashedBeaconState (yet). So to keep consistent, puts wrapper
|
||||
# only in one function.
|
||||
proc state_transition(
|
||||
data: auto, blck: auto, flags: auto, rollback: RollbackHashedProc):
|
||||
preset: RuntimePreset, data: auto, blck: auto, flags: auto, rollback: RollbackHashedProc):
|
||||
auto =
|
||||
var hashedState =
|
||||
HashedBeaconState(data: data.state, root: hash_tree_root(data.state))
|
||||
result = state_transition(hashedState, blck, flags, rollback)
|
||||
result = state_transition(preset, hashedState, blck, flags, rollback)
|
||||
data.state = hashedState.data
|
||||
|
||||
decodeAndProcess(BlockInput):
|
||||
state_transition(data, data.beaconBlock, flags, noRollback)
|
||||
state_transition(defaultRuntimePreset, data, data.beaconBlock, flags, noRollback)
|
||||
|
||||
proc nfuzz_block_header(input: openArray[byte], xoutput: ptr byte,
|
||||
xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
@ -128,7 +128,7 @@ proc nfuzz_block_header(input: openArray[byte], xoutput: ptr byte,
|
||||
proc nfuzz_deposit(input: openArray[byte], xoutput: ptr byte,
|
||||
xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
decodeAndProcess(DepositInput):
|
||||
process_deposit(data.state, data.deposit, flags)
|
||||
process_deposit(defaultRuntimePreset, data.state, data.deposit, flags)
|
||||
|
||||
proc nfuzz_proposer_slashing(input: openArray[byte], xoutput: ptr byte,
|
||||
xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
|
@ -19,9 +19,8 @@ import
|
||||
strformat,
|
||||
options, random, tables,
|
||||
../tests/[testblockutil],
|
||||
../beacon_chain/spec/[
|
||||
beaconstate, crypto, datatypes, digest, helpers, validator, signatures,
|
||||
state_transition],
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, presets,
|
||||
helpers, validator, signatures, state_transition],
|
||||
../beacon_chain/[
|
||||
attestation_pool, block_pool, beacon_node_types, beacon_chain_db,
|
||||
interop, validator_pool],
|
||||
@ -55,7 +54,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
|
||||
BlockPool.preInit(db, state[].data, genesisBlock)
|
||||
|
||||
var
|
||||
blockPool = BlockPool.init(db)
|
||||
blockPool = BlockPool.init(defaultRuntimePreset, db)
|
||||
attPool = AttestationPool.init(blockPool)
|
||||
timers: array[Timers, RunningStat]
|
||||
attesters: RunningStat
|
||||
@ -109,6 +108,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
|
||||
eth1data = get_eth1data_stub(
|
||||
state.eth1_deposit_index, slot.compute_epoch_at_slot())
|
||||
message = makeBeaconBlock(
|
||||
defaultRuntimePreset,
|
||||
hashedState,
|
||||
proposerIdx,
|
||||
head.root,
|
||||
|
@ -3,7 +3,7 @@ import
|
||||
../tests/[testblockutil],
|
||||
../beacon_chain/[extras],
|
||||
../beacon_chain/ssz/[merkleization, ssz_serialization],
|
||||
../beacon_chain/spec/[beaconstate, datatypes, digest, helpers]
|
||||
../beacon_chain/spec/[beaconstate, datatypes, digest, helpers, presets]
|
||||
|
||||
template withTimer*(stats: var RunningStat, body: untyped) =
|
||||
# TODO unify timing somehow
|
||||
@ -67,7 +67,7 @@ proc loadGenesis*(validators: int, validate: bool): ref HashedBeaconState =
|
||||
echo "Generating Genesis..."
|
||||
|
||||
res.data =
|
||||
initialize_beacon_state_from_eth1(Eth2Digest(), 0, deposits, flags)[]
|
||||
initialize_beacon_state_from_eth1(defaultRuntimePreset, Eth2Digest(), 0, deposits, flags)[]
|
||||
res.root = hash_tree_root(res.data)
|
||||
|
||||
echo &"Saving to {fn}..."
|
||||
|
@ -13,7 +13,7 @@ import
|
||||
sets,
|
||||
# Specs
|
||||
../../beacon_chain/spec/[datatypes, beaconstate, helpers, validator, crypto,
|
||||
signatures, state_transition],
|
||||
signatures, state_transition, presets],
|
||||
# Internals
|
||||
../../beacon_chain/[ssz, extras],
|
||||
# Mocking procs
|
||||
@ -130,5 +130,8 @@ proc add*(state: var HashedBeaconState, attestation: Attestation, slot: Slot) =
|
||||
doAssert process_slots(state, slot)
|
||||
signMockBlock(state.data, signedBlock)
|
||||
|
||||
doAssert state_transition(
|
||||
state, signedBlock, flags = {skipStateRootValidation}, noRollback)
|
||||
let success = state_transition(
|
||||
defaultRuntimePreset, state, signedBlock,
|
||||
flags = {skipStateRootValidation}, noRollback)
|
||||
|
||||
doAssert success
|
||||
|
@ -11,10 +11,14 @@
|
||||
import
|
||||
# Standard library
|
||||
math, random,
|
||||
|
||||
# Specs
|
||||
../../beacon_chain/spec/[datatypes, crypto, digest, keystore, signatures],
|
||||
../../beacon_chain/spec/[datatypes, crypto, digest,
|
||||
keystore, signatures, presets],
|
||||
|
||||
# Internals
|
||||
../../beacon_chain/[ssz, extras, merkle_minimal],
|
||||
|
||||
# Mocking procs
|
||||
./mock_validator_keys
|
||||
|
||||
@ -38,7 +42,7 @@ func mockDepositData(
|
||||
): DepositData =
|
||||
var ret = mockDepositData(pubkey, amount)
|
||||
if skipBlsValidation notin flags:
|
||||
ret.signature = get_deposit_signature(ret, privkey)
|
||||
ret.signature = defaultRuntimePreset.get_deposit_signature(ret, privkey)
|
||||
ret
|
||||
|
||||
template mockGenesisDepositsImpl(
|
||||
|
@ -10,13 +10,12 @@
|
||||
|
||||
import
|
||||
# Specs
|
||||
../../beacon_chain/spec/[datatypes, beaconstate],
|
||||
../../beacon_chain/spec/[datatypes, beaconstate, presets],
|
||||
# Internals
|
||||
../../beacon_chain/[extras, interop],
|
||||
# Mocking procs
|
||||
./mock_deposits
|
||||
|
||||
|
||||
proc initGenesisState*(num_validators: uint64, genesis_time: uint64 = 0): HashedBeaconState =
|
||||
let deposits = mockGenesisBalancedDeposits(
|
||||
validatorCount = num_validators,
|
||||
@ -25,7 +24,7 @@ proc initGenesisState*(num_validators: uint64, genesis_time: uint64 = 0): Hashed
|
||||
)
|
||||
|
||||
initialize_hashed_beacon_state_from_eth1(
|
||||
eth1BlockHash, 0, deposits, {skipBlsValidation})
|
||||
defaultRuntimePreset, eth1BlockHash, 0, deposits, {skipBlsValidation})
|
||||
|
||||
when isMainModule:
|
||||
# Smoke test
|
||||
|
@ -10,30 +10,28 @@
|
||||
|
||||
import
|
||||
# Specs
|
||||
../../beacon_chain/spec/[datatypes, crypto]
|
||||
../../beacon_chain/spec/[datatypes, crypto, presets]
|
||||
|
||||
# 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 array[MIN_GENESIS_ACTIVE_VALIDATOR_COUNT, ValidatorPrivKey]) =
|
||||
proc genMockPrivKeys(privkeys: var openarray[ValidatorPrivKey]) =
|
||||
for i in 0 ..< privkeys.len:
|
||||
let pair = newKeyPair()[]
|
||||
privkeys[i] = pair.priv
|
||||
|
||||
proc genMockPubKeys(
|
||||
pubkeys: var array[MIN_GENESIS_ACTIVE_VALIDATOR_COUNT, ValidatorPubKey],
|
||||
privkeys: array[MIN_GENESIS_ACTIVE_VALIDATOR_COUNT, ValidatorPrivKey]
|
||||
pubkeys: var openarray[ValidatorPubKey],
|
||||
privkeys: openarray[ValidatorPrivKey]
|
||||
) =
|
||||
for i in 0 ..< privkeys.len:
|
||||
pubkeys[i] = toPubKey(privkeys[i])
|
||||
|
||||
# Ref array necessary to limit stack usage / binary size
|
||||
var MockPrivKeys*: ref array[MIN_GENESIS_ACTIVE_VALIDATOR_COUNT, ValidatorPrivKey]
|
||||
new MockPrivKeys
|
||||
genMockPrivKeys(MockPrivKeys[])
|
||||
var MockPrivKeys* = newSeq[ValidatorPrivKey](defaultRuntimePreset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT)
|
||||
genMockPrivKeys(MockPrivKeys)
|
||||
|
||||
var MockPubKeys*: ref array[MIN_GENESIS_ACTIVE_VALIDATOR_COUNT, ValidatorPubKey]
|
||||
new MockPubKeys
|
||||
genMockPubKeys(MockPubKeys[], MockPrivKeys[])
|
||||
var MockPubKeys* = newSeq[ValidatorPubKey](defaultRuntimePreset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT)
|
||||
genMockPubKeys(MockPubKeys, MockPrivKeys)
|
||||
|
||||
type MockKey = ValidatorPrivKey or ValidatorPubKey
|
||||
|
||||
@ -43,7 +41,7 @@ template `[]`*[N: static int](a: array[N, MockKey], idx: ValidatorIndex): MockKe
|
||||
when isMainModule:
|
||||
echo "========================================"
|
||||
echo "Mock keys"
|
||||
for i in 0 ..< MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
|
||||
for i in 0 ..< defaultRuntimePreset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
|
||||
echo " validator ", i
|
||||
echo " seckey: ", MockPrivKeys[i].toHex()
|
||||
echo " pubkey: ", MockPubKeys[i]
|
||||
|
@ -12,7 +12,7 @@ import
|
||||
# Status libraries
|
||||
stew/[byteutils, endians2],
|
||||
# Internals
|
||||
../../beacon_chain/spec/[datatypes, digest],
|
||||
../../beacon_chain/spec/[datatypes, digest, presets],
|
||||
# Test utilities
|
||||
../testutil, ./fixtures_utils
|
||||
|
||||
@ -93,7 +93,22 @@ const IgnoreKeys = [
|
||||
# Ignore all non-numeric types
|
||||
"DEPOSIT_CONTRACT_ADDRESS",
|
||||
"GENESIS_FORK_VERSION",
|
||||
"SHARD_BLOCK_OFFSETS"
|
||||
"SHARD_BLOCK_OFFSETS",
|
||||
|
||||
# TODO
|
||||
# There constants were removed from the preset modules
|
||||
# because we consider them run-time settings now, but
|
||||
# it would be still useful to check them.
|
||||
"MIN_GENESIS_ACTIVE_VALIDATOR_COUNT",
|
||||
"MIN_GENESIS_TIME",
|
||||
"GENESIS_FORK_VERSION",
|
||||
"GENESIS_DELAY",
|
||||
|
||||
# TODO
|
||||
# These are phase1 constants.
|
||||
# Not currently present in the phase0 presets.
|
||||
"CUSTODY_PERIOD_TO_RANDAO_PADDING",
|
||||
"EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS"
|
||||
]
|
||||
|
||||
func parseU32LEHex(hexValue: string): uint32 =
|
||||
|
@ -11,7 +11,7 @@ import
|
||||
# Standard library
|
||||
os, unittest,
|
||||
# Beacon chain internals
|
||||
../../beacon_chain/spec/[datatypes, beaconstate],
|
||||
../../beacon_chain/spec/[datatypes, beaconstate, presets],
|
||||
../../beacon_chain/[ssz, extras],
|
||||
# Test utilities
|
||||
../testutil,
|
||||
@ -45,10 +45,10 @@ proc runTest(identifier: string) =
|
||||
|
||||
if existsFile(testDir/"post.ssz"):
|
||||
let postState = newClone(parseTest(testDir/"post.ssz", SSZ, BeaconState))
|
||||
discard process_deposit(preState[], deposit, flags)
|
||||
discard process_deposit(defaultRuntimePreset, preState[], deposit, flags)
|
||||
reportDiff(preState, postState)
|
||||
else:
|
||||
check not process_deposit(preState[], deposit, flags)
|
||||
check not process_deposit(defaultRuntimePreset, preState[], deposit, flags)
|
||||
|
||||
`testImpl _ operations_deposits _ identifier`()
|
||||
|
||||
|
@ -11,7 +11,7 @@ import
|
||||
# Standard library
|
||||
os, sequtils, unittest,
|
||||
# Beacon chain internals
|
||||
../../beacon_chain/spec/[crypto, datatypes, state_transition],
|
||||
../../beacon_chain/spec/[crypto, datatypes, state_transition, presets],
|
||||
../../beacon_chain/ssz,
|
||||
# Test utilities
|
||||
../testutil,
|
||||
@ -48,11 +48,11 @@ proc runTest(identifier: string) =
|
||||
|
||||
if hasPostState:
|
||||
let success = state_transition(
|
||||
hashedPreState[], blck, flags = {}, noRollback)
|
||||
defaultRuntimePreset, hashedPreState[], blck, flags = {}, noRollback)
|
||||
doAssert success, "Failure when applying block " & $i
|
||||
else:
|
||||
let success = state_transition(
|
||||
hashedPreState[], blck, flags = {}, noRollback)
|
||||
defaultRuntimePreset, hashedPreState[], blck, flags = {}, noRollback)
|
||||
doAssert (i + 1 < numBlocks) or not success,
|
||||
"We didn't expect these invalid blocks to be processed"
|
||||
|
||||
|
@ -16,7 +16,7 @@ import
|
||||
# Standard library
|
||||
unittest, math,
|
||||
# Specs
|
||||
../../beacon_chain/spec/[beaconstate, datatypes, crypto],
|
||||
../../beacon_chain/spec/[beaconstate, datatypes, crypto, presets],
|
||||
# Internals
|
||||
../../beacon_chain/[ssz, extras],
|
||||
# Mock helpers
|
||||
@ -55,7 +55,7 @@ suiteReport "[Unit - Spec - Block processing] Deposits " & preset():
|
||||
|
||||
# State transition
|
||||
# ----------------------------------------
|
||||
check: process_deposit(state.data, deposit, {skipBlsValidation})
|
||||
check: process_deposit(defaultRuntimePreset(), state.data, deposit, {skipBlsValidation})
|
||||
|
||||
# Check invariants
|
||||
# ----------------------------------------
|
||||
@ -97,7 +97,7 @@ suiteReport "[Unit - Spec - Block processing] Deposits " & preset():
|
||||
|
||||
# State transition
|
||||
# ----------------------------------------
|
||||
check: process_deposit(state.data, deposit, {skipBlsValidation})
|
||||
check: process_deposit(defaultRuntimePreset(), state.data, deposit, {skipBlsValidation})
|
||||
|
||||
# Check invariants
|
||||
# ----------------------------------------
|
||||
|
@ -16,7 +16,7 @@ import
|
||||
chronicles,
|
||||
stew/byteutils,
|
||||
./testutil, ./testblockutil,
|
||||
../beacon_chain/spec/[digest, validator, state_transition],
|
||||
../beacon_chain/spec/[digest, validator, state_transition, presets],
|
||||
../beacon_chain/[beacon_node_types, attestation_pool, block_pool]
|
||||
|
||||
suiteReport "Attestation pool processing" & preset():
|
||||
@ -26,7 +26,7 @@ suiteReport "Attestation pool processing" & preset():
|
||||
setup:
|
||||
# Genesis state that results in 3 members per committee
|
||||
var
|
||||
blockPool = newClone(BlockPool.init(makeTestDB(SLOTS_PER_EPOCH * 3)))
|
||||
blockPool = newClone(BlockPool.init(defaultRuntimePreset, makeTestDB(SLOTS_PER_EPOCH * 3)))
|
||||
pool = newClone(AttestationPool.init(blockPool[]))
|
||||
state = newClone(loadTailState(blockPool[]))
|
||||
# Slot 0 is a finalized slot - won't be making attestations for it..
|
||||
|
@ -10,7 +10,7 @@
|
||||
import options, unittest, sequtils,
|
||||
../beacon_chain/[beacon_chain_db, extras, interop, ssz],
|
||||
../beacon_chain/spec/[
|
||||
beaconstate, datatypes, digest, crypto, state_transition],
|
||||
beaconstate, datatypes, digest, crypto, state_transition, presets],
|
||||
eth/db/kvstore,
|
||||
# test utilies
|
||||
./testutil, ./testblockutil
|
||||
@ -112,7 +112,8 @@ suiteReport "Beacon chain DB" & preset():
|
||||
|
||||
let
|
||||
state = initialize_beacon_state_from_eth1(
|
||||
eth1BlockHash, 0, makeInitialDeposits(SLOTS_PER_EPOCH), {skipBlsValidation})
|
||||
defaultRuntimePreset, eth1BlockHash, 0,
|
||||
makeInitialDeposits(SLOTS_PER_EPOCH), {skipBlsValidation})
|
||||
root = hash_tree_root(state[])
|
||||
|
||||
db.putState(state[])
|
||||
|
@ -10,10 +10,10 @@
|
||||
import
|
||||
times, unittest,
|
||||
./testutil, ./testblockutil,
|
||||
../beacon_chain/spec/[beaconstate, datatypes, digest]
|
||||
../beacon_chain/spec/[beaconstate, datatypes, digest, presets]
|
||||
|
||||
suiteReport "Beacon state" & preset():
|
||||
timedTest "Smoke test initialize_beacon_state_from_eth1" & preset():
|
||||
let state = initialize_beacon_state_from_eth1(
|
||||
Eth2Digest(), 0, makeInitialDeposits(SLOTS_PER_EPOCH, {}), {})
|
||||
defaultRuntimePreset, Eth2Digest(), 0, makeInitialDeposits(SLOTS_PER_EPOCH, {}), {})
|
||||
check: state.validators.len == SLOTS_PER_EPOCH
|
||||
|
@ -10,7 +10,8 @@
|
||||
import
|
||||
options, sequtils, unittest,
|
||||
./testutil, ./testblockutil,
|
||||
../beacon_chain/spec/[datatypes, digest, helpers, validator, state_transition],
|
||||
../beacon_chain/spec/[datatypes, digest, helpers, validator,
|
||||
state_transition, presets],
|
||||
../beacon_chain/[beacon_node_types, block_pool, ssz]
|
||||
|
||||
when isMainModule:
|
||||
@ -89,7 +90,7 @@ suiteReport "Block pool processing" & preset():
|
||||
setup:
|
||||
var
|
||||
db = makeTestDB(SLOTS_PER_EPOCH)
|
||||
pool = BlockPool.init(db)
|
||||
pool = BlockPool.init(defaultRuntimePreset, db)
|
||||
stateData = newClone(pool.loadTailState())
|
||||
cache = get_empty_per_epoch_cache()
|
||||
b1 = addTestBlock(stateData.data, pool.tail.root, cache)
|
||||
@ -202,7 +203,7 @@ suiteReport "Block pool processing" & preset():
|
||||
|
||||
# check that init also reloads block graph
|
||||
var
|
||||
pool2 = BlockPool.init(db)
|
||||
pool2 = BlockPool.init(defaultRuntimePreset, db)
|
||||
|
||||
check:
|
||||
# ensure we loaded the correct head state
|
||||
@ -284,7 +285,7 @@ suiteReport "BlockPool finalization tests" & preset():
|
||||
setup:
|
||||
var
|
||||
db = makeTestDB(SLOTS_PER_EPOCH)
|
||||
pool = BlockPool.init(db)
|
||||
pool = BlockPool.init(defaultRuntimePreset, db)
|
||||
cache = get_empty_per_epoch_cache()
|
||||
|
||||
timedTest "prune heads on finalization" & preset():
|
||||
@ -327,7 +328,7 @@ suiteReport "BlockPool finalization tests" & preset():
|
||||
pool.add(hash_tree_root(lateBlock.message), lateBlock).error == Unviable
|
||||
|
||||
let
|
||||
pool2 = BlockPool.init(db)
|
||||
pool2 = BlockPool.init(defaultRuntimePreset, db)
|
||||
|
||||
# check that the state reloaded from database resembles what we had before
|
||||
check:
|
||||
@ -367,7 +368,7 @@ suiteReport "BlockPool finalization tests" & preset():
|
||||
pool.updateHead(added)
|
||||
|
||||
let
|
||||
pool2 = BlockPool.init(db)
|
||||
pool2 = BlockPool.init(defaultRuntimePreset, db)
|
||||
|
||||
# check that the state reloaded from database resembles what we had before
|
||||
check:
|
||||
|
@ -3,7 +3,7 @@
|
||||
import
|
||||
unittest, stint, ./testutil, stew/byteutils,
|
||||
../beacon_chain/[interop, merkle_minimal, ssz],
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes]
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, presets]
|
||||
|
||||
# Interop test yaml, found here:
|
||||
# https://github.com/ethereum/eth2.0-pm/blob/a0b9d22fad424574b1307828f867b30237758468/interop/mocked_start/keygen_10_validators.yaml
|
||||
@ -145,13 +145,13 @@ suiteReport "Interop":
|
||||
|
||||
for i in 0..<64:
|
||||
let privKey = makeInteropPrivKey(i)
|
||||
deposits.add makeDeposit(privKey.toPubKey(), privKey)
|
||||
deposits.add makeDeposit(defaultRuntimePreset, privKey.toPubKey(), privKey)
|
||||
attachMerkleProofs(deposits)
|
||||
|
||||
const genesis_time = 1570500000
|
||||
var
|
||||
initialState = initialize_beacon_state_from_eth1(
|
||||
eth1BlockHash, genesis_time, deposits, {})
|
||||
defaultRuntimePreset, eth1BlockHash, genesis_time, deposits, {})
|
||||
|
||||
# https://github.com/ethereum/eth2.0-pm/tree/6e41fcf383ebeb5125938850d8e9b4e9888389b4/interop/mocked_start#create-genesis-state
|
||||
initialState.genesis_time = genesis_time
|
||||
|
@ -10,8 +10,8 @@
|
||||
import
|
||||
unittest,
|
||||
./testutil, ./testblockutil,
|
||||
../beacon_chain/spec/[
|
||||
beaconstate, datatypes, digest, validator, state_transition],
|
||||
../beacon_chain/spec/[beaconstate, datatypes, digest,
|
||||
validator, state_transition, presets],
|
||||
../beacon_chain/ssz
|
||||
|
||||
suiteReport "Block processing" & preset():
|
||||
@ -22,7 +22,7 @@ suiteReport "Block processing" & preset():
|
||||
# Genesis state with minimal number of deposits
|
||||
# TODO bls verification is a bit of a bottleneck here
|
||||
genesisState = newClone(initialize_hashed_beacon_state_from_eth1(
|
||||
Eth2Digest(), 0, makeInitialDeposits(), {}))
|
||||
defaultRuntimePreset, Eth2Digest(), 0, makeInitialDeposits(), {}))
|
||||
genesisBlock = get_initial_beacon_block(genesisState.data)
|
||||
genesisRoot = hash_tree_root(genesisBlock.message)
|
||||
|
||||
@ -40,7 +40,7 @@ suiteReport "Block processing" & preset():
|
||||
cache = get_empty_per_epoch_cache()
|
||||
new_block = makeTestBlock(state[], previous_block_root, cache)
|
||||
|
||||
let block_ok = state_transition(state[], new_block, {}, noRollback)
|
||||
let block_ok = state_transition(defaultRuntimePreset, state[], new_block, {}, noRollback)
|
||||
|
||||
check:
|
||||
block_ok
|
||||
@ -60,7 +60,7 @@ suiteReport "Block processing" & preset():
|
||||
for i in 1..SLOTS_PER_EPOCH.int:
|
||||
let new_block = makeTestBlock(state[], previous_block_root, cache)
|
||||
|
||||
let block_ok = state_transition(state[], new_block, {}, noRollback)
|
||||
let block_ok = state_transition(defaultRuntimePreset, state[], new_block, {}, noRollback)
|
||||
|
||||
check:
|
||||
block_ok
|
||||
@ -96,7 +96,7 @@ suiteReport "Block processing" & preset():
|
||||
new_block = makeTestBlock(state[], previous_block_root, cache,
|
||||
attestations = @[attestation]
|
||||
)
|
||||
check state_transition(state[], new_block, {}, noRollback)
|
||||
check state_transition(defaultRuntimePreset, state[], new_block, {}, noRollback)
|
||||
|
||||
check:
|
||||
# TODO epoch attestations can get multiplied now; clean up paths to
|
||||
|
@ -8,10 +8,11 @@
|
||||
import
|
||||
options, stew/endians2,
|
||||
chronicles, eth/trie/[db],
|
||||
../beacon_chain/[beacon_chain_db, block_pool, extras, merkle_minimal,
|
||||
../beacon_chain/ssz/merkleization, validator_pool],
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest,
|
||||
helpers, validator, signatures, state_transition]
|
||||
../beacon_chain/[beacon_chain_db, block_pool, extras,
|
||||
merkle_minimal, validator_pool],
|
||||
../beacon_chain/ssz/merkleization,
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, presets,
|
||||
helpers, validator, signatures, state_transition]
|
||||
|
||||
func makeFakeValidatorPrivKey(i: int): ValidatorPrivKey =
|
||||
# 0 is not a valid BLS private key - 1000 helps interop with rust BLS library,
|
||||
@ -53,7 +54,8 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
|
||||
)
|
||||
|
||||
if skipBLSValidation notin flags:
|
||||
result.data.signature = get_deposit_signature(result.data, privkey)
|
||||
result.data.signature = get_deposit_signature(
|
||||
defaultRuntimePreset, result.data, privkey)
|
||||
|
||||
proc makeInitialDeposits*(
|
||||
n = SLOTS_PER_EPOCH, flags: UpdateFlags = {}): seq[Deposit] =
|
||||
@ -106,6 +108,7 @@ proc addTestBlock*(
|
||||
|
||||
let
|
||||
message = makeBeaconBlock(
|
||||
defaultRuntimePreset,
|
||||
state,
|
||||
proposer_index.get(),
|
||||
parent_root,
|
||||
|
@ -9,7 +9,7 @@ import
|
||||
algorithm, strformat, stats, times, tables, std/monotimes, stew/endians2,
|
||||
testutils/markdown_reports, chronicles,
|
||||
../beacon_chain/[beacon_chain_db, block_pool, extras, ssz],
|
||||
../beacon_chain/spec/[digest, beaconstate, datatypes],
|
||||
../beacon_chain/spec/[digest, beaconstate, datatypes, presets],
|
||||
eth/db/kvstore,
|
||||
testblockutil
|
||||
|
||||
@ -103,7 +103,7 @@ proc makeTestDB*(tailState: BeaconState, tailBlock: SignedBeaconBlock): BeaconCh
|
||||
proc makeTestDB*(validators: int): BeaconChainDB =
|
||||
let
|
||||
genState = initialize_beacon_state_from_eth1(
|
||||
Eth2Digest(), 0,
|
||||
defaultRuntimePreset, Eth2Digest(), 0,
|
||||
makeInitialDeposits(validators, flags = {skipBlsValidation}),
|
||||
{skipBlsValidation})
|
||||
genBlock = get_initial_beacon_block(genState[])
|
||||
|
2
vendor/eth2-testnets
vendored
2
vendor/eth2-testnets
vendored
@ -1 +1 @@
|
||||
Subproject commit 61d94737812fc40438b70ea49a6a87d17c2f3d4c
|
||||
Subproject commit f0dfca17cf2b27e390ebd18de1538d84db35f9ed
|
2
vendor/nim-serialization
vendored
2
vendor/nim-serialization
vendored
@ -1 +1 @@
|
||||
Subproject commit e0e51015b7348b61aa5d7391af4f8f4487713f91
|
||||
Subproject commit 5b11c4173159a15d52f0bb6a26a1aa2b40f0f2be
|
2
vendor/nim-stew
vendored
2
vendor/nim-stew
vendored
@ -1 +1 @@
|
||||
Subproject commit 61d5cfc37677f2b434d43c06d06695b00e56613b
|
||||
Subproject commit 61e0f8285846c46f39f7281015c107fbae197306
|
Loading…
x
Reference in New Issue
Block a user