mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 13:58:09 -05:00
Compare commits
15 Commits
peerDAS-cK
...
bazel_go_1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
721eb0b404 | ||
|
|
43b233a4d5 | ||
|
|
74eb56020a | ||
|
|
13d2594cea | ||
|
|
d503b8014c | ||
|
|
a8ed5c2aa6 | ||
|
|
d0aace409a | ||
|
|
955321286a | ||
|
|
48a879930e | ||
|
|
605cad0a8c | ||
|
|
78722239da | ||
|
|
3ffef024c7 | ||
|
|
a1eef44492 | ||
|
|
2845ab9365 | ||
|
|
4f43c15ebb |
@@ -1 +1 @@
|
||||
7.1.0
|
||||
7.4.1
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
@@ -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 val.HasCompoundingWithdrawalCredentials() {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ func TestStaticPeering_PeersAreAdded(t *testing.T) {
|
||||
|
||||
func TestHostIsResolved(t *testing.T) {
|
||||
// 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.
|
||||
// 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"
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
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/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_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.
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -1,23 +1,9 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["analyzer.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/tools/analyzers/errcheck",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@org_golang_x_tools//go/analysis:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/inspect:go_default_library",
|
||||
"@org_golang_x_tools//go/ast/inspector:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["embedded_walker_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
],
|
||||
deps = ["@com_github_kisielk_errcheck//errcheck:go_default_library"],
|
||||
)
|
||||
|
||||
@@ -3,443 +3,7 @@
|
||||
package errcheck
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||
"golang.org/x/tools/go/ast/inspector"
|
||||
analyzer "github.com/kisielk/errcheck/errcheck"
|
||||
)
|
||||
|
||||
// Doc explaining the tool.
|
||||
const Doc = "This tool enforces all errors must be handled and that type assertions test that " +
|
||||
"the type implements the given interface to prevent runtime panics."
|
||||
|
||||
// Analyzer runs static analysis.
|
||||
var Analyzer = &analysis.Analyzer{
|
||||
Name: "errcheck",
|
||||
Doc: Doc,
|
||||
Requires: []*analysis.Analyzer{inspect.Analyzer},
|
||||
Run: run,
|
||||
}
|
||||
|
||||
var exclusions = make(map[string]bool)
|
||||
|
||||
func init() {
|
||||
for _, exc := range [...]string{
|
||||
// bytes
|
||||
"(*bytes.Buffer).Write",
|
||||
"(*bytes.Buffer).WriteByte",
|
||||
"(*bytes.Buffer).WriteRune",
|
||||
"(*bytes.Buffer).WriteString",
|
||||
|
||||
// fmt
|
||||
"fmt.Errorf",
|
||||
"fmt.Print",
|
||||
"fmt.Printf",
|
||||
"fmt.Println",
|
||||
"fmt.Fprint(*bytes.Buffer)",
|
||||
"fmt.Fprintf(*bytes.Buffer)",
|
||||
"fmt.Fprintln(*bytes.Buffer)",
|
||||
"fmt.Fprint(*strings.Builder)",
|
||||
"fmt.Fprintf(*strings.Builder)",
|
||||
"fmt.Fprintln(*strings.Builder)",
|
||||
"fmt.Fprint(os.Stderr)",
|
||||
"fmt.Fprintf(os.Stderr)",
|
||||
"fmt.Fprintln(os.Stderr)",
|
||||
|
||||
// math/rand
|
||||
"math/rand.Read",
|
||||
"(*math/rand.Rand).Read",
|
||||
|
||||
// hash
|
||||
"(hash.Hash).Write",
|
||||
} {
|
||||
exclusions[exc] = true
|
||||
}
|
||||
}
|
||||
|
||||
func run(pass *analysis.Pass) (interface{}, error) {
|
||||
inspection, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
|
||||
if !ok {
|
||||
return nil, errors.New("analyzer is not type *inspector.Inspector")
|
||||
}
|
||||
|
||||
nodeFilter := []ast.Node{
|
||||
(*ast.CallExpr)(nil),
|
||||
(*ast.ExprStmt)(nil),
|
||||
(*ast.GoStmt)(nil),
|
||||
(*ast.DeferStmt)(nil),
|
||||
(*ast.AssignStmt)(nil),
|
||||
}
|
||||
|
||||
inspection.Preorder(nodeFilter, func(node ast.Node) {
|
||||
switch stmt := node.(type) {
|
||||
case *ast.ExprStmt:
|
||||
if call, ok := stmt.X.(*ast.CallExpr); ok {
|
||||
if !ignoreCall(pass, call) && callReturnsError(pass, call) {
|
||||
reportUnhandledError(pass, call.Lparen, call)
|
||||
}
|
||||
}
|
||||
case *ast.GoStmt:
|
||||
if !ignoreCall(pass, stmt.Call) && callReturnsError(pass, stmt.Call) {
|
||||
reportUnhandledError(pass, stmt.Call.Lparen, stmt.Call)
|
||||
}
|
||||
case *ast.DeferStmt:
|
||||
if !ignoreCall(pass, stmt.Call) && callReturnsError(pass, stmt.Call) {
|
||||
reportUnhandledError(pass, stmt.Call.Lparen, stmt.Call)
|
||||
}
|
||||
case *ast.AssignStmt:
|
||||
if len(stmt.Rhs) == 1 {
|
||||
// single value on rhs; check against lhs identifiers
|
||||
if call, ok := stmt.Rhs[0].(*ast.CallExpr); ok {
|
||||
if ignoreCall(pass, call) {
|
||||
break
|
||||
}
|
||||
isError := errorsByArg(pass, call)
|
||||
for i := 0; i < len(stmt.Lhs); i++ {
|
||||
if id, ok := stmt.Lhs[i].(*ast.Ident); ok {
|
||||
// We shortcut calls to recover() because errorsByArg can't
|
||||
// check its return types for errors since it returns interface{}.
|
||||
if id.Name == "_" && (isRecover(pass, call) || isError[i]) {
|
||||
reportUnhandledError(pass, id.NamePos, call)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if assert, ok := stmt.Rhs[0].(*ast.TypeAssertExpr); ok {
|
||||
if assert.Type == nil {
|
||||
// type switch
|
||||
break
|
||||
}
|
||||
if len(stmt.Lhs) < 2 {
|
||||
// assertion result not read
|
||||
reportUnhandledTypeAssertion(pass, stmt.Rhs[0].Pos())
|
||||
} else if id, ok := stmt.Lhs[1].(*ast.Ident); ok && id.Name == "_" {
|
||||
// assertion result ignored
|
||||
reportUnhandledTypeAssertion(pass, id.NamePos)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// multiple value on rhs; in this case a call can't return
|
||||
// multiple values. Assume len(stmt.Lhs) == len(stmt.Rhs)
|
||||
for i := 0; i < len(stmt.Lhs); i++ {
|
||||
if id, ok := stmt.Lhs[i].(*ast.Ident); ok {
|
||||
if call, ok := stmt.Rhs[i].(*ast.CallExpr); ok {
|
||||
if ignoreCall(pass, call) {
|
||||
continue
|
||||
}
|
||||
if id.Name == "_" && callReturnsError(pass, call) {
|
||||
reportUnhandledError(pass, id.NamePos, call)
|
||||
}
|
||||
} else if assert, ok := stmt.Rhs[i].(*ast.TypeAssertExpr); ok {
|
||||
if assert.Type == nil {
|
||||
// Shouldn't happen anyway, no multi assignment in type switches
|
||||
continue
|
||||
}
|
||||
reportUnhandledError(pass, id.NamePos, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
}
|
||||
})
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func reportUnhandledError(pass *analysis.Pass, pos token.Pos, call *ast.CallExpr) {
|
||||
pass.Reportf(pos, "Unhandled error for function call %s", fullName(pass, call))
|
||||
}
|
||||
|
||||
func reportUnhandledTypeAssertion(pass *analysis.Pass, pos token.Pos) {
|
||||
pass.Reportf(pos, "Unhandled type assertion check. You must test whether or not an "+
|
||||
"interface implements the asserted type.")
|
||||
}
|
||||
|
||||
func fullName(pass *analysis.Pass, call *ast.CallExpr) string {
|
||||
_, fn, ok := selectorAndFunc(pass, call)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return fn.FullName()
|
||||
}
|
||||
|
||||
// selectorAndFunc tries to get the selector and function from call expression.
|
||||
// For example, given the call expression representing "a.b()", the selector
|
||||
// is "a.b" and the function is "b" itself.
|
||||
//
|
||||
// The final return value will be true if it is able to do extract a selector
|
||||
// from the call and look up the function object it refers to.
|
||||
//
|
||||
// If the call does not include a selector (like if it is a plain "f()" function call)
|
||||
// then the final return value will be false.
|
||||
func selectorAndFunc(pass *analysis.Pass, call *ast.CallExpr) (*ast.SelectorExpr, *types.Func, bool) {
|
||||
if call == nil || call.Fun == nil {
|
||||
return nil, nil, false
|
||||
}
|
||||
sel, ok := call.Fun.(*ast.SelectorExpr)
|
||||
if !ok {
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
fn, ok := pass.TypesInfo.ObjectOf(sel.Sel).(*types.Func)
|
||||
if !ok {
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
return sel, fn, true
|
||||
|
||||
}
|
||||
|
||||
func ignoreCall(pass *analysis.Pass, call *ast.CallExpr) bool {
|
||||
for _, name := range namesForExcludeCheck(pass, call) {
|
||||
if exclusions[name] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface)
|
||||
|
||||
func isErrorType(t types.Type) bool {
|
||||
return types.Implements(t, errorType)
|
||||
}
|
||||
|
||||
func callReturnsError(pass *analysis.Pass, call *ast.CallExpr) bool {
|
||||
if isRecover(pass, call) {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, isError := range errorsByArg(pass, call) {
|
||||
if isError {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// errorsByArg returns a slice s such that
|
||||
// len(s) == number of return types of call
|
||||
// s[i] == true iff return type at position i from left is an error type
|
||||
func errorsByArg(pass *analysis.Pass, call *ast.CallExpr) []bool {
|
||||
switch t := pass.TypesInfo.Types[call].Type.(type) {
|
||||
case *types.Named:
|
||||
// Single return
|
||||
return []bool{isErrorType(t)}
|
||||
case *types.Pointer:
|
||||
// Single return via pointer
|
||||
return []bool{isErrorType(t)}
|
||||
case *types.Tuple:
|
||||
// Multiple returns
|
||||
s := make([]bool, t.Len())
|
||||
for i := 0; i < t.Len(); i++ {
|
||||
switch et := t.At(i).Type().(type) {
|
||||
case *types.Named:
|
||||
// Single return
|
||||
s[i] = isErrorType(et)
|
||||
case *types.Pointer:
|
||||
// Single return via pointer
|
||||
s[i] = isErrorType(et)
|
||||
default:
|
||||
s[i] = false
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
return []bool{false}
|
||||
}
|
||||
|
||||
func isRecover(pass *analysis.Pass, call *ast.CallExpr) bool {
|
||||
if fun, ok := call.Fun.(*ast.Ident); ok {
|
||||
if _, ok := pass.TypesInfo.Uses[fun].(*types.Builtin); ok {
|
||||
return fun.Name == "recover"
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func namesForExcludeCheck(pass *analysis.Pass, call *ast.CallExpr) []string {
|
||||
sel, fn, ok := selectorAndFunc(pass, call)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
name := fullName(pass, call)
|
||||
if name == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// This will be missing for functions without a receiver (like fmt.Printf),
|
||||
// so just fall back to the function's fullName in that case.
|
||||
selection, ok := pass.TypesInfo.Selections[sel]
|
||||
if !ok {
|
||||
return []string{name}
|
||||
}
|
||||
|
||||
// This will return with ok false if the function isn't defined
|
||||
// on an interface, so just fall back to the fullName.
|
||||
ts, ok := walkThroughEmbeddedInterfaces(selection)
|
||||
if !ok {
|
||||
return []string{name}
|
||||
}
|
||||
|
||||
result := make([]string, len(ts))
|
||||
for i, t := range ts {
|
||||
// Like in fullName, vendored packages will have /vendor/ in their name,
|
||||
// thus not matching vendored standard library packages. If we
|
||||
// want to support vendored stdlib packages, we need to implement
|
||||
// additional logic here.
|
||||
result[i] = fmt.Sprintf("(%s).%s", t.String(), fn.Name())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// walkThroughEmbeddedInterfaces returns a slice of Interfaces that
|
||||
// we need to walk through in order to reach the actual definition,
|
||||
// in an Interface, of the method selected by the given selection.
|
||||
//
|
||||
// false will be returned in the second return value if:
|
||||
// - the right side of the selection is not a function
|
||||
// - the actual definition of the function is not in an Interface
|
||||
//
|
||||
// The returned slice will contain all the interface types that need
|
||||
// to be walked through to reach the actual definition.
|
||||
//
|
||||
// For example, say we have:
|
||||
//
|
||||
// type Inner interface {Method()}
|
||||
// type Middle interface {Inner}
|
||||
// type Outer interface {Middle}
|
||||
// type T struct {Outer}
|
||||
// type U struct {T}
|
||||
// type V struct {U}
|
||||
//
|
||||
// And then the selector:
|
||||
//
|
||||
// V.Method
|
||||
//
|
||||
// We'll return [Outer, Middle, Inner] by first walking through the embedded structs
|
||||
// until we reach the Outer interface, then descending through the embedded interfaces
|
||||
// until we find the one that actually explicitly defines Method.
|
||||
func walkThroughEmbeddedInterfaces(sel *types.Selection) ([]types.Type, bool) {
|
||||
fn, ok := sel.Obj().(*types.Func)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Start off at the receiver.
|
||||
currentT := sel.Recv()
|
||||
|
||||
// First, we can walk through any Struct fields provided
|
||||
// by the selection Index() method. We ignore the last
|
||||
// index because it would give the method itself.
|
||||
indexes := sel.Index()
|
||||
for _, fieldIndex := range indexes[:len(indexes)-1] {
|
||||
currentT = typeAtFieldIndex(currentT, fieldIndex)
|
||||
}
|
||||
|
||||
// Now currentT is either a type implementing the actual function,
|
||||
// an Invalid type (if the receiver is a package), or an interface.
|
||||
//
|
||||
// If it's not an Interface, then we're done, as this function
|
||||
// only cares about Interface-defined functions.
|
||||
//
|
||||
// If it is an Interface, we potentially need to continue digging until
|
||||
// we find the Interface that actually explicitly defines the function.
|
||||
interfaceT, ok := maybeUnname(currentT).(*types.Interface)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// The first interface we pass through is this one we've found. We return the possibly
|
||||
// wrapping types.Named because it is more useful to work with for callers.
|
||||
result := []types.Type{currentT}
|
||||
|
||||
// If this interface itself explicitly defines the given method
|
||||
// then we're done digging.
|
||||
for !explicitlyDefinesMethod(interfaceT, fn) {
|
||||
// Otherwise, we find which of the embedded interfaces _does_
|
||||
// define the method, add it to our list, and loop.
|
||||
namedInterfaceT, ok := embeddedInterfaceDefiningMethod(interfaceT, fn)
|
||||
if !ok {
|
||||
// This should be impossible as long as we type-checked: either the
|
||||
// interface or one of its embedded ones must implement the method...
|
||||
panic(fmt.Sprintf("either %v or one of its embedded interfaces must implement %v", currentT, fn))
|
||||
}
|
||||
result = append(result, namedInterfaceT)
|
||||
interfaceT, ok = namedInterfaceT.Underlying().(*types.Interface)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("either %v or one of its embedded interfaces must implement %v", currentT, fn))
|
||||
}
|
||||
}
|
||||
|
||||
return result, true
|
||||
}
|
||||
|
||||
func typeAtFieldIndex(startingAt types.Type, fieldIndex int) types.Type {
|
||||
t := maybeUnname(maybeDereference(startingAt))
|
||||
s, ok := t.(*types.Struct)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("cannot get Field of a type that is not a struct, got a %T", t))
|
||||
}
|
||||
|
||||
return s.Field(fieldIndex).Type()
|
||||
}
|
||||
|
||||
// embeddedInterfaceDefiningMethod searches through any embedded interfaces of the
|
||||
// passed interface searching for one that defines the given function. If found, the
|
||||
// types.Named wrapping that interface will be returned along with true in the second value.
|
||||
//
|
||||
// If no such embedded interface is found, nil and false are returned.
|
||||
func embeddedInterfaceDefiningMethod(interfaceT *types.Interface, fn *types.Func) (*types.Named, bool) {
|
||||
for i := 0; i < interfaceT.NumEmbeddeds(); i++ {
|
||||
embedded, ok := interfaceT.EmbeddedType(i).(*types.Named)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
if definesMethod(embedded.Underlying().(*types.Interface), fn) {
|
||||
return embedded, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func explicitlyDefinesMethod(interfaceT *types.Interface, fn *types.Func) bool {
|
||||
for i := 0; i < interfaceT.NumExplicitMethods(); i++ {
|
||||
if interfaceT.ExplicitMethod(i) == fn {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func definesMethod(interfaceT *types.Interface, fn *types.Func) bool {
|
||||
for i := 0; i < interfaceT.NumMethods(); i++ {
|
||||
if interfaceT.Method(i) == fn {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func maybeDereference(t types.Type) types.Type {
|
||||
p, ok := t.(*types.Pointer)
|
||||
if ok {
|
||||
return p.Elem()
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func maybeUnname(t types.Type) types.Type {
|
||||
n, ok := t.(*types.Named)
|
||||
if ok {
|
||||
return n.Underlying()
|
||||
}
|
||||
return t
|
||||
}
|
||||
var Analyzer = analyzer.Analyzer
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package errcheck
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
)
|
||||
|
||||
const commonSrc = `
|
||||
package p
|
||||
|
||||
type Inner struct {}
|
||||
func (Inner) Method()
|
||||
|
||||
type Outer struct {Inner}
|
||||
type OuterP struct {*Inner}
|
||||
|
||||
type InnerInterface interface {
|
||||
Method()
|
||||
}
|
||||
|
||||
type OuterInterface interface {InnerInterface}
|
||||
type MiddleInterfaceStruct struct {OuterInterface}
|
||||
type OuterInterfaceStruct struct {MiddleInterfaceStruct}
|
||||
|
||||
var c = `
|
||||
|
||||
type testCase struct {
|
||||
selector string
|
||||
expectedOk bool
|
||||
expected []string
|
||||
}
|
||||
|
||||
func TestWalkThroughEmbeddedInterfaces(t *testing.T) {
|
||||
cases := []testCase{
|
||||
{"Inner{}.Method", false, nil},
|
||||
{"(&Inner{}).Method", false, nil},
|
||||
{"Outer{}.Method", false, nil},
|
||||
{"InnerInterface.Method", true, []string{"test.InnerInterface"}},
|
||||
{"OuterInterface.Method", true, []string{"test.OuterInterface", "test.InnerInterface"}},
|
||||
{"OuterInterfaceStruct.Method", true, []string{"test.OuterInterface", "test.InnerInterface"}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "test", commonSrc+c.selector, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
conf := types.Config{}
|
||||
info := types.Info{
|
||||
Selections: make(map[*ast.SelectorExpr]*types.Selection),
|
||||
}
|
||||
_, err = conf.Check("test", fset, []*ast.File{f}, &info)
|
||||
require.NoError(t, err)
|
||||
ast.Inspect(f, func(n ast.Node) bool {
|
||||
s, ok := n.(*ast.SelectorExpr)
|
||||
if ok {
|
||||
selection, ok := info.Selections[s]
|
||||
require.Equal(t, true, ok, "No selection!")
|
||||
ts, ok := walkThroughEmbeddedInterfaces(selection)
|
||||
if ok != c.expectedOk {
|
||||
t.Errorf("expected ok %v got %v", c.expectedOk, ok)
|
||||
return false
|
||||
}
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
require.Equal(t, len(c.expected), len(ts))
|
||||
for i, e := range c.expected {
|
||||
assert.Equal(t, e, ts[i].String(), "mismatch at index %d", i)
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"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 TestBootnode_OK(t *testing.T) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package kv
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
@@ -14,7 +15,7 @@ func TestMain(m *testing.M) {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetOutput(io.Discard)
|
||||
|
||||
m.Run()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// setupDB instantiates and returns a DB instance for the validator client.
|
||||
|
||||
Reference in New Issue
Block a user