Keep cooked pubkeys in cache (#3122)

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.
This commit is contained in:
Jacek Sieka 2021-11-25 19:41:54 +01:00 committed by GitHub
parent 97da6e1365
commit f69b272850
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 15 deletions

View File

@ -83,7 +83,7 @@ type
# immutableValidatorsDb only stores the total count; it's a proxy for SQL # immutableValidatorsDb only stores the total count; it's a proxy for SQL
# queries. # queries.
immutableValidatorsDb*: DbSeq[ImmutableValidatorData2] immutableValidatorsDb*: DbSeq[ImmutableValidatorDataDb2]
immutableValidators*: seq[ImmutableValidatorData2] immutableValidators*: seq[ImmutableValidatorData2]
checkpoint*: proc() {.gcsafe, raises: [Defect].} checkpoint*: proc() {.gcsafe, raises: [Defect].}
@ -257,13 +257,13 @@ proc get*[T](s: DbSeq[T], idx: int64): T =
let found = queryRes.expectDb() let found = queryRes.expectDb()
if not found: panic() 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: for i in 0 ..< vals.len:
result.add vals.get(i) let tmp = vals.get(i)
result.add ImmutableValidatorData2(
proc loadImmutableValidators(vals: DbSeq[ImmutableValidatorData2]): seq[ImmutableValidatorData2] = pubkey: tmp.pubkey.loadValid(),
for i in 0 ..< vals.len: withdrawal_credentials: tmp.withdrawal_credentials)
result.add vals.get(i)
proc new*(T: type BeaconChainDB, proc new*(T: type BeaconChainDB,
dir: string, dir: string,
@ -299,7 +299,7 @@ proc new*(T: type BeaconChainDB,
genesisDepositsSeq = genesisDepositsSeq =
DbSeq[DepositData].init(db, "genesis_deposits").expectDb() DbSeq[DepositData].init(db, "genesis_deposits").expectDb()
immutableValidatorsDb = 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 # V1 - expected-to-be small rows get without rowid optimizations
keyValues = kvStore db.openKvStore("key_values", true).expectDb() keyValues = kvStore db.openKvStore("key_values", true).expectDb()
@ -325,7 +325,7 @@ proc new*(T: type BeaconChainDB,
len = immutableValidatorsDb1.len() len = immutableValidatorsDb1.len()
while immutableValidatorsDb.len() < immutableValidatorsDb1.len(): while immutableValidatorsDb.len() < immutableValidatorsDb1.len():
let val = immutableValidatorsDb1.get(immutableValidatorsDb.len()) let val = immutableValidatorsDb1.get(immutableValidatorsDb.len())
immutableValidatorsDb.add(ImmutableValidatorData2( immutableValidatorsDb.add(ImmutableValidatorDataDb2(
pubkey: val.pubkey.loadValid().toUncompressed(), pubkey: val.pubkey.loadValid().toUncompressed(),
withdrawal_credentials: val.withdrawal_credentials withdrawal_credentials: val.withdrawal_credentials
)) ))
@ -505,7 +505,9 @@ proc updateImmutableValidators*(
while db.immutableValidators.len() < numValidators: while db.immutableValidators.len() < numValidators:
let immutableValidator = let immutableValidator =
getImmutableValidatorData(validators[db.immutableValidators.len()]) 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 db.immutableValidators.add immutableValidator
template toBeaconStateNoImmutableValidators(state: phase0.BeaconState): template toBeaconStateNoImmutableValidators(state: phase0.BeaconState):
@ -657,7 +659,7 @@ proc getStateOnlyMutableValidators(
assign( assign(
dstValidator.pubkey, dstValidator.pubkey,
immutableValidators[i].pubkey.loadValid().toPubKey()) immutableValidators[i].pubkey.toPubKey())
assign( assign(
dstValidator.withdrawal_credentials, dstValidator.withdrawal_credentials,
immutableValidators[i].withdrawal_credentials) immutableValidators[i].withdrawal_credentials)

View File

@ -282,10 +282,14 @@ type
# Non-spec type that represents the immutable part of a validator - an # Non-spec type that represents the immutable part of a validator - an
# uncompressed key serialization is used to speed up loading from database # uncompressed key serialization is used to speed up loading from database
ImmutableValidatorData2* = object ImmutableValidatorDataDb2* = object
pubkey*: UncompressedPubKey pubkey*: UncompressedPubKey
withdrawal_credentials*: Eth2Digest 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 # https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/phase0/beacon-chain.md#validator
Validator* = object Validator* = object
pubkey*: ValidatorPubKey pubkey*: ValidatorPubKey
@ -520,7 +524,7 @@ func getImmutableValidatorData*(validator: Validator): ImmutableValidatorData2 =
doAssert cookedKey.isSome, doAssert cookedKey.isSome,
"Cannot parse validator key: " & toHex(validator.pubkey) "Cannot parse validator key: " & toHex(validator.pubkey)
ImmutableValidatorData2( ImmutableValidatorData2(
pubkey: cookedKey.get().toUncompressed(), pubkey: cookedKey.get(),
withdrawal_credentials: validator.withdrawal_credentials) withdrawal_credentials: validator.withdrawal_credentials)
# TODO when https://github.com/nim-lang/Nim/issues/14440 lands in Status's Nim, # TODO when https://github.com/nim-lang/Nim/issues/14440 lands in Status's Nim,
@ -875,7 +879,7 @@ proc load*(
if validators.lenu64() <= index.uint64: if validators.lenu64() <= index.uint64:
none(CookedPubKey) none(CookedPubKey)
else: else:
some(validators[index.int].pubkey.loadValid()) some(validators[index.int].pubkey)
template hash*(header: BeaconBlockHeader): Hash = template hash*(header: BeaconBlockHeader): Hash =
hash(header.state_root) hash(header.state_root)

View File

@ -32,7 +32,7 @@ func applyValidatorIdentities(
hl: auto) = hl: auto) =
for item in hl: for item in hl:
if not validators.add Validator( if not validators.add Validator(
pubkey: item.pubkey.loadValid().toPubKey(), pubkey: item.pubkey.toPubKey(),
withdrawal_credentials: item.withdrawal_credentials): withdrawal_credentials: item.withdrawal_credentials):
raiseAssert "cannot readd" raiseAssert "cannot readd"