don't require optional fields importing slashing protection information (#4997)

This commit is contained in:
tersec 2023-05-31 15:51:00 +00:00 committed by GitHub
parent c036de5973
commit bc458921ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 15 deletions

View File

@ -13,12 +13,12 @@ import
# Status # Status
stew/[byteutils, results], stew/[byteutils, results],
serialization, serialization,
json_serialization, json_serialization, json_serialization/std/options,
chronicles, chronicles,
# Internal # Internal
../spec/datatypes/base ../spec/datatypes/base
export serialization, json_serialization # Generic sandwich https://github.com/nim-lang/Nim/issues/11225 export options, serialization, json_serialization # Generic sandwich https://github.com/nim-lang/Nim/issues/11225
# Slashing Protection Interop # Slashing Protection Interop
# -------------------------------------------- # --------------------------------------------
@ -29,7 +29,7 @@ export serialization, json_serialization # Generic sandwich https://github.com/n
# References: https://eips.ethereum.org/EIPS/eip-3076 # References: https://eips.ethereum.org/EIPS/eip-3076
# #
# SPDIR: Nimbus-specific, Slashing Protection Database Intermediate Representation # SPDIR: Nimbus-specific, Slashing Protection Database Intermediate Representation
# SPDIF: Cross-client, json, Slashing Protection Database Interchange Format # SPDIF: Cross-client, JSON, Slashing Protection Database Interchange Format
type type
SPDIR* = object SPDIR* = object
@ -70,12 +70,12 @@ type
SPDIR_SignedBlock* = object SPDIR_SignedBlock* = object
slot*: SlotString slot*: SlotString
signing_root*: Eth2Digest0x # compute_signing_root(block, domain) signing_root*: Option[Eth2Digest0x] # compute_signing_root(block, domain)
SPDIR_SignedAttestation* = object SPDIR_SignedAttestation* = object
source_epoch*: EpochString source_epoch*: EpochString
target_epoch*: EpochString target_epoch*: EpochString
signing_root*: Eth2Digest0x # compute_signing_root(attestation, domain) signing_root*: Option[Eth2Digest0x] # compute_signing_root(attestation, domain)
# Slashing Protection types # Slashing Protection types
# -------------------------------------------- # --------------------------------------------
@ -241,16 +241,24 @@ proc importSlashingInterchange*(
# Logging # Logging
# -------------------------------------------- # --------------------------------------------
func shortLog*(v: Option[Eth2Digest0x]): auto =
(
if v.isSome:
v.get.Eth2Digest.shortLog
else:
"none"
)
func shortLog*(v: SPDIR_SignedBlock): auto = func shortLog*(v: SPDIR_SignedBlock): auto =
( (
slot: shortLog(v.slot.Slot), slot: shortLog(v.slot.Slot),
signing_root: shortLog(v.signing_root.Eth2Digest) signing_root: shortLog(v.signing_root)
) )
func shortLog*(v: SPDIR_SignedAttestation): auto = func shortLog*(v: SPDIR_SignedAttestation): auto =
( (
source_epoch: shortLog(v.source_epoch.Epoch), source_epoch: shortLog(v.source_epoch.Epoch),
target_epoch: shortLog(v.target_epoch.Epoch), target_epoch: shortLog(v.target_epoch.Epoch),
signing_root: shortLog(v.signing_root.Eth2Digest) signing_root: shortLog(v.signing_root)
) )
chronicles.formatIt SlotString: it.Slot.shortLog chronicles.formatIt SlotString: it.Slot.shortLog
@ -319,11 +327,23 @@ proc importInterchangeV5Impl*(
maxValidSlotSeen = int dbSlot.get() maxValidSlotSeen = int dbSlot.get()
if spdir.data[v].signed_blocks.len >= 1: if spdir.data[v].signed_blocks.len >= 1:
# Minification, to limit Sqlite IO we only import the last block after sorting # Minification, to limit SQLite IO we only import the last block after sorting
template B: untyped = spdir.data[v].signed_blocks[^1] template B: untyped = spdir.data[v].signed_blocks[^1]
let status = db.registerBlock( let
parsedKey, B.slot.Slot, B.signing_root.Eth2Digest signing_root =
) if B.signing_root.isSome:
B.signing_root.get.Eth2Digest
else:
# https://eips.ethereum.org/EIPS/eip-3076#advice-for-complete-databases
# "If your database records the signing roots of messages in
# addition to their slot/epochs, you should ensure that imported
# messages without signing roots are assigned a suitable dummy
# signing root internally. We suggest using a special "null" value
# which is distinct from all other signing roots, although a value
# like 0x0 may be used instead (as it is extremely unlikely to
# collide with any real signing root)."
ZeroDigest
status = db.registerBlock(parsedKey, B.slot.Slot, signing_root)
if status.isErr(): if status.isErr():
# We might be importing a duplicate which EIP-3076 allows # We might be importing a duplicate which EIP-3076 allows
# there is no reason during normal operation to integrate # there is no reason during normal operation to integrate
@ -333,8 +353,8 @@ proc importInterchangeV5Impl*(
# having 2 blocks with the same signing root and different slots # having 2 blocks with the same signing root and different slots
# would break the blockchain so we only check for exact slot. # would break the blockchain so we only check for exact slot.
if status.error.kind == DoubleProposal and if status.error.kind == DoubleProposal and
B.signing_root.Eth2Digest != ZeroDigest and signing_root != ZeroDigest and
status.error.existingBlock == B.signing_root.Eth2Digest: status.error.existingBlock == signing_root:
warn "Block already exists in the DB", warn "Block already exists in the DB",
pubkey = spdir.data[v].pubkey.PubKeyBytes.toHex(), pubkey = spdir.data[v].pubkey.PubKeyBytes.toHex(),
candidateBlock = B candidateBlock = B

View File

@ -1422,7 +1422,7 @@ proc toSPDIR*(db: SlashingProtectionDB_v2): SPDIR
let status = selectBlkStmt.exec(validator.pubkey.PubKeyBytes) do (res: tuple[slot: int64, root: Hash32]): let status = selectBlkStmt.exec(validator.pubkey.PubKeyBytes) do (res: tuple[slot: int64, root: Hash32]):
validator.signed_blocks.add SPDIR_SignedBlock( validator.signed_blocks.add SPDIR_SignedBlock(
slot: SlotString res.slot, slot: SlotString res.slot,
signing_root: Eth2Digest0x(Eth2Digest(data: res.root)) signing_root: some Eth2Digest0x(Eth2Digest(data: res.root))
) )
doAssert status.isOk() doAssert status.isOk()
block: # Attestations block: # Attestations
@ -1430,7 +1430,7 @@ proc toSPDIR*(db: SlashingProtectionDB_v2): SPDIR
validator.signed_attestations.add SPDIR_SignedAttestation( validator.signed_attestations.add SPDIR_SignedAttestation(
source_epoch: EpochString res.source, source_epoch: EpochString res.source,
target_epoch: EpochString res.target, target_epoch: EpochString res.target,
signing_root: Eth2Digest0x(Eth2Digest(data: res.root)) signing_root: some Eth2Digest0x(Eth2Digest(data: res.root))
) )
doAssert status.isOk() doAssert status.isOk()