mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
30 Commits
changelog-
...
bazel_go_1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
721eb0b404 | ||
|
|
43b233a4d5 | ||
|
|
74eb56020a | ||
|
|
13d2594cea | ||
|
|
d503b8014c | ||
|
|
a8ed5c2aa6 | ||
|
|
d0aace409a | ||
|
|
955321286a | ||
|
|
48a879930e | ||
|
|
605cad0a8c | ||
|
|
78722239da | ||
|
|
3ffef024c7 | ||
|
|
a1eef44492 | ||
|
|
2845ab9365 | ||
|
|
4f43c15ebb | ||
|
|
e473d7cc4d | ||
|
|
794a05af26 | ||
|
|
15df13c7e6 | ||
|
|
b76f7fed2f | ||
|
|
e263687ea5 | ||
|
|
0b16c79c35 | ||
|
|
dc002c2806 | ||
|
|
e7e48dcaf9 | ||
|
|
8f43f6cc84 | ||
|
|
e07341e1d5 | ||
|
|
ef293e52f8 | ||
|
|
72cc63a6a3 | ||
|
|
34ff4c3ea9 | ||
|
|
e8c968326a | ||
|
|
2000ef457b |
@@ -1 +1 @@
|
||||
7.1.0
|
||||
7.4.1
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -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.
|
||||
|
||||
47
.github/workflows/changelog.yml
vendored
47
.github/workflows/changelog.yml
vendored
@@ -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
|
||||
|
||||
64
CHANGELOG.md
64
CHANGELOG.md
@@ -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.
|
||||
|
||||
@@ -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
1689
MODULE.bazel.lock
generated
File diff suppressed because it is too large
Load Diff
35
WORKSPACE
35
WORKSPACE
@@ -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",
|
||||
)
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
3
beacon-chain/cache/cache_test.go
vendored
3
beacon-chain/cache/cache_test.go
vendored
@@ -1,9 +1,10 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
m.Run()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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 := ðpb.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 {
|
||||
|
||||
@@ -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, ðpb.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)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -910,13 +910,15 @@ func TestProposerIndexFromCheckpoint(t *testing.T) {
|
||||
func TestHasETH1WithdrawalCredentials(t *testing.T) {
|
||||
creds := []byte{0xFA, 0xCC}
|
||||
v := ðpb.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 = ðpb.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 = ðpb.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",
|
||||
ðpb.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",
|
||||
ðpb.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())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -517,6 +517,19 @@ func (s *Store) unmarshalState(_ context.Context, enc []byte, validatorEntries [
|
||||
}
|
||||
|
||||
switch {
|
||||
case hasFuluKey(enc):
|
||||
protoState := ðpb.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 := ðpb.BeaconStateElectra{}
|
||||
if err := protoState.UnmarshalSSZ(enc[len(electraKey):]); err != nil {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -123,7 +123,7 @@ func InitializeDataMaps() {
|
||||
return ðpb.SingleAttestation{}, nil
|
||||
},
|
||||
bytesutil.ToBytes4(params.BeaconConfig().FuluForkVersion): func() (ethpb.Att, error) {
|
||||
return ðpb.AttestationElectra{}, nil
|
||||
return ðpb.SingleAttestation{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -461,7 +461,7 @@ func TestStreamEvents_OperationsEvents(t *testing.T) {
|
||||
defer testSync.cleanup()
|
||||
|
||||
st := tc.getState()
|
||||
v := ð.Validator{ExitEpoch: math.MaxUint64, EffectiveBalance: params.BeaconConfig().MinActivationBalance}
|
||||
v := ð.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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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{
|
||||
ð.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
ð.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||
Data: util.HydrateAttestationData(ð.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{
|
||||
ð.AttestationElectra{
|
||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
CommitteeBits: cb,
|
||||
},
|
||||
ð.AttestationElectra{
|
||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
CommitteeBits: cb,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
atts = []eth.Att{
|
||||
ð.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
ð.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
}
|
||||
}
|
||||
require.NoError(t, sbb.SetAttestations(atts))
|
||||
|
||||
attData1 := util.HydrateAttestationData(ð.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root1"), 32)})
|
||||
attData2 := util.HydrateAttestationData(ð.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{
|
||||
ð.AttesterSlashing{
|
||||
|
||||
var attSlashing eth.AttSlashing
|
||||
if ver >= version.Electra {
|
||||
attSlashing = ð.AttesterSlashingElectra{
|
||||
Attestation_1: ð.IndexedAttestationElectra{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: attData1,
|
||||
Signature: secretKeys[0].Sign(sigRoot1[:]).Marshal(),
|
||||
},
|
||||
Attestation_2: ð.IndexedAttestationElectra{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: attData2,
|
||||
Signature: secretKeys[0].Sign(sigRoot2[:]).Marshal(),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
attSlashing = ð.AttesterSlashing{
|
||||
Attestation_1: ð.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 := ð.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(ð.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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)",
|
||||
ðpb.IndexedAttestationElectra{},
|
||||
existingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"incoming attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestationElectra{},
|
||||
incomingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
slashing := ðpb.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 = ðpb.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)",
|
||||
ðpb.IndexedAttestationElectra{},
|
||||
existingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"incoming attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestationElectra{},
|
||||
incomingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
slashing := ðpb.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 = ðpb.AttesterSlashingElectra{
|
||||
Attestation_1: incoming,
|
||||
Attestation_2: existing,
|
||||
}
|
||||
}
|
||||
|
||||
return slashing, nil
|
||||
}
|
||||
|
||||
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)",
|
||||
ðpb.IndexedAttestation{},
|
||||
existingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"incoming attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
incomingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
var slashing ethpb.AttSlashing
|
||||
|
||||
slashing := ðpb.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)",
|
||||
ðpb.IndexedAttestationElectra{},
|
||||
existingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestationElectra)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"incoming attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestationElectra{},
|
||||
incomingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
slashing = ðpb.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 = ðpb.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)",
|
||||
ðpb.IndexedAttestation{},
|
||||
existingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"incoming attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
incomingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
slashing = ðpb.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 = ðpb.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)",
|
||||
ðpb.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)",
|
||||
ðpb.IndexedAttestation{},
|
||||
wrapper_2.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
var slashing ethpb.AttSlashing
|
||||
|
||||
slashing := ðpb.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)",
|
||||
ðpb.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)",
|
||||
ðpb.IndexedAttestationElectra{},
|
||||
wrapper_2.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
slashing = ðpb.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 = ðpb.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)",
|
||||
ðpb.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)",
|
||||
ðpb.IndexedAttestation{},
|
||||
wrapper_2.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
slashing = ðpb.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 = ðpb.AttesterSlashing{
|
||||
Attestation_1: att_2,
|
||||
Attestation_2: att_1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 = ðpb.IndexedAttestationElectra{
|
||||
AttestingIndices: w1.IndexedAttestation.GetAttestingIndices(),
|
||||
Data: w1.IndexedAttestation.GetData(),
|
||||
Signature: w1.IndexedAttestation.GetSignature(),
|
||||
}
|
||||
return
|
||||
}
|
||||
w2.IndexedAttestation = ðpb.IndexedAttestationElectra{
|
||||
AttestingIndices: w2.IndexedAttestation.GetAttestingIndices(),
|
||||
Data: w2.IndexedAttestation.GetData(),
|
||||
Signature: w2.IndexedAttestation.GetSignature(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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: ðpb.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: ðpb.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: ðpb.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),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -292,7 +292,7 @@ func TestExtractDataType(t *testing.T) {
|
||||
return wsb
|
||||
}(),
|
||||
wantMd: wrapper.WrappedMetadataV1(ðpb.MetaDataV1{}),
|
||||
wantAtt: ðpb.AttestationElectra{},
|
||||
wantAtt: ðpb.SingleAttestation{},
|
||||
wantAggregate: ðpb.SignedAggregateAttestationAndProofElectra{},
|
||||
wantErr: false,
|
||||
},
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
2
changelog/hidewrong_use_time.DateTime.md
Normal file
2
changelog/hidewrong_use_time.DateTime.md
Normal file
@@ -0,0 +1,2 @@
|
||||
### Changed
|
||||
- Refactor `2006-01-02 15:04:05` to `time.DateTime`
|
||||
3
changelog/james-prysm_e2e-scenario-fork-fix.md
Normal file
3
changelog/james-prysm_e2e-scenario-fork-fix.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- added conditional evaluators to fix scenario e2e tests
|
||||
3
changelog/james-prysm_handle-pbgeneric-error.md
Normal file
3
changelog/james-prysm_handle-pbgeneric-error.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- fix panic with type cast on pbgenericblock()
|
||||
3
changelog/james-prysm_remote-signer-electra.md
Normal file
3
changelog/james-prysm_remote-signer-electra.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- Remote signer electra fork support.
|
||||
55
changelog/kasey_changelog-tool.md
Normal file
55
changelog/kasey_changelog-tool.md
Normal 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)
|
||||
13
changelog/kasey_stabilize-unclog.md
Normal file
13
changelog/kasey_stabilize-unclog.md
Normal 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.
|
||||
2
changelog/kasey_unclog-v0-1-3.md
Normal file
2
changelog/kasey_unclog-v0-1-3.md
Normal file
@@ -0,0 +1,2 @@
|
||||
### Changed
|
||||
- Version pinning unclog after making some ux improvements.
|
||||
3
changelog/manu_blob_subnets_node_filter.md
Normal file
3
changelog/manu_blob_subnets_node_filter.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- `nodeFilter`: Implement `filterPeerForBlobSubnet` to avoid error logs.
|
||||
3
changelog/manu_fulu_fork.md
Normal file
3
changelog/manu_fulu_fork.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- `UpgradeToFulu`: Respect the specification.
|
||||
3
changelog/manu_fulu_to_blinded.md
Normal file
3
changelog/manu_fulu_to_blinded.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- `ToBlinded`: Use Fulu struct for Fulu (instead of Electra)
|
||||
2
changelog/potuz_credentials_as_methods.md
Normal file
2
changelog/potuz_credentials_as_methods.md
Normal file
@@ -0,0 +1,2 @@
|
||||
### Changed
|
||||
- Remove helpers to check for execution/compounding withdrawal credentials and expose them as methods.
|
||||
3
changelog/potuz_remove_copy_beaconblock.md
Normal file
3
changelog/potuz_remove_copy_beaconblock.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Removed
|
||||
|
||||
- Remove `Copy()` from the `ReadOnlyBeaconBlock` interface.
|
||||
3
changelog/pvl_dns_test_fix.md
Normal file
3
changelog/pvl_dns_test_fix.md
Normal 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)
|
||||
3
changelog/radek_eip-7549-slasher-pt1.md
Normal file
3
changelog/radek_eip-7549-slasher-pt1.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- Update slasher service to Electra
|
||||
3
changelog/radek_fulu-object-mapping.md
Normal file
3
changelog/radek_fulu-object-mapping.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- Use `SingleAttestation` for Fulu in p2p attestation map.
|
||||
3
changelog/radek_proto_test-electra.md
Normal file
3
changelog/radek_proto_test-electra.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- Update `proto_test.go` to Electra.
|
||||
3
changelog/radek_rewards-electra.md
Normal file
3
changelog/radek_rewards-electra.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- Add Electra test case to rewards API.
|
||||
3
changelog/syjn99_change-example-ip-address.md
Normal file
3
changelog/syjn99_change-example-ip-address.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- Replace exampleIP to `96.7.129.13`
|
||||
3
changelog/syjn99_clean-upgrade-tests.md
Normal file
3
changelog/syjn99_clean-upgrade-tests.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Removed
|
||||
|
||||
- Clean `TestCanUpgrade*` tests
|
||||
3
changelog/tt_fix_generate_genesis.md
Normal file
3
changelog/tt_fix_generate_genesis.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- Prysmctl generate genesis state: fix truncation of ExtraData to 32 bytes to satisfy SSZ marshaling
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -124,8 +124,12 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
|
||||
Block: ð.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 ð.GenericSignedBeaconBlock{
|
||||
Block: ð.GenericSignedBeaconBlock_Deneb{Deneb: pb.(*eth.SignedBeaconBlockContentsDeneb)},
|
||||
Block: ð.GenericSignedBeaconBlock_Deneb{Deneb: bc},
|
||||
}, nil
|
||||
case version.Electra:
|
||||
if b.IsBlinded() {
|
||||
@@ -133,8 +137,12 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
|
||||
Block: ð.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 ð.GenericSignedBeaconBlock{
|
||||
Block: ð.GenericSignedBeaconBlock_Electra{Electra: pb.(*eth.SignedBeaconBlockContentsElectra)},
|
||||
Block: ð.GenericSignedBeaconBlock_Electra{Electra: bc},
|
||||
}, nil
|
||||
case version.Fulu:
|
||||
if b.IsBlinded() {
|
||||
@@ -142,8 +150,12 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
|
||||
Block: ð.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 ð.GenericSignedBeaconBlock{
|
||||
Block: ð.GenericSignedBeaconBlock_Fulu{Fulu: pb.(*eth.SignedBeaconBlockContentsFulu)},
|
||||
Block: ð.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(
|
||||
ð.SignedBlindedBeaconBlockFulu{
|
||||
Message: ð.BlindedBeaconBlockFulu{
|
||||
Slot: b.block.slot,
|
||||
ProposerIndex: b.block.proposerIndex,
|
||||
ParentRoot: b.block.parentRoot[:],
|
||||
StateRoot: b.block.stateRoot[:],
|
||||
Body: ð.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(
|
||||
ð.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(
|
||||
ð.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(
|
||||
ð.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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 := ð.SignedBeaconBlockElectra{
|
||||
Block: ð.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 := ð.SignedBlindedBeaconBlockElectra{
|
||||
Message: ð.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 := ð.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 := ð.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 := ð.SignedBeaconBlockElectra{
|
||||
Block: ð.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 := ð.SignedBlindedBeaconBlockElectra{
|
||||
Message: ð.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 := ð.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 := ð.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 := ð.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 ð.BeaconBlockBody{
|
||||
@@ -1244,6 +1511,52 @@ func bodyPbBlindedDeneb() *eth.BlindedBeaconBlockBodyDeneb {
|
||||
}
|
||||
}
|
||||
|
||||
func bodyPbElectra() *eth.BeaconBlockBodyElectra {
|
||||
f := getFields()
|
||||
return ð.BeaconBlockBodyElectra{
|
||||
RandaoReveal: f.sig[:],
|
||||
Eth1Data: ð.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 ð.BlindedBeaconBlockBodyElectra{
|
||||
RandaoReveal: f.sig[:],
|
||||
Eth1Data: ð.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: ð.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: ð.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] = ð.Attestation{}
|
||||
atts[i].Signature = sig[:]
|
||||
atts[i].AggregationBits = bitfield.NewBitlist(1)
|
||||
atts[i].AggregationBits = attBits
|
||||
atts[i].Data = ð.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] = ð.AttestationElectra{}
|
||||
attsElectra[i].Signature = sig[:]
|
||||
attsElectra[i].AggregationBits = attBits
|
||||
attsElectra[i].CommitteeBits = committeeBits
|
||||
attsElectra[i].Data = ð.AttestationData{
|
||||
Slot: 128,
|
||||
CommitteeIndex: 128,
|
||||
BeaconBlockRoot: root[:],
|
||||
Source: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: root[:],
|
||||
},
|
||||
Target: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: root[:],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
proposerSlashing := ð.ProposerSlashing{
|
||||
Header_1: ð.SignedBeaconBlockHeader{
|
||||
Header: ð.BeaconBlockHeader{
|
||||
@@ -1529,6 +1918,42 @@ func getFields() fields {
|
||||
Signature: sig[:],
|
||||
},
|
||||
}
|
||||
attesterSlashingElectra := ð.AttesterSlashingElectra{
|
||||
Attestation_1: ð.IndexedAttestationElectra{
|
||||
AttestingIndices: []uint64{1, 2, 8},
|
||||
Data: ð.AttestationData{
|
||||
Slot: 128,
|
||||
CommitteeIndex: 128,
|
||||
BeaconBlockRoot: root[:],
|
||||
Source: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: root[:],
|
||||
},
|
||||
Target: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: root[:],
|
||||
},
|
||||
},
|
||||
Signature: sig[:],
|
||||
},
|
||||
Attestation_2: ð.IndexedAttestationElectra{
|
||||
AttestingIndices: []uint64{1, 2, 8},
|
||||
Data: ð.AttestationData{
|
||||
Slot: 128,
|
||||
CommitteeIndex: 128,
|
||||
BeaconBlockRoot: root[:],
|
||||
Source: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: root[:],
|
||||
},
|
||||
Target: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: root[:],
|
||||
},
|
||||
},
|
||||
Signature: sig[:],
|
||||
},
|
||||
}
|
||||
voluntaryExit := ð.SignedVoluntaryExit{
|
||||
Exit: ð.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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
36
deps.bzl
36
deps.bzl
@@ -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
25
go.mod
@@ -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
38
go.sum
@@ -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=
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
|
||||
@@ -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 := ðpb.IndexedAttestation{
|
||||
AttestingIndices: indices,
|
||||
Data: attData,
|
||||
Signature: params.BeaconConfig().EmptySignature[:],
|
||||
|
||||
var att ethpb.IndexedAtt
|
||||
if ver >= version.Electra {
|
||||
att = ðpb.IndexedAttestationElectra{
|
||||
AttestingIndices: indices,
|
||||
Data: attData,
|
||||
Signature: params.BeaconConfig().EmptySignature[:],
|
||||
}
|
||||
} else {
|
||||
att = ðpb.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 := ðpb.AttesterSlashing{
|
||||
Attestation_1: att,
|
||||
Attestation_2: slashableAtt,
|
||||
var slashing ethpb.AttSlashing
|
||||
if ver >= version.Electra {
|
||||
slashing = ðpb.AttesterSlashingElectra{
|
||||
Attestation_1: att.(*ethpb.IndexedAttestationElectra),
|
||||
Attestation_2: slashableAtt.(*ethpb.IndexedAttestationElectra),
|
||||
}
|
||||
} else {
|
||||
slashing = ðpb.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 = ðpb.AttesterSlashing{
|
||||
Attestation_1: slashableAtt,
|
||||
Attestation_2: att,
|
||||
if ver >= version.Electra {
|
||||
slashing = ðpb.AttesterSlashingElectra{
|
||||
Attestation_1: slashableAtt.(*ethpb.IndexedAttestationElectra),
|
||||
Attestation_2: att.(*ethpb.IndexedAttestationElectra),
|
||||
}
|
||||
} else {
|
||||
slashing = ðpb.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 := ðpb.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: ðpb.Checkpoint{
|
||||
Epoch: att.Data.Source.Epoch - 3,
|
||||
Root: att.Data.Source.Root,
|
||||
Epoch: att.GetData().Source.Epoch - 3,
|
||||
Root: att.GetData().Source.Root,
|
||||
},
|
||||
Target: ðpb.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 ðpb.IndexedAttestationElectra{
|
||||
AttestingIndices: indices,
|
||||
Data: attData,
|
||||
Signature: params.BeaconConfig().EmptySignature[:],
|
||||
}
|
||||
}
|
||||
|
||||
return ðpb.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 := ðpb.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: ðpb.Checkpoint{
|
||||
Epoch: att.Data.Source.Epoch,
|
||||
Root: att.Data.Source.Root,
|
||||
Epoch: att.GetData().Source.Epoch,
|
||||
Root: att.GetData().Source.Root,
|
||||
},
|
||||
Target: ðpb.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 ðpb.IndexedAttestationElectra{
|
||||
AttestingIndices: indices,
|
||||
Data: attData,
|
||||
Signature: params.BeaconConfig().EmptySignature[:],
|
||||
}
|
||||
}
|
||||
|
||||
return ðpb.IndexedAttestation{
|
||||
AttestingIndices: indices,
|
||||
Data: attData,
|
||||
|
||||
@@ -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++
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user