Compare commits

...

9 Commits

Author SHA1 Message Date
potuz
aa06ce5e0e don't panic on underflow 2025-04-25 12:36:25 -03:00
james-prysm
e5d7888e5c Merge branch 'develop' into fix_deadlines 2025-04-25 09:26:03 -05:00
Preston Van Loon
f7eddedd1d update geth v1.15.9 (#15216)
* Update go-ethereum to v1.15.9

* Fix go-ethereum secp256k1 build after https://github.com/ethereum/go-ethereum/pull/31242

* Fix Ping API change

* Changelog fragment
2025-04-25 12:40:19 +00:00
kira
7887ebbc4a Broadcast Proposer Slashing on equivocation (#14693)
* Add equivocation detection logic; broadcast slashing immediately on equivocation

* nit: comments

* move equivocation detection to validateBeaconBlockPubSub

* include broadcasting logic within the helper function

* fix lint

* Add unit tests for equivocation detection

* remove comment that are not required

* Add changelog file

* Add descriptive comment for detectAndBroadcastEquivocation

* use head block instead of block cache for equivocation detection

* add more equivocation unit tests; update a mock to include HeadState error

* update the order of the checks

* move slashing before state fetch; update Tests

* update changelog

* use verifyProposerSlashing to verify and reject block; remove verifySlashableBlock; update tests

* Update changelog

* nit: cleaner error check

* nit: clean up

* revert code logic; update string check; add a unit test

* improve errors; merge tests

* Update a unit test

* fix lint

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-04-24 20:27:34 +00:00
potuz
4ea3699c51 make all duties deadlines to end of epoch 2025-04-24 12:31:27 -03:00
potuz
06a5a16007 review 2 2025-04-23 18:27:20 -03:00
potuz
fb2eeb5ce9 review 2025-04-23 18:16:29 -03:00
potuz
b526d99a55 Fix deadlines 2025-04-23 17:50:07 -03:00
Nishant Das
1b13520270 Fix Unmarshalling of BlobSidecarsByRoot Requests (#15209)
* Handle Electra Lists

* Changelog
2025-04-23 14:04:46 +00:00
21 changed files with 530 additions and 137 deletions

View File

@@ -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
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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),

View File

@@ -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))

View File

@@ -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",

View File

@@ -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 := &ethpb.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
}

View File

@@ -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: &ethpb.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)
})
}

View 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`

View File

@@ -0,0 +1,3 @@
### Fixed
- Fixes our blob sidecar by root request lists for electra.

View File

@@ -0,0 +1,3 @@
### Fixed
- Fixed deadlines in update duties.

View File

@@ -0,0 +1,3 @@
### Changed
- Updated geth to v1.15.9

View File

@@ -2,5 +2,5 @@ package params
// Re-exports for blackbox testing.
const MainnetDenebForkEpoch = mainnetDenebForkEpoch
var MainnetBeaconConfig = mainnetBeaconConfig
var MainnetBeaconConfig = mainnetBeaconConfig

View File

@@ -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
View File

@@ -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
View File

@@ -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=

View File

@@ -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 := &ethpb.ListBlocksRequest{QueryFilter: &ethpb.ListBlocksRequest_Epoch{Epoch: chainHead.HeadEpoch.Sub(1)}}
blks, err := client.ListBeaconBlocks(context.Background(), req)
if err != nil {

View File

@@ -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"],
+)
+

View File

@@ -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)

View File

@@ -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 := &ethpb.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")