mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-25 13:07:17 +00:00
Full BLS Validatition for lightclient update (#5751)
This commit is contained in:
parent
497d414b36
commit
f6e7cc4d3e
@ -7,7 +7,7 @@ import (
|
||||
"github.com/ledgerwatch/erigon/cmd/lightclient/fork"
|
||||
"github.com/ledgerwatch/erigon/cmd/lightclient/utils"
|
||||
"github.com/ledgerwatch/erigon/common"
|
||||
//"github.com/prysmaticlabs/go-bls"
|
||||
blst "github.com/supranational/blst/bindings/go"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -15,7 +15,10 @@ const (
|
||||
FinalizedRootIndex = 105
|
||||
)
|
||||
|
||||
var DomainSyncCommittee = common.Hex2Bytes("07000000")
|
||||
var (
|
||||
DomainSyncCommittee = common.Hex2Bytes("07000000")
|
||||
dst = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_")
|
||||
)
|
||||
|
||||
func (l *LightClient) validateLegacyUpdate(update *cltypes.LightClientUpdate, finalityUpdate bool) (bool, error) {
|
||||
if update.SyncAggregate.Sum() < MinSyncCommitteeParticipants {
|
||||
@ -112,24 +115,23 @@ func (l *LightClient) validateLegacyUpdate(update *cltypes.LightClientUpdate, fi
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Create signature objects
|
||||
/*var signature bls.Sign
|
||||
if err := signature.Deserialize(update.SyncAggregate.SyncCommiteeSignature[:]); err != nil {
|
||||
_ = signingRoot
|
||||
signature, err := utils.SignatureFromBytes(update.SyncAggregate.SyncCommiteeSignature[:])
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Aggreggate public keys
|
||||
var pubKey bls.PublicKey
|
||||
|
||||
pks := []*blst.P1Affine{}
|
||||
|
||||
for _, key := range pubkeys {
|
||||
var currPubKey bls.PublicKey
|
||||
if err := currPubKey.Deserialize(key[:]); err != nil {
|
||||
pk, err := utils.PublicKeyFromBytes(key[:])
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
pubKey.Add(&currPubKey)
|
||||
}*/
|
||||
_ = signingRoot
|
||||
_ = pubkeys
|
||||
return true, nil
|
||||
// return signature.Verify(&pubKey, signingRoot[:]), nil
|
||||
pks = append(pks, pk)
|
||||
}
|
||||
|
||||
return signature.FastAggregateVerify(true, pks, signingRoot[:], dst), nil
|
||||
}
|
||||
|
||||
func (l *LightClient) validateOptimisticUpdate(update *cltypes.LightClientOptimisticUpdate) (bool, error) {
|
||||
@ -139,78 +141,3 @@ func (l *LightClient) validateOptimisticUpdate(update *cltypes.LightClientOptimi
|
||||
func (l *LightClient) validateFinalityUpdate(update *cltypes.LightClientFinalityUpdate) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
/*def validate_light_client_update(store: LightClientStore,
|
||||
update: LightClientUpdate,
|
||||
current_slot: Slot,
|
||||
genesis_validators_root: Root) -> None:
|
||||
# Verify sync committee has sufficient participants
|
||||
sync_aggregate = update.sync_aggregate
|
||||
assert sum(sync_aggregate.sync_committee_bits) >= MIN_SYNC_COMMITTEE_PARTICIPANTS
|
||||
|
||||
# Verify update does not skip a sync committee period
|
||||
assert current_slot >= update.signature_slot > update.attested_header.slot >= update.finalized_header.slot
|
||||
store_period = compute_sync_committee_period_at_slot(store.finalized_header.slot)
|
||||
update_signature_period = compute_sync_committee_period_at_slot(update.signature_slot)
|
||||
if is_next_sync_committee_known(store):
|
||||
assert update_signature_period in (store_period, store_period + 1)
|
||||
else:
|
||||
assert update_signature_period == store_period
|
||||
|
||||
# Verify update is relevant
|
||||
update_attested_period = compute_sync_committee_period_at_slot(update.attested_header.slot)
|
||||
update_has_next_sync_committee = not is_next_sync_committee_known(store) and (
|
||||
is_sync_committee_update(update) and update_attested_period == store_period
|
||||
)
|
||||
assert (
|
||||
update.attested_header.slot > store.finalized_header.slot
|
||||
or update_has_next_sync_committee
|
||||
)
|
||||
|
||||
# Verify that the `finality_branch`, if present, confirms `finalized_header`
|
||||
# to match the finalized checkpoint root saved in the state of `attested_header`.
|
||||
# Note that the genesis finalized checkpoint root is represented as a zero hash.
|
||||
if not is_finality_update(update):
|
||||
assert update.finalized_header == BeaconBlockHeader()
|
||||
else:
|
||||
if update.finalized_header.slot == GENESIS_SLOT:
|
||||
assert update.finalized_header == BeaconBlockHeader()
|
||||
finalized_root = Bytes32()
|
||||
else:
|
||||
finalized_root = hash_tree_root(update.finalized_header)
|
||||
assert is_valid_merkle_branch(
|
||||
leaf=finalized_root,
|
||||
branch=update.finality_branch,
|
||||
depth=floorlog2(FINALIZED_ROOT_INDEX),
|
||||
index=get_subtree_index(FINALIZED_ROOT_INDEX),
|
||||
root=update.attested_header.state_root,
|
||||
)
|
||||
|
||||
# Verify that the `next_sync_committee`, if present, actually is the next sync committee saved in the
|
||||
# state of the `attested_header`
|
||||
if not is_sync_committee_update(update):
|
||||
assert update.next_sync_committee == SyncCommittee()
|
||||
else:
|
||||
if update_attested_period == store_period and is_next_sync_committee_known(store):
|
||||
assert update.next_sync_committee == store.next_sync_committee
|
||||
assert is_valid_merkle_branch(
|
||||
leaf=hash_tree_root(update.next_sync_committee),
|
||||
branch=update.next_sync_committee_branch,
|
||||
depth=floorlog2(NEXT_SYNC_COMMITTEE_INDEX),
|
||||
index=get_subtree_index(NEXT_SYNC_COMMITTEE_INDEX),
|
||||
root=update.attested_header.state_root,
|
||||
)
|
||||
|
||||
# Verify sync committee aggregate signature
|
||||
if update_signature_period == store_period:
|
||||
sync_committee = store.current_sync_committee
|
||||
else:
|
||||
sync_committee = store.next_sync_committee
|
||||
participant_pubkeys = [
|
||||
pubkey for (bit, pubkey) in zip(sync_aggregate.sync_committee_bits, sync_committee.pubkeys)
|
||||
if bit
|
||||
]
|
||||
fork_version = compute_fork_version(compute_epoch_at_slot(update.signature_slot))
|
||||
domain = compute_domain(DOMAIN_SYNC_COMMITTEE, fork_version, genesis_validators_root)
|
||||
signing_root = compute_signing_root(update.attested_header, domain)
|
||||
assert bls.FastAggregateVerify(participant_pubkeys, signing_root, sync_aggregate.sync_committee_signature)*/
|
||||
|
@ -32,6 +32,7 @@ var (
|
||||
const DefaultUri = "https://beaconstate.ethstaker.cc/eth/v2/debug/beacon/states/finalized"
|
||||
|
||||
func main() {
|
||||
|
||||
ctx := context.Background()
|
||||
log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StderrHandler))
|
||||
addr := "localhost:7777"
|
||||
|
@ -199,7 +199,6 @@ func readUvarint(r io.Reader) (x uint64, err error) {
|
||||
func DecodeLightClientUpdate(data []byte) (*cltypes.LightClientUpdate, error) {
|
||||
resp := &cltypes.LightClientUpdate{}
|
||||
singleLen := resp.SizeSSZ()
|
||||
fmt.Println(len(data[7:]))
|
||||
r := bytes.NewReader(data[7:])
|
||||
|
||||
sr := snappy.NewReader(r)
|
||||
|
@ -15,8 +15,12 @@ package utils
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"sync"
|
||||
|
||||
blst "github.com/supranational/blst/bindings/go"
|
||||
)
|
||||
|
||||
var hasherPool = sync.Pool{
|
||||
@ -40,3 +44,39 @@ func Keccak256(data []byte) [32]byte {
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// PublicKeyFromBytes creates a BLS public key from a BigEndian byte slice.
|
||||
func PublicKeyFromBytes(pubKey []byte) (*blst.P1Affine, error) {
|
||||
if len(pubKey) != 48 {
|
||||
return nil, fmt.Errorf("public key must be 48 bytes")
|
||||
}
|
||||
|
||||
// Subgroup check NOT done when decompressing pubkey.
|
||||
p := new(blst.P1Affine).Uncompress(pubKey)
|
||||
if p == nil {
|
||||
return nil, errors.New("could not unmarshal bytes into public key")
|
||||
}
|
||||
// Subgroup and infinity check
|
||||
if !p.KeyValidate() {
|
||||
return nil, fmt.Errorf("infinite key")
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// SignatureFromBytes creates a BLS signature from a LittleEndian byte slice.
|
||||
func SignatureFromBytes(sig []byte) (*blst.P2Affine, error) {
|
||||
if len(sig) != 96 {
|
||||
return nil, fmt.Errorf("signature must be 96 bytes")
|
||||
}
|
||||
signature := new(blst.P2Affine).Uncompress(sig)
|
||||
if signature == nil {
|
||||
return nil, errors.New("could not unmarshal bytes into signature")
|
||||
}
|
||||
// Group check signature. Do not check for infinity since an aggregated signature
|
||||
// could be infinite.
|
||||
if !signature.SigValidate(false) {
|
||||
return nil, errors.New("signature not in group")
|
||||
}
|
||||
return signature, nil
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@ -63,6 +63,7 @@ require (
|
||||
github.com/spf13/cobra v1.5.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/supranational/blst v0.3.10
|
||||
github.com/tendermint/go-amino v0.14.1
|
||||
github.com/tendermint/tendermint v0.31.12
|
||||
github.com/torquem-ch/mdbx-go v0.26.1
|
||||
|
2
go.sum
2
go.sum
@ -939,6 +939,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/supranational/blst v0.3.10 h1:CMciDZ/h4pXDDXQASe8ZGTNKUiVNxVVA5hpci2Uuhuk=
|
||||
github.com/supranational/blst v0.3.10/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk=
|
||||
github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso=
|
||||
|
Loading…
Reference in New Issue
Block a user