Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AllTests-mainnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ AllTests-mainnet
## Block processor [Preset: mainnet]
```diff
+ Invalidate block root [Preset: mainnet] OK
+ Process a block from each fork (without blobs) [Preset: mainnet] OK
+ Reverse order block add & get [Preset: mainnet] OK
```
## Block quarantine
Expand Down
9 changes: 6 additions & 3 deletions beacon_chain/gossip_processing/block_processor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,6 @@ proc verifyPayload(
# There are no `blob_kzg_commitments` before Deneb to compare against
discard

if signedBlock.root in self.invalidBlockRoots:
returnWithError "Block root treated as invalid via config", $signedBlock.root

ok OptimisticStatus.notValidated
else:
ok OptimisticStatus.valid
Expand Down Expand Up @@ -580,6 +577,12 @@ proc storeBlock(
chronos.nanoseconds((slotTime - wallTime).nanoseconds)
deadline = sleepAsync(deadlineTime)

if signedBlock.root in self.invalidBlockRoots:
warn "Block root treated as invalid via config",
blck = shortLog(signedBlock.message),
blockRoot = shortLog(signedBlock.root)
return err(VerifierError.Invalid)

# We have to be careful that there exists only one in-flight entry point
# for adding blocks or the checks performed in `checkHeadBlock` might
# be invalidated (ie a block could be added while we wait for EL response
Expand Down
41 changes: 29 additions & 12 deletions beacon_chain/spec/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -535,19 +535,36 @@ func toExecutionBlockHeader(
requestsHash : requestsHash) # EIP-7685

func compute_execution_block_hash*(
body: ForkyBeaconBlockBody,
parentRoot: Eth2Digest): Eth2Digest =
when typeof(body).kind >= ConsensusFork.Electra:
body.execution_payload.toExecutionBlockHeader(
Opt.some parentRoot, Opt.some body.execution_requests.computeRequestsHash())
.computeRlpHash().to(Eth2Digest)
elif typeof(body).kind >= ConsensusFork.Deneb:
body.execution_payload.toExecutionBlockHeader(
Opt.some parentRoot)
.computeRlpHash().to(Eth2Digest)
consensusFork: static ConsensusFork,
payload: ForkyExecutionPayload,
parentRoot: Eth2Digest,
requestsHash = Opt.none(EthHash32),
): Eth2Digest =
let header =
when consensusFork >= ConsensusFork.Electra:
payload.toExecutionBlockHeader(Opt.some parentRoot, requestsHash)
elif consensusFork >= ConsensusFork.Deneb:
payload.toExecutionBlockHeader(Opt.some parentRoot)
else:
payload.toExecutionBlockHeader(Opt.none(Eth2Digest))

header.computeRlpHash().to(Eth2Digest)

func compute_execution_block_hash*(
body: ForkyBeaconBlockBody, parentRoot: Eth2Digest
): Eth2Digest =
const consensusFork = typeof(body).kind
when consensusFork >= ConsensusFork.Electra:
compute_execution_block_hash(
consensusFork,
body.execution_payload,
parentRoot,
Opt.some body.execution_requests.computeRequestsHash(),
)
else:
body.execution_payload.toExecutionBlockHeader(Opt.none(Eth2Digest))
.computeRlpHash().to(Eth2Digest)
compute_execution_block_hash(
consensusFork, body.execution_payload, parentRoot
)

func compute_execution_block_hash*(blck: ForkyBeaconBlock): Eth2Digest =
blck.body.compute_execution_block_hash(blck.parent_root)
Expand Down
87 changes: 65 additions & 22 deletions tests/test_block_processor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import
../beacon_chain/gossip_processing/block_processor,
../beacon_chain/consensus_object_pools/[
attestation_pool, blockchain_dag, blob_quarantine, block_quarantine,
block_clearance, consensus_manager],
block_clearance, consensus_manager,
],
../beacon_chain/el/el_manager,
./testutil, ./testdbutil, ./testblockutil
./[testblockutil, testdbutil, testutil]

from chronos/unittest2/asynctests import asyncTest
from ../beacon_chain/spec/eth2_apis/dynamic_fee_recipients import
Expand All @@ -40,43 +41,57 @@ suite "Block processor" & preset():
var res = defaultRuntimeConfig
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
res.CAPELLA_FORK_EPOCH = Epoch(1)
res.DENEB_FORK_EPOCH = Epoch(2)
res.ELECTRA_FORK_EPOCH = Epoch(3)
res.FULU_FORK_EPOCH = Epoch(4)
res
db = cfg.makeTestDB(SLOTS_PER_EPOCH)
validatorMonitor = newClone(ValidatorMonitor.init(cfg.timeParams))
dag = init(ChainDAGRef, cfg, db, validatorMonitor, {})
var
taskpool = Taskpool.new()
quarantine = newClone(Quarantine.init(cfg))
blobQuarantine = newClone(BlobQuarantine())
dataColumnQuarantine = newClone(ColumnQuarantine())
attestationPool = newClone(AttestationPool.init(dag, quarantine))
elManager = new ELManager # TODO: initialise this properly
actionTracker: ActionTracker
actionTracker = default(ActionTracker)
consensusManager = ConsensusManager.new(
dag, attestationPool, quarantine, elManager, actionTracker,
newClone(DynamicFeeRecipientsStore.init()), "",
Opt.some default(Eth1Address), defaultGasLimit)
dag,
attestationPool,
quarantine,
elManager,
actionTracker,
newClone(DynamicFeeRecipientsStore.init()),
"",
Opt.some default(Eth1Address),
defaultGasLimit,
)
state = newClone(dag.headState)
cache: StateCache
info: ForkedEpochInfo
cfg.process_slots(
state[], cfg.lastPremergeSlotInTestCfg, cache, info, {}).expect("OK")
var
b1 = addTestBlock(state[], cache, cfg = cfg).bellatrixData
b2 = addTestBlock(state[], cache, cfg = cfg).bellatrixData
getTimeFn = proc(): BeaconTime =
b2.message.slot.start_beacon_time(cfg.timeParams)
getStateField(state[], slot).start_beacon_time(cfg.timeParams)
batchVerifier = BatchVerifier.new(rng, taskpool)
processor = BlockProcessor.new(
false, "", "", batchVerifier, consensusManager,
validatorMonitor, blobQuarantine, dataColumnQuarantine, getTimeFn)
var
cache: StateCache
info: ForkedEpochInfo

cfg.process_slots(state[], cfg.lastPremergeSlotInTestCfg, cache, info, {}).expect(
"OK"
)

asyncTest "Reverse order block add & get" & preset():
let missing = await processor.addBlock(MsgSource.gossip, b2, noSidecars)
let
processor = BlockProcessor.new(
false, "", "", batchVerifier, consensusManager, validatorMonitor,
blobQuarantine, dataColumnQuarantine, getTimeFn,
)
b1 = addTestBlock(state[], cache, cfg = cfg).bellatrixData
b2 = addTestBlock(state[], cache, cfg = cfg).bellatrixData

check: missing.error == VerifierError.MissingParent
missing = await processor.addBlock(MsgSource.gossip, b2, noSidecars)

check:
missing.error == VerifierError.MissingParent
not dag.containsForkBlock(b2.root) # Unresolved, shouldn't show up

FetchRecord(root: b1.root) in quarantine[].checkMissing(32)
Expand All @@ -94,8 +109,7 @@ suite "Block processor" & preset():
while processor[].hasBlocks():
poll()

let
b2Get = dag.getBlockRef(b2.root)
let b2Get = dag.getBlockRef(b2.root)

check:
b2Get.isSome()
Expand Down Expand Up @@ -126,6 +140,8 @@ suite "Block processor" & preset():

asyncTest "Invalidate block root" & preset():
let
b1 = addTestBlock(state[], cache, cfg = cfg).bellatrixData
b2 = addTestBlock(state[], cache, cfg = cfg).bellatrixData
processor = BlockProcessor.new(
false, "", "", batchVerifier, consensusManager,
validatorMonitor, blobQuarantine, dataColumnQuarantine,
Expand Down Expand Up @@ -156,3 +172,30 @@ suite "Block processor" & preset():
res == Result[void, VerifierError].err VerifierError.Invalid
dag.containsForkBlock(b1.root)
not dag.containsForkBlock(b2.root)

asyncTest "Process a block from each fork (without blobs)" & preset():
let processor = BlockProcessor.new(
false, "", "", batchVerifier, consensusManager, validatorMonitor, blobQuarantine,
dataColumnQuarantine, getTimeFn,
)

debugGloasComment "TODO testing"
for consensusFork in ConsensusFork.Bellatrix .. ConsensusFork.Fulu:
process_slots(
cfg,
state[],
max(
getStateField(state[], slot) + 1,
cfg.consensusForkEpoch(consensusFork).start_slot,
),
cache,
info,
{},
)
.expect("OK")

withState(state[]):
let b0 = addTestEngineBlock(cfg, consensusFork, forkyState, cache)
discard await processor.addBlock(
MsgSource.gossip, b0.blck, b0.blobsBundle.toSidecarsOpt(consensusFork)
)
Loading
Loading