mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
Compare commits
9 Commits
event-stru
...
fix_deadli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa06ce5e0e | ||
|
|
e5d7888e5c | ||
|
|
f7eddedd1d | ||
|
|
7887ebbc4a | ||
|
|
4ea3699c51 | ||
|
|
06a5a16007 | ||
|
|
fb2eeb5ce9 | ||
|
|
b526d99a55 | ||
|
|
1b13520270 |
@@ -53,6 +53,7 @@ type ChainService struct {
|
||||
InitSyncBlockRoots map[[32]byte]bool
|
||||
DB db.Database
|
||||
State state.BeaconState
|
||||
HeadStateErr error
|
||||
Block interfaces.ReadOnlySignedBeaconBlock
|
||||
VerifyBlkDescendantErr error
|
||||
stateNotifier statefeed.Notifier
|
||||
@@ -364,6 +365,9 @@ func (s *ChainService) HeadState(context.Context) (state.BeaconState, error) {
|
||||
|
||||
// HeadStateReadOnly mocks HeadStateReadOnly method in chain service.
|
||||
func (s *ChainService) HeadStateReadOnly(context.Context) (state.ReadOnlyBeaconState, error) {
|
||||
if s.HeadStateErr != nil {
|
||||
return nil, s.HeadStateErr
|
||||
}
|
||||
return s.State, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// ErrCouldNotVerifyBlockHeader is returned when a block header's signature cannot be verified.
|
||||
var ErrCouldNotVerifyBlockHeader = errors.New("could not verify beacon block header")
|
||||
|
||||
type slashValidatorFunc func(
|
||||
ctx context.Context,
|
||||
st state.BeaconState,
|
||||
@@ -114,7 +117,7 @@ func VerifyProposerSlashing(
|
||||
for _, header := range headers {
|
||||
if err := signing.ComputeDomainVerifySigningRoot(beaconState, pIdx, slots.ToEpoch(hSlot),
|
||||
header.Header, params.BeaconConfig().DomainBeaconProposer, header.Signature); err != nil {
|
||||
return errors.Wrap(err, "could not verify beacon block header")
|
||||
return errors.Wrap(ErrCouldNotVerifyBlockHeader, err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -105,7 +105,8 @@ func (l *listenerWrapper) RandomNodes() enode.Iterator {
|
||||
func (l *listenerWrapper) Ping(node *enode.Node) error {
|
||||
l.mu.RLock()
|
||||
defer l.mu.RUnlock()
|
||||
return l.listener.Ping(node)
|
||||
_, err := l.listener.Ping(node)
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *listenerWrapper) RequestENR(node *enode.Node) (*enode.Node, error) {
|
||||
|
||||
@@ -162,9 +162,9 @@ func (b *BlobSidecarsByRootReq) MarshalSSZ() ([]byte, error) {
|
||||
// BlobSidecarsByRootReq value.
|
||||
func (b *BlobSidecarsByRootReq) UnmarshalSSZ(buf []byte) error {
|
||||
bufLen := len(buf)
|
||||
maxLength := int(params.BeaconConfig().MaxRequestBlobSidecars) * blobIdSize
|
||||
maxLength := int(params.BeaconConfig().MaxRequestBlobSidecarsElectra) * blobIdSize
|
||||
if bufLen > maxLength {
|
||||
return errors.Errorf("expected buffer with length of up to %d but received length %d", maxLength, bufLen)
|
||||
return errors.Wrapf(ssz.ErrIncorrectListSize, "expected buffer with length of up to %d but received length %d", maxLength, bufLen)
|
||||
}
|
||||
if bufLen%blobIdSize != 0 {
|
||||
return errors.Wrapf(ssz.ErrIncorrectByteSize, "size=%d", bufLen)
|
||||
|
||||
@@ -43,6 +43,15 @@ func TestBlobSidecarsByRootReq_MarshalSSZ(t *testing.T) {
|
||||
name: "10 item list",
|
||||
ids: generateBlobIdentifiers(10),
|
||||
},
|
||||
{
|
||||
name: "max list",
|
||||
ids: generateBlobIdentifiers(int(params.BeaconConfig().MaxRequestBlobSidecarsElectra)),
|
||||
},
|
||||
{
|
||||
name: "beyond max list",
|
||||
ids: generateBlobIdentifiers(int(params.BeaconConfig().MaxRequestBlobSidecarsElectra) + 1),
|
||||
unmarshalErr: ssz.ErrIncorrectListSize,
|
||||
},
|
||||
{
|
||||
name: "wonky unmarshal size",
|
||||
ids: generateBlobIdentifiers(10),
|
||||
|
||||
@@ -82,7 +82,7 @@ func TestProposeAttestation(t *testing.T) {
|
||||
config := params.BeaconConfig()
|
||||
config.ElectraForkEpoch = 0
|
||||
params.OverrideBeaconConfig(config)
|
||||
|
||||
|
||||
state, err := util.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, state.SetSlot(params.BeaconConfig().SlotsPerEpoch+1))
|
||||
|
||||
@@ -211,6 +211,7 @@ go_test(
|
||||
"//beacon-chain/operations/attestations:go_default_library",
|
||||
"//beacon-chain/operations/blstoexec:go_default_library",
|
||||
"//beacon-chain/operations/slashings:go_default_library",
|
||||
"//beacon-chain/operations/slashings/mock:go_default_library",
|
||||
"//beacon-chain/p2p:go_default_library",
|
||||
"//beacon-chain/p2p/encoder:go_default_library",
|
||||
"//beacon-chain/p2p/peers:go_default_library",
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/OffchainLabs/prysm/v6/encoding/bytesutil"
|
||||
"github.com/OffchainLabs/prysm/v6/monitoring/tracing"
|
||||
"github.com/OffchainLabs/prysm/v6/monitoring/tracing/trace"
|
||||
ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
|
||||
"github.com/OffchainLabs/prysm/v6/runtime/version"
|
||||
prysmTime "github.com/OffchainLabs/prysm/v6/time"
|
||||
"github.com/OffchainLabs/prysm/v6/time/slots"
|
||||
@@ -31,8 +32,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrOptimisticParent = errors.New("parent of the block is optimistic")
|
||||
errRejectCommitmentLen = errors.New("[REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer")
|
||||
ErrOptimisticParent = errors.New("parent of the block is optimistic")
|
||||
errRejectCommitmentLen = errors.New("[REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer")
|
||||
ErrSlashingSignatureFailure = errors.New("proposer slashing signature verification failed")
|
||||
)
|
||||
|
||||
// validateBeaconBlockPubSub checks that the incoming block has a valid BLS signature.
|
||||
@@ -109,6 +111,16 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms
|
||||
|
||||
// Verify the block is the first block received for the proposer for the slot.
|
||||
if s.hasSeenBlockIndexSlot(blk.Block().Slot(), blk.Block().ProposerIndex()) {
|
||||
// Attempt to detect and broadcast equivocation before ignoring
|
||||
err = s.detectAndBroadcastEquivocation(ctx, blk)
|
||||
if err != nil {
|
||||
// If signature verification fails, reject the block
|
||||
if errors.Is(err, ErrSlashingSignatureFailure) {
|
||||
return pubsub.ValidationReject, err
|
||||
}
|
||||
// In case there is some other error log but don't reject
|
||||
log.WithError(err).Debug("Could not detect/broadcast equivocation")
|
||||
}
|
||||
return pubsub.ValidationIgnore, nil
|
||||
}
|
||||
|
||||
@@ -469,3 +481,74 @@ func getBlockFields(b interfaces.ReadOnlySignedBeaconBlock) logrus.Fields {
|
||||
"version": b.Block().Version(),
|
||||
}
|
||||
}
|
||||
|
||||
// detectAndBroadcastEquivocation checks if the given block is an equivocating block by comparing it with
|
||||
// the head block. If the blocks are from the same slot and proposer but have different signatures,
|
||||
// it creates and broadcasts a proposer slashing object after verification.
|
||||
func (s *Service) detectAndBroadcastEquivocation(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) error {
|
||||
slot := blk.Block().Slot()
|
||||
proposerIndex := blk.Block().ProposerIndex()
|
||||
|
||||
// Get head block for comparison
|
||||
headBlock, err := s.cfg.chain.HeadBlock(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get head block")
|
||||
}
|
||||
|
||||
// Only proceed if this block is from same slot and proposer as head
|
||||
if headBlock.Block().Slot() != slot || headBlock.Block().ProposerIndex() != proposerIndex {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compare signatures
|
||||
sig1 := blk.Signature()
|
||||
sig2 := headBlock.Signature()
|
||||
|
||||
// If signatures match, these are the same block
|
||||
if sig1 == sig2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Extract headers for slashing
|
||||
header1, err := blk.Header()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get header from new block")
|
||||
}
|
||||
header2, err := headBlock.Header()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get header from head block")
|
||||
}
|
||||
|
||||
slashing := ðpb.ProposerSlashing{
|
||||
Header_1: header1,
|
||||
Header_2: header2,
|
||||
}
|
||||
|
||||
// Get state for verification
|
||||
headState, err := s.cfg.chain.HeadStateReadOnly(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get head state")
|
||||
}
|
||||
|
||||
// Verify the slashing against current state
|
||||
if err := blocks.VerifyProposerSlashing(headState, slashing); err != nil {
|
||||
if errors.Is(err, blocks.ErrCouldNotVerifyBlockHeader) {
|
||||
return errors.Wrap(ErrSlashingSignatureFailure, err.Error())
|
||||
}
|
||||
return errors.Wrap(err, "could not verify proposer slashing")
|
||||
}
|
||||
|
||||
// Broadcast if verification passes
|
||||
if !features.Get().DisableBroadcastSlashings {
|
||||
if err := s.cfg.p2p.Broadcast(ctx, slashing); err != nil {
|
||||
return errors.Wrap(err, "could not broadcast slashing object")
|
||||
}
|
||||
}
|
||||
|
||||
// Insert into slashing pool
|
||||
if err := s.cfg.slashingPool.InsertProposerSlashing(ctx, headState, slashing); err != nil {
|
||||
return errors.Wrap(err, "could not insert proposer slashing into pool")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
dbtest "github.com/OffchainLabs/prysm/v6/beacon-chain/db/testing"
|
||||
doublylinkedtree "github.com/OffchainLabs/prysm/v6/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
"github.com/OffchainLabs/prysm/v6/beacon-chain/operations/attestations"
|
||||
slashingsmock "github.com/OffchainLabs/prysm/v6/beacon-chain/operations/slashings/mock"
|
||||
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p"
|
||||
p2ptest "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/testing"
|
||||
"github.com/OffchainLabs/prysm/v6/beacon-chain/startup"
|
||||
@@ -713,8 +714,21 @@ func TestValidateBeaconBlockPubSub_SeenProposerSlot(t *testing.T) {
|
||||
msg.Signature, err = signing.ComputeDomainAndSign(beaconState, 0, msg.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx])
|
||||
require.NoError(t, err)
|
||||
|
||||
chainService := &mock.ChainService{Genesis: time.Unix(time.Now().Unix()-int64(params.BeaconConfig().SecondsPerSlot), 0),
|
||||
State: beaconState,
|
||||
// Create a clone of the same block (same signature, not an equivocation)
|
||||
msgClone := util.NewBeaconBlock()
|
||||
msgClone.Block.Slot = 1
|
||||
msgClone.Block.ProposerIndex = proposerIdx
|
||||
msgClone.Block.ParentRoot = bRoot[:]
|
||||
msgClone.Signature = msg.Signature // Use the same signature
|
||||
|
||||
signedBlock, err := blocks.NewSignedBeaconBlock(msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
slashingPool := &slashingsmock.PoolMock{}
|
||||
chainService := &mock.ChainService{
|
||||
Genesis: time.Unix(time.Now().Unix()-int64(params.BeaconConfig().SecondsPerSlot), 0),
|
||||
State: beaconState,
|
||||
Block: signedBlock, // Set the first block as the head block
|
||||
FinalizedCheckPoint: ðpb.Checkpoint{
|
||||
Epoch: 0,
|
||||
Root: make([]byte, 32),
|
||||
@@ -728,6 +742,7 @@ func TestValidateBeaconBlockPubSub_SeenProposerSlot(t *testing.T) {
|
||||
chain: chainService,
|
||||
clock: startup.NewClock(chainService.Genesis, chainService.ValidatorsRoot),
|
||||
blockNotifier: chainService.BlockNotifier(),
|
||||
slashingPool: slashingPool,
|
||||
},
|
||||
seenBlockCache: lruwrpr.New(10),
|
||||
badBlockCache: lruwrpr.New(10),
|
||||
@@ -735,10 +750,15 @@ func TestValidateBeaconBlockPubSub_SeenProposerSlot(t *testing.T) {
|
||||
seenPendingBlocks: make(map[[32]byte]bool),
|
||||
}
|
||||
|
||||
// Mark the proposer/slot as seen
|
||||
r.setSeenBlockIndexSlot(msg.Block.Slot, msg.Block.ProposerIndex)
|
||||
time.Sleep(10 * time.Millisecond) // Wait for cached value to pass through buffers
|
||||
|
||||
// Prepare and validate the second message (clone)
|
||||
buf := new(bytes.Buffer)
|
||||
_, err = p.Encoding().EncodeGossip(buf, msg)
|
||||
_, err = p.Encoding().EncodeGossip(buf, msgClone)
|
||||
require.NoError(t, err)
|
||||
topic := p2p.GossipTypeMapping[reflect.TypeOf(msg)]
|
||||
topic := p2p.GossipTypeMapping[reflect.TypeOf(msgClone)]
|
||||
digest, err := r.currentForkDigest()
|
||||
assert.NoError(t, err)
|
||||
topic = r.addDigestToTopic(topic, digest)
|
||||
@@ -748,11 +768,14 @@ func TestValidateBeaconBlockPubSub_SeenProposerSlot(t *testing.T) {
|
||||
Topic: &topic,
|
||||
},
|
||||
}
|
||||
r.setSeenBlockIndexSlot(msg.Block.Slot, msg.Block.ProposerIndex)
|
||||
time.Sleep(10 * time.Millisecond) // Wait for cached value to pass through buffers.
|
||||
|
||||
// Since this is not an equivocation (same signature), it should be ignored
|
||||
res, err := r.validateBeaconBlockPubSub(ctx, "", m)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, res, pubsub.ValidationIgnore, "seen proposer block should be ignored")
|
||||
assert.Equal(t, pubsub.ValidationIgnore, res, "block with same signature should be ignored")
|
||||
|
||||
// Verify no slashings were created
|
||||
assert.Equal(t, 0, len(slashingPool.PendingPropSlashings), "Expected no slashings for same signature")
|
||||
}
|
||||
|
||||
func TestValidateBeaconBlockPubSub_FilterByFinalizedEpoch(t *testing.T) {
|
||||
@@ -1495,3 +1518,218 @@ func Test_validateDenebBeaconBlock(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.ErrorIs(t, validateDenebBeaconBlock(bdb.Block()), errRejectCommitmentLen)
|
||||
}
|
||||
|
||||
func TestDetectAndBroadcastEquivocation(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p := p2ptest.NewTestP2P(t)
|
||||
beaconState, privKeys := util.DeterministicGenesisState(t, 100)
|
||||
|
||||
t.Run("no equivocation", func(t *testing.T) {
|
||||
block := util.NewBeaconBlock()
|
||||
block.Block.Slot = 1
|
||||
block.Block.ProposerIndex = 0
|
||||
|
||||
sig, err := signing.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
|
||||
require.NoError(t, err)
|
||||
block.Signature = sig
|
||||
|
||||
// Create head block with different slot/proposer
|
||||
headBlock := util.NewBeaconBlock()
|
||||
headBlock.Block.Slot = 2 // Different slot
|
||||
headBlock.Block.ProposerIndex = 1 // Different proposer
|
||||
signedHeadBlock, err := blocks.NewSignedBeaconBlock(headBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
chainService := &mock.ChainService{
|
||||
State: beaconState,
|
||||
Genesis: time.Now(),
|
||||
Block: signedHeadBlock,
|
||||
}
|
||||
|
||||
slashingPool := &slashingsmock.PoolMock{}
|
||||
r := &Service{
|
||||
cfg: &config{
|
||||
p2p: p,
|
||||
chain: chainService,
|
||||
slashingPool: slashingPool,
|
||||
},
|
||||
seenBlockCache: lruwrpr.New(10),
|
||||
}
|
||||
|
||||
signedBlock, err := blocks.NewSignedBeaconBlock(block)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = r.detectAndBroadcastEquivocation(ctx, signedBlock)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, len(slashingPool.PendingPropSlashings), "Expected no slashings")
|
||||
})
|
||||
|
||||
t.Run("equivocation detected", func(t *testing.T) {
|
||||
// Create head block
|
||||
headBlock := util.NewBeaconBlock()
|
||||
headBlock.Block.Slot = 1
|
||||
headBlock.Block.ProposerIndex = 0
|
||||
headBlock.Block.ParentRoot = bytesutil.PadTo([]byte("parent1"), 32)
|
||||
sig1, err := signing.ComputeDomainAndSign(beaconState, 0, headBlock.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
|
||||
require.NoError(t, err)
|
||||
headBlock.Signature = sig1
|
||||
|
||||
// Create second block with same slot/proposer but different contents
|
||||
newBlock := util.NewBeaconBlock()
|
||||
newBlock.Block.Slot = 1
|
||||
newBlock.Block.ProposerIndex = 0
|
||||
newBlock.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
||||
sig2, err := signing.ComputeDomainAndSign(beaconState, 0, newBlock.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
|
||||
require.NoError(t, err)
|
||||
newBlock.Signature = sig2
|
||||
|
||||
signedHeadBlock, err := blocks.NewSignedBeaconBlock(headBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
slashingPool := &slashingsmock.PoolMock{}
|
||||
chainService := &mock.ChainService{
|
||||
State: beaconState,
|
||||
Genesis: time.Now(),
|
||||
Block: signedHeadBlock,
|
||||
}
|
||||
|
||||
r := &Service{
|
||||
cfg: &config{
|
||||
p2p: p,
|
||||
chain: chainService,
|
||||
slashingPool: slashingPool,
|
||||
},
|
||||
seenBlockCache: lruwrpr.New(10),
|
||||
}
|
||||
|
||||
signedNewBlock, err := blocks.NewSignedBeaconBlock(newBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = r.detectAndBroadcastEquivocation(ctx, signedNewBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify slashing was inserted
|
||||
require.Equal(t, 1, len(slashingPool.PendingPropSlashings), "Expected a slashing to be inserted")
|
||||
slashing := slashingPool.PendingPropSlashings[0]
|
||||
assert.Equal(t, primitives.ValidatorIndex(0), slashing.Header_1.Header.ProposerIndex, "Wrong proposer index")
|
||||
assert.Equal(t, primitives.Slot(1), slashing.Header_1.Header.Slot, "Wrong slot")
|
||||
})
|
||||
|
||||
t.Run("same signature", func(t *testing.T) {
|
||||
// Create block
|
||||
block := util.NewBeaconBlock()
|
||||
block.Block.Slot = 1
|
||||
block.Block.ProposerIndex = 0
|
||||
sig, err := signing.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
|
||||
require.NoError(t, err)
|
||||
block.Signature = sig
|
||||
|
||||
signedBlock, err := blocks.NewSignedBeaconBlock(block)
|
||||
require.NoError(t, err)
|
||||
|
||||
slashingPool := &slashingsmock.PoolMock{}
|
||||
chainService := &mock.ChainService{
|
||||
State: beaconState,
|
||||
Genesis: time.Now(),
|
||||
Block: signedBlock,
|
||||
}
|
||||
|
||||
r := &Service{
|
||||
cfg: &config{
|
||||
p2p: p,
|
||||
chain: chainService,
|
||||
slashingPool: slashingPool,
|
||||
},
|
||||
seenBlockCache: lruwrpr.New(10),
|
||||
}
|
||||
|
||||
err = r.detectAndBroadcastEquivocation(ctx, signedBlock)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, len(slashingPool.PendingPropSlashings), "Expected no slashings for same signature")
|
||||
})
|
||||
|
||||
t.Run("head state error", func(t *testing.T) {
|
||||
block := util.NewBeaconBlock()
|
||||
block.Block.Slot = 1
|
||||
block.Block.ProposerIndex = 0
|
||||
block.Block.ParentRoot = bytesutil.PadTo([]byte("parent1"), 32)
|
||||
sig1, err := signing.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
|
||||
require.NoError(t, err)
|
||||
block.Signature = sig1
|
||||
|
||||
headBlock := util.NewBeaconBlock()
|
||||
headBlock.Block.Slot = 1 // Same slot
|
||||
headBlock.Block.ProposerIndex = 0 // Same proposer
|
||||
headBlock.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32) // Different parent root
|
||||
sig2, err := signing.ComputeDomainAndSign(beaconState, 0, headBlock.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
|
||||
require.NoError(t, err)
|
||||
headBlock.Signature = sig2
|
||||
|
||||
signedBlock, err := blocks.NewSignedBeaconBlock(block)
|
||||
require.NoError(t, err)
|
||||
|
||||
signedHeadBlock, err := blocks.NewSignedBeaconBlock(headBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
chainService := &mock.ChainService{
|
||||
State: nil,
|
||||
Block: signedHeadBlock,
|
||||
HeadStateErr: errors.New("could not get head state"),
|
||||
}
|
||||
|
||||
r := &Service{
|
||||
cfg: &config{
|
||||
p2p: p,
|
||||
chain: chainService,
|
||||
slashingPool: &slashingsmock.PoolMock{},
|
||||
},
|
||||
seenBlockCache: lruwrpr.New(10),
|
||||
}
|
||||
|
||||
err = r.detectAndBroadcastEquivocation(ctx, signedBlock)
|
||||
require.ErrorContains(t, "could not get head state", err)
|
||||
})
|
||||
t.Run("signature verification failure", func(t *testing.T) {
|
||||
// Create head block
|
||||
headBlock := util.NewBeaconBlock()
|
||||
headBlock.Block.Slot = 1
|
||||
headBlock.Block.ProposerIndex = 0
|
||||
sig1, err := signing.ComputeDomainAndSign(beaconState, 0, headBlock.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
|
||||
require.NoError(t, err)
|
||||
headBlock.Signature = sig1
|
||||
|
||||
// Create test block with invalid signature
|
||||
newBlock := util.NewBeaconBlock()
|
||||
newBlock.Block.Slot = 1
|
||||
newBlock.Block.ProposerIndex = 0
|
||||
newBlock.Block.ParentRoot = bytesutil.PadTo([]byte("different"), 32)
|
||||
// generate invalid signature
|
||||
invalidSig := make([]byte, 96)
|
||||
copy(invalidSig, []byte("invalid signature"))
|
||||
newBlock.Signature = invalidSig
|
||||
|
||||
signedHeadBlock, err := blocks.NewSignedBeaconBlock(headBlock)
|
||||
require.NoError(t, err)
|
||||
signedNewBlock, err := blocks.NewSignedBeaconBlock(newBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
slashingPool := &slashingsmock.PoolMock{}
|
||||
chainService := &mock.ChainService{
|
||||
State: beaconState,
|
||||
Genesis: time.Now(),
|
||||
Block: signedHeadBlock,
|
||||
}
|
||||
|
||||
r := &Service{
|
||||
cfg: &config{
|
||||
p2p: p,
|
||||
chain: chainService,
|
||||
slashingPool: slashingPool,
|
||||
},
|
||||
seenBlockCache: lruwrpr.New(10),
|
||||
}
|
||||
|
||||
err = r.detectAndBroadcastEquivocation(ctx, signedNewBlock)
|
||||
require.ErrorIs(t, err, ErrSlashingSignatureFailure)
|
||||
})
|
||||
}
|
||||
|
||||
3
changelog/kira_broadcast_slashings.md
Normal file
3
changelog/kira_broadcast_slashings.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
- Added immediate broadcasting of proposer slashings when equivocating blocks are detected during block processing.
|
||||
- Added 2 new errors: `HeadStateErr` and `ErrCouldNotVerifyBlockHeader`
|
||||
3
changelog/nisdas_fix_p2p_req_ssz.md
Normal file
3
changelog/nisdas_fix_p2p_req_ssz.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- Fixes our blob sidecar by root request lists for electra.
|
||||
3
changelog/potuz_vc_deadlines.md
Normal file
3
changelog/potuz_vc_deadlines.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- Fixed deadlines in update duties.
|
||||
3
changelog/pvl_geth_update.md
Normal file
3
changelog/pvl_geth_update.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Changed
|
||||
|
||||
- Updated geth to v1.15.9
|
||||
@@ -2,5 +2,5 @@ package params
|
||||
|
||||
// Re-exports for blackbox testing.
|
||||
const MainnetDenebForkEpoch = mainnetDenebForkEpoch
|
||||
var MainnetBeaconConfig = mainnetBeaconConfig
|
||||
|
||||
var MainnetBeaconConfig = mainnetBeaconConfig
|
||||
|
||||
42
deps.bzl
42
deps.bzl
@@ -427,8 +427,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "com_github_cloudflare_cloudflare_go",
|
||||
importpath = "github.com/cloudflare/cloudflare-go",
|
||||
sum = "h1:ErwCYDjFCYppDJlDJ/5WhsSmzegAUe2+K9qgFyQDg3M=",
|
||||
version = "v0.79.0",
|
||||
sum = "h1:ucoti4/7Exo0XQ+rzpn1H+IfVVe++zgiM+tyKtf0HUA=",
|
||||
version = "v0.114.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_cloudykit_fastprinter",
|
||||
@@ -555,8 +555,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "com_github_cpuguy83_go_md2man_v2",
|
||||
importpath = "github.com/cpuguy83/go-md2man/v2",
|
||||
sum = "h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=",
|
||||
version = "v2.0.3",
|
||||
sum = "h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=",
|
||||
version = "v2.0.5",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_crate_crypto_go_ipa",
|
||||
@@ -772,8 +772,8 @@ def prysm_deps():
|
||||
patches = [
|
||||
"//third_party:com_github_ethereum_go_ethereum_secp256k1.patch",
|
||||
],
|
||||
sum = "h1:LLb2jCPsbJZcB4INw+E/MgzUX5wlR6SdwXcv09/1ME4=",
|
||||
version = "v1.15.0",
|
||||
sum = "h1:bRra1zi+/q+qyXZ6fylZOrlaF8kDdnlTtzNTmNHfX+g=",
|
||||
version = "v1.15.9",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_ethereum_go_verkle",
|
||||
@@ -1108,8 +1108,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "com_github_goccy_go_json",
|
||||
importpath = "github.com/goccy/go-json",
|
||||
sum = "h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=",
|
||||
version = "v0.10.2",
|
||||
sum = "h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=",
|
||||
version = "v0.10.4",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_godbus_dbus_v5",
|
||||
@@ -1410,8 +1410,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "com_github_hashicorp_go_cleanhttp",
|
||||
importpath = "github.com/hashicorp/go-cleanhttp",
|
||||
sum = "h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=",
|
||||
version = "v0.5.2",
|
||||
sum = "h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=",
|
||||
version = "v0.5.1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_hashicorp_go_immutable_radix",
|
||||
@@ -1437,12 +1437,6 @@ def prysm_deps():
|
||||
sum = "h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw=",
|
||||
version = "v0.0.1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_hashicorp_go_retryablehttp",
|
||||
importpath = "github.com/hashicorp/go-retryablehttp",
|
||||
sum = "h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=",
|
||||
version = "v0.7.4",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_hashicorp_go_rootcerts",
|
||||
importpath = "github.com/hashicorp/go-rootcerts",
|
||||
@@ -2830,8 +2824,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "com_github_protolambda_zrnt",
|
||||
importpath = "github.com/protolambda/zrnt",
|
||||
sum = "h1:KZ48T+3UhsPXNdtE/5QEvGc9DGjUaRI17nJaoznoIaM=",
|
||||
version = "v0.32.2",
|
||||
sum = "h1:qW55rnhZJDnOb3TwFiFRJZi3yTXFrJdGOFQM7vCwYGg=",
|
||||
version = "v0.34.1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_protolambda_ztyp",
|
||||
@@ -3393,8 +3387,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "com_github_urfave_cli_v2",
|
||||
importpath = "github.com/urfave/cli/v2",
|
||||
sum = "h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=",
|
||||
version = "v2.27.1",
|
||||
sum = "h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=",
|
||||
version = "v2.27.5",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_urfave_negroni",
|
||||
@@ -3534,8 +3528,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "com_github_xrash_smetrics",
|
||||
importpath = "github.com/xrash/smetrics",
|
||||
sum = "h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=",
|
||||
version = "v0.0.0-20201216005158-039620a65673",
|
||||
sum = "h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=",
|
||||
version = "v0.0.0-20240521201337-686a1a2994c1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_xtaci_kcp_go",
|
||||
@@ -4829,8 +4823,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "org_golang_x_time",
|
||||
importpath = "golang.org/x/time",
|
||||
sum = "h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=",
|
||||
version = "v0.5.0",
|
||||
sum = "h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=",
|
||||
version = "v0.9.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_tools",
|
||||
|
||||
10
go.mod
10
go.mod
@@ -15,7 +15,7 @@ require (
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/emicklei/dot v0.11.0
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.1
|
||||
github.com/ethereum/go-ethereum v1.15.0
|
||||
github.com/ethereum/go-ethereum v1.15.9
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible
|
||||
@@ -74,7 +74,7 @@ require (
|
||||
github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e
|
||||
github.com/trailofbits/go-mutexasserts v0.0.0-20250212181730-4c2b8e9e784b
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
github.com/urfave/cli/v2 v2.27.1
|
||||
github.com/urfave/cli/v2 v2.27.5
|
||||
github.com/uudashr/gocognit v1.0.5
|
||||
github.com/wealdtech/go-bytesutil v1.1.1
|
||||
github.com/wealdtech/go-eth2-util v1.6.3
|
||||
@@ -125,7 +125,7 @@ require (
|
||||
github.com/consensys/bavard v0.1.22 // indirect
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||
@@ -249,7 +249,7 @@ require (
|
||||
github.com/tklauser/numcpus v0.7.0 // indirect
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.8.2 // indirect
|
||||
github.com/wlynxg/anet v0.0.4 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
|
||||
@@ -265,7 +265,7 @@ require (
|
||||
golang.org/x/oauth2 v0.24.0 // indirect
|
||||
golang.org/x/term v0.30.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
|
||||
20
go.sum
20
go.sum
@@ -172,8 +172,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg=
|
||||
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM=
|
||||
github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4=
|
||||
@@ -239,8 +239,8 @@ github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHE
|
||||
github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.1 h1:KhzBVjmURsfr1+S3k/VE35T02+AW2qU9t9gr4R6YpSo=
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.1/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E=
|
||||
github.com/ethereum/go-ethereum v1.15.0 h1:LLb2jCPsbJZcB4INw+E/MgzUX5wlR6SdwXcv09/1ME4=
|
||||
github.com/ethereum/go-ethereum v1.15.0/go.mod h1:4q+4t48P2C03sjqGvTXix5lEOplf5dz4CTosbjt5tGs=
|
||||
github.com/ethereum/go-ethereum v1.15.9 h1:bRra1zi+/q+qyXZ6fylZOrlaF8kDdnlTtzNTmNHfX+g=
|
||||
github.com/ethereum/go-ethereum v1.15.9/go.mod h1:+S9k+jFzlyVTNcYGvqFhzN/SFhI6vA+aOY4T5tLSPL0=
|
||||
github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8=
|
||||
github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@@ -1048,8 +1048,8 @@ github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
|
||||
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
|
||||
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/uudashr/gocognit v1.0.5 h1:rrSex7oHr3/pPLQ0xoWq108XMU8s678FJcQ+aSfOHa4=
|
||||
github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
@@ -1074,8 +1074,8 @@ github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguH
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@@ -1432,8 +1432,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
@@ -72,6 +72,9 @@ func feeRecipientIsPresent(_ *types.EvaluationContext, conns ...*grpc.ClientConn
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get chain head")
|
||||
}
|
||||
if chainHead.HeadEpoch == 0 {
|
||||
return nil
|
||||
}
|
||||
req := ðpb.ListBlocksRequest{QueryFilter: ðpb.ListBlocksRequest_Epoch{Epoch: chainHead.HeadEpoch.Sub(1)}}
|
||||
blks, err := client.ListBeaconBlocks(context.Background(), req)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
diff --color -ruN a/crypto/secp256k1/BUILD.bazel b/crypto/secp256k1/BUILD.bazel
|
||||
--- a/crypto/secp256k1/BUILD.bazel 2021-10-14 20:32:30.202922024 -0500
|
||||
+++ b/crypto/secp256k1/BUILD.bazel 2021-10-14 20:30:17.921027939 -0500
|
||||
@@ -11,10 +11,11 @@
|
||||
diff --git a/crypto/secp256k1/BUILD.bazel b/crypto/secp256k1/BUILD.bazel
|
||||
index 379c6df1a..24ad195fd 100644
|
||||
--- a/crypto/secp256k1/BUILD.bazel
|
||||
+++ b/crypto/secp256k1/BUILD.bazel
|
||||
@@ -10,10 +10,11 @@ go_library(
|
||||
"scalar_mult_nocgo.go",
|
||||
"secp256.go",
|
||||
],
|
||||
@@ -15,44 +16,62 @@ diff --color -ruN a/crypto/secp256k1/BUILD.bazel b/crypto/secp256k1/BUILD.bazel
|
||||
],
|
||||
importpath = "github.com/ethereum/go-ethereum/crypto/secp256k1",
|
||||
visibility = ["//visibility:public"],
|
||||
diff --color -ruN a/crypto/secp256k1/libsecp256k1/BUILD.bazel b/crypto/secp256k1/libsecp256k1/BUILD.bazel
|
||||
--- a/crypto/secp256k1/libsecp256k1/BUILD.bazel 1969-12-31 18:00:00.000000000 -0600
|
||||
+++ b/crypto/secp256k1/libsecp256k1/BUILD.bazel 2021-10-14 12:54:27.704265206 -0500
|
||||
@@ -0,0 +1,37 @@
|
||||
diff --git a/crypto/secp256k1/libsecp256k1/BUILD.bazel b/crypto/secp256k1/libsecp256k1/BUILD.bazel
|
||||
new file mode 100644
|
||||
index 000000000..1a6a1ea78
|
||||
--- /dev/null
|
||||
+++ b/crypto/secp256k1/libsecp256k1/BUILD.bazel
|
||||
@@ -0,0 +1,53 @@
|
||||
+cc_library(
|
||||
+ name = "hdrs",
|
||||
+ hdrs = [
|
||||
+ "include/secp256k1.h",
|
||||
+ "include/secp256k1_recovery.h",
|
||||
+ "src/ecdsa.h",
|
||||
+ "src/ecdsa_impl.h",
|
||||
+ "src/eckey.h",
|
||||
+ "src/eckey_impl.h",
|
||||
+ "src/ecmult.h",
|
||||
+ "src/ecmult_const.h",
|
||||
+ "src/ecmult_const_impl.h",
|
||||
+ "src/ecmult_gen.h",
|
||||
+ "src/ecmult_gen_impl.h",
|
||||
+ "src/ecmult_impl.h",
|
||||
+ "src/field.h",
|
||||
+ "src/field_5x52.h",
|
||||
+ "src/field_5x52_impl.h",
|
||||
+ "src/field_5x52_int128_impl.h",
|
||||
+ "src/field_impl.h",
|
||||
+ "src/group.h",
|
||||
+ "src/group_impl.h",
|
||||
+ "src/hash.h",
|
||||
+ "src/hash_impl.h",
|
||||
+ "src/modules/recovery/main_impl.h",
|
||||
+ "src/num.h",
|
||||
+ "src/num_impl.h",
|
||||
+ "src/scalar.h",
|
||||
+ "src/scalar_4x64.h",
|
||||
+ "src/scalar_4x64_impl.h",
|
||||
+ "src/scalar_impl.h",
|
||||
+ "src/secp256k1.c",
|
||||
+ "src/util.h",
|
||||
+ ],
|
||||
+ visibility = ["//visibility:public"],
|
||||
+ name = "hdrs",
|
||||
+ hdrs = [
|
||||
+ "include/secp256k1.h",
|
||||
+ "include/secp256k1_preallocated.h",
|
||||
+ "include/secp256k1_recovery.h",
|
||||
+ "src/assumptions.h",
|
||||
+ "src/checkmem.h",
|
||||
+ "src/ecdsa.h",
|
||||
+ "src/ecdsa_impl.h",
|
||||
+ "src/eckey.h",
|
||||
+ "src/eckey_impl.h",
|
||||
+ "src/ecmult.h",
|
||||
+ "src/ecmult_const.h",
|
||||
+ "src/ecmult_const_impl.h",
|
||||
+ "src/ecmult_gen.h",
|
||||
+ "src/ecmult_gen_impl.h",
|
||||
+ "src/ecmult_impl.h",
|
||||
+ "src/field.h",
|
||||
+ "src/field_5x52.h",
|
||||
+ "src/field_5x52_impl.h",
|
||||
+ "src/field_5x52_int128_impl.h",
|
||||
+ "src/field_impl.h",
|
||||
+ "src/group.h",
|
||||
+ "src/group_impl.h",
|
||||
+ "src/hash.h",
|
||||
+ "src/hash_impl.h",
|
||||
+ "src/hsort.h",
|
||||
+ "src/hsort_impl.h",
|
||||
+ "src/int128.h",
|
||||
+ "src/int128_impl.h",
|
||||
+ "src/int128_native.h",
|
||||
+ "src/int128_native_impl.h",
|
||||
+ "src/modinv64.h",
|
||||
+ "src/modinv64_impl.h",
|
||||
+ "src/modules/recovery/main_impl.h",
|
||||
+ "src/precomputed_ecmult.c",
|
||||
+ "src/precomputed_ecmult.h",
|
||||
+ "src/precomputed_ecmult_gen.c",
|
||||
+ "src/precomputed_ecmult_gen.h",
|
||||
+ "src/scalar.h",
|
||||
+ "src/scalar_4x64.h",
|
||||
+ "src/scalar_4x64_impl.h",
|
||||
+ "src/scalar_impl.h",
|
||||
+ "src/scratch.h",
|
||||
+ "src/scratch_impl.h",
|
||||
+ "src/secp256k1.c",
|
||||
+ "src/selftest.h",
|
||||
+ "src/util.h",
|
||||
+ ],
|
||||
+ visibility = ["//visibility:public"],
|
||||
+)
|
||||
+
|
||||
|
||||
@@ -43,7 +43,15 @@ func run(ctx context.Context, v iface.Validator) {
|
||||
if err != nil {
|
||||
return // Exit if context is canceled.
|
||||
}
|
||||
if err := v.UpdateDuties(ctx, headSlot); err != nil {
|
||||
endEpoch, err := slots.EpochEnd(slots.ToEpoch(headSlot))
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get current epoch")
|
||||
return
|
||||
}
|
||||
deadline := v.SlotDeadline(endEpoch)
|
||||
dutiesCtx, cancel := context.WithDeadline(ctx, deadline)
|
||||
defer cancel()
|
||||
if err := v.UpdateDuties(dutiesCtx, headSlot); err != nil {
|
||||
handleAssignmentError(err, headSlot)
|
||||
}
|
||||
eventsChan := make(chan *event.Event, 1)
|
||||
@@ -77,24 +85,35 @@ func run(ctx context.Context, v iface.Validator) {
|
||||
continue
|
||||
}
|
||||
|
||||
deadline := v.SlotDeadline(slot)
|
||||
slotCtx, cancel := context.WithDeadline(ctx, deadline)
|
||||
endEpoch, err := slots.EpochEnd(slots.ToEpoch(slot))
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get current epoch")
|
||||
continue
|
||||
}
|
||||
deadline := v.SlotDeadline(endEpoch)
|
||||
dutiesCtx, cancel := context.WithDeadline(ctx, deadline)
|
||||
|
||||
var span trace.Span
|
||||
slotCtx, span = prysmTrace.StartSpan(slotCtx, "validator.processSlot")
|
||||
dutiesCtx, span = prysmTrace.StartSpan(dutiesCtx, "validator.processSlot.updateDuties")
|
||||
span.SetAttributes(prysmTrace.Int64Attribute("slot", int64(slot))) // lint:ignore uintcast -- This conversion is OK for tracing.
|
||||
|
||||
log := log.WithField("slot", slot)
|
||||
log.WithField("deadline", deadline).Debug("Set deadline for proposals and attestations")
|
||||
|
||||
// Keep trying to update assignments if they are nil or if we are past an
|
||||
// epoch transition in the beacon node's state.
|
||||
if err := v.UpdateDuties(slotCtx, slot); err != nil {
|
||||
if err := v.UpdateDuties(dutiesCtx, slot); err != nil {
|
||||
handleAssignmentError(err, slot)
|
||||
cancel()
|
||||
span.End()
|
||||
cancel()
|
||||
continue
|
||||
}
|
||||
span.End()
|
||||
cancel()
|
||||
|
||||
deadline = v.SlotDeadline(slot)
|
||||
slotCtx, cancel := context.WithDeadline(ctx, deadline)
|
||||
slotCtx, span = prysmTrace.StartSpan(slotCtx, "validator.processSlot.performRoles")
|
||||
span.SetAttributes(prysmTrace.Int64Attribute("slot", int64(slot))) // lint:ignore uintcast -- This conversion is OK for tracing.
|
||||
log := log.WithField("slot", slot)
|
||||
log.WithField("deadline", deadline).Debug("Set deadline for proposals and attestations")
|
||||
|
||||
// call push proposer settings often to account for the following edge cases:
|
||||
// proposer is activated at the start of epoch and tries to propose immediately
|
||||
@@ -113,11 +132,13 @@ func run(ctx context.Context, v iface.Validator) {
|
||||
allRoles, err := v.RolesAt(slotCtx, slot)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get validator roles")
|
||||
cancel()
|
||||
span.End()
|
||||
cancel()
|
||||
continue
|
||||
}
|
||||
performRoles(slotCtx, allRoles, v, slot, &wg, span)
|
||||
span.End()
|
||||
cancel()
|
||||
case isHealthyAgain := <-healthTracker.HealthUpdates():
|
||||
if isHealthyAgain {
|
||||
headSlot, err = initializeValidatorAndGetHeadSlot(ctx, v)
|
||||
@@ -125,10 +146,18 @@ func run(ctx context.Context, v iface.Validator) {
|
||||
log.WithError(err).Error("Failed to re initialize validator and get head slot")
|
||||
continue
|
||||
}
|
||||
if err := v.UpdateDuties(ctx, headSlot); err != nil {
|
||||
handleAssignmentError(err, headSlot)
|
||||
endEpoch, err := slots.EpochEnd(slots.ToEpoch(headSlot))
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get current epoch")
|
||||
continue
|
||||
}
|
||||
dutiesCtx, cancel := context.WithDeadline(ctx, v.SlotDeadline(endEpoch))
|
||||
if err := v.UpdateDuties(dutiesCtx, headSlot); err != nil {
|
||||
handleAssignmentError(err, headSlot)
|
||||
cancel()
|
||||
continue
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
case e := <-eventsChan:
|
||||
v.ProcessEvent(ctx, e)
|
||||
|
||||
@@ -511,27 +511,11 @@ func retrieveLatestRecord(recs []*dbCommon.AttestationRecord) *dbCommon.Attestat
|
||||
return chosenRec
|
||||
}
|
||||
|
||||
// UpdateDuties checks the slot number to determine if the validator's
|
||||
// list of upcoming assignments needs to be updated. For example, at the
|
||||
// beginning of a new epoch.
|
||||
func (v *validator) UpdateDuties(ctx context.Context, slot primitives.Slot) error {
|
||||
if !slots.IsEpochStart(slot) && v.duties != nil {
|
||||
// Do nothing if not epoch start AND assignments already exist.
|
||||
return nil
|
||||
}
|
||||
// Set deadline to end of epoch.
|
||||
ss, err := slots.EpochStart(slots.ToEpoch(slot) + 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx, cancel := context.WithDeadline(ctx, v.SlotDeadline(ss))
|
||||
defer cancel()
|
||||
ctx, span := trace.StartSpan(ctx, "validator.UpdateDuties")
|
||||
defer span.End()
|
||||
|
||||
// getFilteredKeys returns the list of keys that are not slashable.
|
||||
func (v *validator) getFilteredKeys(ctx context.Context) ([][fieldparams.BLSPubkeyLength]byte, error) {
|
||||
validatingKeys, err := v.km.FetchValidatingPublicKeys(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, errors.Wrap(err, "could not fetch validating public keys")
|
||||
}
|
||||
|
||||
// Filter out the slashable public keys from the duties request.
|
||||
@@ -548,6 +532,23 @@ func (v *validator) UpdateDuties(ctx context.Context, slot primitives.Slot) erro
|
||||
}
|
||||
}
|
||||
v.blacklistedPubkeysLock.RUnlock()
|
||||
return filteredKeys, nil
|
||||
}
|
||||
|
||||
// UpdateDuties checks the slot number to determine if the validator's
|
||||
// list of upcoming assignments needs to be updated. For example, at the
|
||||
// beginning of a new epoch.
|
||||
func (v *validator) UpdateDuties(ctx context.Context, slot primitives.Slot) error {
|
||||
if !slots.IsEpochStart(slot) && v.duties != nil {
|
||||
// Do nothing if not epoch start AND assignments already exist.
|
||||
return nil
|
||||
}
|
||||
ctx, span := trace.StartSpan(ctx, "validator.UpdateDuties")
|
||||
defer span.End()
|
||||
filteredKeys, err := v.getFilteredKeys(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get filtered keys")
|
||||
}
|
||||
|
||||
req := ðpb.DutiesRequest{
|
||||
Epoch: primitives.Epoch(slot / params.BeaconConfig().SlotsPerEpoch),
|
||||
@@ -1148,21 +1149,17 @@ func (v *validator) checkDependentRoots(ctx context.Context, head *structs.HeadE
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to decode previous duty dependent root")
|
||||
}
|
||||
uintSlot, err := strconv.ParseUint(head.Slot, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to parse slot")
|
||||
}
|
||||
|
||||
slot := primitives.Slot(uintSlot)
|
||||
slot := slots.CurrentSlot(v.genesisTime)
|
||||
currEpochStart, err := slots.EpochStart(slots.ToEpoch(slot))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
deadline := v.SlotDeadline(slot)
|
||||
slotCtx, cancel := context.WithDeadline(ctx, deadline)
|
||||
// set deadline for next epoch instead of dutiesDeadline
|
||||
deadline := v.SlotDeadline(currEpochStart + params.BeaconConfig().SlotsPerEpoch)
|
||||
dutiesCtx, cancel := context.WithDeadline(ctx, deadline)
|
||||
defer cancel()
|
||||
if !bytes.Equal(prevDepedentRoot, v.duties.PrevDependentRoot) {
|
||||
if err := v.UpdateDuties(slotCtx, currEpochStart); err != nil {
|
||||
if err := v.UpdateDuties(dutiesCtx, currEpochStart); err != nil {
|
||||
return errors.Wrap(err, "failed to update duties")
|
||||
}
|
||||
log.Info("Updated duties due to previous dependent root change")
|
||||
@@ -1173,7 +1170,7 @@ func (v *validator) checkDependentRoots(ctx context.Context, head *structs.HeadE
|
||||
return errors.Wrap(err, "failed to decode current duty dependent root")
|
||||
}
|
||||
if !bytes.Equal(currDepedentRoot, v.duties.CurrDependentRoot) {
|
||||
if err := v.UpdateDuties(slotCtx, currEpochStart); err != nil {
|
||||
if err := v.UpdateDuties(dutiesCtx, currEpochStart); err != nil {
|
||||
return errors.Wrap(err, "failed to update duties")
|
||||
}
|
||||
log.Info("Updated duties due to current dependent root change")
|
||||
|
||||
Reference in New Issue
Block a user