Remove the genesis detection code
This commit is contained in:
parent
2ac28b1346
commit
3b03ef8ffb
1
Makefile
1
Makefile
|
@ -601,7 +601,6 @@ gnosis-build gnosis-chain-build: | build deps
|
|||
$(NIM_PARAMS) \
|
||||
-d:gnosisChainBinary \
|
||||
-d:const_preset=gnosis \
|
||||
-d:has_genesis_detection \
|
||||
&& \
|
||||
echo -e $(BUILD_END_MSG) "build/nimbus_beacon_node_gnosis"
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ contract(DepositContract):
|
|||
const
|
||||
web3Timeouts = 60.seconds
|
||||
hasDepositRootChecks = defined(has_deposit_root_checks)
|
||||
hasGenesisDetection* = defined(has_genesis_detection)
|
||||
|
||||
targetBlocksPerLogsRequest = 5000'u64 # This is roughly a day of Eth1 blocks
|
||||
|
||||
|
@ -85,9 +84,6 @@ type
|
|||
## Global deposits count and hash tree root of the entire sequence
|
||||
## These are computed when the block is added to the chain (see `addBlock`)
|
||||
|
||||
when hasGenesisDetection:
|
||||
activeValidatorsCount*: uint64
|
||||
|
||||
Eth1Chain* = object
|
||||
db: BeaconChainDB
|
||||
cfg: RuntimeConfig
|
||||
|
@ -143,12 +139,6 @@ type
|
|||
|
||||
ttdReachedField: bool
|
||||
|
||||
when hasGenesisDetection:
|
||||
genesisValidators: seq[ImmutableValidatorData]
|
||||
genesisValidatorKeyToIndex: Table[ValidatorPubKey, ValidatorIndex]
|
||||
genesisState: GenesisStateRef
|
||||
genesisStateFut: Future[void]
|
||||
|
||||
Web3DataProvider* = object
|
||||
url: string
|
||||
web3: Web3
|
||||
|
@ -204,72 +194,6 @@ func ttdReached*(m: Eth1Monitor): bool =
|
|||
template cfg(m: Eth1Monitor): auto =
|
||||
m.depositsChain.cfg
|
||||
|
||||
when hasGenesisDetection:
|
||||
import ../spec/[beaconstate, signatures]
|
||||
|
||||
template hasEnoughValidators(m: Eth1Monitor, blk: Eth1Block): bool =
|
||||
blk.activeValidatorsCount >= m.cfg.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||
|
||||
func chainHasEnoughValidators(m: Eth1Monitor): bool =
|
||||
m.depositsChain.blocks.len > 0 and m.hasEnoughValidators(m.depositsChain.blocks[^1])
|
||||
|
||||
func isAfterMinGenesisTime(m: Eth1Monitor, blk: Eth1Block): bool =
|
||||
doAssert blk.timestamp != 0
|
||||
let t = genesis_time_from_eth1_timestamp(m.cfg, uint64 blk.timestamp)
|
||||
t >= m.cfg.MIN_GENESIS_TIME
|
||||
|
||||
func isGenesisCandidate(m: Eth1Monitor, blk: Eth1Block): bool =
|
||||
m.hasEnoughValidators(blk) and m.isAfterMinGenesisTime(blk)
|
||||
|
||||
proc findGenesisBlockInRange(m: Eth1Monitor, startBlock, endBlock: Eth1Block):
|
||||
Future[Eth1Block] {.gcsafe.}
|
||||
|
||||
proc signalGenesis(m: Eth1Monitor, genesisState: GenesisStateRef) =
|
||||
m.genesisState = genesisState
|
||||
|
||||
if not m.genesisStateFut.isNil:
|
||||
m.genesisStateFut.complete()
|
||||
m.genesisStateFut = nil
|
||||
|
||||
func allGenesisDepositsUpTo(m: Eth1Monitor, totalDeposits: uint64): seq[DepositData] =
|
||||
for i in 0 ..< int64(totalDeposits):
|
||||
result.add m.depositsChain.db.genesisDeposits.get(i)
|
||||
|
||||
proc createGenesisState(m: Eth1Monitor, eth1Block: Eth1Block): GenesisStateRef =
|
||||
notice "Generating genesis state",
|
||||
blockNum = eth1Block.number,
|
||||
blockHash = eth1Block.hash,
|
||||
blockTimestamp = eth1Block.timestamp,
|
||||
totalDeposits = eth1Block.depositCount,
|
||||
activeValidators = eth1Block.activeValidatorsCount
|
||||
|
||||
var deposits = m.allGenesisDepositsUpTo(eth1Block.depositCount)
|
||||
|
||||
result = newClone(initialize_beacon_state_from_eth1(
|
||||
m.cfg,
|
||||
eth1Block.hash,
|
||||
eth1Block.timestamp.uint64,
|
||||
deposits, {}))
|
||||
|
||||
if eth1Block.activeValidatorsCount != 0:
|
||||
doAssert result.validators.lenu64 == eth1Block.activeValidatorsCount
|
||||
|
||||
proc produceDerivedData(m: Eth1Monitor, deposit: DepositData) =
|
||||
let htr = hash_tree_root(deposit)
|
||||
|
||||
if verify_deposit_signature(m.cfg, deposit):
|
||||
let pubkey = deposit.pubkey
|
||||
if pubkey notin m.genesisValidatorKeyToIndex:
|
||||
let idx = ValidatorIndex m.genesisValidators.len
|
||||
m.genesisValidators.add ImmutableValidatorData(
|
||||
pubkey: pubkey,
|
||||
withdrawal_credentials: deposit.withdrawal_credentials)
|
||||
m.genesisValidatorKeyToIndex[pubkey] = idx
|
||||
|
||||
proc processGenesisDeposit*(m: Eth1Monitor, newDeposit: DepositData) =
|
||||
m.depositsChain.db.genesisDeposits.add newDeposit
|
||||
m.produceDerivedData(newDeposit)
|
||||
|
||||
template depositChainBlocks*(m: Eth1Monitor): Deque[Eth1Block] =
|
||||
m.depositsChain.blocks
|
||||
|
||||
|
@ -508,9 +432,6 @@ func makeSuccessorWithoutDeposits(existingBlock: Eth1Block,
|
|||
number: Eth1BlockNumber successor.number,
|
||||
timestamp: Eth1BlockTimestamp successor.timestamp)
|
||||
|
||||
when hasGenesisDetection:
|
||||
result.activeValidatorsCount = existingBlock.activeValidatorsCount
|
||||
|
||||
func latestCandidateBlock(chain: Eth1Chain, periodStart: uint64): Eth1Block =
|
||||
for i in countdown(chain.blocks.len - 1, 0):
|
||||
let blk = chain.blocks[i]
|
||||
|
@ -1423,74 +1344,6 @@ proc syncBlockRange(m: Eth1Monitor,
|
|||
blockNumber = lastBlock.number,
|
||||
depositsProcessed = lastBlock.depositCount
|
||||
|
||||
when hasGenesisDetection:
|
||||
if blocksWithDeposits.len > 0:
|
||||
for blk in blocksWithDeposits:
|
||||
for deposit in blk.deposits:
|
||||
m.processGenesisDeposit(deposit)
|
||||
blk.activeValidatorsCount = m.genesisValidators.lenu64
|
||||
|
||||
let
|
||||
lastBlock = blocksWithDeposits[^1]
|
||||
depositTreeSnapshot = DepositTreeSnapshot(
|
||||
eth1Block: lastBlock.hash,
|
||||
depositContractState: m.headMerkleizer.toDepositContractState,
|
||||
blockHeight: lastBlock.number)
|
||||
|
||||
m.depositsChain.db.putDepositTreeSnapshot depositTreeSnapshot
|
||||
|
||||
if m.genesisStateFut != nil and m.chainHasEnoughValidators:
|
||||
let lastIdx = m.depositsChain.blocks.len - 1
|
||||
template lastBlock: auto = m.depositsChain.blocks[lastIdx]
|
||||
|
||||
if maxBlockNumberRequested == toBlock and
|
||||
(m.depositsChain.blocks.len == 0 or lastBlock.number != toBlock):
|
||||
let web3Block = awaitWithRetries(
|
||||
m.dataProvider.getBlockByNumber(toBlock))
|
||||
|
||||
debug "Latest block doesn't hold deposits. Obtaining it",
|
||||
ts = web3Block.timestamp.uint64,
|
||||
number = web3Block.number.uint64
|
||||
|
||||
m.depositsChain.addBlock lastBlock.makeSuccessorWithoutDeposits(web3Block)
|
||||
else:
|
||||
await lastBlock.fetchTimestampWithRetries(m.dataProvider)
|
||||
|
||||
var genesisBlockIdx = m.depositsChain.blocks.len - 1
|
||||
if m.isAfterMinGenesisTime(m.depositsChain.blocks[genesisBlockIdx]):
|
||||
for i in 1 ..< blocksWithDeposits.len:
|
||||
let idx = (m.depositsChain.blocks.len - 1) - i
|
||||
let blk = m.depositsChain.blocks[idx]
|
||||
await blk.fetchTimestampWithRetries(m.dataProvider)
|
||||
if m.isGenesisCandidate(blk):
|
||||
genesisBlockIdx = idx
|
||||
else:
|
||||
break
|
||||
# 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
|
||||
# deposits (triggered by MIN_GENESIS_TIME).
|
||||
#
|
||||
# This can happen when the beacon node is launched after the genesis
|
||||
# event. We take a short cut when constructing the initial Eth1Chain
|
||||
# by downloading only deposit log entries. Thus, we'll see all the
|
||||
# blocks with deposits, but not the regular blocks in between.
|
||||
#
|
||||
# We'll handle this special case below by examing whether we are in
|
||||
# this potential scenario and we'll use a fast guessing algorith to
|
||||
# discover the ETh1 block with minimal valid genesis time.
|
||||
var genesisBlock = m.depositsChain.blocks[genesisBlockIdx]
|
||||
if genesisBlockIdx > 0:
|
||||
let genesisParent = m.depositsChain.blocks[genesisBlockIdx - 1]
|
||||
if genesisParent.timestamp == 0:
|
||||
await genesisParent.fetchTimestampWithRetries(m.dataProvider)
|
||||
if m.hasEnoughValidators(genesisParent) and
|
||||
genesisBlock.number - genesisParent.number > 1:
|
||||
genesisBlock = awaitWithRetries(
|
||||
m.findGenesisBlockInRange(genesisParent, genesisBlock))
|
||||
|
||||
m.signalGenesis m.createGenesisState(genesisBlock)
|
||||
|
||||
func init(T: type FullBlockId, blk: Eth1BlockHeader|BlockObject): T =
|
||||
FullBlockId(number: Eth1BlockNumber blk.number, hash: blk.hash)
|
||||
|
||||
|
@ -1681,10 +1534,6 @@ proc startEth1Syncing(m: Eth1Monitor, delayBeforeStart: Duration) {.async.} =
|
|||
var didPollOnce = false
|
||||
while true:
|
||||
if bnStatus == BeaconNodeStatus.Stopping:
|
||||
when hasGenesisDetection:
|
||||
if not m.genesisStateFut.isNil:
|
||||
m.genesisStateFut.complete()
|
||||
m.genesisStateFut = nil
|
||||
await m.stop()
|
||||
return
|
||||
|
||||
|
@ -1827,70 +1676,3 @@ proc testWeb3Provider*(web3Url: Uri,
|
|||
|
||||
depositRoot = request "Deposit root":
|
||||
ns.get_deposit_root.call(blockNumber = latestBlock.number.uint64)
|
||||
|
||||
when hasGenesisDetection:
|
||||
proc loadPersistedDeposits*(monitor: Eth1Monitor) =
|
||||
for i in 0 ..< monitor.depositsChain.db.genesisDeposits.len:
|
||||
monitor.produceDerivedData monitor.depositsChain.db.genesisDeposits.get(i)
|
||||
|
||||
proc findGenesisBlockInRange(m: Eth1Monitor, startBlock, endBlock: Eth1Block):
|
||||
Future[Eth1Block] {.async.} =
|
||||
doAssert m.dataProvider != nil, "close not called concurrently"
|
||||
doAssert startBlock.timestamp != 0 and not m.isAfterMinGenesisTime(startBlock)
|
||||
doAssert endBlock.timestamp != 0 and m.isAfterMinGenesisTime(endBlock)
|
||||
doAssert m.hasEnoughValidators(startBlock)
|
||||
doAssert m.hasEnoughValidators(endBlock)
|
||||
|
||||
var
|
||||
startBlock = startBlock
|
||||
endBlock = endBlock
|
||||
activeValidatorsCountDuringRange = startBlock.activeValidatorsCount
|
||||
|
||||
while startBlock.number + 1 < endBlock.number:
|
||||
let
|
||||
MIN_GENESIS_TIME = m.cfg.MIN_GENESIS_TIME
|
||||
startBlockTime = genesis_time_from_eth1_timestamp(m.cfg, startBlock.timestamp)
|
||||
secondsPerBlock = float(endBlock.timestamp - startBlock.timestamp) /
|
||||
float(endBlock.number - startBlock.number)
|
||||
blocksToJump = max(float(MIN_GENESIS_TIME - startBlockTime) / secondsPerBlock, 1.0)
|
||||
candidateNumber = min(endBlock.number - 1, startBlock.number + blocksToJump.uint64)
|
||||
candidateBlock = awaitWithRetries(
|
||||
m.dataProvider.getBlockByNumber(candidateNumber))
|
||||
|
||||
var candidateAsEth1Block = Eth1Block(hash: candidateBlock.hash.asEth2Digest,
|
||||
number: candidateBlock.number.uint64,
|
||||
timestamp: candidateBlock.timestamp.uint64)
|
||||
|
||||
let candidateGenesisTime = genesis_time_from_eth1_timestamp(
|
||||
m.cfg, candidateBlock.timestamp.uint64)
|
||||
|
||||
notice "Probing possible genesis block",
|
||||
`block` = candidateBlock.number.uint64,
|
||||
candidateGenesisTime
|
||||
|
||||
if candidateGenesisTime < MIN_GENESIS_TIME:
|
||||
startBlock = candidateAsEth1Block
|
||||
else:
|
||||
endBlock = candidateAsEth1Block
|
||||
|
||||
if endBlock.activeValidatorsCount == 0:
|
||||
endBlock.activeValidatorsCount = activeValidatorsCountDuringRange
|
||||
|
||||
return endBlock
|
||||
|
||||
proc waitGenesis*(m: Eth1Monitor): Future[GenesisStateRef] {.async.} =
|
||||
if m.genesisState.isNil:
|
||||
m.start()
|
||||
|
||||
if m.genesisStateFut.isNil:
|
||||
m.genesisStateFut = newFuture[void]("waitGenesis")
|
||||
|
||||
info "Awaiting genesis event"
|
||||
await m.genesisStateFut
|
||||
m.genesisStateFut = nil
|
||||
|
||||
if m.genesisState != nil:
|
||||
return m.genesisState
|
||||
else:
|
||||
doAssert bnStatus == BeaconNodeStatus.Stopping
|
||||
return nil
|
||||
|
|
|
@ -492,51 +492,9 @@ proc init*(T: type BeaconNode,
|
|||
|
||||
if not ChainDAGRef.isInitialized(db).isOk():
|
||||
if genesisState == nil and checkpointState == nil:
|
||||
when hasGenesisDetection:
|
||||
# This is a fresh start without a known genesis state
|
||||
# (most likely, it hasn't arrived yet). We'll try to
|
||||
# obtain a genesis through the Eth1 deposits monitor:
|
||||
if config.web3Urls.len == 0:
|
||||
fatal "Web3 URL not specified"
|
||||
quit 1
|
||||
|
||||
# TODO Could move this to a separate "GenesisMonitor" process or task
|
||||
# that would do only this - see Paul's proposal for this.
|
||||
let eth1Monitor = Eth1Monitor.init(
|
||||
cfg,
|
||||
metadata.depositContractBlock,
|
||||
metadata.depositContractBlockHash,
|
||||
db,
|
||||
nil,
|
||||
config.web3Urls,
|
||||
eth1Network,
|
||||
config.web3ForcePolling,
|
||||
optJwtSecret,
|
||||
ttdReached = false)
|
||||
|
||||
eth1Monitor.loadPersistedDeposits()
|
||||
|
||||
let phase0Genesis = waitFor eth1Monitor.waitGenesis()
|
||||
genesisState = (ref ForkedHashedBeaconState)(
|
||||
kind: BeaconStateFork.Phase0,
|
||||
phase0Data:
|
||||
(ref phase0.HashedBeaconState)(
|
||||
data: phase0Genesis[],
|
||||
root: hash_tree_root(phase0Genesis[]))[])
|
||||
|
||||
if bnStatus == BeaconNodeStatus.Stopping:
|
||||
return nil
|
||||
|
||||
notice "Eth2 genesis state detected",
|
||||
genesisTime = phase0Genesis.genesisTime,
|
||||
eth1Block = phase0Genesis.eth1_data.block_hash,
|
||||
totalDeposits = phase0Genesis.eth1_data.deposit_count
|
||||
else:
|
||||
fatal "No database and no genesis snapshot found: supply a genesis.ssz " &
|
||||
"with the network configuration, or compile the beacon node with " &
|
||||
"the -d:has_genesis_detection option " &
|
||||
"in order to support monitoring for genesis events"
|
||||
quit 1
|
||||
fatal "No database and no genesis snapshot found. Please supply a genesis.ssz " &
|
||||
"with the network configuration"
|
||||
quit 1
|
||||
|
||||
if not genesisState.isNil and not checkpointState.isNil:
|
||||
if getStateField(genesisState[], genesis_validators_root) !=
|
||||
|
|
Loading…
Reference in New Issue