@@ -5,9 +5,11 @@ import (
55 "fmt"
66 "time"
77
8+ "github.com/Giulio2002/bls"
89 "github.com/ledgerwatch/erigon/cl/beacon/synced_data"
910 "github.com/ledgerwatch/erigon/cl/clparams"
1011 "github.com/ledgerwatch/erigon/cl/cltypes/solid"
12+ "github.com/ledgerwatch/erigon/cl/fork"
1113 "github.com/ledgerwatch/erigon/cl/phase1/core/state/lru"
1214 "github.com/ledgerwatch/erigon/cl/phase1/forkchoice"
1315 "github.com/ledgerwatch/erigon/cl/phase1/network/subnets"
@@ -19,6 +21,8 @@ import (
1921var (
2022 computeSubnetForAttestation = subnets .ComputeSubnetForAttestation
2123 computeCommitteeCountPerSlot = subnets .ComputeCommitteeCountPerSlot
24+ computeSigningRoot = fork .ComputeSigningRoot
25+ blsVerify = bls .Verify
2226)
2327
2428type attestationService struct {
@@ -59,7 +63,7 @@ func (s *attestationService) ProcessMessage(ctx context.Context, subnet *uint64,
5963 committeeIndex = att .AttestantionData ().CommitteeIndex ()
6064 targetEpoch = att .AttestantionData ().Target ().Epoch ()
6165 )
62- headState := s .syncedDataManager .HeadState ()
66+ headState := s .syncedDataManager .HeadStateReader ()
6367 if headState == nil {
6468 return ErrIgnore
6569 }
@@ -117,7 +121,6 @@ func (s *attestationService) ProcessMessage(ctx context.Context, subnet *uint64,
117121 if setBits != 1 {
118122 return fmt .Errorf ("attestation does not have exactly one participating validator" )
119123 }
120-
121124 // [IGNORE] There has been no other valid attestation seen on an attestation subnet that has an identical attestation.data.target.epoch and participating validator index.
122125 if err != nil {
123126 return err
@@ -133,6 +136,26 @@ func (s *attestationService) ProcessMessage(ctx context.Context, subnet *uint64,
133136 }
134137 s .validatorAttestationSeen .Add (vIndex , targetEpoch )
135138
139+ // [REJECT] The signature of attestation is valid.
140+ signature := att .Signature ()
141+ pubKey , err := headState .ValidatorPublicKey (int (beaconCommittee [onBitIndex ]))
142+ if err != nil {
143+ return fmt .Errorf ("unable to get public key: %v" , err )
144+ }
145+ domain , err := headState .GetDomain (s .beaconCfg .DomainBeaconAttester , targetEpoch )
146+ if err != nil {
147+ return fmt .Errorf ("unable to get the domain: %v" , err )
148+ }
149+ signingRoot , err := computeSigningRoot (att .AttestantionData (), domain )
150+ if err != nil {
151+ return fmt .Errorf ("unable to get signing root: %v" , err )
152+ }
153+ if valid , err := blsVerify (signature [:], signingRoot [:], pubKey [:]); err != nil {
154+ return err
155+ } else if ! valid {
156+ return fmt .Errorf ("invalid signature" )
157+ }
158+
136159 // [IGNORE] The block being voted for (attestation.data.beacon_block_root) has been seen (via both gossip and non-gossip sources)
137160 // (a client MAY queue attestations for processing once block is retrieved).
138161 if _ , ok := s .forkchoiceStore .GetHeader (root ); ! ok {
0 commit comments