Compare commits

...

10 Commits

Author SHA1 Message Date
Preston Van Loon
11c83bbc63 Changelog for v6.0.5 2025-09-26 10:11:39 -05:00
Jun Song
29fe707143 SSZ-QL: Support nested List type (#15725)
* Add nested 2d list cases

* Add elementSize member for listInfo to track each element's byte size

* Fix misleading variable in RunStructTest

* Changelog

* Regen pb file

* Update encoding/ssz/query/list.go

Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>

* Rename elementSize into plural

* Update changelog/syjn99_ssz-ql-nested-list.md

---------

Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>
2025-09-26 14:23:22 +00:00
kasey
d68196822b additional log information around invalid payloads (#15754)
* additional log information around invalid payloads

* fix test with reversed require.ErrorIs args

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-09-26 02:33:57 +00:00
terence
924fe4de98 Restructure golangci-lint config: explicit opt-in (#15744)
* update golangci-lint configuration to enable basic linters only

* Add back formatter

* feedback

* Add nolint
2025-09-25 17:01:22 +00:00
Preston Van Loon
fe9dd255c7 slasherkv: Set a 1 minute timeout on PruneAttestationOnEpoch operations (#15746)
* slasherkv: Set a 1 minute timeout on PruneAttestationOnEpoch operations to prevent very large bolt transactions.

* Fix CI

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2025-09-25 15:46:28 +00:00
Potuz
83d75bcb78 Update quick-go (#15749) 2025-09-25 11:02:10 +00:00
james-prysm
ba5f7361ad flipping if statement check to fix metric (#15743) 2025-09-24 20:43:39 +00:00
Manu NALEPA
8fa956036a Update go.mod to v1.25.1. (#15740)
* Updated go.mod to v1.25.1.

Run `golangci-lint migrate`
GolangCI lint: Add `noinlineerr`.
Run `golangci-lint run --config=.golangci.yml`.
`golangci`: Add `--new`.

* `go.yml`: Added `fetch-depth: 0` to have something working with merge queue according to

https://github.com/golangci/golangci-lint-action/issues/956

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-09-24 19:57:17 +00:00
james-prysm
58ce1c25f5 fixing error handling of unfound block (#15742) 2025-09-24 19:03:55 +00:00
Potuz
98532a2df3 update spectests to 1.6.0-beta.0 (#15741)
* update spectests to 1.6.0-beta.0

* start fixing ethspecify
2025-09-24 18:13:46 +00:00
41 changed files with 635 additions and 343 deletions

View File

@@ -1,4 +1,4 @@
FROM golang:1.24-alpine
FROM golang:1.25.1-alpine
COPY entrypoint.sh /entrypoint.sh

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.23.5'
go-version: '1.25.1'
- id: list
uses: shogo82148/actions-go-fuzz/list@v0
with:
@@ -36,7 +36,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.23.5'
go-version: '1.25.1'
- uses: shogo82148/actions-go-fuzz/run@v0
with:
packages: ${{ matrix.package }}

View File

@@ -31,7 +31,7 @@ jobs:
- name: Set up Go 1.24
uses: actions/setup-go@v4
with:
go-version: '1.24.0'
go-version: '1.25.1'
- name: Run Gosec Security Scanner
run: | # https://github.com/securego/gosec/issues/469
export PATH=$PATH:$(go env GOPATH)/bin
@@ -44,27 +44,27 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go 1.24
uses: actions/setup-go@v4
with:
go-version: '1.24.0'
id: go
fetch-depth: 0
- name: Set up Go 1.25.1
uses: actions/setup-go@v5
with:
go-version: '1.25.1'
- name: Golangci-lint
uses: golangci/golangci-lint-action@v5
uses: golangci/golangci-lint-action@v8
with:
version: v1.64.5
args: --config=.golangci.yml --out-${NO_FUTURE}format colored-line-number
version: v2.4
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.x
- name: Set up Go 1.25.1
uses: actions/setup-go@v4
with:
go-version: '1.24.0'
go-version: '1.25.1'
id: go
- name: Check out code into the Go module directory

View File

@@ -1,90 +1,41 @@
version: "2"
run:
timeout: 10m
go: '1.23.5'
issues:
exclude-files:
- validator/web/site_data.go
- .*_test.go
exclude-dirs:
- proto
- tools/analyzers
go: 1.23.5
linters:
enable-all: true
disable:
# Deprecated linters:
enable:
- errcheck
- ineffassign
- govet
# Disabled for now:
- asasalint
- bodyclose
- containedctx
- contextcheck
- cyclop
- depguard
- dogsled
- dupl
- durationcheck
- errname
- err113
- exhaustive
- exhaustruct
- forbidigo
- forcetypeassert
- funlen
- gci
- gochecknoglobals
- gochecknoinits
- goconst
- gocritic
- gocyclo
- godot
- godox
- gofumpt
- gomoddirectives
- gosec
- inamedparam
- interfacebloat
- intrange
- ireturn
- lll
- maintidx
- makezero
- mnd
- musttag
- nakedret
- nestif
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- recvcheck
- revive
- spancheck
disable:
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- thelper
- unparam
- usetesting
- varnamelen
- wrapcheck
- wsl
- unused
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- validator/web/site_data.go
- .*_test.go
- proto
- tools/analyzers
- third_party$
- builtin$
- examples$
linters-settings:
gocognit:
# TODO: We should target for < 50
min-complexity: 65
output:
print-issued-lines: true
sort-results: true
formatters:
enable:
- gofmt
- goimports
exclusions:
generated: lax
paths:
- validator/web/site_data.go
- .*_test.go
- proto
- tools/analyzers
- third_party$
- builtin$
- examples$

View File

@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
## [v6.0.5](https://github.com/prysmaticlabs/prysm/compare/v6.0.4...v6.0.5) - 2025-09-26
### Changed
- Updated quick-go to latest version. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15749)
## [v6.0.4](https://github.com/prysmaticlabs/prysm/compare/v6.0.3...v6.0.4) - 2025-06-05
This release has more work on PeerDAS, and light client support. Additionally, we have a few bug fixes:
@@ -3458,4 +3464,4 @@ There are no security updates in this release.
# Older than v2.0.0
For changelog history for releases older than v2.0.0, please refer to https://github.com/prysmaticlabs/prysm/releases
For changelog history for releases older than v2.0.0, please refer to https://github.com/prysmaticlabs/prysm/releases

View File

@@ -253,16 +253,16 @@ filegroup(
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
)
consensus_spec_version = "v1.6.0-alpha.6"
consensus_spec_version = "v1.6.0-beta.0"
load("@prysm//tools:download_spectests.bzl", "consensus_spec_tests")
consensus_spec_tests(
name = "consensus_spec_tests",
flavors = {
"general": "sha256-7wkWuahuCO37uVYnxq8Badvi+jY907pBj68ixL8XDOI=",
"minimal": "sha256-Qy/f27N0LffS/ej7VhIubwDejD6LMK0VdenKkqtZVt4=",
"mainnet": "sha256-3H7mu5yE+FGz2Wr/nc8Nd9aEu93YoEpsYtn0zBSoeDE=",
"general": "sha256-rT3jQp2+ZaDiO66gIQggetzqr+kGeexaLqEhbx4HDMY=",
"minimal": "sha256-wowwwyvd0KJLsE+oDOtPkrhZyJndJpJ0lbXYsLH6XBw=",
"mainnet": "sha256-4ZLrLNeO7NihZ4TuWH5V5fUhvW9Y3mAPBQDCqrfShps=",
},
version = consensus_spec_version,
)
@@ -278,7 +278,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-uvz3XfMTGfy3/BtQQoEp5XQOgrWgcH/5Zo/gR0iiP+k=",
integrity = "sha256-sBe3Rx8zGq9IrvfgIhZQpYidGjy3mE1SiCb6/+pjLdY=",
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
)

View File

@@ -16,7 +16,7 @@ import (
"github.com/OffchainLabs/prysm/v6/beacon-chain/state"
"github.com/OffchainLabs/prysm/v6/config/features"
"github.com/OffchainLabs/prysm/v6/config/params"
consensusblocks "github.com/OffchainLabs/prysm/v6/consensus-types/blocks"
blocktypes "github.com/OffchainLabs/prysm/v6/consensus-types/blocks"
"github.com/OffchainLabs/prysm/v6/consensus-types/interfaces"
payloadattribute "github.com/OffchainLabs/prysm/v6/consensus-types/payload-attribute"
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
@@ -218,24 +218,18 @@ func (s *Service) getPayloadHash(ctx context.Context, root []byte) ([32]byte, er
// notifyNewPayload signals execution engine on a new payload.
// It returns true if the EL has returned VALID for the block
func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion int,
preStateHeader interfaces.ExecutionData, blk interfaces.ReadOnlySignedBeaconBlock) (bool, error) {
// stVersion should represent the version of the pre-state; header should also be from the pre-state.
func (s *Service) notifyNewPayload(ctx context.Context, stVersion int, header interfaces.ExecutionData, blk blocktypes.ROBlock) (bool, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.notifyNewPayload")
defer span.End()
// Execution payload is only supported in Bellatrix and beyond. Pre
// merge blocks are never optimistic
if blk == nil {
return false, errors.New("signed beacon block can't be nil")
}
if preStateVersion < version.Bellatrix {
if stVersion < version.Bellatrix {
return true, nil
}
if err := consensusblocks.BeaconBlockIsNil(blk); err != nil {
return false, err
}
body := blk.Block().Body()
enabled, err := blocks.IsExecutionEnabledUsingHeader(preStateHeader, body)
enabled, err := blocks.IsExecutionEnabledUsingHeader(header, body)
if err != nil {
return false, errors.Wrap(invalidBlock{error: err}, "could not determine if execution is enabled")
}
@@ -268,28 +262,32 @@ func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion int,
return false, errors.New("nil execution requests")
}
}
lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, parentRoot, requests)
switch {
case err == nil:
lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, parentRoot, requests)
if err == nil {
newPayloadValidNodeCount.Inc()
return true, nil
case errors.Is(err, execution.ErrAcceptedSyncingPayloadStatus):
}
logFields := logrus.Fields{
"slot": blk.Block().Slot(),
"parentRoot": fmt.Sprintf("%#x", parentRoot),
"root": fmt.Sprintf("%#x", blk.Root()),
"payloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(payload.BlockHash())),
}
if errors.Is(err, execution.ErrAcceptedSyncingPayloadStatus) {
newPayloadOptimisticNodeCount.Inc()
log.WithFields(logrus.Fields{
"slot": blk.Block().Slot(),
"payloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(payload.BlockHash())),
}).Info("Called new payload with optimistic block")
log.WithFields(logFields).Info("Called new payload with optimistic block")
return false, nil
case errors.Is(err, execution.ErrInvalidPayloadStatus):
lvh := bytesutil.ToBytes32(lastValidHash)
}
if errors.Is(err, execution.ErrInvalidPayloadStatus) {
log.WithFields(logFields).WithError(err).Error("Invalid payload status")
return false, invalidBlock{
error: ErrInvalidPayload,
lastValidHash: lvh,
lastValidHash: bytesutil.ToBytes32(lastValidHash),
}
default:
return false, errors.WithMessage(ErrUndefinedExecutionEngineError, err.Error())
}
log.WithFields(logFields).WithError(err).Error("Unexpected execution engine error")
return false, errors.WithMessage(ErrUndefinedExecutionEngineError, err.Error())
}
// reportInvalidBlock deals with the event that an invalid block was detected by the execution layer

View File

@@ -481,33 +481,12 @@ func Test_NotifyNewPayload(t *testing.T) {
phase0State, _ := util.DeterministicGenesisState(t, 1)
altairState, _ := util.DeterministicGenesisStateAltair(t, 1)
bellatrixState, _ := util.DeterministicGenesisStateBellatrix(t, 2)
a := &ethpb.SignedBeaconBlockAltair{
Block: &ethpb.BeaconBlockAltair{
Body: &ethpb.BeaconBlockBodyAltair{},
},
}
a := util.NewBeaconBlockAltair()
altairBlk, err := consensusblocks.NewSignedBeaconBlock(a)
require.NoError(t, err)
blk := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Slot: 1,
Body: &ethpb.BeaconBlockBodyBellatrix{
ExecutionPayload: &v1.ExecutionPayload{
BlockNumber: 1,
ParentHash: make([]byte, fieldparams.RootLength),
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
StateRoot: make([]byte, fieldparams.RootLength),
ReceiptsRoot: make([]byte, fieldparams.RootLength),
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
PrevRandao: make([]byte, fieldparams.RootLength),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
Transactions: make([][]byte, 0),
},
},
},
}
blk := util.NewBeaconBlockBellatrix()
blk.Block.Slot = 1
blk.Block.Body.ExecutionPayload.BlockNumber = 1
bellatrixBlk, err := consensusblocks.NewSignedBeaconBlock(util.HydrateSignedBeaconBlockBellatrix(blk))
require.NoError(t, err)
st := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epochsSinceFinalitySaveHotStateDB))
@@ -544,12 +523,6 @@ func Test_NotifyNewPayload(t *testing.T) {
blk: altairBlk,
isValidPayload: true,
},
{
name: "nil beacon block",
postState: bellatrixState,
errString: "signed beacon block can't be nil",
isValidPayload: false,
},
{
name: "new payload with optimistic block",
postState: bellatrixState,
@@ -576,15 +549,8 @@ func Test_NotifyNewPayload(t *testing.T) {
name: "altair pre state, happy case",
postState: bellatrixState,
blk: func() interfaces.ReadOnlySignedBeaconBlock {
blk := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Body: &ethpb.BeaconBlockBodyBellatrix{
ExecutionPayload: &v1.ExecutionPayload{
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
},
},
},
}
blk := util.NewBeaconBlockBellatrix()
blk.Block.Body.ExecutionPayload.ParentHash = bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength)
b, err := consensusblocks.NewSignedBeaconBlock(blk)
require.NoError(t, err)
return b
@@ -595,24 +561,7 @@ func Test_NotifyNewPayload(t *testing.T) {
name: "not at merge transition",
postState: bellatrixState,
blk: func() interfaces.ReadOnlySignedBeaconBlock {
blk := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Body: &ethpb.BeaconBlockBodyBellatrix{
ExecutionPayload: &v1.ExecutionPayload{
ParentHash: make([]byte, fieldparams.RootLength),
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
StateRoot: make([]byte, fieldparams.RootLength),
ReceiptsRoot: make([]byte, fieldparams.RootLength),
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
PrevRandao: make([]byte, fieldparams.RootLength),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
Transactions: make([][]byte, 0),
},
},
},
}
blk := util.NewBeaconBlockBellatrix()
b, err := consensusblocks.NewSignedBeaconBlock(blk)
require.NoError(t, err)
return b
@@ -623,15 +572,8 @@ func Test_NotifyNewPayload(t *testing.T) {
name: "happy case",
postState: bellatrixState,
blk: func() interfaces.ReadOnlySignedBeaconBlock {
blk := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Body: &ethpb.BeaconBlockBodyBellatrix{
ExecutionPayload: &v1.ExecutionPayload{
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
},
},
},
}
blk := util.NewBeaconBlockBellatrix()
blk.Block.Body.ExecutionPayload.ParentHash = bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength)
b, err := consensusblocks.NewSignedBeaconBlock(blk)
require.NoError(t, err)
return b
@@ -642,15 +584,8 @@ func Test_NotifyNewPayload(t *testing.T) {
name: "undefined error from ee",
postState: bellatrixState,
blk: func() interfaces.ReadOnlySignedBeaconBlock {
blk := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Body: &ethpb.BeaconBlockBodyBellatrix{
ExecutionPayload: &v1.ExecutionPayload{
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
},
},
},
}
blk := util.NewBeaconBlockBellatrix()
blk.Block.Body.ExecutionPayload.ParentHash = bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength)
b, err := consensusblocks.NewSignedBeaconBlock(blk)
require.NoError(t, err)
return b
@@ -662,15 +597,8 @@ func Test_NotifyNewPayload(t *testing.T) {
name: "invalid block hash error from ee",
postState: bellatrixState,
blk: func() interfaces.ReadOnlySignedBeaconBlock {
blk := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Body: &ethpb.BeaconBlockBodyBellatrix{
ExecutionPayload: &v1.ExecutionPayload{
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
},
},
},
}
blk := util.NewBeaconBlockBellatrix()
blk.Block.Body.ExecutionPayload.ParentHash = bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength)
b, err := consensusblocks.NewSignedBeaconBlock(blk)
require.NoError(t, err)
return b
@@ -701,7 +629,9 @@ func Test_NotifyNewPayload(t *testing.T) {
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
postVersion, postHeader, err := getStateVersionAndPayload(tt.postState)
require.NoError(t, err)
isValidPayload, err := service.notifyNewPayload(ctx, postVersion, postHeader, tt.blk)
rob, err := consensusblocks.NewROBlock(tt.blk)
require.NoError(t, err)
isValidPayload, err := service.notifyNewPayload(ctx, postVersion, postHeader, rob)
if tt.errString != "" {
require.ErrorContains(t, tt.errString, err)
if tt.invalidBlock {
@@ -725,17 +655,12 @@ func Test_NotifyNewPayload_SetOptimisticToValid(t *testing.T) {
ctx := tr.ctx
bellatrixState, _ := util.DeterministicGenesisStateBellatrix(t, 2)
blk := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Body: &ethpb.BeaconBlockBodyBellatrix{
ExecutionPayload: &v1.ExecutionPayload{
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
},
},
},
}
blk := util.NewBeaconBlockBellatrix()
blk.Block.Body.ExecutionPayload.ParentHash = bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength)
bellatrixBlk, err := consensusblocks.NewSignedBeaconBlock(blk)
require.NoError(t, err)
rob, err := consensusblocks.NewROBlock(bellatrixBlk)
require.NoError(t, err)
e := &mockExecution.EngineClient{BlockByHashMap: map[[32]byte]*v1.ExecutionBlock{}}
e.BlockByHashMap[[32]byte{'a'}] = &v1.ExecutionBlock{
Header: gethtypes.Header{
@@ -752,7 +677,7 @@ func Test_NotifyNewPayload_SetOptimisticToValid(t *testing.T) {
service.cfg.ExecutionEngineCaller = e
postVersion, postHeader, err := getStateVersionAndPayload(bellatrixState)
require.NoError(t, err)
validated, err := service.notifyNewPayload(ctx, postVersion, postHeader, bellatrixBlk)
validated, err := service.notifyNewPayload(ctx, postVersion, postHeader, rob)
require.NoError(t, err)
require.Equal(t, true, validated)
}

View File

@@ -248,7 +248,7 @@ func (s *Service) handleDA(ctx context.Context, avs das.AvailabilityStore, block
err = s.isDataAvailable(ctx, block)
}
elapsed := time.Since(start)
if err != nil {
if err == nil {
dataAvailWaitedTime.Observe(float64(elapsed.Milliseconds()))
}
return elapsed, err

View File

@@ -4,17 +4,26 @@ import (
"bytes"
"context"
"encoding/binary"
"time"
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v6/time/slots"
"github.com/pkg/errors"
bolt "go.etcd.io/bbolt"
)
var errTimeOut = errors.New("operation timed out")
// PruneAttestationsAtEpoch deletes all attestations from the slasher DB with target epoch
// less than or equal to the specified epoch.
func (s *Store) PruneAttestationsAtEpoch(
_ context.Context, maxEpoch primitives.Epoch,
ctx context.Context, maxEpoch primitives.Epoch,
) (numPruned uint, err error) {
// In some cases, pruning may take a very long time and consume significant memory in the
// open Update transaction. Therefore, we impose a 1 minute timeout on this operation.
ctx, cancel := context.WithTimeout(ctx, 1*time.Minute)
defer cancel()
// We can prune everything less than the current epoch - history length.
encodedEndPruneEpoch := make([]byte, 8)
binary.BigEndian.PutUint64(encodedEndPruneEpoch, uint64(maxEpoch))
@@ -48,13 +57,18 @@ func (s *Store) PruneAttestationsAtEpoch(
return
}
if err = s.db.Update(func(tx *bolt.Tx) error {
err = s.db.Update(func(tx *bolt.Tx) error {
signingRootsBkt := tx.Bucket(attestationDataRootsBucket)
attRecordsBkt := tx.Bucket(attestationRecordsBucket)
c := signingRootsBkt.Cursor()
// We begin a pruning iteration starting from the first item in the bucket.
for k, v := c.First(); k != nil; k, v = c.Next() {
if ctx.Err() != nil {
// Exit the routine if the context has expired.
return errTimeOut
}
// We check the epoch from the current key in the database.
// If we have hit an epoch that is greater than the end epoch of the pruning process,
// we then completely exit the process as we are done.
@@ -67,18 +81,27 @@ func (s *Store) PruneAttestationsAtEpoch(
// so it is possible we have a few adjacent objects that have the same slot, such as
// (target_epoch = 3 ++ _) => encode(attestation)
if err := signingRootsBkt.Delete(k); err != nil {
return err
return errors.Wrap(err, "delete attestation signing root")
}
if err := attRecordsBkt.Delete(v); err != nil {
return err
return errors.Wrap(err, "delete attestation record")
}
slasherAttestationsPrunedTotal.Inc()
numPruned++
}
return nil
}); err != nil {
})
if errors.Is(err, errTimeOut) {
log.Warning("Aborting pruning routine")
return
}
if err != nil {
log.WithError(err).Error("Failed to prune attestations")
return
}
return
}

View File

@@ -142,10 +142,9 @@ var ErrEmptyBlockHash = errors.New("Block hash is empty 0x0000...")
func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash, executionRequests *pb.ExecutionRequests) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.NewPayload")
defer span.End()
start := time.Now()
defer func() {
defer func(start time.Time) {
newPayloadLatency.Observe(float64(time.Since(start).Milliseconds()))
}()
}(time.Now())
d := time.Now().Add(time.Duration(params.BeaconConfig().ExecutionEngineTimeoutValue) * time.Second)
ctx, cancel := context.WithDeadline(ctx, d)
@@ -183,7 +182,10 @@ func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionDa
return nil, errors.New("unknown execution data type")
}
if result.ValidationError != "" {
log.WithError(errors.New(result.ValidationError)).Error("Got a validation error in newPayload")
log.WithField("status", result.Status.String()).
WithField("parentRoot", fmt.Sprintf("%#x", parentBlockRoot)).
WithError(errors.New(result.ValidationError)).
Error("Got a validation error in newPayload")
}
switch result.Status {
case pb.PayloadStatus_INVALID_BLOCK_HASH:
@@ -195,7 +197,7 @@ func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionDa
case pb.PayloadStatus_VALID:
return result.LatestValidHash, nil
default:
return nil, ErrUnknownPayloadStatus
return nil, errors.Wrapf(ErrUnknownPayloadStatus, "unknown payload status: %s", result.Status.String())
}
}

View File

@@ -928,7 +928,7 @@ func TestClient_HTTP(t *testing.T) {
wrappedPayload, err := blocks.WrappedExecutionPayload(execPayload)
require.NoError(t, err)
resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil)
require.ErrorIs(t, ErrUnknownPayloadStatus, err)
require.ErrorIs(t, err, ErrUnknownPayloadStatus)
require.DeepEqual(t, []uint8(nil), resp)
})
t.Run(BlockByNumberMethod, func(t *testing.T) {

View File

@@ -1465,8 +1465,7 @@ func (s *Server) GetBlockHeader(w http.ResponseWriter, r *http.Request) {
}
blk, err := s.Blocker.Block(ctx, []byte(blockID))
ok := shared.WriteBlockFetchError(w, blk, err)
if !ok {
if !shared.WriteBlockFetchError(w, blk, err) {
return
}
blockHeader, err := blk.Header()

View File

@@ -58,12 +58,7 @@ func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
}
blk, err := s.Blocker.Block(ctx, []byte(blockId))
if err != nil {
httputil.HandleError(w, "Could not fetch block: "+err.Error(), http.StatusInternalServerError)
return
}
if blk == nil {
httputil.HandleError(w, "Block not found", http.StatusNotFound)
if !shared.WriteBlockFetchError(w, blk, err) {
return
}
@@ -174,12 +169,7 @@ func (s *Server) GetBlobs(w http.ResponseWriter, r *http.Request) {
}
blk, err := s.Blocker.Block(ctx, []byte(blockId))
if err != nil {
httputil.HandleError(w, "Could not fetch block: "+err.Error(), http.StatusInternalServerError)
return
}
if blk == nil {
httputil.HandleError(w, "Block not found", http.StatusNotFound)
if !shared.WriteBlockFetchError(w, blk, err) {
return
}

View File

@@ -269,12 +269,7 @@ func (s *Server) DataColumnSidecars(w http.ResponseWriter, r *http.Request) {
}
blk, err := s.Blocker.Block(ctx, []byte(blockId))
if err != nil {
httputil.HandleError(w, "Could not fetch block: "+err.Error(), http.StatusInternalServerError)
return
}
if blk == nil {
httputil.HandleError(w, "Block not found", http.StatusNotFound)
if !shared.WriteBlockFetchError(w, blk, err) {
return
}

View File

@@ -29,6 +29,11 @@ func WriteStateFetchError(w http.ResponseWriter, err error) {
// WriteBlockFetchError writes an appropriate error based on the supplied argument.
// The argument error should be a result of fetching block.
func WriteBlockFetchError(w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock, err error) bool {
var blockNotFoundErr *lookup.BlockNotFoundError
if errors.As(err, &blockNotFoundErr) {
httputil.HandleError(w, "Block not found: "+blockNotFoundErr.Error(), http.StatusNotFound)
return false
}
var invalidBlockIdErr *lookup.BlockIdParseError
if errors.As(err, &invalidBlockIdErr) {
httputil.HandleError(w, "Invalid block ID: "+invalidBlockIdErr.Error(), http.StatusBadRequest)

View File

@@ -49,3 +49,59 @@ func TestWriteStateFetchError(t *testing.T) {
assert.NoError(t, json.Unmarshal(writer.Body.Bytes(), e), "failed to unmarshal response")
}
}
// TestWriteBlockFetchError tests the WriteBlockFetchError function
// to ensure that the correct error message and code are written to the response
// and that the function returns the correct boolean value.
func TestWriteBlockFetchError(t *testing.T) {
cases := []struct {
name string
err error
expectedMessage string
expectedCode int
expectedReturn bool
}{
{
name: "BlockNotFoundError should return 404",
err: lookup.NewBlockNotFoundError("block not found at slot 123"),
expectedMessage: "Block not found",
expectedCode: http.StatusNotFound,
expectedReturn: false,
},
{
name: "BlockIdParseError should return 400",
err: &lookup.BlockIdParseError{},
expectedMessage: "Invalid block ID",
expectedCode: http.StatusBadRequest,
expectedReturn: false,
},
{
name: "Generic error should return 500",
err: errors.New("database connection failed"),
expectedMessage: "Could not get block from block ID",
expectedCode: http.StatusInternalServerError,
expectedReturn: false,
},
{
name: "Nil block should return 404",
err: nil,
expectedMessage: "Could not find requested block",
expectedCode: http.StatusNotFound,
expectedReturn: false,
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
writer := httptest.NewRecorder()
result := WriteBlockFetchError(writer, nil, c.err)
assert.Equal(t, c.expectedReturn, result, "incorrect return value")
assert.Equal(t, c.expectedCode, writer.Code, "incorrect status code")
assert.StringContains(t, c.expectedMessage, writer.Body.String(), "incorrect error message")
e := &httputil.DefaultJsonError{}
assert.NoError(t, json.Unmarshal(writer.Body.Bytes(), e), "failed to unmarshal response")
})
}
}

View File

@@ -0,0 +1,3 @@
### Fixed
- da metric was not writing correctly because if statement on err was accidently flipped

View File

@@ -0,0 +1,3 @@
### Fixed
- fixed regression introduced in PR #15715 , blocker now returns an error for not found, and error handling correctly handles error and returns 404 instead of 500

View File

@@ -0,0 +1,2 @@
### Ignored
- Adding context to logs around execution engine notification failures.

View File

@@ -0,0 +1,3 @@
### Changed
- Updated go.mod to v1.25.1

View File

@@ -0,0 +1,3 @@
### Changed
- Updated quick-go to latest version.

View File

@@ -0,0 +1,3 @@
### Added
- Update spectests to 1.6.0-beta.0

View File

@@ -0,0 +1,3 @@
### Ignored
- Updated the changelog for v6.0.5 release

View File

@@ -0,0 +1,2 @@
### Added
- Added a 1 minute timeout on PruneAttestationOnEpoch operations to prevent very large bolt transactions

View File

@@ -0,0 +1,3 @@
### Fixed
- SSZ-QL: Support nested `List` type (e.g., `ExecutionPayload.Transactions`)

View File

@@ -0,0 +1,3 @@
### Ignored
- Update golangci-lint config to enable only basic linters that currently pass

View File

@@ -2915,8 +2915,8 @@ def prysm_deps():
"gazelle:exclude tools.go",
],
importpath = "github.com/quic-go/quic-go",
sum = "h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94=",
version = "v0.49.0",
sum = "h1:x09Agz4ATTMEP3qb5P0MRxNZfd6O9wAyK3qwwqQZVQc=",
version = "v0.49.1-0.20250925085836-275c172fec2b",
)
go_repository(
name = "com_github_quic_go_webtransport_go",

View File

@@ -60,9 +60,21 @@ func PopulateVariableLengthInfo(sszInfo *sszInfo, value any) error {
if val.Kind() != reflect.Slice {
return fmt.Errorf("expected slice for List type, got %v", val.Kind())
}
length := val.Len()
length := uint64(val.Len())
if err := listInfo.SetLength(length); err != nil {
if listInfo.element.isVariable {
listInfo.elementSizes = make([]uint64, 0, length)
// Populate nested variable-sized type element lengths recursively.
for i := range length {
if err := PopulateVariableLengthInfo(listInfo.element, val.Index(i).Interface()); err != nil {
return fmt.Errorf("could not populate nested list element at index %d: %w", i, err)
}
listInfo.elementSizes = append(listInfo.elementSizes, listInfo.element.Size())
}
}
if err := listInfo.SetLength(uint64(length)); err != nil {
return fmt.Errorf("could not set list length: %w", err)
}
@@ -111,15 +123,20 @@ func PopulateVariableLengthInfo(sszInfo *sszInfo, value any) error {
continue
}
// Set the actual offset for variable-sized fields.
fieldInfo.offset = currentOffset
// Recursively populate variable-sized fields.
fieldValue := derefValue.FieldByName(fieldInfo.goFieldName)
if err := PopulateVariableLengthInfo(childSszInfo, fieldValue.Interface()); err != nil {
return fmt.Errorf("could not populate from value for field %s: %w", fieldName, err)
}
// Each variable-sized element needs an offset entry.
if childSszInfo.sszType == List {
currentOffset += childSszInfo.listInfo.OffsetBytes()
}
// Set the actual offset for variable-sized fields.
fieldInfo.offset = currentOffset
currentOffset += childSszInfo.Size()
}

View File

@@ -16,6 +16,8 @@ type listInfo struct {
element *sszInfo
// length is the actual number of elements at runtime (0 if not set).
length uint64
// elementSizes caches each element's byte size for variable-sized type elements
elementSizes []uint64
}
func (l *listInfo) Limit() uint64 {
@@ -51,3 +53,35 @@ func (l *listInfo) SetLength(length uint64) error {
l.length = length
return nil
}
func (l *listInfo) Size() uint64 {
if l == nil {
return 0
}
// For fixed-sized type elements, size is multiplying length by element size.
if !l.element.isVariable {
return l.length * l.element.Size()
}
// For variable-sized type elements, sum up the sizes of each element.
totalSize := uint64(0)
for _, sz := range l.elementSizes {
totalSize += sz
}
return totalSize
}
// OffsetBytes returns the total number of offset bytes used for the list elements.
// Each variable-sized element uses 4 bytes to store its offset.
func (l *listInfo) OffsetBytes() uint64 {
if l == nil {
return 0
}
if !l.element.isVariable {
return 0
}
return offsetBytes * l.length
}

View File

@@ -133,56 +133,73 @@ func TestCalculateOffsetAndLength(t *testing.T) {
{
name: "field_list_uint64",
path: ".field_list_uint64",
expectedOffset: 108, // First part of variable-sized type.
expectedOffset: 112, // First part of variable-sized type.
expectedLength: 40, // 5 elements * uint64 (8 bytes each)
},
{
name: "field_list_container",
path: ".field_list_container",
expectedOffset: 148, // Second part of variable-sized type.
expectedOffset: 152, // Second part of variable-sized type.
expectedLength: 120, // 3 elements * FixedNestedContainer (40 bytes each)
},
{
name: "field_list_bytes32",
path: ".field_list_bytes32",
expectedOffset: 268,
expectedOffset: 272,
expectedLength: 96, // 3 elements * 32 bytes each
},
// Nested paths
{
name: "nested",
path: ".nested",
expectedOffset: 364,
expectedOffset: 368,
// Calculated with:
// - Value1: 8 bytes
// - field_list_uint64 offset: 4 bytes
// - field_list_uint64 length: 40 bytes
expectedLength: 52,
// - nested_list_field offset: 4 bytes
// - nested_list_field length: 99 bytes
// - 3 offset pointers for each element in nested_list_field: 12 bytes
// Total: 8 + 4 + 40 + 4 + 99 + 12 = 167 bytes
expectedLength: 167,
},
{
name: "nested.value1",
path: ".nested.value1",
expectedOffset: 364,
expectedOffset: 368,
expectedLength: 8,
},
{
name: "nested.field_list_uint64",
path: ".nested.field_list_uint64",
expectedOffset: 376,
expectedOffset: 384,
expectedLength: 40,
},
{
name: "nested.nested_list_field",
path: ".nested.nested_list_field",
expectedOffset: 436,
expectedLength: 99,
},
// Bitlist field
{
name: "bitlist_field",
path: ".bitlist_field",
expectedOffset: 416,
expectedOffset: 535,
expectedLength: 33, // 32 bytes + 1 byte for length delimiter
},
// 2D bytes field
{
name: "nested_list_field",
path: ".nested_list_field",
expectedOffset: 580,
expectedLength: 99,
},
// Fixed trailing field
{
name: "trailing_field",
path: ".trailing_field",
expectedOffset: 52, // After leading_field + 5 offset pointers
expectedOffset: 56, // After leading_field + 6 offset pointers
expectedLength: 56,
},
}
@@ -377,6 +394,15 @@ func createVariableTestContainer() *sszquerypb.VariableTestContainer {
bitlistField.SetBitAt(100, true)
bitlistField.SetBitAt(255, true)
// Total size: 3 lists with lengths 32, 33, and 34 = 99 bytes
nestedListField := make([][]byte, 3)
for i := range nestedListField {
nestedListField[i] = make([]byte, (32 + i)) // Different lengths for each sub-list
for j := range nestedListField[i] {
nestedListField[i][j] = byte(j + i*16)
}
}
return &sszquerypb.VariableTestContainer{
// Fixed leading field
LeadingField: leadingField,
@@ -394,11 +420,15 @@ func createVariableTestContainer() *sszquerypb.VariableTestContainer {
Nested: &sszquerypb.VariableNestedContainer{
Value1: 42,
FieldListUint64: []uint64{1, 2, 3, 4, 5},
NestedListField: nestedListField,
},
// Bitlist field
BitlistField: bitlistField,
// 2D bytes field
NestedListField: nestedListField,
// Fixed trailing field
TrailingField: trailingField,
}
@@ -445,11 +475,20 @@ func getVariableTestContainerSpec() testutil.TestSpec {
Path: ".nested.field_list_uint64",
Expected: testContainer.Nested.FieldListUint64,
},
{
Path: ".nested.nested_list_field",
Expected: testContainer.Nested.NestedListField,
},
// Bitlist field
{
Path: ".bitlist_field",
Expected: testContainer.BitlistField,
},
// 2D bytes field
{
Path: ".nested_list_field",
Expected: testContainer.NestedListField,
},
// Fixed trailing field
{
Path: ".trailing_field",

View File

@@ -54,10 +54,7 @@ func (info *sszInfo) Size() uint64 {
switch info.sszType {
case List:
length := info.listInfo.length
elementSize := info.listInfo.element.Size()
return length * elementSize
return info.listInfo.Size()
case Bitlist:
return info.bitlistInfo.Size()
@@ -69,6 +66,11 @@ func (info *sszInfo) Size() uint64 {
continue
}
// Include offset bytes inside nested lists.
if fieldInfo.sszInfo.sszType == List {
size += fieldInfo.sszInfo.listInfo.OffsetBytes()
}
size += fieldInfo.sszInfo.Size()
}
return size

View File

@@ -31,10 +31,10 @@ func RunStructTest(t *testing.T, spec TestSpec) {
_, offset, length, err := query.CalculateOffsetAndLength(info, path)
require.NoError(t, err)
expectedRawBytes := marshalledData[offset : offset+length]
rawBytes, err := marshalAny(pathTest.Expected)
actualRawBytes := marshalledData[offset : offset+length]
expectedRawBytes, err := marshalAny(pathTest.Expected)
require.NoError(t, err, "Marshalling expected value should not return an error")
require.DeepEqual(t, expectedRawBytes, rawBytes, "Extracted value should match expected")
require.DeepEqual(t, actualRawBytes, expectedRawBytes, "Extracted value should match expected")
})
}
})

4
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/OffchainLabs/prysm/v6
go 1.24.5
go 1.25.1
require (
github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20240516070431-7828990cad7d
@@ -238,7 +238,7 @@ require (
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.49.0 // indirect
github.com/quic-go/quic-go v0.49.1-0.20250925085836-275c172fec2b // indirect
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect

4
go.sum
View File

@@ -916,8 +916,8 @@ github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294 h
github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.49.0 h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94=
github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s=
github.com/quic-go/quic-go v0.49.1-0.20250925085836-275c172fec2b h1:x09Agz4ATTMEP3qb5P0MRxNZfd6O9wAyK3qwwqQZVQc=
github.com/quic-go/quic-go v0.49.1-0.20250925085836-275c172fec2b/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s=
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0=

View File

@@ -195,6 +195,7 @@ type VariableNestedContainer struct {
state protoimpl.MessageState `protogen:"open.v1"`
Value1 uint64 `protobuf:"varint,1,opt,name=value1,proto3" json:"value1,omitempty"`
FieldListUint64 []uint64 `protobuf:"varint,2,rep,packed,name=field_list_uint64,json=fieldListUint64,proto3" json:"field_list_uint64,omitempty" ssz-max:"100"`
NestedListField [][]byte `protobuf:"bytes,3,rep,name=nested_list_field,json=nestedListField,proto3" json:"nested_list_field,omitempty" ssz-max:"100,50" ssz-size:"?,?"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -243,6 +244,13 @@ func (x *VariableNestedContainer) GetFieldListUint64() []uint64 {
return nil
}
func (x *VariableNestedContainer) GetNestedListField() [][]byte {
if x != nil {
return x.NestedListField
}
return nil
}
type VariableTestContainer struct {
state protoimpl.MessageState `protogen:"open.v1"`
LeadingField []byte `protobuf:"bytes,1,opt,name=leading_field,json=leadingField,proto3" json:"leading_field,omitempty" ssz-size:"32"`
@@ -251,7 +259,8 @@ type VariableTestContainer struct {
FieldListBytes32 [][]byte `protobuf:"bytes,4,rep,name=field_list_bytes32,json=fieldListBytes32,proto3" json:"field_list_bytes32,omitempty" ssz-max:"100" ssz-size:"?,32"`
Nested *VariableNestedContainer `protobuf:"bytes,5,opt,name=nested,proto3" json:"nested,omitempty"`
BitlistField github_com_prysmaticlabs_go_bitfield.Bitlist `protobuf:"bytes,6,opt,name=bitlist_field,json=bitlistField,proto3" json:"bitlist_field,omitempty" cast-type:"github.com/prysmaticlabs/go-bitfield.Bitlist" ssz-max:"2048"`
TrailingField []byte `protobuf:"bytes,7,opt,name=trailing_field,json=trailingField,proto3" json:"trailing_field,omitempty" ssz-size:"56"`
NestedListField [][]byte `protobuf:"bytes,7,rep,name=nested_list_field,json=nestedListField,proto3" json:"nested_list_field,omitempty" ssz-max:"100,50" ssz-size:"?,?"`
TrailingField []byte `protobuf:"bytes,8,opt,name=trailing_field,json=trailingField,proto3" json:"trailing_field,omitempty" ssz-size:"56"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -328,6 +337,13 @@ func (x *VariableTestContainer) GetBitlistField() github_com_prysmaticlabs_go_bi
return github_com_prysmaticlabs_go_bitfield.Bitlist(nil)
}
func (x *VariableTestContainer) GetNestedListField() [][]byte {
if x != nil {
return x.NestedListField
}
return nil
}
func (x *VariableTestContainer) GetTrailingField() []byte {
if x != nil {
return x.TrailingField
@@ -384,14 +400,18 @@ var file_proto_ssz_query_ssz_query_proto_rawDesc = []byte{
0x74, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x35, 0x31, 0x32, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12,
0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c,
0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x35, 0x36, 0x52,
0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x66,
0x0a, 0x17, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x31, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f,
0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x42, 0x07, 0x92, 0xb5,
0x18, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4c, 0x69, 0x73, 0x74,
0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x22, 0xdf, 0x03, 0x0a, 0x15, 0x56, 0x61, 0x72, 0x69, 0x61,
0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0xa5,
0x01, 0x0a, 0x17, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65,
0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x31, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74,
0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x42, 0x07, 0x92,
0xb5, 0x18, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4c, 0x69, 0x73,
0x74, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x3d, 0x0a, 0x11, 0x6e, 0x65, 0x73, 0x74, 0x65,
0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0c, 0x42, 0x11, 0x8a, 0xb5, 0x18, 0x03, 0x3f, 0x2c, 0x3f, 0x92, 0xb5, 0x18, 0x06, 0x31,
0x30, 0x30, 0x2c, 0x35, 0x30, 0x52, 0x0f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4c, 0x69, 0x73,
0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x9e, 0x04, 0x0a, 0x15, 0x56, 0x61, 0x72, 0x69, 0x61,
0x62, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x12, 0x2b, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52,
@@ -418,14 +438,18 @@ var file_proto_ssz_query_ssz_query_proto_rawDesc = []byte{
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
0x67, 0x6f, 0x2d, 0x62, 0x69, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x42, 0x69, 0x74, 0x6c,
0x69, 0x73, 0x74, 0x92, 0xb5, 0x18, 0x04, 0x32, 0x30, 0x34, 0x38, 0x52, 0x0c, 0x62, 0x69, 0x74,
0x6c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61,
0x69, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28,
0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x35, 0x36, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c,
0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c,
0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2f, 0x73, 0x73, 0x7a, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
0x6c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x3d, 0x0a, 0x11, 0x6e, 0x65, 0x73,
0x74, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x07,
0x20, 0x03, 0x28, 0x0c, 0x42, 0x11, 0x8a, 0xb5, 0x18, 0x03, 0x3f, 0x2c, 0x3f, 0x92, 0xb5, 0x18,
0x06, 0x31, 0x30, 0x30, 0x2c, 0x35, 0x30, 0x52, 0x0f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4c,
0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x69,
0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c,
0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x35, 0x36, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69,
0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61,
0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x73, 0x73, 0x7a, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (

View File

@@ -65,6 +65,10 @@ message FixedTestContainer {
message VariableNestedContainer {
uint64 value1 = 1;
repeated uint64 field_list_uint64 = 2 [ (ethereum.eth.ext.ssz_max) = "100" ];
repeated bytes nested_list_field = 3 [
(ethereum.eth.ext.ssz_size) = "?,?",
(ethereum.eth.ext.ssz_max) = "100,50"
];
}
// VariableTestContainer - comprehensive variable-size container for SSZ query testing
@@ -96,7 +100,14 @@ message VariableTestContainer {
"github.com/prysmaticlabs/go-bitfield.Bitlist"
];
// 2D bytes list - test list of bytelists.
// e.g., ExecutionPayload.transactions
repeated bytes nested_list_field = 7 [
(ethereum.eth.ext.ssz_size) = "?,?",
(ethereum.eth.ext.ssz_max) = "100,50"
];
// Fixed-size trailing field - test fixed field after variable fields
// Verifies correct offset calculation after variable-size fields
bytes trailing_field = 7 [ (ethereum.eth.ext.ssz_size) = "56" ]; // Test: fixed 56-byte field at end, offset: 32 + 4 + 4 + 4 + 4 + 4 = 52
bytes trailing_field = 8 [ (ethereum.eth.ext.ssz_size) = "56" ]; // Test: fixed 56-byte field at end, offset: 32 + 4 + 4 + 4 + 4 + 4 + 4 = 56
}

View File

@@ -324,7 +324,7 @@ func (v *VariableNestedContainer) MarshalSSZ() ([]byte, error) {
// MarshalSSZTo ssz marshals the VariableNestedContainer object to a target array
func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(12)
offset := int(16)
// Field (0) 'Value1'
dst = ssz.MarshalUint64(dst, v.Value1)
@@ -333,6 +333,13 @@ func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err erro
dst = ssz.WriteOffset(dst, offset)
offset += len(v.FieldListUint64) * 8
// Offset (2) 'NestedListField'
dst = ssz.WriteOffset(dst, offset)
for ii := 0; ii < len(v.NestedListField); ii++ {
offset += 4
offset += len(v.NestedListField[ii])
}
// Field (1) 'FieldListUint64'
if size := len(v.FieldListUint64); size > 100 {
err = ssz.ErrListTooBigFn("--.FieldListUint64", size, 100)
@@ -342,6 +349,26 @@ func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err erro
dst = ssz.MarshalUint64(dst, v.FieldListUint64[ii])
}
// Field (2) 'NestedListField'
if size := len(v.NestedListField); size > 100 {
err = ssz.ErrListTooBigFn("--.NestedListField", size, 100)
return
}
{
offset = 4 * len(v.NestedListField)
for ii := 0; ii < len(v.NestedListField); ii++ {
dst = ssz.WriteOffset(dst, offset)
offset += len(v.NestedListField[ii])
}
}
for ii := 0; ii < len(v.NestedListField); ii++ {
if size := len(v.NestedListField[ii]); size > 50 {
err = ssz.ErrBytesLengthFn("--.NestedListField[ii]", size, 50)
return
}
dst = append(dst, v.NestedListField[ii]...)
}
return
}
@@ -349,12 +376,12 @@ func (v *VariableNestedContainer) MarshalSSZTo(buf []byte) (dst []byte, err erro
func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 12 {
if size < 16 {
return ssz.ErrSize
}
tail := buf
var o1 uint64
var o1, o2 uint64
// Field (0) 'Value1'
v.Value1 = ssz.UnmarshallUint64(buf[0:8])
@@ -364,13 +391,18 @@ func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
if o1 != 12 {
if o1 != 16 {
return ssz.ErrInvalidVariableOffset
}
// Offset (2) 'NestedListField'
if o2 = ssz.ReadOffset(buf[12:16]); o2 > size || o1 > o2 {
return ssz.ErrOffset
}
// Field (1) 'FieldListUint64'
{
buf = tail[o1:]
buf = tail[o1:o2]
num, err := ssz.DivideInt2(len(buf), 8, 100)
if err != nil {
return err
@@ -380,16 +412,45 @@ func (v *VariableNestedContainer) UnmarshalSSZ(buf []byte) error {
v.FieldListUint64[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8])
}
}
// Field (2) 'NestedListField'
{
buf = tail[o2:]
num, err := ssz.DecodeDynamicLength(buf, 100)
if err != nil {
return err
}
v.NestedListField = make([][]byte, num)
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
if len(buf) > 50 {
return ssz.ErrBytesLength
}
if cap(v.NestedListField[indx]) == 0 {
v.NestedListField[indx] = make([]byte, 0, len(buf))
}
v.NestedListField[indx] = append(v.NestedListField[indx], buf...)
return nil
})
if err != nil {
return err
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the VariableNestedContainer object
func (v *VariableNestedContainer) SizeSSZ() (size int) {
size = 12
size = 16
// Field (1) 'FieldListUint64'
size += len(v.FieldListUint64) * 8
// Field (2) 'NestedListField'
for ii := 0; ii < len(v.NestedListField); ii++ {
size += 4
size += len(v.NestedListField[ii])
}
return
}
@@ -421,6 +482,29 @@ func (v *VariableNestedContainer) HashTreeRootWith(hh *ssz.Hasher) (err error) {
hh.MerkleizeWithMixin(subIndx, numItems, ssz.CalculateLimit(100, numItems, 8))
}
// Field (2) 'NestedListField'
{
subIndx := hh.Index()
num := uint64(len(v.NestedListField))
if num > 100 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range v.NestedListField {
{
elemIndx := hh.Index()
byteLen := uint64(len(elem))
if byteLen > 50 {
err = ssz.ErrIncorrectListSize
return
}
hh.AppendBytes32(elem)
hh.MerkleizeWithMixin(elemIndx, byteLen, (50+31)/32)
}
}
hh.MerkleizeWithMixin(subIndx, num, 100)
}
hh.Merkleize(indx)
return
}
@@ -433,7 +517,7 @@ func (v *VariableTestContainer) MarshalSSZ() ([]byte, error) {
// MarshalSSZTo ssz marshals the VariableTestContainer object to a target array
func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(108)
offset := int(112)
// Field (0) 'LeadingField'
if size := len(v.LeadingField); size != 32 {
@@ -465,7 +549,14 @@ func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error)
dst = ssz.WriteOffset(dst, offset)
offset += len(v.BitlistField)
// Field (6) 'TrailingField'
// Offset (6) 'NestedListField'
dst = ssz.WriteOffset(dst, offset)
for ii := 0; ii < len(v.NestedListField); ii++ {
offset += 4
offset += len(v.NestedListField[ii])
}
// Field (7) 'TrailingField'
if size := len(v.TrailingField); size != 56 {
err = ssz.ErrBytesLengthFn("--.TrailingField", size, 56)
return
@@ -517,6 +608,26 @@ func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error)
}
dst = append(dst, v.BitlistField...)
// Field (6) 'NestedListField'
if size := len(v.NestedListField); size > 100 {
err = ssz.ErrListTooBigFn("--.NestedListField", size, 100)
return
}
{
offset = 4 * len(v.NestedListField)
for ii := 0; ii < len(v.NestedListField); ii++ {
dst = ssz.WriteOffset(dst, offset)
offset += len(v.NestedListField[ii])
}
}
for ii := 0; ii < len(v.NestedListField); ii++ {
if size := len(v.NestedListField[ii]); size > 50 {
err = ssz.ErrBytesLengthFn("--.NestedListField[ii]", size, 50)
return
}
dst = append(dst, v.NestedListField[ii]...)
}
return
}
@@ -524,12 +635,12 @@ func (v *VariableTestContainer) MarshalSSZTo(buf []byte) (dst []byte, err error)
func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 108 {
if size < 112 {
return ssz.ErrSize
}
tail := buf
var o1, o2, o3, o4, o5 uint64
var o1, o2, o3, o4, o5, o6 uint64
// Field (0) 'LeadingField'
if cap(v.LeadingField) == 0 {
@@ -542,7 +653,7 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
if o1 != 108 {
if o1 != 112 {
return ssz.ErrInvalidVariableOffset
}
@@ -566,11 +677,16 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
// Field (6) 'TrailingField'
if cap(v.TrailingField) == 0 {
v.TrailingField = make([]byte, 0, len(buf[52:108]))
// Offset (6) 'NestedListField'
if o6 = ssz.ReadOffset(buf[52:56]); o6 > size || o5 > o6 {
return ssz.ErrOffset
}
v.TrailingField = append(v.TrailingField, buf[52:108]...)
// Field (7) 'TrailingField'
if cap(v.TrailingField) == 0 {
v.TrailingField = make([]byte, 0, len(buf[56:112]))
}
v.TrailingField = append(v.TrailingField, buf[56:112]...)
// Field (1) 'FieldListUint64'
{
@@ -632,7 +748,7 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
// Field (5) 'BitlistField'
{
buf = tail[o5:]
buf = tail[o5:o6]
if err = ssz.ValidateBitlist(buf, 2048); err != nil {
return err
}
@@ -641,12 +757,35 @@ func (v *VariableTestContainer) UnmarshalSSZ(buf []byte) error {
}
v.BitlistField = append(v.BitlistField, buf...)
}
// Field (6) 'NestedListField'
{
buf = tail[o6:]
num, err := ssz.DecodeDynamicLength(buf, 100)
if err != nil {
return err
}
v.NestedListField = make([][]byte, num)
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
if len(buf) > 50 {
return ssz.ErrBytesLength
}
if cap(v.NestedListField[indx]) == 0 {
v.NestedListField[indx] = make([]byte, 0, len(buf))
}
v.NestedListField[indx] = append(v.NestedListField[indx], buf...)
return nil
})
if err != nil {
return err
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the VariableTestContainer object
func (v *VariableTestContainer) SizeSSZ() (size int) {
size = 108
size = 112
// Field (1) 'FieldListUint64'
size += len(v.FieldListUint64) * 8
@@ -666,6 +805,12 @@ func (v *VariableTestContainer) SizeSSZ() (size int) {
// Field (5) 'BitlistField'
size += len(v.BitlistField)
// Field (6) 'NestedListField'
for ii := 0; ii < len(v.NestedListField); ii++ {
size += 4
size += len(v.NestedListField[ii])
}
return
}
@@ -748,7 +893,30 @@ func (v *VariableTestContainer) HashTreeRootWith(hh *ssz.Hasher) (err error) {
}
hh.PutBitlist(v.BitlistField, 2048)
// Field (6) 'TrailingField'
// Field (6) 'NestedListField'
{
subIndx := hh.Index()
num := uint64(len(v.NestedListField))
if num > 100 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range v.NestedListField {
{
elemIndx := hh.Index()
byteLen := uint64(len(elem))
if byteLen > 50 {
err = ssz.ErrIncorrectListSize
return
}
hh.AppendBytes32(elem)
hh.MerkleizeWithMixin(elemIndx, byteLen, (50+31)/32)
}
}
hh.MerkleizeWithMixin(subIndx, num, 100)
}
// Field (7) 'TrailingField'
if size := len(v.TrailingField); size != 56 {
err = ssz.ErrBytesLengthFn("--.TrailingField", size, 56)
return

View File

@@ -1,4 +1,4 @@
version: v1.6.0-alpha.6
version: v1.6.0-beta.0
style: full
specrefs:
@@ -90,14 +90,14 @@ exceptions:
- BuilderPendingWithdrawal#gloas
- DataColumnSidecar#gloas
- ExecutionPayloadEnvelope#gloas
- ExecutionPayloadHeader#gloas
- ExecutionPayloadBid#gloas
- ForkChoiceNode#gloas
- IndexedPayloadAttestation#gloas
- PayloadAttestation#gloas
- PayloadAttestationData#gloas
- PayloadAttestationMessage#gloas
- SignedExecutionPayloadEnvelope#gloas
- SignedExecutionPayloadHeader#gloas
- SignedExecutionPayloadBid#gloas
dataclasses:
# Not implemented
@@ -172,7 +172,9 @@ exceptions:
- compute_pulled_up_tip#phase0
- filter_block_tree#phase0
- get_aggregate_and_proof#phase0
- get_aggregate_due_ms#phase0
- get_attestation_component_deltas#phase0
- get_attestation_due_ms#phase0
- get_attesting_balance#phase0
- get_base_reward#phase0
- get_checkpoint_block#phase0
@@ -186,6 +188,7 @@ exceptions:
- get_matching_source_attestations#phase0
- get_matching_target_attestations#phase0
- get_proposer_head#phase0
- get_proposer_reorg_cutoff_ms#phase0
- get_proposer_score#phase0
- get_slot_component_duration_ms#phase0
- get_slot_signature#phase0
@@ -214,11 +217,13 @@ exceptions:
- compute_sync_committee_period_at_slot#altair
- compute_timestamp_at_slot#bellatrix
- get_contribution_and_proof#altair
- get_contribution_due_ms#altair
- get_index_for_new_validator#altair
- get_safety_threshold#altair
- get_subtree_index#altair
- get_sync_committee_message#altair
- get_sync_committee_selection_proof#altair
- get_sync_message_due_ms#altair
- get_unslashed_participating_indices#altair
- is_assigned_to_sync_committee#altair
- is_finality_update#altair
@@ -294,13 +299,17 @@ exceptions:
- compute_fork_version#gloas
- compute_proposer_indices#gloas
- get_ancestor#gloas
- get_aggregate_due_ms#gloas
- get_attestation_due_ms#gloas
- get_attestation_participation_flag_indices#gloas
- get_builder_payment_quorum_threshold#gloas
- get_checkpoint_block#gloas
- get_contribution_due_ms#gloas
- get_data_column_sidecars#gloas
- get_data_column_sidecars_from_block#gloas
- get_data_column_sidecars_from_column_sidecar#gloas
- get_execution_payload_envelope_signature#gloas
- get_execution_payload_header_signature#gloas
- get_execution_payload_bid_signature#gloas
- get_expected_withdrawals#gloas
- get_forkchoice_store#gloas
- get_head#gloas
@@ -308,8 +317,11 @@ exceptions:
- get_next_sync_committee_indices#gloas
- get_node_children#gloas
- get_parent_payload_status#gloas
- get_payload_attestation_due_ms#gloas
- get_payload_attestation_message_signature#gloas
- get_payload_status_tiebreaker#gloas
- get_pending_balance_to_withdraw#gloas
- get_sync_message_due_ms#gloas
- get_ptc#gloas
- get_ptc_assignment#gloas
- get_weight#gloas
@@ -334,9 +346,10 @@ exceptions:
- process_builder_pending_payments#gloas
- process_epoch#gloas
- process_execution_payload#gloas
- process_execution_payload_header#gloas
- process_execution_payload_bid#gloas
- process_operations#gloas
- process_payload_attestation#gloas
- process_proposer_slashing#gloas
- process_slot#gloas
- process_withdrawals#gloas
- remove_flag#gloas
@@ -347,4 +360,4 @@ exceptions:
- validate_on_attestation#gloas
- verify_data_column_sidecar_inclusion_proof#gloas
- verify_execution_payload_envelope_signature#gloas
- verify_execution_payload_header_signature#gloas
- verify_execution_payload_bid_signature#gloas

View File

@@ -4200,11 +4200,12 @@
- name: is_proposing_on_time
sources: []
spec: |
<spec fn="is_proposing_on_time" fork="phase0" hash="cadfde05">
<spec fn="is_proposing_on_time" fork="phase0" hash="dc5256b4">
def is_proposing_on_time(store: Store) -> bool:
seconds_since_genesis = store.time - store.genesis_time
time_into_slot_ms = seconds_to_milliseconds(seconds_since_genesis) % SLOT_DURATION_MS
proposer_reorg_cutoff_ms = get_slot_component_duration_ms(PROPOSER_REORG_CUTOFF_BPS)
epoch = get_current_store_epoch(store)
proposer_reorg_cutoff_ms = get_proposer_reorg_cutoff_ms(epoch)
return time_into_slot_ms <= proposer_reorg_cutoff_ms
</spec>
@@ -4655,7 +4656,7 @@
- file: beacon-chain/blockchain/receive_block.go
search: func (s *Service) ReceiveBlock(
spec: |
<spec fn="on_block" fork="phase0" hash="0bd081f0">
<spec fn="on_block" fork="phase0" hash="aff24b59">
def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
block = signed_block.message
# Parent block must be known
@@ -4688,7 +4689,8 @@
# Add block timeliness to the store
seconds_since_genesis = store.time - store.genesis_time
time_into_slot_ms = seconds_to_milliseconds(seconds_since_genesis) % SLOT_DURATION_MS
attestation_threshold_ms = get_slot_component_duration_ms(ATTESTATION_DUE_BPS)
epoch = get_current_store_epoch(store)
attestation_threshold_ms = get_attestation_due_ms(epoch)
is_before_attesting_interval = time_into_slot_ms < attestation_threshold_ms
is_timely = get_current_slot(store) == block.slot and is_before_attesting_interval
store.block_timeliness[hash_tree_root(block)] = is_timely
@@ -4710,7 +4712,7 @@
- file: beacon-chain/blockchain/receive_block.go
search: func (s *Service) ReceiveBlock(
spec: |
<spec fn="on_block" fork="bellatrix" hash="cceac63a">
<spec fn="on_block" fork="bellatrix" hash="a3193d92">
def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
"""
Run ``on_block`` upon receiving a new block.
@@ -4754,7 +4756,8 @@
# Add block timeliness to the store
seconds_since_genesis = store.time - store.genesis_time
time_into_slot_ms = seconds_to_milliseconds(seconds_since_genesis) % SLOT_DURATION_MS
attestation_threshold_ms = get_slot_component_duration_ms(ATTESTATION_DUE_BPS)
epoch = get_current_store_epoch(store)
attestation_threshold_ms = get_attestation_due_ms(epoch)
is_before_attesting_interval = time_into_slot_ms < attestation_threshold_ms
is_timely = get_current_slot(store) == block.slot and is_before_attesting_interval
store.block_timeliness[hash_tree_root(block)] = is_timely
@@ -4776,7 +4779,7 @@
- file: beacon-chain/blockchain/receive_block.go
search: func (s *Service) ReceiveBlock(
spec: |
<spec fn="on_block" fork="capella" hash="b051b7c6">
<spec fn="on_block" fork="capella" hash="560056ad">
def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
"""
Run ``on_block`` upon receiving a new block.
@@ -4812,7 +4815,8 @@
# Add block timeliness to the store
seconds_since_genesis = store.time - store.genesis_time
time_into_slot_ms = seconds_to_milliseconds(seconds_since_genesis) % SLOT_DURATION_MS
attestation_threshold_ms = get_slot_component_duration_ms(ATTESTATION_DUE_BPS)
epoch = get_current_store_epoch(store)
attestation_threshold_ms = get_attestation_due_ms(epoch)
is_before_attesting_interval = time_into_slot_ms < attestation_threshold_ms
is_timely = get_current_slot(store) == block.slot and is_before_attesting_interval
store.block_timeliness[hash_tree_root(block)] = is_timely
@@ -4834,7 +4838,7 @@
- file: beacon-chain/blockchain/receive_block.go
search: func (s *Service) ReceiveBlock(
spec: |
<spec fn="on_block" fork="deneb" hash="1f48df4d">
<spec fn="on_block" fork="deneb" hash="9565acee">
def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
"""
Run ``on_block`` upon receiving a new block.
@@ -4875,7 +4879,8 @@
# Add block timeliness to the store
seconds_since_genesis = store.time - store.genesis_time
time_into_slot_ms = seconds_to_milliseconds(seconds_since_genesis) % SLOT_DURATION_MS
attestation_threshold_ms = get_slot_component_duration_ms(ATTESTATION_DUE_BPS)
epoch = get_current_store_epoch(store)
attestation_threshold_ms = get_attestation_due_ms(epoch)
is_before_attesting_interval = time_into_slot_ms < attestation_threshold_ms
is_timely = get_current_slot(store) == block.slot and is_before_attesting_interval
store.block_timeliness[hash_tree_root(block)] = is_timely
@@ -4897,7 +4902,7 @@
- file: beacon-chain/blockchain/receive_block.go
search: func (s *Service) ReceiveBlock(
spec: |
<spec fn="on_block" fork="fulu" hash="a27a9edb">
<spec fn="on_block" fork="fulu" hash="4f955de9">
def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
"""
Run ``on_block`` upon receiving a new block.
@@ -4938,7 +4943,8 @@
# Add block timeliness to the store
seconds_since_genesis = store.time - store.genesis_time
time_into_slot_ms = seconds_to_milliseconds(seconds_since_genesis) % SLOT_DURATION_MS
attestation_threshold_ms = get_slot_component_duration_ms(ATTESTATION_DUE_BPS)
epoch = get_current_store_epoch(store)
attestation_threshold_ms = get_attestation_due_ms(epoch)
is_before_attesting_interval = time_into_slot_ms < attestation_threshold_ms
is_timely = get_current_slot(store) == block.slot and is_before_attesting_interval
store.block_timeliness[hash_tree_root(block)] = is_timely
@@ -7034,7 +7040,7 @@
- file: beacon-chain/core/blocks/exit.go
search: func ProcessVoluntaryExits(
spec: |
<spec fn="process_voluntary_exit" fork="electra" hash="6dcb5530">
<spec fn="process_voluntary_exit" fork="electra" hash="51b07d36">
def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
voluntary_exit = signed_voluntary_exit.message
validator = state.validators[voluntary_exit.validator_index]
@@ -7048,7 +7054,6 @@
assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
# [New in Electra:EIP7251]
# Only exit validator if it has no pending withdrawals in the queue
assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0
# Verify signature
domain = compute_domain(

View File

@@ -90,6 +90,7 @@ func (r *runner) run(ctx context.Context) {
select {
case <-ctx.Done():
log.Info("Context canceled, stopping validator")
//nolint:govet
return // Exit if context is canceled.
case slot := <-v.NextSlot():
if !r.healthMonitor.IsHealthy() {
@@ -98,7 +99,7 @@ func (r *runner) run(ctx context.Context) {
}
deadline := v.SlotDeadline(slot)
slotCtx, cancel := context.WithDeadline(ctx, deadline)
slotCtx, cancel := context.WithDeadline(ctx, deadline) //nolint:govet
var span trace.Span
slotCtx, span = prysmTrace.StartSpan(slotCtx, "validator.processSlot")
@@ -131,7 +132,7 @@ func (r *runner) run(ctx context.Context) {
// Start fetching domain data for the next epoch.
if slots.IsEpochEnd(slot) {
domainCtx, _ := context.WithDeadline(ctx, deadline)
domainCtx, _ := context.WithDeadline(ctx, deadline) //nolint:govet
go v.UpdateDomainDataCaches(domainCtx, slot+1)
}
@@ -145,7 +146,7 @@ func (r *runner) run(ctx context.Context) {
continue
}
// performRoles calls span.End()
rolesCtx, _ := context.WithDeadline(ctx, deadline)
rolesCtx, _ := context.WithDeadline(ctx, deadline) //nolint:govet
performRoles(rolesCtx, allRoles, v, slot, &wg, span)
case e := <-v.EventsChan():
v.ProcessEvent(ctx, e)