[WIP] Fake bls at runtime (#735)
* Initial implementation of runtime bls skipping. Add libnfuzz skipBLSValidation handling, check that it propagates. * Rename skipBLSValidation -> skipBlsValidation, start skipStateRootValidation * Replace skipValidation flags with more granular flags. Also added skipBlockParentRootValidation flag Mainly replaced with skipBlsValidation but also StateRoot or BlockParentRootValidation flags where appropriate. * Adjust interop test to pass when skipping merkle validation. * Stop skipping validation for mainchain_monitor. * Remove comment. * Also skipMerkleValidation for test_beacon_chain_db.
This commit is contained in:
parent
c382c6434a
commit
9a3db7a81f
|
@ -30,7 +30,7 @@ proc combine*(tgt: var Attestation, src: Attestation, flags: UpdateFlags) =
|
|||
if not tgt.aggregation_bits.overlaps(src.aggregation_bits):
|
||||
tgt.aggregation_bits.combine(src.aggregation_bits)
|
||||
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
tgt.signature.combine(src.signature)
|
||||
else:
|
||||
trace "Ignoring overlapping attestations"
|
||||
|
|
|
@ -412,7 +412,7 @@ proc proposeBlock(node: BeaconNode,
|
|||
parent_root: head.root,
|
||||
body: blockBody))
|
||||
tmpState = hashedState
|
||||
discard state_transition(tmpState, newBlock, {skipValidation})
|
||||
discard state_transition(tmpState, newBlock, {skipStateRootValidation})
|
||||
# TODO only enable in fast-fail debugging situations
|
||||
# otherwise, bad attestations can bring down network
|
||||
# doAssert ok # TODO: err, could this fail somehow?
|
||||
|
@ -1103,7 +1103,7 @@ when isMainModule:
|
|||
else: waitFor getLatestEth1BlockHash(config.depositWeb3Url)
|
||||
var
|
||||
initialState = initialize_beacon_state_from_eth1(
|
||||
eth1Hash, startTime, deposits, {skipValidation, skipMerkleValidation})
|
||||
eth1Hash, startTime, deposits, {skipBlsValidation, skipMerkleValidation})
|
||||
|
||||
# https://github.com/ethereum/eth2.0-pm/tree/6e41fcf383ebeb5125938850d8e9b4e9888389b4/interop/mocked_start#create-genesis-state
|
||||
initialState.genesis_time = startTime
|
||||
|
|
|
@ -714,7 +714,7 @@ proc updateStateData*(pool: BlockPool, state: var StateData, bs: BlockSlot) =
|
|||
let ok =
|
||||
skipAndUpdateState(state.data,
|
||||
ancestors[i].data,
|
||||
{skipValidation}) do (state: HashedBeaconState):
|
||||
{skipBlsValidation, skipMerkleValidation, skipStateRootValidation}) do (state: HashedBeaconState):
|
||||
pool.maybePutState(state, ancestors[i].refs)
|
||||
doAssert ok, "Blocks in database should never fail to apply.."
|
||||
|
||||
|
|
|
@ -7,17 +7,18 @@
|
|||
|
||||
# Temporary dumping ground for extra types and helpers that could make it into
|
||||
# the spec potentially
|
||||
#
|
||||
# The `skipXXXValidation` flags are used to skip over certain checks that are
|
||||
# normally done when an untrusted block arrives from the network. The
|
||||
# primary use case for this flag is when a proposer must propose a new
|
||||
# block - in order to do so, it needs to update the state as if the block
|
||||
# was valid, before it can sign it. Also useful for some testing, fuzzing with
|
||||
# improved coverage, and to avoid unnecessary validation when replaying trusted
|
||||
# (previously validated) blocks.
|
||||
|
||||
# TOdO
|
||||
|
||||
type
|
||||
UpdateFlag* = enum
|
||||
skipValidation ##\
|
||||
## The `skipValidation` flag is used to skip over certain checks that are
|
||||
## normally done when an untrusted block arrives from the network. The
|
||||
## primary use case for this flag is when a proposer must propose a new
|
||||
## block - in order to do so, it needs to update the state as if the block
|
||||
## was valid, before it can sign it.
|
||||
nextSlot ##\
|
||||
## Perform the operation as if the next slot was being processed - this is
|
||||
## useful when using the state to verify data that will go in the next slot,
|
||||
|
@ -35,5 +36,13 @@ type
|
|||
## in place while minimizing the tech debt they create. One, in principle,
|
||||
## should be able to remove this flag entirely. It is not intrinsically an
|
||||
## expensive operation to perform.
|
||||
skipBlsValidation ##\
|
||||
## Skip verification of BLS signatures in block processing.
|
||||
## Predominantly intended for use in testing, e.g. to allow extra coverage.
|
||||
## Also useful to avoid unnecessary work when replaying known, good blocks.
|
||||
skipStateRootValidation ##\
|
||||
## Skip verification of block state root.
|
||||
skipBlockParentRootValidation ##\
|
||||
## Skip verification that the block's parent root matches the previous block header.
|
||||
|
||||
UpdateFlags* = set[UpdateFlag]
|
||||
|
|
|
@ -56,7 +56,7 @@ func makeDeposit*(
|
|||
pubkey: pubkey,
|
||||
withdrawal_credentials: makeWithdrawalCredentials(pubkey)))
|
||||
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
ret.data.signature =
|
||||
bls_sign(
|
||||
privkey, hash_tree_root(ret.getDepositMessage).data,
|
||||
|
|
|
@ -84,7 +84,7 @@ proc processDeposits(m: MainchainMonitor, web3: Web3) {.async.} =
|
|||
h.data = array[32, byte](blkHash)
|
||||
let startTime = blk.timestamp.uint64
|
||||
var s = initialize_beacon_state_from_eth1(
|
||||
h, startTime, m.pendingDeposits, {skipValidation})
|
||||
h, startTime, m.pendingDeposits, {})
|
||||
|
||||
if is_valid_genesis_state(s):
|
||||
# https://github.com/ethereum/eth2.0-pm/tree/6e41fcf383ebeb5125938850d8e9b4e9888389b4/interop/mocked_start#create-genesis-state
|
||||
|
|
|
@ -73,7 +73,7 @@ proc process_deposit*(
|
|||
|
||||
if index == -1:
|
||||
# Verify the deposit signature (proof of possession)
|
||||
if skipValidation notin flags and not bls_verify(
|
||||
if skipBlsValidation notin flags and not bls_verify(
|
||||
pubkey, hash_tree_root(deposit.getDepositMessage).data,
|
||||
deposit.data.signature, compute_domain(DOMAIN_DEPOSIT)):
|
||||
return false
|
||||
|
@ -381,7 +381,7 @@ proc is_valid_indexed_attestation*(
|
|||
return false
|
||||
|
||||
# Verify aggregate signature
|
||||
if skipValidation notin flags and not bls_verify(
|
||||
if skipBlsValidation notin flags and not bls_verify(
|
||||
bls_aggregate_pubkeys(mapIt(indices, state.validators[it.int].pubkey)),
|
||||
hash_tree_root(indexed_attestation.data).data,
|
||||
indexed_attestation.signature,
|
||||
|
|
|
@ -149,7 +149,8 @@ func bls_aggregate_signatures*(keys: openArray[ValidatorSig]): ValidatorSig =
|
|||
# https://github.com/ethereum/eth2.0-specs/blob/v0.9.4/specs/bls_signature.md#bls_verify
|
||||
func bls_verify*(
|
||||
pubkey: ValidatorPubKey, msg: openArray[byte], sig: ValidatorSig,
|
||||
domain: Domain): bool =
|
||||
domain: Domain
|
||||
): bool =
|
||||
# name from spec!
|
||||
if sig.kind != Real:
|
||||
# Invalid signatures are possible in deposits (discussed with Danny)
|
||||
|
|
|
@ -56,10 +56,8 @@ proc process_block_header*(
|
|||
return false
|
||||
|
||||
# Verify that the parent matches
|
||||
if skipValidation notin flags and not (blck.parent_root ==
|
||||
if skipBlockParentRootValidation notin flags and not (blck.parent_root ==
|
||||
hash_tree_root(state.latest_block_header)):
|
||||
# TODO: skip validation is too strong
|
||||
# can't do "invalid_parent_root" test
|
||||
notice "Block header: previous block root mismatch",
|
||||
latest_block_header = state.latest_block_header,
|
||||
blck = shortLog(blck),
|
||||
|
@ -102,8 +100,7 @@ proc process_randao(
|
|||
let proposer = addr state.validators[proposer_index.get]
|
||||
|
||||
# Verify that the provided randao value is valid
|
||||
if skipValidation notin flags:
|
||||
if not bls_verify(
|
||||
if skipBlsValidation notin flags and not bls_verify(
|
||||
proposer.pubkey,
|
||||
hash_tree_root(epoch.uint64).data,
|
||||
body.randao_reveal,
|
||||
|
@ -167,7 +164,7 @@ proc process_proposer_slashing*(
|
|||
return false
|
||||
|
||||
# Signatures are valid
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
for i, signed_header in [proposer_slashing.signed_header_1,
|
||||
proposer_slashing.signed_header_2]:
|
||||
if not bls_verify(
|
||||
|
@ -253,7 +250,7 @@ proc process_attester_slashing*(
|
|||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/beacon-chain.md#attester-slashings
|
||||
proc processAttesterSlashings(state: var BeaconState, blck: BeaconBlock,
|
||||
stateCache: var StateCache): bool {.nbench.}=
|
||||
flags: UpdateFlags, stateCache: var StateCache): bool {.nbench.}=
|
||||
# Process ``AttesterSlashing`` operation.
|
||||
if len(blck.body.attester_slashings) > MAX_ATTESTER_SLASHINGS:
|
||||
notice "Attester slashing: too many!"
|
||||
|
@ -340,7 +337,7 @@ proc process_voluntary_exit*(
|
|||
return false
|
||||
|
||||
# Verify signature
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
let domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
|
||||
if not bls_verify(
|
||||
validator.pubkey,
|
||||
|
@ -413,7 +410,7 @@ proc processBlock*(
|
|||
debug "[Block processing] Proposer slashing failure", slot = shortLog(state.slot)
|
||||
return false
|
||||
|
||||
if not processAttesterSlashings(state, blck, stateCache):
|
||||
if not processAttesterSlashings(state, blck, flags, stateCache):
|
||||
debug "[Block processing] Attester slashing failure", slot = shortLog(state.slot)
|
||||
return false
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# The purpose of this code right is primarily educational, to help piece
|
||||
# together the mechanics of the beacon state and to discover potential problem
|
||||
# areas. The entry point is `updateState` which is at the bottom of the file!
|
||||
# areas. The entry point is `state_transition` which is at the bottom of the file!
|
||||
#
|
||||
# General notes about the code (TODO):
|
||||
# * It's inefficient - we quadratically copy, allocate and iterate when there
|
||||
|
@ -161,10 +161,7 @@ proc state_transition*(
|
|||
# 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, 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
|
||||
if skipStateRootValidation in flags or verifyStateRoot(state, signedBlock.message):
|
||||
# State root is what it should be - we're done!
|
||||
return true
|
||||
|
||||
|
@ -228,7 +225,7 @@ proc state_transition*(
|
|||
var per_epoch_cache = get_empty_per_epoch_cache()
|
||||
|
||||
if processBlock(state.data, signedBlock.message, flags, per_epoch_cache):
|
||||
if skipValidation in flags or verifyStateRoot(state.data, signedBlock.message):
|
||||
if skipStateRootValidation 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
|
||||
|
|
|
@ -149,7 +149,7 @@ proc runFullTransition*(dir, preState, blocksPrefix: string, blocksQty: int, ski
|
|||
echo "Processing: ", blockPath
|
||||
|
||||
let signedBlock = parseSSZ(blockPath, SignedBeaconBlock)
|
||||
let flags = if skipBLS: {skipValidation} # TODO: this also skips state root verification
|
||||
let flags = if skipBLS: {skipBlsValidation}
|
||||
else: {}
|
||||
let success = state_transition(state[], signedBlock.message, flags)
|
||||
echo "State transition status: ", if success: "SUCCESS ✓" else: "FAILURE ⚠️"
|
||||
|
@ -207,7 +207,7 @@ template processBlockScenarioImpl(
|
|||
when needCache:
|
||||
var cache = get_empty_per_epoch_cache()
|
||||
when needFlags:
|
||||
let flags = if skipBLS: {skipValidation} # TODO: this also skips state root verification
|
||||
let flags = if skipBLS: {skipBlsValidation}
|
||||
else: {}
|
||||
|
||||
let consObjPath = dir/paramName & ".ssz"
|
||||
|
|
|
@ -7,7 +7,7 @@ cli do(pre: string, blck: string, post: string, verifyStateRoot = false):
|
|||
let
|
||||
stateX = SSZ.loadFile(pre, BeaconState)
|
||||
blckX = SSZ.loadFile(blck, SignedBeaconBlock)
|
||||
flags = if verifyStateRoot: {skipValidation} else: {}
|
||||
flags = if verifyStateRoot: {skipStateRootValidation} else: {}
|
||||
|
||||
var stateY = HashedBeaconState(data: stateX, root: hash_tree_root(stateX))
|
||||
if not state_transition(stateY, blckX, flags):
|
||||
|
|
|
@ -13,20 +13,20 @@ void NimMain();
|
|||
|
||||
/** Supported fuzzing tests */
|
||||
bool nfuzz_attestation(uint8_t* input_ptr, size_t input_size,
|
||||
uint8_t* output_ptr, size_t* output_size);
|
||||
uint8_t* output_ptr, size_t* output_size, bool disable_bls);
|
||||
bool nfuzz_attester_slashing(uint8_t* input_ptr, size_t input_size,
|
||||
uint8_t* output_ptr, size_t* output_size);
|
||||
uint8_t* output_ptr, size_t* output_size, bool disable_bls);
|
||||
bool nfuzz_block(uint8_t* input_ptr, size_t input_size,
|
||||
uint8_t* output_ptr, size_t* output_size);
|
||||
uint8_t* output_ptr, size_t* output_size, bool disable_bls);
|
||||
bool nfuzz_block_header(uint8_t* input_ptr, size_t input_size,
|
||||
uint8_t* output_ptr, size_t* output_size);
|
||||
uint8_t* output_ptr, size_t* output_size, bool disable_bls);
|
||||
bool nfuzz_deposit(uint8_t* input_ptr, size_t input_size,
|
||||
uint8_t* output_ptr, size_t* output_size);
|
||||
uint8_t* output_ptr, size_t* output_size, bool disable_bls);
|
||||
bool nfuzz_proposer_slashing(uint8_t* input_ptr, size_t input_size,
|
||||
uint8_t* output_ptr, size_t* output_size);
|
||||
uint8_t* output_ptr, size_t* output_size, bool disable_bls);
|
||||
bool nfuzz_shuffle(uint8_t* seed_ptr, uint64_t* output_ptr, size_t output_size);
|
||||
bool nfuzz_voluntary_exit(uint8_t* input_ptr, size_t input_size,
|
||||
uint8_t* output_ptr, size_t* output_size);
|
||||
uint8_t* output_ptr, size_t* output_size, bool disable_bls);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -58,10 +58,11 @@ proc copyState(state: BeaconState, output: ptr byte,
|
|||
result = true
|
||||
|
||||
proc nfuzz_attestation(input: openArray[byte], output: ptr byte,
|
||||
output_size: ptr uint): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
output_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
var
|
||||
data: AttestationInput
|
||||
cache = get_empty_per_epoch_cache()
|
||||
let flags = if disable_bls: {skipBlsValidation} else: {}
|
||||
|
||||
try:
|
||||
data = SSZ.decode(input, AttestationInput)
|
||||
|
@ -75,7 +76,7 @@ proc nfuzz_attestation(input: openArray[byte], output: ptr byte,
|
|||
|
||||
try:
|
||||
result = process_attestation(data.state, data.attestation,
|
||||
{skipValidation}, cache)
|
||||
flags, cache)
|
||||
except ValueError as e:
|
||||
# These exceptions are expected to be raised by chronicles logging:
|
||||
# See status-im/nim-chronicles#60
|
||||
|
@ -90,10 +91,11 @@ proc nfuzz_attestation(input: openArray[byte], output: ptr byte,
|
|||
result = copyState(data.state, output, output_size)
|
||||
|
||||
proc nfuzz_attester_slashing(input: openArray[byte], output: ptr byte,
|
||||
output_size: ptr uint): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
output_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
var
|
||||
data: AttesterSlashingInput
|
||||
cache = get_empty_per_epoch_cache()
|
||||
let flags = if disable_bls: {skipBlsValidation} else: {}
|
||||
|
||||
try:
|
||||
data = SSZ.decode(input, AttesterSlashingInput)
|
||||
|
@ -107,7 +109,7 @@ proc nfuzz_attester_slashing(input: openArray[byte], output: ptr byte,
|
|||
|
||||
try:
|
||||
# TODO flags
|
||||
result = process_attester_slashing(data.state, data.attesterSlashing, cache)
|
||||
result = process_attester_slashing(data.state, data.attesterSlashing, flags, cache)
|
||||
except ValueError as e:
|
||||
# TODO remove when status-im/nim-chronicles#60 is resolved
|
||||
raise newException(
|
||||
|
@ -120,8 +122,9 @@ proc nfuzz_attester_slashing(input: openArray[byte], output: ptr byte,
|
|||
result = copyState(data.state, output, output_size)
|
||||
|
||||
proc nfuzz_block(input: openArray[byte], output: ptr byte,
|
||||
output_size: ptr uint): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
output_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
var data: BlockInput
|
||||
let flags = if disable_bls: {skipBlsValidation} else: {}
|
||||
|
||||
try:
|
||||
data = SSZ.decode(input, BlockInput)
|
||||
|
@ -134,7 +137,7 @@ proc nfuzz_block(input: openArray[byte], output: ptr byte,
|
|||
)
|
||||
|
||||
try:
|
||||
result = state_transition(data.state, data.beaconBlock, {})
|
||||
result = state_transition(data.state, data.beaconBlock, flags)
|
||||
except IOError, ValueError:
|
||||
# TODO remove when status-im/nim-chronicles#60 is resolved
|
||||
let e = getCurrentException()
|
||||
|
@ -152,10 +155,11 @@ proc nfuzz_block(input: openArray[byte], output: ptr byte,
|
|||
result = copyState(data.state, output, output_size)
|
||||
|
||||
proc nfuzz_block_header(input: openArray[byte], output: ptr byte,
|
||||
output_size: ptr uint): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
output_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
var
|
||||
data: BlockHeaderInput
|
||||
cache = get_empty_per_epoch_cache()
|
||||
let flags = if disable_bls: {skipBlsValidation} else: {}
|
||||
|
||||
try:
|
||||
data = SSZ.decode(input, BlockHeaderInput)
|
||||
|
@ -169,7 +173,7 @@ proc nfuzz_block_header(input: openArray[byte], output: ptr byte,
|
|||
|
||||
try:
|
||||
# TODO disable bls
|
||||
result = process_block_header(data.state, data.beaconBlock, {}, cache)
|
||||
result = process_block_header(data.state, data.beaconBlock, flags, cache)
|
||||
except IOError, ValueError:
|
||||
let e = getCurrentException()
|
||||
# TODO remove when status-im/nim-chronicles#60 is resolved
|
||||
|
@ -184,9 +188,10 @@ proc nfuzz_block_header(input: openArray[byte], output: ptr byte,
|
|||
|
||||
|
||||
proc nfuzz_deposit(input: openArray[byte], output: ptr byte,
|
||||
output_size: ptr uint): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
output_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
var
|
||||
data: DepositInput
|
||||
let flags = if disable_bls: {skipBlsValidation} else: {}
|
||||
|
||||
try:
|
||||
data = SSZ.decode(input, DepositInput)
|
||||
|
@ -199,7 +204,7 @@ proc nfuzz_deposit(input: openArray[byte], output: ptr byte,
|
|||
)
|
||||
|
||||
try:
|
||||
result = process_deposit(data.state, data.deposit, {})
|
||||
result = process_deposit(data.state, data.deposit, flags)
|
||||
except IOError, ValueError:
|
||||
let e = getCurrentException()
|
||||
# TODO remove when status-im/nim-chronicles#60 is resolved
|
||||
|
@ -213,10 +218,11 @@ proc nfuzz_deposit(input: openArray[byte], output: ptr byte,
|
|||
result = copyState(data.state, output, output_size)
|
||||
|
||||
proc nfuzz_proposer_slashing(input: openArray[byte], output: ptr byte,
|
||||
output_size: ptr uint): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
output_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
var
|
||||
data: ProposerSlashingInput
|
||||
cache = get_empty_per_epoch_cache()
|
||||
let flags = if disable_bls: {skipBlsValidation} else: {}
|
||||
|
||||
try:
|
||||
data = SSZ.decode(input, ProposerSlashingInput)
|
||||
|
@ -229,7 +235,7 @@ proc nfuzz_proposer_slashing(input: openArray[byte], output: ptr byte,
|
|||
)
|
||||
|
||||
try:
|
||||
result = process_proposer_slashing(data.state, data.proposerSlashing, {}, cache)
|
||||
result = process_proposer_slashing(data.state, data.proposerSlashing, flags, cache)
|
||||
except ValueError as e:
|
||||
# TODO remove when status-im/nim-chronicles#60 is resolved
|
||||
raise newException(
|
||||
|
@ -270,9 +276,10 @@ proc nfuzz_shuffle(input_seed: ptr byte, output: var openArray[uint64]): bool
|
|||
result = true
|
||||
|
||||
proc nfuzz_voluntary_exit(input: openArray[byte], output: ptr byte,
|
||||
output_size: ptr uint): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
output_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError, Defect].} =
|
||||
var
|
||||
data: VoluntaryExitInput
|
||||
let flags = if disable_bls: {skipBlsValidation} else: {}
|
||||
|
||||
try:
|
||||
data = SSZ.decode(input, VoluntaryExitInput)
|
||||
|
@ -285,7 +292,7 @@ proc nfuzz_voluntary_exit(input: openArray[byte], output: ptr byte,
|
|||
)
|
||||
|
||||
try:
|
||||
result = process_voluntary_exit(data.state, data.exit, {})
|
||||
result = process_voluntary_exit(data.state, data.exit, flags)
|
||||
except ValueError as e:
|
||||
# TODO remove when status-im/nim-chronicles#60 is resolved
|
||||
raise newException(
|
||||
|
|
|
@ -7,7 +7,7 @@ import
|
|||
proc stateSize(deposits: int, maxContent = false) =
|
||||
var state = initialize_beacon_state_from_eth1(
|
||||
Eth2Digest(), 0,
|
||||
makeInitialDeposits(deposits, {skipValidation}), {skipValidation})
|
||||
makeInitialDeposits(deposits, {skipBLSValidation}), {skipBLSValidation})
|
||||
|
||||
if maxContent:
|
||||
# TODO: state.latest_attestations was removed
|
||||
|
|
|
@ -71,7 +71,8 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
|
|||
validate = true):
|
||||
echo "Preparing validators..."
|
||||
let
|
||||
flags = if validate: {} else: {skipValidation}
|
||||
# TODO should we include other skipXXXValidation flags here (e.g. StateRoot)?
|
||||
flags = if validate: {} else: {skipBlsValidation}
|
||||
deposits = makeInitialDeposits(validators, flags)
|
||||
|
||||
echo "Generating Genesis..."
|
||||
|
@ -79,7 +80,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
|
|||
let
|
||||
genesisState =
|
||||
initialize_beacon_state_from_eth1(
|
||||
Eth2Digest(), 0, deposits, {skipMerkleValidation})
|
||||
Eth2Digest(), 0, deposits, flags + {skipMerkleValidation})
|
||||
genesisBlock = get_initial_beacon_block(genesisState)
|
||||
|
||||
echo "Starting simulation..."
|
||||
|
|
|
@ -114,7 +114,7 @@ proc mockAttestationImpl(
|
|||
for i in 0 ..< beacon_committee.len:
|
||||
result.aggregation_bits[i] = true
|
||||
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
signMockAttestation(state, result)
|
||||
|
||||
proc mockAttestation*(
|
||||
|
@ -146,6 +146,5 @@ proc add*(state: var BeaconState, attestation: Attestation, slot: Slot) =
|
|||
process_slots(state, slot)
|
||||
signMockBlock(state, signedBlock)
|
||||
|
||||
# TODO: we can skip just VerifyStateRoot
|
||||
doAssert state_transition(
|
||||
state, signedBlock, flags = {skipValidation})
|
||||
state, signedBlock, flags = {skipStateRootValidation})
|
||||
|
|
|
@ -76,7 +76,7 @@ proc mockBlock(
|
|||
slot: Slot,
|
||||
flags: UpdateFlags = {}): SignedBeaconBlock =
|
||||
## Mock a BeaconBlock for the specific slot
|
||||
## Add skipValidation if block should not be signed
|
||||
## Skip signature creation if block should not be signed (skipBlsValidation present)
|
||||
|
||||
result.message.slot = slot
|
||||
result.message.body.eth1_data.deposit_count = state.eth1_deposit_index
|
||||
|
@ -86,7 +86,7 @@ proc mockBlock(
|
|||
previous_block_header.state_root = state.hash_tree_root()
|
||||
result.message.parent_root = previous_block_header.hash_tree_root()
|
||||
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
signMockBlock(state, result)
|
||||
|
||||
proc mockBlockForNextSlot*(state: BeaconState, flags: UpdateFlags = {}):
|
||||
|
@ -97,6 +97,4 @@ proc applyEmptyBlock*(state: var BeaconState) =
|
|||
## Do a state transition with an empty signed block
|
||||
## on the current slot
|
||||
let signedBlock = mockBlock(state, state.slot, flags = {})
|
||||
# TODO: we only need to skip verifyStateRoot validation
|
||||
# processBlock validation should work
|
||||
doAssert state_transition(state, signedBlock, {skipValidation})
|
||||
doAssert state_transition(state, signedBlock, {skipStateRootValidation})
|
||||
|
|
|
@ -71,7 +71,7 @@ func mockDepositData(
|
|||
flags: UpdateFlags = {}
|
||||
) =
|
||||
mockDepositData(deposit_data, pubkey, amount)
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
signMockDepositData(deposit_data, privkey)
|
||||
|
||||
func mockDepositData(
|
||||
|
@ -84,7 +84,7 @@ func mockDepositData(
|
|||
flags: UpdateFlags = {}
|
||||
) =
|
||||
mockDepositData(deposit_data, pubkey, amount)
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
signMockDepositData(deposit_data, privkey, state)
|
||||
|
||||
template mockGenesisDepositsImpl(
|
||||
|
@ -96,7 +96,9 @@ template mockGenesisDepositsImpl(
|
|||
) =
|
||||
# Genesis deposits with varying amounts
|
||||
|
||||
if skipValidation in flags:
|
||||
# NOTE: this could also apply for skipMerkleValidation, but prefer to er on the
|
||||
# side of caution and generate a valid Deposit (it can still be skipped later).
|
||||
if skipBlsValidation in flags:
|
||||
# 1st loop - build deposit data
|
||||
for valIdx in 0 ..< validatorCount.int:
|
||||
# Directly build the Deposit in-place for speed
|
||||
|
|
|
@ -21,11 +21,11 @@ proc initGenesisState*(num_validators: uint64, genesis_time: uint64 = 0): Beacon
|
|||
let deposits = mockGenesisBalancedDeposits(
|
||||
validatorCount = num_validators,
|
||||
amountInEth = 32, # We create canonical validators with 32 Eth
|
||||
flags = {skipValidation}
|
||||
flags = {skipBlsValidation}
|
||||
)
|
||||
|
||||
initialize_beacon_state_from_eth1(
|
||||
eth1BlockHash, 0, deposits, {skipValidation, skipMerkleValidation})
|
||||
eth1BlockHash, 0, deposits, {skipBlsValidation, skipMerkleValidation})
|
||||
|
||||
when isMainModule:
|
||||
# Smoke test
|
||||
|
|
|
@ -33,7 +33,7 @@ proc runTest(identifier: string) =
|
|||
var flags: UpdateFlags
|
||||
var prefix: string
|
||||
if not existsFile(testDir/"meta.yaml"):
|
||||
flags.incl skipValidation
|
||||
flags.incl skipBlsValidation
|
||||
if existsFile(testDir/"post.ssz"):
|
||||
prefix = "[Valid] "
|
||||
else:
|
||||
|
|
|
@ -33,7 +33,7 @@ proc runTest(identifier: string) =
|
|||
var flags: UpdateFlags
|
||||
var prefix: string
|
||||
if not existsFile(testDir/"meta.yaml"):
|
||||
flags.incl skipValidation
|
||||
flags.incl skipBlsValidation
|
||||
if existsFile(testDir/"post.ssz"):
|
||||
prefix = "[Valid] "
|
||||
else:
|
||||
|
|
|
@ -33,7 +33,7 @@ proc runTest(identifier: string) =
|
|||
var flags: UpdateFlags
|
||||
var prefix: string
|
||||
if not existsFile(testDir/"meta.yaml"):
|
||||
flags.incl skipValidation
|
||||
flags.incl skipBlsValidation
|
||||
if existsFile(testDir/"post.ssz"):
|
||||
prefix = "[Valid] "
|
||||
else:
|
||||
|
|
|
@ -33,7 +33,7 @@ proc runTest(identifier: string) =
|
|||
var flags: UpdateFlags
|
||||
var prefix: string
|
||||
if not existsFile(testDir/"meta.yaml"):
|
||||
flags.incl skipValidation
|
||||
flags.incl skipBlsValidation
|
||||
if existsFile(testDir/"post.ssz"):
|
||||
prefix = "[Valid] "
|
||||
else:
|
||||
|
|
|
@ -33,7 +33,7 @@ proc runTest(identifier: string) =
|
|||
var flags: UpdateFlags
|
||||
var prefix: string
|
||||
if not existsFile(testDir/"meta.yaml"):
|
||||
flags.incl skipValidation
|
||||
flags.incl skipBlsValidation
|
||||
if existsFile(testDir/"post.ssz"):
|
||||
prefix = "[Valid] "
|
||||
else:
|
||||
|
|
|
@ -53,7 +53,7 @@ proc runTest(identifier: string) =
|
|||
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, flags = {skipValidation})
|
||||
let success = state_transition(stateRef[], blck, flags = {skipBlsValidation})
|
||||
doAssert success, "Failure when applying block " & $i
|
||||
|
||||
# check: stateRef.hash_tree_root() == postRef.hash_tree_root()
|
||||
|
|
|
@ -43,7 +43,7 @@ suite "[Unit - Spec - Block processing] Deposits " & preset():
|
|||
state,
|
||||
uint64 validator_index,
|
||||
deposit_amount,
|
||||
flags = {skipValidation}
|
||||
flags = {skipBlsValidation}
|
||||
)
|
||||
|
||||
# Params for sanity checks
|
||||
|
@ -57,7 +57,7 @@ suite "[Unit - Spec - Block processing] Deposits " & preset():
|
|||
# State transition
|
||||
# ----------------------------------------
|
||||
check: state.process_deposit(deposit,
|
||||
{skipValidation, skipMerkleValidation})
|
||||
{skipBlsValidation, skipMerkleValidation})
|
||||
|
||||
# Check invariants
|
||||
# ----------------------------------------
|
||||
|
@ -88,7 +88,7 @@ suite "[Unit - Spec - Block processing] Deposits " & preset():
|
|||
state,
|
||||
uint64 validator_index,
|
||||
deposit_amount,
|
||||
flags = {skipValidation}
|
||||
flags = {skipBlsValidation}
|
||||
)
|
||||
|
||||
# Params for sanity checks
|
||||
|
@ -102,7 +102,7 @@ suite "[Unit - Spec - Block processing] Deposits " & preset():
|
|||
# State transition
|
||||
# ----------------------------------------
|
||||
check: state.process_deposit(deposit,
|
||||
{skipValidation, skipMerkleValidation})
|
||||
{skipBlsValidation, skipMerkleValidation})
|
||||
|
||||
# Check invariants
|
||||
# ----------------------------------------
|
||||
|
|
|
@ -104,7 +104,7 @@ suite "Beacon chain DB" & preset():
|
|||
|
||||
let
|
||||
state = initialize_beacon_state_from_eth1(
|
||||
eth1BlockHash, 0, makeInitialDeposits(SLOTS_PER_EPOCH), {skipValidation})
|
||||
eth1BlockHash, 0, makeInitialDeposits(SLOTS_PER_EPOCH), {skipBlsValidation, skipMerkleValidation})
|
||||
root = hash_tree_root(state)
|
||||
|
||||
db.putState(state)
|
||||
|
|
|
@ -149,6 +149,8 @@ suite "Interop":
|
|||
deposits.add(makeDeposit(privKey.pubKey(), privKey))
|
||||
|
||||
var
|
||||
# TODO this currently requires skipMerkleValidation to pass the test
|
||||
# makeDeposit doesn't appear to produce a proof?
|
||||
initialState = initialize_beacon_state_from_eth1(
|
||||
eth1BlockHash, 1570500000, deposits, {skipMerkleValidation})
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
|
|||
)
|
||||
)
|
||||
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
result.data.signature =
|
||||
bls_sign(privkey, hash_tree_root(result.getDepositMessage).data,
|
||||
domain)
|
||||
|
@ -77,8 +77,10 @@ proc addBlock*(
|
|||
body: BeaconBlockBody, flags: UpdateFlags = {}): SignedBeaconBlock =
|
||||
# Create and add a block to state - state will advance by one slot!
|
||||
# This is the equivalent of running
|
||||
# updateState(state, prev_block, makeBlock(...), {skipValidation})
|
||||
# updateState(state, prev_block, makeBlock(...), {skipBlsValidation})
|
||||
# but avoids some slow block copies
|
||||
# FIXME update comment - updateState no longer exists, could be `state_transition`
|
||||
# but different number of parameters
|
||||
|
||||
state.slot += 1
|
||||
var cache = get_empty_per_epoch_cache()
|
||||
|
@ -93,7 +95,7 @@ proc addBlock*(
|
|||
|
||||
# TODO ugly hack; API needs rethinking
|
||||
var new_body = body
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
new_body.randao_reveal = privKey.genRandaoReveal(state.fork, state.slot + 1)
|
||||
|
||||
new_body.eth1_data = Eth1Data()
|
||||
|
@ -111,7 +113,7 @@ proc addBlock*(
|
|||
)
|
||||
)
|
||||
|
||||
let block_ok = state_transition(state, new_block, {skipValidation})
|
||||
let block_ok = state_transition(state, new_block, {skipBlsValidation, skipStateRootValidation})
|
||||
doAssert block_ok
|
||||
|
||||
# Ok, we have the new state as it would look with the block applied - now we
|
||||
|
@ -121,7 +123,7 @@ proc addBlock*(
|
|||
doAssert privKey.pubKey() == proposer.pubkey,
|
||||
"signature key should be derived from private key! - wrong privkey?"
|
||||
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
let block_root = hash_tree_root(new_block.message)
|
||||
# We have a signature - put it in the block and we should be done!
|
||||
new_block.signature =
|
||||
|
@ -171,7 +173,7 @@ proc makeAttestation*(
|
|||
let
|
||||
msg = hash_tree_root(data)
|
||||
sig =
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
bls_sign(
|
||||
hackPrivKey(validator), msg.data,
|
||||
get_domain(state, DOMAIN_BEACON_ATTESTER, data.target.epoch))
|
||||
|
@ -231,7 +233,7 @@ proc makeFullAttestations*(
|
|||
)
|
||||
for j in 0..<committee.len():
|
||||
attestation.aggregation_bits.setBit j
|
||||
if skipValidation notin flags:
|
||||
if skipBlsValidation notin flags:
|
||||
attestation.signature.combine(bls_sign(
|
||||
hackPrivKey(state.validators[committee[j]]), msg.data,
|
||||
get_domain(state, DOMAIN_BEACON_ATTESTER, data.target.epoch)))
|
||||
|
|
|
@ -80,8 +80,8 @@ proc makeTestDB*(validators: int): BeaconChainDB =
|
|||
let
|
||||
genState = initialize_beacon_state_from_eth1(
|
||||
Eth2Digest(), 0,
|
||||
makeInitialDeposits(validators, flags = {skipValidation}),
|
||||
{skipValidation, skipMerkleValidation})
|
||||
makeInitialDeposits(validators, flags = {skipBlsValidation}),
|
||||
{skipBlsValidation, skipMerkleValidation})
|
||||
genBlock = get_initial_beacon_block(genState)
|
||||
makeTestDB(genState, genBlock)
|
||||
|
||||
|
|
Loading…
Reference in New Issue