Skip to content

Commit

Permalink
Handing pending atts if they dont have the state (prysmaticlabs#4904)
Browse files Browse the repository at this point in the history
  • Loading branch information
terencechain authored and cryptomental committed Feb 24, 2020
1 parent d1bb4b2 commit a325bc7
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 6 deletions.
4 changes: 2 additions & 2 deletions beacon-chain/sync/pending_attestations_queue.go
Expand Up @@ -60,8 +60,8 @@ func (s *Service) processPendingAtts(ctx context.Context) error {
s.pendingAttsLock.RLock()
attestations := s.blkRootToPendingAtts[bRoot]
s.pendingAttsLock.RUnlock()
// Has the pending attestation's missing block arrived yet?
if s.db.HasBlock(ctx, bRoot) {
// Has the pending attestation's missing block arrived and the node processed block yet?
if s.db.HasBlock(ctx, bRoot) && s.db.HasState(ctx, bRoot) {
numberOfBlocksRecoveredFromAtt.Inc()
for _, att := range attestations {
// The pending attestations can arrive in both aggregated and unaggregated forms,
Expand Down
5 changes: 5 additions & 0 deletions beacon-chain/sync/pending_attestations_queue_test.go
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
Expand Down Expand Up @@ -77,7 +78,9 @@ func TestProcessPendingAtts_HasBlockSaveUnAggregatedAtt(t *testing.T) {

b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
r32, _ := ssz.HashTreeRoot(b.Block)
s, _ := beaconstate.InitializeFromProto(&pb.BeaconState{})
r.db.SaveBlock(context.Background(), b)
r.db.SaveState(context.Background(), s, r32)

r.blkRootToPendingAtts[r32] = []*ethpb.AggregateAttestationAndProof{a}
if err := r.processPendingAtts(context.Background()); err != nil {
Expand Down Expand Up @@ -172,6 +175,8 @@ func TestProcessPendingAtts_HasBlockSaveAggregatedAtt(t *testing.T) {
sb = &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
r32, _ := ssz.HashTreeRoot(sb.Block)
r.db.SaveBlock(context.Background(), sb)
s, _ := beaconstate.InitializeFromProto(&pb.BeaconState{})
r.db.SaveState(context.Background(), s, r32)

r.blkRootToPendingAtts[r32] = []*ethpb.AggregateAttestationAndProof{aggregateAndProof}
if err := r.processPendingAtts(context.Background()); err != nil {
Expand Down
Expand Up @@ -14,7 +14,9 @@ import (
dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil"
)

Expand All @@ -39,6 +41,9 @@ func TestService_committeeIndexBeaconAttestationSubscriber_ValidMessage(t *testi
if err := db.SaveBlock(ctx, blk); err != nil {
t.Fatal(err)
}
savedState, _ := beaconstate.InitializeFromProto(&pb.BeaconState{})
db.SaveState(context.Background(), savedState, root)

r := &Service{
attPool: attestations.NewPool(),
chain: &mock.ChainService{
Expand Down
6 changes: 4 additions & 2 deletions beacon-chain/sync/validate_aggregate_proof.go
Expand Up @@ -127,8 +127,10 @@ func (r *Service) validateAggregatedAtt(ctx context.Context, a *ethpb.AggregateA
}

func (r *Service) validateBlockInAttestation(ctx context.Context, a *ethpb.AggregateAttestationAndProof) bool {
// Verify the block being voted is in DB. The block should have passed validation if it's in the DB.
if !r.db.HasBlock(ctx, bytesutil.ToBytes32(a.Aggregate.Data.BeaconBlockRoot)) {
// Verify the block being voted and the processed state is in DB. The block should have passed validation if it's in the DB.
hasState := r.db.HasState(ctx, bytesutil.ToBytes32(a.Aggregate.Data.BeaconBlockRoot))
hasBlock := r.db.HasBlock(ctx, bytesutil.ToBytes32(a.Aggregate.Data.BeaconBlockRoot))
if !(hasState && hasBlock) {
// A node doesn't have the block, it'll request from peer while saving the pending attestation to a queue.
r.savePendingAtt(a)
return false
Expand Down
6 changes: 6 additions & 0 deletions beacon-chain/sync/validate_aggregate_proof_test.go
Expand Up @@ -19,7 +19,9 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/params"
Expand Down Expand Up @@ -165,6 +167,8 @@ func TestValidateAggregateAndProof_NotWithinSlotRange(t *testing.T) {
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
db.SaveBlock(context.Background(), b)
root, _ := ssz.HashTreeRoot(b.Block)
s, _ := beaconstate.InitializeFromProto(&pb.BeaconState{})
db.SaveState(context.Background(), s, root)

aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
Expand Down Expand Up @@ -305,6 +309,8 @@ func TestValidateAggregateAndProof_CanValidate(t *testing.T) {
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
db.SaveBlock(context.Background(), b)
root, _ := ssz.HashTreeRoot(b.Block)
s, _ := beaconstate.InitializeFromProto(&pb.BeaconState{})
db.SaveState(context.Background(), s, root)

aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
Expand Down
Expand Up @@ -73,8 +73,10 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p
return false
}

// Verify the block being voted is in DB. The block should have passed validation if it's in the DB.
if !s.db.HasBlock(ctx, bytesutil.ToBytes32(att.Data.BeaconBlockRoot)) {
// Verify the block being voted and the processed state is in DB and. The block should have passed validation if it's in the DB.
hasState := s.db.HasState(ctx, bytesutil.ToBytes32(att.Data.BeaconBlockRoot))
hasBlock := s.db.HasBlock(ctx, bytesutil.ToBytes32(att.Data.BeaconBlockRoot))
if !(hasState && hasBlock) {
// A node doesn't have the block, it'll request from peer while saving the pending attestation to a queue.
s.savePendingAtt(&eth.AggregateAttestationAndProof{Aggregate: att})
return false
Expand Down
Expand Up @@ -14,7 +14,9 @@ import (
mockChain "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
)

Expand Down Expand Up @@ -49,6 +51,9 @@ func TestService_validateCommitteeIndexBeaconAttestation(t *testing.T) {
t.Fatal(err)
}

savedState, _ := beaconstate.InitializeFromProto(&pb.BeaconState{})
db.SaveState(context.Background(), savedState, validBlockRoot)

tests := []struct {
name string
msg *ethpb.Attestation
Expand Down

0 comments on commit a325bc7

Please sign in to comment.