Skip to content

Commit b5448d6

Browse files
committed
Decompose Electra block attestations
1 parent 44ff0b1 commit b5448d6

File tree

4 files changed

+136
-10
lines changed

4 files changed

+136
-10
lines changed

beacon-chain/blockchain/BUILD.bazel

+3
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ go_library(
9696
"@com_github_pkg_errors//:go_default_library",
9797
"@com_github_prometheus_client_golang//prometheus:go_default_library",
9898
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
99+
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
99100
"@com_github_sirupsen_logrus//:go_default_library",
100101
"@org_golang_x_sync//errgroup:go_default_library",
101102
],
@@ -154,6 +155,7 @@ go_test(
154155
"//beacon-chain/forkchoice/doubly-linked-tree:go_default_library",
155156
"//beacon-chain/forkchoice/types:go_default_library",
156157
"//beacon-chain/operations/attestations:go_default_library",
158+
"//beacon-chain/operations/attestations/kv:go_default_library",
157159
"//beacon-chain/operations/blstoexec:go_default_library",
158160
"//beacon-chain/operations/slashings:go_default_library",
159161
"//beacon-chain/operations/voluntaryexits:go_default_library",
@@ -185,6 +187,7 @@ go_test(
185187
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
186188
"@com_github_holiman_uint256//:go_default_library",
187189
"@com_github_pkg_errors//:go_default_library",
190+
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
188191
"@com_github_sirupsen_logrus//:go_default_library",
189192
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
190193
"@org_golang_google_protobuf//proto:go_default_library",

beacon-chain/blockchain/forkchoice_update_execution.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (s *Service) forkchoiceUpdateWithExecution(ctx context.Context, args *fcuCo
103103
}
104104

105105
// Only need to prune attestations from pool if the head has changed.
106-
if err := s.pruneAttsFromPool(args.headBlock); err != nil {
106+
if err := s.pruneAttsFromPool(s.ctx, args.headState, args.headBlock); err != nil {
107107
log.WithError(err).Error("could not prune attestations from pool")
108108
}
109109
return nil

beacon-chain/blockchain/process_block.go

+46-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"time"
77

88
"github.com/pkg/errors"
9+
"github.com/prysmaticlabs/go-bitfield"
910
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
1011
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
1112
coreTime "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
@@ -420,21 +421,58 @@ func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interface
420421
}
421422

422423
// This removes the attestations in block `b` from the attestation mem pool.
423-
func (s *Service) pruneAttsFromPool(headBlock interfaces.ReadOnlySignedBeaconBlock) error {
424+
func (s *Service) pruneAttsFromPool(ctx context.Context, headState state.BeaconState, headBlock interfaces.ReadOnlySignedBeaconBlock) error {
424425
atts := headBlock.Block().Body().Attestations()
425426
for _, att := range atts {
426-
if features.Get().EnableExperimentalAttestationPool {
427-
if err := s.cfg.AttestationCache.DeleteCovered(att); err != nil {
428-
return errors.Wrap(err, "could not delete attestation")
427+
if !att.IsAggregated() {
428+
if err := s.cfg.AttPool.DeleteUnaggregatedAttestation(att); err != nil {
429+
return err
429430
}
430-
} else if att.IsAggregated() {
431-
if err := s.cfg.AttPool.DeleteAggregatedAttestation(att); err != nil {
431+
continue
432+
}
433+
434+
if att.Version() == version.Phase0 {
435+
if features.Get().EnableExperimentalAttestationPool {
436+
if err := s.cfg.AttestationCache.DeleteCovered(att); err != nil {
437+
return err
438+
}
439+
} else if err := s.cfg.AttPool.DeleteAggregatedAttestation(att); err != nil {
432440
return err
433441
}
434-
} else {
435-
if err := s.cfg.AttPool.DeleteUnaggregatedAttestation(att); err != nil {
442+
continue
443+
}
444+
445+
offset := uint64(0)
446+
447+
committeeIndices := att.CommitteeBitsVal().BitIndices()
448+
committees, err := helpers.AttestationCommittees(ctx, headState, att)
449+
if err != nil {
450+
return err
451+
}
452+
for i, c := range committees {
453+
ab := bitfield.NewBitlist(uint64(len(c)))
454+
for j := uint64(0); j < uint64(len(c)); j++ {
455+
ab.SetBitAt(j, att.GetAggregationBits().BitAt(j+offset) == true)
456+
}
457+
458+
cb := primitives.NewAttestationCommitteeBits()
459+
cb.SetBitAt(uint64(committeeIndices[i]), true)
460+
461+
a := &ethpb.AttestationElectra{
462+
AggregationBits: ab,
463+
Data: att.GetData(),
464+
CommitteeBits: cb,
465+
}
466+
467+
if features.Get().EnableExperimentalAttestationPool {
468+
if err := s.cfg.AttestationCache.DeleteCovered(a); err != nil {
469+
return err
470+
}
471+
} else if err := s.cfg.AttPool.DeleteAggregatedAttestation(a); err != nil {
436472
return err
437473
}
474+
475+
offset += uint64(len(c))
438476
}
439477
}
440478
return nil

beacon-chain/blockchain/process_block_test.go

+86-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import (
1212
"github.com/ethereum/go-ethereum/common"
1313
gethtypes "github.com/ethereum/go-ethereum/core/types"
1414
"github.com/pkg/errors"
15+
"github.com/prysmaticlabs/go-bitfield"
1516
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
1617
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
18+
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
1719
lightClient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client"
1820
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
1921
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
@@ -25,6 +27,7 @@ import (
2527
mockExecution "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/testing"
2628
doublylinkedtree "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/doubly-linked-tree"
2729
forkchoicetypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/types"
30+
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/attestations/kv"
2831
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
2932
"github.com/prysmaticlabs/prysm/v5/config/features"
3033
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
@@ -45,6 +48,88 @@ import (
4548
logTest "github.com/sirupsen/logrus/hooks/test"
4649
)
4750

51+
func Test_pruneAttsFromPool_Electra(t *testing.T) {
52+
ctx := context.Background()
53+
54+
params.SetupTestConfigCleanup(t)
55+
cfg := params.BeaconConfig().Copy()
56+
cfg.TargetCommitteeSize = 8
57+
params.OverrideBeaconConfig(cfg)
58+
59+
s := Service{
60+
cfg: &config{
61+
AttPool: kv.NewAttCaches(),
62+
},
63+
}
64+
65+
data := &ethpb.AttestationData{
66+
BeaconBlockRoot: make([]byte, 32),
67+
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
68+
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
69+
}
70+
71+
cb := primitives.NewAttestationCommitteeBits()
72+
cb.SetBitAt(0, true)
73+
att1 := &ethpb.AttestationElectra{
74+
AggregationBits: bitfield.Bitlist{0b11110111, 0b00000001},
75+
Data: data,
76+
Signature: make([]byte, 96),
77+
CommitteeBits: cb,
78+
}
79+
80+
cb = primitives.NewAttestationCommitteeBits()
81+
cb.SetBitAt(1, true)
82+
att2 := &ethpb.AttestationElectra{
83+
AggregationBits: bitfield.Bitlist{0b11110111, 0b00000001},
84+
Data: data,
85+
Signature: make([]byte, 96),
86+
CommitteeBits: cb,
87+
}
88+
89+
cb = primitives.NewAttestationCommitteeBits()
90+
cb.SetBitAt(3, true)
91+
att3 := &ethpb.AttestationElectra{
92+
AggregationBits: bitfield.Bitlist{0b11110111, 0b00000001},
93+
Data: data,
94+
Signature: make([]byte, 96),
95+
CommitteeBits: cb,
96+
}
97+
98+
require.NoError(t, s.cfg.AttPool.SaveAggregatedAttestation(att1))
99+
require.NoError(t, s.cfg.AttPool.SaveAggregatedAttestation(att2))
100+
require.NoError(t, s.cfg.AttPool.SaveAggregatedAttestation(att3))
101+
require.Equal(t, 3, len(s.cfg.AttPool.AggregatedAttestations()))
102+
103+
cb = primitives.NewAttestationCommitteeBits()
104+
cb.SetBitAt(0, true)
105+
cb.SetBitAt(1, true)
106+
onChainAtt := &ethpb.AttestationElectra{
107+
AggregationBits: bitfield.Bitlist{0b11110111, 0b11110111, 0b00000001},
108+
Data: data,
109+
Signature: make([]byte, 96),
110+
CommitteeBits: cb,
111+
}
112+
bl := &ethpb.SignedBeaconBlockElectra{
113+
Block: &ethpb.BeaconBlockElectra{
114+
Body: &ethpb.BeaconBlockBodyElectra{
115+
Attestations: []*ethpb.AttestationElectra{onChainAtt},
116+
},
117+
},
118+
Signature: make([]byte, 96),
119+
}
120+
rob, err := consensusblocks.NewSignedBeaconBlock(bl)
121+
require.NoError(t, err)
122+
st, _ := util.DeterministicGenesisStateElectra(t, 1024)
123+
committees, err := helpers.BeaconCommittees(ctx, st, 0)
124+
require.NoError(t, err)
125+
require.Equal(t, 4, len(committees))
126+
127+
require.NoError(t, s.pruneAttsFromPool(ctx, st, rob))
128+
attsInPool := s.cfg.AttPool.AggregatedAttestations()
129+
require.Equal(t, 1, len(attsInPool))
130+
assert.DeepEqual(t, att3, attsInPool[0])
131+
}
132+
48133
func TestStore_OnBlockBatch(t *testing.T) {
49134
service, tr := minimalTestService(t)
50135
ctx := tr.ctx
@@ -840,7 +925,7 @@ func TestRemoveBlockAttestationsInPool(t *testing.T) {
840925
require.NoError(t, service.cfg.AttPool.SaveAggregatedAttestations(atts))
841926
wsb, err := consensusblocks.NewSignedBeaconBlock(b)
842927
require.NoError(t, err)
843-
require.NoError(t, service.pruneAttsFromPool(wsb))
928+
require.NoError(t, service.pruneAttsFromPool(context.Background(), nil /* state not needed pre-Electra */, wsb))
844929
require.Equal(t, 0, service.cfg.AttPool.AggregatedAttestationCount())
845930
}
846931

0 commit comments

Comments
 (0)