2018-11-28 19:49:03 +00:00
|
|
|
# beacon_chain
|
2024-01-06 14:26:56 +00:00
|
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
2018-11-28 19:49:03 +00:00
|
|
|
# Licensed and distributed under either of
|
2019-11-25 15:30:02 +00:00
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
2018-11-28 19:49:03 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2024-02-18 01:16:49 +00:00
|
|
|
{.push raises: [].}
|
|
|
|
|
2018-11-28 19:49:03 +00:00
|
|
|
# At the time of writing, the exact definitions of what should be used for
|
|
|
|
# cryptography in the spec is in flux, with sizes and test vectors still being
|
|
|
|
# hashed out. This layer helps isolate those chagnes.
|
|
|
|
|
2019-12-10 14:20:40 +00:00
|
|
|
# BLS signatures can be combined such that multiple signatures are aggregated.
|
|
|
|
# Each time a new signature is added, the corresponding public key must be
|
|
|
|
# added to the verification key as well - if a key signs twice, it must be added
|
|
|
|
# twice to the verification key. Aggregated signatures can be combined
|
|
|
|
# arbitrarily (like addition) as long as public keys are aggregated in the same
|
|
|
|
# way.
|
2018-12-27 20:14:37 +00:00
|
|
|
#
|
2019-12-10 14:20:40 +00:00
|
|
|
# In eth2, we use a single bit to record which keys have signed, thus we cannot
|
|
|
|
# combined overlapping aggregates - ie if we have an aggregate of signatures of
|
|
|
|
# A, B and C, and another with B, C and D, we cannot practically combine them
|
|
|
|
# even if in theory it is possible to allow this in BLS.
|
2018-12-27 20:14:37 +00:00
|
|
|
|
2018-11-28 19:49:03 +00:00
|
|
|
import
|
2020-03-04 21:27:11 +00:00
|
|
|
# Status
|
2024-01-16 22:37:14 +00:00
|
|
|
results,
|
|
|
|
stew/[bitseqs, endians2, objects, byteutils],
|
2020-04-11 08:51:07 +00:00
|
|
|
blscurve,
|
2020-03-04 21:27:11 +00:00
|
|
|
chronicles,
|
2022-06-21 08:29:16 +00:00
|
|
|
bearssl/rand,
|
2022-01-08 20:06:34 +00:00
|
|
|
json_serialization
|
|
|
|
|
2022-12-08 16:21:53 +00:00
|
|
|
from std/hashes import Hash
|
|
|
|
from std/sequtils import mapIt
|
|
|
|
from std/tables import Table, withValue, `[]=`
|
|
|
|
|
2022-01-08 20:06:34 +00:00
|
|
|
from nimcrypto/utils import burnMem
|
2018-12-19 12:58:53 +00:00
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
export results, blscurve, rand, json_serialization
|
2020-03-04 21:27:11 +00:00
|
|
|
|
|
|
|
# Type definitions
|
|
|
|
# ----------------------------------------------------------------------
|
2018-11-28 19:49:03 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
const
|
|
|
|
RawSigSize* = 96
|
|
|
|
RawPubKeySize* = 48
|
2021-06-10 07:37:02 +00:00
|
|
|
UncompressedPubKeySize* = 96
|
2024-02-22 16:13:31 +00:00
|
|
|
# RawPrivKeySize* = 32 for BLST
|
2020-04-11 08:51:07 +00:00
|
|
|
|
2018-11-28 19:49:03 +00:00
|
|
|
type
|
2021-06-10 07:37:02 +00:00
|
|
|
ValidatorPubKey* = object ##\
|
|
|
|
## Compressed raw serialized key bytes - this type is used in so as to not
|
|
|
|
## eagerly load keys - deserialization is slow, as are equality checks -
|
|
|
|
## however, it is not guaranteed that the key is valid (except in some
|
|
|
|
## cases, like the database state)
|
2023-08-08 19:01:32 +00:00
|
|
|
##
|
|
|
|
## It must be 8-byte aligned because `hash(ValidatorPubKey)` just casts a
|
|
|
|
## ptr to one to a ptr to the other, so it needs a compatible alignment.
|
2023-08-17 03:06:21 +00:00
|
|
|
blob* {.align: 16.}: array[RawPubKeySize, byte]
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2021-06-10 07:37:02 +00:00
|
|
|
UncompressedPubKey* = object
|
|
|
|
## Uncompressed variation of ValidatorPubKey - this type is faster to
|
|
|
|
## deserialize but doubles the storage footprint
|
2023-08-17 03:06:21 +00:00
|
|
|
blob* {.align: 16.}: array[UncompressedPubKeySize, byte]
|
2021-06-10 07:37:02 +00:00
|
|
|
|
2021-06-01 11:13:40 +00:00
|
|
|
CookedPubKey* = distinct blscurve.PublicKey ## Valid deserialized key
|
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
ValidatorSig* = object
|
2023-08-17 06:27:26 +00:00
|
|
|
blob* {.align: 16.}: array[RawSigSize, byte]
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
ValidatorPrivKey* = distinct blscurve.SecretKey
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
BlsCurveType* = ValidatorPrivKey | ValidatorPubKey | ValidatorSig
|
|
|
|
|
|
|
|
BlsResult*[T] = Result[T, cstring]
|
2018-11-29 01:08:34 +00:00
|
|
|
|
2020-06-25 10:23:10 +00:00
|
|
|
TrustedSig* = object
|
2024-06-13 13:11:04 +00:00
|
|
|
blob* {.align: 16.}: array[RawSigSize, byte]
|
2020-06-25 10:23:10 +00:00
|
|
|
|
|
|
|
SomeSig* = TrustedSig | ValidatorSig
|
|
|
|
|
2021-03-17 13:35:59 +00:00
|
|
|
CookedSig* = distinct blscurve.Signature ## \
|
2021-04-26 20:39:44 +00:00
|
|
|
## Cooked signatures are those that have been loaded successfully from a
|
|
|
|
## ValidatorSig and are used to avoid expensive reloading as well as error
|
|
|
|
## checking
|
2021-08-27 09:00:06 +00:00
|
|
|
|
2022-05-10 00:32:12 +00:00
|
|
|
SignatureShare* = object
|
|
|
|
sign*: blscurve.Signature
|
|
|
|
id*: uint32
|
|
|
|
|
|
|
|
SecretShare* = object
|
|
|
|
key*: ValidatorPrivKey
|
|
|
|
id*: uint32
|
|
|
|
|
2021-08-27 09:00:06 +00:00
|
|
|
export
|
|
|
|
AggregateSignature
|
2020-08-15 17:33:58 +00:00
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# API
|
|
|
|
# ----------------------------------------------------------------------
|
2024-01-20 11:19:47 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#bls-signatures
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2021-06-01 11:13:40 +00:00
|
|
|
func toPubKey*(privkey: ValidatorPrivKey): CookedPubKey =
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
## Derive a public key from a private key
|
|
|
|
# Un-specced in either hash-to-curve or Eth2
|
|
|
|
var pubKey: blscurve.PublicKey
|
|
|
|
let ok = publicFromSecret(pubKey, SecretKey privkey)
|
2020-10-27 08:37:04 +00:00
|
|
|
doAssert ok, "The validator private key was a zero key. This should never happen."
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2021-06-01 11:13:40 +00:00
|
|
|
CookedPubKey(pubKey)
|
|
|
|
|
|
|
|
template toRaw*(x: CookedPubKey): auto =
|
|
|
|
PublicKey(x).exportRaw()
|
2021-08-27 09:00:06 +00:00
|
|
|
|
2021-06-10 07:37:02 +00:00
|
|
|
template toUncompressed*(x: CookedPubKey): auto =
|
|
|
|
UncompressedPubKey(blob: PublicKey(x).exportUncompressed())
|
2021-06-01 11:13:40 +00:00
|
|
|
|
|
|
|
func toPubKey*(pubKey: CookedPubKey): ValidatorPubKey =
|
|
|
|
## Derive a public key from a private key
|
|
|
|
# Un-specced in either hash-to-curve or Eth2
|
|
|
|
ValidatorPubKey(blob: pubKey.toRaw())
|
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
func load*(v: ValidatorPubKey): Opt[CookedPubKey] =
|
2021-06-01 11:13:40 +00:00
|
|
|
## Parse signature blob - this may fail
|
|
|
|
var val: blscurve.PublicKey
|
|
|
|
if fromBytes(val, v.blob):
|
2023-01-11 12:29:21 +00:00
|
|
|
Opt.some CookedPubKey(val)
|
2021-06-01 11:13:40 +00:00
|
|
|
else:
|
2023-01-11 12:29:21 +00:00
|
|
|
Opt.none CookedPubKey
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
func load*(v: UncompressedPubKey): Opt[CookedPubKey] =
|
2021-06-10 07:37:02 +00:00
|
|
|
## Parse signature blob - this may fail
|
|
|
|
var val: blscurve.PublicKey
|
|
|
|
if fromBytes(val, v.blob):
|
2023-01-11 12:29:21 +00:00
|
|
|
Opt.some CookedPubKey(val)
|
2021-06-10 07:37:02 +00:00
|
|
|
else:
|
2023-01-11 12:29:21 +00:00
|
|
|
Opt.none CookedPubKey
|
2021-06-10 07:37:02 +00:00
|
|
|
|
|
|
|
func loadValid*(v: UncompressedPubKey | ValidatorPubKey): CookedPubKey {.noinit.} =
|
|
|
|
## Parse known-to-be-valid key - this is the case for any key that's passed
|
|
|
|
## parsing once and is the output of serialization, such as those keys we
|
|
|
|
## keep in the database or state.
|
|
|
|
var val: blscurve.PublicKey
|
|
|
|
let ok = fromBytesKnownOnCurve(val, v.blob)
|
|
|
|
doAssert ok, "Valid key no longer parses, data corrupt? " & $v
|
|
|
|
|
|
|
|
CookedPubKey(val)
|
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
proc loadWithCache*(v: ValidatorPubKey): Opt[CookedPubKey] =
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
## Parse public key blob - this may fail - this function uses a cache to
|
|
|
|
## avoid the expensive deserialization - for now, external public keys only
|
|
|
|
## come from deposits in blocks - when more sources are added, the memory
|
|
|
|
## usage of the cache should be considered
|
2021-06-01 11:13:40 +00:00
|
|
|
var cache {.threadvar.}: Table[typeof(v.blob), CookedPubKey]
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
|
|
|
|
# Try to get parse value from cache - if it's not in there, try to parse it -
|
|
|
|
# if that's not possible, it's broken
|
|
|
|
cache.withValue(v.blob, key) do:
|
2023-01-11 12:29:21 +00:00
|
|
|
return Opt.some key[]
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
do:
|
|
|
|
# Only valid keys are cached
|
2021-06-01 11:13:40 +00:00
|
|
|
let cooked = v.load()
|
|
|
|
if cooked.isSome():
|
|
|
|
cache[v.blob] = cooked.get()
|
|
|
|
return cooked
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
func load*(v: ValidatorSig): Opt[CookedSig] =
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
## Parse signature blob - this may fail
|
|
|
|
var parsed: blscurve.Signature
|
|
|
|
if fromBytes(parsed, v.blob):
|
2023-01-11 12:29:21 +00:00
|
|
|
Opt.some(CookedSig(parsed))
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
else:
|
2023-01-11 12:29:21 +00:00
|
|
|
Opt.none(CookedSig)
|
2020-08-15 17:33:58 +00:00
|
|
|
|
2021-06-01 11:13:40 +00:00
|
|
|
func init*(agg: var AggregatePublicKey, pubkey: CookedPubKey) {.inline.}=
|
|
|
|
## Initializes an aggregate signature context
|
|
|
|
agg.init(blscurve.PublicKey(pubkey))
|
|
|
|
|
|
|
|
func init*(T: type AggregatePublicKey, pubkey: CookedPubKey): T =
|
|
|
|
result.init(pubkey)
|
|
|
|
|
2022-02-17 11:53:55 +00:00
|
|
|
func aggregate*(agg: var AggregatePublicKey, pubkey: CookedPubKey) {.inline.}=
|
2021-06-01 11:13:40 +00:00
|
|
|
## Aggregate two valid Validator Public Keys
|
|
|
|
agg.aggregate(blscurve.PublicKey(pubkey))
|
|
|
|
|
|
|
|
func finish*(agg: AggregatePublicKey): CookedPubKey {.inline.} =
|
|
|
|
## Canonicalize an AggregatePublicKey into a signature
|
|
|
|
var pubkey: blscurve.PublicKey
|
|
|
|
pubkey.finish(agg)
|
|
|
|
CookedPubKey(pubkey)
|
|
|
|
|
2021-03-17 13:35:59 +00:00
|
|
|
func init*(agg: var AggregateSignature, sig: CookedSig) {.inline.}=
|
|
|
|
## Initializes an aggregate signature context
|
|
|
|
agg.init(blscurve.Signature(sig))
|
|
|
|
|
2021-04-26 20:39:44 +00:00
|
|
|
func init*(T: type AggregateSignature, sig: CookedSig): T =
|
2021-04-12 20:25:09 +00:00
|
|
|
result.init(sig)
|
|
|
|
|
2022-02-17 11:53:55 +00:00
|
|
|
func aggregate*(agg: var AggregateSignature, sig: CookedSig) {.inline.}=
|
2021-04-26 20:39:44 +00:00
|
|
|
## Aggregate two valid Validator Signatures
|
2021-03-17 13:35:59 +00:00
|
|
|
agg.aggregate(blscurve.Signature(sig))
|
|
|
|
|
2021-04-26 20:39:44 +00:00
|
|
|
func finish*(agg: AggregateSignature): CookedSig {.inline.} =
|
2020-08-15 17:33:58 +00:00
|
|
|
## Canonicalize an AggregateSignature into a signature
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
var sig: blscurve.Signature
|
|
|
|
sig.finish(agg)
|
2021-04-12 20:25:09 +00:00
|
|
|
CookedSig(sig)
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2024-01-20 11:19:47 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#bls-signatures
|
2022-02-17 11:53:55 +00:00
|
|
|
func blsVerify*(
|
2021-06-01 11:13:40 +00:00
|
|
|
pubkey: CookedPubKey, message: openArray[byte],
|
2021-04-26 20:39:44 +00:00
|
|
|
signature: CookedSig): bool =
|
2020-03-04 21:27:11 +00:00
|
|
|
## Check that a signature is valid for a message
|
|
|
|
## under the provided public key.
|
|
|
|
## returns `true` if the signature is valid, `false` otherwise.
|
|
|
|
##
|
|
|
|
## The proof-of-possession MUST be verified before calling this function.
|
|
|
|
## It is recommended to use the overload that accepts a proof-of-possession
|
|
|
|
## to enforce correct usage.
|
2021-06-01 11:13:40 +00:00
|
|
|
PublicKey(pubkey).verify(message, blscurve.Signature(signature))
|
|
|
|
|
2024-01-20 11:19:47 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#bls-signatures
|
2021-06-01 11:13:40 +00:00
|
|
|
proc blsVerify*(
|
|
|
|
pubkey: ValidatorPubKey, message: openArray[byte],
|
|
|
|
signature: CookedSig): bool =
|
|
|
|
## Check that a signature is valid for a message
|
|
|
|
## under the provided public key.
|
|
|
|
## returns `true` if the signature and the pubkey is valid, `false` otherwise.
|
|
|
|
##
|
|
|
|
## The proof-of-possession MUST be verified before calling this function.
|
|
|
|
## It is recommended to use the overload that accepts a proof-of-possession
|
|
|
|
## to enforce correct usage.
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
let
|
2021-04-26 20:39:44 +00:00
|
|
|
parsedKey = pubkey.loadWithCache()
|
|
|
|
|
2021-06-01 11:13:40 +00:00
|
|
|
# Guard against invalid signature blobs that fail to parse
|
|
|
|
parsedKey.isSome() and blsVerify(parsedKey.get(), message, signature)
|
2021-04-26 20:39:44 +00:00
|
|
|
|
|
|
|
proc blsVerify*(
|
2021-06-01 11:13:40 +00:00
|
|
|
pubkey: ValidatorPubKey | CookedPubKey, message: openArray[byte],
|
2021-04-26 20:39:44 +00:00
|
|
|
signature: ValidatorSig): bool =
|
2021-06-01 11:13:40 +00:00
|
|
|
let
|
|
|
|
parsedSig = signature.load()
|
|
|
|
# Guard against invalid signature blobs that fail to parse
|
|
|
|
parsedSig.isSome() and blsVerify(pubkey, message, parsedSig.get())
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2024-08-16 21:42:46 +00:00
|
|
|
func blsVerify*(sigset: SignatureSet): bool =
|
2021-04-02 14:36:43 +00:00
|
|
|
## Unbatched verification
|
|
|
|
## of 1 SignatureSet
|
|
|
|
## tuple[pubkey: blscurve.PublicKey, message: array[32, byte], blscurve.signature: Signature]
|
|
|
|
verify(
|
2024-08-16 21:42:46 +00:00
|
|
|
sigset.pubkey,
|
|
|
|
sigset.message,
|
|
|
|
sigset.signature
|
2021-04-02 14:36:43 +00:00
|
|
|
)
|
|
|
|
|
2021-04-26 20:39:44 +00:00
|
|
|
func blsSign*(privkey: ValidatorPrivKey, message: openArray[byte]): CookedSig =
|
2020-03-04 21:27:11 +00:00
|
|
|
## Computes a signature from a secret key and a message
|
2021-04-26 20:39:44 +00:00
|
|
|
CookedSig(SecretKey(privkey).sign(message))
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2022-02-17 11:53:55 +00:00
|
|
|
func blsFastAggregateVerify*(
|
2021-06-01 11:13:40 +00:00
|
|
|
publicKeys: openArray[CookedPubKey],
|
2020-06-16 05:45:04 +00:00
|
|
|
message: openArray[byte],
|
2021-04-26 20:39:44 +00:00
|
|
|
signature: CookedSig
|
2020-03-04 21:27:11 +00:00
|
|
|
): bool =
|
|
|
|
## Verify the aggregate of multiple signatures on the same message
|
|
|
|
## This function is faster than AggregateVerify
|
|
|
|
##
|
|
|
|
## The proof-of-possession MUST be verified before calling this function.
|
|
|
|
## It is recommended to use the overload that accepts a proof-of-possession
|
|
|
|
## to enforce correct usage.
|
|
|
|
# TODO: Note: `invalid` in the following paragraph means invalid by construction
|
|
|
|
# The keys/signatures are not even points on the elliptic curves.
|
|
|
|
# To respect both the IETF API and the fact that
|
|
|
|
# we can have invalid public keys (as in not point on the elliptic curve),
|
|
|
|
# requiring a wrapper indirection,
|
|
|
|
# we need a first pass to extract keys from the wrapper
|
|
|
|
# and then call fastAggregateVerify.
|
|
|
|
# Instead:
|
|
|
|
# - either we expose a new API: context + init-update-finish
|
|
|
|
# in blscurve which already exists internally
|
|
|
|
# - or at network/databases/serialization boundaries we do not
|
|
|
|
# allow invalid BLS objects to pollute consensus routines
|
2021-06-01 11:13:40 +00:00
|
|
|
let keys = mapIt(publicKeys, PublicKey(it))
|
|
|
|
fastAggregateVerify(keys, message, blscurve.Signature(signature))
|
|
|
|
|
|
|
|
proc blsFastAggregateVerify*(
|
|
|
|
publicKeys: openArray[ValidatorPubKey],
|
|
|
|
message: openArray[byte],
|
|
|
|
signature: CookedSig
|
|
|
|
): bool =
|
2020-03-04 21:27:11 +00:00
|
|
|
var unwrapped: seq[PublicKey]
|
2020-08-04 17:15:13 +00:00
|
|
|
for pubkey in publicKeys:
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
let realkey = pubkey.loadWithCache()
|
2020-07-23 14:38:28 +00:00
|
|
|
if realkey.isNone:
|
2020-03-04 21:27:11 +00:00
|
|
|
return false
|
2021-06-01 11:13:40 +00:00
|
|
|
unwrapped.add PublicKey(realkey.get)
|
2020-06-16 05:45:04 +00:00
|
|
|
|
2021-04-26 20:39:44 +00:00
|
|
|
fastAggregateVerify(unwrapped, message, blscurve.Signature(signature))
|
|
|
|
|
2022-02-17 11:53:55 +00:00
|
|
|
func blsFastAggregateVerify*(
|
2021-06-01 11:13:40 +00:00
|
|
|
publicKeys: openArray[CookedPubKey],
|
|
|
|
message: openArray[byte],
|
|
|
|
signature: ValidatorSig
|
|
|
|
): bool =
|
|
|
|
let parsedSig = signature.load()
|
|
|
|
parsedSig.isSome and blsFastAggregateVerify(publicKeys, message, parsedSig.get())
|
|
|
|
|
2021-04-26 20:39:44 +00:00
|
|
|
proc blsFastAggregateVerify*(
|
|
|
|
publicKeys: openArray[ValidatorPubKey],
|
|
|
|
message: openArray[byte],
|
|
|
|
signature: ValidatorSig
|
|
|
|
): bool =
|
|
|
|
let parsedSig = signature.load()
|
2021-06-01 11:13:40 +00:00
|
|
|
parsedSig.isSome and blsFastAggregateVerify(publicKeys, message, parsedSig.get())
|
2019-09-10 22:03:06 +00:00
|
|
|
|
2023-08-09 06:50:07 +00:00
|
|
|
proc blsFastAggregateVerify*(
|
|
|
|
fullParticipationAggregatePublicKey: ValidatorPubKey,
|
|
|
|
nonParticipatingPublicKeys: openArray[ValidatorPubKey],
|
|
|
|
message: openArray[byte],
|
|
|
|
signature: CookedSig
|
|
|
|
): bool =
|
|
|
|
let unwrappedFull = fullParticipationAggregatePublicKey.loadWithCache.valueOr:
|
|
|
|
return false
|
|
|
|
|
|
|
|
var unwrapped = newSeqOfCap[PublicKey](nonParticipatingPublicKeys.len)
|
|
|
|
for pubkey in nonParticipatingPublicKeys:
|
|
|
|
let realkey = pubkey.loadWithCache.valueOr:
|
|
|
|
return false
|
|
|
|
unwrapped.add PublicKey(realkey)
|
|
|
|
|
|
|
|
fastAggregateVerify(
|
|
|
|
PublicKey(unwrappedFull), unwrapped,
|
|
|
|
message, blscurve.Signature(signature))
|
|
|
|
|
|
|
|
proc blsFastAggregateVerify*(
|
|
|
|
fullParticipationAggregatePublicKey: ValidatorPubKey,
|
|
|
|
nonParticipatingPublicKeys: openArray[ValidatorPubKey],
|
|
|
|
message: openArray[byte],
|
|
|
|
signature: ValidatorSig
|
|
|
|
): bool =
|
|
|
|
let parsedSig = signature.load()
|
|
|
|
parsedSig.isSome and blsFastAggregateVerify(
|
|
|
|
fullParticipationAggregatePublicKey, nonParticipatingPublicKeys,
|
|
|
|
message, parsedSig.get())
|
|
|
|
|
|
|
|
proc blsFastAggregateVerify*(
|
|
|
|
allPublicKeys: openArray[ValidatorPubKey],
|
|
|
|
fullParticipationAggregatePublicKey: ValidatorPubKey,
|
|
|
|
participantBits: BitArray,
|
|
|
|
message: openArray[byte],
|
|
|
|
signature: ValidatorSig
|
|
|
|
): bool =
|
|
|
|
const maxParticipants = participantBits.bits
|
|
|
|
var numParticipants = 0
|
|
|
|
for idx in 0 ..< maxParticipants:
|
|
|
|
if participantBits[idx]:
|
|
|
|
inc numParticipants
|
|
|
|
|
|
|
|
return
|
|
|
|
if numParticipants < 1:
|
|
|
|
false
|
|
|
|
elif numParticipants > maxParticipants div 2:
|
|
|
|
var nonParticipatingPublicKeys = newSeqOfCap[ValidatorPubKey](
|
|
|
|
maxParticipants - numParticipants)
|
|
|
|
for idx, pubkey in allPublicKeys:
|
|
|
|
if not participantBits[idx]:
|
|
|
|
nonParticipatingPublicKeys.add pubkey
|
|
|
|
blsFastAggregateVerify(
|
|
|
|
fullParticipationAggregatePublicKey, nonParticipatingPublicKeys,
|
|
|
|
message, signature)
|
|
|
|
else:
|
|
|
|
var publicKeys = newSeqOfCap[ValidatorPubKey](numParticipants)
|
|
|
|
for idx, pubkey in allPublicKeys:
|
|
|
|
if participantBits[idx]:
|
|
|
|
publicKeys.add pubkey
|
|
|
|
blsFastAggregateVerify(publicKeys, message, signature)
|
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# Codecs
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
func `$`*(x: ValidatorPrivKey): string =
|
|
|
|
"<private key>"
|
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
func `$`*(x: ValidatorPubKey | ValidatorSig): string =
|
|
|
|
x.blob.toHex()
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-08-15 17:33:58 +00:00
|
|
|
func toRaw*(x: ValidatorPrivKey): array[32, byte] =
|
2020-07-26 08:27:11 +00:00
|
|
|
# TODO: distinct type - see https://github.com/status-im/nim-blscurve/pull/67
|
2024-02-22 16:13:31 +00:00
|
|
|
static: doAssert BLS_BACKEND == BLST
|
|
|
|
result = SecretKey(x).exportRaw()
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2024-06-13 13:11:04 +00:00
|
|
|
template toRaw*(x: ValidatorPubKey | SomeSig): auto =
|
|
|
|
x.blob
|
2020-06-25 10:23:10 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
func toHex*(x: BlsCurveType): string =
|
|
|
|
toHex(toRaw(x))
|
|
|
|
|
2021-06-01 11:13:40 +00:00
|
|
|
func toHex*(x: CookedPubKey): string =
|
|
|
|
toHex(x.toPubKey())
|
|
|
|
|
|
|
|
func `$`*(x: CookedPubKey): string =
|
|
|
|
$(x.toPubKey())
|
|
|
|
|
2021-04-26 20:39:44 +00:00
|
|
|
func toValidatorSig*(x: CookedSig): ValidatorSig =
|
2021-03-17 13:35:59 +00:00
|
|
|
ValidatorSig(blob: blscurve.Signature(x).exportRaw())
|
|
|
|
|
2020-06-16 05:45:04 +00:00
|
|
|
func fromRaw*(T: type ValidatorPrivKey, bytes: openArray[byte]): BlsResult[T] =
|
2020-04-11 08:51:07 +00:00
|
|
|
var val: SecretKey
|
|
|
|
if val.fromBytes(bytes):
|
|
|
|
ok ValidatorPrivKey(val)
|
|
|
|
else:
|
|
|
|
err "bls: invalid private key"
|
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
func fromRaw*(BT: type[ValidatorPubKey | ValidatorSig], bytes: openArray[byte]): BlsResult[BT] =
|
|
|
|
# Signatures and keys are deserialized lazily
|
|
|
|
if bytes.len() != sizeof(BT):
|
|
|
|
err "bls: invalid bls length"
|
2019-07-03 07:35:05 +00:00
|
|
|
else:
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
ok BT(blob: toArray(sizeof(BT), bytes))
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
func fromHex*(T: type BlsCurveType, hexStr: string): BlsResult[T] {.inline.} =
|
2020-03-04 21:27:11 +00:00
|
|
|
## Initialize a BLSValue from its hex representation
|
2020-04-11 08:51:07 +00:00
|
|
|
try:
|
|
|
|
T.fromRaw(hexStr.hexToSeqByte())
|
|
|
|
except ValueError:
|
|
|
|
err "bls: cannot parse value"
|
2019-10-01 13:44:38 +00:00
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
func `==`*(a, b: ValidatorPubKey | ValidatorSig): bool =
|
|
|
|
equalMem(unsafeAddr a.blob[0], unsafeAddr b.blob[0], sizeof(a.blob))
|
2020-08-18 20:29:33 +00:00
|
|
|
|
2022-03-13 07:12:45 +00:00
|
|
|
func `==`*(a, b: ValidatorPrivKey): bool {.error: "Secret keys should stay secret".}
|
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# Hashing
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
template hash*(x: ValidatorPubKey | ValidatorSig): Hash =
|
|
|
|
static: doAssert sizeof(Hash) <= x.blob.len div 2
|
|
|
|
# We use rough "middle" of blob for the hash, assuming this is where most of
|
|
|
|
# the entropy is found
|
|
|
|
cast[ptr Hash](unsafeAddr x.blob[x.blob.len div 2])[]
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2021-12-22 12:37:31 +00:00
|
|
|
# Comparison/Sorting
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
|
|
|
template `<`*(x, y: ValidatorPubKey): bool =
|
|
|
|
x.blob < y.blob
|
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# Serialization
|
|
|
|
# ----------------------------------------------------------------------
|
2018-12-19 12:58:53 +00:00
|
|
|
|
2023-08-25 09:29:07 +00:00
|
|
|
{.pragma: serializationRaises, raises: [SerializationError, IOError].}
|
2020-06-15 22:20:31 +00:00
|
|
|
|
2023-08-19 15:11:56 +00:00
|
|
|
proc writeValue*(
|
|
|
|
writer: var JsonWriter, value: ValidatorPubKey | CookedPubKey
|
|
|
|
) {.inline, raises: [IOError].} =
|
2020-03-12 01:11:48 +00:00
|
|
|
writer.writeValue(value.toHex())
|
2018-12-19 12:58:53 +00:00
|
|
|
|
2020-06-15 22:20:31 +00:00
|
|
|
proc readValue*(reader: var JsonReader, value: var ValidatorPubKey)
|
|
|
|
{.serializationRaises.} =
|
|
|
|
let key = ValidatorPubKey.fromHex(reader.readValue(string))
|
|
|
|
if key.isOk:
|
|
|
|
value = key.get
|
|
|
|
else:
|
|
|
|
# TODO: Can we provide better diagnostic?
|
|
|
|
raiseUnexpectedValue(reader, "Valid hex-encoded public key expected")
|
2018-12-19 12:58:53 +00:00
|
|
|
|
2023-08-19 15:11:56 +00:00
|
|
|
proc writeValue*(
|
|
|
|
writer: var JsonWriter, value: ValidatorSig
|
|
|
|
) {.inline, raises: [IOError].} =
|
2020-10-08 19:02:05 +00:00
|
|
|
# Workaround: https://github.com/status-im/nimbus-eth2/issues/374
|
2020-03-12 01:11:48 +00:00
|
|
|
writer.writeValue(value.toHex())
|
2019-08-07 03:09:26 +00:00
|
|
|
|
2020-06-15 22:20:31 +00:00
|
|
|
proc readValue*(reader: var JsonReader, value: var ValidatorSig)
|
|
|
|
{.serializationRaises.} =
|
|
|
|
let sig = ValidatorSig.fromHex(reader.readValue(string))
|
|
|
|
if sig.isOk:
|
|
|
|
value = sig.get
|
|
|
|
else:
|
|
|
|
# TODO: Can we provide better diagnostic?
|
|
|
|
raiseUnexpectedValue(reader, "Valid hex-encoded signature expected")
|
2019-08-07 03:09:26 +00:00
|
|
|
|
2023-08-19 15:11:56 +00:00
|
|
|
proc writeValue*(
|
|
|
|
writer: var JsonWriter, value: ValidatorPrivKey
|
|
|
|
) {.inline, raises: [IOError].} =
|
2020-03-12 01:11:48 +00:00
|
|
|
writer.writeValue(value.toHex())
|
2019-08-07 03:09:26 +00:00
|
|
|
|
2020-06-15 22:20:31 +00:00
|
|
|
proc readValue*(reader: var JsonReader, value: var ValidatorPrivKey)
|
|
|
|
{.serializationRaises.} =
|
|
|
|
let key = ValidatorPrivKey.fromHex(reader.readValue(string))
|
|
|
|
if key.isOk:
|
|
|
|
value = key.get
|
|
|
|
else:
|
|
|
|
# TODO: Can we provide better diagnostic?
|
|
|
|
raiseUnexpectedValue(reader, "Valid hex-encoded private key expected")
|
2019-11-09 10:46:34 +00:00
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
template fromSszBytes*(T: type[ValidatorPubKey | ValidatorSig], bytes: openArray[byte]): auto =
|
2020-04-11 08:51:07 +00:00
|
|
|
let v = fromRaw(T, bytes)
|
|
|
|
if v.isErr:
|
|
|
|
raise newException(MalformedSszError, $v.error)
|
|
|
|
v[]
|
|
|
|
|
|
|
|
# Logging
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
2024-06-13 13:11:04 +00:00
|
|
|
func shortLog*(x: ValidatorPubKey | SomeSig): string =
|
2020-04-11 08:51:07 +00:00
|
|
|
## Logging for wrapped BLS types
|
|
|
|
## that may contain valid or non-validated data
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
byteutils.toHex(x.blob.toOpenArray(0, 3))
|
2020-04-11 08:51:07 +00:00
|
|
|
|
2021-06-01 11:13:40 +00:00
|
|
|
func shortLog*(x: CookedPubKey): string =
|
|
|
|
let raw = x.toRaw()
|
|
|
|
byteutils.toHex(raw.toOpenArray(0, 3))
|
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
func shortLog*(x: ValidatorPrivKey): string =
|
|
|
|
## Logging for raw unwrapped BLS types
|
2020-07-26 08:27:11 +00:00
|
|
|
"<private key>"
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-03-04 22:13:37 +00:00
|
|
|
# Initialization
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
# TODO more specific exceptions? don't raise?
|
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# For confutils
|
2023-08-25 09:29:07 +00:00
|
|
|
func init*(T: typedesc[ValidatorPrivKey], hex: string): T {.noinit, raises: [ValueError].} =
|
2020-04-11 08:51:07 +00:00
|
|
|
let v = T.fromHex(hex)
|
|
|
|
if v.isErr:
|
|
|
|
raise (ref ValueError)(msg: $v.error)
|
2020-07-21 16:35:43 +00:00
|
|
|
v[]
|
2020-04-11 08:51:07 +00:00
|
|
|
|
2020-03-04 22:13:37 +00:00
|
|
|
# For mainchain monitor
|
2023-08-25 09:29:07 +00:00
|
|
|
func init*(T: typedesc[ValidatorPubKey], data: array[RawPubKeySize, byte]): T {.noinit, raises: [ValueError].} =
|
2020-04-11 08:51:07 +00:00
|
|
|
let v = T.fromRaw(data)
|
|
|
|
if v.isErr:
|
|
|
|
raise (ref ValueError)(msg: $v.error)
|
2020-07-21 16:35:43 +00:00
|
|
|
v[]
|
2020-03-04 22:41:21 +00:00
|
|
|
|
|
|
|
# For mainchain monitor
|
2023-08-25 09:29:07 +00:00
|
|
|
func init*(T: typedesc[ValidatorSig], data: array[RawSigSize, byte]): T {.noinit, raises: [ValueError].} =
|
2020-04-11 08:51:07 +00:00
|
|
|
let v = T.fromRaw(data)
|
|
|
|
if v.isErr:
|
|
|
|
raise (ref ValueError)(msg: $v.error)
|
2020-07-21 16:35:43 +00:00
|
|
|
v[]
|
2020-07-17 20:59:50 +00:00
|
|
|
|
2021-08-28 09:00:00 +00:00
|
|
|
func infinity*(T: type ValidatorSig): T =
|
|
|
|
result.blob[0] = byte 0xC0
|
|
|
|
|
2022-02-17 11:53:55 +00:00
|
|
|
func burnMem*(key: var ValidatorPrivKey) =
|
2022-01-08 20:06:34 +00:00
|
|
|
burnMem(addr key, sizeof(ValidatorPrivKey))
|
2022-05-10 00:32:12 +00:00
|
|
|
|
2023-06-13 16:45:00 +00:00
|
|
|
{.push warning[ProveField]:off.} # https://github.com/nim-lang/Nim/issues/22060
|
2022-06-21 08:29:16 +00:00
|
|
|
proc keyGen(rng: var HmacDrbgContext): BlsResult[blscurve.SecretKey] =
|
2022-05-10 00:32:12 +00:00
|
|
|
var
|
|
|
|
pubkey: blscurve.PublicKey
|
2022-06-21 08:29:16 +00:00
|
|
|
let bytes = rng.generate(array[32, byte])
|
2022-05-10 00:32:12 +00:00
|
|
|
result.ok default(blscurve.SecretKey)
|
|
|
|
if not keyGen(bytes, pubkey, result.value):
|
|
|
|
return err "key generation failed"
|
2023-06-13 16:45:00 +00:00
|
|
|
{.pop.}
|
2022-05-10 00:32:12 +00:00
|
|
|
|
|
|
|
proc secretShareId(x: uint32) : blscurve.ID =
|
|
|
|
let bytes: array[8, uint32] = [uint32 x, 0, 0, 0, 0, 0, 0, 0]
|
|
|
|
blscurve.ID.fromUint32(bytes)
|
|
|
|
|
|
|
|
func generateSecretShares*(sk: ValidatorPrivKey,
|
2022-06-21 08:29:16 +00:00
|
|
|
rng: var HmacDrbgContext,
|
2022-05-10 00:32:12 +00:00
|
|
|
k: uint32, n: uint32): BlsResult[seq[SecretShare]] =
|
|
|
|
doAssert k > 0 and k <= n
|
|
|
|
|
|
|
|
var originPts: seq[blscurve.SecretKey]
|
|
|
|
originPts.add(blscurve.SecretKey(sk))
|
|
|
|
for i in 1 ..< k:
|
|
|
|
originPts.add(? keyGen(rng))
|
|
|
|
|
|
|
|
var shares: seq[SecretShare]
|
|
|
|
for i in uint32(0) ..< n:
|
|
|
|
let numericShareId = i + 1 # the share id must not be zero
|
|
|
|
let blsShareId = secretShareId(numericShareId)
|
|
|
|
let secret = genSecretShare(originPts, blsShareId)
|
|
|
|
let share = SecretShare(key: ValidatorPrivKey(secret), id: numericShareId)
|
|
|
|
shares.add(share)
|
|
|
|
|
|
|
|
return ok shares
|
|
|
|
|
|
|
|
func toSignatureShare*(sig: CookedSig, id: uint32): SignatureShare =
|
|
|
|
result.sign = blscurve.Signature(sig)
|
|
|
|
result.id = id
|
|
|
|
|
|
|
|
func recoverSignature*(sings: seq[SignatureShare]): CookedSig =
|
|
|
|
let signs = sings.mapIt(it.sign)
|
|
|
|
let ids = sings.mapIt(secretShareId(it.id))
|
|
|
|
CookedSig blscurve.recover(signs, ids).expect(
|
|
|
|
"valid shares (validated when loading the keystore)")
|
|
|
|
|
|
|
|
proc confirmShares*(pubKey: ValidatorPubKey,
|
|
|
|
shares: seq[SecretShare],
|
2022-06-21 08:29:16 +00:00
|
|
|
rng: var HmacDrbgContext): bool =
|
|
|
|
let confirmationData = rng.generate(array[32, byte])
|
2022-05-10 00:32:12 +00:00
|
|
|
var signs: seq[SignatureShare]
|
|
|
|
for share in items(shares):
|
|
|
|
let signature = share.key.blsSign(confirmationData).toSignatureShare(share.id);
|
|
|
|
signs.add(signature)
|
|
|
|
let recovered = signs.recoverSignature()
|
|
|
|
return pubKey.blsVerify(confirmationData, recovered)
|