Eip 7549 core (#14037)

* interfaces move

* build fix

* remove annoying warning

* more build fixes

* review

* core code

* tests part 1

* tests part 2

* TranslateParticipation doesn't need Electra

* remove unused function

* pending atts don't need Electra

* tests part 3

* build fixes

* review

* remove newline

* review

* fix test
This commit is contained in:
Radosław Kapka
2024-05-28 22:56:36 +09:00
committed by GitHub
parent 2f2152e039
commit 2d15e53dab
35 changed files with 924 additions and 236 deletions

View File

@@ -80,11 +80,11 @@ func (s *Service) OnAttestation(ctx context.Context, a ethpb.Att, disparity time
}
// Use the target state to verify attesting indices are valid.
committee, err := helpers.BeaconCommitteeFromState(ctx, baseState, a.GetData().Slot, a.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, baseState, a)
if err != nil {
return err
}
indexedAtt, err := attestation.ConvertToIndexed(ctx, a, committee)
indexedAtt, err := attestation.ConvertToIndexed(ctx, a, committees...)
if err != nil {
return err
}

View File

@@ -7,9 +7,11 @@ import (
"time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
@@ -125,25 +127,36 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
}
func TestStore_OnAttestation_Ok_DoublyLinkedTree(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
eval := func(ctx context.Context, service *Service, genesisState state.BeaconState, pks []bls.SecretKey) {
service.SetGenesisTime(time.Unix(time.Now().Unix()-int64(params.BeaconConfig().SecondsPerSlot), 0))
require.NoError(t, service.saveGenesisData(ctx, genesisState))
att, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err)
tRoot := bytesutil.ToBytes32(att[0].GetData().Target.Root)
copied := genesisState.Copy()
copied, err = transition.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
ojc := &ethpb.Checkpoint{Epoch: 0, Root: tRoot[:]}
ofc := &ethpb.Checkpoint{Epoch: 0, Root: tRoot[:]}
state, blkRoot, err := prepareForkchoiceState(ctx, 0, tRoot, tRoot, params.BeaconConfig().ZeroHash, ojc, ofc)
require.NoError(t, err)
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
require.NoError(t, service.OnAttestation(ctx, att[0], 0))
}
genesisState, pks := util.DeterministicGenesisState(t, 64)
service.SetGenesisTime(time.Unix(time.Now().Unix()-int64(params.BeaconConfig().SecondsPerSlot), 0))
require.NoError(t, service.saveGenesisData(ctx, genesisState))
att, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err)
tRoot := bytesutil.ToBytes32(att[0].Data.Target.Root)
copied := genesisState.Copy()
copied, err = transition.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
ojc := &ethpb.Checkpoint{Epoch: 0, Root: tRoot[:]}
ofc := &ethpb.Checkpoint{Epoch: 0, Root: tRoot[:]}
state, blkRoot, err := prepareForkchoiceState(ctx, 0, tRoot, tRoot, params.BeaconConfig().ZeroHash, ojc, ofc)
require.NoError(t, err)
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
require.NoError(t, service.OnAttestation(ctx, att[0], 0))
t.Run("pre-Electra", func(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
genesisState, pks := util.DeterministicGenesisState(t, 64)
eval(ctx, service, genesisState, pks)
})
t.Run("post-Electra", func(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
genesisState, pks := util.DeterministicGenesisStateElectra(t, 64)
eval(ctx, service, genesisState, pks)
})
}
func TestService_GetRecentPreState(t *testing.T) {

View File

@@ -366,11 +366,11 @@ func (s *Service) handleEpochBoundary(ctx context.Context, slot primitives.Slot,
func (s *Service) handleBlockAttestations(ctx context.Context, blk interfaces.ReadOnlyBeaconBlock, st state.BeaconState) error {
// Feed in block's attestations to fork choice store.
for _, a := range blk.Body().Attestations() {
committee, err := helpers.BeaconCommitteeFromState(ctx, st, a.GetData().Slot, a.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, st, a)
if err != nil {
return err
}
indices, err := attestation.AttestingIndices(a, committee)
indices, err := attestation.AttestingIndices(a, committees...)
if err != nil {
return err
}

View File

@@ -1963,68 +1963,130 @@ func TestNoViableHead_Reboot(t *testing.T) {
}
func TestOnBlock_HandleBlockAttestations(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
t.Run("pre-Electra", func(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
st, keys := util.DeterministicGenesisState(t, 64)
stateRoot, err := st.HashTreeRoot(ctx)
require.NoError(t, err, "Could not hash genesis state")
st, keys := util.DeterministicGenesisState(t, 64)
stateRoot, err := st.HashTreeRoot(ctx)
require.NoError(t, err, "Could not hash genesis state")
require.NoError(t, service.saveGenesisData(ctx, st))
require.NoError(t, service.saveGenesisData(ctx, st))
genesis := blocks.NewGenesisBlock(stateRoot[:])
wsb, err := consensusblocks.NewSignedBeaconBlock(genesis)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wsb), "Could not save genesis block")
parentRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err, "Could not get signing root")
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st, parentRoot), "Could not save genesis state")
require.NoError(t, service.cfg.BeaconDB.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state")
genesis := blocks.NewGenesisBlock(stateRoot[:])
wsb, err := consensusblocks.NewSignedBeaconBlock(genesis)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wsb), "Could not save genesis block")
parentRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err, "Could not get signing root")
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st, parentRoot), "Could not save genesis state")
require.NoError(t, service.cfg.BeaconDB.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state")
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 1)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
preState, err := service.getBlockPreState(ctx, wsb.Block())
require.NoError(t, err)
postState, err := service.validateStateTransition(ctx, preState, wsb)
require.NoError(t, err)
require.NoError(t, service.savePostStateInfo(ctx, root, wsb, postState))
require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, wsb, root, [32]byte{}, postState, false}))
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 1)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
preState, err := service.getBlockPreState(ctx, wsb.Block())
require.NoError(t, err)
postState, err := service.validateStateTransition(ctx, preState, wsb)
require.NoError(t, err)
require.NoError(t, service.savePostStateInfo(ctx, root, wsb, postState))
require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, wsb, root, [32]byte{}, postState, false}))
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err = util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 2)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err = util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 2)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
// prepare another block that is not inserted
st3, err := transition.ExecuteStateTransition(ctx, st, wsb)
require.NoError(t, err)
b3, err := util.GenerateFullBlock(st3, keys, util.DefaultBlockGenConfig(), 3)
require.NoError(t, err)
wsb3, err := consensusblocks.NewSignedBeaconBlock(b3)
require.NoError(t, err)
// prepare another block that is not inserted
st3, err := transition.ExecuteStateTransition(ctx, st, wsb)
require.NoError(t, err)
b3, err := util.GenerateFullBlock(st3, keys, util.DefaultBlockGenConfig(), 3)
require.NoError(t, err)
wsb3, err := consensusblocks.NewSignedBeaconBlock(b3)
require.NoError(t, err)
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a := wsb.Block().Body().Attestations()[0]
r := bytesutil.ToBytes32(a.GetData().BeaconBlockRoot)
require.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r))
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a := wsb.Block().Body().Attestations()[0]
r := bytesutil.ToBytes32(a.GetData().BeaconBlockRoot)
require.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r))
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a3 := wsb3.Block().Body().Attestations()[0]
r3 := bytesutil.ToBytes32(a3.GetData().BeaconBlockRoot)
require.Equal(t, false, service.cfg.ForkChoiceStore.HasNode(r3))
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a3 := wsb3.Block().Body().Attestations()[0]
r3 := bytesutil.ToBytes32(a3.GetData().BeaconBlockRoot)
require.Equal(t, false, service.cfg.ForkChoiceStore.HasNode(r3))
require.NoError(t, service.handleBlockAttestations(ctx, wsb.Block(), st)) // fine to use the same committee as st
require.Equal(t, 0, service.cfg.AttPool.ForkchoiceAttestationCount())
require.NoError(t, service.handleBlockAttestations(ctx, wsb3.Block(), st3)) // fine to use the same committee as st
require.Equal(t, 1, len(service.cfg.AttPool.BlockAttestations()))
require.NoError(t, service.handleBlockAttestations(ctx, wsb.Block(), st)) // fine to use the same committee as st
require.Equal(t, 0, service.cfg.AttPool.ForkchoiceAttestationCount())
require.NoError(t, service.handleBlockAttestations(ctx, wsb3.Block(), st3)) // fine to use the same committee as st
require.Equal(t, 1, len(service.cfg.AttPool.BlockAttestations()))
})
t.Run("post-Electra", func(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
st, keys := util.DeterministicGenesisStateElectra(t, 64)
require.NoError(t, service.saveGenesisData(ctx, st))
genesis, err := blocks.NewGenesisBlockForState(ctx, st)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, genesis), "Could not save genesis block")
parentRoot, err := genesis.Block().HashTreeRoot()
require.NoError(t, err, "Could not get signing root")
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st, parentRoot), "Could not save genesis state")
require.NoError(t, service.cfg.BeaconDB.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state")
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err := util.GenerateFullBlockElectra(st, keys, util.DefaultBlockGenConfig(), 1)
require.NoError(t, err)
wsb, err := consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
preState, err := service.getBlockPreState(ctx, wsb.Block())
require.NoError(t, err)
postState, err := service.validateStateTransition(ctx, preState, wsb)
require.NoError(t, err)
require.NoError(t, service.savePostStateInfo(ctx, root, wsb, postState))
require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, wsb, root, [32]byte{}, postState, false}))
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err = util.GenerateFullBlockElectra(st, keys, util.DefaultBlockGenConfig(), 2)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
// prepare another block that is not inserted
st3, err := transition.ExecuteStateTransition(ctx, st, wsb)
require.NoError(t, err)
b3, err := util.GenerateFullBlockElectra(st3, keys, util.DefaultBlockGenConfig(), 3)
require.NoError(t, err)
wsb3, err := consensusblocks.NewSignedBeaconBlock(b3)
require.NoError(t, err)
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a := wsb.Block().Body().Attestations()[0]
r := bytesutil.ToBytes32(a.GetData().BeaconBlockRoot)
require.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r))
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a3 := wsb3.Block().Body().Attestations()[0]
r3 := bytesutil.ToBytes32(a3.GetData().BeaconBlockRoot)
require.Equal(t, false, service.cfg.ForkChoiceStore.HasNode(r3))
require.NoError(t, service.handleBlockAttestations(ctx, wsb.Block(), st)) // fine to use the same committee as st
require.Equal(t, 0, service.cfg.AttPool.ForkchoiceAttestationCount())
require.NoError(t, service.handleBlockAttestations(ctx, wsb3.Block(), st3)) // fine to use the same committee as st
require.Equal(t, 1, len(service.cfg.AttPool.BlockAttestations()))
})
}
func TestFillMissingBlockPayloadId_DiffSlotExitEarly(t *testing.T) {

View File

@@ -73,7 +73,7 @@ func TestProcessAttestations_Ok(t *testing.T) {
require.NoError(t, service.saveGenesisData(ctx, genesisState))
atts, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err)
tRoot := bytesutil.ToBytes32(atts[0].Data.Target.Root)
tRoot := bytesutil.ToBytes32(atts[0].GetData().Target.Root)
copied := genesisState.Copy()
copied, err = transition.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
@@ -131,8 +131,8 @@ func TestService_ProcessAttestationsAndUpdateHead(t *testing.T) {
}
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(attsToSave))
// Verify the target is in forkchoice
require.Equal(t, true, fcs.HasNode(bytesutil.ToBytes32(atts[0].Data.BeaconBlockRoot)))
require.Equal(t, tRoot, bytesutil.ToBytes32(atts[0].Data.BeaconBlockRoot))
require.Equal(t, true, fcs.HasNode(bytesutil.ToBytes32(atts[0].GetData().BeaconBlockRoot)))
require.Equal(t, tRoot, bytesutil.ToBytes32(atts[0].GetData().BeaconBlockRoot))
require.Equal(t, true, fcs.HasNode(service.originBlockRoot))
// Insert a new block to forkchoice

View File

@@ -479,12 +479,12 @@ func (s *Service) sendBlockAttestationsToSlasher(signed interfaces.ReadOnlySigne
// is done in the background to avoid adding more load to this critical code path.
ctx := context.TODO()
for _, att := range signed.Block().Body().Attestations() {
committee, err := helpers.BeaconCommitteeFromState(ctx, preState, att.GetData().Slot, att.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, preState, att)
if err != nil {
log.WithError(err).Error("Could not get attestation committee")
log.WithError(err).Error("Could not get attestation committees")
return
}
indexedAtt, err := attestation.ConvertToIndexed(ctx, att, committee)
indexedAtt, err := attestation.ConvertToIndexed(ctx, att, committees...)
if err != nil {
log.WithError(err).Error("Could not convert to indexed attestation")
return

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filesystem"
testDB "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/testing"
mockExecution "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/testing"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice"
doublylinkedtree "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/doubly-linked-tree"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/attestations"
@@ -120,6 +121,7 @@ func minimalTestService(t *testing.T, opts ...Option) (*Service, *testServiceReq
WithTrackedValidatorsCache(cache.NewTrackedValidatorsCache()),
WithBlobStorage(filesystem.NewEphemeralBlobStorage(t)),
WithSyncChecker(mock.MockChecker{}),
WithExecutionEngineCaller(&mockExecution.EngineClient{}),
}
// append the variadic opts so they override the defaults by being processed afterwards
opts = append(defOpts, opts...)

View File

@@ -66,11 +66,11 @@ func ProcessAttestationNoVerifySignature(
if err != nil {
return nil, err
}
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, beaconState, att)
if err != nil {
return nil, err
}
indices, err := attestation.AttestingIndices(att, committee)
indices, err := attestation.AttestingIndices(att, committees...)
if err != nil {
return nil, err
}

View File

@@ -195,47 +195,95 @@ func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
}
func TestProcessAttestations_OK(t *testing.T) {
beaconState, privKeys := util.DeterministicGenesisStateAltair(t, 100)
t.Run("pre-Electra", func(t *testing.T) {
beaconState, privKeys := util.DeterministicGenesisStateAltair(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := util.HydrateAttestation(&ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Root: mockRoot[:]},
},
AggregationBits: aggBits,
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := util.HydrateAttestation(&ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Root: mockRoot[:]},
},
AggregationBits: aggBits,
})
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
committee, err := helpers.BeaconCommitteeFromState(context.Background(), beaconState, att.Data.Slot, 0)
require.NoError(t, err)
attestingIndices, err := attestation.AttestingIndices(att, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices))
for i, indice := range attestingIndices {
sb, err := signing.ComputeDomainAndSign(beaconState, 0, att.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att.Signature = bls.AggregateSignatures(sigs).Marshal()
block := util.NewBeaconBlockAltair()
block.Block.Body.Attestations = []*ethpb.Attestation{att}
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
wsb, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
_, err = altair.ProcessAttestationsNoVerifySignature(context.Background(), beaconState, wsb.Block())
require.NoError(t, err)
})
t.Run("post-Electra", func(t *testing.T) {
beaconState, privKeys := util.DeterministicGenesisStateElectra(t, 100)
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
committeeBits := primitives.NewAttestationCommitteeBits()
committeeBits.SetBitAt(0, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := util.HydrateAttestationElectra(&ethpb.AttestationElectra{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Root: mockRoot[:]},
},
AggregationBits: aggBits,
CommitteeBits: committeeBits,
})
committee, err := helpers.BeaconCommitteeFromState(context.Background(), beaconState, att.Data.Slot, att.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices, err := attestation.AttestingIndices(att, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices))
for i, indice := range attestingIndices {
sb, err := signing.ComputeDomainAndSign(beaconState, 0, att.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
committee, err := helpers.BeaconCommitteeFromState(context.Background(), beaconState, att.Data.Slot, 0)
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
attestingIndices, err := attestation.AttestingIndices(att, committee)
require.NoError(t, err)
sigs[i] = sig
}
att.Signature = bls.AggregateSignatures(sigs).Marshal()
sigs := make([]bls.Signature, len(attestingIndices))
for i, indice := range attestingIndices {
sb, err := signing.ComputeDomainAndSign(beaconState, 0, att.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att.Signature = bls.AggregateSignatures(sigs).Marshal()
block := util.NewBeaconBlockAltair()
block.Block.Body.Attestations = []*ethpb.Attestation{att}
block := util.NewBeaconBlockElectra()
block.Block.Body.Attestations = []*ethpb.AttestationElectra{att}
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
wsb, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
_, err = altair.ProcessAttestationsNoVerifySignature(context.Background(), beaconState, wsb.Block())
require.NoError(t, err)
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
wsb, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
_, err = altair.ProcessAttestationsNoVerifySignature(context.Background(), beaconState, wsb.Block())
require.NoError(t, err)
})
}
func TestProcessAttestationNoVerify_SourceTargetHead(t *testing.T) {

View File

@@ -154,7 +154,7 @@ func TranslateParticipation(ctx context.Context, state state.BeaconState, atts [
if err != nil {
return nil, err
}
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.Data.Slot, att.Data.CommitteeIndex)
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.GetData().Slot, att.GetData().CommitteeIndex)
if err != nil {
return nil, err
}

View File

@@ -200,23 +200,6 @@ func ProcessAttestationNoVerifySignature(
return beaconState, nil
}
// VerifyAttestationSignature converts and attestation into an indexed attestation and verifies
// the signature in that attestation.
func VerifyAttestationSignature(ctx context.Context, beaconState state.ReadOnlyBeaconState, att ethpb.Att) error {
if err := helpers.ValidateNilAttestation(att); err != nil {
return err
}
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
if err != nil {
return err
}
indexedAtt, err := attestation.ConvertToIndexed(ctx, att, committee)
if err != nil {
return err
}
return VerifyIndexedAttestation(ctx, beaconState, indexedAtt)
}
// VerifyIndexedAttestation determines the validity of an indexed attestation.
//
// Spec pseudocode definition:

View File

@@ -578,53 +578,109 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
}
}
st, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
t.Run("pre-Electra", func(t *testing.T) {
st, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm1, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
},
comm1, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
},
})
domain, err := signing.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
require.NoError(t, err)
root, err := signing.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
},
})
root, err = signing.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
set, err := blocks.AttestationSignatureBatch(ctx, st, []ethpb.Att{att1, att2})
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
})
domain, err := signing.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
require.NoError(t, err)
root, err := signing.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
t.Run("post-Electra", func(t *testing.T) {
st, err := util.NewBeaconStateElectra()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm2, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
},
comm1, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
commBits1 := primitives.NewAttestationCommitteeBits()
commBits1.SetBitAt(0, true)
att1 := util.HydrateAttestationElectra(&ethpb.AttestationElectra{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
CommitteeBits: commBits1,
Data: &ethpb.AttestationData{
Slot: 1,
},
})
domain, err := signing.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
require.NoError(t, err)
root, err := signing.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
commBits2 := primitives.NewAttestationCommitteeBits()
commBits2.SetBitAt(1, true)
att2 := util.HydrateAttestationElectra(&ethpb.AttestationElectra{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
CommitteeBits: commBits2,
Data: &ethpb.AttestationData{
Slot: 1,
},
})
root, err = signing.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
set, err := blocks.AttestationSignatureBatch(ctx, st, []ethpb.Att{att1, att2})
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
})
root, err = signing.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
set, err := blocks.AttestationSignatureBatch(ctx, st, []ethpb.Att{att1, att2})
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
}
func TestRetrieveAttestationSignatureSet_AcrossFork(t *testing.T) {

View File

@@ -297,21 +297,6 @@ func TestFuzzVerifyIndexedAttestationn_10000(t *testing.T) {
}
}
func TestFuzzVerifyAttestation_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethpb.BeaconState{}
attestation := &ethpb.Attestation{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := state_native.InitializeFromProtoUnsafePhase0(state)
require.NoError(t, err)
err = VerifyAttestationSignature(ctx, s, attestation)
_ = err
}
}
func TestFuzzProcessDeposits_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethpb.BeaconState{}

View File

@@ -163,7 +163,42 @@ func NewGenesisBlockForState(ctx context.Context, st state.BeaconState) (interfa
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{ // Deneb difference.
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),
ReceiptsRoot: make([]byte, 32),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, 32),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
Transactions: make([][]byte, 0),
Withdrawals: make([]*enginev1.Withdrawal, 0),
},
BlsToExecutionChanges: make([]*ethpb.SignedBLSToExecutionChange, 0),
BlobKzgCommitments: make([][]byte, 0),
},
},
Signature: params.BeaconConfig().EmptySignature[:],
})
case *ethpb.BeaconStateElectra:
return blocks.NewSignedBeaconBlock(&ethpb.SignedBeaconBlockElectra{
Block: &ethpb.BeaconBlockElectra{
ParentRoot: params.BeaconConfig().ZeroHash[:],
StateRoot: root[:],
Body: &ethpb.BeaconBlockBodyElectra{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayloadElectra{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),

View File

@@ -192,11 +192,11 @@ func createAttestationSignatureBatch(
descs := make([]string, len(atts))
for i, a := range atts {
sigs[i] = a.GetSignature()
c, err := helpers.BeaconCommitteeFromState(ctx, beaconState, a.GetData().Slot, a.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, beaconState, a)
if err != nil {
return nil, err
}
ia, err := attestation.ConvertToIndexed(ctx, a, c)
ia, err := attestation.ConvertToIndexed(ctx, a, committees...)
if err != nil {
return nil, err
}

View File

@@ -470,7 +470,7 @@ func UnslashedAttestingIndices(ctx context.Context, state state.ReadOnlyBeaconSt
seen := make(map[uint64]bool)
for _, att := range atts {
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.Data.Slot, att.Data.CommitteeIndex)
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.GetData().Slot, att.GetData().CommitteeIndex)
if err != nil {
return nil, err
}

View File

@@ -34,6 +34,7 @@ go_library(
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//time:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",

View File

@@ -21,6 +21,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/math"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/time/slots"
)
@@ -58,6 +59,29 @@ func SlotCommitteeCount(activeValidatorCount uint64) uint64 {
return committeesPerSlot
}
// AttestationCommittees returns beacon state committees that reflect attestation's committee indices.
func AttestationCommittees(ctx context.Context, st state.ReadOnlyBeaconState, att ethpb.Att) ([][]primitives.ValidatorIndex, error) {
var committees [][]primitives.ValidatorIndex
if att.Version() >= version.Electra {
committeeIndices := att.CommitteeBitsVal().BitIndices()
committees = make([][]primitives.ValidatorIndex, len(committeeIndices))
for i, ci := range committeeIndices {
committee, err := BeaconCommitteeFromState(ctx, st, att.GetData().Slot, primitives.CommitteeIndex(ci))
if err != nil {
return nil, err
}
committees[i] = committee
}
} else {
committee, err := BeaconCommitteeFromState(ctx, st, att.GetData().Slot, att.GetData().CommitteeIndex)
if err != nil {
return nil, err
}
committees = [][]primitives.ValidatorIndex{committee}
}
return committees, nil
}
// BeaconCommitteeFromState returns the crosslink committee of a given slot and committee index. This
// is a spec implementation where state is used as an argument. In case of state retrieval
// becomes expensive, consider using BeaconCommittee below.

View File

@@ -715,3 +715,37 @@ func TestCommitteeIndices(t *testing.T) {
indices := helpers.CommitteeIndices(bitfield)
assert.DeepEqual(t, []primitives.CommitteeIndex{0, 1, 3}, indices)
}
func TestAttestationCommittees(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().TargetCommitteeSize))
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
}
}
state, err := state_native.InitializeFromProtoPhase0(&ethpb.BeaconState{
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
t.Run("pre-Electra", func(t *testing.T) {
att := &ethpb.Attestation{Data: &ethpb.AttestationData{CommitteeIndex: 0}}
committees, err := helpers.AttestationCommittees(context.Background(), state, att)
require.NoError(t, err)
require.Equal(t, 1, len(committees))
assert.Equal(t, params.BeaconConfig().TargetCommitteeSize, uint64(len(committees[0])))
})
t.Run("post-Electra", func(t *testing.T) {
bits := primitives.NewAttestationCommitteeBits()
bits.SetBitAt(0, true)
bits.SetBitAt(1, true)
att := &ethpb.AttestationElectra{CommitteeBits: bits, Data: &ethpb.AttestationData{}}
committees, err := helpers.AttestationCommittees(context.Background(), state, att)
require.NoError(t, err)
require.Equal(t, 2, len(committees))
assert.Equal(t, params.BeaconConfig().TargetCommitteeSize, uint64(len(committees[0])))
assert.Equal(t, params.BeaconConfig().TargetCommitteeSize, uint64(len(committees[1])))
})
}

View File

@@ -17,9 +17,9 @@ import (
func validAttesterSlashingForValIdx(t *testing.T, beaconState state.BeaconState, privs []bls.SecretKey, valIdx ...uint64) *ethpb.AttesterSlashing {
var slashings []*ethpb.AttesterSlashing
for _, idx := range valIdx {
slashing, err := util.GenerateAttesterSlashingForValidator(beaconState, privs[idx], primitives.ValidatorIndex(idx))
generatedSlashing, err := util.GenerateAttesterSlashingForValidator(beaconState, privs[idx], primitives.ValidatorIndex(idx))
require.NoError(t, err)
slashings = append(slashings, slashing)
slashings = append(slashings, generatedSlashing.(*ethpb.AttesterSlashing))
}
var allSig1 []bls.Signature
var allSig2 []bls.Signature
@@ -78,12 +78,14 @@ func TestPool_InsertAttesterSlashing(t *testing.T) {
pendingSlashings := make([]*PendingAttesterSlashing, 20)
slashings := make([]*ethpb.AttesterSlashing, 20)
for i := 0; i < len(pendingSlashings); i++ {
sl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
generatedSl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
require.NoError(t, err)
pendingSlashings[i] = &PendingAttesterSlashing{
attesterSlashing: sl,
attesterSlashing: generatedSl,
validatorToSlash: primitives.ValidatorIndex(i),
}
sl, ok := generatedSl.(*ethpb.AttesterSlashing)
require.Equal(t, true, ok, "Attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, generatedSl)
slashings[i] = sl
}
require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch))
@@ -303,12 +305,16 @@ func TestPool_InsertAttesterSlashing_SigFailsVerify_ClearPool(t *testing.T) {
pendingSlashings := make([]*PendingAttesterSlashing, 2)
slashings := make([]*ethpb.AttesterSlashing, 2)
for i := 0; i < 2; i++ {
sl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
generatedSl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
require.NoError(t, err)
pendingSlashings[i] = &PendingAttesterSlashing{
attesterSlashing: sl,
attesterSlashing: generatedSl,
validatorToSlash: primitives.ValidatorIndex(i),
}
sl, ok := generatedSl.(*ethpb.AttesterSlashing)
if !ok {
require.Equal(t, true, ok, "Attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, generatedSl)
}
slashings[i] = sl
}
// We mess up the signature of the second slashing.

View File

@@ -66,13 +66,13 @@ func TestServer_SubmitAttesterSlashing(t *testing.T) {
Broadcaster: mb,
}
slashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
generatedSlashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
require.NoError(t, err)
// We want the intersection of the slashing attesting indices
// to be slashed, so we expect validators 2 and 3 to be in the response
// slashed indices.
_, err = bs.SubmitAttesterSlashing(ctx, slashing)
_, err = bs.SubmitAttesterSlashing(ctx, generatedSlashing.(*ethpb.AttesterSlashing))
require.NoError(t, err)
assert.Equal(t, true, mb.BroadcastCalled.Load(), "Expected broadcast to be called when flag is set")
}
@@ -144,7 +144,7 @@ func TestServer_SubmitAttesterSlashing_DontBroadcast(t *testing.T) {
Broadcaster: mb,
}
slashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
generatedSlashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
require.NoError(t, err)
// We want the intersection of the slashing attesting indices
@@ -153,17 +153,17 @@ func TestServer_SubmitAttesterSlashing_DontBroadcast(t *testing.T) {
wanted := &ethpb.SubmitSlashingResponse{
SlashedIndices: []primitives.ValidatorIndex{2},
}
res, err := bs.SubmitAttesterSlashing(ctx, slashing)
res, err := bs.SubmitAttesterSlashing(ctx, generatedSlashing.(*ethpb.AttesterSlashing))
require.NoError(t, err)
if !proto.Equal(wanted, res) {
t.Errorf("Wanted %v, received %v", wanted, res)
}
assert.Equal(t, false, mb.BroadcastCalled.Load(), "Expected broadcast not to be called by default")
slashing, err = util.GenerateAttesterSlashingForValidator(st, privs[5], primitives.ValidatorIndex(5))
generatedSlashing, err = util.GenerateAttesterSlashingForValidator(st, privs[5], primitives.ValidatorIndex(5))
require.NoError(t, err)
// If any of the attesting indices in the slashing object have already
// been slashed, we should fail to insert properly into the attester slashing pool.
_, err = bs.SubmitAttesterSlashing(ctx, slashing)
_, err = bs.SubmitAttesterSlashing(ctx, generatedSlashing.(*ethpb.AttesterSlashing))
assert.NotNil(t, err, "Expected including a attester slashing for an already slashed validator to fail")
}

View File

@@ -753,10 +753,12 @@ func injectSlashings(t *testing.T, st state.BeaconState, keys []bls.SecretKey, s
attSlashings := make([]*ethpb.AttesterSlashing, params.BeaconConfig().MaxAttesterSlashings)
for i := uint64(0); i < params.BeaconConfig().MaxAttesterSlashings; i++ {
attesterSlashing, err := util.GenerateAttesterSlashingForValidator(st, keys[i+params.BeaconConfig().MaxProposerSlashings], primitives.ValidatorIndex(i+params.BeaconConfig().MaxProposerSlashings) /* validator index */)
generatedAttesterSlashing, err := util.GenerateAttesterSlashingForValidator(st, keys[i+params.BeaconConfig().MaxProposerSlashings], primitives.ValidatorIndex(i+params.BeaconConfig().MaxProposerSlashings) /* validator index */)
require.NoError(t, err)
attesterSlashing, ok := generatedAttesterSlashing.(*ethpb.AttesterSlashing)
require.Equal(t, true, ok, "Attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, generatedAttesterSlashing)
attSlashings[i] = attesterSlashing
err = server.SlashingsPool.InsertAttesterSlashing(context.Background(), st, attesterSlashing)
err = server.SlashingsPool.InsertAttesterSlashing(context.Background(), st, generatedAttesterSlashing.(*ethpb.AttesterSlashing))
require.NoError(t, err)
}
return proposerSlashings, attSlashings

View File

@@ -170,7 +170,7 @@ func TestSubscribe_ReceivesAttesterSlashing(t *testing.T) {
1, /* validator index */
)
require.NoError(t, err, "Error generating attester slashing")
err = r.cfg.beaconDB.SaveState(ctx, beaconState, bytesutil.ToBytes32(attesterSlashing.Attestation_1.Data.BeaconBlockRoot))
err = r.cfg.beaconDB.SaveState(ctx, beaconState, bytesutil.ToBytes32(attesterSlashing.FirstAttestation().GetData().BeaconBlockRoot))
require.NoError(t, err)
p2pService.ReceivePubSub(topic, attesterSlashing)

View File

@@ -3,6 +3,8 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"committee_bits_mainnet.go",
"committee_bits_minimal.go", # keep
"committee_index.go",
"domain.go",
"epoch.go",
@@ -20,6 +22,7 @@ go_library(
deps = [
"//math:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
],
)

View File

@@ -0,0 +1,9 @@
//go:build !minimal
package primitives
import "github.com/prysmaticlabs/go-bitfield"
func NewAttestationCommitteeBits() bitfield.Bitvector64 {
return bitfield.NewBitvector64()
}

View File

@@ -0,0 +1,9 @@
//go:build minimal
package primitives
import "github.com/prysmaticlabs/go-bitfield"
func NewAttestationCommitteeBits() bitfield.Bitvector4 {
return bitfield.NewBitvector4()
}

View File

@@ -17,6 +17,7 @@ go_library(
"deneb_state.go",
"deposits.go",
"electra.go",
"electra_block.go",
"electra_state.go",
"helpers.go",
"merge.go",

View File

@@ -345,19 +345,35 @@ func GenerateFullBlockAltair(
numToGen = conf.NumAttesterSlashings
var aSlashings []*ethpb.AttesterSlashing
if numToGen > 0 {
aSlashings, err = generateAttesterSlashings(bState, privs, numToGen)
generated, err := generateAttesterSlashings(bState, privs, numToGen)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attester slashings:", numToGen)
}
aSlashings = make([]*ethpb.AttesterSlashing, len(generated))
var ok bool
for i, s := range generated {
aSlashings[i], ok = s.(*ethpb.AttesterSlashing)
if !ok {
return nil, fmt.Errorf("attester slashing has wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, s)
}
}
}
numToGen = conf.NumAttestations
var atts []*ethpb.Attestation
if numToGen > 0 {
atts, err = GenerateAttestations(bState, privs, numToGen, slot, false)
generatedAtts, err := GenerateAttestations(bState, privs, numToGen, slot, false)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attestations:", numToGen)
}
atts = make([]*ethpb.Attestation, len(generatedAtts))
var ok bool
for i, a := range generatedAtts {
atts[i], ok = a.(*ethpb.Attestation)
if !ok {
return nil, fmt.Errorf("attestation has the wrong type (expected %T, got %T)", &ethpb.Attestation{}, a)
}
}
}
numToGen = conf.NumDeposits

View File

@@ -2,7 +2,6 @@ package util
import (
"context"
"errors"
"fmt"
"math"
@@ -48,10 +47,8 @@ func NewAttestation() *ethpb.Attestation {
// for the same data with their aggregation bits split uniformly.
//
// If you request 4 attestations, but there are 8 committees, you will get 4 fully aggregated attestations.
func GenerateAttestations(
bState state.BeaconState, privs []bls.SecretKey, numToGen uint64, slot primitives.Slot, randomRoot bool,
) ([]*ethpb.Attestation, error) {
var attestations []*ethpb.Attestation
func GenerateAttestations(bState state.BeaconState, privs []bls.SecretKey, numToGen uint64, slot primitives.Slot, randomRoot bool) ([]ethpb.Att, error) { // nolint:gocognit
var attestations []ethpb.Att
generateHeadState := false
bState = bState.Copy()
if slot > bState.Slot() {
@@ -108,8 +105,28 @@ func GenerateAttestations(
return nil, err
}
headState = genState
case version.Deneb:
pbState, err := state_native.ProtobufBeaconStateDeneb(bState.ToProto())
if err != nil {
return nil, err
}
genState, err := state_native.InitializeFromProtoUnsafeDeneb(pbState)
if err != nil {
return nil, err
}
headState = genState
case version.Electra:
pbState, err := state_native.ProtobufBeaconStateElectra(bState.ToProto())
if err != nil {
return nil, err
}
genState, err := state_native.InitializeFromProtoUnsafeElectra(pbState)
if err != nil {
return nil, err
}
headState = genState
default:
return nil, errors.New("state type isn't supported")
return nil, fmt.Errorf("state version %s isn't supported", version.String(bState.Version()))
}
headState, err = transition.ProcessSlots(context.Background(), headState, slot+1)
@@ -180,9 +197,14 @@ func GenerateAttestations(
return nil, err
}
ci := c
if bState.Version() >= version.Electra {
// committee index must be 0 post-Electra
ci = 0
}
attData := &ethpb.AttestationData{
Slot: slot,
CommitteeIndex: c,
CommitteeIndex: ci,
BeaconBlockRoot: headRoot,
Source: bState.CurrentJustifiedCheckpoint(),
Target: &ethpb.Checkpoint{
@@ -211,10 +233,22 @@ func GenerateAttestations(
continue
}
att := &ethpb.Attestation{
Data: attData,
AggregationBits: aggregationBits,
Signature: bls.AggregateSignatures(sigs).Marshal(),
var att ethpb.Att
if bState.Version() >= version.Electra {
cb := primitives.NewAttestationCommitteeBits()
cb.SetBitAt(uint64(c), true)
att = &ethpb.AttestationElectra{
Data: attData,
CommitteeBits: cb,
AggregationBits: aggregationBits,
Signature: bls.AggregateSignatures(sigs).Marshal(),
}
} else {
att = &ethpb.Attestation{
Data: attData,
AggregationBits: aggregationBits,
Signature: bls.AggregateSignatures(sigs).Marshal(),
}
}
attestations = append(attestations, att)
}
@@ -238,6 +272,25 @@ func HydrateAttestation(a *ethpb.Attestation) *ethpb.Attestation {
return a
}
// HydrateAttestationElectra hydrates an attestation object with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateAttestationElectra(a *ethpb.AttestationElectra) *ethpb.AttestationElectra {
if a.Signature == nil {
a.Signature = make([]byte, 96)
}
if a.AggregationBits == nil {
a.AggregationBits = make([]byte, 1)
}
if a.CommitteeBits == nil {
a.CommitteeBits = primitives.NewAttestationCommitteeBits()
}
if a.Data == nil {
a.Data = &ethpb.AttestationData{}
}
a.Data = HydrateAttestationData(a.Data)
return a
}
// HydrateV1Attestation hydrates a v1 attestation object with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateV1Attestation(a *attv1.Attestation) *attv1.Attestation {

View File

@@ -56,19 +56,35 @@ func GenerateFullBlockBellatrix(
numToGen = conf.NumAttesterSlashings
var aSlashings []*ethpb.AttesterSlashing
if numToGen > 0 {
aSlashings, err = generateAttesterSlashings(bState, privs, numToGen)
generated, err := generateAttesterSlashings(bState, privs, numToGen)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attester slashings:", numToGen)
}
aSlashings = make([]*ethpb.AttesterSlashing, len(generated))
var ok bool
for i, s := range generated {
aSlashings[i], ok = s.(*ethpb.AttesterSlashing)
if !ok {
return nil, fmt.Errorf("attester slashing has wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, s)
}
}
}
numToGen = conf.NumAttestations
var atts []*ethpb.Attestation
if numToGen > 0 {
atts, err = GenerateAttestations(bState, privs, numToGen, slot, false)
generatedAtts, err := GenerateAttestations(bState, privs, numToGen, slot, false)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attestations:", numToGen)
}
atts = make([]*ethpb.Attestation, len(generatedAtts))
var ok bool
for i, a := range generatedAtts {
atts[i], ok = a.(*ethpb.Attestation)
if !ok {
return nil, fmt.Errorf("attestation has the wrong type (expected %T, got %T)", &ethpb.Attestation{}, a)
}
}
}
numToGen = conf.NumDeposits

View File

@@ -22,6 +22,7 @@ import (
v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/assertions"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
@@ -109,19 +110,35 @@ func GenerateFullBlock(
numToGen = conf.NumAttesterSlashings
var aSlashings []*ethpb.AttesterSlashing
if numToGen > 0 {
aSlashings, err = generateAttesterSlashings(bState, privs, numToGen)
generated, err := generateAttesterSlashings(bState, privs, numToGen)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attester slashings:", numToGen)
}
aSlashings = make([]*ethpb.AttesterSlashing, len(generated))
var ok bool
for i, s := range generated {
aSlashings[i], ok = s.(*ethpb.AttesterSlashing)
if !ok {
return nil, fmt.Errorf("attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, s)
}
}
}
numToGen = conf.NumAttestations
var atts []*ethpb.Attestation
if numToGen > 0 {
atts, err = GenerateAttestations(bState, privs, numToGen, slot, false)
generatedAtts, err := GenerateAttestations(bState, privs, numToGen, slot, false)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attestations:", numToGen)
}
atts = make([]*ethpb.Attestation, len(generatedAtts))
var ok bool
for i, a := range generatedAtts {
atts[i], ok = a.(*ethpb.Attestation)
if !ok {
return nil, fmt.Errorf("attestation has the wrong type (expected %T, got %T)", &ethpb.Attestation{}, a)
}
}
}
numToGen = conf.NumDeposits
@@ -265,9 +282,59 @@ func GenerateAttesterSlashingForValidator(
bState state.BeaconState,
priv bls.SecretKey,
idx primitives.ValidatorIndex,
) (*ethpb.AttesterSlashing, error) {
) (ethpb.AttSlashing, error) {
currentEpoch := time.CurrentEpoch(bState)
if bState.Version() >= version.Electra {
att1 := &ethpb.IndexedAttestationElectra{
Data: &ethpb.AttestationData{
Slot: bState.Slot(),
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, fieldparams.RootLength),
Target: &ethpb.Checkpoint{
Epoch: currentEpoch,
Root: params.BeaconConfig().ZeroHash[:],
},
Source: &ethpb.Checkpoint{
Epoch: currentEpoch + 1,
Root: params.BeaconConfig().ZeroHash[:],
},
},
AttestingIndices: []uint64{uint64(idx)},
}
var err error
att1.Signature, err = signing.ComputeDomainAndSign(bState, currentEpoch, att1.Data, params.BeaconConfig().DomainBeaconAttester, priv)
if err != nil {
return nil, err
}
att2 := &ethpb.IndexedAttestationElectra{
Data: &ethpb.AttestationData{
Slot: bState.Slot(),
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, fieldparams.RootLength),
Target: &ethpb.Checkpoint{
Epoch: currentEpoch,
Root: params.BeaconConfig().ZeroHash[:],
},
Source: &ethpb.Checkpoint{
Epoch: currentEpoch,
Root: params.BeaconConfig().ZeroHash[:],
},
},
AttestingIndices: []uint64{uint64(idx)},
}
att2.Signature, err = signing.ComputeDomainAndSign(bState, currentEpoch, att2.Data, params.BeaconConfig().DomainBeaconAttester, priv)
if err != nil {
return nil, err
}
return &ethpb.AttesterSlashingElectra{
Attestation_1: att1,
Attestation_2: att2,
}, nil
}
att1 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Slot: bState.Slot(),
@@ -321,8 +388,8 @@ func generateAttesterSlashings(
bState state.BeaconState,
privs []bls.SecretKey,
numSlashings uint64,
) ([]*ethpb.AttesterSlashing, error) {
attesterSlashings := make([]*ethpb.AttesterSlashing, numSlashings)
) ([]ethpb.AttSlashing, error) {
attesterSlashings := make([]ethpb.AttSlashing, numSlashings)
randGen := rand.NewDeterministicGenerator()
for i := uint64(0); i < numSlashings; i++ {
committeeIndex := randGen.Uint64() % helpers.SlotCommitteeCount(uint64(bState.NumValidators()))

View File

@@ -24,7 +24,6 @@ import (
// GenerateFullBlockCapella generates a fully valid Capella block with the requested parameters.
// Use BlockGenConfig to declare the conditions you would like the block generated under.
// This function modifies the passed state as follows:
func GenerateFullBlockCapella(
bState state.BeaconState,
privs []bls.SecretKey,
@@ -55,19 +54,35 @@ func GenerateFullBlockCapella(
numToGen = conf.NumAttesterSlashings
var aSlashings []*ethpb.AttesterSlashing
if numToGen > 0 {
aSlashings, err = generateAttesterSlashings(bState, privs, numToGen)
generated, err := generateAttesterSlashings(bState, privs, numToGen)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attester slashings:", numToGen)
}
aSlashings = make([]*ethpb.AttesterSlashing, len(generated))
var ok bool
for i, s := range generated {
aSlashings[i], ok = s.(*ethpb.AttesterSlashing)
if !ok {
return nil, fmt.Errorf("attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, s)
}
}
}
numToGen = conf.NumAttestations
var atts []*ethpb.Attestation
if numToGen > 0 {
atts, err = GenerateAttestations(bState, privs, numToGen, slot, false)
generatedAtts, err := GenerateAttestations(bState, privs, numToGen, slot, false)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attestations:", numToGen)
}
atts = make([]*ethpb.Attestation, len(generatedAtts))
var ok bool
for i, a := range generatedAtts {
atts[i], ok = a.(*ethpb.Attestation)
if !ok {
return nil, fmt.Errorf("attestation has the wrong type (expected %T, got %T)", &ethpb.Attestation{}, a)
}
}
}
numToGen = conf.NumDeposits

View File

@@ -0,0 +1,223 @@
package util
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
v1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/time/slots"
)
// GenerateFullBlockElectra generates a fully valid Electra block with the requested parameters.
// Use BlockGenConfig to declare the conditions you would like the block generated under.
// This function modifies the passed state as follows:
func GenerateFullBlockElectra(
bState state.BeaconState,
privs []bls.SecretKey,
conf *BlockGenConfig,
slot primitives.Slot,
) (*ethpb.SignedBeaconBlockElectra, error) {
ctx := context.Background()
currentSlot := bState.Slot()
if currentSlot > slot {
return nil, fmt.Errorf("current slot in state is larger than given slot. %d > %d", currentSlot, slot)
}
bState = bState.Copy()
if conf == nil {
conf = &BlockGenConfig{}
}
var err error
var pSlashings []*ethpb.ProposerSlashing
numToGen := conf.NumProposerSlashings
if numToGen > 0 {
pSlashings, err = generateProposerSlashings(bState, privs, numToGen)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d proposer slashings:", numToGen)
}
}
numToGen = conf.NumAttesterSlashings
var aSlashings []*ethpb.AttesterSlashingElectra
if numToGen > 0 {
generated, err := generateAttesterSlashings(bState, privs, numToGen)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attester slashings:", numToGen)
}
aSlashings = make([]*ethpb.AttesterSlashingElectra, len(generated))
var ok bool
for i, s := range generated {
aSlashings[i], ok = s.(*ethpb.AttesterSlashingElectra)
if !ok {
return nil, fmt.Errorf("attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashingElectra{}, s)
}
}
}
numToGen = conf.NumAttestations
var atts []*ethpb.AttestationElectra
if numToGen > 0 {
generatedAtts, err := GenerateAttestations(bState, privs, numToGen, slot, false)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attestations:", numToGen)
}
atts = make([]*ethpb.AttestationElectra, len(generatedAtts))
var ok bool
for i, a := range generatedAtts {
atts[i], ok = a.(*ethpb.AttestationElectra)
if !ok {
return nil, fmt.Errorf("attestation has the wrong type (expected %T, got %T)", &ethpb.AttestationElectra{}, a)
}
}
}
numToGen = conf.NumDeposits
var newDeposits []*ethpb.Deposit
eth1Data := bState.Eth1Data()
if numToGen > 0 {
newDeposits, eth1Data, err = generateDepositsAndEth1Data(bState, numToGen)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d deposits:", numToGen)
}
}
numToGen = conf.NumVoluntaryExits
var exits []*ethpb.SignedVoluntaryExit
if numToGen > 0 {
exits, err = generateVoluntaryExits(bState, privs, numToGen)
if err != nil {
return nil, errors.Wrapf(err, "failed generating %d attester slashings:", numToGen)
}
}
numToGen = conf.NumTransactions
newTransactions := make([][]byte, numToGen)
for i := uint64(0); i < numToGen; i++ {
newTransactions[i] = bytesutil.Uint64ToBytesLittleEndian(i)
}
newWithdrawals := make([]*v1.Withdrawal, 0)
random, err := helpers.RandaoMix(bState, time.CurrentEpoch(bState))
if err != nil {
return nil, errors.Wrap(err, "could not process randao mix")
}
timestamp, err := slots.ToTime(bState.GenesisTime(), slot)
if err != nil {
return nil, errors.Wrap(err, "could not get current timestamp")
}
stCopy := bState.Copy()
stCopy, err = transition.ProcessSlots(context.Background(), stCopy, slot)
if err != nil {
return nil, err
}
parentExecution, err := stCopy.LatestExecutionPayloadHeader()
if err != nil {
return nil, err
}
blockHash := indexToHash(uint64(slot))
newExecutionPayloadCapella := &v1.ExecutionPayloadElectra{
ParentHash: parentExecution.BlockHash(),
FeeRecipient: make([]byte, 20),
StateRoot: params.BeaconConfig().ZeroHash[:],
ReceiptsRoot: params.BeaconConfig().ZeroHash[:],
LogsBloom: make([]byte, 256),
PrevRandao: random,
BlockNumber: uint64(slot),
ExtraData: params.BeaconConfig().ZeroHash[:],
BaseFeePerGas: params.BeaconConfig().ZeroHash[:],
BlockHash: blockHash[:],
Timestamp: uint64(timestamp.Unix()),
Transactions: newTransactions,
Withdrawals: newWithdrawals,
}
var syncCommitteeBits []byte
currSize := new(ethpb.SyncAggregate).SyncCommitteeBits.Len()
switch currSize {
case 512:
syncCommitteeBits = bitfield.NewBitvector512()
case 32:
syncCommitteeBits = bitfield.NewBitvector32()
default:
return nil, errors.New("invalid bit vector size")
}
newSyncAggregate := &ethpb.SyncAggregate{
SyncCommitteeBits: syncCommitteeBits,
SyncCommitteeSignature: append([]byte{0xC0}, make([]byte, 95)...),
}
newHeader := bState.LatestBlockHeader()
prevStateRoot, err := bState.HashTreeRoot(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not hash state")
}
newHeader.StateRoot = prevStateRoot[:]
parentRoot, err := newHeader.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "could not hash the new header")
}
if slot == currentSlot {
slot = currentSlot + 1
}
reveal, err := RandaoReveal(stCopy, time.CurrentEpoch(stCopy), privs)
if err != nil {
return nil, errors.Wrap(err, "could not compute randao reveal")
}
idx, err := helpers.BeaconProposerIndex(ctx, stCopy)
if err != nil {
return nil, errors.Wrap(err, "could not compute beacon proposer index")
}
changes := make([]*ethpb.SignedBLSToExecutionChange, conf.NumBLSChanges)
for i := uint64(0); i < conf.NumBLSChanges; i++ {
changes[i], err = GenerateBLSToExecutionChange(bState, privs[i+1], primitives.ValidatorIndex(i))
if err != nil {
return nil, err
}
}
block := &ethpb.BeaconBlockElectra{
Slot: slot,
ParentRoot: parentRoot[:],
ProposerIndex: idx,
Body: &ethpb.BeaconBlockBodyElectra{
Eth1Data: eth1Data,
RandaoReveal: reveal,
ProposerSlashings: pSlashings,
AttesterSlashings: aSlashings,
Attestations: atts,
VoluntaryExits: exits,
Deposits: newDeposits,
Graffiti: make([]byte, fieldparams.RootLength),
SyncAggregate: newSyncAggregate,
ExecutionPayload: newExecutionPayloadCapella,
BlsToExecutionChanges: changes,
},
}
// The fork can change after processing the state
signature, err := BlockSignature(bState, block, privs)
if err != nil {
return nil, errors.Wrap(err, "could not compute block signature")
}
return &ethpb.SignedBeaconBlockElectra{Block: block, Signature: signature.Marshal()}, nil
}

View File

@@ -3,6 +3,7 @@ package util
import (
"context"
"encoding/binary"
"fmt"
"testing"
"github.com/pkg/errors"
@@ -54,8 +55,12 @@ func BlockSignature(
wsb, err = blocks.NewSignedBeaconBlock(&ethpb.SignedBeaconBlockBellatrix{Block: b})
case *ethpb.BeaconBlockCapella:
wsb, err = blocks.NewSignedBeaconBlock(&ethpb.SignedBeaconBlockCapella{Block: b})
case *ethpb.BeaconBlockDeneb:
wsb, err = blocks.NewSignedBeaconBlock(&ethpb.SignedBeaconBlockDeneb{Block: b})
case *ethpb.BeaconBlockElectra:
wsb, err = blocks.NewSignedBeaconBlock(&ethpb.SignedBeaconBlockElectra{Block: b})
default:
return nil, errors.New("unsupported block type")
return nil, fmt.Errorf("unsupported block type %T", b)
}
if err != nil {
return nil, errors.Wrap(err, "could not wrap block")
@@ -74,6 +79,10 @@ func BlockSignature(
b.StateRoot = s[:]
case *ethpb.BeaconBlockCapella:
b.StateRoot = s[:]
case *ethpb.BeaconBlockDeneb:
b.StateRoot = s[:]
case *ethpb.BeaconBlockElectra:
b.StateRoot = s[:]
}
// Temporarily increasing the beacon state slot here since BeaconProposerIndex is a
@@ -88,6 +97,10 @@ func BlockSignature(
blockSlot = b.Slot
case *ethpb.BeaconBlockCapella:
blockSlot = b.Slot
case *ethpb.BeaconBlockDeneb:
blockSlot = b.Slot
case *ethpb.BeaconBlockElectra:
blockSlot = b.Slot
}
// process slots to get the right fork
@@ -111,6 +124,10 @@ func BlockSignature(
blockRoot, err = signing.ComputeSigningRoot(b, domain)
case *ethpb.BeaconBlockCapella:
blockRoot, err = signing.ComputeSigningRoot(b, domain)
case *ethpb.BeaconBlockDeneb:
blockRoot, err = signing.ComputeSigningRoot(b, domain)
case *ethpb.BeaconBlockElectra:
blockRoot, err = signing.ComputeSigningRoot(b, domain)
}
if err != nil {
return nil, err

View File

@@ -122,10 +122,18 @@ func generateMarshalledFullStateAndBlock() error {
var atts []*ethpb.Attestation
for i := slotOffset + 1; i < slotsPerEpoch+slotOffset; i++ {
attsForSlot, err := util.GenerateAttestations(beaconState, privs, attConfig.NumAttestations, i, false)
generatedAttsForSlot, err := util.GenerateAttestations(beaconState, privs, attConfig.NumAttestations, i, false)
if err != nil {
return err
}
attsForSlot := make([]*ethpb.Attestation, len(generatedAttsForSlot))
for j, att := range generatedAttsForSlot {
a, ok := att.(*ethpb.Attestation)
if !ok {
return errors.New("attestation is not of type *ethpb.Attestation")
}
attsForSlot[j] = a
}
atts = append(atts, attsForSlot...)
}