SignedBeaconBlock in state_transition (#773)

* using SignedBeaconBlock in state_transition
This commit is contained in:
Joao Gabriel Carvalho 2020-02-29 12:15:44 -03:00 committed by GitHub
parent ab1a08084b
commit 91f87b55b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 44 additions and 44 deletions

View File

@ -61,7 +61,7 @@ type
mainchainMonitor: MainchainMonitor
beaconClock: BeaconClock
proc onBeaconBlock*(node: BeaconNode, blck: SignedBeaconBlock) {.gcsafe.}
proc onBeaconBlock*(node: BeaconNode, signedBlock: SignedBeaconBlock) {.gcsafe.}
proc updateHead(node: BeaconNode): BlockRef
proc saveValidatorKey(keyName, key: string, conf: BeaconNodeConf) =
@ -412,7 +412,7 @@ proc proposeBlock(node: BeaconNode,
parent_root: head.root,
body: blockBody))
tmpState = hashedState
discard state_transition(tmpState, newBlock.message, {skipValidation})
discard state_transition(tmpState, newBlock, {skipValidation})
# TODO only enable in fast-fail debugging situations
# otherwise, bad attestations can bring down network
# doAssert ok # TODO: err, could this fail somehow?
@ -492,19 +492,19 @@ proc onAttestation(node: BeaconNode, attestation: Attestation) =
node.attestationPool.add(attestation)
proc onBeaconBlock(node: BeaconNode, blck: SignedBeaconBlock) =
proc onBeaconBlock(node: BeaconNode, signedBlock: SignedBeaconBlock) =
# We received a block but don't know much about it yet - in particular, we
# don't know if it's part of the chain we're currently building.
let blockRoot = hash_tree_root(blck.message)
let blockRoot = hash_tree_root(signedBlock.message)
debug "Block received",
blck = shortLog(blck.message),
signedBlock = shortLog(signedBlock.message),
blockRoot = shortLog(blockRoot),
cat = "block_listener",
pcs = "receive_block"
beacon_blocks_received.inc()
if node.blockPool.add(blockRoot, blck).isNil:
if node.blockPool.add(blockRoot, signedBlock).isNil:
return
# The block we received contains attestations, and we might not yet know about
@ -514,8 +514,8 @@ proc onBeaconBlock(node: BeaconNode, blck: SignedBeaconBlock) =
# TODO shouldn't add attestations if the block turns out to be invalid..
let currentSlot = node.beaconClock.now.toSlot
if currentSlot.afterGenesis and
blck.message.slot.epoch + 1 >= currentSlot.slot.epoch:
for attestation in blck.message.body.attestations:
signedBlock.message.slot.epoch + 1 >= currentSlot.slot.epoch:
for attestation in signedBlock.message.body.attestations:
node.onAttestation(attestation)
proc handleAttestations(node: BeaconNode, head: BlockRef, slot: Slot) =

View File

@ -374,7 +374,7 @@ proc add*(
# but maybe we should use it as a hint that our clock is wrong?
updateStateData(pool, pool.tmpState, BlockSlot(blck: parent, slot: blck.slot - 1))
if not state_transition(pool.tmpState.data, blck, {}):
if not state_transition(pool.tmpState.data, signedBlock, {}):
# TODO find a better way to log all this block data
notice "Invalid block",
blck = shortLog(blck),
@ -570,12 +570,12 @@ proc skipAndUpdateState(
afterUpdate(state)
proc skipAndUpdateState(
state: var HashedBeaconState, blck: BeaconBlock, flags: UpdateFlags,
state: var HashedBeaconState, signedBlock: SignedBeaconBlock, flags: UpdateFlags,
afterUpdate: proc (state: HashedBeaconState)): bool =
skipAndUpdateState(state, blck.slot - 1, afterUpdate)
skipAndUpdateState(state, signedBlock.message.slot - 1, afterUpdate)
let ok = state_transition(state, blck, flags)
let ok = state_transition(state, signedBlock, flags)
afterUpdate(state)
@ -713,7 +713,7 @@ proc updateStateData*(pool: BlockPool, state: var StateData, bs: BlockSlot) =
for i in countdown(ancestors.len - 1, 0):
let ok =
skipAndUpdateState(state.data,
ancestors[i].data.message,
ancestors[i].data,
{skipValidation}) do (state: HashedBeaconState):
pool.maybePutState(state, ancestors[i].refs)
doAssert ok, "Blocks in database should never fail to apply.."

View File

@ -113,7 +113,7 @@ proc verifyStateRoot(state: BeaconState, blck: BeaconBlock): bool =
true
proc state_transition*(
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool {.nbench.}=
state: var BeaconState, signedBlock: SignedBeaconBlock, flags: UpdateFlags): bool {.nbench.}=
## Time in the beacon chain moves by slots. Every time (haha.) that happens,
## we will update the beacon state. Normally, the state updates will be driven
## by the contents of a new block, but it may happen that the block goes
@ -147,7 +147,7 @@ proc state_transition*(
var old_state = state
# These should never fail.
process_slots(state, blck.slot)
process_slots(state, signedBlock.message.slot)
# Block updates - these happen when there's a new block being suggested
# by the block proposer. Every actor in the network will update its state
@ -157,11 +157,11 @@ proc state_transition*(
# https://github.com/ethereum/eth2.0-specs/issues/293
var per_epoch_cache = get_empty_per_epoch_cache()
if processBlock(state, blck, flags, per_epoch_cache):
if processBlock(state, signedBlock.message, flags, per_epoch_cache):
# This is a bit awkward - at the end of processing we verify that the
# state we arrive at is what the block producer thought it would be -
# meaning that potentially, it could fail verification
if skipValidation in flags or verifyStateRoot(state, blck):
if skipValidation in flags or verifyStateRoot(state, signedBlock.message):
# TODO: allow skipping just verifyStateRoot for mocking
# instead of both processBlock and verifyStateRoot
# https://github.com/status-im/nim-beacon-chain/issues/407
@ -220,23 +220,23 @@ proc process_slots*(state: var HashedBeaconState, slot: Slot) =
state.root = hash_tree_root(state.data)
proc state_transition*(
state: var HashedBeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
state: var HashedBeaconState, signedBlock: SignedBeaconBlock, flags: UpdateFlags): bool =
# Save for rollback
var old_state = state
process_slots(state, blck.slot)
process_slots(state, signedBlock.message.slot)
var per_epoch_cache = get_empty_per_epoch_cache()
if processBlock(state.data, blck, flags, per_epoch_cache):
if skipValidation in flags or verifyStateRoot(state.data, blck):
if processBlock(state.data, signedBlock.message, flags, per_epoch_cache):
if skipValidation in flags or verifyStateRoot(state.data, signedBlock.message):
# State root is what it should be - we're done!
# TODO when creating a new block, state_root is not yet set.. comparing
# with zero hash here is a bit fragile however, but this whole thing
# should go away with proper hash caching
state.root =
if blck.state_root == Eth2Digest(): hash_tree_root(state.data)
else: blck.state_root
if signedBlock.message.state_root == Eth2Digest(): hash_tree_root(state.data)
else: signedBlock.message.state_root
return true

View File

@ -22,7 +22,7 @@ type
else:
index: uint32
BeaconBlockCallback* = proc(blck: SignedBeaconBlock) {.gcsafe.}
BeaconBlockCallback* = proc(signedBlock: SignedBeaconBlock) {.gcsafe.}
BeaconSyncNetworkState* = ref object
blockPool*: BlockPool
forkVersion*: array[4, byte]

View File

@ -148,10 +148,10 @@ proc runFullTransition*(dir, preState, blocksPrefix: string, blocksQty: int, ski
let blockPath = dir / blocksPrefix & $i & ".ssz"
echo "Processing: ", blockPath
let blck = parseSSZ(blockPath, SignedBeaconBlock)
let signedBlock = parseSSZ(blockPath, SignedBeaconBlock)
let flags = if skipBLS: {skipValidation} # TODO: this also skips state root verification
else: {}
let success = state_transition(state[], blck.message, flags)
let success = state_transition(state[], signedBlock.message, flags)
echo "State transition status: ", if success: "SUCCESS ✓" else: "FAILURE ⚠️"
proc runProcessSlots*(dir, preState: string, numSlots: uint64) =

View File

@ -6,7 +6,7 @@ import
cli do(pre: string, blck: string, post: string, verifyStateRoot = false):
let
stateX = SSZ.loadFile(pre, BeaconState)
blckX = SSZ.loadFile(blck, BeaconBlock)
blckX = SSZ.loadFile(blck, SignedBeaconBlock)
flags = if verifyStateRoot: {skipValidation} else: {}
var stateY = HashedBeaconState(data: stateX, root: hash_tree_root(stateX))

View File

@ -91,7 +91,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
timers: array[Timers, RunningStat]
attesters: RunningStat
r: Rand
blck: SignedBeaconBlock
signedBlock: SignedBeaconBlock
cache = get_empty_per_epoch_cache()
proc maybeWrite(last: bool) =
@ -133,9 +133,9 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
else: tBlock
withTimer(timers[t]):
blck = addBlock(state, latest_block_root, body, flags)
signedBlock = addBlock(state, latest_block_root, body, flags)
latest_block_root = withTimerRet(timers[tHashBlock]):
hash_tree_root(blck.message)
hash_tree_root(signedBlock.message)
if attesterRatio > 0.0:
# attesterRatio is the fraction of attesters that actually do their

View File

@ -148,4 +148,4 @@ proc add*(state: var BeaconState, attestation: Attestation, slot: Slot) =
# TODO: we can skip just VerifyStateRoot
doAssert state_transition(
state, signedBlock.message, flags = {skipValidation})
state, signedBlock, flags = {skipValidation})

View File

@ -99,4 +99,4 @@ proc applyEmptyBlock*(state: var BeaconState) =
let signedBlock = mockBlock(state, state.slot, flags = {})
# TODO: we only need to skip verifyStateRoot validation
# processBlock validation should work
doAssert state_transition(state, signedBlock.message, {skipValidation})
doAssert state_transition(state, signedBlock, {skipValidation})

View File

@ -49,11 +49,11 @@ proc runTest(identifier: string) =
let blck = parseTest(testDir/"blocks_" & $i & ".ssz", SSZ, SignedBeaconBlock)
if postRef.isNil:
let success = state_transition(stateRef[], blck.message, flags = {})
let success = state_transition(stateRef[], blck, flags = {})
doAssert not success, "We didn't expect this invalid block to be processed"
else:
# TODO: The EF is using invalid BLS keys so we can't verify them
let success = state_transition(stateRef[], blck.message, flags = {skipValidation})
let success = state_transition(stateRef[], blck, flags = {skipValidation})
doAssert success, "Failure when applying block " & $i
# check: stateRef.hash_tree_root() == postRef.hash_tree_root()

View File

@ -30,18 +30,18 @@ suite "Beacon chain DB" & preset():
db = init(BeaconChainDB, kvStore MemoryStoreRef.init())
let
blck = SignedBeaconBlock()
root = hash_tree_root(blck.message)
signedBlock = SignedBeaconBlock()
root = hash_tree_root(signedBlock.message)
db.putBlock(blck)
db.putBlock(signedBlock)
check:
db.containsBlock(root)
db.getBlock(root).get() == blck
db.getBlock(root).get() == signedBlock
db.putStateRoot(root, blck.message.slot, root)
db.putStateRoot(root, signedBlock.message.slot, root)
check:
db.getStateRoot(root, blck.message.slot).get() == root
db.getStateRoot(root, signedBlock.message.slot).get() == root
timedTest "sanity check states" & preset():
var

View File

@ -40,7 +40,7 @@ suite "Block processing" & preset():
previous_block_root = hash_tree_root(genesisBlock.message)
new_block = makeBlock(state, previous_block_root, BeaconBlockBody())
let block_ok = state_transition(state, new_block.message, {})
let block_ok = state_transition(state, new_block, {})
check:
block_ok
@ -64,7 +64,7 @@ suite "Block processing" & preset():
for i in 1..SLOTS_PER_EPOCH.int:
var new_block = makeBlock(state, previous_block_root, BeaconBlockBody())
let block_ok = state_transition(state, new_block.message, {})
let block_ok = state_transition(state, new_block, {})
check:
block_ok
@ -98,7 +98,7 @@ suite "Block processing" & preset():
new_block = makeBlock(state, previous_block_root, BeaconBlockBody(
attestations: @[attestation]
))
discard state_transition(state, new_block.message, {})
discard state_transition(state, new_block, {})
check:
# TODO epoch attestations can get multiplied now; clean up paths to

View File

@ -111,7 +111,7 @@ proc addBlock*(
)
)
let block_ok = state_transition(state, new_block.message, {skipValidation})
let block_ok = state_transition(state, new_block, {skipValidation})
doAssert block_ok
# Ok, we have the new state as it would look with the block applied - now we