Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -481,9 +481,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 @@ -572,6 +569,12 @@ proc storeBlock(
# DAG doesn't know about unviable ancestor blocks - we do however!
return err(VerifierError.UnviableFork)

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
88 changes: 65 additions & 23 deletions tests/test_block_processor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import
taskpools,
../beacon_chain/conf,
../beacon_chain/spec/[beaconstate, forks, helpers, state_transition],
../beacon_chain/spec/datatypes/[deneb, fulu],
../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 @@ -41,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 @@ -95,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 @@ -127,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 @@ -157,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