Skip to content

Commit 18968e9

Browse files
authored
Bugfix: Invalid blocks were produced in the presence of invalid deposits (#3639)
Since we were not verifying BLS signature in blocks that we produce, we were failing to notice that some deposits need to be ignored (due to having an invalid signature). Processing these deposits resulted in a different ending state after the state transition which caused our blocks to be rejected by the network.
1 parent 397033a commit 18968e9

File tree

4 files changed

+29
-36
lines changed

4 files changed

+29
-36
lines changed

beacon_chain/spec/state_transition.nim

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,11 @@ proc makeBeaconBlock*(
329329
sync_aggregate: SyncAggregate,
330330
execution_payload: ExecutionPayload,
331331
rollback: RollbackHashedProc[phase0.HashedBeaconState],
332-
cache: var StateCache): Result[phase0.BeaconBlock, cstring] =
332+
cache: var StateCache,
333+
# TODO:
334+
# `verificationFlags` is needed only in tests and can be
335+
# removed if we don't use invalid signatures there
336+
verificationFlags: UpdateFlags = {}): Result[phase0.BeaconBlock, cstring] =
333337
## Create a block for the given state. The latest block applied to it will
334338
## be used for the parent_root value, and the slot will be take from
335339
## state.slot meaning process_slots must be called up to the slot for which
@@ -342,7 +346,7 @@ proc makeBeaconBlock*(
342346
randao_reveal, eth1_data, graffiti, attestations, deposits,
343347
exits, sync_aggregate, execution_payload)
344348

345-
let res = process_block(cfg, state.data, blck, {skipBlsValidation}, cache)
349+
let res = process_block(cfg, state.data, blck, verificationFlags, cache)
346350

347351
if res.isErr:
348352
rollback(state)
@@ -394,7 +398,11 @@ proc makeBeaconBlock*(
394398
sync_aggregate: SyncAggregate,
395399
execution_payload: ExecutionPayload,
396400
rollback: RollbackHashedProc[altair.HashedBeaconState],
397-
cache: var StateCache): Result[altair.BeaconBlock, cstring] =
401+
cache: var StateCache,
402+
# TODO:
403+
# `verificationFlags` is needed only in tests and can be
404+
# removed if we don't use invalid signatures there
405+
verificationFlags: UpdateFlags = {}): Result[altair.BeaconBlock, cstring] =
398406
## Create a block for the given state. The latest block applied to it will
399407
## be used for the parent_root value, and the slot will be take from
400408
## state.slot meaning process_slots must be called up to the slot for which
@@ -407,7 +415,7 @@ proc makeBeaconBlock*(
407415
randao_reveal, eth1_data, graffiti, attestations, deposits,
408416
exits, sync_aggregate, execution_payload)
409417

410-
let res = process_block(cfg, state.data, blck, {skipBlsValidation}, cache)
418+
let res = process_block(cfg, state.data, blck, verificationFlags, cache)
411419

412420
if res.isErr:
413421
rollback(state)
@@ -460,7 +468,11 @@ proc makeBeaconBlock*(
460468
sync_aggregate: SyncAggregate,
461469
execution_payload: ExecutionPayload,
462470
rollback: RollbackHashedProc[bellatrix.HashedBeaconState],
463-
cache: var StateCache): Result[bellatrix.BeaconBlock, cstring] =
471+
cache: var StateCache,
472+
# TODO:
473+
# `verificationFlags` is needed only in tests and can be
474+
# removed if we don't use invalid signatures there
475+
verificationFlags: UpdateFlags = {}): Result[bellatrix.BeaconBlock, cstring] =
464476
## Create a block for the given state. The latest block applied to it will
465477
## be used for the parent_root value, and the slot will be take from
466478
## state.slot meaning process_slots must be called up to the slot for which
@@ -473,7 +485,7 @@ proc makeBeaconBlock*(
473485
randao_reveal, eth1_data, graffiti, attestations, deposits,
474486
exits, sync_aggregate, execution_payload)
475487

476-
let res = process_block(cfg, state.data, blck, {skipBlsValidation}, cache)
488+
let res = process_block(cfg, state.data, blck, verificationFlags, cache)
477489

478490
if res.isErr:
479491
rollback(state)
@@ -497,7 +509,11 @@ proc makeBeaconBlock*(
497509
sync_aggregate: SyncAggregate,
498510
executionPayload: ExecutionPayload,
499511
rollback: RollbackForkedHashedProc,
500-
cache: var StateCache): Result[ForkedBeaconBlock, cstring] =
512+
cache: var StateCache,
513+
# TODO:
514+
# `verificationFlags` is needed only in tests and can be
515+
# removed if we don't use invalid signatures there
516+
verificationFlags: UpdateFlags = {}): Result[ForkedBeaconBlock, cstring] =
501517
## Create a block for the given state. The latest block applied to it will
502518
## be used for the parent_root value, and the slot will be take from
503519
## state.slot meaning process_slots must be called up to the slot for which
@@ -514,8 +530,7 @@ proc makeBeaconBlock*(
514530
exits, sync_aggregate, executionPayload))
515531

516532
let res = process_block(cfg, state.`kind Data`.data, blck.`kind Data`,
517-
{skipBlsValidation}, cache)
518-
533+
verificationFlags, cache)
519534
if res.isErr:
520535
rollback(state)
521536
return err(res.error())

beacon_chain/spec/state_transition_block.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ proc process_deposit*(cfg: RuntimeConfig,
296296
else:
297297
# Verify the deposit signature (proof of possession) which is not checked
298298
# by the deposit contract
299-
if skipBlsValidation in flags or verify_deposit_signature(cfg, deposit.data):
299+
if verify_deposit_signature(cfg, deposit.data):
300300
# New validator! Add validator and balance entries
301301
if not state.validators.add(get_validator_from_deposit(deposit.data)):
302302
return err("process_deposit: too many validators")

ncli/resttest-rules.json

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,18 +2972,6 @@
29722972
"status": {"operator": "equals", "value": "400"}
29732973
}
29742974
},
2975-
{
2976-
"topics": ["validator", "blocks"],
2977-
"request": {
2978-
"url": "/eth/v1/validator/blocks/1?randao_reveal=0x97897b5e8526b4d0f808e7b60bcd1942935b124720bd5156da54c54adc25fe458ef7c934b4e5018afe4659978b06e6510797e5cc7fc31f329035ec6a46889ee9aea375d57b22be71dd4ff181b7f1a07b9199e73c2b80e39e04ba904596d9e4db",
2979-
"headers": {"Accept": "application/json"}
2980-
},
2981-
"response": {
2982-
"status": {"operator": "equals", "value": "200"},
2983-
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
2984-
"body": [{"operator": "jstructcmps", "start": ["data"], "value": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [], "attester_slashings": [], "attestations": [], "deposits": [], "voluntary_exits": []}}}]
2985-
}
2986-
},
29872975
{
29882976
"topics": ["validator", "blocksV2"],
29892977
"request": {
@@ -2994,18 +2982,6 @@
29942982
"status": {"operator": "equals", "value": "400"}
29952983
}
29962984
},
2997-
{
2998-
"topics": ["validator", "blocksV2"],
2999-
"request": {
3000-
"url": "/eth/v2/validator/blocks/1?randao_reveal=0x97897b5e8526b4d0f808e7b60bcd1942935b124720bd5156da54c54adc25fe458ef7c934b4e5018afe4659978b06e6510797e5cc7fc31f329035ec6a46889ee9aea375d57b22be71dd4ff181b7f1a07b9199e73c2b80e39e04ba904596d9e4db",
3001-
"headers": {"Accept": "application/json"}
3002-
},
3003-
"response": {
3004-
"status": {"operator": "equals", "value": "200"},
3005-
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
3006-
"body": [{"operator": "jstructcmps", "start": ["data"], "value": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [], "attester_slashings": [], "attestations": [], "deposits": [], "voluntary_exits": []}}}]
3007-
}
3008-
},
30092985
{
30102986
"topics": ["validator", "attestation_data"],
30112987
"request": {

tests/testblockutil.nim

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,11 @@ proc addTestBlock*(
124124
sync_aggregate,
125125
default(ExecutionPayload),
126126
noRollback,
127-
cache)
127+
cache,
128+
verificationFlags = {skipBlsValidation})
128129

129-
doAssert message.isOk(), "Should have created a valid block!"
130+
if message.isErr:
131+
raiseAssert "Failed to create a block: " & $message.error
130132

131133
let
132134
new_block = signBlock(

0 commit comments

Comments
 (0)