Skip to content

Commit

Permalink
Keep cooked pubkeys in cache (#3122)
Browse files Browse the repository at this point in the history
Turning uncompressed pubkeys into cooked ones is fast, but unnecessary -
this should avoid a little work for every signature validation we do by
pre-loading them at startup.
  • Loading branch information
arnetheduck authored Nov 25, 2021
1 parent 97da6e1 commit f69b272
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
24 changes: 13 additions & 11 deletions beacon_chain/beacon_chain_db.nim
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ type

# immutableValidatorsDb only stores the total count; it's a proxy for SQL
# queries.
immutableValidatorsDb*: DbSeq[ImmutableValidatorData2]
immutableValidatorsDb*: DbSeq[ImmutableValidatorDataDb2]
immutableValidators*: seq[ImmutableValidatorData2]

checkpoint*: proc() {.gcsafe, raises: [Defect].}
Expand Down Expand Up @@ -257,13 +257,13 @@ proc get*[T](s: DbSeq[T], idx: int64): T =
let found = queryRes.expectDb()
if not found: panic()

proc loadImmutableValidators(vals: DbSeq[ImmutableValidatorData]): seq[ImmutableValidatorData] =
proc loadImmutableValidators(vals: DbSeq[ImmutableValidatorDataDb2]): seq[ImmutableValidatorData2] =
result = newSeqOfCap[ImmutableValidatorData2](vals.len())
for i in 0 ..< vals.len:
result.add vals.get(i)

proc loadImmutableValidators(vals: DbSeq[ImmutableValidatorData2]): seq[ImmutableValidatorData2] =
for i in 0 ..< vals.len:
result.add vals.get(i)
let tmp = vals.get(i)
result.add ImmutableValidatorData2(
pubkey: tmp.pubkey.loadValid(),
withdrawal_credentials: tmp.withdrawal_credentials)

proc new*(T: type BeaconChainDB,
dir: string,
Expand Down Expand Up @@ -299,7 +299,7 @@ proc new*(T: type BeaconChainDB,
genesisDepositsSeq =
DbSeq[DepositData].init(db, "genesis_deposits").expectDb()
immutableValidatorsDb =
DbSeq[ImmutableValidatorData2].init(db, "immutable_validators2").expectDb()
DbSeq[ImmutableValidatorDataDb2].init(db, "immutable_validators2").expectDb()

# V1 - expected-to-be small rows get without rowid optimizations
keyValues = kvStore db.openKvStore("key_values", true).expectDb()
Expand All @@ -325,7 +325,7 @@ proc new*(T: type BeaconChainDB,
len = immutableValidatorsDb1.len()
while immutableValidatorsDb.len() < immutableValidatorsDb1.len():
let val = immutableValidatorsDb1.get(immutableValidatorsDb.len())
immutableValidatorsDb.add(ImmutableValidatorData2(
immutableValidatorsDb.add(ImmutableValidatorDataDb2(
pubkey: val.pubkey.loadValid().toUncompressed(),
withdrawal_credentials: val.withdrawal_credentials
))
Expand Down Expand Up @@ -505,7 +505,9 @@ proc updateImmutableValidators*(
while db.immutableValidators.len() < numValidators:
let immutableValidator =
getImmutableValidatorData(validators[db.immutableValidators.len()])
db.immutableValidatorsDb.add immutableValidator
db.immutableValidatorsDb.add ImmutableValidatorDataDb2(
pubkey: immutableValidator.pubkey.toUncompressed(),
withdrawal_credentials: immutableValidator.withdrawal_credentials)
db.immutableValidators.add immutableValidator

template toBeaconStateNoImmutableValidators(state: phase0.BeaconState):
Expand Down Expand Up @@ -657,7 +659,7 @@ proc getStateOnlyMutableValidators(

assign(
dstValidator.pubkey,
immutableValidators[i].pubkey.loadValid().toPubKey())
immutableValidators[i].pubkey.toPubKey())
assign(
dstValidator.withdrawal_credentials,
immutableValidators[i].withdrawal_credentials)
Expand Down
10 changes: 7 additions & 3 deletions beacon_chain/spec/datatypes/base.nim
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,14 @@ type

# Non-spec type that represents the immutable part of a validator - an
# uncompressed key serialization is used to speed up loading from database
ImmutableValidatorData2* = object
ImmutableValidatorDataDb2* = object
pubkey*: UncompressedPubKey
withdrawal_credentials*: Eth2Digest

ImmutableValidatorData2* = object
pubkey*: CookedPubKey
withdrawal_credentials*: Eth2Digest

# https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/phase0/beacon-chain.md#validator
Validator* = object
pubkey*: ValidatorPubKey
Expand Down Expand Up @@ -520,7 +524,7 @@ func getImmutableValidatorData*(validator: Validator): ImmutableValidatorData2 =
doAssert cookedKey.isSome,
"Cannot parse validator key: " & toHex(validator.pubkey)
ImmutableValidatorData2(
pubkey: cookedKey.get().toUncompressed(),
pubkey: cookedKey.get(),
withdrawal_credentials: validator.withdrawal_credentials)

# TODO when https://github.com/nim-lang/Nim/issues/14440 lands in Status's Nim,
Expand Down Expand Up @@ -875,7 +879,7 @@ proc load*(
if validators.lenu64() <= index.uint64:
none(CookedPubKey)
else:
some(validators[index.int].pubkey.loadValid())
some(validators[index.int].pubkey)

template hash*(header: BeaconBlockHeader): Hash =
hash(header.state_root)
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/statediff.nim
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func applyValidatorIdentities(
hl: auto) =
for item in hl:
if not validators.add Validator(
pubkey: item.pubkey.loadValid().toPubKey(),
pubkey: item.pubkey.toPubKey(),
withdrawal_credentials: item.withdrawal_credentials):
raiseAssert "cannot readd"

Expand Down

0 comments on commit f69b272

Please sign in to comment.