github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/sync/validate_aggregate_proof_test.go (about) 1 package sync 2 3 import ( 4 "bytes" 5 "context" 6 "reflect" 7 "testing" 8 "time" 9 10 lru "github.com/hashicorp/golang-lru" 11 pubsub "github.com/libp2p/go-libp2p-pubsub" 12 pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" 13 types "github.com/prysmaticlabs/eth2-types" 14 "github.com/prysmaticlabs/go-bitfield" 15 mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" 16 "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" 17 dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing" 18 "github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations" 19 "github.com/prysmaticlabs/prysm/beacon-chain/p2p" 20 p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing" 21 mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing" 22 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 23 "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper" 24 "github.com/prysmaticlabs/prysm/shared/attestationutil" 25 "github.com/prysmaticlabs/prysm/shared/bls" 26 "github.com/prysmaticlabs/prysm/shared/bytesutil" 27 "github.com/prysmaticlabs/prysm/shared/params" 28 "github.com/prysmaticlabs/prysm/shared/testutil" 29 "github.com/prysmaticlabs/prysm/shared/testutil/assert" 30 "github.com/prysmaticlabs/prysm/shared/testutil/require" 31 ) 32 33 func TestVerifyIndexInCommittee_CanVerify(t *testing.T) { 34 ctx := context.Background() 35 params.UseMinimalConfig() 36 defer params.UseMainnetConfig() 37 38 validators := uint64(32) 39 s, _ := testutil.DeterministicGenesisState(t, validators) 40 require.NoError(t, s.SetSlot(params.BeaconConfig().SlotsPerEpoch)) 41 42 bf := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch)) 43 bf.SetBitAt(0, true) 44 att := ðpb.Attestation{Data: ðpb.AttestationData{ 45 Target: ðpb.Checkpoint{Epoch: 0}}, 46 AggregationBits: bf} 47 48 committee, err := helpers.BeaconCommitteeFromState(s, att.Data.Slot, att.Data.CommitteeIndex) 49 assert.NoError(t, err) 50 indices, err := attestationutil.AttestingIndices(att.AggregationBits, committee) 51 require.NoError(t, err) 52 require.NoError(t, validateIndexInCommittee(ctx, s, att, types.ValidatorIndex(indices[0]))) 53 54 wanted := "validator index 1000 is not within the committee" 55 assert.ErrorContains(t, wanted, validateIndexInCommittee(ctx, s, att, 1000)) 56 } 57 58 func TestVerifyIndexInCommittee_ExistsInBeaconCommittee(t *testing.T) { 59 ctx := context.Background() 60 params.UseMinimalConfig() 61 defer params.UseMainnetConfig() 62 63 validators := uint64(64) 64 s, _ := testutil.DeterministicGenesisState(t, validators) 65 require.NoError(t, s.SetSlot(params.BeaconConfig().SlotsPerEpoch)) 66 67 bf := []byte{0xff} 68 att := ðpb.Attestation{Data: ðpb.AttestationData{ 69 Target: ðpb.Checkpoint{Epoch: 0}}, 70 AggregationBits: bf} 71 72 committee, err := helpers.BeaconCommitteeFromState(s, att.Data.Slot, att.Data.CommitteeIndex) 73 require.NoError(t, err) 74 75 require.NoError(t, validateIndexInCommittee(ctx, s, att, committee[0])) 76 77 wanted := "validator index 1000 is not within the committee" 78 assert.ErrorContains(t, wanted, validateIndexInCommittee(ctx, s, att, 1000)) 79 } 80 81 func TestVerifySelection_NotAnAggregator(t *testing.T) { 82 ctx := context.Background() 83 params.UseMinimalConfig() 84 defer params.UseMainnetConfig() 85 validators := uint64(2048) 86 beaconState, privKeys := testutil.DeterministicGenesisState(t, validators) 87 88 sig := privKeys[0].Sign([]byte{'A'}) 89 data := testutil.HydrateAttestationData(ðpb.AttestationData{}) 90 91 _, err := validateSelectionIndex(ctx, beaconState, data, 0, sig.Marshal()) 92 wanted := "validator is not an aggregator for slot" 93 assert.ErrorContains(t, wanted, err) 94 } 95 96 func TestValidateAggregateAndProof_NoBlock(t *testing.T) { 97 db := dbtest.SetupDB(t) 98 p := p2ptest.NewTestP2P(t) 99 100 att := testutil.HydrateAttestation(ðpb.Attestation{ 101 Data: ðpb.AttestationData{ 102 Source: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 103 Target: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 104 }, 105 }) 106 107 aggregateAndProof := ðpb.AggregateAttestationAndProof{ 108 SelectionProof: bytesutil.PadTo([]byte{'A'}, 96), 109 Aggregate: att, 110 AggregatorIndex: 0, 111 } 112 signedAggregateAndProof := ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof, Signature: make([]byte, 96)} 113 114 c, err := lru.New(10) 115 require.NoError(t, err) 116 r := &Service{ 117 cfg: &Config{ 118 P2P: p, 119 DB: db, 120 InitialSync: &mockSync.Sync{IsSyncing: false}, 121 AttPool: attestations.NewPool(), 122 Chain: &mock.ChainService{}, 123 }, 124 blkRootToPendingAtts: make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof), 125 seenAggregatedAttestationCache: c, 126 } 127 err = r.initCaches() 128 require.NoError(t, err) 129 130 buf := new(bytes.Buffer) 131 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 132 require.NoError(t, err) 133 134 topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)] 135 msg := &pubsub.Message{ 136 Message: &pubsubpb.Message{ 137 Data: buf.Bytes(), 138 Topic: &topic, 139 }, 140 } 141 142 if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept { 143 t.Error("Expected validate to fail") 144 } 145 } 146 147 func TestValidateAggregateAndProof_NotWithinSlotRange(t *testing.T) { 148 db := dbtest.SetupDB(t) 149 p := p2ptest.NewTestP2P(t) 150 151 validators := uint64(256) 152 beaconState, _ := testutil.DeterministicGenesisState(t, validators) 153 154 b := testutil.NewBeaconBlock() 155 require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b))) 156 root, err := b.Block.HashTreeRoot() 157 require.NoError(t, err) 158 s, err := testutil.NewBeaconState() 159 require.NoError(t, err) 160 require.NoError(t, db.SaveState(context.Background(), s, root)) 161 162 aggBits := bitfield.NewBitlist(3) 163 aggBits.SetBitAt(0, true) 164 att := ðpb.Attestation{ 165 Data: ðpb.AttestationData{ 166 Slot: 1, 167 BeaconBlockRoot: root[:], 168 Source: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 169 Target: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 170 }, 171 AggregationBits: aggBits, 172 Signature: make([]byte, 96), 173 } 174 175 aggregateAndProof := ðpb.AggregateAttestationAndProof{ 176 Aggregate: att, 177 SelectionProof: make([]byte, 96), 178 } 179 signedAggregateAndProof := ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof, Signature: make([]byte, 96)} 180 181 require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix()))) 182 183 c, err := lru.New(10) 184 require.NoError(t, err) 185 r := &Service{ 186 cfg: &Config{ 187 P2P: p, 188 DB: db, 189 InitialSync: &mockSync.Sync{IsSyncing: false}, 190 Chain: &mock.ChainService{ 191 Genesis: time.Now(), 192 State: beaconState, 193 }, 194 AttPool: attestations.NewPool(), 195 AttestationNotifier: (&mock.ChainService{}).OperationNotifier(), 196 }, 197 seenAggregatedAttestationCache: c, 198 } 199 err = r.initCaches() 200 require.NoError(t, err) 201 202 buf := new(bytes.Buffer) 203 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 204 require.NoError(t, err) 205 206 topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)] 207 msg := &pubsub.Message{ 208 Message: &pubsubpb.Message{ 209 Data: buf.Bytes(), 210 Topic: &topic, 211 }, 212 } 213 214 if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept { 215 t.Error("Expected validate to fail") 216 } 217 218 att.Data.Slot = 1<<32 - 1 219 220 buf = new(bytes.Buffer) 221 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 222 require.NoError(t, err) 223 224 msg = &pubsub.Message{ 225 Message: &pubsubpb.Message{ 226 Data: buf.Bytes(), 227 Topic: &topic, 228 }, 229 } 230 if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept { 231 t.Error("Expected validate to fail") 232 } 233 } 234 235 func TestValidateAggregateAndProof_ExistedInPool(t *testing.T) { 236 db := dbtest.SetupDB(t) 237 p := p2ptest.NewTestP2P(t) 238 239 validators := uint64(256) 240 beaconState, _ := testutil.DeterministicGenesisState(t, validators) 241 242 b := testutil.NewBeaconBlock() 243 require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b))) 244 root, err := b.Block.HashTreeRoot() 245 require.NoError(t, err) 246 247 aggBits := bitfield.NewBitlist(3) 248 aggBits.SetBitAt(0, true) 249 att := ðpb.Attestation{ 250 Data: ðpb.AttestationData{ 251 Slot: 1, 252 BeaconBlockRoot: root[:], 253 Source: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 254 Target: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 255 }, 256 AggregationBits: aggBits, 257 Signature: make([]byte, 96), 258 } 259 260 aggregateAndProof := ðpb.AggregateAttestationAndProof{ 261 Aggregate: att, 262 SelectionProof: make([]byte, 96), 263 } 264 signedAggregateAndProof := ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof, Signature: make([]byte, 96)} 265 266 require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix()))) 267 c, err := lru.New(10) 268 require.NoError(t, err) 269 r := &Service{ 270 cfg: &Config{ 271 AttPool: attestations.NewPool(), 272 P2P: p, 273 DB: db, 274 InitialSync: &mockSync.Sync{IsSyncing: false}, 275 Chain: &mock.ChainService{Genesis: time.Now(), 276 State: beaconState}, 277 AttestationNotifier: (&mock.ChainService{}).OperationNotifier(), 278 }, 279 seenAggregatedAttestationCache: c, 280 blkRootToPendingAtts: make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof), 281 } 282 err = r.initCaches() 283 require.NoError(t, err) 284 285 buf := new(bytes.Buffer) 286 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 287 require.NoError(t, err) 288 289 topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)] 290 msg := &pubsub.Message{ 291 Message: &pubsubpb.Message{ 292 Data: buf.Bytes(), 293 Topic: &topic, 294 }, 295 } 296 297 require.NoError(t, r.cfg.AttPool.SaveBlockAttestation(att)) 298 if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept { 299 t.Error("Expected validate to fail") 300 } 301 } 302 303 func TestValidateAggregateAndProof_CanValidate(t *testing.T) { 304 db := dbtest.SetupDB(t) 305 p := p2ptest.NewTestP2P(t) 306 307 validators := uint64(256) 308 beaconState, privKeys := testutil.DeterministicGenesisState(t, validators) 309 310 b := testutil.NewBeaconBlock() 311 require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b))) 312 root, err := b.Block.HashTreeRoot() 313 require.NoError(t, err) 314 s, err := testutil.NewBeaconState() 315 require.NoError(t, err) 316 require.NoError(t, db.SaveState(context.Background(), s, root)) 317 318 aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch)) 319 aggBits.SetBitAt(0, true) 320 att := ðpb.Attestation{ 321 Data: ðpb.AttestationData{ 322 BeaconBlockRoot: root[:], 323 Source: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 324 Target: ðpb.Checkpoint{Epoch: 0, Root: root[:]}, 325 }, 326 AggregationBits: aggBits, 327 } 328 329 committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex) 330 assert.NoError(t, err) 331 attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee) 332 require.NoError(t, err) 333 assert.NoError(t, err) 334 attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot()) 335 assert.NoError(t, err) 336 hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain) 337 assert.NoError(t, err) 338 sigs := make([]bls.Signature, len(attestingIndices)) 339 for i, indice := range attestingIndices { 340 sig := privKeys[indice].Sign(hashTreeRoot[:]) 341 sigs[i] = sig 342 } 343 att.Signature = bls.AggregateSignatures(sigs).Marshal() 344 ai := committee[0] 345 sszUint := types.SSZUint64(att.Data.Slot) 346 sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[ai]) 347 require.NoError(t, err) 348 aggregateAndProof := ðpb.AggregateAttestationAndProof{ 349 SelectionProof: sig, 350 Aggregate: att, 351 AggregatorIndex: ai, 352 } 353 signedAggregateAndProof := ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof} 354 signedAggregateAndProof.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, signedAggregateAndProof.Message, params.BeaconConfig().DomainAggregateAndProof, privKeys[ai]) 355 require.NoError(t, err) 356 357 require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix()))) 358 c, err := lru.New(10) 359 require.NoError(t, err) 360 r := &Service{ 361 cfg: &Config{ 362 P2P: p, 363 DB: db, 364 InitialSync: &mockSync.Sync{IsSyncing: false}, 365 Chain: &mock.ChainService{Genesis: time.Now(), 366 State: beaconState, 367 ValidAttestation: true, 368 FinalizedCheckPoint: ðpb.Checkpoint{ 369 Epoch: 0, 370 Root: att.Data.BeaconBlockRoot, 371 }}, 372 AttPool: attestations.NewPool(), 373 AttestationNotifier: (&mock.ChainService{}).OperationNotifier(), 374 }, 375 seenAggregatedAttestationCache: c, 376 } 377 err = r.initCaches() 378 require.NoError(t, err) 379 380 buf := new(bytes.Buffer) 381 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 382 require.NoError(t, err) 383 384 topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)] 385 msg := &pubsub.Message{ 386 Message: &pubsubpb.Message{ 387 Data: buf.Bytes(), 388 Topic: &topic, 389 }, 390 } 391 392 assert.Equal(t, pubsub.ValidationAccept, r.validateAggregateAndProof(context.Background(), "", msg), "Validated status is false") 393 assert.NotNil(t, msg.ValidatorData, "Did not set validator data") 394 } 395 396 func TestVerifyIndexInCommittee_SeenAggregatorEpoch(t *testing.T) { 397 db := dbtest.SetupDB(t) 398 p := p2ptest.NewTestP2P(t) 399 400 validators := uint64(256) 401 beaconState, privKeys := testutil.DeterministicGenesisState(t, validators) 402 403 b := testutil.NewBeaconBlock() 404 require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b))) 405 root, err := b.Block.HashTreeRoot() 406 require.NoError(t, err) 407 s, err := testutil.NewBeaconState() 408 require.NoError(t, err) 409 require.NoError(t, db.SaveState(context.Background(), s, root)) 410 411 aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch)) 412 aggBits.SetBitAt(0, true) 413 att := ðpb.Attestation{ 414 Data: ðpb.AttestationData{ 415 BeaconBlockRoot: root[:], 416 Source: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 417 Target: ðpb.Checkpoint{Epoch: 0, Root: root[:]}, 418 }, 419 AggregationBits: aggBits, 420 } 421 422 committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex) 423 require.NoError(t, err) 424 attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee) 425 require.NoError(t, err) 426 attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot()) 427 require.NoError(t, err) 428 hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain) 429 assert.NoError(t, err) 430 sigs := make([]bls.Signature, len(attestingIndices)) 431 for i, indice := range attestingIndices { 432 sig := privKeys[indice].Sign(hashTreeRoot[:]) 433 sigs[i] = sig 434 } 435 att.Signature = bls.AggregateSignatures(sigs).Marshal() 436 ai := committee[0] 437 sszUint := types.SSZUint64(att.Data.Slot) 438 sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[ai]) 439 require.NoError(t, err) 440 aggregateAndProof := ðpb.AggregateAttestationAndProof{ 441 SelectionProof: sig, 442 Aggregate: att, 443 AggregatorIndex: ai, 444 } 445 signedAggregateAndProof := ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof} 446 signedAggregateAndProof.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, signedAggregateAndProof.Message, params.BeaconConfig().DomainAggregateAndProof, privKeys[ai]) 447 require.NoError(t, err) 448 require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix()))) 449 450 c, err := lru.New(10) 451 require.NoError(t, err) 452 r := &Service{ 453 cfg: &Config{ 454 P2P: p, 455 DB: db, 456 InitialSync: &mockSync.Sync{IsSyncing: false}, 457 Chain: &mock.ChainService{Genesis: time.Now(), 458 ValidatorsRoot: [32]byte{'A'}, 459 State: beaconState, 460 ValidAttestation: true, 461 FinalizedCheckPoint: ðpb.Checkpoint{ 462 Epoch: 0, 463 Root: signedAggregateAndProof.Message.Aggregate.Data.BeaconBlockRoot, 464 }}, 465 466 AttPool: attestations.NewPool(), 467 AttestationNotifier: (&mock.ChainService{}).OperationNotifier(), 468 }, 469 seenAggregatedAttestationCache: c, 470 } 471 err = r.initCaches() 472 require.NoError(t, err) 473 474 buf := new(bytes.Buffer) 475 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 476 require.NoError(t, err) 477 478 topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)] 479 msg := &pubsub.Message{ 480 Message: &pubsubpb.Message{ 481 Data: buf.Bytes(), 482 Topic: &topic, 483 }, 484 } 485 486 require.Equal(t, pubsub.ValidationAccept, r.validateAggregateAndProof(context.Background(), "", msg), "Validated status is false") 487 488 // Should fail with another attestation in the same epoch. 489 signedAggregateAndProof.Message.Aggregate.Data.Slot++ 490 buf = new(bytes.Buffer) 491 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 492 require.NoError(t, err) 493 msg = &pubsub.Message{ 494 Message: &pubsubpb.Message{ 495 Data: buf.Bytes(), 496 Topic: &topic, 497 }, 498 } 499 500 time.Sleep(10 * time.Millisecond) // Wait for cached value to pass through buffers. 501 if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept { 502 t.Fatal("Validated status is true") 503 } 504 } 505 506 func TestValidateAggregateAndProof_BadBlock(t *testing.T) { 507 508 db := dbtest.SetupDB(t) 509 p := p2ptest.NewTestP2P(t) 510 511 validators := uint64(256) 512 beaconState, privKeys := testutil.DeterministicGenesisState(t, validators) 513 514 b := testutil.NewBeaconBlock() 515 root, err := b.Block.HashTreeRoot() 516 require.NoError(t, err) 517 s, err := testutil.NewBeaconState() 518 require.NoError(t, err) 519 require.NoError(t, db.SaveState(context.Background(), s, root)) 520 521 aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch)) 522 aggBits.SetBitAt(0, true) 523 att := ðpb.Attestation{ 524 Data: ðpb.AttestationData{ 525 BeaconBlockRoot: root[:], 526 Source: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 527 Target: ðpb.Checkpoint{Epoch: 0, Root: root[:]}, 528 }, 529 AggregationBits: aggBits, 530 } 531 532 committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex) 533 assert.NoError(t, err) 534 attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee) 535 require.NoError(t, err) 536 assert.NoError(t, err) 537 attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot()) 538 assert.NoError(t, err) 539 hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain) 540 assert.NoError(t, err) 541 sigs := make([]bls.Signature, len(attestingIndices)) 542 for i, indice := range attestingIndices { 543 sig := privKeys[indice].Sign(hashTreeRoot[:]) 544 sigs[i] = sig 545 } 546 att.Signature = bls.AggregateSignatures(sigs).Marshal() 547 ai := committee[0] 548 sszUint := types.SSZUint64(att.Data.Slot) 549 sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[ai]) 550 require.NoError(t, err) 551 552 aggregateAndProof := ðpb.AggregateAttestationAndProof{ 553 SelectionProof: sig, 554 Aggregate: att, 555 AggregatorIndex: ai, 556 } 557 signedAggregateAndProof := ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof} 558 signedAggregateAndProof.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, signedAggregateAndProof.Message, params.BeaconConfig().DomainAggregateAndProof, privKeys[ai]) 559 require.NoError(t, err) 560 561 require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix()))) 562 c, err := lru.New(10) 563 require.NoError(t, err) 564 r := &Service{ 565 cfg: &Config{ 566 P2P: p, 567 DB: db, 568 InitialSync: &mockSync.Sync{IsSyncing: false}, 569 Chain: &mock.ChainService{Genesis: time.Now(), 570 State: beaconState, 571 ValidAttestation: true, 572 FinalizedCheckPoint: ðpb.Checkpoint{ 573 Epoch: 0, 574 }}, 575 AttPool: attestations.NewPool(), 576 AttestationNotifier: (&mock.ChainService{}).OperationNotifier(), 577 }, 578 seenAggregatedAttestationCache: c, 579 } 580 err = r.initCaches() 581 require.NoError(t, err) 582 // Set beacon block as bad. 583 r.setBadBlock(context.Background(), root) 584 buf := new(bytes.Buffer) 585 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 586 require.NoError(t, err) 587 588 topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)] 589 msg := &pubsub.Message{ 590 Message: &pubsubpb.Message{ 591 Data: buf.Bytes(), 592 Topic: &topic, 593 }, 594 } 595 596 assert.Equal(t, pubsub.ValidationReject, r.validateAggregateAndProof(context.Background(), "", msg), "Validated status is true") 597 } 598 599 func TestValidateAggregateAndProof_RejectWhenAttEpochDoesntEqualTargetEpoch(t *testing.T) { 600 db := dbtest.SetupDB(t) 601 p := p2ptest.NewTestP2P(t) 602 603 validators := uint64(256) 604 beaconState, privKeys := testutil.DeterministicGenesisState(t, validators) 605 606 b := testutil.NewBeaconBlock() 607 require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b))) 608 root, err := b.Block.HashTreeRoot() 609 require.NoError(t, err) 610 s, err := testutil.NewBeaconState() 611 require.NoError(t, err) 612 require.NoError(t, db.SaveState(context.Background(), s, root)) 613 614 aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch)) 615 aggBits.SetBitAt(0, true) 616 att := ðpb.Attestation{ 617 Data: ðpb.AttestationData{ 618 BeaconBlockRoot: root[:], 619 Source: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, 620 Target: ðpb.Checkpoint{Epoch: 1, Root: root[:]}, 621 }, 622 AggregationBits: aggBits, 623 } 624 625 committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex) 626 assert.NoError(t, err) 627 attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee) 628 require.NoError(t, err) 629 assert.NoError(t, err) 630 attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot()) 631 assert.NoError(t, err) 632 hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain) 633 assert.NoError(t, err) 634 sigs := make([]bls.Signature, len(attestingIndices)) 635 for i, indice := range attestingIndices { 636 sig := privKeys[indice].Sign(hashTreeRoot[:]) 637 sigs[i] = sig 638 } 639 att.Signature = bls.AggregateSignatures(sigs).Marshal() 640 ai := committee[0] 641 sszUint := types.SSZUint64(att.Data.Slot) 642 sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[ai]) 643 require.NoError(t, err) 644 aggregateAndProof := ðpb.AggregateAttestationAndProof{ 645 SelectionProof: sig, 646 Aggregate: att, 647 AggregatorIndex: ai, 648 } 649 signedAggregateAndProof := ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof} 650 signedAggregateAndProof.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, signedAggregateAndProof.Message, params.BeaconConfig().DomainAggregateAndProof, privKeys[ai]) 651 require.NoError(t, err) 652 653 require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix()))) 654 c, err := lru.New(10) 655 require.NoError(t, err) 656 r := &Service{ 657 cfg: &Config{ 658 P2P: p, 659 DB: db, 660 InitialSync: &mockSync.Sync{IsSyncing: false}, 661 Chain: &mock.ChainService{Genesis: time.Now(), 662 State: beaconState, 663 ValidAttestation: true, 664 FinalizedCheckPoint: ðpb.Checkpoint{ 665 Epoch: 0, 666 Root: att.Data.BeaconBlockRoot, 667 }}, 668 AttPool: attestations.NewPool(), 669 AttestationNotifier: (&mock.ChainService{}).OperationNotifier(), 670 }, 671 seenAggregatedAttestationCache: c, 672 } 673 err = r.initCaches() 674 require.NoError(t, err) 675 676 buf := new(bytes.Buffer) 677 _, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof) 678 require.NoError(t, err) 679 680 topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)] 681 msg := &pubsub.Message{ 682 Message: &pubsubpb.Message{ 683 Data: buf.Bytes(), 684 Topic: &topic, 685 }, 686 } 687 688 assert.Equal(t, pubsub.ValidationReject, r.validateAggregateAndProof(context.Background(), "", msg)) 689 }