Remove the genesis detection code

This commit is contained in:
Zahary Karadjov 2023-01-12 02:49:43 +02:00
parent 2ac28b1346
commit 3b03ef8ffb
No known key found for this signature in database
GPG Key ID: C1F42EAFF38D570F
3 changed files with 3 additions and 264 deletions

View File

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

View File

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

View File

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