accelerate RANDAO computation for post-merge blocks (#5190)

Post-merge blocks contain all information to directly obtain RANDAO
without having to load any additional info. Take advantage of that to
further accelerate `ShufflingRef` computation. Note that it is still
necessary to verify that `blck` / `state` share a sufficiently recent
ancestor for the purpose of computing attester shufflings.

- new: 243.71s, 239.67s, 237.32s, 238.36s, 239.57s
- old: 251.33s, 234.29s, 249.28s, 237.03s, 236.78s
This commit is contained in:
Etan Kissling 2023-07-15 22:16:56 +02:00 committed by GitHub
parent 565edfa351
commit 2efc44a8ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 16 deletions

View File

@ -450,6 +450,12 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
+ Accelerated shuffling computation (with epochRefState jump) OK
```
OK: 2/2 Fail: 0/2 Skip: 0/2
## Shufflings (merged)
```diff
+ Accelerated shuffling computation OK
+ Accelerated shuffling computation (with epochRefState jump) OK
```
OK: 2/2 Fail: 0/2 Skip: 0/2
## Slashing Interchange tests [Preset: mainnet]
```diff
+ Slashing test: duplicate_pubkey_not_slashable.json OK
@ -690,4 +696,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
OK: 9/9 Fail: 0/9 Skip: 0/9
---TOTAL---
OK: 391/396 Fail: 0/396 Skip: 5/396
OK: 393/398 Fail: 0/398 Skip: 5/398

View File

@ -1401,17 +1401,6 @@ proc computeAttesterRandaoMix(
doAssert ancestorSlot <= stateSlot
doAssert ancestorSlot <= dependentSlot
var mix: Eth2Digest
proc mixToAncestor(highBid: BlockId): Opt[void] =
## Mix in/out RANDAO reveals back to `ancestorSlot`
var bid = highBid
while bid.slot > ancestorSlot:
let bdata = ? dag.getForkedBlock(bid)
withBlck(bdata): # See `process_randao` / `process_randao_mixes_reset`
mix.data.mxor eth2digest(blck.message.body.randao_reveal.toRaw()).data
bid = ? dag.parent(bid)
ok()
# Determine block for obtaining RANDAO mix
let
dependentBid =
@ -1422,10 +1411,35 @@ proc computeAttesterRandaoMix(
else:
let bsi = ? dag.getBlockIdAtSlot(dependentSlot)
bsi.bid
dependentBdata = ? dag.getForkedBlock(dependentBid)
var mix {.noinit.}: Eth2Digest
# If `dependentBid` is post merge, RANDAO information is available
withBlck(dependentBdata):
when consensusFork >= ConsensusFork.Bellatrix:
if blck.message.is_execution_block:
mix = eth2digest(blck.message.body.randao_reveal.toRaw())
mix.data.mxor blck.message.body.execution_payload.prev_randao.data
return ok (dependentBid: dependentBid, mix: mix)
# RANDAO mix has to be recomputed from `blck` and `state`
proc mixToAncestor(highBid: BlockId): Opt[void] =
## Mix in/out RANDAO reveals back to `ancestorSlot`
var bid = highBid
while bid.slot > ancestorSlot:
let bdata = ? dag.getForkedBlock(bid)
withBlck(bdata): # See `process_randao` / `process_randao_mixes_reset`
mix.data.mxor eth2digest(blck.message.body.randao_reveal.toRaw()).data
bid = ? dag.parent(bid)
ok()
# Mix in RANDAO from `blck`
if ancestorSlot < dependentBid.slot:
? mixToAncestor(dependentBid)
withBlck(dependentBdata):
mix = eth2digest(blck.message.body.randao_reveal.toRaw())
? mixToAncestor(? dag.parent(dependentBid))
else:
mix.reset()
# Mix in RANDAO from `state`
let ancestorEpoch = ancestorSlot.epoch

View File

@ -1180,11 +1180,10 @@ suite "Pruning":
dag.tail.slot == Epoch(EPOCHS_PER_STATE_SNAPSHOT).start_slot - 1
not db.containsBlock(blocks[1].root)
suite "Shufflings":
template runShufflingTests(cfg: RuntimeConfig, numRandomTests: int) =
const
numValidators = SLOTS_PER_EPOCH
targetNumValidators = 20 * SLOTS_PER_EPOCH * MAX_DEPOSITS
let cfg = defaultRuntimeConfig
var deposits = newSeqOfCap[Deposit](targetNumValidators)
for depositIndex in 0 ..< targetNumValidators:
deposits.add Deposit(data: makeDeposit(depositIndex.int, cfg = cfg))
@ -1286,7 +1285,7 @@ suite "Shufflings":
test "Accelerated shuffling computation":
randomize()
let forkBlocks = dag.forkBlocks.toSeq()
for _ in 0 ..< 150: # Number of random tests (against _all_ cached states)
for _ in 0 ..< numRandomTests: # Each test runs against _all_ cached states
let
blck = sample(forkBlocks).data
epoch = rand(GENESIS_EPOCH .. maxEpochOfInterest)
@ -1366,3 +1365,15 @@ suite "Shufflings":
# If shuffling is computable from DB, check its correctness
epochRef.checkShuffling dag.computeShufflingRefFromDatabase(blck, epoch)
suite "Shufflings":
let cfg = defaultRuntimeConfig
runShufflingTests(cfg, numRandomTests = 150)
suite "Shufflings (merged)":
let cfg = block:
var cfg = defaultRuntimeConfig
cfg.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
cfg.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
cfg
runShufflingTests(cfg, numRandomTests = 50)