Compare commits

...

30 Commits

Author SHA1 Message Date
Preston Van Loon
721eb0b404 gofmt with go1.23.5 2025-01-22 22:34:36 -06:00
Preston Van Loon
43b233a4d5 Update go to 1.23.5 2025-01-22 22:34:36 -06:00
Preston Van Loon
74eb56020a Remove problematic ginkgo and gomega test helpers. Rewrote tests without these test libraries. 2025-01-22 22:34:36 -06:00
Preston Van Loon
13d2594cea Update errcheck by re-exporting the upstream repo 2025-01-22 22:34:36 -06:00
Preston Van Loon
d503b8014c Fix violations of SA3000 2025-01-22 22:34:36 -06:00
Preston Van Loon
a8ed5c2aa6 Update golang.org/x/tools 2025-01-22 22:34:36 -06:00
Preston Van Loon
d0aace409a Update go_honnef_go_tools 2025-01-22 22:34:36 -06:00
Preston Van Loon
955321286a Use toolchains_protoc 2025-01-22 22:34:36 -06:00
Preston Van Loon
48a879930e Update rules_go 2025-01-22 22:27:26 -06:00
Preston Van Loon
605cad0a8c Update bazel version 2025-01-22 22:27:26 -06:00
Manu NALEPA
78722239da nodeFilter: Add GossipBlobSidecarMessage case. (#14822)
Before this commit, this kind of logs were possible:

```
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_0/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_1/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_2/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_3/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_4/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_5/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_6/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_7/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_8/ssz_snappy
```

Note this bug has no real other impact than logging these errors: Since all nodes are subscribed to these subnets, as soon as some peers are found, there is no more issue.

Why not using `s.subscribe` instead of `s.subscribeWithParameters`?
Blobs subnets were before considered as static subnets. But since Electra, the number of subnets is a function of the epoch.
So it's better to use `s.subscribeWithParameters` than 2 specific but almost identic functions in `s.subscribe`.

Why `filterPeerForBlobSubnet` is the only one returning always `true`?
Because blobs subnets are actually the only subnets which are both dynamic AND which have to be subscribed by all the nodes.
So, `filterPeerForBlobSubnet` does not filter out any node.
2025-01-22 19:56:55 +00:00
Manu NALEPA
3ffef024c7 UpgradeToFulu: Respect the specification. (#14821)
188a2ff818/specs/fulu/fork.md (upgrading-the-state)

Before this commit, the `UpgradeToFulu` did not really respect the specification. This commit fixes that.

How can we be sure now the specification is really respected?

As long as the equivalent of https://github.com/ethereum/consensus-spec-tests/tree/master/tests/mainnet/electra/fork/fork/pyspec_tests are not released, we cannot be sure.

However, with this commit, Prysm and Lighthouse do agree with the post state after the Fulu fork (which is not the case without this commit).

So either both Prysm and Lighthouse are both right,
either the are both wrong (but in the exact same way, which has a pretty low likelyhood).
2025-01-22 18:39:12 +00:00
Radosław Kapka
a1eef44492 Update slasher service to Electra (#14812)
* Update slasher service to Electra

* Update beacon-chain/slasher/chunks.go

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>

* Update beacon-chain/slasher/chunks_test.go

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>

* Manu's review

* Manu's review again

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2025-01-22 17:32:19 +00:00
Radosław Kapka
2845ab9365 Update proto_test.go to Electra (#14817) 2025-01-21 20:30:52 +00:00
Radosław Kapka
4f43c15ebb Update rewards API to Electra (#14816) 2025-01-21 20:13:36 +00:00
Radosław Kapka
e473d7cc4d Use SingleAttestation for Fulu in p2p attestation map (#14809)
* Use `SingleAttestation` for Fulu in p2p attestation map.

* Fix `TestExtractDataType`.

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2025-01-20 10:35:52 +00:00
Potuz
794a05af26 Remove unused Copy() from the ReadOnlyBeaconBlock interface (#14811) 2025-01-19 19:56:14 +00:00
hidewrong
15df13c7e6 Signed-off-by: hidewrong <hidewrong@outlook.com> (#14792)
Signed-off-by: hidewrong <hidewrong@outlook.com>
2025-01-17 15:59:29 +00:00
Potuz
b76f7fed2f move credential helpers to ReadOnlyValidator methods (#14808)
* move credential helpers to ReadOnlyValidator methods

* Changelog + Gazelle

* Fix nil tests

* Fix more nil tests

* Fix another nil test
2025-01-17 12:37:08 +00:00
james-prysm
e263687ea5 Remote Signer: Electra (#14477)
* updating blockv2 to handle electra blocks

* adding aggregate attesation and proof electra

* gaz

* changelogs

* updating web3signer dependency

* test mock was flipped

* fixing hex value

* accidently checked in dependency changes

* preston feedback

* readding old metrics to not break linting

* review feedback and changelog

* gaz
2025-01-16 17:51:59 +00:00
james-prysm
0b16c79c35 fix e2e scenario evaluators (#14798)
* make fork evaluators conditional on fork for scenario tests

* changelog
2025-01-16 04:38:26 +00:00
terence
dc002c2806 Truncate ExtraData to 32 bytes for to satisfy SSZ marshal (#14803) 2025-01-16 00:14:56 +00:00
kasey
e7e48dcaf9 version pin unclog release (#14802)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-01-15 23:50:10 +00:00
james-prysm
8f43f6cc84 adding in error for generic check (#14801) 2025-01-15 21:36:09 +00:00
Manu NALEPA
e07341e1d5 ToBlinded: Use Fulu. (#14797)
* `ToBlinded`: Use Fulu.

* Fix Sammy's comment.

* `unmarshalState`: Use `hasFuluKey`.
2025-01-15 19:50:48 +00:00
Preston Van Loon
ef293e52f8 Use ip.addr.tools for DNS resolution test in p2p (#14800)
* Use ip.addr.tools for DNS resolution test in p2p

* Changelog fragment
2025-01-15 18:07:00 +00:00
Jun Song
72cc63a6a3 Clean TestCanUpgrade* tests (#14791)
* Clean TestCanUpgrade* tests

* Add new changelog file
2025-01-15 15:42:21 +00:00
Jun Song
34ff4c3ea9 Replace new exampleIP for example.org (#14795)
* Replace new exampleIP for example.org

* Add changelog
2025-01-15 06:14:25 +00:00
kasey
e8c968326a switch to unclog latest release instead of run artifact (#14793)
* use latest unclog release instead of run artifact

* add missing changelog entries to pre-unclog starter pack

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-01-14 21:47:20 +00:00
kasey
2000ef457b Move prysm to unclog for changelog management (#14782)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-01-14 18:22:38 +00:00
118 changed files with 3265 additions and 3956 deletions

View File

@@ -1 +1 @@
7.1.0
7.4.1

View File

@@ -33,5 +33,5 @@ Fixes #
**Acknowledgements**
- [ ] I have read [CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [ ] I have made an appropriate entry to [CHANGELOG.md](https://github.com/prysmaticlabs/prysm/blob/develop/CHANGELOG.md).
- [ ] I have included a uniquely named [changelog fragment file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [ ] I have added a description to this PR with sufficient context for reviewers to understand this PR.

View File

@@ -1,33 +1,34 @@
name: CI
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
name: changelog
on:
pull_request:
branches:
- develop
branches: [ "develop" ]
jobs:
changed_files:
runs-on: ubuntu-latest
name: Check CHANGELOG.md
run-changelog-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: changelog modified
id: changelog-modified
- name: Checkout source code
uses: actions/checkout@v3
- name: Download unclog binary
uses: dsaltares/fetch-gh-release-asset@aa2ab1243d6e0d5b405b973c89fa4d06a2d0fff7 # 1.1.2
with:
repo: OffchainLabs/unclog
version: "tags/v0.1.3"
file: "unclog"
- name: Get new changelog files
id: new-changelog-files
uses: tj-actions/changed-files@v45
with:
files: CHANGELOG.md
files: |
changelog/**.md
- name: List all changed files
- name: Run lint command
env:
ALL_CHANGED_FILES: ${{ steps.changelog-modified.outputs.all_changed_files }}
run: |
if [[ ${ALL_CHANGED_FILES[*]} =~ (^|[[:space:]])"CHANGELOG.md"($|[[:space:]]) ]];
then
echo "CHANGELOG.md was modified.";
exit 0;
else
echo "CHANGELOG.md was not modified.";
echo "Please see CHANGELOG.md and follow the instructions to add your changes to that file."
echo "In some rare scenarios, a changelog entry is not required and this CI check can be ignored."
exit 1;
fi
ALL_ADDED_MARKDOWN: ${{ steps.new-changelog-files.outputs.added_files }}
run: chmod +x unclog && ./unclog check -fragment-env=ALL_ADDED_MARKDOWN

View File

@@ -4,70 +4,6 @@ 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.
## [Unreleased](https://github.com/prysmaticlabs/prysm/compare/v5.2.0...HEAD)
### Added
- Added proper gas limit check for header from the builder.
- Added an error field to log `Finished building block`.
- Implemented a new `EmptyExecutionPayloadHeader` function.
- `Finished building block`: Display error only if not nil.
- Added support to update target and max blob count to different values per hard fork config.
- Log before blob filesystem cache warm-up.
- New design for the attestation pool. [PR](https://github.com/prysmaticlabs/prysm/pull/14324)
- Add field param placeholder for Electra blob target and max to pass spec tests.
- Add EIP-7691: Blob throughput increase.
- SSZ files generation: Remove the `// Hash: ...` header.
- DB optimization for saving light client bootstraps (save unique sync committees only).
- Trace IDONTWANT Messages in Pubsub.
- Add Fulu fork boilerplate.
- Separate type for unaggregated network attestations. [PR](https://github.com/prysmaticlabs/prysm/pull/14659)
- Update spec tests to v1.5.0-beta.0.
### Changed
- Process light client finality updates only for new finalized epochs instead of doing it for every block.
- Refactor subnets subscriptions.
- Refactor RPC handlers subscriptions.
- Go deps upgrade, from `ioutil` to `io`
- Move successfully registered validator(s) on builder log to debug.
- Update some test files to use `crypto/rand` instead of `math/rand`
- Enforce Compound prefix (0x02) for target when processing pending consolidation request.
- Limit consolidating by validator's effective balance.
- Use 16-bit random value for proposer and sync committee selection filter.
- Re-organize the content of the `*.proto` files (No functional change).
- Updated spec definitions for `process_slashings` in godocs. Simplified `ProcessSlashings` API.
- Updated spec definition electra `process_registry_updates`.
- Updated Electra spec definition for `process_epoch`.
- Update our `go-libp2p-pubsub` dependency.
- Re-organize the content of files to ease the creation of a new fork boilerplate.
- Fixed Metadata errors for peers connected via QUIC.
- Process light client finality updates only for new finalized epochs instead of doing it for every block.
- Update blobs by rpc topics from V2 to V1.
- Updated geth to 1.14 ~
- E2e tests start from bellatrix
### Deprecated
### Removed
- Cleanup ProcessSlashings method to remove unnecessary argument.
- Remove `/proto/eth/v2` directory. [PR](https://github.com/prysmaticlabs/prysm/pull/14765)
- Remove `/memsize/` pprof endpoint as it will no longer be supported in go 1.23, geth also removed in https://github.com/ethereum/go-ethereum/commit/e4675771eda550e7eeb63a8884816982c1980644
### Fixed
- Added check to prevent nil pointer deference or out of bounds array access when validating the BLSToExecutionChange on an impossibly nil validator.
- EIP-7691: Ensure new blobs subnets are subscribed on epoch in advance.
- Fix kzg commitment inclusion proof depth minimal value.
### Security
- go version upgrade to 1.22.10 for CVE CVE-2024-34156
- Update golang.org/x/crypto to v0.31.0 to address CVE-2024-45337
- Update golang.org/x/net to v0.33.0 to address CVE-2024-45338
## [v5.2.0](https://github.com/prysmaticlabs/prysm/compare/v5.1.2...v5.2.0)
Updating to this release is highly recommended, especially for users running v5.1.1 or v5.1.2.

View File

@@ -125,7 +125,7 @@ Navigate to your fork of the repo on GitHub. On the upper left where the current
**16. Add an entry to CHANGELOG.md.**
If your change is user facing, you must include a CHANGELOG.md entry. See the [Maintaining CHANGELOG.md](#maintaining-changelogmd) section for more information.
All PRs must must include a changelog fragment file in the `changelog` directory. If your change is not user-facing or should not be mentioned in the changelog for some other reason, you may use the `Ignored` changelog section in your fragment's header to satisfy this requirement without altering the final release changelog. See the [Maintaining CHANGELOG.md](#maintaining-changelogmd) section for more information.
**17. Create a pull request.**
@@ -177,16 +177,10 @@ $ git push myrepo feature-in-progress-branch -f
## Maintaining CHANGELOG.md
This project follows the changelog guidelines from [keepachangelog.com](https://keepachangelog.com/en/1.1.0/).
All PRs with user facing changes should have an entry in the CHANGELOG.md file and the change should be categorized in the appropriate category within the "Unreleased" section. The categories are:
- `Added` for new features.
- `Changed` for changes in existing functionality.
- `Deprecated` for soon-to-be removed features.
- `Removed` for now removed features.
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities. Please see the [Security Policy](SECURITY.md) for responsible disclosure before adding a change with this category.
This project follows the changelog guidelines from [keepachangelog.com](https://keepachangelog.com/en/1.1.0/). In order to minimize conflicts and workflow headaches, we chose to implement a changelog management
strategy that uses changelog "fragment" files, managed by our changelog management tool called `unclog`. Each PR must include a new changelog fragment file in the `changelog` directory, as specified by unclog's
[README.md](https://github.com/OffchainLabs/unclog?tab=readme-ov-file#what-is-a-changelog-fragment). As the `unclog` README suggests in the [Best Practices](https://github.com/OffchainLabs/unclog?tab=readme-ov-file#best-practices) section,
the standard naming convention for your PR's fragment file, to avoid conflicting with another fragment file, is `changelog/<github user name>_<PR branch name>.md`.
### Releasing

1689
MODULE.bazel.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,33 @@ load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
rules_pkg_dependencies()
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "toolchains_protoc",
sha256 = "abb1540f8a9e045422730670ebb2f25b41fa56ca5a7cf795175a110a0a68f4ad",
strip_prefix = "toolchains_protoc-0.3.6",
url = "https://github.com/aspect-build/toolchains_protoc/releases/download/v0.3.6/toolchains_protoc-v0.3.6.tar.gz",
)
load("@toolchains_protoc//protoc:repositories.bzl", "rules_protoc_dependencies")
rules_protoc_dependencies()
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
rules_proto_dependencies()
load("@bazel_features//:deps.bzl", "bazel_features_deps")
bazel_features_deps()
load("@toolchains_protoc//protoc:toolchain.bzl", "protoc_toolchains")
protoc_toolchains(
name = "protoc_toolchains",
version = "v25.3",
)
HERMETIC_CC_TOOLCHAIN_VERSION = "v3.0.1"
http_archive(
@@ -137,10 +164,10 @@ http_archive(
# Expose internals of go_test for custom build transitions.
"//third_party:io_bazel_rules_go_test.patch",
],
sha256 = "80a98277ad1311dacd837f9b16db62887702e9f1d1c4c9f796d0121a46c8e184",
sha256 = "b2038e2de2cace18f032249cb4bb0048abf583a36369fa98f687af1b3f880b26",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.48.1/rules_go-v0.48.1.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.48.1/rules_go-v0.48.1.zip",
],
)
@@ -182,7 +209,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
go_rules_dependencies()
go_register_toolchains(
go_version = "1.22.10",
go_version = "1.23.5",
nogo = "@//:nogo",
)

View File

@@ -2,6 +2,7 @@ package blockchain
import (
"io"
"os"
"testing"
"github.com/sirupsen/logrus"
@@ -11,5 +12,5 @@ func TestMain(m *testing.M) {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(io.Discard)
m.Run()
os.Exit(m.Run())
}

View File

@@ -1,9 +1,10 @@
package cache
import (
"os"
"testing"
)
func TestMain(m *testing.M) {
m.Run()
os.Exit(m.Run())
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
@@ -233,13 +234,18 @@ func ProcessConsolidationRequests(ctx context.Context, st state.BeaconState, req
return fmt.Errorf("failed to fetch source validator: %w", err) // This should never happen.
}
roSrcV, err := state_native.NewValidator(srcV)
if err != nil {
return err
}
tgtV, err := st.ValidatorAtIndexReadOnly(tgtIdx)
if err != nil {
return fmt.Errorf("failed to fetch target validator: %w", err) // This should never happen.
}
// Verify source withdrawal credentials
if !helpers.HasExecutionWithdrawalCredentials(srcV) {
if !roSrcV.HasExecutionWithdrawalCredentials() {
continue
}
// Confirm source_validator.withdrawal_credentials[12:] == consolidation_request.source_address
@@ -248,7 +254,7 @@ func ProcessConsolidationRequests(ctx context.Context, st state.BeaconState, req
}
// Target validator must have their withdrawal credentials set appropriately.
if !helpers.HasCompoundingWithdrawalCredential(tgtV) {
if !tgtV.HasCompoundingWithdrawalCredentials() {
continue
}
@@ -364,7 +370,7 @@ func IsValidSwitchToCompoundingRequest(st state.BeaconState, req *enginev1.Conso
return false
}
if !helpers.HasETH1WithdrawalCredential(srcV) {
if !srcV.HasETH1WithdrawalCredentials() {
return false
}

View File

@@ -3,7 +3,6 @@ package electra
import (
"fmt"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v5/config/params"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
@@ -40,7 +39,7 @@ func ProcessEffectiveBalanceUpdates(st state.BeaconState) error {
// Update effective balances with hysteresis.
validatorFunc := func(idx int, val state.ReadOnlyValidator) (newVal *ethpb.Validator, err error) {
if val == nil {
if val.IsNil() {
return nil, fmt.Errorf("validator %d is nil in state", idx)
}
if idx >= len(bals) {
@@ -49,7 +48,7 @@ func ProcessEffectiveBalanceUpdates(st state.BeaconState) error {
balance := bals[idx]
effectiveBalanceLimit := params.BeaconConfig().MinActivationBalance
if helpers.HasCompoundingWithdrawalCredential(val) {
if val.HasCompoundingWithdrawalCredentials() {
effectiveBalanceLimit = params.BeaconConfig().MaxEffectiveBalanceElectra
}

View File

@@ -77,7 +77,7 @@ func TestProcessEffectiveBalnceUpdates(t *testing.T) {
Validators: []*eth.Validator{
{
EffectiveBalance: params.BeaconConfig().MinActivationBalance / 2,
WithdrawalCredentials: nil,
WithdrawalCredentials: make([]byte, 32),
},
},
Balances: []uint64{

View File

@@ -194,7 +194,7 @@ func UpgradeToElectra(beaconState state.BeaconState) (state.BeaconState, error)
if val.ActivationEpoch() == params.BeaconConfig().FarFutureEpoch {
preActivationIndices = append(preActivationIndices, primitives.ValidatorIndex(index))
}
if helpers.HasCompoundingWithdrawalCredential(val) {
if val.HasCompoundingWithdrawalCredentials() {
compoundWithdrawalIndices = append(compoundWithdrawalIndices, primitives.ValidatorIndex(index))
}
return nil

View File

@@ -116,7 +116,7 @@ func ProcessWithdrawalRequests(ctx context.Context, st state.BeaconState, wrs []
return nil, err
}
// Verify withdrawal credentials
hasCorrectCredential := helpers.HasExecutionWithdrawalCredentials(validator)
hasCorrectCredential := validator.HasExecutionWithdrawalCredentials()
wc := validator.GetWithdrawalCredentials()
isCorrectSourceAddress := bytes.Equal(wc[12:], wr.SourceAddress)
if !hasCorrectCredential || !isCorrectSourceAddress {
@@ -165,7 +165,7 @@ func ProcessWithdrawalRequests(ctx context.Context, st state.BeaconState, wrs []
hasExcessBalance := vBal > params.BeaconConfig().MinActivationBalance+pendingBalanceToWithdraw
// Only allow partial withdrawals with compounding withdrawal credentials
if helpers.HasCompoundingWithdrawalCredential(validator) && hasSufficientEffectiveBalance && hasExcessBalance {
if validator.HasCompoundingWithdrawalCredentials() && hasSufficientEffectiveBalance && hasExcessBalance {
// Spec definition:
// to_withdraw = min(
// state.balances[index] - MIN_ACTIVATION_BALANCE - pending_balance_to_withdraw,

View File

@@ -6,15 +6,12 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/fulu",
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],
)
@@ -24,7 +21,6 @@ go_test(
srcs = ["upgrade_test.go"],
deps = [
":go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",
@@ -32,6 +28,5 @@ go_test(
"//proto/prysm/v1alpha1:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"//time/slots:go_default_library",
],
)

View File

@@ -1,18 +1,13 @@
package fulu
import (
"sort"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/time/slots"
)
// UpgradeToFulu updates inputs a generic state to return the version Fulu state.
@@ -74,32 +69,37 @@ func UpgradeToFulu(beaconState state.BeaconState) (state.BeaconState, error) {
if err != nil {
return nil, err
}
earliestExitEpoch := helpers.ActivationExitEpoch(time.CurrentEpoch(beaconState))
preActivationIndices := make([]primitives.ValidatorIndex, 0)
compoundWithdrawalIndices := make([]primitives.ValidatorIndex, 0)
if err = beaconState.ReadFromEveryValidator(func(index int, val state.ReadOnlyValidator) error {
if val.ExitEpoch() != params.BeaconConfig().FarFutureEpoch && val.ExitEpoch() > earliestExitEpoch {
earliestExitEpoch = val.ExitEpoch()
}
if val.ActivationEpoch() == params.BeaconConfig().FarFutureEpoch {
preActivationIndices = append(preActivationIndices, primitives.ValidatorIndex(index))
}
if helpers.HasCompoundingWithdrawalCredential(val) {
compoundWithdrawalIndices = append(compoundWithdrawalIndices, primitives.ValidatorIndex(index))
}
return nil
}); err != nil {
depositBalanceToConsume, err := beaconState.DepositBalanceToConsume()
if err != nil {
return nil, err
}
earliestExitEpoch++ // Increment to find the earliest possible exit epoch
// note: should be the same in prestate and post beaconState.
// we are deviating from the specs a bit as it calls for using the post beaconState
tab, err := helpers.TotalActiveBalance(beaconState)
exitBalanceToConsume, err := beaconState.ExitBalanceToConsume()
if err != nil {
return nil, errors.Wrap(err, "failed to get total active balance")
return nil, err
}
earliestExitEpoch, err := beaconState.EarliestExitEpoch()
if err != nil {
return nil, err
}
consolidationBalanceToConsume, err := beaconState.ConsolidationBalanceToConsume()
if err != nil {
return nil, err
}
earliestConsolidationEpoch, err := beaconState.EarliestConsolidationEpoch()
if err != nil {
return nil, err
}
pendingDeposits, err := beaconState.PendingDeposits()
if err != nil {
return nil, err
}
pendingPartialWithdrawals, err := beaconState.PendingPartialWithdrawals()
if err != nil {
return nil, err
}
pendingConsolidations, err := beaconState.PendingConsolidations()
if err != nil {
return nil, err
}
s := &ethpb.BeaconStateFulu{
@@ -155,25 +155,16 @@ func UpgradeToFulu(beaconState state.BeaconState) (state.BeaconState, error) {
HistoricalSummaries: summaries,
DepositRequestsStartIndex: params.BeaconConfig().UnsetDepositRequestsStartIndex,
DepositBalanceToConsume: 0,
ExitBalanceToConsume: helpers.ActivationExitChurnLimit(primitives.Gwei(tab)),
DepositBalanceToConsume: depositBalanceToConsume,
ExitBalanceToConsume: exitBalanceToConsume,
EarliestExitEpoch: earliestExitEpoch,
ConsolidationBalanceToConsume: helpers.ConsolidationChurnLimit(primitives.Gwei(tab)),
EarliestConsolidationEpoch: helpers.ActivationExitEpoch(slots.ToEpoch(beaconState.Slot())),
PendingDeposits: make([]*ethpb.PendingDeposit, 0),
PendingPartialWithdrawals: make([]*ethpb.PendingPartialWithdrawal, 0),
PendingConsolidations: make([]*ethpb.PendingConsolidation, 0),
ConsolidationBalanceToConsume: consolidationBalanceToConsume,
EarliestConsolidationEpoch: earliestConsolidationEpoch,
PendingDeposits: pendingDeposits,
PendingPartialWithdrawals: pendingPartialWithdrawals,
PendingConsolidations: pendingConsolidations,
}
// Sorting preActivationIndices based on a custom criteria
sort.Slice(preActivationIndices, func(i, j int) bool {
// Comparing based on ActivationEligibilityEpoch and then by index if the epochs are the same
if s.Validators[preActivationIndices[i]].ActivationEligibilityEpoch == s.Validators[preActivationIndices[j]].ActivationEligibilityEpoch {
return preActivationIndices[i] < preActivationIndices[j]
}
return s.Validators[preActivationIndices[i]].ActivationEligibilityEpoch < s.Validators[preActivationIndices[j]].ActivationEligibilityEpoch
})
// Need to cast the beaconState to use in helper functions
post, err := state_native.InitializeFromProtoUnsafeFulu(s)
if err != nil {

View File

@@ -4,7 +4,6 @@ import (
"testing"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/fulu"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
@@ -12,7 +11,6 @@ import (
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/testing/util"
"github.com/prysmaticlabs/prysm/v5/time/slots"
)
func TestUpgradeToFulu(t *testing.T) {
@@ -33,57 +31,6 @@ func TestUpgradeToFulu(t *testing.T) {
require.Equal(t, preForkState.GenesisTime(), mSt.GenesisTime())
require.DeepSSZEqual(t, preForkState.GenesisValidatorsRoot(), mSt.GenesisValidatorsRoot())
require.Equal(t, preForkState.Slot(), mSt.Slot())
require.DeepSSZEqual(t, preForkState.LatestBlockHeader(), mSt.LatestBlockHeader())
require.DeepSSZEqual(t, preForkState.BlockRoots(), mSt.BlockRoots())
require.DeepSSZEqual(t, preForkState.StateRoots(), mSt.StateRoots())
require.DeepSSZEqual(t, preForkState.Validators()[2:], mSt.Validators()[2:])
require.DeepSSZEqual(t, preForkState.Balances()[2:], mSt.Balances()[2:])
require.DeepSSZEqual(t, preForkState.Eth1Data(), mSt.Eth1Data())
require.DeepSSZEqual(t, preForkState.Eth1DataVotes(), mSt.Eth1DataVotes())
require.DeepSSZEqual(t, preForkState.Eth1DepositIndex(), mSt.Eth1DepositIndex())
require.DeepSSZEqual(t, preForkState.RandaoMixes(), mSt.RandaoMixes())
require.DeepSSZEqual(t, preForkState.Slashings(), mSt.Slashings())
require.DeepSSZEqual(t, preForkState.JustificationBits(), mSt.JustificationBits())
require.DeepSSZEqual(t, preForkState.PreviousJustifiedCheckpoint(), mSt.PreviousJustifiedCheckpoint())
require.DeepSSZEqual(t, preForkState.CurrentJustifiedCheckpoint(), mSt.CurrentJustifiedCheckpoint())
require.DeepSSZEqual(t, preForkState.FinalizedCheckpoint(), mSt.FinalizedCheckpoint())
require.Equal(t, len(preForkState.Validators()), len(mSt.Validators()))
preVal, err := preForkState.ValidatorAtIndex(0)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MaxEffectiveBalance, preVal.EffectiveBalance)
preVal2, err := preForkState.ValidatorAtIndex(1)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MaxEffectiveBalance, preVal2.EffectiveBalance)
// TODO: Fix this test
// mVal, err := mSt.ValidatorAtIndex(0)
_, err = mSt.ValidatorAtIndex(0)
require.NoError(t, err)
// require.Equal(t, uint64(0), mVal.EffectiveBalance)
mVal2, err := mSt.ValidatorAtIndex(1)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MinActivationBalance, mVal2.EffectiveBalance)
numValidators := mSt.NumValidators()
p, err := mSt.PreviousEpochParticipation()
require.NoError(t, err)
require.DeepSSZEqual(t, make([]byte, numValidators), p)
p, err = mSt.CurrentEpochParticipation()
require.NoError(t, err)
require.DeepSSZEqual(t, make([]byte, numValidators), p)
s, err := mSt.InactivityScores()
require.NoError(t, err)
require.DeepSSZEqual(t, make([]uint64, numValidators), s)
hr1, err := preForkState.HistoricalRoots()
require.NoError(t, err)
hr2, err := mSt.HistoricalRoots()
require.NoError(t, err)
require.DeepEqual(t, hr1, hr2)
f := mSt.Fork()
require.DeepSSZEqual(t, &ethpb.Fork{
@@ -91,11 +38,50 @@ func TestUpgradeToFulu(t *testing.T) {
CurrentVersion: params.BeaconConfig().FuluForkVersion,
Epoch: time.CurrentEpoch(st),
}, f)
require.DeepSSZEqual(t, preForkState.LatestBlockHeader(), mSt.LatestBlockHeader())
require.DeepSSZEqual(t, preForkState.BlockRoots(), mSt.BlockRoots())
require.DeepSSZEqual(t, preForkState.StateRoots(), mSt.StateRoots())
hr1, err := preForkState.HistoricalRoots()
require.NoError(t, err)
hr2, err := mSt.HistoricalRoots()
require.NoError(t, err)
require.DeepEqual(t, hr1, hr2)
require.DeepSSZEqual(t, preForkState.Eth1Data(), mSt.Eth1Data())
require.DeepSSZEqual(t, preForkState.Eth1DataVotes(), mSt.Eth1DataVotes())
require.DeepSSZEqual(t, preForkState.Eth1DepositIndex(), mSt.Eth1DepositIndex())
require.DeepSSZEqual(t, preForkState.Validators(), mSt.Validators())
require.DeepSSZEqual(t, preForkState.Balances(), mSt.Balances())
require.DeepSSZEqual(t, preForkState.RandaoMixes(), mSt.RandaoMixes())
require.DeepSSZEqual(t, preForkState.Slashings(), mSt.Slashings())
numValidators := mSt.NumValidators()
p, err := mSt.PreviousEpochParticipation()
require.NoError(t, err)
require.DeepSSZEqual(t, make([]byte, numValidators), p)
p, err = mSt.CurrentEpochParticipation()
require.NoError(t, err)
require.DeepSSZEqual(t, make([]byte, numValidators), p)
require.DeepSSZEqual(t, preForkState.JustificationBits(), mSt.JustificationBits())
require.DeepSSZEqual(t, preForkState.PreviousJustifiedCheckpoint(), mSt.PreviousJustifiedCheckpoint())
require.DeepSSZEqual(t, preForkState.CurrentJustifiedCheckpoint(), mSt.CurrentJustifiedCheckpoint())
require.DeepSSZEqual(t, preForkState.FinalizedCheckpoint(), mSt.FinalizedCheckpoint())
s, err := mSt.InactivityScores()
require.NoError(t, err)
require.DeepSSZEqual(t, make([]uint64, numValidators), s)
csc, err := mSt.CurrentSyncCommittee()
require.NoError(t, err)
psc, err := preForkState.CurrentSyncCommittee()
require.NoError(t, err)
require.DeepSSZEqual(t, psc, csc)
nsc, err := mSt.NextSyncCommittee()
require.NoError(t, err)
psc, err = preForkState.NextSyncCommittee()
@@ -110,7 +96,6 @@ func TestUpgradeToFulu(t *testing.T) {
require.NoError(t, err)
txRoot, err := prevHeader.TransactionsRoot()
require.NoError(t, err)
wdRoot, err := prevHeader.WithdrawalsRoot()
require.NoError(t, err)
wanted := &enginev1.ExecutionPayloadHeaderDeneb{
@@ -144,45 +129,57 @@ func TestUpgradeToFulu(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 0, len(summaries))
startIndex, err := mSt.DepositRequestsStartIndex()
preDepositRequestsStartIndex, err := preForkState.DepositRequestsStartIndex()
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().UnsetDepositRequestsStartIndex, startIndex)
postDepositRequestsStartIndex, err := mSt.DepositRequestsStartIndex()
require.NoError(t, err)
require.Equal(t, preDepositRequestsStartIndex, postDepositRequestsStartIndex)
balance, err := mSt.DepositBalanceToConsume()
preDepositBalanceToConsume, err := preForkState.DepositBalanceToConsume()
require.NoError(t, err)
require.Equal(t, primitives.Gwei(0), balance)
postDepositBalanceToConsume, err := mSt.DepositBalanceToConsume()
require.NoError(t, err)
require.Equal(t, preDepositBalanceToConsume, postDepositBalanceToConsume)
tab, err := helpers.TotalActiveBalance(mSt)
preExitBalanceToConsume, err := preForkState.ExitBalanceToConsume()
require.NoError(t, err)
postExitBalanceToConsume, err := mSt.ExitBalanceToConsume()
require.NoError(t, err)
require.Equal(t, preExitBalanceToConsume, postExitBalanceToConsume)
ebtc, err := mSt.ExitBalanceToConsume()
preEarliestExitEpoch, err := preForkState.EarliestExitEpoch()
require.NoError(t, err)
require.Equal(t, helpers.ActivationExitChurnLimit(primitives.Gwei(tab)), ebtc)
postEarliestExitEpoch, err := mSt.EarliestExitEpoch()
require.NoError(t, err)
require.Equal(t, preEarliestExitEpoch, postEarliestExitEpoch)
eee, err := mSt.EarliestExitEpoch()
preConsolidationBalanceToConsume, err := preForkState.ConsolidationBalanceToConsume()
require.NoError(t, err)
require.Equal(t, helpers.ActivationExitEpoch(primitives.Epoch(1)), eee)
postConsolidationBalanceToConsume, err := mSt.ConsolidationBalanceToConsume()
require.NoError(t, err)
require.Equal(t, preConsolidationBalanceToConsume, postConsolidationBalanceToConsume)
cbtc, err := mSt.ConsolidationBalanceToConsume()
preEarliesConsolidationEoch, err := preForkState.EarliestConsolidationEpoch()
require.NoError(t, err)
require.Equal(t, helpers.ConsolidationChurnLimit(primitives.Gwei(tab)), cbtc)
postEarliestConsolidationEpoch, err := mSt.EarliestConsolidationEpoch()
require.NoError(t, err)
require.Equal(t, preEarliesConsolidationEoch, postEarliestConsolidationEpoch)
earliestConsolidationEpoch, err := mSt.EarliestConsolidationEpoch()
prePendingDeposits, err := preForkState.PendingDeposits()
require.NoError(t, err)
require.Equal(t, helpers.ActivationExitEpoch(slots.ToEpoch(preForkState.Slot())), earliestConsolidationEpoch)
postPendingDeposits, err := mSt.PendingDeposits()
require.NoError(t, err)
require.DeepSSZEqual(t, prePendingDeposits, postPendingDeposits)
// TODO: Fix this test
// pendingDeposits, err := mSt.PendingDeposits()
_, err = mSt.PendingDeposits()
prePendingPartialWithdrawals, err := preForkState.PendingPartialWithdrawals()
require.NoError(t, err)
// require.Equal(t, 2, len(pendingDeposits))
// require.Equal(t, uint64(1000), pendingDeposits[1].Amount)
postPendingPartialWithdrawals, err := mSt.PendingPartialWithdrawals()
require.NoError(t, err)
require.DeepSSZEqual(t, prePendingPartialWithdrawals, postPendingPartialWithdrawals)
numPendingPartialWithdrawals, err := mSt.NumPendingPartialWithdrawals()
prePendingConsolidations, err := preForkState.PendingConsolidations()
require.NoError(t, err)
require.Equal(t, uint64(0), numPendingPartialWithdrawals)
consolidations, err := mSt.PendingConsolidations()
postPendingConsolidations, err := mSt.PendingConsolidations()
require.NoError(t, err)
require.Equal(t, 0, len(consolidations))
require.DeepSSZEqual(t, prePendingConsolidations, postPendingConsolidations)
}

View File

@@ -25,7 +25,6 @@ go_library(
"//beacon-chain/state:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//container/slice:go_default_library",
"//container/trie:go_default_library",

View File

@@ -14,7 +14,6 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
@@ -515,63 +514,6 @@ func LastActivatedValidatorIndex(ctx context.Context, st state.ReadOnlyBeaconSta
return lastActivatedvalidatorIndex, nil
}
// hasETH1WithdrawalCredential returns whether the validator has an ETH1
// Withdrawal prefix. It assumes that the caller has a lock on the state
func HasETH1WithdrawalCredential(val interfaces.WithWithdrawalCredentials) bool {
if val == nil {
return false
}
return isETH1WithdrawalCredential(val.GetWithdrawalCredentials())
}
func isETH1WithdrawalCredential(creds []byte) bool {
return bytes.HasPrefix(creds, []byte{params.BeaconConfig().ETH1AddressWithdrawalPrefixByte})
}
// HasCompoundingWithdrawalCredential checks if the validator has a compounding withdrawal credential.
// New in Electra EIP-7251: https://eips.ethereum.org/EIPS/eip-7251
//
// Spec definition:
//
// def has_compounding_withdrawal_credential(validator: Validator) -> bool:
// """
// Check if ``validator`` has an 0x02 prefixed "compounding" withdrawal credential.
// """
// return is_compounding_withdrawal_credential(validator.withdrawal_credentials)
func HasCompoundingWithdrawalCredential(v interfaces.WithWithdrawalCredentials) bool {
if v == nil {
return false
}
return IsCompoundingWithdrawalCredential(v.GetWithdrawalCredentials())
}
// IsCompoundingWithdrawalCredential checks if the credentials are a compounding withdrawal credential.
//
// Spec definition:
//
// def is_compounding_withdrawal_credential(withdrawal_credentials: Bytes32) -> bool:
// return withdrawal_credentials[:1] == COMPOUNDING_WITHDRAWAL_PREFIX
func IsCompoundingWithdrawalCredential(creds []byte) bool {
return bytes.HasPrefix(creds, []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte})
}
// HasExecutionWithdrawalCredentials checks if the validator has an execution withdrawal credential or compounding credential.
// New in Electra EIP-7251: https://eips.ethereum.org/EIPS/eip-7251
//
// Spec definition:
//
// def has_execution_withdrawal_credential(validator: Validator) -> bool:
// """
// Check if ``validator`` has a 0x01 or 0x02 prefixed withdrawal credential.
// """
// return has_compounding_withdrawal_credential(validator) or has_eth1_withdrawal_credential(validator)
func HasExecutionWithdrawalCredentials(v interfaces.WithWithdrawalCredentials) bool {
if v == nil {
return false
}
return HasCompoundingWithdrawalCredential(v) || HasETH1WithdrawalCredential(v)
}
// IsSameWithdrawalCredentials returns true if both validators have the same withdrawal credentials.
//
// return a.withdrawal_credentials[12:] == b.withdrawal_credentials[12:]
@@ -606,10 +548,10 @@ func IsFullyWithdrawableValidator(val state.ReadOnlyValidator, balance uint64, e
// Electra / EIP-7251 logic
if fork >= version.Electra {
return HasExecutionWithdrawalCredentials(val) && val.WithdrawableEpoch() <= epoch
return val.HasExecutionWithdrawalCredentials() && val.WithdrawableEpoch() <= epoch
}
return HasETH1WithdrawalCredential(val) && val.WithdrawableEpoch() <= epoch
return val.HasETH1WithdrawalCredentials() && val.WithdrawableEpoch() <= epoch
}
// IsPartiallyWithdrawableValidator returns whether the validator is able to perform a
@@ -650,7 +592,7 @@ func isPartiallyWithdrawableValidatorElectra(val state.ReadOnlyValidator, balanc
hasMaxBalance := val.EffectiveBalance() == maxEB
hasExcessBalance := balance > maxEB
return HasExecutionWithdrawalCredentials(val) &&
return val.HasExecutionWithdrawalCredentials() &&
hasMaxBalance &&
hasExcessBalance
}
@@ -670,7 +612,7 @@ func isPartiallyWithdrawableValidatorElectra(val state.ReadOnlyValidator, balanc
func isPartiallyWithdrawableValidatorCapella(val state.ReadOnlyValidator, balance uint64, epoch primitives.Epoch) bool {
hasMaxBalance := val.EffectiveBalance() == params.BeaconConfig().MaxEffectiveBalance
hasExcessBalance := balance > params.BeaconConfig().MaxEffectiveBalance
return HasETH1WithdrawalCredential(val) && hasExcessBalance && hasMaxBalance
return val.HasETH1WithdrawalCredentials() && hasExcessBalance && hasMaxBalance
}
// ValidatorMaxEffectiveBalance returns the maximum effective balance for a validator.
@@ -686,7 +628,7 @@ func isPartiallyWithdrawableValidatorCapella(val state.ReadOnlyValidator, balanc
// else:
// return MIN_ACTIVATION_BALANCE
func ValidatorMaxEffectiveBalance(val state.ReadOnlyValidator) uint64 {
if HasCompoundingWithdrawalCredential(val) {
if val.HasCompoundingWithdrawalCredentials() {
return params.BeaconConfig().MaxEffectiveBalanceElectra
}
return params.BeaconConfig().MinActivationBalance

View File

@@ -910,13 +910,15 @@ func TestProposerIndexFromCheckpoint(t *testing.T) {
func TestHasETH1WithdrawalCredentials(t *testing.T) {
creds := []byte{0xFA, 0xCC}
v := &ethpb.Validator{WithdrawalCredentials: creds}
require.Equal(t, false, helpers.HasETH1WithdrawalCredential(v))
roV, err := state_native.NewValidator(v)
require.NoError(t, err)
require.Equal(t, false, roV.HasETH1WithdrawalCredentials())
creds = []byte{params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, 0xCC}
v = &ethpb.Validator{WithdrawalCredentials: creds}
require.Equal(t, true, helpers.HasETH1WithdrawalCredential(v))
roV, err = state_native.NewValidator(v)
require.NoError(t, err)
require.Equal(t, true, roV.HasETH1WithdrawalCredentials())
// No Withdrawal cred
v = &ethpb.Validator{}
require.Equal(t, false, helpers.HasETH1WithdrawalCredential(v))
}
func TestHasCompoundingWithdrawalCredential(t *testing.T) {
@@ -931,11 +933,12 @@ func TestHasCompoundingWithdrawalCredential(t *testing.T) {
{"Does not have compounding withdrawal credential",
&ethpb.Validator{WithdrawalCredentials: bytesutil.PadTo([]byte{0x00}, 32)},
false},
{"Handles nil case", nil, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, helpers.HasCompoundingWithdrawalCredential(tt.validator))
roV, err := state_native.NewValidator(tt.validator)
require.NoError(t, err)
assert.Equal(t, tt.want, roV.HasCompoundingWithdrawalCredentials())
})
}
}
@@ -955,11 +958,12 @@ func TestHasExecutionWithdrawalCredentials(t *testing.T) {
{"Does not have compounding withdrawal credential or eth1 withdrawal credential",
&ethpb.Validator{WithdrawalCredentials: bytesutil.PadTo([]byte{0x00}, 32)},
false},
{"Handles nil case", nil, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, helpers.HasExecutionWithdrawalCredentials(tt.validator))
roV, err := state_native.NewValidator(tt.validator)
require.NoError(t, err)
assert.Equal(t, tt.want, roV.HasExecutionWithdrawalCredentials())
})
}
}

View File

@@ -84,76 +84,6 @@ func TestNextEpoch_OK(t *testing.T) {
}
}
func TestCanUpgradeToAltair(t *testing.T) {
params.SetupTestConfigCleanup(t)
bc := params.BeaconConfig()
bc.AltairForkEpoch = 5
params.OverrideBeaconConfig(bc)
tests := []struct {
name string
slot primitives.Slot
want bool
}{
{
name: "not epoch start",
slot: 1,
want: false,
},
{
name: "not altair epoch",
slot: params.BeaconConfig().SlotsPerEpoch,
want: false,
},
{
name: "altair epoch",
slot: primitives.Slot(params.BeaconConfig().AltairForkEpoch) * params.BeaconConfig().SlotsPerEpoch,
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := time.CanUpgradeToAltair(tt.slot); got != tt.want {
t.Errorf("canUpgradeToAltair() = %v, want %v", got, tt.want)
}
})
}
}
func TestCanUpgradeBellatrix(t *testing.T) {
params.SetupTestConfigCleanup(t)
bc := params.BeaconConfig()
bc.BellatrixForkEpoch = 5
params.OverrideBeaconConfig(bc)
tests := []struct {
name string
slot primitives.Slot
want bool
}{
{
name: "not epoch start",
slot: 1,
want: false,
},
{
name: "not bellatrix epoch",
slot: params.BeaconConfig().SlotsPerEpoch,
want: false,
},
{
name: "bellatrix epoch",
slot: primitives.Slot(params.BeaconConfig().BellatrixForkEpoch) * params.BeaconConfig().SlotsPerEpoch,
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := time.CanUpgradeToBellatrix(tt.slot); got != tt.want {
t.Errorf("CanUpgradeToBellatrix() = %v, want %v", got, tt.want)
}
})
}
}
func TestCanProcessEpoch_TrueOnEpochsLastSlot(t *testing.T) {
tests := []struct {
slot primitives.Slot
@@ -273,6 +203,16 @@ func TestCanUpgradeTo(t *testing.T) {
forkEpoch *primitives.Epoch
upgradeFunc func(primitives.Slot) bool
}{
{
name: "Altair",
forkEpoch: &beaconConfig.AltairForkEpoch,
upgradeFunc: time.CanUpgradeToAltair,
},
{
name: "Bellatrix",
forkEpoch: &beaconConfig.BellatrixForkEpoch,
upgradeFunc: time.CanUpgradeToBellatrix,
},
{
name: "Capella",
forkEpoch: &beaconConfig.CapellaForkEpoch,

View File

@@ -517,6 +517,19 @@ func (s *Store) unmarshalState(_ context.Context, enc []byte, validatorEntries [
}
switch {
case hasFuluKey(enc):
protoState := &ethpb.BeaconStateFulu{}
if err := protoState.UnmarshalSSZ(enc[len(fuluKey):]); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal encoding for Electra")
}
ok, err := s.isStateValidatorMigrationOver()
if err != nil {
return nil, err
}
if ok {
protoState.Validators = validatorEntries
}
return statenative.InitializeFromProtoUnsafeFulu(protoState)
case hasElectraKey(enc):
protoState := &ethpb.BeaconStateElectra{}
if err := protoState.UnmarshalSSZ(enc[len(electraKey):]); err != nil {

View File

@@ -2,6 +2,7 @@ package slasherkv
import (
"io"
"os"
"testing"
"github.com/sirupsen/logrus"
@@ -10,5 +11,5 @@ import (
func TestMain(m *testing.M) {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(io.Discard)
m.Run()
os.Exit(m.Run())
}

View File

@@ -2,6 +2,7 @@ package execution
import (
"io"
"os"
"testing"
"github.com/sirupsen/logrus"
@@ -11,5 +12,5 @@ func TestMain(m *testing.M) {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(io.Discard)
m.Run()
os.Exit(m.Run())
}

View File

@@ -354,10 +354,10 @@ func TestStaticPeering_PeersAreAdded(t *testing.T) {
}
func TestHostIsResolved(t *testing.T) {
// As defined in RFC 2606 , example.org is a
// reserved example domain name.
exampleHost := "example.org"
exampleIP := "93.184.215.14"
// ip.addr.tools - construct domain names that resolve to any given IP address
// ex: 192-0-2-1.ip.addr.tools resolves to 192.0.2.1.
exampleHost := "96-7-129-13.ip.addr.tools"
exampleIP := "96.7.129.13"
s := &Service{
cfg: &Config{

View File

@@ -2,6 +2,7 @@ package peers_test
import (
"io"
"os"
"testing"
"github.com/prysmaticlabs/prysm/v5/cmd/beacon-chain/flags"
@@ -28,5 +29,5 @@ func TestMain(m *testing.M) {
defer func() {
flags.Init(resetFlags)
}()
m.Run()
os.Exit(m.Run())
}

View File

@@ -3,6 +3,7 @@ package scorers_test
import (
"io"
"math"
"os"
"testing"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/peers/scorers"
@@ -28,7 +29,7 @@ func TestMain(m *testing.M) {
defer func() {
flags.Init(resetFlags)
}()
m.Run()
os.Exit(m.Run())
}
// roundScore returns score rounded in accordance with the score manager's rounding factor.

View File

@@ -54,6 +54,8 @@ func (s *Service) nodeFilter(topic string, index uint64) (func(node *enode.Node)
return s.filterPeerForAttSubnet(index), nil
case strings.Contains(topic, GossipSyncCommitteeMessage):
return s.filterPeerForSyncSubnet(index), nil
case strings.Contains(topic, GossipBlobSidecarMessage):
return s.filterPeerForBlobSubnet(), nil
default:
return nil, errors.Errorf("no subnet exists for provided topic: %s", topic)
}
@@ -266,6 +268,14 @@ func (s *Service) filterPeerForSyncSubnet(index uint64) func(node *enode.Node) b
}
}
// returns a method with filters peers specifically for a particular blob subnet.
// All peers are supposed to be subscribed to all blob subnets.
func (s *Service) filterPeerForBlobSubnet() func(_ *enode.Node) bool {
return func(_ *enode.Node) bool {
return true
}
}
// lower threshold to broadcast object compared to searching
// for a subnet. So that even in the event of poor peer
// connectivity, we can still broadcast an attestation.

View File

@@ -123,7 +123,7 @@ func InitializeDataMaps() {
return &ethpb.SingleAttestation{}, nil
},
bytesutil.ToBytes4(params.BeaconConfig().FuluForkVersion): func() (ethpb.Att, error) {
return &ethpb.AttestationElectra{}, nil
return &ethpb.SingleAttestation{}, nil
},
}

View File

@@ -461,7 +461,7 @@ func TestStreamEvents_OperationsEvents(t *testing.T) {
defer testSync.cleanup()
st := tc.getState()
v := &eth.Validator{ExitEpoch: math.MaxUint64, EffectiveBalance: params.BeaconConfig().MinActivationBalance}
v := &eth.Validator{ExitEpoch: math.MaxUint64, EffectiveBalance: params.BeaconConfig().MinActivationBalance, WithdrawalCredentials: make([]byte, 32)}
require.NoError(t, st.SetValidators([]*eth.Validator{v}))
currentSlot := primitives.Slot(0)
// to avoid slot processing

View File

@@ -63,6 +63,7 @@ go_test(
"//encoding/bytesutil:go_default_library",
"//network/httputil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",

View File

@@ -32,45 +32,52 @@ import (
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/network/httputil"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/testing/util"
)
func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, interfaces.SignedBeaconBlock, error) {
func BlockRewardTestSetup(t *testing.T, ver int) (state.BeaconState, interfaces.SignedBeaconBlock, error) {
helpers.ClearCache()
var sbb interfaces.SignedBeaconBlock
var st state.BeaconState
var err error
switch forkName {
case "phase0":
switch ver {
case version.Phase0:
return nil, nil, errors.New("phase0 not supported")
case "altair":
case version.Altair:
st, err = util.NewBeaconStateAltair()
require.NoError(t, err)
b := util.HydrateSignedBeaconBlockAltair(util.NewBeaconBlockAltair())
sbb, err = blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
case "bellatrix":
case version.Bellatrix:
st, err = util.NewBeaconStateBellatrix()
require.NoError(t, err)
b := util.HydrateSignedBeaconBlockBellatrix(util.NewBeaconBlockBellatrix())
sbb, err = blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
case "capella":
case version.Capella:
st, err = util.NewBeaconStateCapella()
require.NoError(t, err)
b := util.HydrateSignedBeaconBlockCapella(util.NewBeaconBlockCapella())
sbb, err = blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
case "deneb":
case version.Deneb:
st, err = util.NewBeaconStateDeneb()
require.NoError(t, err)
b := util.HydrateSignedBeaconBlockDeneb(util.NewBeaconBlockDeneb())
sbb, err = blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
case version.Electra:
st, err = util.NewBeaconStateElectra()
require.NoError(t, err)
b := util.HydrateSignedBeaconBlockElectra(util.NewBeaconBlockElectra())
sbb, err = blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
default:
return nil, nil, errors.New("fork is not supported")
return nil, nil, fmt.Errorf("fork %s is not supported", version.String(ver))
}
valCount := 64
require.NoError(t, st.SetSlot(1))
@@ -102,20 +109,47 @@ func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, int
require.NoError(t, st.SetBlockRoots(bRoots))
sbb.SetSlot(2)
// we have to set the proposer index to the value that will be randomly chosen (fortunately it's deterministic)
sbb.SetProposerIndex(12)
require.NoError(t, sbb.SetAttestations([]eth.Att{
&eth.Attestation{
AggregationBits: bitfield.Bitlist{0b00000111},
Data: util.HydrateAttestationData(&eth.AttestationData{}),
Signature: make([]byte, fieldparams.BLSSignatureLength),
},
&eth.Attestation{
AggregationBits: bitfield.Bitlist{0b00000111},
Data: util.HydrateAttestationData(&eth.AttestationData{}),
Signature: make([]byte, fieldparams.BLSSignatureLength),
},
}))
if ver >= version.Electra {
sbb.SetProposerIndex(4)
} else {
sbb.SetProposerIndex(12)
}
var atts []eth.Att
if ver >= version.Electra {
cb := primitives.NewAttestationCommitteeBits()
cb.SetBitAt(0, true)
atts = []eth.Att{
&eth.AttestationElectra{
AggregationBits: bitfield.Bitlist{0b00000111},
Data: util.HydrateAttestationData(&eth.AttestationData{}),
Signature: make([]byte, fieldparams.BLSSignatureLength),
CommitteeBits: cb,
},
&eth.AttestationElectra{
AggregationBits: bitfield.Bitlist{0b00000111},
Data: util.HydrateAttestationData(&eth.AttestationData{}),
Signature: make([]byte, fieldparams.BLSSignatureLength),
CommitteeBits: cb,
},
}
} else {
atts = []eth.Att{
&eth.Attestation{
AggregationBits: bitfield.Bitlist{0b00000111},
Data: util.HydrateAttestationData(&eth.AttestationData{}),
Signature: make([]byte, fieldparams.BLSSignatureLength),
},
&eth.Attestation{
AggregationBits: bitfield.Bitlist{0b00000111},
Data: util.HydrateAttestationData(&eth.AttestationData{}),
Signature: make([]byte, fieldparams.BLSSignatureLength),
},
}
}
require.NoError(t, sbb.SetAttestations(atts))
attData1 := util.HydrateAttestationData(&eth.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root1"), 32)})
attData2 := util.HydrateAttestationData(&eth.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root2"), 32)})
@@ -125,8 +159,23 @@ func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, int
require.NoError(t, err)
sigRoot2, err := signing.ComputeSigningRoot(attData2, domain)
require.NoError(t, err)
require.NoError(t, sbb.SetAttesterSlashings([]eth.AttSlashing{
&eth.AttesterSlashing{
var attSlashing eth.AttSlashing
if ver >= version.Electra {
attSlashing = &eth.AttesterSlashingElectra{
Attestation_1: &eth.IndexedAttestationElectra{
AttestingIndices: []uint64{0},
Data: attData1,
Signature: secretKeys[0].Sign(sigRoot1[:]).Marshal(),
},
Attestation_2: &eth.IndexedAttestationElectra{
AttestingIndices: []uint64{0},
Data: attData2,
Signature: secretKeys[0].Sign(sigRoot2[:]).Marshal(),
},
}
} else {
attSlashing = &eth.AttesterSlashing{
Attestation_1: &eth.IndexedAttestation{
AttestingIndices: []uint64{0},
Data: attData1,
@@ -137,8 +186,10 @@ func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, int
Data: attData2,
Signature: secretKeys[0].Sign(sigRoot2[:]).Marshal(),
},
},
}))
}
}
require.NoError(t, sbb.SetAttesterSlashings([]eth.AttSlashing{attSlashing}))
header1 := &eth.BeaconBlockHeader{
Slot: 0,
ProposerIndex: 1,
@@ -179,11 +230,21 @@ func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, int
sszBytes := primitives.SSZBytes(slot0bRoot)
r, err := signing.ComputeSigningRoot(&sszBytes, domain)
require.NoError(t, err)
// Bits set in sync committee bits determine which validators will be treated as participating in sync committee.
// These validators have to sign the message.
sig1, err := blst.SignatureFromBytes(secretKeys[47].Sign(r[:]).Marshal())
var scValIdx1 int
var scValIdx2 int
if ver >= version.Electra {
scValIdx1 = 14
scValIdx2 = 27
} else {
scValIdx1 = 47
scValIdx2 = 19
}
sig1, err := blst.SignatureFromBytes(secretKeys[scValIdx1].Sign(r[:]).Marshal())
require.NoError(t, err)
sig2, err := blst.SignatureFromBytes(secretKeys[19].Sign(r[:]).Marshal())
sig2, err := blst.SignatureFromBytes(secretKeys[scValIdx2].Sign(r[:]).Marshal())
require.NoError(t, err)
aggSig := bls.AggregateSignatures([]bls.Signature{sig1, sig2}).Marshal()
err = sbb.SetSyncAggregate(&eth.SyncAggregate{SyncCommitteeBits: scBits, SyncCommitteeSignature: aggSig})
@@ -211,14 +272,14 @@ func TestBlockRewards(t *testing.T) {
writer.Body = &bytes.Buffer{}
s.BlockRewards(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
require.Equal(t, http.StatusBadRequest, writer.Code)
e := &httputil.DefaultJsonError{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
require.Equal(t, http.StatusBadRequest, e.Code)
assert.Equal(t, "Block rewards are not supported for Phase 0 blocks", e.Message)
})
t.Run("altair", func(t *testing.T) {
st, sbb, err := BlockRewardTestSetup(t, "altair")
st, sbb, err := BlockRewardTestSetup(t, version.Altair)
require.NoError(t, err)
mockChainService := &mock.ChainService{Optimistic: true}
@@ -241,7 +302,7 @@ func TestBlockRewards(t *testing.T) {
writer.Body = &bytes.Buffer{}
s.BlockRewards(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
require.Equal(t, http.StatusOK, writer.Code)
resp := &structs.BlockRewardsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "12", resp.Data.ProposerIndex)
@@ -254,7 +315,7 @@ func TestBlockRewards(t *testing.T) {
assert.Equal(t, false, resp.Finalized)
})
t.Run("bellatrix", func(t *testing.T) {
st, sbb, err := BlockRewardTestSetup(t, "bellatrix")
st, sbb, err := BlockRewardTestSetup(t, version.Bellatrix)
require.NoError(t, err)
mockChainService := &mock.ChainService{Optimistic: true}
@@ -277,7 +338,7 @@ func TestBlockRewards(t *testing.T) {
writer.Body = &bytes.Buffer{}
s.BlockRewards(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
require.Equal(t, http.StatusOK, writer.Code)
resp := &structs.BlockRewardsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "12", resp.Data.ProposerIndex)
@@ -290,7 +351,7 @@ func TestBlockRewards(t *testing.T) {
assert.Equal(t, false, resp.Finalized)
})
t.Run("capella", func(t *testing.T) {
st, sbb, err := BlockRewardTestSetup(t, "capella")
st, sbb, err := BlockRewardTestSetup(t, version.Capella)
require.NoError(t, err)
mockChainService := &mock.ChainService{Optimistic: true}
@@ -313,7 +374,7 @@ func TestBlockRewards(t *testing.T) {
writer.Body = &bytes.Buffer{}
s.BlockRewards(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
require.Equal(t, http.StatusOK, writer.Code)
resp := &structs.BlockRewardsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "12", resp.Data.ProposerIndex)
@@ -326,7 +387,7 @@ func TestBlockRewards(t *testing.T) {
assert.Equal(t, false, resp.Finalized)
})
t.Run("deneb", func(t *testing.T) {
st, sbb, err := BlockRewardTestSetup(t, "deneb")
st, sbb, err := BlockRewardTestSetup(t, version.Deneb)
require.NoError(t, err)
mockChainService := &mock.ChainService{Optimistic: true}
@@ -349,7 +410,7 @@ func TestBlockRewards(t *testing.T) {
writer.Body = &bytes.Buffer{}
s.BlockRewards(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
require.Equal(t, http.StatusOK, writer.Code)
resp := &structs.BlockRewardsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "12", resp.Data.ProposerIndex)
@@ -361,6 +422,42 @@ func TestBlockRewards(t *testing.T) {
assert.Equal(t, true, resp.ExecutionOptimistic)
assert.Equal(t, false, resp.Finalized)
})
t.Run("electra", func(t *testing.T) {
st, sbb, err := BlockRewardTestSetup(t, version.Electra)
require.NoError(t, err)
mockChainService := &mock.ChainService{Optimistic: true}
s := &Server{
Blocker: &testutil.MockBlocker{SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
0: phase0block,
2: sbb,
}},
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
BlockRewardFetcher: &BlockRewardService{
Replayer: mockstategen.NewReplayerBuilder(mockstategen.WithMockState(st)),
DB: db,
},
}
url := "http://only.the.slot.number.at.the.end.is.important/2"
request := httptest.NewRequest("GET", url, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.BlockRewards(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &structs.BlockRewardsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "4", resp.Data.ProposerIndex)
assert.Equal(t, "15714490", resp.Data.Total)
assert.Equal(t, "89442", resp.Data.Attestations)
assert.Equal(t, "48", resp.Data.SyncAggregate)
assert.Equal(t, "7812500", resp.Data.AttesterSlashings)
assert.Equal(t, "7812500", resp.Data.ProposerSlashings)
assert.Equal(t, true, resp.ExecutionOptimistic)
assert.Equal(t, false, resp.Finalized)
})
}
func TestAttestationRewards(t *testing.T) {

View File

@@ -1,6 +1,7 @@
package beacon
import (
"os"
"testing"
"github.com/prysmaticlabs/prysm/v5/cmd/beacon-chain/flags"
@@ -21,5 +22,5 @@ func TestMain(m *testing.M) {
flags.Init(resetFlags)
}()
m.Run()
os.Exit(m.Run())
}

View File

@@ -2,6 +2,7 @@ package validator
import (
"io"
"os"
"testing"
"github.com/prysmaticlabs/prysm/v5/config/params"
@@ -16,5 +17,5 @@ func TestMain(m *testing.M) {
defer params.OverrideBeaconConfig(prevConfig)
params.OverrideBeaconConfig(params.MinimalSpecConfig())
m.Run()
os.Exit(m.Run())
}

View File

@@ -41,6 +41,7 @@ go_library(
"//encoding/bytesutil:go_default_library",
"//monitoring/tracing/trace:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
@@ -83,6 +84,7 @@ go_test(
"//crypto/bls/common:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",

View File

@@ -11,6 +11,7 @@ import (
slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/sirupsen/logrus"
)
@@ -232,6 +233,43 @@ func (m *MinSpanChunksSlice) CheckSlashable(
surroundingVotesTotal.Inc()
// Both attestations should have the same type. If not, we convert both to Electra attestations.
unifyAttWrapperVersion(existingAttWrapper, incomingAttWrapper)
postElectra := existingAttWrapper.IndexedAttestation.Version() >= version.Electra
if postElectra {
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
if !ok {
return nil, fmt.Errorf(
"existing attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestationElectra{},
existingAttWrapper.IndexedAttestation,
)
}
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
if !ok {
return nil, fmt.Errorf(
"incoming attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestationElectra{},
incomingAttWrapper.IndexedAttestation,
)
}
slashing := &ethpb.AttesterSlashingElectra{
Attestation_1: existing,
Attestation_2: incoming,
}
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
slashing = &ethpb.AttesterSlashingElectra{
Attestation_1: incoming,
Attestation_2: existing,
}
}
return slashing, nil
}
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
@@ -328,6 +366,43 @@ func (m *MaxSpanChunksSlice) CheckSlashable(
surroundedVotesTotal.Inc()
// Both attestations should have the same type. If not, we convert the non-Electra attestation into an Electra attestation.
unifyAttWrapperVersion(existingAttWrapper, incomingAttWrapper)
postElectra := existingAttWrapper.IndexedAttestation.Version() >= version.Electra
if postElectra {
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
if !ok {
return nil, fmt.Errorf(
"existing attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestationElectra{},
existingAttWrapper.IndexedAttestation,
)
}
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
if !ok {
return nil, fmt.Errorf(
"incoming attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestationElectra{},
incomingAttWrapper.IndexedAttestation,
)
}
slashing := &ethpb.AttesterSlashingElectra{
Attestation_1: existing,
Attestation_2: incoming,
}
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
slashing = &ethpb.AttesterSlashingElectra{
Attestation_1: incoming,
Attestation_2: existing,
}
}
return slashing, nil
}
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(

View File

@@ -3,12 +3,14 @@ package slasher
import (
"context"
"math"
"reflect"
"testing"
dbtest "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/testing"
slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
@@ -82,6 +84,99 @@ func TestMaxSpanChunksSlice_MaxChunkSpanFrom(t *testing.T) {
func TestMinSpanChunksSlice_CheckSlashable(t *testing.T) {
ctx := context.Background()
for _, v := range []int{version.Phase0, version.Electra} {
t.Run(version.String(v), func(t *testing.T) {
slasherDB := dbtest.SetupSlasherDB(t)
params := &Parameters{
chunkSize: 3,
validatorChunkSize: 2,
historyLength: 3,
}
validatorIdx := primitives.ValidatorIndex(1)
source := primitives.Epoch(1)
target := primitives.Epoch(2)
att := createAttestationWrapperEmptySig(t, v, source, target, nil, nil)
// A faulty chunk should lead to error.
chunk := &MinSpanChunksSlice{
params: params,
data: []uint16{},
}
_, err := chunk.CheckSlashable(ctx, nil, validatorIdx, att)
require.ErrorContains(t, "could not get min target for validator", err)
// We initialize a proper slice with 2 chunks with chunk size 3, 2 validators, and
// a history length of 3 representing a perfect attesting history.
//
// val0 val1
// { } { }
// [2, 2, 2, 2, 2, 2]
data := []uint16{2, 2, 2, 2, 2, 2}
chunk, err = MinChunkSpansSliceFrom(params, data)
require.NoError(t, err)
// An attestation with source 1 and target 2 should not be slashable
// based on our min chunk for either validator.
slashing, err := chunk.CheckSlashable(ctx, slasherDB, validatorIdx, att)
require.NoError(t, err)
require.Equal(t, nil, slashing)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx.Sub(1), att)
require.NoError(t, err)
require.Equal(t, nil, slashing)
// Next up we initialize an empty chunks slice and mark an attestation
// with (source 1, target 2) as attested.
chunk = EmptyMinSpanChunksSlice(params)
source = primitives.Epoch(1)
target = primitives.Epoch(2)
att = createAttestationWrapperEmptySig(t, v, source, target, nil, nil)
chunkIndex := uint64(0)
startEpoch := target
currentEpoch := target
_, err = chunk.Update(chunkIndex, currentEpoch, validatorIdx, startEpoch, target)
require.NoError(t, err)
// Next up, we create a surrounding vote, but it should NOT be slashable
// because we DO NOT have an existing attestation record in our database at the min target epoch.
source = primitives.Epoch(0)
target = primitives.Epoch(3)
surroundingVote := createAttestationWrapperEmptySig(t, v, source, target, nil, nil)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundingVote)
require.NoError(t, err)
require.Equal(t, nil, slashing)
// Next up, we save the old attestation record, then check if the
// surrounding vote is indeed slashable.
attData := att.IndexedAttestation.GetData()
attRecord := createAttestationWrapperEmptySig(t, v, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, []byte{1})
err = slasherDB.SaveAttestationRecordsForValidators(
ctx,
[]*slashertypes.IndexedAttestationWrapper{attRecord},
)
require.NoError(t, err)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundingVote)
require.NoError(t, err)
require.Equal(t, false, reflect.ValueOf(slashing).IsNil())
// We check the attestation with the lower data root is the first attestation.
// Firstly we require the setup to have the surrounding vote as the second attestation.
// Then we modify the root of the surrounding vote and expect the vote to be the first attestation.
require.DeepEqual(t, surroundingVote.IndexedAttestation, slashing.SecondAttestation())
surroundingVote.DataRoot = [32]byte{}
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundingVote)
require.NoError(t, err)
require.Equal(t, false, reflect.ValueOf(slashing).IsNil())
assert.DeepEqual(t, surroundingVote.IndexedAttestation, slashing.FirstAttestation())
})
}
}
func TestMinSpanChunksSlice_CheckSlashable_DifferentVersions(t *testing.T) {
ctx := context.Background()
slasherDB := dbtest.SetupSlasherDB(t)
params := &Parameters{
chunkSize: 3,
@@ -91,75 +186,138 @@ func TestMinSpanChunksSlice_CheckSlashable(t *testing.T) {
validatorIdx := primitives.ValidatorIndex(1)
source := primitives.Epoch(1)
target := primitives.Epoch(2)
att := createAttestationWrapperEmptySig(t, source, target, nil, nil)
// A faulty chunk should lead to error.
chunk := &MinSpanChunksSlice{
params: params,
data: []uint16{},
}
_, err := chunk.CheckSlashable(ctx, nil, validatorIdx, att)
require.ErrorContains(t, "could not get min target for validator", err)
// We create a vote with Phase0 version.
att := createAttestationWrapperEmptySig(t, version.Phase0, source, target, nil, nil)
// We initialize a proper slice with 2 chunks with chunk size 3, 2 validators, and
// a history length of 3 representing a perfect attesting history.
//
// val0 val1
// { } { }
// [2, 2, 2, 2, 2, 2]
data := []uint16{2, 2, 2, 2, 2, 2}
chunk, err = MinChunkSpansSliceFrom(params, data)
require.NoError(t, err)
// An attestation with source 1 and target 2 should not be slashable
// based on our min chunk for either validator.
slashing, err := chunk.CheckSlashable(ctx, slasherDB, validatorIdx, att)
require.NoError(t, err)
require.Equal(t, nil, slashing)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx.Sub(1), att)
require.NoError(t, err)
require.Equal(t, nil, slashing)
// Next up we initialize an empty chunks slice and mark an attestation
// with (source 1, target 2) as attested.
chunk = EmptyMinSpanChunksSlice(params)
source = primitives.Epoch(1)
target = primitives.Epoch(2)
att = createAttestationWrapperEmptySig(t, source, target, nil, nil)
// We initialize an empty chunks slice and mark an attestation with (source 1, target 2) as attested.
chunk := EmptyMinSpanChunksSlice(params)
chunkIndex := uint64(0)
startEpoch := target
currentEpoch := target
_, err = chunk.Update(chunkIndex, currentEpoch, validatorIdx, startEpoch, target)
_, err := chunk.Update(chunkIndex, currentEpoch, validatorIdx, startEpoch, target)
require.NoError(t, err)
// Next up, we create a surrounding vote, but it should NOT be slashable
// because we DO NOT have an existing attestation record in our database at the min target epoch.
// We create a surrounding vote with Electra version.
source = primitives.Epoch(0)
target = primitives.Epoch(3)
surroundingVote := createAttestationWrapperEmptySig(t, source, target, nil, nil)
surroundingVote := createAttestationWrapperEmptySig(t, version.Electra, source, target, nil, nil)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundingVote)
require.NoError(t, err)
require.Equal(t, nil, slashing)
// Next up, we save the old attestation record, then check if the
// surrounding vote is indeed slashable.
// We save the old attestation record, then check if the surrounding vote is indeed slashable.
attData := att.IndexedAttestation.GetData()
attRecord := createAttestationWrapperEmptySig(t, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, []byte{1})
attRecord := createAttestationWrapperEmptySig(t, version.Phase0, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, []byte{1})
err = slasherDB.SaveAttestationRecordsForValidators(
ctx,
[]*slashertypes.IndexedAttestationWrapper{attRecord},
)
require.NoError(t, err)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundingVote)
slashing, err := chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundingVote)
require.NoError(t, err)
require.NotEqual(t, (*ethpb.AttesterSlashing)(nil), slashing)
// The old record should be converted to Electra and the resulting slashing should be an Electra slashing.
electraSlashing, ok := slashing.(*ethpb.AttesterSlashingElectra)
require.Equal(t, true, ok, "slashing has the wrong type")
assert.NotNil(t, electraSlashing)
}
func TestMaxSpanChunksSlice_CheckSlashable(t *testing.T) {
ctx := context.Background()
for _, v := range []int{version.Phase0, version.Electra} {
t.Run(version.String(v), func(t *testing.T) {
slasherDB := dbtest.SetupSlasherDB(t)
params := &Parameters{
chunkSize: 4,
validatorChunkSize: 2,
historyLength: 4,
}
validatorIdx := primitives.ValidatorIndex(1)
source := primitives.Epoch(1)
target := primitives.Epoch(2)
att := createAttestationWrapperEmptySig(t, v, source, target, nil, nil)
// A faulty chunk should lead to error.
chunk := &MaxSpanChunksSlice{
params: params,
data: []uint16{},
}
_, err := chunk.CheckSlashable(ctx, nil, validatorIdx, att)
require.ErrorContains(t, "could not get max target for validator", err)
// We initialize a proper slice with 2 chunks with chunk size 4, 2 validators, and
// a history length of 4 representing a perfect attesting history.
//
// val0 val1
// { } { }
// [0, 0, 0, 0, 0, 0, 0, 0]
data := []uint16{0, 0, 0, 0, 0, 0, 0, 0}
chunk, err = MaxChunkSpansSliceFrom(params, data)
require.NoError(t, err)
// An attestation with source 1 and target 2 should not be slashable
// based on our max chunk for either validator.
slashing, err := chunk.CheckSlashable(ctx, slasherDB, validatorIdx, att)
require.NoError(t, err)
require.Equal(t, nil, slashing)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx.Sub(1), att)
require.NoError(t, err)
require.Equal(t, nil, slashing)
// Next up we initialize an empty chunks slice and mark an attestation
// with (source 0, target 3) as attested.
chunk = EmptyMaxSpanChunksSlice(params)
source = primitives.Epoch(0)
target = primitives.Epoch(3)
att = createAttestationWrapperEmptySig(t, v, source, target, nil, nil)
chunkIndex := uint64(0)
startEpoch := source
currentEpoch := target
_, err = chunk.Update(chunkIndex, currentEpoch, validatorIdx, startEpoch, target)
require.NoError(t, err)
// Next up, we create a surrounded vote, but it should NOT be slashable
// because we DO NOT have an existing attestation record in our database at the max target epoch.
source = primitives.Epoch(1)
target = primitives.Epoch(2)
surroundedVote := createAttestationWrapperEmptySig(t, v, source, target, nil, nil)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundedVote)
require.NoError(t, err)
require.Equal(t, nil, slashing)
// Next up, we save the old attestation record, then check if the
// surroundedVote vote is indeed slashable.
attData := att.IndexedAttestation.GetData()
signingRoot := [32]byte{1}
attRecord := createAttestationWrapperEmptySig(
t, v, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, signingRoot[:],
)
err = slasherDB.SaveAttestationRecordsForValidators(
ctx,
[]*slashertypes.IndexedAttestationWrapper{attRecord},
)
require.NoError(t, err)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundedVote)
require.NoError(t, err)
require.Equal(t, false, reflect.ValueOf(slashing).IsNil())
// We check the attestation with the lower data root is the first attestation.
// Firstly we require the setup to have the surrounded vote as the second attestation.
// Then we modify the root of the surrounded vote and expect the vote to be the first attestation.
require.DeepEqual(t, surroundedVote.IndexedAttestation, slashing.SecondAttestation())
surroundedVote.DataRoot = [32]byte{}
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundedVote)
require.NoError(t, err)
require.Equal(t, false, reflect.ValueOf(slashing).IsNil())
assert.DeepEqual(t, surroundedVote.IndexedAttestation, slashing.FirstAttestation())
})
}
}
func TestMaxSpanChunksSlice_CheckSlashable_DifferentVersions(t *testing.T) {
ctx := context.Background()
slasherDB := dbtest.SetupSlasherDB(t)
params := &Parameters{
chunkSize: 4,
@@ -167,76 +325,38 @@ func TestMaxSpanChunksSlice_CheckSlashable(t *testing.T) {
historyLength: 4,
}
validatorIdx := primitives.ValidatorIndex(1)
source := primitives.Epoch(1)
target := primitives.Epoch(2)
att := createAttestationWrapperEmptySig(t, source, target, nil, nil)
source := primitives.Epoch(0)
target := primitives.Epoch(3)
// A faulty chunk should lead to error.
chunk := &MaxSpanChunksSlice{
params: params,
data: []uint16{},
}
_, err := chunk.CheckSlashable(ctx, nil, validatorIdx, att)
require.ErrorContains(t, "could not get max target for validator", err)
// We create a vote with Phase0 version.
att := createAttestationWrapperEmptySig(t, version.Phase0, source, target, nil, nil)
// We initialize a proper slice with 2 chunks with chunk size 4, 2 validators, and
// a history length of 4 representing a perfect attesting history.
//
// val0 val1
// { } { }
// [0, 0, 0, 0, 0, 0, 0, 0]
data := []uint16{0, 0, 0, 0, 0, 0, 0, 0}
chunk, err = MaxChunkSpansSliceFrom(params, data)
require.NoError(t, err)
// An attestation with source 1 and target 2 should not be slashable
// based on our max chunk for either validator.
slashing, err := chunk.CheckSlashable(ctx, slasherDB, validatorIdx, att)
require.NoError(t, err)
require.Equal(t, nil, slashing)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx.Sub(1), att)
require.NoError(t, err)
require.Equal(t, nil, slashing)
// Next up we initialize an empty chunks slice and mark an attestation
// with (source 0, target 3) as attested.
chunk = EmptyMaxSpanChunksSlice(params)
source = primitives.Epoch(0)
target = primitives.Epoch(3)
att = createAttestationWrapperEmptySig(t, source, target, nil, nil)
// We initialize an empty chunks slice and mark an attestation with (source 0, target 3) as attested.
chunk := EmptyMaxSpanChunksSlice(params)
chunkIndex := uint64(0)
startEpoch := source
currentEpoch := target
_, err = chunk.Update(chunkIndex, currentEpoch, validatorIdx, startEpoch, target)
_, err := chunk.Update(chunkIndex, target, validatorIdx, source, target)
require.NoError(t, err)
// Next up, we create a surrounded vote, but it should NOT be slashable
// because we DO NOT have an existing attestation record in our database at the max target epoch.
// We create a surrounded vote with Electra version.
source = primitives.Epoch(1)
target = primitives.Epoch(2)
surroundedVote := createAttestationWrapperEmptySig(t, source, target, nil, nil)
surroundedVote := createAttestationWrapperEmptySig(t, version.Electra, source, target, nil, nil)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundedVote)
require.NoError(t, err)
require.Equal(t, nil, slashing)
// Next up, we save the old attestation record, then check if the
// surroundedVote vote is indeed slashable.
// We save the old attestation record, then check if the surrounded vote is indeed slashable.
attData := att.IndexedAttestation.GetData()
signingRoot := [32]byte{1}
attRecord := createAttestationWrapperEmptySig(
t, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, signingRoot[:],
)
attRecord := createAttestationWrapperEmptySig(t, version.Phase0, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, []byte{1})
err = slasherDB.SaveAttestationRecordsForValidators(
ctx,
[]*slashertypes.IndexedAttestationWrapper{attRecord},
)
require.NoError(t, err)
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundedVote)
slashing, err := chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundedVote)
require.NoError(t, err)
require.NotEqual(t, (*ethpb.AttesterSlashing)(nil), slashing)
// The old record should be converted to Electra and the resulting slashing should be an Electra slashing.
electraSlashing, ok := slashing.(*ethpb.AttesterSlashingElectra)
require.Equal(t, true, ok, "slashing has wrong type")
assert.NotNil(t, electraSlashing)
}
func TestMinSpanChunksSlice_Update_MultipleChunks(t *testing.T) {

View File

@@ -11,6 +11,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"golang.org/x/exp/maps"
)
@@ -193,33 +194,69 @@ func (s *Service) checkDoubleVotes(
// This is a double vote.
doubleVotesTotal.Inc()
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"existing attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
existingAttWrapper.IndexedAttestation,
)
}
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"incoming attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
incomingAttWrapper.IndexedAttestation,
)
}
var slashing ethpb.AttSlashing
slashing := &ethpb.AttesterSlashing{
Attestation_1: existing,
Attestation_2: incoming,
}
// Both attestations should have the same type. If not, we convert both to Electra attestations.
unifyAttWrapperVersion(existingAttWrapper, incomingAttWrapper)
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
postElectra := existingAttWrapper.IndexedAttestation.Version() >= version.Electra
if postElectra {
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
if !ok {
return nil, fmt.Errorf(
"existing attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestationElectra{},
existingAttWrapper.IndexedAttestation,
)
}
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
if !ok {
return nil, fmt.Errorf(
"incoming attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestationElectra{},
incomingAttWrapper.IndexedAttestation,
)
}
slashing = &ethpb.AttesterSlashingElectra{
Attestation_1: existing,
Attestation_2: incoming,
}
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
slashing = &ethpb.AttesterSlashingElectra{
Attestation_1: incoming,
Attestation_2: existing,
}
}
} else {
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"existing attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
existingAttWrapper.IndexedAttestation,
)
}
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"incoming attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
incomingAttWrapper.IndexedAttestation,
)
}
slashing = &ethpb.AttesterSlashing{
Attestation_1: incoming,
Attestation_2: existing,
Attestation_1: existing,
Attestation_2: incoming,
}
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
slashing = &ethpb.AttesterSlashing{
Attestation_1: incoming,
Attestation_2: existing,
}
}
}
@@ -245,33 +282,69 @@ func (s *Service) checkDoubleVotes(
wrapper_1 := doubleVote.Wrapper_1
wrapper_2 := doubleVote.Wrapper_2
att_1, ok := wrapper_1.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"first attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
wrapper_1.IndexedAttestation,
)
}
att_2, ok := wrapper_2.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"second attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
wrapper_2.IndexedAttestation,
)
}
var slashing ethpb.AttSlashing
slashing := &ethpb.AttesterSlashing{
Attestation_1: att_1,
Attestation_2: att_2,
}
// Both attestations should have the same type. If not, we convert both to Electra attestations.
unifyAttWrapperVersion(wrapper_1, wrapper_2)
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(wrapper_1.DataRoot[:], wrapper_2.DataRoot[:]) > 0 {
postElectra := wrapper_1.IndexedAttestation.Version() >= version.Electra
if postElectra {
att_1, ok := wrapper_1.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
if !ok {
return nil, fmt.Errorf(
"first attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestationElectra{},
wrapper_1.IndexedAttestation,
)
}
att_2, ok := wrapper_2.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
if !ok {
return nil, fmt.Errorf(
"second attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestationElectra{},
wrapper_2.IndexedAttestation,
)
}
slashing = &ethpb.AttesterSlashingElectra{
Attestation_1: att_1,
Attestation_2: att_2,
}
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(wrapper_1.DataRoot[:], wrapper_2.DataRoot[:]) > 0 {
slashing = &ethpb.AttesterSlashingElectra{
Attestation_1: att_2,
Attestation_2: att_1,
}
}
} else {
att_1, ok := wrapper_1.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"first attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
wrapper_1.IndexedAttestation,
)
}
att_2, ok := wrapper_2.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"second attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
wrapper_2.IndexedAttestation,
)
}
slashing = &ethpb.AttesterSlashing{
Attestation_1: att_2,
Attestation_2: att_1,
Attestation_1: att_1,
Attestation_2: att_2,
}
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(wrapper_1.DataRoot[:], wrapper_2.DataRoot[:]) > 0 {
slashing = &ethpb.AttesterSlashing{
Attestation_1: att_2,
Attestation_2: att_1,
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/container/slice"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/sirupsen/logrus"
)
@@ -249,3 +250,24 @@ func closeDB(d *slasherkv.Store) {
log.WithError(err).Error("could not close database")
}
}
// unifyAttWrapperVersion ensures that the two wrappers wrap indexed attestations of the same version.
// If versions differ, the wrapped attestation with the lower version will be converted to the higher version.
func unifyAttWrapperVersion(w1 *slashertypes.IndexedAttestationWrapper, w2 *slashertypes.IndexedAttestationWrapper) {
if w1.IndexedAttestation.Version() == w2.IndexedAttestation.Version() {
return
}
if w1.IndexedAttestation.Version() != version.Electra {
w1.IndexedAttestation = &ethpb.IndexedAttestationElectra{
AttestingIndices: w1.IndexedAttestation.GetAttestingIndices(),
Data: w1.IndexedAttestation.GetData(),
Signature: w1.IndexedAttestation.GetSignature(),
}
return
}
w2.IndexedAttestation = &ethpb.IndexedAttestationElectra{
AttestingIndices: w2.IndexedAttestation.GetAttestingIndices(),
Data: w2.IndexedAttestation.GetData(),
Signature: w2.IndexedAttestation.GetSignature(),
}
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/require"
logTest "github.com/sirupsen/logrus/hooks/test"
)
@@ -32,13 +33,13 @@ func TestService_groupByValidatorChunkIndex(t *testing.T) {
validatorChunkSize: 2,
},
atts: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 1}, nil),
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 1}, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0, 1}, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0, 1}, nil),
},
want: map[uint64][]*slashertypes.IndexedAttestationWrapper{
0: {
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 1}, nil),
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 1}, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0, 1}, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0, 1}, nil),
},
},
},
@@ -48,17 +49,17 @@ func TestService_groupByValidatorChunkIndex(t *testing.T) {
validatorChunkSize: 2,
},
atts: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 2, 4}, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0, 2, 4}, nil),
},
want: map[uint64][]*slashertypes.IndexedAttestationWrapper{
0: {
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 2, 4}, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0, 2, 4}, nil),
},
1: {
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 2, 4}, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0, 2, 4}, nil),
},
2: {
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 2, 4}, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0, 2, 4}, nil),
},
},
},
@@ -95,13 +96,13 @@ func TestService_groupByChunkIndex(t *testing.T) {
historyLength: 3,
},
atts: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 0, nil, nil),
createAttestationWrapperEmptySig(t, 1, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 1, 0, nil, nil),
},
want: map[uint64][]*slashertypes.IndexedAttestationWrapper{
0: {
createAttestationWrapperEmptySig(t, 0, 0, nil, nil),
createAttestationWrapperEmptySig(t, 1, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 1, 0, nil, nil),
},
},
},
@@ -112,17 +113,17 @@ func TestService_groupByChunkIndex(t *testing.T) {
historyLength: 3,
},
atts: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 0, nil, nil),
createAttestationWrapperEmptySig(t, 1, 0, nil, nil),
createAttestationWrapperEmptySig(t, 2, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 1, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 2, 0, nil, nil),
},
want: map[uint64][]*slashertypes.IndexedAttestationWrapper{
0: {
createAttestationWrapperEmptySig(t, 0, 0, nil, nil),
createAttestationWrapperEmptySig(t, 1, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 1, 0, nil, nil),
},
1: {
createAttestationWrapperEmptySig(t, 2, 0, nil, nil),
createAttestationWrapperEmptySig(t, version.Phase0, 2, 0, nil, nil),
},
},
},
@@ -207,7 +208,7 @@ func TestService_filterAttestations(t *testing.T) {
{
name: "Source > target gets dropped",
input: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 1, 0, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 1, 0, []uint64{1}, make([]byte, 32)),
},
inputEpoch: 0,
wantedDropped: 1,
@@ -215,33 +216,33 @@ func TestService_filterAttestations(t *testing.T) {
{
name: "Source < target is valid",
input: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 1, []uint64{1}, make([]byte, 32)),
},
inputEpoch: 1,
wantedValid: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 1, []uint64{1}, make([]byte, 32)),
},
wantedDropped: 0,
},
{
name: "Source == target is valid",
input: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 0, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{1}, make([]byte, 32)),
},
inputEpoch: 1,
wantedValid: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 0, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{1}, make([]byte, 32)),
},
wantedDropped: 0,
},
{
name: "Attestation from the future is deferred",
input: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 2, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 2, []uint64{1}, make([]byte, 32)),
},
inputEpoch: 1,
wantedDeferred: []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 2, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 2, []uint64{1}, make([]byte, 32)),
},
wantedDropped: 0,
},
@@ -271,22 +272,22 @@ func Test_logSlashingEvent(t *testing.T) {
{
name: "Surrounding vote",
slashing: &ethpb.AttesterSlashing{
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_1: createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_2: createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
},
},
{
name: "Surrounded vote",
slashing: &ethpb.AttesterSlashing{
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_1: createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_2: createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
},
},
{
name: "Double vote",
slashing: &ethpb.AttesterSlashing{
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_1: createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
Attestation_2: createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
},
},
}

View File

@@ -5,6 +5,7 @@ import (
slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
@@ -12,8 +13,8 @@ func Test_attestationsQueue(t *testing.T) {
t.Run("push_and_dequeue", func(tt *testing.T) {
attQueue := newAttestationsQueue()
wantedAtts := []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, 1, 2, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 1, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 1, 2, []uint64{1}, make([]byte, 32)),
}
attQueue.push(wantedAtts[0])
attQueue.push(wantedAtts[1])
@@ -27,8 +28,8 @@ func Test_attestationsQueue(t *testing.T) {
t.Run("extend_and_dequeue", func(tt *testing.T) {
attQueue := newAttestationsQueue()
wantedAtts := []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, 1, 2, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 1, []uint64{1}, make([]byte, 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 1, 2, []uint64{1}, make([]byte, 32)),
}
attQueue.extend(wantedAtts)
require.DeepEqual(t, 2, attQueue.size())

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/testing/util"
@@ -38,8 +39,8 @@ func TestSlasher_receiveAttestations_OK(t *testing.T) {
}()
firstIndices := []uint64{1, 2, 3}
secondIndices := []uint64{4, 5, 6}
att1 := createAttestationWrapperEmptySig(t, 1, 2, firstIndices, nil)
att2 := createAttestationWrapperEmptySig(t, 1, 2, secondIndices, nil)
att1 := createAttestationWrapperEmptySig(t, version.Phase0, 1, 2, firstIndices, nil)
att2 := createAttestationWrapperEmptySig(t, version.Phase0, 1, 2, secondIndices, nil)
wrappedAtt1 := &slashertypes.WrappedIndexedAtt{IndexedAtt: att1.IndexedAttestation}
wrappedAtt2 := &slashertypes.WrappedIndexedAtt{IndexedAtt: att2.IndexedAttestation}
indexedAttsChan <- wrappedAtt1
@@ -67,14 +68,14 @@ func TestService_pruneSlasherDataWithinSlidingWindow_AttestationsPruned(t *testi
// Setup attestations for 2 validators at each epoch for epochs 0, 1, 2, 3.
err := slasherDB.SaveAttestationRecordsForValidators(ctx, []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0}, bytesutil.PadTo([]byte("0a"), 32)),
createAttestationWrapperEmptySig(t, 0, 0, []uint64{1}, bytesutil.PadTo([]byte("0b"), 32)),
createAttestationWrapperEmptySig(t, 0, 1, []uint64{0}, bytesutil.PadTo([]byte("1a"), 32)),
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, bytesutil.PadTo([]byte("1b"), 32)),
createAttestationWrapperEmptySig(t, 0, 2, []uint64{0}, bytesutil.PadTo([]byte("2a"), 32)),
createAttestationWrapperEmptySig(t, 0, 2, []uint64{1}, bytesutil.PadTo([]byte("2b"), 32)),
createAttestationWrapperEmptySig(t, 0, 3, []uint64{0}, bytesutil.PadTo([]byte("3a"), 32)),
createAttestationWrapperEmptySig(t, 0, 3, []uint64{1}, bytesutil.PadTo([]byte("3b"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{0}, bytesutil.PadTo([]byte("0a"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 0, []uint64{1}, bytesutil.PadTo([]byte("0b"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 1, []uint64{0}, bytesutil.PadTo([]byte("1a"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 1, []uint64{1}, bytesutil.PadTo([]byte("1b"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 2, []uint64{0}, bytesutil.PadTo([]byte("2a"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 2, []uint64{1}, bytesutil.PadTo([]byte("2b"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 3, []uint64{0}, bytesutil.PadTo([]byte("3a"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 3, []uint64{1}, bytesutil.PadTo([]byte("3b"), 32)),
})
require.NoError(t, err)
@@ -95,8 +96,8 @@ func TestService_pruneSlasherDataWithinSlidingWindow_AttestationsPruned(t *testi
// Setup attestations for 2 validators at epoch 4.
err = slasherDB.SaveAttestationRecordsForValidators(ctx, []*slashertypes.IndexedAttestationWrapper{
createAttestationWrapperEmptySig(t, 0, 4, []uint64{0}, bytesutil.PadTo([]byte("4a"), 32)),
createAttestationWrapperEmptySig(t, 0, 4, []uint64{1}, bytesutil.PadTo([]byte("4b"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 4, []uint64{0}, bytesutil.PadTo([]byte("4a"), 32)),
createAttestationWrapperEmptySig(t, version.Phase0, 0, 4, []uint64{1}, bytesutil.PadTo([]byte("4b"), 32)),
})
require.NoError(t, err)
@@ -224,7 +225,7 @@ func TestSlasher_receiveAttestations_OnlyValidAttestations(t *testing.T) {
firstIndices := []uint64{1, 2, 3}
secondIndices := []uint64{4, 5, 6}
// Add a valid attestation.
validAtt := createAttestationWrapperEmptySig(t, 1, 2, firstIndices, nil)
validAtt := createAttestationWrapperEmptySig(t, version.Phase0, 1, 2, firstIndices, nil)
wrappedValidAtt := &slashertypes.WrappedIndexedAtt{IndexedAtt: validAtt.IndexedAttestation}
indexedAttsChan <- wrappedValidAtt
// Send an invalid, bad attestation which will not

View File

@@ -3,6 +3,7 @@ package slasher
import (
"context"
"io"
"os"
"testing"
"time"
@@ -23,7 +24,7 @@ func TestMain(m *testing.M) {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(io.Discard)
m.Run()
os.Exit(m.Run())
}
func TestService_StartStop_ChainInitialized(t *testing.T) {

View File

@@ -119,6 +119,9 @@ type ReadOnlyValidator interface {
Copy() *ethpb.Validator
Slashed() bool
IsNil() bool
HasETH1WithdrawalCredentials() bool
HasCompoundingWithdrawalCredentials() bool
HasExecutionWithdrawalCredentials() bool
}
// ReadOnlyValidators defines a struct which only has read access to validators methods.

View File

@@ -4,6 +4,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
@@ -88,6 +89,27 @@ func (v readOnlyValidator) IsNil() bool {
return v.validator == nil
}
// HasETH1WithdrawalCredentials returns true if the validator has an ETH1 withdrawal credentials.
func (v readOnlyValidator) HasETH1WithdrawalCredentials() bool {
if v.IsNil() {
return false
}
return v.validator.WithdrawalCredentials[0] == params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
}
// HasCompoundingWithdrawalCredentials returns true if the validator has a compounding withdrawal credentials.
func (v readOnlyValidator) HasCompoundingWithdrawalCredentials() bool {
if v.IsNil() {
return false
}
return v.validator.WithdrawalCredentials[0] == params.BeaconConfig().CompoundingWithdrawalPrefixByte
}
// HasExecutionWithdrawalCredentials returns true if the validator has an execution withdrawal credentials.
func (v readOnlyValidator) HasExecutionWithdrawalCredentials() bool {
return v.HasETH1WithdrawalCredentials() || v.HasCompoundingWithdrawalCredentials()
}
// Copy returns a new validator from the read only validator
func (v readOnlyValidator) Copy() *ethpb.Validator {
pubKey := v.PublicKey()

View File

@@ -292,7 +292,7 @@ func TestExtractDataType(t *testing.T) {
return wsb
}(),
wantMd: wrapper.WrappedMetadataV1(&ethpb.MetaDataV1{}),
wantAtt: &ethpb.AttestationElectra{},
wantAtt: &ethpb.SingleAttestation{},
wantAggregate: &ethpb.SignedAggregateAttestationAndProofElectra{},
wantErr: false,
},

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
"os"
"sync"
"testing"
"time"
@@ -70,7 +71,7 @@ func TestMain(m *testing.M) {
flags.Init(resetFlags)
}()
m.Run()
os.Exit(m.Run())
}
func initializeTestServices(t *testing.T, slots []primitives.Slot, peers []*peerData) (*mock.ChainService, *p2pt.TestP2P, db.Database) {

View File

@@ -2,6 +2,7 @@ package sync
import (
"io"
"os"
"testing"
"github.com/prysmaticlabs/prysm/v5/cmd/beacon-chain/flags"
@@ -22,5 +23,5 @@ func TestMain(m *testing.M) {
defer func() {
flags.Init(resetFlags)
}()
m.Run()
os.Exit(m.Run())
}

View File

@@ -0,0 +1,2 @@
### Changed
- Refactor `2006-01-02 15:04:05` to `time.DateTime`

View File

@@ -0,0 +1,3 @@
### Fixed
- added conditional evaluators to fix scenario e2e tests

View File

@@ -0,0 +1,3 @@
### Fixed
- fix panic with type cast on pbgenericblock()

View File

@@ -0,0 +1,3 @@
### Added
- Remote signer electra fork support.

View File

@@ -0,0 +1,55 @@
### Added
- Added an error field to log `Finished building block`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14696)
- Implemented a new `EmptyExecutionPayloadHeader` function. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14713)
- Added proper gas limit check for header from the builder. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14707)
- `Finished building block`: Display error only if not nil. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14722)
- Added light client feature flag check to RPC handlers. [PR](https://github.com/prysmaticlabs/prysm/pull/14736)
- Added support to update target and max blob count to different values per hard fork config. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14678)
- Log before blob filesystem cache warm-up. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14735)
- New design for the attestation pool. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14324)
- Add field param placeholder for Electra blob target and max to pass spec tests. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14733)
- Light client: Add better error handling. [PR](https://github.com/prysmaticlabs/prysm/pull/14749)
- Add EIP-7691: Blob throughput increase. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14750)
- Trace IDONTWANT Messages in Pubsub. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14778)
- Add Fulu fork boilerplate. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14771)
- DB optimization for saving light client bootstraps (save unique sync committees only)
- Separate type for unaggregated network attestations. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14659)
### Changed
- Process light client finality updates only for new finalized epochs instead of doing it for every block. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14713)
- Refactor subnets subscriptions. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14711)
- Refactor RPC handlers subscriptions. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14732)
- Go deps upgrade, from `ioutil` to `io`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14737)
- Move successfully registered validator(s) on builder log to debug. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14735)
- Update some test files to use `crypto/rand` instead of `math/rand`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14747)
- Re-organize the content of the `*.proto` files (No functional change). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14755)
- SSZ files generation: Remove the `// Hash: ...` header.[[PR]](https://github.com/prysmaticlabs/prysm/pull/14760)
- Updated Electra spec definition for `process_epoch`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14768)
- Update our `go-libp2p-pubsub` dependency. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14770)
- Re-organize the content of files to ease the creation of a new fork boilerplate. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14761)
- Updated spec definition electra `process_registry_updates`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14767)
- Fixed Metadata errors for peers connected via QUIC. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14776)
- Updated spec definitions for `process_slashings` in godocs. Simplified `ProcessSlashings` API. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14766)
- Update spec tests to v1.5.0-beta.0. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14788)
- Process light client finality updates only for new finalized epochs instead of doing it for every block. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14718)
- Update blobs by rpc topics from V2 to V1. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14785)
### Fixed
- Added check to prevent nil pointer deference or out of bounds array access when validating the BLSToExecutionChange on an impossibly nil validator. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14705)
- EIP-7691: Ensure new blobs subnets are subscribed on epoch in advance. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14759)
- Fix kzg commitment inclusion proof depth minimal value. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14787)
### Removed
- Cleanup ProcessSlashings method to remove unnecessary argument. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14762)
- Remove `/proto/eth/v2` directory. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14765)
### Security
- go version upgrade to 1.22.10 for CVE CVE-2024-34156. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14729)
- Update golang.org/x/crypto to v0.31.0 to address CVE-2024-45337. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14777)
- Update golang.org/x/net to v0.33.0 to address CVE-2024-45338. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14780)

View File

@@ -0,0 +1,13 @@
### Changed
- Updated geth to 1.14~. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14351)
- E2e tests start from bellatrix. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14351)
### Removed
- Remove `/memsize/` pprof endpoint as it will no longer be supported in go 1.23. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14351)
### Ignored
- switches unclog from using a flaky github artifact to using a stable release asset.
- Adds changelog entries that were missing from the branch switching prysm over to unclog.

View File

@@ -0,0 +1,2 @@
### Changed
- Version pinning unclog after making some ux improvements.

View File

@@ -0,0 +1,3 @@
### Fixed
- `nodeFilter`: Implement `filterPeerForBlobSubnet` to avoid error logs.

View File

@@ -0,0 +1,3 @@
### Fixed
- `UpgradeToFulu`: Respect the specification.

View File

@@ -0,0 +1,3 @@
### Fixed
- `ToBlinded`: Use Fulu struct for Fulu (instead of Electra)

View File

@@ -0,0 +1,2 @@
### Changed
- Remove helpers to check for execution/compounding withdrawal credentials and expose them as methods.

View File

@@ -0,0 +1,3 @@
### Removed
- Remove `Copy()` from the `ReadOnlyBeaconBlock` interface.

View File

@@ -0,0 +1,3 @@
### Fixed
- Fixed a p2p test to reliably return a static IP through DNS resolution. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14800)

View File

@@ -0,0 +1,3 @@
### Added
- Update slasher service to Electra

View File

@@ -0,0 +1,3 @@
### Fixed
- Use `SingleAttestation` for Fulu in p2p attestation map.

View File

@@ -0,0 +1,3 @@
### Added
- Update `proto_test.go` to Electra.

View File

@@ -0,0 +1,3 @@
### Added
- Add Electra test case to rewards API.

View File

@@ -0,0 +1,3 @@
### Fixed
- Replace exampleIP to `96.7.129.13`

View File

@@ -0,0 +1,3 @@
### Removed
- Clean `TestCanUpgrade*` tests

View File

@@ -0,0 +1,3 @@
### Fixed
- Prysmctl generate genesis state: fix truncation of ExtraData to 32 bytes to satisfy SSZ marshaling

View File

@@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
runtimeDebug "runtime/debug"
"time"
gethlog "github.com/ethereum/go-ethereum/log"
golog "github.com/ipfs/go-log/v2"
@@ -163,7 +164,7 @@ func before(ctx *cli.Context) error {
switch format {
case "text":
formatter := new(prefixed.TextFormatter)
formatter.TimestampFormat = "2006-01-02 15:04:05"
formatter.TimestampFormat = time.DateTime
formatter.FullTimestamp = true
// If persistent log files are written - we disable the log messages coloring because

View File

@@ -60,7 +60,7 @@ func main() {
switch format {
case "text":
formatter := new(prefixed.TextFormatter)
formatter.TimestampFormat = "2006-01-02 15:04:05"
formatter.TimestampFormat = time.DateTime
formatter.FullTimestamp = true
// If persistent log files are written - we disable the log messages coloring because
// the colors are ANSI codes and seen as gibberish in the log files.

View File

@@ -8,6 +8,7 @@ import (
"os"
"path/filepath"
runtimeDebug "runtime/debug"
"time"
joonix "github.com/joonix/log"
"github.com/pkg/errors"
@@ -153,7 +154,7 @@ func main() {
switch format {
case "text":
formatter := new(prefixed.TextFormatter)
formatter.TimestampFormat = "2006-01-02 15:04:05"
formatter.TimestampFormat = time.DateTime
formatter.FullTimestamp = true
// If persistent log files are written - we disable the log messages coloring because
// the colors are ANSI codes and seen as gibberish in the log files.

View File

@@ -366,5 +366,5 @@ func FillTestVersions(c *BeaconChainConfig, b byte) {
c.CapellaForkVersion[0] = 3
c.DenebForkVersion[0] = 4
c.ElectraForkVersion[0] = 5
c.FuluForkVersion[0] = 5
c.FuluForkVersion[0] = 6
}

View File

@@ -55,6 +55,7 @@ go_test(
embed = [":go_default_library"],
deps = [
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",

View File

@@ -784,7 +784,10 @@ func PayloadToHeaderDeneb(payload interfaces.ExecutionData) (*enginev1.Execution
}, nil
}
var PayloadToHeaderElectra = PayloadToHeaderDeneb
var (
PayloadToHeaderElectra = PayloadToHeaderDeneb
PayloadToHeaderFulu = PayloadToHeaderDeneb
)
// IsEmptyExecutionData checks if an execution data is empty underneath. If a single field has
// a non-zero value, this function will return false.

View File

@@ -124,8 +124,12 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
Block: &eth.GenericSignedBeaconBlock_BlindedDeneb{BlindedDeneb: pb.(*eth.SignedBlindedBeaconBlockDeneb)},
}, nil
}
bc, ok := pb.(*eth.SignedBeaconBlockContentsDeneb)
if !ok {
return nil, fmt.Errorf("PbGenericBlock() only supports block content type but got %T", pb)
}
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Deneb{Deneb: pb.(*eth.SignedBeaconBlockContentsDeneb)},
Block: &eth.GenericSignedBeaconBlock_Deneb{Deneb: bc},
}, nil
case version.Electra:
if b.IsBlinded() {
@@ -133,8 +137,12 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
Block: &eth.GenericSignedBeaconBlock_BlindedElectra{BlindedElectra: pb.(*eth.SignedBlindedBeaconBlockElectra)},
}, nil
}
bc, ok := pb.(*eth.SignedBeaconBlockContentsElectra)
if !ok {
return nil, fmt.Errorf("PbGenericBlock() only supports block content type but got %T", pb)
}
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Electra{Electra: pb.(*eth.SignedBeaconBlockContentsElectra)},
Block: &eth.GenericSignedBeaconBlock_Electra{Electra: bc},
}, nil
case version.Fulu:
if b.IsBlinded() {
@@ -142,8 +150,12 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
Block: &eth.GenericSignedBeaconBlock_BlindedFulu{BlindedFulu: pb.(*eth.SignedBlindedBeaconBlockFulu)},
}, nil
}
bc, ok := pb.(*eth.SignedBeaconBlockContentsFulu)
if !ok {
return nil, fmt.Errorf("PbGenericBlock() only supports block content type but got %T", pb)
}
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Fulu{Fulu: pb.(*eth.SignedBeaconBlockContentsFulu)},
Block: &eth.GenericSignedBeaconBlock_Fulu{Fulu: bc},
}, nil
default:
return nil, errIncorrectBlockVersion
@@ -166,6 +178,43 @@ func (b *SignedBeaconBlock) ToBlinded() (interfaces.ReadOnlySignedBeaconBlock, e
return nil, err
}
if b.version >= version.Fulu {
p, ok := payload.Proto().(*enginev1.ExecutionPayloadDeneb)
if !ok {
return nil, fmt.Errorf("%T is not an execution payload header of Deneb version", p)
}
header, err := PayloadToHeaderFulu(payload)
if err != nil {
return nil, errors.Wrap(err, "payload to header fulu")
}
return initBlindedSignedBlockFromProtoFulu(
&eth.SignedBlindedBeaconBlockFulu{
Message: &eth.BlindedBeaconBlockFulu{
Slot: b.block.slot,
ProposerIndex: b.block.proposerIndex,
ParentRoot: b.block.parentRoot[:],
StateRoot: b.block.stateRoot[:],
Body: &eth.BlindedBeaconBlockBodyFulu{
RandaoReveal: b.block.body.randaoReveal[:],
Eth1Data: b.block.body.eth1Data,
Graffiti: b.block.body.graffiti[:],
ProposerSlashings: b.block.body.proposerSlashings,
AttesterSlashings: b.block.body.attesterSlashingsElectra,
Attestations: b.block.body.attestationsElectra,
Deposits: b.block.body.deposits,
VoluntaryExits: b.block.body.voluntaryExits,
SyncAggregate: b.block.body.syncAggregate,
ExecutionPayloadHeader: header,
BlsToExecutionChanges: b.block.body.blsToExecutionChanges,
BlobKzgCommitments: b.block.body.blobKzgCommitments,
ExecutionRequests: b.block.body.executionRequests,
},
},
Signature: b.signature[:],
})
}
if b.version >= version.Electra {
p, ok := payload.Proto().(*enginev1.ExecutionPayloadDeneb)
if !ok {
@@ -173,7 +222,7 @@ func (b *SignedBeaconBlock) ToBlinded() (interfaces.ReadOnlySignedBeaconBlock, e
}
header, err := PayloadToHeaderElectra(payload)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "payload to header electra")
}
return initBlindedSignedBlockFromProtoElectra(
&eth.SignedBlindedBeaconBlockElectra{
@@ -206,7 +255,7 @@ func (b *SignedBeaconBlock) ToBlinded() (interfaces.ReadOnlySignedBeaconBlock, e
case *enginev1.ExecutionPayload:
header, err := PayloadToHeader(payload)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "payload to header")
}
return initBlindedSignedBlockFromProtoBellatrix(
&eth.SignedBlindedBeaconBlockBellatrix{
@@ -261,7 +310,7 @@ func (b *SignedBeaconBlock) ToBlinded() (interfaces.ReadOnlySignedBeaconBlock, e
case *enginev1.ExecutionPayloadDeneb:
header, err := PayloadToHeaderDeneb(payload)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "payload to header deneb")
}
return initBlindedSignedBlockFromProtoDeneb(
&eth.SignedBlindedBeaconBlockDeneb{
@@ -1058,50 +1107,6 @@ func (b *BeaconBlock) AsSignRequestObject() (validatorpb.SignRequestObject, erro
}
}
func (b *BeaconBlock) Copy() (interfaces.ReadOnlyBeaconBlock, error) {
if b == nil {
return nil, nil
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
switch b.version {
case version.Phase0:
return initBlockFromProtoPhase0(pb.(*eth.BeaconBlock).Copy())
case version.Altair:
return initBlockFromProtoAltair(pb.(*eth.BeaconBlockAltair).Copy())
case version.Bellatrix:
if b.IsBlinded() {
return initBlindedBlockFromProtoBellatrix(pb.(*eth.BlindedBeaconBlockBellatrix).Copy())
}
return initBlockFromProtoBellatrix(pb.(*eth.BeaconBlockBellatrix).Copy())
case version.Capella:
if b.IsBlinded() {
return initBlindedBlockFromProtoCapella(pb.(*eth.BlindedBeaconBlockCapella).Copy())
}
return initBlockFromProtoCapella(pb.(*eth.BeaconBlockCapella).Copy())
case version.Deneb:
if b.IsBlinded() {
return initBlindedBlockFromProtoDeneb(pb.(*eth.BlindedBeaconBlockDeneb).Copy())
}
return initBlockFromProtoDeneb(pb.(*eth.BeaconBlockDeneb).Copy())
case version.Electra:
if b.IsBlinded() {
return initBlindedBlockFromProtoElectra(pb.(*eth.BlindedBeaconBlockElectra).Copy())
}
return initBlockFromProtoElectra(pb.(*eth.BeaconBlockElectra).Copy())
case version.Fulu:
if b.IsBlinded() {
return initBlindedBlockFromProtoFulu(pb.(*eth.BlindedBeaconBlockFulu).Copy())
}
return initBlockFromProtoFulu(pb.(*eth.BeaconBlockFulu).Copy())
default:
return nil, errIncorrectBlockVersion
}
}
// IsNil checks if the block body is nil.
func (b *BeaconBlockBody) IsNil() bool {
return b == nil

View File

@@ -169,70 +169,6 @@ func Test_BeaconBlock_Body(t *testing.T) {
assert.Equal(t, bb, b.Body())
}
func Test_BeaconBlock_Copy(t *testing.T) {
bb := &BeaconBlockBody{randaoReveal: bytesutil.ToBytes96([]byte{246}), graffiti: bytesutil.ToBytes32([]byte("graffiti"))}
b := &BeaconBlock{body: bb, slot: 123, proposerIndex: 456, parentRoot: bytesutil.ToBytes32([]byte("parentroot")), stateRoot: bytesutil.ToBytes32([]byte("stateroot"))}
cp, err := b.Copy()
require.NoError(t, err)
assert.NotEqual(t, cp, b)
assert.NotEqual(t, cp.Body(), bb)
b.version = version.Altair
b.body.version = b.version
cp, err = b.Copy()
require.NoError(t, err)
assert.NotEqual(t, cp, b)
assert.NotEqual(t, cp.Body(), bb)
b.version = version.Bellatrix
b.body.version = b.version
cp, err = b.Copy()
require.NoError(t, err)
assert.NotEqual(t, cp, b)
assert.NotEqual(t, cp.Body(), bb)
b.version = version.Capella
b.body.version = b.version
cp, err = b.Copy()
require.NoError(t, err)
assert.NotEqual(t, cp, b)
assert.NotEqual(t, cp.Body(), bb)
b.version = version.Bellatrix
b.body.version = b.version
cp, err = b.Copy()
require.NoError(t, err)
assert.NotEqual(t, cp, b)
assert.NotEqual(t, cp.Body(), bb)
b.version = version.Capella
b.body.version = b.version
cp, err = b.Copy()
require.NoError(t, err)
assert.NotEqual(t, cp, b)
assert.NotEqual(t, cp.Body(), bb)
payload := &pb.ExecutionPayloadDeneb{ExcessBlobGas: 123}
header := &pb.ExecutionPayloadHeaderDeneb{ExcessBlobGas: 223}
payloadInterface, err := WrappedExecutionPayloadDeneb(payload)
require.NoError(t, err)
headerInterface, err := WrappedExecutionPayloadHeaderDeneb(header)
require.NoError(t, err)
bb = &BeaconBlockBody{executionPayload: payloadInterface, executionPayloadHeader: headerInterface, randaoReveal: bytesutil.ToBytes96([]byte{246}), graffiti: bytesutil.ToBytes32([]byte("graffiti"))}
b = &BeaconBlock{body: bb, slot: 123, proposerIndex: 456, parentRoot: bytesutil.ToBytes32([]byte("parentroot")), stateRoot: bytesutil.ToBytes32([]byte("stateroot"))}
b.version = version.Deneb
b.body.version = b.version
cp, err = b.Copy()
require.NoError(t, err)
assert.NotEqual(t, cp, b)
assert.NotEqual(t, cp.Body(), bb)
e, err := cp.Body().Execution()
require.NoError(t, err)
gas, err := e.ExcessBlobGas()
require.NoError(t, err)
require.DeepEqual(t, gas, uint64(123))
}
func Test_BeaconBlock_IsNil(t *testing.T) {
t.Run("nil block", func(t *testing.T) {
var b *BeaconBlock

View File

@@ -4,6 +4,8 @@ import (
"testing"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
@@ -17,8 +19,10 @@ type fields struct {
sig [96]byte
deposits []*eth.Deposit
atts []*eth.Attestation
attsElectra []*eth.AttestationElectra
proposerSlashings []*eth.ProposerSlashing
attesterSlashings []*eth.AttesterSlashing
attesterSlashingsElectra []*eth.AttesterSlashingElectra
voluntaryExits []*eth.SignedVoluntaryExit
syncAggregate *eth.SyncAggregate
execPayload *enginev1.ExecutionPayload
@@ -29,6 +33,7 @@ type fields struct {
execPayloadHeaderDeneb *enginev1.ExecutionPayloadHeaderDeneb
blsToExecutionChanges []*eth.SignedBLSToExecutionChange
kzgCommitments [][]byte
execRequests *enginev1.ExecutionRequests
}
func Test_SignedBeaconBlock_Proto(t *testing.T) {
@@ -306,6 +311,74 @@ func Test_SignedBeaconBlock_Proto(t *testing.T) {
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
t.Run("Electra", func(t *testing.T) {
expectedBlock := &eth.SignedBeaconBlockElectra{
Block: &eth.BeaconBlockElectra{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
StateRoot: f.root[:],
Body: bodyPbElectra(),
},
Signature: f.sig[:],
}
block := &SignedBeaconBlock{
version: version.Electra,
block: &BeaconBlock{
version: version.Electra,
slot: 128,
proposerIndex: 128,
parentRoot: f.root,
stateRoot: f.root,
body: bodyElectra(t),
},
signature: f.sig,
}
result, err := block.Proto()
require.NoError(t, err)
resultBlock, ok := result.(*eth.SignedBeaconBlockElectra)
require.Equal(t, true, ok)
resultHTR, err := resultBlock.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
t.Run("ElectraBlind", func(t *testing.T) {
expectedBlock := &eth.SignedBlindedBeaconBlockElectra{
Message: &eth.BlindedBeaconBlockElectra{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
StateRoot: f.root[:],
Body: bodyPbBlindedElectra(),
},
Signature: f.sig[:],
}
block := &SignedBeaconBlock{
version: version.Electra,
block: &BeaconBlock{
version: version.Electra,
slot: 128,
proposerIndex: 128,
parentRoot: f.root,
stateRoot: f.root,
body: bodyBlindedElectra(t),
},
signature: f.sig,
}
result, err := block.Proto()
require.NoError(t, err)
resultBlock, ok := result.(*eth.SignedBlindedBeaconBlockElectra)
require.Equal(t, true, ok)
resultHTR, err := resultBlock.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
}
func Test_BeaconBlock_Proto(t *testing.T) {
@@ -527,6 +600,60 @@ func Test_BeaconBlock_Proto(t *testing.T) {
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
t.Run("Electra", func(t *testing.T) {
expectedBlock := &eth.BeaconBlockElectra{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
StateRoot: f.root[:],
Body: bodyPbElectra(),
}
block := &BeaconBlock{
version: version.Electra,
slot: 128,
proposerIndex: 128,
parentRoot: f.root,
stateRoot: f.root,
body: bodyElectra(t),
}
result, err := block.Proto()
require.NoError(t, err)
resultBlock, ok := result.(*eth.BeaconBlockElectra)
require.Equal(t, true, ok)
resultHTR, err := resultBlock.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
t.Run("ElectraBlind", func(t *testing.T) {
expectedBlock := &eth.BlindedBeaconBlockElectra{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
StateRoot: f.root[:],
Body: bodyPbBlindedElectra(),
}
block := &BeaconBlock{
version: version.Electra,
slot: 128,
proposerIndex: 128,
parentRoot: f.root,
stateRoot: f.root,
body: bodyBlindedElectra(t),
}
result, err := block.Proto()
require.NoError(t, err)
resultBlock, ok := result.(*eth.BlindedBeaconBlockElectra)
require.Equal(t, true, ok)
resultHTR, err := resultBlock.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
}
func Test_BeaconBlockBody_Proto(t *testing.T) {
@@ -635,6 +762,32 @@ func Test_BeaconBlockBody_Proto(t *testing.T) {
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
t.Run("Electra", func(t *testing.T) {
expectedBody := bodyPbElectra()
body := bodyElectra(t)
result, err := body.Proto()
require.NoError(t, err)
resultBlock, ok := result.(*eth.BeaconBlockBodyElectra)
require.Equal(t, true, ok)
resultHTR, err := resultBlock.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBody.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
t.Run("ElectraBlind", func(t *testing.T) {
expectedBody := bodyPbBlindedElectra()
body := bodyBlindedElectra(t)
result, err := body.Proto()
require.NoError(t, err)
resultBlock, ok := result.(*eth.BlindedBeaconBlockBodyElectra)
require.Equal(t, true, ok)
resultHTR, err := resultBlock.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBody.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
})
t.Run("Bellatrix - wrong payload type", func(t *testing.T) {
body := bodyBellatrix(t)
body.executionPayload = &executionPayloadHeader{}
@@ -671,6 +824,18 @@ func Test_BeaconBlockBody_Proto(t *testing.T) {
_, err := body.Proto()
require.ErrorIs(t, err, errPayloadHeaderWrongType)
})
t.Run("Electra - wrong payload type", func(t *testing.T) {
body := bodyElectra(t)
body.executionPayload = &executionPayloadHeaderDeneb{}
_, err := body.Proto()
require.ErrorIs(t, err, errPayloadWrongType)
})
t.Run("ElectraBlind - wrong payload type", func(t *testing.T) {
body := bodyBlindedElectra(t)
body.executionPayloadHeader = &executionPayloadDeneb{}
_, err := body.Proto()
require.ErrorIs(t, err, errPayloadHeaderWrongType)
})
}
func Test_initSignedBlockFromProtoPhase0(t *testing.T) {
@@ -849,6 +1014,50 @@ func Test_initBlindedSignedBlockFromProtoDeneb(t *testing.T) {
assert.DeepEqual(t, expectedBlock.Signature, resultBlock.signature[:])
}
func Test_initSignedBlockFromProtoElectra(t *testing.T) {
f := getFields()
expectedBlock := &eth.SignedBeaconBlockElectra{
Block: &eth.BeaconBlockElectra{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
StateRoot: f.root[:],
Body: bodyPbElectra(),
},
Signature: f.sig[:],
}
resultBlock, err := initSignedBlockFromProtoElectra(expectedBlock)
require.NoError(t, err)
resultHTR, err := resultBlock.block.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.Block.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
assert.DeepEqual(t, expectedBlock.Signature, resultBlock.signature[:])
}
func Test_initBlindedSignedBlockFromProtoElectra(t *testing.T) {
f := getFields()
expectedBlock := &eth.SignedBlindedBeaconBlockElectra{
Message: &eth.BlindedBeaconBlockElectra{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
StateRoot: f.root[:],
Body: bodyPbBlindedElectra(),
},
Signature: f.sig[:],
}
resultBlock, err := initBlindedSignedBlockFromProtoElectra(expectedBlock)
require.NoError(t, err)
resultHTR, err := resultBlock.block.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.Message.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
assert.DeepEqual(t, expectedBlock.Signature, resultBlock.signature[:])
}
func Test_initBlockFromProtoPhase0(t *testing.T) {
f := getFields()
expectedBlock := &eth.BeaconBlock{
@@ -993,6 +1202,42 @@ func Test_initBlockFromProtoBlindedDeneb(t *testing.T) {
assert.DeepEqual(t, expectedHTR, resultHTR)
}
func Test_initBlockFromProtoElectra(t *testing.T) {
f := getFields()
expectedBlock := &eth.BeaconBlockElectra{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
StateRoot: f.root[:],
Body: bodyPbElectra(),
}
resultBlock, err := initBlockFromProtoElectra(expectedBlock)
require.NoError(t, err)
resultHTR, err := resultBlock.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
}
func Test_initBlockFromProtoBlindedElectra(t *testing.T) {
f := getFields()
expectedBlock := &eth.BlindedBeaconBlockElectra{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
StateRoot: f.root[:],
Body: bodyPbBlindedElectra(),
}
resultBlock, err := initBlindedBlockFromProtoElectra(expectedBlock)
require.NoError(t, err)
resultHTR, err := resultBlock.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
}
func Test_initBlockBodyFromProtoPhase0(t *testing.T) {
expectedBody := bodyPbPhase0()
resultBody, err := initBlockBodyFromProtoPhase0(expectedBody)
@@ -1081,6 +1326,28 @@ func Test_initBlockBodyFromProtoBlindedDeneb(t *testing.T) {
assert.DeepEqual(t, expectedHTR, resultHTR)
}
func Test_initBlockBodyFromProtoElectra(t *testing.T) {
expectedBody := bodyPbElectra()
resultBody, err := initBlockBodyFromProtoElectra(expectedBody)
require.NoError(t, err)
resultHTR, err := resultBody.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBody.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
}
func Test_initBlockBodyFromProtoBlindedElectra(t *testing.T) {
expectedBody := bodyPbBlindedElectra()
resultBody, err := initBlindedBlockBodyFromProtoElectra(expectedBody)
require.NoError(t, err)
resultHTR, err := resultBody.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBody.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
}
func bodyPbPhase0() *eth.BeaconBlockBody {
f := getFields()
return &eth.BeaconBlockBody{
@@ -1244,6 +1511,52 @@ func bodyPbBlindedDeneb() *eth.BlindedBeaconBlockBodyDeneb {
}
}
func bodyPbElectra() *eth.BeaconBlockBodyElectra {
f := getFields()
return &eth.BeaconBlockBodyElectra{
RandaoReveal: f.sig[:],
Eth1Data: &eth.Eth1Data{
DepositRoot: f.root[:],
DepositCount: 128,
BlockHash: f.root[:],
},
Graffiti: f.root[:],
ProposerSlashings: f.proposerSlashings,
AttesterSlashings: f.attesterSlashingsElectra,
Attestations: f.attsElectra,
Deposits: f.deposits,
VoluntaryExits: f.voluntaryExits,
SyncAggregate: f.syncAggregate,
ExecutionPayload: f.execPayloadDeneb,
BlsToExecutionChanges: f.blsToExecutionChanges,
BlobKzgCommitments: f.kzgCommitments,
ExecutionRequests: f.execRequests,
}
}
func bodyPbBlindedElectra() *eth.BlindedBeaconBlockBodyElectra {
f := getFields()
return &eth.BlindedBeaconBlockBodyElectra{
RandaoReveal: f.sig[:],
Eth1Data: &eth.Eth1Data{
DepositRoot: f.root[:],
DepositCount: 128,
BlockHash: f.root[:],
},
Graffiti: f.root[:],
ProposerSlashings: f.proposerSlashings,
AttesterSlashings: f.attesterSlashingsElectra,
Attestations: f.attsElectra,
Deposits: f.deposits,
VoluntaryExits: f.voluntaryExits,
SyncAggregate: f.syncAggregate,
ExecutionPayloadHeader: f.execPayloadHeaderDeneb,
BlsToExecutionChanges: f.blsToExecutionChanges,
BlobKzgCommitments: f.kzgCommitments,
ExecutionRequests: f.execRequests,
}
}
func bodyPhase0() *BeaconBlockBody {
f := getFields()
return &BeaconBlockBody{
@@ -1427,6 +1740,58 @@ func bodyBlindedDeneb(t *testing.T) *BeaconBlockBody {
}
}
func bodyElectra(t *testing.T) *BeaconBlockBody {
f := getFields()
p, err := WrappedExecutionPayloadDeneb(f.execPayloadDeneb)
require.NoError(t, err)
return &BeaconBlockBody{
version: version.Electra,
randaoReveal: f.sig,
eth1Data: &eth.Eth1Data{
DepositRoot: f.root[:],
DepositCount: 128,
BlockHash: f.root[:],
},
graffiti: f.root,
proposerSlashings: f.proposerSlashings,
attesterSlashingsElectra: f.attesterSlashingsElectra,
attestationsElectra: f.attsElectra,
deposits: f.deposits,
voluntaryExits: f.voluntaryExits,
syncAggregate: f.syncAggregate,
executionPayload: p,
blsToExecutionChanges: f.blsToExecutionChanges,
blobKzgCommitments: f.kzgCommitments,
executionRequests: f.execRequests,
}
}
func bodyBlindedElectra(t *testing.T) *BeaconBlockBody {
f := getFields()
ph, err := WrappedExecutionPayloadHeaderDeneb(f.execPayloadHeaderDeneb)
require.NoError(t, err)
return &BeaconBlockBody{
version: version.Electra,
randaoReveal: f.sig,
eth1Data: &eth.Eth1Data{
DepositRoot: f.root[:],
DepositCount: 128,
BlockHash: f.root[:],
},
graffiti: f.root,
proposerSlashings: f.proposerSlashings,
attesterSlashingsElectra: f.attesterSlashingsElectra,
attestationsElectra: f.attsElectra,
deposits: f.deposits,
voluntaryExits: f.voluntaryExits,
syncAggregate: f.syncAggregate,
executionPayloadHeader: ph,
blsToExecutionChanges: f.blsToExecutionChanges,
blobKzgCommitments: f.kzgCommitments,
executionRequests: f.execRequests,
}
}
func getFields() fields {
b20 := make([]byte, 20)
b48 := make([]byte, 48)
@@ -1452,11 +1817,14 @@ func getFields() fields {
Signature: sig[:],
}
}
atts := make([]*eth.Attestation, 128)
attBits := bitfield.NewBitlist(1)
committeeBits := primitives.NewAttestationCommitteeBits()
atts := make([]*eth.Attestation, params.BeaconConfig().MaxAttestations)
for i := range atts {
atts[i] = &eth.Attestation{}
atts[i].Signature = sig[:]
atts[i].AggregationBits = bitfield.NewBitlist(1)
atts[i].AggregationBits = attBits
atts[i].Data = &eth.AttestationData{
Slot: 128,
CommitteeIndex: 128,
@@ -1471,6 +1839,27 @@ func getFields() fields {
},
}
}
attsElectra := make([]*eth.AttestationElectra, params.BeaconConfig().MaxAttestationsElectra)
for i := range attsElectra {
attsElectra[i] = &eth.AttestationElectra{}
attsElectra[i].Signature = sig[:]
attsElectra[i].AggregationBits = attBits
attsElectra[i].CommitteeBits = committeeBits
attsElectra[i].Data = &eth.AttestationData{
Slot: 128,
CommitteeIndex: 128,
BeaconBlockRoot: root[:],
Source: &eth.Checkpoint{
Epoch: 128,
Root: root[:],
},
Target: &eth.Checkpoint{
Epoch: 128,
Root: root[:],
},
}
}
proposerSlashing := &eth.ProposerSlashing{
Header_1: &eth.SignedBeaconBlockHeader{
Header: &eth.BeaconBlockHeader{
@@ -1529,6 +1918,42 @@ func getFields() fields {
Signature: sig[:],
},
}
attesterSlashingElectra := &eth.AttesterSlashingElectra{
Attestation_1: &eth.IndexedAttestationElectra{
AttestingIndices: []uint64{1, 2, 8},
Data: &eth.AttestationData{
Slot: 128,
CommitteeIndex: 128,
BeaconBlockRoot: root[:],
Source: &eth.Checkpoint{
Epoch: 128,
Root: root[:],
},
Target: &eth.Checkpoint{
Epoch: 128,
Root: root[:],
},
},
Signature: sig[:],
},
Attestation_2: &eth.IndexedAttestationElectra{
AttestingIndices: []uint64{1, 2, 8},
Data: &eth.AttestationData{
Slot: 128,
CommitteeIndex: 128,
BeaconBlockRoot: root[:],
Source: &eth.Checkpoint{
Epoch: 128,
Root: root[:],
},
Target: &eth.Checkpoint{
Epoch: 128,
Root: root[:],
},
},
Signature: sig[:],
},
}
voluntaryExit := &eth.SignedVoluntaryExit{
Exit: &eth.VoluntaryExit{
Epoch: 128,
@@ -1689,13 +2114,35 @@ func getFields() fields {
bytesutil.PadTo([]byte{143}, 48),
}
execRequests := &enginev1.ExecutionRequests{
Deposits: []*enginev1.DepositRequest{{
Pubkey: b48,
WithdrawalCredentials: root[:],
Amount: 128,
Signature: sig[:],
Index: 128,
}},
Withdrawals: []*enginev1.WithdrawalRequest{{
SourceAddress: b20,
ValidatorPubkey: b48,
Amount: 128,
}},
Consolidations: []*enginev1.ConsolidationRequest{{
SourceAddress: b20,
SourcePubkey: b48,
TargetPubkey: b48,
}},
}
return fields{
root: root,
sig: sig,
deposits: deposits,
atts: atts,
attsElectra: attsElectra,
proposerSlashings: []*eth.ProposerSlashing{proposerSlashing},
attesterSlashings: []*eth.AttesterSlashing{attesterSlashing},
attesterSlashingsElectra: []*eth.AttesterSlashingElectra{attesterSlashingElectra},
voluntaryExits: []*eth.SignedVoluntaryExit{voluntaryExit},
syncAggregate: syncAggregate,
execPayload: execPayload,
@@ -1706,5 +2153,6 @@ func getFields() fields {
execPayloadHeaderDeneb: execPayloadHeaderDeneb,
blsToExecutionChanges: blsToExecutionChanges,
kzgCommitments: kzgCommitments,
execRequests: execRequests,
}
}

View File

@@ -47,7 +47,6 @@ type ReadOnlyBeaconBlock interface {
ssz.HashRoot
Version() int
AsSignRequestObject() (validatorpb.SignRequestObject, error)
Copy() (ReadOnlyBeaconBlock, error)
}
// ReadOnlyBeaconBlockBody describes the method set employed by an object

View File

@@ -163,10 +163,6 @@ func (BeaconBlock) SetParentRoot(_ []byte) {
panic("implement me")
}
func (BeaconBlock) Copy() (interfaces.ReadOnlyBeaconBlock, error) {
panic("implement me")
}
type BeaconBlockBody struct{}
func (BeaconBlockBody) RandaoReveal() [field_params.BLSSignatureLength]byte {

View File

@@ -37,8 +37,8 @@ def prysm_deps():
go_repository(
name = "co_honnef_go_tools",
importpath = "honnef.co/go/tools",
sum = "h1:VUeHARd+9362HPYyFWjsRa6jBIAf2xWbDv6QXMRztbQ=",
version = "v0.5.0-0.dev.0.20231205170804-aef76f4feee2",
sum = "h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I=",
version = "v0.5.1",
)
go_repository(
name = "com_github_aclements_go_moremath",
@@ -331,8 +331,8 @@ def prysm_deps():
go_repository(
name = "com_github_burntsushi_toml",
importpath = "github.com/BurntSushi/toml",
sum = "h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=",
version = "v1.3.2",
sum = "h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=",
version = "v1.4.1-0.20240526193622-a339e1f7089c",
)
go_repository(
name = "com_github_burntsushi_xgb",
@@ -1802,8 +1802,8 @@ def prysm_deps():
go_repository(
name = "com_github_kisielk_errcheck",
importpath = "github.com/kisielk/errcheck",
sum = "h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=",
version = "v1.5.0",
sum = "h1:ZX/URYa7ilESY19ik/vBmCn6zdGQLxACwjAcWbHlYlg=",
version = "v1.8.0",
)
go_repository(
name = "com_github_kisielk_gotool",
@@ -4661,8 +4661,8 @@ def prysm_deps():
go_repository(
name = "org_golang_x_crypto",
importpath = "golang.org/x/crypto",
sum = "h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=",
version = "v0.31.0",
sum = "h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=",
version = "v0.32.0",
)
go_repository(
name = "org_golang_x_exp",
@@ -4697,14 +4697,14 @@ def prysm_deps():
go_repository(
name = "org_golang_x_mod",
importpath = "golang.org/x/mod",
sum = "h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=",
version = "v0.20.0",
sum = "h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=",
version = "v0.22.0",
)
go_repository(
name = "org_golang_x_net",
importpath = "golang.org/x/net",
sum = "h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=",
version = "v0.33.0",
sum = "h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=",
version = "v0.34.0",
)
go_repository(
name = "org_golang_x_oauth2",
@@ -4727,8 +4727,8 @@ def prysm_deps():
go_repository(
name = "org_golang_x_sys",
importpath = "golang.org/x/sys",
sum = "h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=",
version = "v0.28.0",
sum = "h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=",
version = "v0.29.0",
)
go_repository(
name = "org_golang_x_telemetry",
@@ -4739,8 +4739,8 @@ def prysm_deps():
go_repository(
name = "org_golang_x_term",
importpath = "golang.org/x/term",
sum = "h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=",
version = "v0.27.0",
sum = "h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=",
version = "v0.28.0",
)
go_repository(
name = "org_golang_x_text",
@@ -4757,8 +4757,8 @@ def prysm_deps():
go_repository(
name = "org_golang_x_tools",
importpath = "golang.org/x/tools",
sum = "h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=",
version = "v0.24.0",
sum = "h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=",
version = "v0.29.0",
)
go_repository(
name = "org_golang_x_xerrors",

25
go.mod
View File

@@ -1,8 +1,6 @@
module github.com/prysmaticlabs/prysm/v5
go 1.22.0
toolchain go1.22.10
go 1.23.5
require (
github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20240516070431-7828990cad7d
@@ -40,6 +38,7 @@ require (
github.com/joonix/log v0.0.0-20200409080653-9c1d2ceb5f1d
github.com/json-iterator/go v1.1.12
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213
github.com/kisielk/errcheck v1.8.0
github.com/kr/pretty v0.3.1
github.com/libp2p/go-libp2p v0.36.5
github.com/libp2p/go-libp2p-mplex v0.9.0
@@ -52,8 +51,6 @@ require (
github.com/minio/sha256-simd v1.0.1
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/multiformats/go-multiaddr v0.13.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.34.1
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/paulbellamy/ratecounter v0.2.0
github.com/pborman/uuid v1.2.1
@@ -89,24 +86,24 @@ require (
go.opentelemetry.io/otel/trace v1.29.0
go.uber.org/automaxprocs v1.5.2
go.uber.org/mock v0.4.0
golang.org/x/crypto v0.31.0
golang.org/x/crypto v0.32.0
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
golang.org/x/mod v0.20.0
golang.org/x/mod v0.22.0
golang.org/x/sync v0.10.0
golang.org/x/tools v0.24.0
golang.org/x/tools v0.29.0
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
google.golang.org/grpc v1.65.0
google.golang.org/protobuf v1.34.2
gopkg.in/d4l3k/messagediff.v1 v1.2.1
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
honnef.co/go/tools v0.5.0-0.dev.0.20231205170804-aef76f4feee2
honnef.co/go/tools v0.5.1
k8s.io/apimachinery v0.30.4
k8s.io/client-go v0.30.4
)
require (
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/VictoriaMetrics/fastcache v1.12.2 // indirect
@@ -207,7 +204,6 @@ require (
github.com/multiformats/go-multistream v0.5.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nxadm/tail v1.4.11 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/onsi/ginkgo/v2 v2.20.0 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
@@ -255,15 +251,14 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/term v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.5.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
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
@@ -280,7 +275,7 @@ require (
github.com/go-playground/validator/v10 v10.13.0
github.com/peterh/liner v1.2.0 // indirect
github.com/prysmaticlabs/gohashtree v0.0.4-beta.0.20240624100937-73632381301b
golang.org/x/sys v0.28.0 // indirect
golang.org/x/sys v0.29.0 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
)

38
go.sum
View File

@@ -45,8 +45,8 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
@@ -312,7 +312,6 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
@@ -541,6 +540,8 @@ github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/errcheck v1.8.0 h1:ZX/URYa7ilESY19ik/vBmCn6zdGQLxACwjAcWbHlYlg=
github.com/kisielk/errcheck v1.8.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
@@ -731,7 +732,6 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
@@ -1153,8 +1153,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1197,8 +1197,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1255,8 +1255,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1352,7 +1352,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1377,8 +1376,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -1387,8 +1386,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1468,7 +1467,6 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@@ -1478,8 +1476,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1655,8 +1653,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.5.0-0.dev.0.20231205170804-aef76f4feee2 h1:VUeHARd+9362HPYyFWjsRa6jBIAf2xWbDv6QXMRztbQ=
honnef.co/go/tools v0.5.0-0.dev.0.20231205170804-aef76f4feee2/go.mod h1:J8YyqAvNy0yWpeKUOCONA1m2G4hH2CqUSo/5ZO2/5UA=
honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I=
honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs=
k8s.io/api v0.30.4 h1:XASIELmW8w8q0i1Y4124LqPoWMycLjyQti/fdYHYjCs=
k8s.io/api v0.30.4/go.mod h1:ZqniWRKu7WIeLijbbzetF4U9qZ03cg5IRwl8YVs8mX0=
k8s.io/apimachinery v0.30.4 h1:5QHQI2tInzr8LsT4kU/2+fSeibH1eIHswNx480cqIoY=

View File

@@ -2,6 +2,7 @@ package attestations
import (
"io"
"os"
"sort"
"testing"
@@ -19,7 +20,7 @@ import (
func TestMain(m *testing.M) {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(io.Discard)
m.Run()
os.Exit(m.Run())
}
func TestAggregateAttestations_AggregatePair(t *testing.T) {

View File

@@ -621,6 +621,10 @@ func (s *PremineGenesisConfig) setLatestBlockHeader(g state.BeaconState) error {
func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error {
gb := s.GB
extraData := gb.Extra()
if len(extraData) > 32 {
extraData = extraData[:32]
}
if s.Version >= version.Deneb {
payload := &enginev1.ExecutionPayloadDeneb{
@@ -634,7 +638,7 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error {
GasLimit: gb.GasLimit(),
GasUsed: gb.GasUsed(),
Timestamp: gb.Time(),
ExtraData: gb.Extra(),
ExtraData: extraData,
BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength),
BlockHash: gb.Hash().Bytes(),
Transactions: make([][]byte, 0),
@@ -673,7 +677,7 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error {
GasLimit: gb.GasLimit(),
GasUsed: gb.GasUsed(),
Timestamp: gb.Time(),
ExtraData: gb.Extra(),
ExtraData: extraData,
BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength),
BlockHash: gb.Hash().Bytes(),
Transactions: make([][]byte, 0),
@@ -709,7 +713,7 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error {
GasLimit: gb.GasLimit(),
GasUsed: gb.GasUsed(),
Timestamp: gb.Time(),
ExtraData: gb.Extra(),
ExtraData: extraData,
BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength),
BlockHash: gb.Hash().Bytes(),
Transactions: make([][]byte, 0),

View File

@@ -14,15 +14,10 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"formatter_test.go",
"logrus_prefixed_formatter_suite_test.go",
],
srcs = ["formatter_test.go"],
deps = [
":go_default_library",
"//testing/require:go_default_library",
"@com_github_onsi_ginkgo//:go_default_library",
"@com_github_onsi_gomega//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],

View File

@@ -5,55 +5,76 @@ import (
"regexp"
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
prefixed "github.com/prysmaticlabs/prysm/v5/runtime/logging/logrus-prefixed-formatter"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/sirupsen/logrus"
)
var _ = Describe("Formatter", func() {
var formatter *prefixed.TextFormatter
var log *logrus.Logger
var output *LogOutput
type LogOutput struct {
buffer string
}
BeforeEach(func() {
output = new(LogOutput)
formatter = new(prefixed.TextFormatter)
log = logrus.New()
log.Out = output
log.Formatter = formatter
log.Level = logrus.DebugLevel
})
func (o *LogOutput) Write(p []byte) (int, error) {
o.buffer += string(p)
return len(p), nil
}
Describe("logfmt output", func() {
It("should output simple message", func() {
func (o *LogOutput) GetValue() string {
return o.buffer
}
func TestFormatter_logfmt_output(t *testing.T) {
tests := []struct {
name string
callback func(l *logrus.Logger)
expected string
}{
{
name: "should output simple message",
callback: func(l *logrus.Logger) {
l.Debug("test")
},
expected: "level=debug msg=test\n",
},
{
name: "should output message with additional field",
callback: func(l *logrus.Logger) {
l.WithFields(logrus.Fields{"animal": "walrus"}).Debug("test")
},
expected: "level=debug msg=test animal=walrus\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
output := new(LogOutput)
formatter := new(prefixed.TextFormatter)
formatter.DisableTimestamp = true
log.Debug("test")
Ω(output.GetValue()).Should(Equal("level=debug msg=test\n"))
log := logrus.New()
log.Out = output
log.Formatter = formatter
log.Level = logrus.DebugLevel
tt.callback(log)
require.Equal(t, output.GetValue(), tt.expected)
})
}
}
It("should output message with additional field", func() {
formatter.DisableTimestamp = true
log.WithFields(logrus.Fields{"animal": "walrus"}).Debug("test")
Ω(output.GetValue()).Should(Equal("level=debug msg=test animal=walrus\n"))
})
})
func TestFormatter_formatted_output(t *testing.T) {
output := new(LogOutput)
formatter := new(prefixed.TextFormatter)
formatter.DisableTimestamp = true
formatter.ForceFormatting = true
log := logrus.New()
log.Out = output
log.Formatter = formatter
log.Level = logrus.DebugLevel
Describe("Formatted output", func() {
It("should output formatted message", func() {
formatter.DisableTimestamp = true
formatter.ForceFormatting = true
log.Debug("test")
Ω(output.GetValue()).Should(Equal("DEBUG test\n"))
})
})
Describe("Theming support", func() {
})
})
log.Debug("test")
require.Equal(t, output.GetValue(), "DEBUG test\n")
}
func TestFormatter_SuppressErrorStackTraces(t *testing.T) {
formatter := new(prefixed.TextFormatter)

View File

@@ -1,26 +0,0 @@
package prefixed_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
type LogOutput struct {
buffer string
}
func (o *LogOutput) Write(p []byte) (int, error) {
o.buffer += string(p)
return len(p), nil
}
func (o *LogOutput) GetValue() string {
return o.buffer
}
func TestLogrusPrefixedFormatter(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "LogrusPrefixedFormatter Suite")
}

View File

@@ -6,10 +6,10 @@ lighthouse_archive_name = "lighthouse-%s-x86_64-unknown-linux-gnu-portable.tar.g
def e2e_deps():
http_archive(
name = "web3signer",
urls = ["https://artifacts.consensys.net/public/web3signer/raw/names/web3signer.tar.gz/versions/23.11.0/web3signer-23.11.0.tar.gz"],
sha256 = "e7643a6aa32efd859e96a82cb3ea03a294fd92c22fffeab987e5ec97500867a8",
urls = ["https://artifacts.consensys.net/public/web3signer/raw/names/web3signer.tar.gz/versions/24.12.0/web3signer-24.12.0.tar.gz"],
sha256 = "5d2eff119e065a50bd2bd727e098963d0e61a3f6525bdc12b11515d3677a84d1",
build_file = "@prysm//testing/endtoend:web3signer.BUILD",
strip_prefix = "web3signer-23.11.0",
strip_prefix = "web3signer-24.12.0",
)
http_archive(

View File

@@ -187,8 +187,8 @@ func addIfForkSet(
return evals
}
func scenarioEvals() []types.Evaluator {
return []types.Evaluator{
func scenarioEvals(cfg *params.BeaconChainConfig) []types.Evaluator {
evals := []types.Evaluator{
ev.PeersConnect,
ev.HealthzCheck,
ev.MetricsCheck,
@@ -198,18 +198,19 @@ func scenarioEvals() []types.Evaluator {
ev.ProposeVoluntaryExit,
ev.ValidatorsHaveExited,
ev.ColdStateCheckpoint,
ev.AltairForkTransition,
ev.BellatrixForkTransition,
ev.CapellaForkTransition,
ev.DenebForkTransition,
ev.FinishedSyncing,
ev.AllNodesHaveSameHead,
ev.ValidatorSyncParticipation,
}
evals = addIfForkSet(evals, cfg.AltairForkEpoch, ev.AltairForkTransition)
evals = addIfForkSet(evals, cfg.BellatrixForkEpoch, ev.BellatrixForkTransition)
evals = addIfForkSet(evals, cfg.CapellaForkEpoch, ev.CapellaForkTransition)
evals = addIfForkSet(evals, cfg.DenebForkEpoch, ev.DenebForkTransition)
return evals
}
func scenarioEvalsMulti() []types.Evaluator {
return []types.Evaluator{
func scenarioEvalsMulti(cfg *params.BeaconChainConfig) []types.Evaluator {
evals := []types.Evaluator{
ev.PeersConnect,
ev.HealthzCheck,
ev.MetricsCheck,
@@ -218,11 +219,12 @@ func scenarioEvalsMulti() []types.Evaluator {
ev.ProposeVoluntaryExit,
ev.ValidatorsHaveExited,
ev.ColdStateCheckpoint,
ev.AltairForkTransition,
ev.BellatrixForkTransition,
ev.CapellaForkTransition,
ev.DenebForkTransition,
ev.FinishedSyncing,
ev.AllNodesHaveSameHead,
}
evals = addIfForkSet(evals, cfg.AltairForkEpoch, ev.AltairForkTransition)
evals = addIfForkSet(evals, cfg.BellatrixForkEpoch, ev.BellatrixForkTransition)
evals = addIfForkSet(evals, cfg.CapellaForkEpoch, ev.CapellaForkTransition)
evals = addIfForkSet(evals, cfg.DenebForkEpoch, ev.DenebForkTransition)
return evals
}

View File

@@ -9,8 +9,10 @@ import (
)
func TestEndToEnd_MultiScenarioRun_Multiclient(t *testing.T) {
runner := e2eMainnet(t, false, true, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2EMainnetTestConfig()), types.WithEpochs(24))
runner.config.Evaluators = scenarioEvalsMulti()
cfg := types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2EMainnetTestConfig())
runner := e2eMainnet(t, false, true, cfg, types.WithEpochs(24))
// override for scenario tests
runner.config.Evaluators = scenarioEvalsMulti(cfg)
runner.config.EvalInterceptor = runner.multiScenarioMulticlient
runner.scenarioRunner()
}

View File

@@ -9,9 +9,10 @@ import (
)
func TestEndToEnd_MultiScenarioRun(t *testing.T) {
runner := e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig()), types.WithEpochs(26))
runner.config.Evaluators = scenarioEvals()
cfg := types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig())
runner := e2eMinimal(t, cfg, types.WithEpochs(26))
// override for scenario tests
runner.config.Evaluators = scenarioEvals(cfg)
runner.config.EvalInterceptor = runner.multiScenario
runner.scenarioRunner()
}
@@ -30,9 +31,10 @@ func TestEndToEnd_MinimalConfig_ValidatorRESTApi(t *testing.T) {
func TestEndToEnd_ScenarioRun_EEOffline(t *testing.T) {
t.Skip("TODO(#10242) Prysm is current unable to handle an offline e2e")
runner := e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig()))
runner.config.Evaluators = scenarioEvals()
cfg := types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig())
runner := e2eMinimal(t, cfg)
// override for scenario tests
runner.config.Evaluators = scenarioEvals(cfg)
runner.config.EvalInterceptor = runner.eeOffline
runner.scenarioRunner()
}

View File

@@ -32,6 +32,7 @@ go_library(
"//crypto/rand:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
@@ -55,6 +56,7 @@ go_test(
"//crypto/bls:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/slashings:go_default_library",
"//runtime/version:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
],

View File

@@ -15,15 +15,14 @@ import (
"github.com/prysmaticlabs/prysm/v5/crypto/rand"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/time/slots"
"github.com/sirupsen/logrus"
)
func (s *Simulator) generateAttestationsForSlot(
ctx context.Context, slot primitives.Slot,
) ([]*ethpb.IndexedAttestation, []*ethpb.AttesterSlashing, error) {
attestations := make([]*ethpb.IndexedAttestation, 0)
slashings := make([]*ethpb.AttesterSlashing, 0)
func (s *Simulator) generateAttestationsForSlot(ctx context.Context, ver int, slot primitives.Slot) ([]ethpb.IndexedAtt, []ethpb.AttSlashing, error) {
attestations := make([]ethpb.IndexedAtt, 0)
slashings := make([]ethpb.AttSlashing, 0)
currentEpoch := slots.ToEpoch(slot)
committeesPerSlot := helpers.SlotCommitteeCount(s.srvConfig.Params.NumValidators)
@@ -64,12 +63,23 @@ func (s *Simulator) generateAttestationsForSlot(
for idx := i; idx < attEndIdx; idx++ {
indices = append(indices, idx)
}
att := &ethpb.IndexedAttestation{
AttestingIndices: indices,
Data: attData,
Signature: params.BeaconConfig().EmptySignature[:],
var att ethpb.IndexedAtt
if ver >= version.Electra {
att = &ethpb.IndexedAttestationElectra{
AttestingIndices: indices,
Data: attData,
Signature: params.BeaconConfig().EmptySignature[:],
}
} else {
att = &ethpb.IndexedAttestation{
AttestingIndices: indices,
Data: attData,
Signature: params.BeaconConfig().EmptySignature[:],
}
}
beaconState, err := s.srvConfig.AttestationStateFetcher.AttestationTargetState(ctx, att.Data.Target)
beaconState, err := s.srvConfig.AttestationStateFetcher.AttestationTargetState(ctx, att.GetData().Target)
if err != nil {
return nil, nil, err
}
@@ -79,7 +89,12 @@ func (s *Simulator) generateAttestationsForSlot(
if err != nil {
return nil, nil, err
}
att.Signature = aggSig.Marshal()
if ver >= version.Electra {
att.(*ethpb.IndexedAttestationElectra).Signature = aggSig.Marshal()
} else {
att.(*ethpb.IndexedAttestation).Signature = aggSig.Marshal()
}
attestations = append(attestations, att)
if rand.NewGenerator().Float64() < s.srvConfig.Params.AttesterSlashingProbab {
@@ -88,29 +103,50 @@ func (s *Simulator) generateAttestationsForSlot(
if err != nil {
return nil, nil, err
}
slashableAtt.Signature = aggSig.Marshal()
slashedIndices = append(slashedIndices, slashableAtt.AttestingIndices...)
attDataRoot, err := att.Data.HashTreeRoot()
if ver >= version.Electra {
slashableAtt.(*ethpb.IndexedAttestationElectra).Signature = aggSig.Marshal()
} else {
slashableAtt.(*ethpb.IndexedAttestation).Signature = aggSig.Marshal()
}
slashedIndices = append(slashedIndices, slashableAtt.GetAttestingIndices()...)
attDataRoot, err := att.GetData().HashTreeRoot()
if err != nil {
return nil, nil, errors.Wrap(err, "cannot compte `att` hash tree root")
}
slashableAttDataRoot, err := slashableAtt.Data.HashTreeRoot()
slashableAttDataRoot, err := slashableAtt.GetData().HashTreeRoot()
if err != nil {
return nil, nil, errors.Wrap(err, "cannot compte `slashableAtt` hash tree root")
}
slashing := &ethpb.AttesterSlashing{
Attestation_1: att,
Attestation_2: slashableAtt,
var slashing ethpb.AttSlashing
if ver >= version.Electra {
slashing = &ethpb.AttesterSlashingElectra{
Attestation_1: att.(*ethpb.IndexedAttestationElectra),
Attestation_2: slashableAtt.(*ethpb.IndexedAttestationElectra),
}
} else {
slashing = &ethpb.AttesterSlashing{
Attestation_1: att.(*ethpb.IndexedAttestation),
Attestation_2: slashableAtt.(*ethpb.IndexedAttestation),
}
}
// Ensure the attestation with the lower data root is the first attestation.
if bytes.Compare(attDataRoot[:], slashableAttDataRoot[:]) > 0 {
slashing = &ethpb.AttesterSlashing{
Attestation_1: slashableAtt,
Attestation_2: att,
if ver >= version.Electra {
slashing = &ethpb.AttesterSlashingElectra{
Attestation_1: slashableAtt.(*ethpb.IndexedAttestationElectra),
Attestation_2: att.(*ethpb.IndexedAttestationElectra),
}
} else {
slashing = &ethpb.AttesterSlashing{
Attestation_1: slashableAtt.(*ethpb.IndexedAttestation),
Attestation_2: att.(*ethpb.IndexedAttestation),
}
}
}
@@ -131,46 +167,55 @@ func (s *Simulator) generateAttestationsForSlot(
}
func (s *Simulator) aggregateSigForAttestation(
beaconState state.ReadOnlyBeaconState, att *ethpb.IndexedAttestation,
beaconState state.ReadOnlyBeaconState, att ethpb.IndexedAtt,
) (bls.Signature, error) {
domain, err := signing.Domain(
beaconState.Fork(),
att.Data.Target.Epoch,
att.GetData().Target.Epoch,
params.BeaconConfig().DomainBeaconAttester,
beaconState.GenesisValidatorsRoot(),
)
if err != nil {
return nil, err
}
signingRoot, err := signing.ComputeSigningRoot(att.Data, domain)
signingRoot, err := signing.ComputeSigningRoot(att.GetData(), domain)
if err != nil {
return nil, err
}
sigs := make([]bls.Signature, len(att.AttestingIndices))
for i, validatorIndex := range att.AttestingIndices {
sigs := make([]bls.Signature, len(att.GetAttestingIndices()))
for i, validatorIndex := range att.GetAttestingIndices() {
privKey := s.srvConfig.PrivateKeysByValidatorIndex[primitives.ValidatorIndex(validatorIndex)]
sigs[i] = privKey.Sign(signingRoot[:])
}
return bls.AggregateSignatures(sigs), nil
}
func makeSlashableFromAtt(att *ethpb.IndexedAttestation, indices []uint64) *ethpb.IndexedAttestation {
if att.Data.Source.Epoch <= 2 {
func makeSlashableFromAtt(att ethpb.IndexedAtt, indices []uint64) ethpb.IndexedAtt {
if att.GetData().Source.Epoch <= 2 {
return makeDoubleVoteFromAtt(att, indices)
}
attData := &ethpb.AttestationData{
Slot: att.Data.Slot,
CommitteeIndex: att.Data.CommitteeIndex,
BeaconBlockRoot: att.Data.BeaconBlockRoot,
Slot: att.GetData().Slot,
CommitteeIndex: att.GetData().CommitteeIndex,
BeaconBlockRoot: att.GetData().BeaconBlockRoot,
Source: &ethpb.Checkpoint{
Epoch: att.Data.Source.Epoch - 3,
Root: att.Data.Source.Root,
Epoch: att.GetData().Source.Epoch - 3,
Root: att.GetData().Source.Root,
},
Target: &ethpb.Checkpoint{
Epoch: att.Data.Target.Epoch,
Root: att.Data.Target.Root,
Epoch: att.GetData().Target.Epoch,
Root: att.GetData().Target.Root,
},
}
if att.Version() >= version.Electra {
return &ethpb.IndexedAttestationElectra{
AttestingIndices: indices,
Data: attData,
Signature: params.BeaconConfig().EmptySignature[:],
}
}
return &ethpb.IndexedAttestation{
AttestingIndices: indices,
Data: attData,
@@ -178,20 +223,29 @@ func makeSlashableFromAtt(att *ethpb.IndexedAttestation, indices []uint64) *ethp
}
}
func makeDoubleVoteFromAtt(att *ethpb.IndexedAttestation, indices []uint64) *ethpb.IndexedAttestation {
func makeDoubleVoteFromAtt(att ethpb.IndexedAtt, indices []uint64) ethpb.IndexedAtt {
attData := &ethpb.AttestationData{
Slot: att.Data.Slot,
CommitteeIndex: att.Data.CommitteeIndex,
Slot: att.GetData().Slot,
CommitteeIndex: att.GetData().CommitteeIndex,
BeaconBlockRoot: bytesutil.PadTo([]byte("slash me"), 32),
Source: &ethpb.Checkpoint{
Epoch: att.Data.Source.Epoch,
Root: att.Data.Source.Root,
Epoch: att.GetData().Source.Epoch,
Root: att.GetData().Source.Root,
},
Target: &ethpb.Checkpoint{
Epoch: att.Data.Target.Epoch,
Root: att.Data.Target.Root,
Epoch: att.GetData().Target.Epoch,
Root: att.GetData().Target.Root,
},
}
if att.Version() >= version.Electra {
return &ethpb.IndexedAttestationElectra{
AttestingIndices: indices,
Data: attData,
Signature: params.BeaconConfig().EmptySignature[:],
}
}
return &ethpb.IndexedAttestation{
AttestingIndices: indices,
Data: attData,

View File

@@ -6,6 +6,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/slashings"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
@@ -20,14 +21,18 @@ func TestGenerateAttestationsForSlot_Slashing(t *testing.T) {
}
srv := setupService(t, simParams)
epoch3Atts, _, err := srv.generateAttestationsForSlot(ctx, params.BeaconConfig().SlotsPerEpoch*3)
require.NoError(t, err)
epoch4Atts, _, err := srv.generateAttestationsForSlot(ctx, params.BeaconConfig().SlotsPerEpoch*4)
require.NoError(t, err)
for i := 0; i < len(epoch3Atts); i += 2 {
goodAtt := epoch3Atts[i]
surroundAtt := epoch4Atts[i+1]
require.Equal(t, true, slashings.IsSurround(surroundAtt, goodAtt))
for _, v := range []int{version.Phase0, version.Electra} {
t.Run(version.String(v), func(t *testing.T) {
epoch3Atts, _, err := srv.generateAttestationsForSlot(ctx, v, params.BeaconConfig().SlotsPerEpoch*3)
require.NoError(t, err)
epoch4Atts, _, err := srv.generateAttestationsForSlot(ctx, v, params.BeaconConfig().SlotsPerEpoch*4)
require.NoError(t, err)
for i := 0; i < len(epoch3Atts); i += 2 {
goodAtt := epoch3Atts[i]
surroundAtt := epoch4Atts[i+1]
require.Equal(t, true, slashings.IsSurround(surroundAtt, goodAtt))
}
})
}
}
@@ -41,24 +46,29 @@ func TestGenerateAttestationsForSlot_CorrectIndices(t *testing.T) {
AttesterSlashingProbab: 0,
}
srv := setupService(t, simParams)
slot0Atts, _, err := srv.generateAttestationsForSlot(ctx, 0)
require.NoError(t, err)
slot1Atts, _, err := srv.generateAttestationsForSlot(ctx, 1)
require.NoError(t, err)
slot2Atts, _, err := srv.generateAttestationsForSlot(ctx, 2)
require.NoError(t, err)
var validatorIndices []uint64
for _, att := range append(slot0Atts, slot1Atts...) {
validatorIndices = append(validatorIndices, att.AttestingIndices...)
}
for _, att := range slot2Atts {
validatorIndices = append(validatorIndices, att.AttestingIndices...)
}
// Making sure indices are one after the other for attestations.
var validatorIndex uint64
for _, ii := range validatorIndices {
require.Equal(t, validatorIndex, ii)
validatorIndex++
for _, v := range []int{version.Phase0, version.Electra} {
t.Run(version.String(v), func(t *testing.T) {
slot0Atts, _, err := srv.generateAttestationsForSlot(ctx, v, 0)
require.NoError(t, err)
slot1Atts, _, err := srv.generateAttestationsForSlot(ctx, v, 1)
require.NoError(t, err)
slot2Atts, _, err := srv.generateAttestationsForSlot(ctx, v, 2)
require.NoError(t, err)
var validatorIndices []uint64
for _, att := range append(slot0Atts, slot1Atts...) {
validatorIndices = append(validatorIndices, att.GetAttestingIndices()...)
}
for _, att := range slot2Atts {
validatorIndices = append(validatorIndices, att.GetAttestingIndices()...)
}
// Making sure indices are one after the other for attestations.
var validatorIndex uint64
for _, ii := range validatorIndices {
require.Equal(t, validatorIndex, ii)
validatorIndex++
}
})
}
}

View File

@@ -19,6 +19,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/time/slots"
"github.com/sirupsen/logrus"
)
@@ -62,7 +63,7 @@ type Simulator struct {
sentAttSlashingFeed *event.Feed
sentBlockSlashingFeed *event.Feed
sentProposerSlashings map[[32]byte]*ethpb.ProposerSlashing
sentAttesterSlashings map[[32]byte]*ethpb.AttesterSlashing
sentAttesterSlashings map[[32]byte]ethpb.AttSlashing
genesisTime time.Time
}
@@ -111,7 +112,7 @@ func New(ctx context.Context, srvConfig *ServiceConfig) (*Simulator, error) {
sentAttSlashingFeed: sentAttSlashingFeed,
sentBlockSlashingFeed: sentBlockSlashingFeed,
sentProposerSlashings: make(map[[32]byte]*ethpb.ProposerSlashing),
sentAttesterSlashings: make(map[[32]byte]*ethpb.AttesterSlashing),
sentAttesterSlashings: make(map[[32]byte]ethpb.AttSlashing),
}, nil
}
@@ -206,7 +207,7 @@ func (s *Simulator) simulateBlocksAndAttestations(ctx context.Context) {
s.beaconBlocksFeed.Send(bb)
}
atts, attSlashings, err := s.generateAttestationsForSlot(ctx, slot)
atts, attSlashings, err := s.generateAttestationsForSlot(ctx, version.Phase0, slot)
if err != nil {
log.WithError(err).Fatal("Could not generate attestations for slot")
}
@@ -271,20 +272,20 @@ func (s *Simulator) verifySlashingsWereDetected(ctx context.Context) {
for slashingRoot, slashing := range s.sentAttesterSlashings {
if _, ok := detectedAttesterSlashings[slashingRoot]; !ok {
log.WithFields(logrus.Fields{
"targetEpoch": slashing.Attestation_1.Data.Target.Epoch,
"prevTargetEpoch": slashing.Attestation_2.Data.Target.Epoch,
"sourceEpoch": slashing.Attestation_1.Data.Source.Epoch,
"prevSourceEpoch": slashing.Attestation_2.Data.Source.Epoch,
"prevBeaconBlockRoot": fmt.Sprintf("%#x", slashing.Attestation_1.Data.BeaconBlockRoot),
"newBeaconBlockRoot": fmt.Sprintf("%#x", slashing.Attestation_2.Data.BeaconBlockRoot),
"targetEpoch": slashing.FirstAttestation().GetData().Target.Epoch,
"prevTargetEpoch": slashing.SecondAttestation().GetData().Target.Epoch,
"sourceEpoch": slashing.FirstAttestation().GetData().Source.Epoch,
"prevSourceEpoch": slashing.SecondAttestation().GetData().Source.Epoch,
"prevBeaconBlockRoot": fmt.Sprintf("%#x", slashing.FirstAttestation().GetData().BeaconBlockRoot),
"newBeaconBlockRoot": fmt.Sprintf("%#x", slashing.SecondAttestation().GetData().BeaconBlockRoot),
}).Errorf("Did not detect simulated attester slashing")
continue
}
log.WithFields(logrus.Fields{
"targetEpoch": slashing.Attestation_1.Data.Target.Epoch,
"prevTargetEpoch": slashing.Attestation_2.Data.Target.Epoch,
"sourceEpoch": slashing.Attestation_1.Data.Source.Epoch,
"prevSourceEpoch": slashing.Attestation_2.Data.Source.Epoch,
"targetEpoch": slashing.FirstAttestation().GetData().Target.Epoch,
"prevTargetEpoch": slashing.SecondAttestation().GetData().Target.Epoch,
"sourceEpoch": slashing.FirstAttestation().GetData().Source.Epoch,
"prevSourceEpoch": slashing.SecondAttestation().GetData().Source.Epoch,
}).Info("Correctly detected simulated attester slashing")
}
}

View File

@@ -1,6 +1,7 @@
package epoch_processing
import (
"os"
"testing"
"github.com/prysmaticlabs/prysm/v5/config/params"
@@ -13,5 +14,5 @@ func TestMain(m *testing.M) {
c.MinGenesisActiveValidatorCount = 16384
params.OverrideBeaconConfig(c)
m.Run()
os.Exit(m.Run())
}

View File

@@ -1,6 +1,7 @@
package epoch_processing
import (
"os"
"testing"
"github.com/prysmaticlabs/prysm/v5/config/params"
@@ -13,5 +14,5 @@ func TestMain(m *testing.M) {
c.MinGenesisActiveValidatorCount = 16384
params.OverrideBeaconConfig(c)
m.Run()
os.Exit(m.Run())
}

View File

@@ -322,3 +322,30 @@ func TestGenerateVoluntaryExits(t *testing.T) {
require.NoError(t, err)
require.NoError(t, coreBlock.VerifyExitAndSignature(val, beaconState, exit))
}
func Test_PostDenebPbGenericBlock_ErrorsForPlainBlock(t *testing.T) {
t.Run("Deneb block returns type error", func(t *testing.T) {
eb := NewBeaconBlockDeneb()
b, err := blocks.NewSignedBeaconBlock(eb)
require.NoError(t, err)
_, err = b.PbGenericBlock()
require.ErrorContains(t, "PbGenericBlock() only supports block content type but got", err)
})
t.Run("Electra block returns type error", func(t *testing.T) {
eb := NewBeaconBlockElectra()
b, err := blocks.NewSignedBeaconBlock(eb)
require.NoError(t, err)
_, err = b.PbGenericBlock()
require.ErrorContains(t, "PbGenericBlock() only supports block content type but got", err)
})
t.Run("Fulu block returns type error", func(t *testing.T) {
eb := NewBeaconBlockFulu()
b, err := blocks.NewSignedBeaconBlock(eb)
require.NoError(t, err)
_, err = b.PbGenericBlock()
require.ErrorContains(t, "PbGenericBlock() only supports block content type but got", err)
})
}

View File

@@ -2,6 +2,7 @@ package slots
import (
"io"
"os"
"testing"
"github.com/sirupsen/logrus"
@@ -11,5 +12,5 @@ func TestMain(m *testing.M) {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(io.Discard)
m.Run()
os.Exit(m.Run())
}

Some files were not shown because too many files have changed in this diff Show More