mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
32 Commits
v4.2.2-rc.
...
beacon-pro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1b3cd11f5 | ||
|
|
c4c6b47d9b | ||
|
|
06a5548424 | ||
|
|
5e74c798d4 | ||
|
|
7b955c94ec | ||
|
|
256a05bfd5 | ||
|
|
03068ba781 | ||
|
|
5df8b83a05 | ||
|
|
db653b8863 | ||
|
|
af203efa0c | ||
|
|
fa1df7ee53 | ||
|
|
5582c558c6 | ||
|
|
573d9739ea | ||
|
|
bb18fa3f71 | ||
|
|
6a605e6b6d | ||
|
|
a0787e2379 | ||
|
|
621bda068d | ||
|
|
48f0bef9bb | ||
|
|
91504eb95a | ||
|
|
3920cddb18 | ||
|
|
5afb1255fe | ||
|
|
9d6160e112 | ||
|
|
1383546999 | ||
|
|
01116f7f82 | ||
|
|
f102689c2c | ||
|
|
fd132103fd | ||
|
|
b71312f575 | ||
|
|
4540cd5cdc | ||
|
|
d33f1f2d98 | ||
|
|
3dc45c2041 | ||
|
|
f7a04ab66d | ||
|
|
01eb14a0f0 |
10
WORKSPACE
10
WORKSPACE
@@ -234,7 +234,7 @@ filegroup(
|
||||
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
|
||||
)
|
||||
|
||||
consensus_spec_version = "v1.4.0-beta.5"
|
||||
consensus_spec_version = "v1.4.0-beta.6"
|
||||
|
||||
bls_test_version = "v0.1.1"
|
||||
|
||||
@@ -250,7 +250,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "9017ffff84d64a7c4c9e6ff9f421f9479f71d3b463b738f54e02158dbb4f50f0",
|
||||
sha256 = "7dc467d7be97525c88a1d3683665c1354cc86297fd62009e7cf5000905b25652",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -266,7 +266,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "f08711682553fe7c9362f1400ed8c56b2fa9576df08581fcad4c508ba8ad4788",
|
||||
sha256 = "e163011254b6ce100205fb779ba660faedc9bc9f7bb4408c25746a7aa5e8d8bc",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -282,7 +282,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "7ea3189e3879f2ac62467cbf2945c00b6c94d30cdefb2d645c630b1018c50e10",
|
||||
sha256 = "b73c81b6386053a2141f6f43b457489668621c7013f740ed93edf9ac0e34f091",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -297,7 +297,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "4119992a2efc79e5cb2bdc07ed08c0b1fa32332cbd0d88e6467f34938df97026",
|
||||
sha256 = "47726c527512d03ef3e706a8e7f8d5db6a5f2153351db0470dab780f6a87c4dd",
|
||||
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
|
||||
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
@@ -38,3 +38,13 @@ go_library(
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["conversions_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1074,3 +1074,17 @@ func sszBytesToUint256String(b []byte) (string, error) {
|
||||
}
|
||||
return bi.String(), nil
|
||||
}
|
||||
|
||||
func DepositSnapshotFromConsensus(ds *eth.DepositSnapshot) *DepositSnapshot {
|
||||
finalized := make([]string, 0, len(ds.Finalized))
|
||||
for _, f := range ds.Finalized {
|
||||
finalized = append(finalized, hexutil.Encode(f))
|
||||
}
|
||||
return &DepositSnapshot{
|
||||
Finalized: finalized,
|
||||
DepositRoot: hexutil.Encode(ds.DepositRoot),
|
||||
DepositCount: fmt.Sprintf("%d", ds.DepositCount),
|
||||
ExecutionBlockHash: hexutil.Encode(ds.ExecutionHash),
|
||||
ExecutionBlockHeight: fmt.Sprintf("%d", ds.ExecutionDepth),
|
||||
}
|
||||
}
|
||||
|
||||
26
api/server/structs/conversions_test.go
Normal file
26
api/server/structs/conversions_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package structs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
func TestDepositSnapshotFromConsensus(t *testing.T) {
|
||||
ds := ð.DepositSnapshot{
|
||||
Finalized: [][]byte{{0xde, 0xad, 0xbe, 0xef}, {0xca, 0xfe, 0xba, 0xbe}},
|
||||
DepositRoot: []byte{0xab, 0xcd},
|
||||
DepositCount: 12345,
|
||||
ExecutionHash: []byte{0x12, 0x34},
|
||||
ExecutionDepth: 67890,
|
||||
}
|
||||
|
||||
res := DepositSnapshotFromConsensus(ds)
|
||||
require.NotNil(t, res)
|
||||
require.DeepEqual(t, []string{"0xdeadbeef", "0xcafebabe"}, res.Finalized)
|
||||
require.Equal(t, "0xabcd", res.DepositRoot)
|
||||
require.Equal(t, "12345", res.DepositCount)
|
||||
require.Equal(t, "0x1234", res.ExecutionBlockHash)
|
||||
require.Equal(t, "67890", res.ExecutionBlockHeight)
|
||||
}
|
||||
@@ -184,3 +184,15 @@ type WeakSubjectivityData struct {
|
||||
WsCheckpoint *Checkpoint `json:"ws_checkpoint"`
|
||||
StateRoot string `json:"state_root"`
|
||||
}
|
||||
|
||||
type GetDepositSnapshotResponse struct {
|
||||
Data *DepositSnapshot `json:"data"`
|
||||
}
|
||||
|
||||
type DepositSnapshot struct {
|
||||
Finalized []string `json:"finalized"`
|
||||
DepositRoot string `json:"deposit_root"`
|
||||
DepositCount string `json:"deposit_count"`
|
||||
ExecutionBlockHash string `json:"execution_block_hash"`
|
||||
ExecutionBlockHeight string `json:"execution_block_height"`
|
||||
}
|
||||
|
||||
@@ -2046,7 +2046,9 @@ func TestFillMissingBlockPayloadId_PrepareAllPayloads(t *testing.T) {
|
||||
// boost. It alters the genesisTime tracked by the store.
|
||||
func driftGenesisTime(s *Service, slot, delay int64) {
|
||||
offset := slot*int64(params.BeaconConfig().SecondsPerSlot) + delay
|
||||
s.SetGenesisTime(time.Unix(time.Now().Unix()-offset, 0))
|
||||
newTime := time.Unix(time.Now().Unix()-offset, 0)
|
||||
s.SetGenesisTime(newTime)
|
||||
s.cfg.ForkChoiceStore.SetGenesisTime(uint64(newTime.Unix()))
|
||||
}
|
||||
|
||||
func TestMissingIndices(t *testing.T) {
|
||||
|
||||
@@ -228,6 +228,20 @@ func (bs *BlobStorage) Indices(root [32]byte) ([fieldparams.MaxBlobsPerBlock]boo
|
||||
return mask, nil
|
||||
}
|
||||
|
||||
// Clear deletes all files on the filesystem.
|
||||
func (bs *BlobStorage) Clear() error {
|
||||
dirs, err := listDir(bs.fs, ".")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, dir := range dirs {
|
||||
if err := bs.fs.RemoveAll(dir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type blobNamer struct {
|
||||
root [32]byte
|
||||
index uint64
|
||||
|
||||
@@ -88,6 +88,19 @@ func TestBlobStorage_SaveBlobData(t *testing.T) {
|
||||
_, err = bs.Get(expected.BlockRoot(), expected.Index)
|
||||
require.ErrorContains(t, "file does not exist", err)
|
||||
})
|
||||
|
||||
t.Run("clear", func(t *testing.T) {
|
||||
blob := testSidecars[0]
|
||||
b := NewEphemeralBlobStorage(t)
|
||||
require.NoError(t, b.Save(blob))
|
||||
res, err := b.Get(blob.BlockRoot(), blob.Index)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
require.NoError(t, b.Clear())
|
||||
// After clearing, the blob should not exist in the db.
|
||||
_, err = b.Get(blob.BlockRoot(), blob.Index)
|
||||
require.ErrorIs(t, err, os.ErrNotExist)
|
||||
})
|
||||
}
|
||||
|
||||
// pollUntil polls a condition function until it returns true or a timeout is reached.
|
||||
|
||||
@@ -213,6 +213,9 @@ func NewKVStore(ctx context.Context, dirPath string, opts ...KVStoreOption) (*St
|
||||
|
||||
// ClearDB removes the previously stored database in the data directory.
|
||||
func (s *Store) ClearDB() error {
|
||||
if err := s.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close db: %w", err)
|
||||
}
|
||||
if _, err := os.Stat(s.databasePath); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package slasherkv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
@@ -87,6 +88,9 @@ func NewKVStore(ctx context.Context, dirPath string) (*Store, error) {
|
||||
|
||||
// ClearDB removes the previously stored database in the data directory.
|
||||
func (s *Store) ClearDB() error {
|
||||
if err := s.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close db: %w", err)
|
||||
}
|
||||
if _, err := os.Stat(s.databasePath); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -21,9 +21,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// Signing root (32 bytes)
|
||||
attestationRecordKeySize = 32 // Bytes.
|
||||
signingRootSize = 32 // Bytes.
|
||||
rootSize = 32 // Bytes.
|
||||
)
|
||||
|
||||
// LastEpochWrittenForValidators given a list of validator indices returns the latest
|
||||
@@ -170,15 +169,15 @@ func (s *Store) CheckAttesterDoubleVotes(
|
||||
continue
|
||||
}
|
||||
|
||||
// Retrieve the attestation record corresponding to the signing root
|
||||
// Retrieve the attestation record corresponding to the data root
|
||||
// from the database.
|
||||
encExistingAttRecord := attRecordsBkt.Get(attRecordsKey)
|
||||
if encExistingAttRecord == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
existingSigningRoot := bytesutil.ToBytes32(attRecordsKey[:signingRootSize])
|
||||
if existingSigningRoot == attToProcess.SigningRoot {
|
||||
existingDataRoot := bytesutil.ToBytes32(attRecordsKey[:rootSize])
|
||||
if existingDataRoot == attToProcess.DataRoot {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -190,10 +189,10 @@ func (s *Store) CheckAttesterDoubleVotes(
|
||||
|
||||
// Build the proof of double vote.
|
||||
slashAtt := &slashertypes.AttesterDoubleVote{
|
||||
ValidatorIndex: primitives.ValidatorIndex(valIdx),
|
||||
Target: attToProcess.IndexedAttestation.Data.Target.Epoch,
|
||||
PrevAttestationWrapper: existingAttRecord,
|
||||
AttestationWrapper: attToProcess,
|
||||
ValidatorIndex: primitives.ValidatorIndex(valIdx),
|
||||
Target: attToProcess.IndexedAttestation.Data.Target.Epoch,
|
||||
Wrapper_1: existingAttRecord,
|
||||
Wrapper_2: attToProcess,
|
||||
}
|
||||
|
||||
localDoubleVotes = append(localDoubleVotes, slashAtt)
|
||||
@@ -281,12 +280,12 @@ func (s *Store) SaveAttestationRecordsForValidators(
|
||||
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
attRecordsBkt := tx.Bucket(attestationRecordsBucket)
|
||||
signingRootsBkt := tx.Bucket(attestationDataRootsBucket)
|
||||
dataRootsBkt := tx.Bucket(attestationDataRootsBucket)
|
||||
|
||||
for i := len(attestations) - 1; i >= 0; i-- {
|
||||
attestation := attestations[i]
|
||||
|
||||
if err := attRecordsBkt.Put(attestation.SigningRoot[:], encodedRecords[i]); err != nil {
|
||||
if err := attRecordsBkt.Put(attestation.DataRoot[:], encodedRecords[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -294,7 +293,7 @@ func (s *Store) SaveAttestationRecordsForValidators(
|
||||
encIdx := encodeValidatorIndex(primitives.ValidatorIndex(valIdx))
|
||||
|
||||
key := append(encodedTargetEpoch[i], encIdx...)
|
||||
if err := signingRootsBkt.Put(key, attestation.SigningRoot[:]); err != nil {
|
||||
if err := dataRootsBkt.Put(key, attestation.DataRoot[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -396,14 +395,14 @@ func (s *Store) CheckDoubleBlockProposals(
|
||||
|
||||
// If there is no existing proposal record (empty result), then there is no double proposal.
|
||||
// We can continue to the next proposal.
|
||||
if len(encExistingProposalWrapper) < signingRootSize {
|
||||
if len(encExistingProposalWrapper) < rootSize {
|
||||
continue
|
||||
}
|
||||
|
||||
// Compare the proposal signing root in the DB with the incoming proposal signing root.
|
||||
// If they differ, we have a double proposal.
|
||||
existingSigningRoot := bytesutil.ToBytes32(encExistingProposalWrapper[:signingRootSize])
|
||||
if existingSigningRoot != incomingProposal.SigningRoot {
|
||||
existingRoot := bytesutil.ToBytes32(encExistingProposalWrapper[:rootSize])
|
||||
if existingRoot != incomingProposal.HeaderRoot {
|
||||
existingProposalWrapper, err := decodeProposalRecord(encExistingProposalWrapper)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -610,18 +609,18 @@ func encodeAttestationRecord(att *slashertypes.IndexedAttestationWrapper) ([]byt
|
||||
// Compress attestation.
|
||||
compressedAtt := snappy.Encode(nil, encodedAtt)
|
||||
|
||||
return append(att.SigningRoot[:], compressedAtt...), nil
|
||||
return append(att.DataRoot[:], compressedAtt...), nil
|
||||
}
|
||||
|
||||
// Decode attestation record from bytes.
|
||||
// The input encoded attestation record consists in the signing root concatened with the compressed attestation record.
|
||||
func decodeAttestationRecord(encoded []byte) (*slashertypes.IndexedAttestationWrapper, error) {
|
||||
if len(encoded) < signingRootSize {
|
||||
return nil, fmt.Errorf("wrong length for encoded attestation record, want minimum %d, got %d", signingRootSize, len(encoded))
|
||||
if len(encoded) < rootSize {
|
||||
return nil, fmt.Errorf("wrong length for encoded attestation record, want minimum %d, got %d", rootSize, len(encoded))
|
||||
}
|
||||
|
||||
// Decompress attestation.
|
||||
decodedAttBytes, err := snappy.Decode(nil, encoded[signingRootSize:])
|
||||
decodedAttBytes, err := snappy.Decode(nil, encoded[rootSize:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -633,13 +632,13 @@ func decodeAttestationRecord(encoded []byte) (*slashertypes.IndexedAttestationWr
|
||||
}
|
||||
|
||||
// Decode signing root.
|
||||
signingRootBytes := encoded[:signingRootSize]
|
||||
signingRoot := bytesutil.ToBytes32(signingRootBytes)
|
||||
dataRootBytes := encoded[:rootSize]
|
||||
dataRoot := bytesutil.ToBytes32(dataRootBytes)
|
||||
|
||||
// Return decoded attestation.
|
||||
attestation := &slashertypes.IndexedAttestationWrapper{
|
||||
IndexedAttestation: decodedAtt,
|
||||
SigningRoot: signingRoot,
|
||||
DataRoot: dataRoot,
|
||||
}
|
||||
|
||||
return attestation, nil
|
||||
@@ -654,18 +653,18 @@ func encodeProposalRecord(blkHdr *slashertypes.SignedBlockHeaderWrapper) ([]byte
|
||||
return nil, err
|
||||
}
|
||||
compressedHdr := snappy.Encode(nil, encodedHdr)
|
||||
return append(blkHdr.SigningRoot[:], compressedHdr...), nil
|
||||
return append(blkHdr.HeaderRoot[:], compressedHdr...), nil
|
||||
}
|
||||
|
||||
func decodeProposalRecord(encoded []byte) (*slashertypes.SignedBlockHeaderWrapper, error) {
|
||||
if len(encoded) < signingRootSize {
|
||||
if len(encoded) < rootSize {
|
||||
return nil, fmt.Errorf(
|
||||
"wrong length for encoded proposal record, want %d, got %d", signingRootSize, len(encoded),
|
||||
"wrong length for encoded proposal record, want %d, got %d", rootSize, len(encoded),
|
||||
)
|
||||
}
|
||||
signingRoot := encoded[:signingRootSize]
|
||||
dataRoot := encoded[:rootSize]
|
||||
decodedBlkHdr := ðpb.SignedBeaconBlockHeader{}
|
||||
decodedHdrBytes, err := snappy.Decode(nil, encoded[signingRootSize:])
|
||||
decodedHdrBytes, err := snappy.Decode(nil, encoded[rootSize:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -674,7 +673,7 @@ func decodeProposalRecord(encoded []byte) (*slashertypes.SignedBlockHeaderWrappe
|
||||
}
|
||||
return &slashertypes.SignedBlockHeaderWrapper{
|
||||
SignedBeaconBlockHeader: decodedBlkHdr,
|
||||
SigningRoot: bytesutil.ToBytes32(signingRoot),
|
||||
HeaderRoot: bytesutil.ToBytes32(dataRoot),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestStore_AttestationRecordForValidator_SaveRetrieve(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, target, attRecord.IndexedAttestation.Data.Target.Epoch)
|
||||
assert.DeepEqual(t, source, attRecord.IndexedAttestation.Data.Source.Epoch)
|
||||
assert.DeepEqual(t, sr, attRecord.SigningRoot)
|
||||
assert.DeepEqual(t, sr, attRecord.DataRoot)
|
||||
}
|
||||
|
||||
func TestStore_LastEpochWrittenForValidators(t *testing.T) {
|
||||
@@ -93,28 +93,28 @@ func TestStore_CheckAttesterDoubleVotes(t *testing.T) {
|
||||
|
||||
wanted := []*slashertypes.AttesterDoubleVote{
|
||||
{
|
||||
ValidatorIndex: 0,
|
||||
Target: 3,
|
||||
PrevAttestationWrapper: createAttestationWrapper(2, 3, []uint64{0, 1}, []byte{1}),
|
||||
AttestationWrapper: createAttestationWrapper(2, 3, []uint64{0, 1}, []byte{2}),
|
||||
ValidatorIndex: 0,
|
||||
Target: 3,
|
||||
Wrapper_1: createAttestationWrapper(2, 3, []uint64{0, 1}, []byte{1}),
|
||||
Wrapper_2: createAttestationWrapper(2, 3, []uint64{0, 1}, []byte{2}),
|
||||
},
|
||||
{
|
||||
ValidatorIndex: 1,
|
||||
Target: 3,
|
||||
PrevAttestationWrapper: createAttestationWrapper(2, 3, []uint64{0, 1}, []byte{1}),
|
||||
AttestationWrapper: createAttestationWrapper(2, 3, []uint64{0, 1}, []byte{2}),
|
||||
ValidatorIndex: 1,
|
||||
Target: 3,
|
||||
Wrapper_1: createAttestationWrapper(2, 3, []uint64{0, 1}, []byte{1}),
|
||||
Wrapper_2: createAttestationWrapper(2, 3, []uint64{0, 1}, []byte{2}),
|
||||
},
|
||||
{
|
||||
ValidatorIndex: 2,
|
||||
Target: 4,
|
||||
PrevAttestationWrapper: createAttestationWrapper(3, 4, []uint64{2, 3}, []byte{3}),
|
||||
AttestationWrapper: createAttestationWrapper(3, 4, []uint64{2, 3}, []byte{4}),
|
||||
ValidatorIndex: 2,
|
||||
Target: 4,
|
||||
Wrapper_1: createAttestationWrapper(3, 4, []uint64{2, 3}, []byte{3}),
|
||||
Wrapper_2: createAttestationWrapper(3, 4, []uint64{2, 3}, []byte{4}),
|
||||
},
|
||||
{
|
||||
ValidatorIndex: 3,
|
||||
Target: 4,
|
||||
PrevAttestationWrapper: createAttestationWrapper(3, 4, []uint64{2, 3}, []byte{3}),
|
||||
AttestationWrapper: createAttestationWrapper(3, 4, []uint64{2, 3}, []byte{4}),
|
||||
ValidatorIndex: 3,
|
||||
Target: 4,
|
||||
Wrapper_1: createAttestationWrapper(3, 4, []uint64{2, 3}, []byte{3}),
|
||||
Wrapper_2: createAttestationWrapper(3, 4, []uint64{2, 3}, []byte{4}),
|
||||
},
|
||||
}
|
||||
doubleVotes, err := beaconDB.CheckAttesterDoubleVotes(ctx, slashableAtts)
|
||||
@@ -126,8 +126,8 @@ func TestStore_CheckAttesterDoubleVotes(t *testing.T) {
|
||||
for i, double := range doubleVotes {
|
||||
require.DeepEqual(t, wanted[i].ValidatorIndex, double.ValidatorIndex)
|
||||
require.DeepEqual(t, wanted[i].Target, double.Target)
|
||||
require.DeepEqual(t, wanted[i].PrevAttestationWrapper, double.PrevAttestationWrapper)
|
||||
require.DeepEqual(t, wanted[i].AttestationWrapper, double.AttestationWrapper)
|
||||
require.DeepEqual(t, wanted[i].Wrapper_1, double.Wrapper_1)
|
||||
require.DeepEqual(t, wanted[i].Wrapper_2, double.Wrapper_2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,9 +224,9 @@ func TestStore_ExistingBlockProposals(t *testing.T) {
|
||||
|
||||
// Second time checking same proposals but all with different signing root should
|
||||
// return all double proposals.
|
||||
proposals[0].SigningRoot = bytesutil.ToBytes32([]byte{2})
|
||||
proposals[1].SigningRoot = bytesutil.ToBytes32([]byte{2})
|
||||
proposals[2].SigningRoot = bytesutil.ToBytes32([]byte{2})
|
||||
proposals[0].HeaderRoot = bytesutil.ToBytes32([]byte{2})
|
||||
proposals[1].HeaderRoot = bytesutil.ToBytes32([]byte{2})
|
||||
proposals[2].HeaderRoot = bytesutil.ToBytes32([]byte{2})
|
||||
|
||||
doubleProposals, err = beaconDB.CheckDoubleBlockProposals(ctx, proposals)
|
||||
require.NoError(t, err)
|
||||
@@ -515,7 +515,7 @@ func createProposalWrapper(t *testing.T, slot primitives.Slot, proposerIndex pri
|
||||
StateRoot: bytesutil.PadTo(signingRoot, 32),
|
||||
BodyRoot: params.BeaconConfig().ZeroHash[:],
|
||||
}
|
||||
signRoot, err := header.HashTreeRoot()
|
||||
headerRoot, err := header.HashTreeRoot()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -524,15 +524,16 @@ func createProposalWrapper(t *testing.T, slot primitives.Slot, proposerIndex pri
|
||||
Header: header,
|
||||
Signature: params.BeaconConfig().EmptySignature[:],
|
||||
},
|
||||
SigningRoot: signRoot,
|
||||
HeaderRoot: headerRoot,
|
||||
}
|
||||
}
|
||||
|
||||
func createAttestationWrapper(source, target primitives.Epoch, indices []uint64, signingRoot []byte) *slashertypes.IndexedAttestationWrapper {
|
||||
signRoot := bytesutil.ToBytes32(signingRoot)
|
||||
if signingRoot == nil {
|
||||
signRoot = params.BeaconConfig().ZeroHash
|
||||
func createAttestationWrapper(source, target primitives.Epoch, indices []uint64, dataRootBytes []byte) *slashertypes.IndexedAttestationWrapper {
|
||||
dataRoot := bytesutil.ToBytes32(dataRootBytes)
|
||||
if dataRootBytes == nil {
|
||||
dataRoot = params.BeaconConfig().ZeroHash
|
||||
}
|
||||
|
||||
data := ðpb.AttestationData{
|
||||
BeaconBlockRoot: params.BeaconConfig().ZeroHash[:],
|
||||
Source: ðpb.Checkpoint{
|
||||
@@ -544,13 +545,14 @@ func createAttestationWrapper(source, target primitives.Epoch, indices []uint64,
|
||||
Root: params.BeaconConfig().ZeroHash[:],
|
||||
},
|
||||
}
|
||||
|
||||
return &slashertypes.IndexedAttestationWrapper{
|
||||
IndexedAttestation: ðpb.IndexedAttestation{
|
||||
AttestingIndices: indices,
|
||||
Data: data,
|
||||
Signature: params.BeaconConfig().EmptySignature[:],
|
||||
},
|
||||
SigningRoot: signRoot,
|
||||
DataRoot: dataRoot,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -493,7 +493,12 @@ func (s *Service) GetPayloadBodiesByHash(ctx context.Context, executionBlockHash
|
||||
return result, nil
|
||||
}
|
||||
err := s.rpcClient.CallContext(ctx, &result, GetPayloadBodiesByHashV1, executionBlockHashes)
|
||||
|
||||
if err != nil {
|
||||
return nil, handleRPCError(err)
|
||||
}
|
||||
if len(result) != len(executionBlockHashes) {
|
||||
return nil, fmt.Errorf("mismatch of payloads retrieved from the execution client: %d vs %d", len(result), len(executionBlockHashes))
|
||||
}
|
||||
for i, item := range result {
|
||||
if item == nil {
|
||||
result[i] = &pb.ExecutionPayloadBodyV1{
|
||||
@@ -502,7 +507,7 @@ func (s *Service) GetPayloadBodiesByHash(ctx context.Context, executionBlockHash
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, handleRPCError(err)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetPayloadBodiesByRange returns the relevant payload bodies for the provided range.
|
||||
@@ -635,6 +640,8 @@ func (s *Service) retrievePayloadFromExecutionHash(ctx context.Context, executio
|
||||
return fullPayloadFromPayloadBody(header, bdy, version)
|
||||
}
|
||||
|
||||
// This method assumes that the provided execution hashes are all valid and part of the
|
||||
// canonical chain.
|
||||
func (s *Service) retrievePayloadsFromExecutionHashes(
|
||||
ctx context.Context,
|
||||
executionHashes []common.Hash,
|
||||
|
||||
@@ -912,6 +912,73 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, payload, got.Proto())
|
||||
})
|
||||
t.Run("handles invalid response from EL", func(t *testing.T) {
|
||||
fix := fixtures()
|
||||
payload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload)
|
||||
require.Equal(t, true, ok)
|
||||
|
||||
jsonPayload := make(map[string]interface{})
|
||||
tx := gethtypes.NewTransaction(
|
||||
0,
|
||||
common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"),
|
||||
big.NewInt(0), 0, big.NewInt(0),
|
||||
nil,
|
||||
)
|
||||
txs := []*gethtypes.Transaction{tx}
|
||||
encodedBinaryTxs := make([][]byte, 1)
|
||||
var err error
|
||||
encodedBinaryTxs[0], err = txs[0].MarshalBinary()
|
||||
require.NoError(t, err)
|
||||
payload.Transactions = encodedBinaryTxs
|
||||
jsonPayload["transactions"] = []hexutil.Bytes{encodedBinaryTxs[0]}
|
||||
|
||||
wrappedPayload, err := blocks.WrappedExecutionPayload(payload)
|
||||
require.NoError(t, err)
|
||||
header, err := blocks.PayloadToHeader(wrappedPayload)
|
||||
require.NoError(t, err)
|
||||
|
||||
bellatrixBlock := util.NewBlindedBeaconBlockBellatrix()
|
||||
wanted := util.NewBeaconBlockBellatrix()
|
||||
wanted.Block.Slot = 1
|
||||
// Make sure block hash is the zero hash.
|
||||
bellatrixBlock.Block.Body.ExecutionPayloadHeader.BlockHash = make([]byte, 32)
|
||||
bellatrixBlock.Block.Slot = 1
|
||||
wrappedEmpty, err := blocks.NewSignedBeaconBlock(bellatrixBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
|
||||
respJSON := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": []map[string]interface{}{},
|
||||
}
|
||||
require.NoError(t, json.NewEncoder(w).Encode(respJSON))
|
||||
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
defer rpcClient.Close()
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
blindedBlock := util.NewBlindedBeaconBlockBellatrix()
|
||||
|
||||
blindedBlock.Block.Body.ExecutionPayloadHeader = header
|
||||
wrapped, err := blocks.NewSignedBeaconBlock(blindedBlock)
|
||||
require.NoError(t, err)
|
||||
copiedWrapped, err := wrapped.Copy()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = service.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{wrappedEmpty, wrapped, copiedWrapped})
|
||||
require.ErrorContains(t, "mismatch of payloads retrieved from the execution client", err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
|
||||
@@ -2166,7 +2233,7 @@ func TestCapella_PayloadBodiesByHash(t *testing.T) {
|
||||
|
||||
bRoot := [32]byte{}
|
||||
copy(bRoot[:], "hash")
|
||||
results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot})
|
||||
results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot, bRoot})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(results))
|
||||
|
||||
|
||||
@@ -77,5 +77,6 @@ go_test(
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -93,13 +93,13 @@ func (n *Node) updateBestDescendant(ctx context.Context, justifiedEpoch, finaliz
|
||||
// Any node with different finalized or justified epoch than
|
||||
// the ones in fork choice store should not be viable to head.
|
||||
func (n *Node) viableForHead(justifiedEpoch, currentEpoch primitives.Epoch) bool {
|
||||
justified := justifiedEpoch == n.justifiedEpoch || justifiedEpoch == 0
|
||||
if !justified && justifiedEpoch+1 == currentEpoch {
|
||||
if n.unrealizedJustifiedEpoch+1 >= currentEpoch && n.justifiedEpoch+2 >= currentEpoch {
|
||||
justified = true
|
||||
}
|
||||
if justifiedEpoch == 0 {
|
||||
return true
|
||||
}
|
||||
return justified
|
||||
// We use n.justifiedEpoch as the voting source because:
|
||||
// 1. if this node is from current epoch, n.justifiedEpoch is the realized justification epoch.
|
||||
// 2. if this node is from a previous epoch, n.justifiedEpoch has already been updated to the unrealized justification epoch.
|
||||
return n.justifiedEpoch == justifiedEpoch || n.justifiedEpoch+2 >= currentEpoch
|
||||
}
|
||||
|
||||
func (n *Node) leadsToViableHead(justifiedEpoch, currentEpoch primitives.Epoch) bool {
|
||||
|
||||
@@ -146,7 +146,9 @@ func TestNode_ViableForHead(t *testing.T) {
|
||||
{&Node{}, 1, false},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1}, 1, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 1}, 2, false},
|
||||
{&Node{finalizedEpoch: 3, justifiedEpoch: 4}, 4, true},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 2}, 3, false},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 2}, 4, false},
|
||||
{&Node{finalizedEpoch: 1, justifiedEpoch: 3}, 4, true},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
got := tc.n.viableForHead(tc.justifiedEpoch, 5)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
)
|
||||
|
||||
func TestStore_SetUnrealizedEpochs(t *testing.T) {
|
||||
@@ -63,14 +64,14 @@ func TestStore_UpdateUnrealizedCheckpoints(t *testing.T) {
|
||||
func TestStore_LongFork(t *testing.T) {
|
||||
f := setup(1, 1)
|
||||
ctx := context.Background()
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, 100, [32]byte{'a'}, params.BeaconConfig().ZeroHash, [32]byte{'A'}, 1, 1)
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, 75, [32]byte{'a'}, params.BeaconConfig().ZeroHash, [32]byte{'A'}, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 101, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'B'}, 1, 1)
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 80, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'B'}, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
require.NoError(t, f.store.setUnrealizedJustifiedEpoch([32]byte{'b'}, 2))
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 102, [32]byte{'c'}, [32]byte{'b'}, [32]byte{'C'}, 1, 1)
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 95, [32]byte{'c'}, [32]byte{'b'}, [32]byte{'C'}, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
require.NoError(t, f.store.setUnrealizedJustifiedEpoch([32]byte{'c'}, 2))
|
||||
@@ -78,27 +79,28 @@ func TestStore_LongFork(t *testing.T) {
|
||||
// Add an attestation to c, it is head
|
||||
f.ProcessAttestation(ctx, []uint64{0}, [32]byte{'c'}, 1)
|
||||
f.justifiedBalances = []uint64{100}
|
||||
c := f.store.nodeByRoot[[32]byte{'c'}]
|
||||
require.Equal(t, primitives.Epoch(2), slots.ToEpoch(c.slot))
|
||||
driftGenesisTime(f, c.slot, 0)
|
||||
headRoot, err := f.Head(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{'c'}, headRoot)
|
||||
|
||||
// D is head even though its weight is lower.
|
||||
// c remains the head even if a block d with higher realized justification is seen
|
||||
ha := [32]byte{'a'}
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 103, [32]byte{'d'}, [32]byte{'b'}, [32]byte{'D'}, 2, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
require.NoError(t, f.UpdateJustifiedCheckpoint(ctx, &forkchoicetypes.Checkpoint{Epoch: 2, Root: ha}))
|
||||
headRoot, err = f.Head(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{'d'}, headRoot)
|
||||
require.Equal(t, uint64(0), f.store.nodeByRoot[[32]byte{'d'}].weight)
|
||||
require.Equal(t, uint64(100), f.store.nodeByRoot[[32]byte{'c'}].weight)
|
||||
|
||||
// Update unrealized justification, c becomes head
|
||||
require.NoError(t, f.updateUnrealizedCheckpoints(ctx))
|
||||
d := f.store.nodeByRoot[[32]byte{'d'}]
|
||||
require.Equal(t, primitives.Epoch(3), slots.ToEpoch(d.slot))
|
||||
driftGenesisTime(f, d.slot, 0)
|
||||
require.Equal(t, true, d.viableForHead(f.store.justifiedCheckpoint.Epoch, slots.ToEpoch(d.slot)))
|
||||
headRoot, err = f.Head(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{'c'}, headRoot)
|
||||
require.Equal(t, uint64(0), f.store.nodeByRoot[[32]byte{'d'}].weight)
|
||||
require.Equal(t, uint64(100), f.store.nodeByRoot[[32]byte{'c'}].weight)
|
||||
}
|
||||
|
||||
// Epoch 1 Epoch 2 Epoch 3
|
||||
|
||||
@@ -55,6 +55,7 @@ go_library(
|
||||
"//beacon-chain/verification:go_default_library",
|
||||
"//cmd:go_default_library",
|
||||
"//cmd/beacon-chain/flags:go_default_library",
|
||||
"//config:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
@@ -62,6 +63,7 @@ go_library(
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//monitoring/prometheus:go_default_library",
|
||||
"//monitoring/tracing:go_default_library",
|
||||
"//proto/prysm/config:go_default_library",
|
||||
"//runtime:go_default_library",
|
||||
"//runtime/debug:go_default_library",
|
||||
"//runtime/prereqs:go_default_library",
|
||||
|
||||
@@ -57,12 +57,14 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/verification"
|
||||
"github.com/prysmaticlabs/prysm/v4/cmd"
|
||||
"github.com/prysmaticlabs/prysm/v4/cmd/beacon-chain/flags"
|
||||
"github.com/prysmaticlabs/prysm/v4/config"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/slice"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/monitoring/prometheus"
|
||||
proposersettings "github.com/prysmaticlabs/prysm/v4/proto/prysm/config"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/debug"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/prereqs"
|
||||
@@ -277,7 +279,7 @@ func New(cliCtx *cli.Context, cancel context.CancelFunc, opts ...Option) (*Beaco
|
||||
}
|
||||
|
||||
log.Debugln("Registering Sync Service")
|
||||
if err := beacon.registerSyncService(beacon.initialSyncComplete); err != nil {
|
||||
if err := beacon.registerSyncService(beacon.initialSyncComplete, bfs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -427,13 +429,12 @@ func (b *BeaconNode) startDB(cliCtx *cli.Context, depositAddress string) error {
|
||||
}
|
||||
if clearDBConfirmed || forceClearDB {
|
||||
log.Warning("Removing database")
|
||||
if err := d.Close(); err != nil {
|
||||
return errors.Wrap(err, "could not close db prior to clearing")
|
||||
}
|
||||
if err := d.ClearDB(); err != nil {
|
||||
return errors.Wrap(err, "could not clear database")
|
||||
}
|
||||
|
||||
if err := b.BlobStorage.Clear(); err != nil {
|
||||
return errors.Wrap(err, "could not clear blob storage")
|
||||
}
|
||||
d, err = kv.NewKVStore(b.ctx, dbPath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not create new database")
|
||||
@@ -531,12 +532,12 @@ func (b *BeaconNode) startSlasherDB(cliCtx *cli.Context) error {
|
||||
}
|
||||
if clearDBConfirmed || forceClearDB {
|
||||
log.Warning("Removing database")
|
||||
if err := d.Close(); err != nil {
|
||||
return errors.Wrap(err, "could not close db prior to clearing")
|
||||
}
|
||||
if err := d.ClearDB(); err != nil {
|
||||
return errors.Wrap(err, "could not clear database")
|
||||
}
|
||||
if err := b.BlobStorage.Clear(); err != nil {
|
||||
return errors.Wrap(err, "could not clear blob storage")
|
||||
}
|
||||
d, err = slasherkv.NewKVStore(b.ctx, dbPath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not create new database")
|
||||
@@ -719,7 +720,7 @@ func (b *BeaconNode) registerPOWChainService() error {
|
||||
return b.services.RegisterService(web3Service)
|
||||
}
|
||||
|
||||
func (b *BeaconNode) registerSyncService(initialSyncComplete chan struct{}) error {
|
||||
func (b *BeaconNode) registerSyncService(initialSyncComplete chan struct{}, bFillStore *backfill.Store) error {
|
||||
var web3Service *execution.Service
|
||||
if err := b.services.FetchService(&web3Service); err != nil {
|
||||
return err
|
||||
@@ -758,6 +759,7 @@ func (b *BeaconNode) registerSyncService(initialSyncComplete chan struct{}) erro
|
||||
regularsync.WithStateNotifier(b),
|
||||
regularsync.WithBlobStorage(b.BlobStorage),
|
||||
regularsync.WithVerifierWaiter(b.verifyInitWaiter),
|
||||
regularsync.WithAvailableBlocker(bFillStore),
|
||||
)
|
||||
return b.services.RegisterService(rs)
|
||||
}
|
||||
@@ -816,6 +818,21 @@ func (b *BeaconNode) registerSlasherService() error {
|
||||
return b.services.RegisterService(slasherSrv)
|
||||
}
|
||||
|
||||
func proposerSettings(cliCtx *cli.Context) (*proposersettings.ProposerSettingsPayload, error) {
|
||||
var fileConfig *proposersettings.ProposerSettingsPayload
|
||||
if cliCtx.IsSet(flags.ProposerSettingsFlag.Name) {
|
||||
if err := config.UnmarshalFromFile(cliCtx.Context, cliCtx.String(flags.ProposerSettingsFlag.Name), &fileConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if cliCtx.IsSet(flags.ProposerSettingsURLFlag.Name) {
|
||||
if err := config.UnmarshalFromURL(cliCtx.Context, cliCtx.String(flags.ProposerSettingsURLFlag.Name), &fileConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return fileConfig, nil
|
||||
}
|
||||
|
||||
func (b *BeaconNode) registerRPCService(router *mux.Router) error {
|
||||
var chainService *blockchain.Service
|
||||
if err := b.services.FetchService(&chainService); err != nil {
|
||||
@@ -865,6 +882,11 @@ func (b *BeaconNode) registerRPCService(router *mux.Router) error {
|
||||
maxMsgSize := b.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name)
|
||||
enableDebugRPCEndpoints := b.cliCtx.Bool(flags.EnableDebugRPCEndpoints.Name)
|
||||
|
||||
psettings, err := proposerSettings(b.cliCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p2pService := b.fetchP2P()
|
||||
rpcService := rpc.NewService(b.ctx, &rpc.Config{
|
||||
ExecutionEngineCaller: web3Service,
|
||||
@@ -896,7 +918,6 @@ func (b *BeaconNode) registerRPCService(router *mux.Router) error {
|
||||
ExitPool: b.exitPool,
|
||||
SlashingsPool: b.slashingsPool,
|
||||
BLSChangesPool: b.blsToExecPool,
|
||||
SlashingChecker: slasherService,
|
||||
SyncCommitteeObjectPool: b.syncCommitteePool,
|
||||
ExecutionChainService: web3Service,
|
||||
ExecutionChainInfoFetcher: web3Service,
|
||||
@@ -917,8 +938,8 @@ func (b *BeaconNode) registerRPCService(router *mux.Router) error {
|
||||
BlobStorage: b.BlobStorage,
|
||||
TrackedValidatorsCache: b.trackedValidatorsCache,
|
||||
PayloadIDCache: b.payloadIDCache,
|
||||
ProposerSettings: psettings,
|
||||
})
|
||||
|
||||
return b.services.RegisterService(rpcService)
|
||||
}
|
||||
|
||||
@@ -1047,7 +1068,7 @@ func (b *BeaconNode) registerBuilderService(cliCtx *cli.Context) error {
|
||||
if err := b.services.FetchService(&chainService); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update here based on proposer settings
|
||||
opts := append(b.serviceFlagOpts.builderOpts,
|
||||
builder.WithHeadFetcher(chainService),
|
||||
builder.WithDatabase(b.db))
|
||||
|
||||
@@ -14,4 +14,5 @@ var (
|
||||
ErrInvalidRequest = errors.New("invalid range, step or count")
|
||||
ErrBlobLTMinRequest = errors.New("blob slot < minimum_request_epoch")
|
||||
ErrMaxBlobReqExceeded = errors.New("requested more than MAX_REQUEST_BLOB_SIDECARS")
|
||||
ErrResourceUnavailable = errors.New("resource requested unavailable")
|
||||
)
|
||||
|
||||
@@ -44,15 +44,21 @@ go_library(
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/node:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/validator:go_default_library",
|
||||
"//beacon-chain/slasher:go_default_library",
|
||||
"//beacon-chain/startup:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/proposer:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//io/logs:go_default_library",
|
||||
"//monitoring/tracing:go_default_library",
|
||||
"//proto/prysm/config:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_gorilla_mux//:go_default_library",
|
||||
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library",
|
||||
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
|
||||
|
||||
@@ -17,6 +17,7 @@ go_library(
|
||||
"//api/server:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/cache/depositsnapshot:go_default_library",
|
||||
"//beacon-chain/core/altair:go_default_library",
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/feed:go_default_library",
|
||||
@@ -77,6 +78,7 @@ go_test(
|
||||
"//api/server:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//beacon-chain/blockchain/testing:go_default_library",
|
||||
"//beacon-chain/cache/depositsnapshot:go_default_library",
|
||||
"//beacon-chain/core/signing:go_default_library",
|
||||
"//beacon-chain/core/time:go_default_library",
|
||||
"//beacon-chain/core/transition:go_default_library",
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/api"
|
||||
"github.com/prysmaticlabs/prysm/v4/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositsnapshot"
|
||||
corehelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/filters"
|
||||
@@ -2071,3 +2072,48 @@ func (s *Server) GetGenesis(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
httputil.WriteJson(w, resp)
|
||||
}
|
||||
|
||||
// GetDepositSnapshot retrieves the EIP-4881 Deposit Tree Snapshot. Either a JSON or,
|
||||
// if the Accept header was added, bytes serialized by SSZ will be returned.
|
||||
func (s *Server) GetDepositSnapshot(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, span := trace.StartSpan(r.Context(), "beacon.GetDepositSnapshot")
|
||||
defer span.End()
|
||||
|
||||
if s.BeaconDB == nil {
|
||||
httputil.HandleError(w, "Could not retrieve beaconDB", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
eth1data, err := s.BeaconDB.ExecutionChainData(ctx)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not retrieve execution chain data: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if eth1data == nil {
|
||||
httputil.HandleError(w, "Could not retrieve execution chain data: empty Eth1Data", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
snapshot := eth1data.DepositSnapshot
|
||||
if snapshot == nil || len(snapshot.Finalized) == 0 {
|
||||
httputil.HandleError(w, "No Finalized Snapshot Available", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if len(snapshot.Finalized) > depositsnapshot.DepositContractDepth {
|
||||
httputil.HandleError(w, "Retrieved invalid deposit snapshot", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if httputil.RespondWithSsz(r) {
|
||||
sszData, err := snapshot.MarshalSSZ()
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not marshal deposit snapshot into SSZ: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
httputil.WriteSsz(w, sszData, "deposit_snapshot.ssz")
|
||||
return
|
||||
}
|
||||
httputil.WriteJson(
|
||||
w,
|
||||
&structs.GetDepositSnapshotResponse{
|
||||
Data: structs.DepositSnapshotFromConsensus(snapshot),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/api"
|
||||
"github.com/prysmaticlabs/prysm/v4/api/server/structs"
|
||||
chainMock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositsnapshot"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
|
||||
dbTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
|
||||
@@ -3617,3 +3618,64 @@ func TestGetGenesis(t *testing.T) {
|
||||
assert.StringContains(t, "Chain genesis info is not yet known", e.Message)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetDepositSnapshot(t *testing.T) {
|
||||
beaconDB := dbTest.SetupDB(t)
|
||||
mockTrie := depositsnapshot.NewDepositTree()
|
||||
deposits := [][32]byte{
|
||||
bytesutil.ToBytes32([]byte{1}),
|
||||
bytesutil.ToBytes32([]byte{2}),
|
||||
bytesutil.ToBytes32([]byte{3}),
|
||||
}
|
||||
finalized := 2
|
||||
for _, leaf := range deposits {
|
||||
err := mockTrie.Insert(leaf[:], 0)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err := mockTrie.Finalize(1, deposits[1], 1)
|
||||
require.NoError(t, err)
|
||||
err = mockTrie.Finalize(2, deposits[2], 2)
|
||||
require.NoError(t, err)
|
||||
|
||||
snapshot, err := mockTrie.GetSnapshot()
|
||||
require.NoError(t, err)
|
||||
root, err := snapshot.CalculateRoot()
|
||||
require.NoError(t, err)
|
||||
chainData := ð.ETH1ChainData{
|
||||
DepositSnapshot: snapshot.ToProto(),
|
||||
}
|
||||
err = beaconDB.SaveExecutionChainData(context.Background(), chainData)
|
||||
require.NoError(t, err)
|
||||
s := Server{
|
||||
BeaconDB: beaconDB,
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodGet, "/eth/v1/beacon/deposit_snapshot", nil)
|
||||
writer := httptest.NewRecorder()
|
||||
t.Run("JSON response", func(t *testing.T) {
|
||||
writer.Body = &bytes.Buffer{}
|
||||
s.GetDepositSnapshot(writer, request)
|
||||
assert.Equal(t, http.StatusOK, writer.Code)
|
||||
resp := &structs.GetDepositSnapshotResponse{}
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||
require.NotNil(t, resp.Data)
|
||||
|
||||
assert.Equal(t, hexutil.Encode(root[:]), resp.Data.DepositRoot)
|
||||
assert.Equal(t, hexutil.Encode(deposits[2][:]), resp.Data.ExecutionBlockHash)
|
||||
assert.Equal(t, strconv.Itoa(mockTrie.NumOfItems()), resp.Data.DepositCount)
|
||||
assert.Equal(t, finalized, len(resp.Data.Finalized))
|
||||
})
|
||||
t.Run("SSZ response", func(t *testing.T) {
|
||||
writer.Body = &bytes.Buffer{}
|
||||
request.Header.Set("Accept", api.OctetStreamMediaType)
|
||||
s.GetDepositSnapshot(writer, request)
|
||||
assert.Equal(t, http.StatusOK, writer.Code)
|
||||
resp := ð.DepositSnapshot{}
|
||||
require.NoError(t, resp.UnmarshalSSZ(writer.Body.Bytes()))
|
||||
|
||||
assert.Equal(t, hexutil.Encode(root[:]), hexutil.Encode(resp.DepositRoot))
|
||||
assert.Equal(t, hexutil.Encode(deposits[2][:]), hexutil.Encode(resp.ExecutionHash))
|
||||
assert.Equal(t, uint64(mockTrie.NumOfItems()), resp.DepositCount)
|
||||
assert.Equal(t, finalized, len(resp.Finalized))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ go_test(
|
||||
"//beacon-chain/db/filesystem:go_default_library",
|
||||
"//beacon-chain/db/testing:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//beacon-chain/rpc/testutil:go_default_library",
|
||||
"//beacon-chain/verification:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/api/server/structs"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/filesystem"
|
||||
testDB "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/verification"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/network/httputil"
|
||||
@@ -71,8 +73,11 @@ func TestBlobs(t *testing.T) {
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{Root: blockRoot[:]},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
@@ -116,8 +121,11 @@ func TestBlobs(t *testing.T) {
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
@@ -137,8 +145,11 @@ func TestBlobs(t *testing.T) {
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{CurrentJustifiedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
@@ -157,7 +168,10 @@ func TestBlobs(t *testing.T) {
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
BeaconDB: db,
|
||||
BeaconDB: db,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
@@ -177,7 +191,10 @@ func TestBlobs(t *testing.T) {
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
BeaconDB: db,
|
||||
BeaconDB: db,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
@@ -198,8 +215,11 @@ func TestBlobs(t *testing.T) {
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
@@ -225,8 +245,11 @@ func TestBlobs(t *testing.T) {
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: filesystem.NewEphemeralBlobStorage(t), // new ephemeral storage
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: filesystem.NewEphemeralBlobStorage(t), // new ephemeral storage
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
@@ -238,6 +261,59 @@ func TestBlobs(t *testing.T) {
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||
require.Equal(t, len(resp.Data), 0)
|
||||
})
|
||||
t.Run("outside retention period returns 200 w/ empty list ", func(t *testing.T) {
|
||||
u := "http://foo.example/123"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
moc := &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: moc,
|
||||
GenesisTimeFetcher: moc, // genesis time is set to 0 here, so it results in current epoch being extremely large
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
}
|
||||
|
||||
s.Blobs(writer, request)
|
||||
|
||||
assert.Equal(t, http.StatusOK, writer.Code)
|
||||
resp := &structs.SidecarsResponse{}
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||
require.Equal(t, 0, len(resp.Data))
|
||||
})
|
||||
t.Run("block without commitments returns 200 w/empty list ", func(t *testing.T) {
|
||||
denebBlock, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, 333, 0)
|
||||
commitments, err := denebBlock.Block().Body().BlobKzgCommitments()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(commitments), 0)
|
||||
require.NoError(t, db.SaveBlock(context.Background(), denebBlock))
|
||||
|
||||
u := "http://foo.example/333"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
}
|
||||
|
||||
s.Blobs(writer, request)
|
||||
|
||||
assert.Equal(t, http.StatusOK, writer.Code)
|
||||
resp := &structs.SidecarsResponse{}
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||
require.Equal(t, 0, len(resp.Data))
|
||||
})
|
||||
t.Run("slot before Deneb fork", func(t *testing.T) {
|
||||
u := "http://foo.example/31"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
@@ -282,8 +358,11 @@ func TestBlobs(t *testing.T) {
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
|
||||
@@ -47,9 +47,10 @@ type Blocker interface {
|
||||
|
||||
// BeaconDbBlocker is an implementation of Blocker. It retrieves blocks from the beacon chain database.
|
||||
type BeaconDbBlocker struct {
|
||||
BeaconDB db.ReadOnlyDatabase
|
||||
ChainInfoFetcher blockchain.ChainInfoFetcher
|
||||
BlobStorage *filesystem.BlobStorage
|
||||
BeaconDB db.ReadOnlyDatabase
|
||||
ChainInfoFetcher blockchain.ChainInfoFetcher
|
||||
GenesisTimeFetcher blockchain.TimeFetcher
|
||||
BlobStorage *filesystem.BlobStorage
|
||||
}
|
||||
|
||||
// Block returns the beacon block for a given identifier. The identifier can be one of:
|
||||
@@ -139,6 +140,13 @@ func (p *BeaconDbBlocker) Block(ctx context.Context, id []byte) (interfaces.Read
|
||||
// - <slot>
|
||||
// - <hex encoded block root with '0x' prefix>
|
||||
// - <block root>
|
||||
//
|
||||
// cases:
|
||||
// - no block, 404
|
||||
// - block exists, no commitment, 200 w/ empty list
|
||||
// - block exists, has commitments, inside retention period (greater of protocol- or user-specified) serve then w/ 200 unless we hit an error reading them.
|
||||
// we are technically not supposed to import a block to forkchoice unless we have the blobs, so the nuance here is if we can't find the file and we are inside the protocol-defined retention period, then it's actually a 500.
|
||||
// - block exists, has commitments, outside retention period (greater of protocol- or user-specified) - ie just like block exists, no commitment
|
||||
func (p *BeaconDbBlocker) Blobs(ctx context.Context, id string, indices []uint64) ([]*blocks.VerifiedROBlob, *core.RpcError) {
|
||||
var root []byte
|
||||
switch id {
|
||||
@@ -207,7 +215,25 @@ func (p *BeaconDbBlocker) Blobs(ctx context.Context, id string, indices []uint64
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !p.BeaconDB.HasBlock(ctx, bytesutil.ToBytes32(root)) {
|
||||
return nil, &core.RpcError{Err: errors.New("block not found"), Reason: core.NotFound}
|
||||
}
|
||||
b, err := p.BeaconDB.Block(ctx, bytesutil.ToBytes32(root))
|
||||
if err != nil {
|
||||
return nil, &core.RpcError{Err: errors.Wrap(err, "failed to retrieve block from db"), Reason: core.Internal}
|
||||
}
|
||||
// if block is not in the retention window return 200 w/ empty list
|
||||
if !params.WithinDAPeriod(slots.ToEpoch(b.Block().Slot()), slots.ToEpoch(p.GenesisTimeFetcher.CurrentSlot())) {
|
||||
return make([]*blocks.VerifiedROBlob, 0), nil
|
||||
}
|
||||
commitments, err := b.Block().Body().BlobKzgCommitments()
|
||||
if err != nil {
|
||||
return nil, &core.RpcError{Err: errors.Wrap(err, "failed to retrieve kzg commitments from block"), Reason: core.Internal}
|
||||
}
|
||||
// if there are no commitments return 200 w/ empty list
|
||||
if len(commitments) == 0 {
|
||||
return make([]*blocks.VerifiedROBlob, 0), nil
|
||||
}
|
||||
if len(indices) == 0 {
|
||||
m, err := p.BlobStorage.Indices(bytesutil.ToBytes32(root))
|
||||
if err != nil {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
mockChain "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
||||
@@ -180,8 +181,11 @@ func TestGetBlob(t *testing.T) {
|
||||
t.Run("head", func(t *testing.T) {
|
||||
blocker := &BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{Root: blockRoot[:]},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
verifiedBlobs, rpcErr := blocker.Blobs(ctx, "head", nil)
|
||||
assert.Equal(t, rpcErr == nil, true)
|
||||
@@ -214,8 +218,11 @@ func TestGetBlob(t *testing.T) {
|
||||
t.Run("finalized", func(t *testing.T) {
|
||||
blocker := &BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
|
||||
verifiedBlobs, rpcErr := blocker.Blobs(ctx, "finalized", nil)
|
||||
@@ -225,8 +232,11 @@ func TestGetBlob(t *testing.T) {
|
||||
t.Run("justified", func(t *testing.T) {
|
||||
blocker := &BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{CurrentJustifiedCheckPoint: ðpbalpha.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
|
||||
verifiedBlobs, rpcErr := blocker.Blobs(ctx, "justified", nil)
|
||||
@@ -235,6 +245,9 @@ func TestGetBlob(t *testing.T) {
|
||||
})
|
||||
t.Run("root", func(t *testing.T) {
|
||||
blocker := &BeaconDbBlocker{
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
@@ -244,6 +257,9 @@ func TestGetBlob(t *testing.T) {
|
||||
})
|
||||
t.Run("slot", func(t *testing.T) {
|
||||
blocker := &BeaconDbBlocker{
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
@@ -254,8 +270,11 @@ func TestGetBlob(t *testing.T) {
|
||||
t.Run("one blob only", func(t *testing.T) {
|
||||
blocker := &BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
verifiedBlobs, rpcErr := blocker.Blobs(ctx, "123", []uint64{2})
|
||||
assert.Equal(t, rpcErr == nil, true)
|
||||
@@ -270,8 +289,11 @@ func TestGetBlob(t *testing.T) {
|
||||
t.Run("no blobs returns an empty array", func(t *testing.T) {
|
||||
blocker := &BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ðpbalpha.Checkpoint{Root: blockRoot[:]}},
|
||||
BeaconDB: db,
|
||||
BlobStorage: filesystem.NewEphemeralBlobStorage(t),
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: filesystem.NewEphemeralBlobStorage(t),
|
||||
}
|
||||
verifiedBlobs, rpcErr := blocker.Blobs(ctx, "123", nil)
|
||||
assert.Equal(t, rpcErr == nil, true)
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/ssz"
|
||||
"github.com/prysmaticlabs/prysm/v4/math"
|
||||
"github.com/prysmaticlabs/prysm/v4/monitoring/tracing"
|
||||
"github.com/prysmaticlabs/prysm/v4/network/forks"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
@@ -231,7 +232,7 @@ func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot primitiv
|
||||
}
|
||||
|
||||
l := log.WithFields(logrus.Fields{
|
||||
"value": v.String(),
|
||||
"gweiValue": math.WeiToGwei(v),
|
||||
"builderPubKey": fmt.Sprintf("%#x", bid.Pubkey()),
|
||||
"blockHash": fmt.Sprintf("%#x", header.BlockHash()),
|
||||
"slot": slot,
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/gorilla/mux"
|
||||
middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
||||
@@ -21,6 +23,11 @@ import (
|
||||
beaconprysm "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/beacon"
|
||||
nodeprysm "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/node"
|
||||
validatorprysm "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/proposer"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
proposersettings "github.com/prysmaticlabs/prysm/v4/proto/prysm/config"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"google.golang.org/grpc"
|
||||
@@ -57,7 +64,6 @@ import (
|
||||
debugv1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/debug"
|
||||
nodev1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/node"
|
||||
validatorv1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
|
||||
slasherservice "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/startup"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
chainSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
|
||||
@@ -112,7 +118,6 @@ type Config struct {
|
||||
AttestationsPool attestations.Pool
|
||||
ExitPool voluntaryexits.PoolManager
|
||||
SlashingsPool slashings.PoolManager
|
||||
SlashingChecker slasherservice.SlashingChecker
|
||||
SyncCommitteeObjectPool synccommittee.Pool
|
||||
BLSChangesPool blstoexec.PoolManager
|
||||
SyncService chainSync.Checker
|
||||
@@ -135,6 +140,7 @@ type Config struct {
|
||||
BlobStorage *filesystem.BlobStorage
|
||||
TrackedValidatorsCache *cache.TrackedValidatorsCache
|
||||
PayloadIDCache *cache.PayloadIDCache
|
||||
ProposerSettings *proposersettings.ProposerSettingsPayload
|
||||
}
|
||||
|
||||
// NewService instantiates a new RPC service instance that will
|
||||
@@ -256,6 +262,7 @@ func (s *Service) initializeBeaconServerRoutes(beaconServer *beacon.Server) {
|
||||
s.cfg.Router.HandleFunc("/eth/v1/beacon/blocks/{block_id}/attestations", beaconServer.GetBlockAttestations).Methods(http.MethodGet)
|
||||
s.cfg.Router.HandleFunc("/eth/v1/beacon/blinded_blocks/{block_id}", beaconServer.GetBlindedBlock).Methods(http.MethodGet)
|
||||
s.cfg.Router.HandleFunc("/eth/v1/beacon/blocks/{block_id}/root", beaconServer.GetBlockRoot).Methods(http.MethodGet)
|
||||
s.cfg.Router.HandleFunc("/eth/v1/beacon/deposit_snapshot", beaconServer.GetDepositSnapshot).Methods(http.MethodGet)
|
||||
s.cfg.Router.HandleFunc("/eth/v1/beacon/pool/attestations", beaconServer.ListAttestations).Methods(http.MethodGet)
|
||||
s.cfg.Router.HandleFunc("/eth/v1/beacon/pool/attestations", beaconServer.SubmitAttestations).Methods(http.MethodPost)
|
||||
s.cfg.Router.HandleFunc("/eth/v1/beacon/pool/voluntary_exits", beaconServer.ListVoluntaryExits).Methods(http.MethodGet)
|
||||
@@ -335,9 +342,10 @@ func (s *Service) Start() {
|
||||
ReplayerBuilder: ch,
|
||||
}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
BeaconDB: s.cfg.BeaconDB,
|
||||
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
||||
BlobStorage: s.cfg.BlobStorage,
|
||||
BeaconDB: s.cfg.BeaconDB,
|
||||
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
||||
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
|
||||
BlobStorage: s.cfg.BlobStorage,
|
||||
}
|
||||
rewardFetcher := &rewards.BlockRewardService{Replayer: ch}
|
||||
|
||||
@@ -373,6 +381,11 @@ func (s *Service) Start() {
|
||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||
}
|
||||
|
||||
// update the tracked validator cache before starting servers
|
||||
if err := updateTrackValidatorCacheWithProposerSettings(s.ctx, s.cfg.SyncService, s.cfg.ChainInfoFetcher, s.cfg.ProposerSettings, s.cfg.TrackedValidatorsCache); err != nil {
|
||||
log.WithError(err).Errorf("Could NOT update tracked validator cache with proposer settings")
|
||||
}
|
||||
|
||||
validatorServer := &validatorv1alpha1.Server{
|
||||
Ctx: s.ctx,
|
||||
AttPool: s.cfg.AttestationsPool,
|
||||
@@ -599,6 +612,67 @@ func (s *Service) Start() {
|
||||
}()
|
||||
}
|
||||
|
||||
func updateTrackValidatorCacheWithProposerSettings(ctx context.Context, syncChecker chainSync.Checker, chain blockchain.ChainInfoFetcher, settings *proposersettings.ProposerSettingsPayload, tackedValidatorCache *cache.TrackedValidatorsCache) error {
|
||||
if settings == nil {
|
||||
return nil
|
||||
}
|
||||
if !syncChecker.Synced() {
|
||||
log.Warning("proposer cache is updating while the chain is not fully synced, using head state for validator information")
|
||||
}
|
||||
if settings.ProposerConfig != nil {
|
||||
st, err := chain.HeadState(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
builderSettingsProvided := false
|
||||
for key, option := range settings.ProposerConfig {
|
||||
decodedKey, err := hexutil.Decode(key)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not decode public key %s", key)
|
||||
}
|
||||
if len(decodedKey) != fieldparams.BLSPubkeyLength {
|
||||
return fmt.Errorf("%v is not a bls public key", key)
|
||||
}
|
||||
if err := proposer.VerifyOption(key, option); err != nil {
|
||||
return err
|
||||
}
|
||||
validatorIndex, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(decodedKey))
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
tackedValidatorCache.Set(cache.TrackedValidator{
|
||||
Active: true, // TODO: either check or add the field in the request
|
||||
Index: validatorIndex,
|
||||
FeeRecipient: primitives.ExecutionAddress(common.HexToAddress(option.FeeRecipient).Bytes()),
|
||||
})
|
||||
if option.Builder != nil {
|
||||
builderSettingsProvided = true
|
||||
}
|
||||
}
|
||||
if builderSettingsProvided {
|
||||
log.Warning("builder settings will be ignored. please provide proposer settings in the validator client to register validators")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if settings.DefaultConfig != nil {
|
||||
if settings.DefaultConfig.FeeRecipient == "" {
|
||||
return errors.New("default fee recipient cannot be empty")
|
||||
}
|
||||
if !common.IsHexAddress(settings.DefaultConfig.FeeRecipient) {
|
||||
return errors.New("fee recipient is not a valid eth1 address")
|
||||
}
|
||||
if err := proposer.WarnNonChecksummedAddress(settings.DefaultConfig.FeeRecipient); err != nil {
|
||||
return err
|
||||
}
|
||||
if settings.DefaultConfig.Builder != nil {
|
||||
log.Warning("builder settings will be ignored. please provide proposer settings in the validator client to register validators")
|
||||
}
|
||||
log.Warning("no public keys provided, proposer cache is not updated from proposer settings file")
|
||||
params.BeaconConfig().DefaultFeeRecipient = common.HexToAddress(settings.DefaultConfig.FeeRecipient)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop the service.
|
||||
func (s *Service) Stop() error {
|
||||
s.cancel()
|
||||
|
||||
@@ -5,11 +5,15 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
|
||||
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
mockExecution "github.com/prysmaticlabs/prysm/v4/beacon-chain/execution/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/blob"
|
||||
@@ -24,9 +28,15 @@ import (
|
||||
nodeprysm "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/node"
|
||||
validatorprysm "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/startup"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
|
||||
mockSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
proposersettings "github.com/prysmaticlabs/prysm/v4/proto/prysm/config"
|
||||
ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
@@ -93,20 +103,20 @@ func TestServer_InitializeRoutes(t *testing.T) {
|
||||
"/eth/v1/beacon/blocks/{block_id}/attestations": {http.MethodGet},
|
||||
"/eth/v1/beacon/blob_sidecars/{block_id}": {http.MethodGet},
|
||||
"/eth/v1/beacon/rewards/sync_committee/{block_id}": {http.MethodPost},
|
||||
//"/eth/v1/beacon/deposit_snapshot": {http.MethodGet}, not implemented
|
||||
"/eth/v1/beacon/rewards/blocks/{block_id}": {http.MethodGet},
|
||||
"/eth/v1/beacon/rewards/attestations/{epoch}": {http.MethodPost},
|
||||
"/eth/v1/beacon/blinded_blocks/{block_id}": {http.MethodGet},
|
||||
"/eth/v1/beacon/light_client/bootstrap/{block_root}": {http.MethodGet},
|
||||
"/eth/v1/beacon/light_client/updates": {http.MethodGet},
|
||||
"/eth/v1/beacon/light_client/finality_update": {http.MethodGet},
|
||||
"/eth/v1/beacon/light_client/optimistic_update": {http.MethodGet},
|
||||
"/eth/v1/beacon/pool/attestations": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/pool/attester_slashings": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/pool/proposer_slashings": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/pool/sync_committees": {http.MethodPost},
|
||||
"/eth/v1/beacon/pool/voluntary_exits": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/pool/bls_to_execution_changes": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/deposit_snapshot": {http.MethodGet},
|
||||
"/eth/v1/beacon/rewards/blocks/{block_id}": {http.MethodGet},
|
||||
"/eth/v1/beacon/rewards/attestations/{epoch}": {http.MethodPost},
|
||||
"/eth/v1/beacon/blinded_blocks/{block_id}": {http.MethodGet},
|
||||
"/eth/v1/beacon/light_client/bootstrap/{block_root}": {http.MethodGet},
|
||||
"/eth/v1/beacon/light_client/updates": {http.MethodGet},
|
||||
"/eth/v1/beacon/light_client/finality_update": {http.MethodGet},
|
||||
"/eth/v1/beacon/light_client/optimistic_update": {http.MethodGet},
|
||||
"/eth/v1/beacon/pool/attestations": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/pool/attester_slashings": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/pool/proposer_slashings": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/pool/sync_committees": {http.MethodPost},
|
||||
"/eth/v1/beacon/pool/voluntary_exits": {http.MethodGet, http.MethodPost},
|
||||
"/eth/v1/beacon/pool/bls_to_execution_changes": {http.MethodGet, http.MethodPost},
|
||||
}
|
||||
|
||||
builderRoutes := map[string][]string{
|
||||
@@ -254,3 +264,167 @@ func TestRPC_InsecureEndpoint(t *testing.T) {
|
||||
require.LogsContain(t, hook, "You are using an insecure gRPC server")
|
||||
assert.NoError(t, rpcService.Stop())
|
||||
}
|
||||
|
||||
func Test_updateTrackValidatorCacheWithProposerSettings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setup func() (sync.Checker, blockchain.ChainInfoFetcher, *proposersettings.ProposerSettingsPayload)
|
||||
verify func(t *testing.T, settings *proposersettings.ProposerSettingsPayload, tackedValidatorCache *cache.TrackedValidatorsCache, err error)
|
||||
}{
|
||||
{
|
||||
name: "proposer settings empty",
|
||||
setup: func() (sync.Checker, blockchain.ChainInfoFetcher, *proposersettings.ProposerSettingsPayload) {
|
||||
key := "0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"
|
||||
pubkey1decoded, err := hexutil.Decode(key)
|
||||
require.NoError(t, err)
|
||||
st, err := util.NewBeaconStateDeneb(util.FillRootsNaturalOptDeneb, func(state *ethpbalpha.BeaconStateDeneb) error {
|
||||
state.Validators = []*ethpbalpha.Validator{{
|
||||
PublicKey: pubkey1decoded,
|
||||
WithdrawalCredentials: bytesutil.PadTo([]byte("withdrawalcredentials"), 32),
|
||||
EffectiveBalance: 9,
|
||||
Slashed: true,
|
||||
ActivationEligibilityEpoch: 10,
|
||||
ActivationEpoch: 11,
|
||||
ExitEpoch: 12,
|
||||
WithdrawableEpoch: 13,
|
||||
}}
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return &mockSync.Sync{IsSynced: true},
|
||||
&mock.ChainService{
|
||||
State: st,
|
||||
}, nil
|
||||
},
|
||||
verify: func(t *testing.T, settings *proposersettings.ProposerSettingsPayload, tackedValidatorCache *cache.TrackedValidatorsCache, err error) {
|
||||
require.NoError(t, err)
|
||||
_, ok := tackedValidatorCache.Validator(0)
|
||||
require.Equal(t, ok, false)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "proposer settings filled and chain is synced",
|
||||
setup: func() (sync.Checker, blockchain.ChainInfoFetcher, *proposersettings.ProposerSettingsPayload) {
|
||||
key := "0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"
|
||||
pubkey1decoded, err := hexutil.Decode(key)
|
||||
require.NoError(t, err)
|
||||
st, err := util.NewBeaconStateDeneb(util.FillRootsNaturalOptDeneb, func(state *ethpbalpha.BeaconStateDeneb) error {
|
||||
state.Validators = []*ethpbalpha.Validator{{
|
||||
PublicKey: pubkey1decoded,
|
||||
WithdrawalCredentials: bytesutil.PadTo([]byte("withdrawalcredentials"), 32),
|
||||
EffectiveBalance: 9,
|
||||
Slashed: true,
|
||||
ActivationEligibilityEpoch: 10,
|
||||
ActivationEpoch: 11,
|
||||
ExitEpoch: 12,
|
||||
WithdrawableEpoch: 13,
|
||||
}}
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return &mockSync.Sync{IsSynced: true},
|
||||
&mock.ChainService{
|
||||
State: st,
|
||||
},
|
||||
&proposersettings.ProposerSettingsPayload{
|
||||
ProposerConfig: map[string]*proposersettings.ProposerOptionPayload{
|
||||
key: {
|
||||
FeeRecipient: "0x967646dCD8d34F4E02204faeDcbAe0cC96fB9245",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
verify: func(t *testing.T, settings *proposersettings.ProposerSettingsPayload, tackedValidatorCache *cache.TrackedValidatorsCache, err error) {
|
||||
require.NoError(t, err)
|
||||
tr, ok := tackedValidatorCache.Validator(0)
|
||||
require.Equal(t, ok, true)
|
||||
require.StringContains(t, strings.ToLower(hexutil.Encode(tr.FeeRecipient[:])), strings.ToLower("0x967646dCD8d34F4E02204faeDcbAe0cC96fB9245"))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "proposer settings filled with non active or non matching key and chain is synced",
|
||||
setup: func() (sync.Checker, blockchain.ChainInfoFetcher, *proposersettings.ProposerSettingsPayload) {
|
||||
key := "0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"
|
||||
|
||||
key2 := "0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44b"
|
||||
pubkey2decoded, err := hexutil.Decode(key2)
|
||||
require.NoError(t, err)
|
||||
st, err := util.NewBeaconStateDeneb(util.FillRootsNaturalOptDeneb, func(state *ethpbalpha.BeaconStateDeneb) error {
|
||||
state.Validators = []*ethpbalpha.Validator{{
|
||||
PublicKey: pubkey2decoded,
|
||||
WithdrawalCredentials: bytesutil.PadTo([]byte("withdrawalcredentials"), 32),
|
||||
EffectiveBalance: 9,
|
||||
Slashed: true,
|
||||
ActivationEligibilityEpoch: 10,
|
||||
ActivationEpoch: 11,
|
||||
ExitEpoch: 12,
|
||||
WithdrawableEpoch: 13,
|
||||
}}
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return &mockSync.Sync{IsSynced: true},
|
||||
&mock.ChainService{
|
||||
State: st,
|
||||
},
|
||||
&proposersettings.ProposerSettingsPayload{
|
||||
ProposerConfig: map[string]*proposersettings.ProposerOptionPayload{
|
||||
key: {
|
||||
FeeRecipient: "0x967646dCD8d34F4E02204faeDcbAe0cC96fB9245",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
verify: func(t *testing.T, settings *proposersettings.ProposerSettingsPayload, tackedValidatorCache *cache.TrackedValidatorsCache, err error) {
|
||||
require.NoError(t, err)
|
||||
_, ok := tackedValidatorCache.Validator(0)
|
||||
require.Equal(t, ok, false)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "default proposer settings filled and chain is synced",
|
||||
setup: func() (sync.Checker, blockchain.ChainInfoFetcher, *proposersettings.ProposerSettingsPayload) {
|
||||
key := "0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"
|
||||
pubkey1decoded, err := hexutil.Decode(key)
|
||||
require.NoError(t, err)
|
||||
st, err := util.NewBeaconStateDeneb(util.FillRootsNaturalOptDeneb, func(state *ethpbalpha.BeaconStateDeneb) error {
|
||||
state.Validators = []*ethpbalpha.Validator{{
|
||||
PublicKey: pubkey1decoded,
|
||||
WithdrawalCredentials: bytesutil.PadTo([]byte("withdrawalcredentials"), 32),
|
||||
EffectiveBalance: 9,
|
||||
Slashed: true,
|
||||
ActivationEligibilityEpoch: 10,
|
||||
ActivationEpoch: 11,
|
||||
ExitEpoch: 12,
|
||||
WithdrawableEpoch: 13,
|
||||
}}
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return &mockSync.Sync{IsSynced: true},
|
||||
&mock.ChainService{
|
||||
State: st,
|
||||
},
|
||||
&proposersettings.ProposerSettingsPayload{
|
||||
DefaultConfig: &proposersettings.ProposerOptionPayload{
|
||||
FeeRecipient: "0x967646dCD8d34F4E02204faeDcbAe0cC96fB9245",
|
||||
},
|
||||
}
|
||||
},
|
||||
verify: func(t *testing.T, settings *proposersettings.ProposerSettingsPayload, tackedValidatorCache *cache.TrackedValidatorsCache, err error) {
|
||||
require.NoError(t, err)
|
||||
_, ok := tackedValidatorCache.Validator(0)
|
||||
require.Equal(t, ok, false)
|
||||
require.Equal(t, params.BeaconConfig().DefaultFeeRecipient.String(), "0x967646dCD8d34F4E02204faeDcbAe0cC96fB9245")
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := cache.NewTrackedValidatorsCache()
|
||||
syncChecker, chain, settings := tt.setup()
|
||||
err := updateTrackValidatorCacheWithProposerSettings(context.Background(), syncChecker, chain, settings, c)
|
||||
tt.verify(t, settings, c, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ go_library(
|
||||
"process_slashings.go",
|
||||
"queue.go",
|
||||
"receive.go",
|
||||
"rpc.go",
|
||||
"service.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher",
|
||||
@@ -31,7 +30,6 @@ go_library(
|
||||
"//beacon-chain/operations/slashings:go_default_library",
|
||||
"//beacon-chain/slasher/types:go_default_library",
|
||||
"//beacon-chain/startup:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
@@ -47,8 +45,6 @@ go_library(
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_grpc//codes:go_default_library",
|
||||
"@org_golang_google_grpc//status:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -63,7 +59,6 @@ go_test(
|
||||
"process_slashings_test.go",
|
||||
"queue_test.go",
|
||||
"receive_test.go",
|
||||
"rpc_test.go",
|
||||
"service_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
@@ -82,6 +77,7 @@ go_test(
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//crypto/bls/common:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package slasher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
@@ -10,16 +11,15 @@ import (
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// A struct encapsulating input arguments to
|
||||
// functions used for attester slashing detection and
|
||||
// loading, saving, and updating min/max span chunks.
|
||||
type chunkUpdateArgs struct {
|
||||
kind slashertypes.ChunkKind
|
||||
chunkIndex uint64
|
||||
validatorChunkIndex uint64
|
||||
currentEpoch primitives.Epoch
|
||||
chunkIndex uint64
|
||||
currentEpoch primitives.Epoch
|
||||
}
|
||||
|
||||
// Chunker defines a struct which represents a slice containing a chunk for K different validator's
|
||||
@@ -187,10 +187,10 @@ func (m *MinSpanChunksSlice) CheckSlashable(
|
||||
ctx context.Context,
|
||||
slasherDB db.SlasherDatabase,
|
||||
validatorIdx primitives.ValidatorIndex,
|
||||
attestation *slashertypes.IndexedAttestationWrapper,
|
||||
incomingAttWrapper *slashertypes.IndexedAttestationWrapper,
|
||||
) (*ethpb.AttesterSlashing, error) {
|
||||
sourceEpoch := attestation.IndexedAttestation.Data.Source.Epoch
|
||||
targetEpoch := attestation.IndexedAttestation.Data.Target.Epoch
|
||||
sourceEpoch := incomingAttWrapper.IndexedAttestation.Data.Source.Epoch
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.Data.Target.Epoch
|
||||
|
||||
minTarget, err := chunkDataAtEpoch(m.params, m.data, validatorIdx, sourceEpoch)
|
||||
if err != nil {
|
||||
@@ -199,30 +199,56 @@ func (m *MinSpanChunksSlice) CheckSlashable(
|
||||
)
|
||||
}
|
||||
|
||||
if targetEpoch > minTarget {
|
||||
existingAttRecord, err := slasherDB.AttestationRecordForValidator(
|
||||
ctx, validatorIdx, minTarget,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err, "could not get existing attestation record at target %d", minTarget,
|
||||
)
|
||||
if targetEpoch <= minTarget {
|
||||
// The incoming attestation does not surround any existing ones.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// The incoming attestation surrounds an existing one.
|
||||
existingAttWrapper, err := slasherDB.AttestationRecordForValidator(ctx, validatorIdx, minTarget)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get existing attestation record at target %d", minTarget)
|
||||
}
|
||||
|
||||
if existingAttWrapper == nil {
|
||||
// This case should normally not happen. If this happen, it means we previously
|
||||
// recorded in our min/max DB an distance corresponding to an attestaiton, but WITHOUT
|
||||
// recording the attestation itself. As a consequence, we say there is no surrounding vote,
|
||||
// but we log an error.
|
||||
fields := logrus.Fields{
|
||||
"validatorIndex": validatorIdx,
|
||||
"targetEpoch": minTarget,
|
||||
}
|
||||
|
||||
if existingAttRecord == nil {
|
||||
return nil, nil
|
||||
}
|
||||
log.WithFields(fields).Error("No existing attestation record found while a surrounding vote was detected.")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if sourceEpoch < existingAttRecord.IndexedAttestation.Data.Source.Epoch {
|
||||
surroundingVotesTotal.Inc()
|
||||
return ðpb.AttesterSlashing{
|
||||
Attestation_1: attestation.IndexedAttestation,
|
||||
Attestation_2: existingAttRecord.IndexedAttestation,
|
||||
}, nil
|
||||
if existingAttWrapper.IndexedAttestation.Data.Source.Epoch <= sourceEpoch {
|
||||
// This case should normally not happen, since if we have targetEpoch > minTarget,
|
||||
// then there is at least one attestation we surround.
|
||||
// However, it can happens if we have multiple attestation with the same target
|
||||
// but with a different source. In this case, we have both a double vote AND a surround vote.
|
||||
// The validator will be slashed for the double vote, and the surround vote will be ignored.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
surroundingVotesTotal.Inc()
|
||||
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: incomingAttWrapper.IndexedAttestation,
|
||||
}
|
||||
|
||||
// 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: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: existingAttWrapper.IndexedAttestation,
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
return slashing, nil
|
||||
}
|
||||
|
||||
// CheckSlashable takes in a validator index and an incoming attestation
|
||||
@@ -240,10 +266,10 @@ func (m *MaxSpanChunksSlice) CheckSlashable(
|
||||
ctx context.Context,
|
||||
slasherDB db.SlasherDatabase,
|
||||
validatorIdx primitives.ValidatorIndex,
|
||||
attestation *slashertypes.IndexedAttestationWrapper,
|
||||
incomingAttWrapper *slashertypes.IndexedAttestationWrapper,
|
||||
) (*ethpb.AttesterSlashing, error) {
|
||||
sourceEpoch := attestation.IndexedAttestation.Data.Source.Epoch
|
||||
targetEpoch := attestation.IndexedAttestation.Data.Target.Epoch
|
||||
sourceEpoch := incomingAttWrapper.IndexedAttestation.Data.Source.Epoch
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.Data.Target.Epoch
|
||||
|
||||
maxTarget, err := chunkDataAtEpoch(m.params, m.data, validatorIdx, sourceEpoch)
|
||||
if err != nil {
|
||||
@@ -252,29 +278,56 @@ func (m *MaxSpanChunksSlice) CheckSlashable(
|
||||
)
|
||||
}
|
||||
|
||||
if targetEpoch < maxTarget {
|
||||
existingAttRecord, err := slasherDB.AttestationRecordForValidator(
|
||||
ctx, validatorIdx, maxTarget,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err, "could not get existing attestation record at target %d", maxTarget,
|
||||
)
|
||||
if targetEpoch >= maxTarget {
|
||||
// The incoming attestation is not surrounded by any existing ones.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// The incoming attestation is surrounded by an existing one.
|
||||
existingAttWrapper, err := slasherDB.AttestationRecordForValidator(ctx, validatorIdx, maxTarget)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get existing attestation record at target %d", maxTarget)
|
||||
}
|
||||
|
||||
if existingAttWrapper == nil {
|
||||
// This case should normally not happen. If this happen, it means we previously
|
||||
// recorded in our min/max DB an distance corresponding to an attestaiton, but WITHOUT
|
||||
// recording the attestation itself. As a consequence, we say there is no surrounded vote,
|
||||
// but we log an error.
|
||||
fields := logrus.Fields{
|
||||
"validatorIndex": validatorIdx,
|
||||
"targetEpoch": maxTarget,
|
||||
}
|
||||
|
||||
if existingAttRecord == nil {
|
||||
return nil, nil
|
||||
}
|
||||
log.WithFields(fields).Error("No existing attestation record found while a surrounded vote was detected.")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if existingAttRecord.IndexedAttestation.Data.Source.Epoch < sourceEpoch {
|
||||
surroundedVotesTotal.Inc()
|
||||
return ðpb.AttesterSlashing{
|
||||
Attestation_1: existingAttRecord.IndexedAttestation,
|
||||
Attestation_2: attestation.IndexedAttestation,
|
||||
}, nil
|
||||
if existingAttWrapper.IndexedAttestation.Data.Source.Epoch >= sourceEpoch {
|
||||
// This case should normally not happen, since if we have targetEpoch < maxTarget,
|
||||
// then there is at least one attestation that surrounds us.
|
||||
// However, it can happens if we have multiple attestation with the same target
|
||||
// but with a different source. In this case, we have both a double vote AND a surround vote.
|
||||
// The validator will be slashed for the double vote, and the surround vote will be ignored.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
surroundedVotesTotal.Inc()
|
||||
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: incomingAttWrapper.IndexedAttestation,
|
||||
}
|
||||
|
||||
// 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: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: existingAttWrapper.IndexedAttestation,
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
return slashing, nil
|
||||
}
|
||||
|
||||
// Update a min span chunk for a validator index starting at the current epoch, e_c, then updating
|
||||
@@ -492,13 +545,13 @@ func (m *MinSpanChunksSlice) NextChunkStartEpoch(startEpoch primitives.Epoch) pr
|
||||
// max_spans_val_i = [[-, -, -], [-, -, -], [-, -, -]]
|
||||
//
|
||||
// If C = chunkSize is 3 epochs per chunk, and we input start epoch of chunk 1 which is 3. The next start
|
||||
// epoch is the start epoch of chunk 2, which is epoch 4. This is computed as:
|
||||
// epoch is the start epoch of chunk 2, which is epoch 6. This is computed as:
|
||||
//
|
||||
// first_epoch(chunkIndex(startEpoch)+1)
|
||||
// first_epoch(chunkIndex(3)+1)
|
||||
// first_epoch(1 + 1)
|
||||
// first_epoch(2)
|
||||
// 4
|
||||
// 6
|
||||
func (m *MaxSpanChunksSlice) NextChunkStartEpoch(startEpoch primitives.Epoch) primitives.Epoch {
|
||||
return m.params.firstEpoch(m.params.chunkIndex(startEpoch) + 1)
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ func TestMinSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
validatorIdx := primitives.ValidatorIndex(1)
|
||||
source := primitives.Epoch(1)
|
||||
target := primitives.Epoch(2)
|
||||
att := createAttestationWrapper(t, source, target, nil, nil)
|
||||
att := createAttestationWrapperEmptySig(t, source, target, nil, nil)
|
||||
|
||||
// A faulty chunk should lead to error.
|
||||
chunk := &MinSpanChunksSlice{
|
||||
@@ -126,7 +126,7 @@ func TestMinSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
chunk = EmptyMinSpanChunksSlice(params)
|
||||
source = primitives.Epoch(1)
|
||||
target = primitives.Epoch(2)
|
||||
att = createAttestationWrapper(t, source, target, nil, nil)
|
||||
att = createAttestationWrapperEmptySig(t, source, target, nil, nil)
|
||||
chunkIdx := uint64(0)
|
||||
startEpoch := target
|
||||
currentEpoch := target
|
||||
@@ -141,7 +141,7 @@ func TestMinSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
// 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 := createAttestationWrapper(t, source, target, nil, nil)
|
||||
surroundingVote := createAttestationWrapperEmptySig(t, source, target, nil, nil)
|
||||
|
||||
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundingVote)
|
||||
require.NoError(t, err)
|
||||
@@ -150,7 +150,7 @@ func TestMinSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
// Next up, we save the old attestation record, then check if the
|
||||
// surrounding vote is indeed slashable.
|
||||
attData := att.IndexedAttestation.Data
|
||||
attRecord := createAttestationWrapper(t, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, []byte{1})
|
||||
attRecord := createAttestationWrapperEmptySig(t, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, []byte{1})
|
||||
err = slasherDB.SaveAttestationRecordsForValidators(
|
||||
ctx,
|
||||
[]*slashertypes.IndexedAttestationWrapper{attRecord},
|
||||
@@ -173,7 +173,7 @@ func TestMaxSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
validatorIdx := primitives.ValidatorIndex(1)
|
||||
source := primitives.Epoch(1)
|
||||
target := primitives.Epoch(2)
|
||||
att := createAttestationWrapper(t, source, target, nil, nil)
|
||||
att := createAttestationWrapperEmptySig(t, source, target, nil, nil)
|
||||
|
||||
// A faulty chunk should lead to error.
|
||||
chunk := &MaxSpanChunksSlice{
|
||||
@@ -208,7 +208,7 @@ func TestMaxSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
chunk = EmptyMaxSpanChunksSlice(params)
|
||||
source = primitives.Epoch(0)
|
||||
target = primitives.Epoch(3)
|
||||
att = createAttestationWrapper(t, source, target, nil, nil)
|
||||
att = createAttestationWrapperEmptySig(t, source, target, nil, nil)
|
||||
chunkIdx := uint64(0)
|
||||
startEpoch := source
|
||||
currentEpoch := target
|
||||
@@ -223,7 +223,7 @@ func TestMaxSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
// 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 := createAttestationWrapper(t, source, target, nil, nil)
|
||||
surroundedVote := createAttestationWrapperEmptySig(t, source, target, nil, nil)
|
||||
|
||||
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundedVote)
|
||||
require.NoError(t, err)
|
||||
@@ -233,7 +233,7 @@ func TestMaxSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
// surroundedVote vote is indeed slashable.
|
||||
attData := att.IndexedAttestation.Data
|
||||
signingRoot := [32]byte{1}
|
||||
attRecord := createAttestationWrapper(
|
||||
attRecord := createAttestationWrapperEmptySig(
|
||||
t, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, signingRoot[:],
|
||||
)
|
||||
err = slasherDB.SaveAttestationRecordsForValidators(
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package slasher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher/types"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -17,61 +19,73 @@ import (
|
||||
// found attester slashings to the caller.
|
||||
func (s *Service) checkSlashableAttestations(
|
||||
ctx context.Context, currentEpoch primitives.Epoch, atts []*slashertypes.IndexedAttestationWrapper,
|
||||
) ([]*ethpb.AttesterSlashing, error) {
|
||||
slashings := make([]*ethpb.AttesterSlashing, 0)
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
totalStart := time.Now()
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
|
||||
// Double votes
|
||||
log.Debug("Checking for double votes")
|
||||
start := time.Now()
|
||||
|
||||
doubleVoteSlashings, err := s.checkDoubleVotes(ctx, atts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not check slashable double votes")
|
||||
}
|
||||
|
||||
log.WithField("elapsed", time.Since(start)).Debug("Done checking double votes")
|
||||
slashings = append(slashings, doubleVoteSlashings...)
|
||||
|
||||
for root, slashing := range doubleVoteSlashings {
|
||||
slashings[root] = slashing
|
||||
}
|
||||
|
||||
// Save the attestation records to our database.
|
||||
// If multiple attestations are provided for the same validator index + target epoch combination,
|
||||
// then the first (validator index + target epoch) => signing root) link is kept into the database.
|
||||
if err := s.serviceCfg.Database.SaveAttestationRecordsForValidators(ctx, atts); err != nil {
|
||||
return nil, errors.Wrap(err, couldNotSaveAttRecord)
|
||||
}
|
||||
|
||||
// Surrounding / surrounded votes
|
||||
groupedAtts := s.groupByValidatorChunkIndex(atts)
|
||||
log.WithField("numBatches", len(groupedAtts)).Debug("Batching attestations by validator chunk index")
|
||||
start = time.Now()
|
||||
batchTimes := make([]time.Duration, 0, len(groupedAtts))
|
||||
groupedByValidatorChunkIndexAtts := s.groupByValidatorChunkIndex(atts)
|
||||
log.WithField("numBatches", len(groupedByValidatorChunkIndexAtts)).Debug("Batching attestations by validator chunk index")
|
||||
groupsCount := len(groupedByValidatorChunkIndexAtts)
|
||||
|
||||
for validatorChunkIdx, batch := range groupedAtts {
|
||||
innerStart := time.Now()
|
||||
surroundStart := time.Now()
|
||||
|
||||
attSlashings, err := s.checkSurrounds(ctx, &chunkUpdateArgs{
|
||||
validatorChunkIndex: validatorChunkIdx,
|
||||
currentEpoch: currentEpoch,
|
||||
}, batch)
|
||||
for validatorChunkIndex, attestations := range groupedByValidatorChunkIndexAtts {
|
||||
// The fact that we use always slashertypes.MinSpan is probably the root cause of
|
||||
// https://github.com/prysmaticlabs/prysm/issues/13591
|
||||
surroundSlashings, err := s.checkSurrounds(ctx, attestations, slashertypes.MinSpan, currentEpoch, validatorChunkIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slashings = append(slashings, attSlashings...)
|
||||
for root, slashing := range surroundSlashings {
|
||||
slashings[root] = slashing
|
||||
}
|
||||
|
||||
indices := s.params.validatorIndicesInChunk(validatorChunkIdx)
|
||||
indices := s.params.validatorIndexesInChunk(validatorChunkIndex)
|
||||
for _, idx := range indices {
|
||||
s.latestEpochWrittenForValidator[idx] = currentEpoch
|
||||
}
|
||||
|
||||
batchTimes = append(batchTimes, time.Since(innerStart))
|
||||
}
|
||||
|
||||
avgProcessingTimePerBatch := time.Duration(0)
|
||||
for _, dur := range batchTimes {
|
||||
avgProcessingTimePerBatch += dur
|
||||
}
|
||||
surroundElapsed := time.Since(surroundStart)
|
||||
totalElapsed := time.Since(totalStart)
|
||||
|
||||
if avgProcessingTimePerBatch != time.Duration(0) {
|
||||
avgProcessingTimePerBatch = avgProcessingTimePerBatch / time.Duration(len(batchTimes))
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
fields := logrus.Fields{
|
||||
"numAttestations": len(atts),
|
||||
"numBatchesByValidatorChunkIndex": len(groupedAtts),
|
||||
"elapsed": time.Since(start),
|
||||
"avgBatchProcessingTime": avgProcessingTimePerBatch,
|
||||
}).Info("Done checking slashable attestations")
|
||||
"numBatchesByValidatorChunkIndex": groupsCount,
|
||||
"elapsed": totalElapsed,
|
||||
}
|
||||
|
||||
if groupsCount > 0 {
|
||||
avgProcessingTimePerBatch := surroundElapsed / time.Duration(groupsCount)
|
||||
fields["avgBatchProcessingTime"] = avgProcessingTimePerBatch
|
||||
}
|
||||
|
||||
log.WithFields(fields).Info("Done checking slashable attestations")
|
||||
|
||||
if len(slashings) > 0 {
|
||||
log.WithField("numSlashings", len(slashings)).Warn("Slashable attestation offenses found")
|
||||
@@ -92,119 +106,204 @@ func (s *Service) checkSlashableAttestations(
|
||||
// This function performs a lot of critical actions and is split into smaller helpers for cleanliness.
|
||||
func (s *Service) checkSurrounds(
|
||||
ctx context.Context,
|
||||
args *chunkUpdateArgs,
|
||||
attestations []*slashertypes.IndexedAttestationWrapper,
|
||||
) ([]*ethpb.AttesterSlashing, error) {
|
||||
chunkKind slashertypes.ChunkKind,
|
||||
currentEpoch primitives.Epoch,
|
||||
validatorChunkIndex uint64,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
// Map of updated chunks by chunk index, which will be saved at the end.
|
||||
updatedChunks := make(map[uint64]Chunker)
|
||||
groupedAtts := s.groupByChunkIndex(attestations)
|
||||
validatorIndices := s.params.validatorIndicesInChunk(args.validatorChunkIndex)
|
||||
groupedByChunkIndexAtts := s.groupByChunkIndex(attestations)
|
||||
validatorIndexes := s.params.validatorIndexesInChunk(validatorChunkIndex)
|
||||
|
||||
// Update the min/max span chunks for the change of current epoch.
|
||||
for _, validatorIndex := range validatorIndices {
|
||||
if err := s.epochUpdateForValidator(ctx, args, updatedChunks, validatorIndex); err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err,
|
||||
"could not update validator index chunks %d",
|
||||
validatorIndex,
|
||||
)
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
|
||||
// Update epoch for validators.
|
||||
for _, validatorIndex := range validatorIndexes {
|
||||
// This function modifies `updatedChunks` in place.
|
||||
if err := s.epochUpdateForValidator(ctx, updatedChunks, validatorChunkIndex, chunkKind, currentEpoch, validatorIndex); err != nil {
|
||||
return nil, errors.Wrapf(err, "could not update validator index chunks %d", validatorIndex)
|
||||
}
|
||||
}
|
||||
|
||||
// Update min and max spans and retrieve any detected slashable offenses.
|
||||
surroundingSlashings, err := s.updateSpans(ctx, updatedChunks, &chunkUpdateArgs{
|
||||
kind: slashertypes.MinSpan,
|
||||
validatorChunkIndex: args.validatorChunkIndex,
|
||||
currentEpoch: args.currentEpoch,
|
||||
}, groupedAtts)
|
||||
// Check for surrounding votes.
|
||||
surroundingSlashings, err := s.updateSpans(ctx, updatedChunks, groupedByChunkIndexAtts, slashertypes.MinSpan, validatorChunkIndex, currentEpoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err,
|
||||
"could not update min attestation spans for validator chunk index %d",
|
||||
args.validatorChunkIndex,
|
||||
)
|
||||
return nil, errors.Wrapf(err, "could not update min attestation spans for validator chunk index %d", validatorChunkIndex)
|
||||
}
|
||||
|
||||
surroundedSlashings, err := s.updateSpans(ctx, updatedChunks, &chunkUpdateArgs{
|
||||
kind: slashertypes.MaxSpan,
|
||||
validatorChunkIndex: args.validatorChunkIndex,
|
||||
currentEpoch: args.currentEpoch,
|
||||
}, groupedAtts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err,
|
||||
"could not update max attestation spans for validator chunk index %d",
|
||||
args.validatorChunkIndex,
|
||||
)
|
||||
for root, slashing := range surroundingSlashings {
|
||||
slashings[root] = slashing
|
||||
}
|
||||
|
||||
slashings := make([]*ethpb.AttesterSlashing, 0, len(surroundingSlashings)+len(surroundedSlashings))
|
||||
slashings = append(slashings, surroundingSlashings...)
|
||||
slashings = append(slashings, surroundedSlashings...)
|
||||
if err := s.saveUpdatedChunks(ctx, args, updatedChunks); err != nil {
|
||||
// Check for surrounded votes.
|
||||
surroundedSlashings, err := s.updateSpans(ctx, updatedChunks, groupedByChunkIndexAtts, slashertypes.MaxSpan, validatorChunkIndex, currentEpoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not update max attestation spans for validator chunk index %d", validatorChunkIndex)
|
||||
}
|
||||
|
||||
for root, slashing := range surroundedSlashings {
|
||||
slashings[root] = slashing
|
||||
}
|
||||
|
||||
if err := s.saveUpdatedChunks(ctx, updatedChunks, chunkKind, validatorChunkIndex); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return slashings, nil
|
||||
}
|
||||
|
||||
// Check for double votes in our database given a list of incoming attestations.
|
||||
func (s *Service) checkDoubleVotes(
|
||||
ctx context.Context, attestations []*slashertypes.IndexedAttestationWrapper,
|
||||
) ([]*ethpb.AttesterSlashing, error) {
|
||||
ctx context.Context, incomingAttWrappers []*slashertypes.IndexedAttestationWrapper,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "Slasher.checkDoubleVotesOnDisk")
|
||||
defer span.End()
|
||||
doubleVotes, err := s.serviceCfg.Database.CheckAttesterDoubleVotes(
|
||||
ctx, attestations,
|
||||
)
|
||||
|
||||
type attestationInfo struct {
|
||||
validatorIndex uint64
|
||||
epoch primitives.Epoch
|
||||
}
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
|
||||
// Check each incoming attestation for double votes against other incoming attestations.
|
||||
existingAttWrappers := make(map[attestationInfo]*slashertypes.IndexedAttestationWrapper)
|
||||
|
||||
for _, incomingAttWrapper := range incomingAttWrappers {
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.Data.Target.Epoch
|
||||
|
||||
for _, validatorIndex := range incomingAttWrapper.IndexedAttestation.AttestingIndices {
|
||||
info := attestationInfo{
|
||||
validatorIndex: validatorIndex,
|
||||
epoch: targetEpoch,
|
||||
}
|
||||
|
||||
existingAttWrapper, ok := existingAttWrappers[info]
|
||||
if !ok {
|
||||
// This is the first attestation for this `validator index x epoch` combination.
|
||||
// There is no double vote. This attestation is memoized for future checks.
|
||||
existingAttWrappers[info] = incomingAttWrapper
|
||||
continue
|
||||
}
|
||||
|
||||
if existingAttWrapper.DataRoot == incomingAttWrapper.DataRoot {
|
||||
// Both attestations are the same, this is not a double vote.
|
||||
continue
|
||||
}
|
||||
|
||||
// There is two different attestations for the same `validator index x epoch` combination.
|
||||
// This is a double vote.
|
||||
doubleVotesTotal.Inc()
|
||||
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: incomingAttWrapper.IndexedAttestation,
|
||||
}
|
||||
|
||||
// Ensure the attestation with the lower data root is the first attestation.
|
||||
// It will be useful for comparing with other double votes.
|
||||
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
|
||||
slashing = ðpb.AttesterSlashing{
|
||||
Attestation_1: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: existingAttWrapper.IndexedAttestation,
|
||||
}
|
||||
}
|
||||
|
||||
root, err := slashing.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not hash tree root for attester slashing")
|
||||
}
|
||||
|
||||
slashings[root] = slashing
|
||||
}
|
||||
}
|
||||
|
||||
// Check each incoming attestation for double votes against the database.
|
||||
doubleVotes, err := s.serviceCfg.Database.CheckAttesterDoubleVotes(ctx, incomingAttWrappers)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not retrieve potential double votes from disk")
|
||||
}
|
||||
doubleVoteSlashings := make([]*ethpb.AttesterSlashing, 0)
|
||||
|
||||
for _, doubleVote := range doubleVotes {
|
||||
doubleVotesTotal.Inc()
|
||||
doubleVoteSlashings = append(doubleVoteSlashings, ðpb.AttesterSlashing{
|
||||
Attestation_1: doubleVote.PrevAttestationWrapper.IndexedAttestation,
|
||||
Attestation_2: doubleVote.AttestationWrapper.IndexedAttestation,
|
||||
})
|
||||
|
||||
wrapper_1 := doubleVote.Wrapper_1
|
||||
wrapper_2 := doubleVote.Wrapper_2
|
||||
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: wrapper_1.IndexedAttestation,
|
||||
Attestation_2: wrapper_2.IndexedAttestation,
|
||||
}
|
||||
|
||||
// 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: wrapper_2.IndexedAttestation,
|
||||
Attestation_2: wrapper_1.IndexedAttestation,
|
||||
}
|
||||
}
|
||||
|
||||
root, err := slashing.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not hash tree root for attester slashing")
|
||||
}
|
||||
|
||||
slashings[root] = slashing
|
||||
}
|
||||
return doubleVoteSlashings, nil
|
||||
|
||||
return slashings, nil
|
||||
}
|
||||
|
||||
// This function updates the slashing spans for a given validator for a change in epoch
|
||||
// since the last epoch we have recorded for the validator. For example, if the last epoch a validator
|
||||
// has written is N, and the current epoch is N+5, we update entries in the slashing spans
|
||||
// with their neutral element for epochs N+1 to N+4. This also puts any loaded chunks in a
|
||||
// map used as a cache for further processing and minimizing database reads later on.
|
||||
// This function updates `updatedChunks`, representing the slashing spans for a given validator for
|
||||
// a change in epoch since the last epoch we have recorded for the validator.
|
||||
// For example, if the last epoch a validator has written is N, and the current epoch is N+5,
|
||||
// we update entries in the slashing spans with their neutral element for epochs N+1 to N+4.
|
||||
// This also puts any loaded chunks in a map used as a cache for further processing and minimizing
|
||||
// database reads later on.
|
||||
func (s *Service) epochUpdateForValidator(
|
||||
ctx context.Context,
|
||||
args *chunkUpdateArgs,
|
||||
updatedChunks map[uint64]Chunker,
|
||||
validatorChunkIndex uint64,
|
||||
chunkKind slashertypes.ChunkKind,
|
||||
currentEpoch primitives.Epoch,
|
||||
validatorIndex primitives.ValidatorIndex,
|
||||
) error {
|
||||
epoch := s.latestEpochWrittenForValidator[validatorIndex]
|
||||
if epoch == 0 {
|
||||
var err error
|
||||
|
||||
latestEpochWritten, ok := s.latestEpochWrittenForValidator[validatorIndex]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
for epoch <= args.currentEpoch {
|
||||
chunkIdx := s.params.chunkIndex(epoch)
|
||||
currentChunk, err := s.getChunk(ctx, args, updatedChunks, chunkIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
for latestEpochWritten <= currentEpoch {
|
||||
chunkIndex := s.params.chunkIndex(latestEpochWritten)
|
||||
|
||||
currentChunk, ok := updatedChunks[chunkIndex]
|
||||
if !ok {
|
||||
currentChunk, err = s.getChunk(ctx, chunkKind, validatorChunkIndex, chunkIndex)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get chunk")
|
||||
}
|
||||
}
|
||||
for s.params.chunkIndex(epoch) == chunkIdx && epoch <= args.currentEpoch {
|
||||
|
||||
for s.params.chunkIndex(latestEpochWritten) == chunkIndex && latestEpochWritten <= currentEpoch {
|
||||
if err := setChunkRawDistance(
|
||||
s.params,
|
||||
currentChunk.Chunk(),
|
||||
validatorIndex,
|
||||
epoch,
|
||||
latestEpochWritten,
|
||||
currentChunk.NeutralElement(),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
updatedChunks[chunkIdx] = currentChunk
|
||||
epoch++
|
||||
|
||||
updatedChunks[chunkIndex] = currentChunk
|
||||
latestEpochWritten++
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -219,23 +318,26 @@ func (s *Service) epochUpdateForValidator(
|
||||
func (s *Service) updateSpans(
|
||||
ctx context.Context,
|
||||
updatedChunks map[uint64]Chunker,
|
||||
args *chunkUpdateArgs,
|
||||
attestationsByChunkIdx map[uint64][]*slashertypes.IndexedAttestationWrapper,
|
||||
) ([]*ethpb.AttesterSlashing, error) {
|
||||
attWrapperByChunkIdx map[uint64][]*slashertypes.IndexedAttestationWrapper,
|
||||
kind slashertypes.ChunkKind,
|
||||
validatorChunkIndex uint64,
|
||||
currentEpoch primitives.Epoch,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "Slasher.updateSpans")
|
||||
defer span.End()
|
||||
|
||||
// Apply the attestations to the related chunks and find any
|
||||
// slashings along the way.
|
||||
slashings := make([]*ethpb.AttesterSlashing, 0)
|
||||
for _, attestationBatch := range attestationsByChunkIdx {
|
||||
for _, att := range attestationBatch {
|
||||
for _, validatorIdx := range att.IndexedAttestation.AttestingIndices {
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
|
||||
for _, attWrappers := range attWrapperByChunkIdx {
|
||||
for _, attWrapper := range attWrappers {
|
||||
for _, validatorIdx := range attWrapper.IndexedAttestation.AttestingIndices {
|
||||
validatorIndex := primitives.ValidatorIndex(validatorIdx)
|
||||
computedValidatorChunkIdx := s.params.validatorChunkIndex(validatorIndex)
|
||||
|
||||
// Every validator chunk index represents a range of validators.
|
||||
// If it possible that the validator index in this loop iteration is
|
||||
// It is possible that the validator index in this loop iteration is
|
||||
// not part of the validator chunk index we are updating chunks for.
|
||||
//
|
||||
// For example, if there are 4 validators per validator chunk index,
|
||||
@@ -243,26 +345,28 @@ func (s *Service) updateSpans(
|
||||
// If we see an attestation with attesting indices [3, 4, 5] and we are updating
|
||||
// chunks for validator chunk index 0, only validator index 3 should make
|
||||
// it past this line.
|
||||
if args.validatorChunkIndex != computedValidatorChunkIdx {
|
||||
if validatorChunkIndex != computedValidatorChunkIdx {
|
||||
continue
|
||||
}
|
||||
|
||||
slashing, err := s.applyAttestationForValidator(
|
||||
ctx,
|
||||
args,
|
||||
validatorIndex,
|
||||
updatedChunks,
|
||||
att,
|
||||
ctx, updatedChunks, attWrapper, kind, validatorChunkIndex, validatorIndex, currentEpoch,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err,
|
||||
"could not apply attestation for validator index %d",
|
||||
validatorIndex,
|
||||
)
|
||||
return nil, errors.Wrapf(err, "could not apply attestation for validator index %d", validatorIndex)
|
||||
}
|
||||
if slashing != nil {
|
||||
slashings = append(slashings, slashing)
|
||||
|
||||
if slashing == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
root, err := slashing.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not hash tree root for attester slashing")
|
||||
}
|
||||
|
||||
slashings[root] = slashing
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,22 +381,30 @@ func (s *Service) updateSpans(
|
||||
// source epoch up to its target.
|
||||
func (s *Service) applyAttestationForValidator(
|
||||
ctx context.Context,
|
||||
args *chunkUpdateArgs,
|
||||
validatorIndex primitives.ValidatorIndex,
|
||||
chunksByChunkIdx map[uint64]Chunker,
|
||||
attestation *slashertypes.IndexedAttestationWrapper,
|
||||
chunkKind slashertypes.ChunkKind,
|
||||
validatorChunkIndex uint64,
|
||||
validatorIndex primitives.ValidatorIndex,
|
||||
currentEpoch primitives.Epoch,
|
||||
) (*ethpb.AttesterSlashing, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "Slasher.applyAttestationForValidator")
|
||||
defer span.End()
|
||||
|
||||
var err error
|
||||
|
||||
sourceEpoch := attestation.IndexedAttestation.Data.Source.Epoch
|
||||
targetEpoch := attestation.IndexedAttestation.Data.Target.Epoch
|
||||
|
||||
attestationDistance.Observe(float64(targetEpoch) - float64(sourceEpoch))
|
||||
chunkIndex := s.params.chunkIndex(sourceEpoch)
|
||||
|
||||
chunkIdx := s.params.chunkIndex(sourceEpoch)
|
||||
chunk, err := s.getChunk(ctx, args, chunksByChunkIdx, chunkIdx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get chunk at index %d", chunkIdx)
|
||||
chunk, ok := chunksByChunkIdx[chunkIndex]
|
||||
if !ok {
|
||||
chunk, err = s.getChunk(ctx, chunkKind, validatorChunkIndex, chunkIndex)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get chunk at index %d", chunkIndex)
|
||||
}
|
||||
}
|
||||
|
||||
// Check slashable, if so, return the slashing.
|
||||
@@ -315,7 +427,7 @@ func (s *Service) applyAttestationForValidator(
|
||||
|
||||
// Get the first start epoch for the chunk. If it does not exist or
|
||||
// is not possible based on the input arguments, do not continue with the update.
|
||||
startEpoch, exists := chunk.StartEpoch(sourceEpoch, args.currentEpoch)
|
||||
startEpoch, exists := chunk.StartEpoch(sourceEpoch, currentEpoch)
|
||||
if !exists {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -327,62 +439,67 @@ func (s *Service) applyAttestationForValidator(
|
||||
// the start epoch of the next chunk. We exit once no longer need to
|
||||
// keep updating chunks.
|
||||
for {
|
||||
chunkIdx = s.params.chunkIndex(startEpoch)
|
||||
chunk, err := s.getChunk(ctx, args, chunksByChunkIdx, chunkIdx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get chunk at index %d", chunkIdx)
|
||||
chunkIndex = s.params.chunkIndex(startEpoch)
|
||||
|
||||
chunk, ok := chunksByChunkIdx[chunkIndex]
|
||||
if !ok {
|
||||
chunk, err = s.getChunk(ctx, chunkKind, validatorChunkIndex, chunkIndex)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get chunk at index %d", chunkIndex)
|
||||
}
|
||||
}
|
||||
|
||||
keepGoing, err := chunk.Update(
|
||||
&chunkUpdateArgs{
|
||||
chunkIndex: chunkIdx,
|
||||
currentEpoch: args.currentEpoch,
|
||||
chunkIndex: chunkIndex,
|
||||
currentEpoch: currentEpoch,
|
||||
},
|
||||
validatorIndex,
|
||||
startEpoch,
|
||||
targetEpoch,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err,
|
||||
"could not update chunk at chunk index %d for validator index %d and current epoch %d",
|
||||
chunkIdx,
|
||||
chunkIndex,
|
||||
validatorIndex,
|
||||
args.currentEpoch,
|
||||
currentEpoch,
|
||||
)
|
||||
}
|
||||
|
||||
// We update the chunksByChunkIdx map with the chunk we just updated.
|
||||
chunksByChunkIdx[chunkIdx] = chunk
|
||||
chunksByChunkIdx[chunkIndex] = chunk
|
||||
if !keepGoing {
|
||||
break
|
||||
}
|
||||
|
||||
// Move to first epoch of next chunk if needed.
|
||||
startEpoch = chunk.NextChunkStartEpoch(startEpoch)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Retrieves a chunk at a chunk index from a map. If such chunk does not exist, which
|
||||
// should be rare (occurring when we receive an attestation with source and target epochs
|
||||
// that span multiple chunk indices), then we fallback to fetching from disk.
|
||||
// Retrieve a chunk from database from database.
|
||||
func (s *Service) getChunk(
|
||||
ctx context.Context,
|
||||
args *chunkUpdateArgs,
|
||||
chunksByChunkIdx map[uint64]Chunker,
|
||||
chunkIdx uint64,
|
||||
chunkKind slashertypes.ChunkKind,
|
||||
validatorChunkIndex uint64,
|
||||
chunkIndex uint64,
|
||||
) (Chunker, error) {
|
||||
chunk, ok := chunksByChunkIdx[chunkIdx]
|
||||
if ok {
|
||||
return chunk, nil
|
||||
}
|
||||
// We can ensure we load the appropriate chunk we need by fetching from the DB.
|
||||
diskChunks, err := s.loadChunks(ctx, args, []uint64{chunkIdx})
|
||||
diskChunks, err := s.loadChunks(ctx, validatorChunkIndex, chunkKind, []uint64{chunkIndex})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not load chunk at index %d", chunkIdx)
|
||||
return nil, errors.Wrapf(err, "could not load chunk at index %d", chunkIndex)
|
||||
}
|
||||
if chunk, ok := diskChunks[chunkIdx]; ok {
|
||||
|
||||
if chunk, ok := diskChunks[chunkIndex]; ok {
|
||||
return chunk, nil
|
||||
}
|
||||
return nil, fmt.Errorf("could not retrieve chunk at chunk index %d from disk", chunkIdx)
|
||||
|
||||
return nil, fmt.Errorf("could not retrieve chunk at chunk index %d from disk", chunkIndex)
|
||||
}
|
||||
|
||||
// Load chunks for a specified list of chunk indices. We attempt to load it from the database.
|
||||
@@ -390,63 +507,75 @@ func (s *Service) getChunk(
|
||||
// an empty chunk, add it to our map, and then return it to the caller.
|
||||
func (s *Service) loadChunks(
|
||||
ctx context.Context,
|
||||
args *chunkUpdateArgs,
|
||||
validatorChunkIndex uint64,
|
||||
chunkKind slashertypes.ChunkKind,
|
||||
chunkIndices []uint64,
|
||||
) (map[uint64]Chunker, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "Slasher.loadChunks")
|
||||
defer span.End()
|
||||
|
||||
chunkKeys := make([][]byte, 0, len(chunkIndices))
|
||||
for _, chunkIdx := range chunkIndices {
|
||||
chunkKeys = append(chunkKeys, s.params.flatSliceID(args.validatorChunkIndex, chunkIdx))
|
||||
chunkKeys = append(chunkKeys, s.params.flatSliceID(validatorChunkIndex, chunkIdx))
|
||||
}
|
||||
rawChunks, chunksExist, err := s.serviceCfg.Database.LoadSlasherChunks(ctx, args.kind, chunkKeys)
|
||||
|
||||
rawChunks, chunksExist, err := s.serviceCfg.Database.LoadSlasherChunks(ctx, chunkKind, chunkKeys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err,
|
||||
"could not load slasher chunk index",
|
||||
)
|
||||
return nil, errors.Wrapf(err, "could not load slasher chunk index")
|
||||
}
|
||||
|
||||
chunksByChunkIdx := make(map[uint64]Chunker, len(rawChunks))
|
||||
for i := 0; i < len(rawChunks); i++ {
|
||||
// If the chunk exists in the database, we initialize it from the raw bytes data.
|
||||
// If it does not exist, we initialize an empty chunk.
|
||||
var chunk Chunker
|
||||
switch args.kind {
|
||||
var (
|
||||
chunk Chunker
|
||||
err error
|
||||
)
|
||||
|
||||
chunkExists := chunksExist[i]
|
||||
|
||||
switch chunkKind {
|
||||
case slashertypes.MinSpan:
|
||||
if chunksExist[i] {
|
||||
if chunkExists {
|
||||
chunk, err = MinChunkSpansSliceFrom(s.params, rawChunks[i])
|
||||
} else {
|
||||
chunk = EmptyMinSpanChunksSlice(s.params)
|
||||
break
|
||||
}
|
||||
chunk = EmptyMinSpanChunksSlice(s.params)
|
||||
|
||||
case slashertypes.MaxSpan:
|
||||
if chunksExist[i] {
|
||||
if chunkExists {
|
||||
chunk, err = MaxChunkSpansSliceFrom(s.params, rawChunks[i])
|
||||
} else {
|
||||
chunk = EmptyMaxSpanChunksSlice(s.params)
|
||||
break
|
||||
}
|
||||
chunk = EmptyMaxSpanChunksSlice(s.params)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not initialize chunk")
|
||||
}
|
||||
|
||||
chunksByChunkIdx[chunkIndices[i]] = chunk
|
||||
}
|
||||
|
||||
return chunksByChunkIdx, nil
|
||||
}
|
||||
|
||||
// Saves updated chunks to disk given the required database schema.
|
||||
func (s *Service) saveUpdatedChunks(
|
||||
ctx context.Context,
|
||||
args *chunkUpdateArgs,
|
||||
updatedChunksByChunkIdx map[uint64]Chunker,
|
||||
chunkKind slashertypes.ChunkKind,
|
||||
validatorChunkIndex uint64,
|
||||
) error {
|
||||
ctx, span := trace.StartSpan(ctx, "Slasher.saveUpdatedChunks")
|
||||
defer span.End()
|
||||
chunkKeys := make([][]byte, 0, len(updatedChunksByChunkIdx))
|
||||
chunks := make([][]uint16, 0, len(updatedChunksByChunkIdx))
|
||||
for chunkIdx, chunk := range updatedChunksByChunkIdx {
|
||||
chunkKeys = append(chunkKeys, s.params.flatSliceID(args.validatorChunkIndex, chunkIdx))
|
||||
chunkKeys = append(chunkKeys, s.params.flatSliceID(validatorChunkIndex, chunkIdx))
|
||||
chunks = append(chunks, chunk.Chunk())
|
||||
}
|
||||
chunksSavedTotal.Add(float64(len(chunks)))
|
||||
return s.serviceCfg.Database.SaveSlasherChunks(ctx, args.kind, chunkKeys, chunks)
|
||||
return s.serviceCfg.Database.SaveSlasherChunks(ctx, chunkKind, chunkKeys, chunks)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,7 @@ func (s *Service) detectProposerSlashings(
|
||||
}
|
||||
|
||||
// If we have seen this proposal before, we check if it is a double proposal.
|
||||
if isDoubleProposal(incomingProposal.SigningRoot, existingProposal.SigningRoot) {
|
||||
if isDoubleProposal(incomingProposal.HeaderRoot, existingProposal.HeaderRoot) {
|
||||
doubleProposalsTotal.Inc()
|
||||
|
||||
slashing := ðpb.ProposerSlashing{
|
||||
|
||||
@@ -204,7 +204,7 @@ func createProposalWrapper(t *testing.T, slot primitives.Slot, proposerIndex pri
|
||||
StateRoot: bytesutil.PadTo(signingRoot, 32),
|
||||
BodyRoot: params.BeaconConfig().ZeroHash[:],
|
||||
}
|
||||
signRoot, err := header.HashTreeRoot()
|
||||
headerRoot, err := header.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
fakeSig := make([]byte, 96)
|
||||
copy(fakeSig, "hello")
|
||||
@@ -213,6 +213,6 @@ func createProposalWrapper(t *testing.T, slot primitives.Slot, proposerIndex pri
|
||||
Header: header,
|
||||
Signature: fakeSig,
|
||||
},
|
||||
SigningRoot: signRoot,
|
||||
HeaderRoot: headerRoot,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,19 +21,23 @@ func (s *Service) groupByValidatorChunkIndex(
|
||||
attestations []*slashertypes.IndexedAttestationWrapper,
|
||||
) map[uint64][]*slashertypes.IndexedAttestationWrapper {
|
||||
groupedAttestations := make(map[uint64][]*slashertypes.IndexedAttestationWrapper)
|
||||
for _, att := range attestations {
|
||||
validatorChunkIndices := make(map[uint64]bool)
|
||||
for _, validatorIdx := range att.IndexedAttestation.AttestingIndices {
|
||||
validatorChunkIndex := s.params.validatorChunkIndex(primitives.ValidatorIndex(validatorIdx))
|
||||
validatorChunkIndices[validatorChunkIndex] = true
|
||||
|
||||
for _, attestation := range attestations {
|
||||
validatorChunkIndexes := make(map[uint64]bool)
|
||||
|
||||
for _, validatorIndex := range attestation.IndexedAttestation.AttestingIndices {
|
||||
validatorChunkIndex := s.params.validatorChunkIndex(primitives.ValidatorIndex(validatorIndex))
|
||||
validatorChunkIndexes[validatorChunkIndex] = true
|
||||
}
|
||||
for validatorChunkIndex := range validatorChunkIndices {
|
||||
|
||||
for validatorChunkIndex := range validatorChunkIndexes {
|
||||
groupedAttestations[validatorChunkIndex] = append(
|
||||
groupedAttestations[validatorChunkIndex],
|
||||
att,
|
||||
attestation,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return groupedAttestations
|
||||
}
|
||||
|
||||
@@ -42,10 +46,12 @@ func (s *Service) groupByChunkIndex(
|
||||
attestations []*slashertypes.IndexedAttestationWrapper,
|
||||
) map[uint64][]*slashertypes.IndexedAttestationWrapper {
|
||||
attestationsByChunkIndex := make(map[uint64][]*slashertypes.IndexedAttestationWrapper)
|
||||
for _, att := range attestations {
|
||||
chunkIdx := s.params.chunkIndex(att.IndexedAttestation.Data.Source.Epoch)
|
||||
attestationsByChunkIndex[chunkIdx] = append(attestationsByChunkIndex[chunkIdx], att)
|
||||
|
||||
for _, attestation := range attestations {
|
||||
chunkIndex := s.params.chunkIndex(attestation.IndexedAttestation.Data.Source.Epoch)
|
||||
attestationsByChunkIndex[chunkIndex] = append(attestationsByChunkIndex[chunkIndex], attestation)
|
||||
}
|
||||
|
||||
return attestationsByChunkIndex
|
||||
}
|
||||
|
||||
|
||||
@@ -32,13 +32,13 @@ func TestService_groupByValidatorChunkIndex(t *testing.T) {
|
||||
validatorChunkSize: 2,
|
||||
},
|
||||
atts: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0, 1}, nil),
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0, 1}, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 1}, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 1}, nil),
|
||||
},
|
||||
want: map[uint64][]*slashertypes.IndexedAttestationWrapper{
|
||||
0: {
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0, 1}, nil),
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0, 1}, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 1}, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 1}, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -48,17 +48,17 @@ func TestService_groupByValidatorChunkIndex(t *testing.T) {
|
||||
validatorChunkSize: 2,
|
||||
},
|
||||
atts: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0, 2, 4}, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 2, 4}, nil),
|
||||
},
|
||||
want: map[uint64][]*slashertypes.IndexedAttestationWrapper{
|
||||
0: {
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0, 2, 4}, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 2, 4}, nil),
|
||||
},
|
||||
1: {
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0, 2, 4}, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 2, 4}, nil),
|
||||
},
|
||||
2: {
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0, 2, 4}, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{0, 2, 4}, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -95,13 +95,13 @@ func TestService_groupByChunkIndex(t *testing.T) {
|
||||
historyLength: 3,
|
||||
},
|
||||
atts: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 0, nil, nil),
|
||||
createAttestationWrapper(t, 1, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 1, 0, nil, nil),
|
||||
},
|
||||
want: map[uint64][]*slashertypes.IndexedAttestationWrapper{
|
||||
0: {
|
||||
createAttestationWrapper(t, 0, 0, nil, nil),
|
||||
createAttestationWrapper(t, 1, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 1, 0, nil, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -112,17 +112,17 @@ func TestService_groupByChunkIndex(t *testing.T) {
|
||||
historyLength: 3,
|
||||
},
|
||||
atts: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 0, nil, nil),
|
||||
createAttestationWrapper(t, 1, 0, nil, nil),
|
||||
createAttestationWrapper(t, 2, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 1, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 2, 0, nil, nil),
|
||||
},
|
||||
want: map[uint64][]*slashertypes.IndexedAttestationWrapper{
|
||||
0: {
|
||||
createAttestationWrapper(t, 0, 0, nil, nil),
|
||||
createAttestationWrapper(t, 1, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 1, 0, nil, nil),
|
||||
},
|
||||
1: {
|
||||
createAttestationWrapper(t, 2, 0, nil, nil),
|
||||
createAttestationWrapperEmptySig(t, 2, 0, nil, nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -207,7 +207,7 @@ func TestService_filterAttestations(t *testing.T) {
|
||||
{
|
||||
name: "Source > target gets dropped",
|
||||
input: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 1, 0, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 1, 0, []uint64{1}, make([]byte, 32)),
|
||||
},
|
||||
inputEpoch: 0,
|
||||
wantedDropped: 1,
|
||||
@@ -215,33 +215,33 @@ func TestService_filterAttestations(t *testing.T) {
|
||||
{
|
||||
name: "Source < target is valid",
|
||||
input: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 1, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, make([]byte, 32)),
|
||||
},
|
||||
inputEpoch: 1,
|
||||
wantedValid: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 1, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, make([]byte, 32)),
|
||||
},
|
||||
wantedDropped: 0,
|
||||
},
|
||||
{
|
||||
name: "Source == target is valid",
|
||||
input: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 0, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{1}, make([]byte, 32)),
|
||||
},
|
||||
inputEpoch: 1,
|
||||
wantedValid: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 0, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 0, []uint64{1}, make([]byte, 32)),
|
||||
},
|
||||
wantedDropped: 0,
|
||||
},
|
||||
{
|
||||
name: "Attestation from the future is deferred",
|
||||
input: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 2, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 2, []uint64{1}, make([]byte, 32)),
|
||||
},
|
||||
inputEpoch: 1,
|
||||
wantedDeferred: []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 2, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 2, []uint64{1}, make([]byte, 32)),
|
||||
},
|
||||
wantedDropped: 0,
|
||||
},
|
||||
@@ -271,22 +271,22 @@ func Test_logSlashingEvent(t *testing.T) {
|
||||
{
|
||||
name: "Surrounding vote",
|
||||
slashing: ðpb.AttesterSlashing{
|
||||
Attestation_1: createAttestationWrapper(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapper(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Surrounded vote",
|
||||
slashing: ðpb.AttesterSlashing{
|
||||
Attestation_1: createAttestationWrapper(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapper(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Double vote",
|
||||
slashing: ðpb.AttesterSlashing{
|
||||
Attestation_1: createAttestationWrapper(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapper(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -141,12 +141,14 @@ func (p *Parameters) flatSliceID(validatorChunkIndex, chunkIndex uint64) []byte
|
||||
|
||||
// Given a validator chunk index, we determine all of the validator
|
||||
// indices that will belong in that chunk.
|
||||
func (p *Parameters) validatorIndicesInChunk(validatorChunkIdx uint64) []primitives.ValidatorIndex {
|
||||
func (p *Parameters) validatorIndexesInChunk(validatorChunkIndex uint64) []primitives.ValidatorIndex {
|
||||
validatorIndices := make([]primitives.ValidatorIndex, 0)
|
||||
low := validatorChunkIdx * p.validatorChunkSize
|
||||
high := (validatorChunkIdx + 1) * p.validatorChunkSize
|
||||
low := validatorChunkIndex * p.validatorChunkSize
|
||||
high := (validatorChunkIndex + 1) * p.validatorChunkSize
|
||||
|
||||
for i := low; i < high; i++ {
|
||||
validatorIndices = append(validatorIndices, primitives.ValidatorIndex(i))
|
||||
}
|
||||
|
||||
return validatorIndices
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ func TestParams_validatorIndicesInChunk(t *testing.T) {
|
||||
c := &Parameters{
|
||||
validatorChunkSize: tt.fields.validatorChunkSize,
|
||||
}
|
||||
if got := c.validatorIndicesInChunk(tt.validatorChunkIdx); !reflect.DeepEqual(got, tt.want) {
|
||||
if got := c.validatorIndexesInChunk(tt.validatorChunkIdx); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("validatorIndicesInChunk() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,78 +3,102 @@ package slasher
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// Verifies attester slashings, logs them, and submits them to the slashing operations pool
|
||||
// in the beacon node if they pass validation.
|
||||
func (s *Service) processAttesterSlashings(ctx context.Context, slashings []*ethpb.AttesterSlashing) error {
|
||||
var beaconState state.BeaconState
|
||||
var err error
|
||||
if len(slashings) > 0 {
|
||||
beaconState, err = s.serviceCfg.HeadStateFetcher.HeadState(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (s *Service) processAttesterSlashings(
|
||||
ctx context.Context, slashings map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
processedSlashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
|
||||
// If no slashings, return early.
|
||||
if len(slashings) == 0 {
|
||||
return processedSlashings, nil
|
||||
}
|
||||
for _, sl := range slashings {
|
||||
if err := s.verifyAttSignature(ctx, sl.Attestation_1); err != nil {
|
||||
log.WithError(err).WithField("a", sl.Attestation_1).Warn(
|
||||
|
||||
// Get the head state.
|
||||
beaconState, err := s.serviceCfg.HeadStateFetcher.HeadState(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get head state")
|
||||
}
|
||||
|
||||
for root, slashing := range slashings {
|
||||
// Verify the signature of the first attestation.
|
||||
if err := s.verifyAttSignature(ctx, slashing.Attestation_1); err != nil {
|
||||
log.WithError(err).WithField("a", slashing.Attestation_1).Warn(
|
||||
"Invalid signature for attestation in detected slashing offense",
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
if err := s.verifyAttSignature(ctx, sl.Attestation_2); err != nil {
|
||||
log.WithError(err).WithField("b", sl.Attestation_2).Warn(
|
||||
|
||||
// Verify the signature of the second attestation.
|
||||
if err := s.verifyAttSignature(ctx, slashing.Attestation_2); err != nil {
|
||||
log.WithError(err).WithField("b", slashing.Attestation_2).Warn(
|
||||
"Invalid signature for attestation in detected slashing offense",
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// Log the slashing event and insert into the beacon node's operations pool.
|
||||
logAttesterSlashing(sl)
|
||||
if err := s.serviceCfg.SlashingPoolInserter.InsertAttesterSlashing(
|
||||
ctx, beaconState, sl,
|
||||
); err != nil {
|
||||
logAttesterSlashing(slashing)
|
||||
if err := s.serviceCfg.SlashingPoolInserter.InsertAttesterSlashing(ctx, beaconState, slashing); err != nil {
|
||||
log.WithError(err).Error("Could not insert attester slashing into operations pool")
|
||||
}
|
||||
|
||||
processedSlashings[root] = slashing
|
||||
}
|
||||
return nil
|
||||
|
||||
return processedSlashings, nil
|
||||
}
|
||||
|
||||
// Verifies proposer slashings, logs them, and submits them to the slashing operations pool
|
||||
// in the beacon node if they pass validation.
|
||||
func (s *Service) processProposerSlashings(ctx context.Context, slashings []*ethpb.ProposerSlashing) error {
|
||||
var beaconState state.BeaconState
|
||||
var err error
|
||||
if len(slashings) > 0 {
|
||||
beaconState, err = s.serviceCfg.HeadStateFetcher.HeadState(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// If no slashings, return early.
|
||||
if len(slashings) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, sl := range slashings {
|
||||
if err := s.verifyBlockSignature(ctx, sl.Header_1); err != nil {
|
||||
log.WithError(err).WithField("a", sl.Header_1).Warn(
|
||||
|
||||
// Get the head state.
|
||||
beaconState, err := s.serviceCfg.HeadStateFetcher.HeadState(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, slashing := range slashings {
|
||||
// Verify the signature of the first block.
|
||||
if err := s.verifyBlockSignature(ctx, slashing.Header_1); err != nil {
|
||||
log.WithError(err).WithField("a", slashing.Header_1).Warn(
|
||||
"Invalid signature for block header in detected slashing offense",
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
if err := s.verifyBlockSignature(ctx, sl.Header_2); err != nil {
|
||||
log.WithError(err).WithField("b", sl.Header_2).Warn(
|
||||
|
||||
// Verify the signature of the second block.
|
||||
if err := s.verifyBlockSignature(ctx, slashing.Header_2); err != nil {
|
||||
log.WithError(err).WithField("b", slashing.Header_2).Warn(
|
||||
"Invalid signature for block header in detected slashing offense",
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// Log the slashing event and insert into the beacon node's operations pool.
|
||||
logProposerSlashing(sl)
|
||||
if err := s.serviceCfg.SlashingPoolInserter.InsertProposerSlashing(ctx, beaconState, sl); err != nil {
|
||||
logProposerSlashing(slashing)
|
||||
if err := s.serviceCfg.SlashingPoolInserter.InsertProposerSlashing(ctx, beaconState, slashing); err != nil {
|
||||
log.WithError(err).Error("Could not insert proposer slashing into operations pool")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
slashingsmock "github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/slashings/mock"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
@@ -75,14 +76,19 @@ func TestService_processAttesterSlashings(t *testing.T) {
|
||||
firstAtt.Signature = signature.Marshal()
|
||||
secondAtt.Signature = make([]byte, 96)
|
||||
|
||||
slashings := []*ethpb.AttesterSlashing{
|
||||
{
|
||||
Attestation_1: firstAtt,
|
||||
Attestation_2: secondAtt,
|
||||
},
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: firstAtt,
|
||||
Attestation_2: secondAtt,
|
||||
}
|
||||
|
||||
err = s.processAttesterSlashings(ctx, slashings)
|
||||
root, err := slashing.HashTreeRoot()
|
||||
require.NoError(tt, err, "failed to hash tree root")
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
||||
root: slashing,
|
||||
}
|
||||
|
||||
_, err = s.processAttesterSlashings(ctx, slashings)
|
||||
require.NoError(tt, err)
|
||||
require.LogsContain(tt, hook, "Invalid signature")
|
||||
})
|
||||
@@ -94,14 +100,19 @@ func TestService_processAttesterSlashings(t *testing.T) {
|
||||
firstAtt.Signature = make([]byte, 96)
|
||||
secondAtt.Signature = signature.Marshal()
|
||||
|
||||
slashings := []*ethpb.AttesterSlashing{
|
||||
{
|
||||
Attestation_1: firstAtt,
|
||||
Attestation_2: secondAtt,
|
||||
},
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: firstAtt,
|
||||
Attestation_2: secondAtt,
|
||||
}
|
||||
|
||||
err = s.processAttesterSlashings(ctx, slashings)
|
||||
root, err := slashing.HashTreeRoot()
|
||||
require.NoError(tt, err, "failed to hash tree root")
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
||||
root: slashing,
|
||||
}
|
||||
|
||||
_, err = s.processAttesterSlashings(ctx, slashings)
|
||||
require.NoError(tt, err)
|
||||
require.LogsContain(tt, hook, "Invalid signature")
|
||||
})
|
||||
@@ -113,14 +124,19 @@ func TestService_processAttesterSlashings(t *testing.T) {
|
||||
firstAtt.Signature = signature.Marshal()
|
||||
secondAtt.Signature = signature.Marshal()
|
||||
|
||||
slashings := []*ethpb.AttesterSlashing{
|
||||
{
|
||||
Attestation_1: firstAtt,
|
||||
Attestation_2: secondAtt,
|
||||
},
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: firstAtt,
|
||||
Attestation_2: secondAtt,
|
||||
}
|
||||
|
||||
err = s.processAttesterSlashings(ctx, slashings)
|
||||
root, err := slashing.HashTreeRoot()
|
||||
require.NoError(tt, err, "failed to hash tree root")
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
||||
root: slashing,
|
||||
}
|
||||
|
||||
_, err = s.processAttesterSlashings(ctx, slashings)
|
||||
require.NoError(tt, err)
|
||||
require.LogsDoNotContain(tt, hook, "Invalid signature")
|
||||
})
|
||||
|
||||
@@ -12,8 +12,8 @@ func Test_attestationsQueue(t *testing.T) {
|
||||
t.Run("push_and_dequeue", func(tt *testing.T) {
|
||||
attQueue := newAttestationsQueue()
|
||||
wantedAtts := []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 1, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapper(t, 1, 2, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 1, 2, []uint64{1}, make([]byte, 32)),
|
||||
}
|
||||
attQueue.push(wantedAtts[0])
|
||||
attQueue.push(wantedAtts[1])
|
||||
@@ -27,8 +27,8 @@ func Test_attestationsQueue(t *testing.T) {
|
||||
t.Run("extend_and_dequeue", func(tt *testing.T) {
|
||||
attQueue := newAttestationsQueue()
|
||||
wantedAtts := []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 1, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapper(t, 1, 2, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 1, []uint64{1}, make([]byte, 32)),
|
||||
createAttestationWrapperEmptySig(t, 1, 2, []uint64{1}, make([]byte, 32)),
|
||||
}
|
||||
attQueue.extend(wantedAtts)
|
||||
require.DeepEqual(t, 2, attQueue.size())
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher/types"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
@@ -32,14 +33,14 @@ func (s *Service) receiveAttestations(ctx context.Context, indexedAttsChan chan
|
||||
if !validateAttestationIntegrity(att) {
|
||||
continue
|
||||
}
|
||||
signingRoot, err := att.Data.HashTreeRoot()
|
||||
dataRoot, err := att.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get hash tree root of attestation")
|
||||
continue
|
||||
}
|
||||
attWrapper := &slashertypes.IndexedAttestationWrapper{
|
||||
IndexedAttestation: att,
|
||||
SigningRoot: signingRoot,
|
||||
DataRoot: dataRoot,
|
||||
}
|
||||
s.attsQueue.push(attWrapper)
|
||||
case err := <-sub.Err():
|
||||
@@ -63,14 +64,14 @@ func (s *Service) receiveBlocks(ctx context.Context, beaconBlockHeadersChan chan
|
||||
if !validateBlockHeaderIntegrity(blockHeader) {
|
||||
continue
|
||||
}
|
||||
signingRoot, err := blockHeader.Header.HashTreeRoot()
|
||||
headerRoot, err := blockHeader.Header.HashTreeRoot()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get hash tree root of signed block header")
|
||||
continue
|
||||
}
|
||||
wrappedProposal := &slashertypes.SignedBlockHeaderWrapper{
|
||||
SignedBeaconBlockHeader: blockHeader,
|
||||
SigningRoot: signingRoot,
|
||||
HeaderRoot: headerRoot,
|
||||
}
|
||||
s.blksQueue.push(wrappedProposal)
|
||||
case err := <-sub.Err():
|
||||
@@ -92,57 +93,70 @@ func (s *Service) processQueuedAttestations(ctx context.Context, slotTicker <-ch
|
||||
for {
|
||||
select {
|
||||
case currentSlot := <-slotTicker:
|
||||
// Retrieve all attestations from the queue.
|
||||
attestations := s.attsQueue.dequeue()
|
||||
currentEpoch := slots.ToEpoch(currentSlot)
|
||||
// We take all the attestations in the queue and filter out
|
||||
// those which are valid now and valid in the future.
|
||||
validAtts, validInFuture, numDropped := s.filterAttestations(attestations, currentEpoch)
|
||||
|
||||
deferredAttestationsTotal.Add(float64(len(validInFuture)))
|
||||
droppedAttestationsTotal.Add(float64(numDropped))
|
||||
|
||||
// We add back those attestations that are valid in the future to the queue.
|
||||
s.attsQueue.extend(validInFuture)
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"currentSlot": currentSlot,
|
||||
"currentEpoch": currentEpoch,
|
||||
"numValidAtts": len(validAtts),
|
||||
"numDeferredAtts": len(validInFuture),
|
||||
"numDroppedAtts": numDropped,
|
||||
}).Info("Processing queued attestations for slashing detection")
|
||||
|
||||
// Save the attestation records to our database.
|
||||
// If multiple attestations are provided for the same validator index + target epoch combination,
|
||||
// then last (validator index + target epoch) => signing root) link is kept into the database.
|
||||
if err := s.serviceCfg.Database.SaveAttestationRecordsForValidators(
|
||||
ctx, validAtts,
|
||||
); err != nil {
|
||||
log.WithError(err).Error(couldNotSaveAttRecord)
|
||||
continue
|
||||
}
|
||||
|
||||
// Check for slashings.
|
||||
slashings, err := s.checkSlashableAttestations(ctx, currentEpoch, validAtts)
|
||||
if err != nil {
|
||||
log.WithError(err).Error(couldNotCheckSlashableAtt)
|
||||
continue
|
||||
}
|
||||
|
||||
// Process attester slashings by verifying their signatures, submitting
|
||||
// to the beacon node's operations pool, and logging them.
|
||||
if err := s.processAttesterSlashings(ctx, slashings); err != nil {
|
||||
log.WithError(err).Error(couldNotProcessAttesterSlashings)
|
||||
continue
|
||||
}
|
||||
|
||||
processedAttestationsTotal.Add(float64(len(validAtts)))
|
||||
// Process the retrieved attestations.
|
||||
s.processAttestations(ctx, attestations, currentSlot)
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) processAttestations(
|
||||
ctx context.Context,
|
||||
attestations []*slashertypes.IndexedAttestationWrapper,
|
||||
currentSlot primitives.Slot,
|
||||
) map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing {
|
||||
// Get the current epoch from the current slot.
|
||||
currentEpoch := slots.ToEpoch(currentSlot)
|
||||
|
||||
// Take all the attestations in the queue and filter out
|
||||
// those which are valid now and valid in the future.
|
||||
validAttestations, validInFutureAttestations, numDropped := s.filterAttestations(attestations, currentEpoch)
|
||||
|
||||
// Increase corresponding prometheus metrics.
|
||||
deferredAttestationsTotal.Add(float64(len(validInFutureAttestations)))
|
||||
droppedAttestationsTotal.Add(float64(numDropped))
|
||||
processedAttestationsTotal.Add(float64(len(validAttestations)))
|
||||
|
||||
// We add back those attestations that are valid in the future to the queue.
|
||||
s.attsQueue.extend(validInFutureAttestations)
|
||||
|
||||
// Compute some counts.
|
||||
queuedAttestationsCount := s.attsQueue.size()
|
||||
validAttestationsCount := len(validAttestations)
|
||||
validInFutureAttestationsCount := len(validInFutureAttestations)
|
||||
|
||||
// Log useful infrormation
|
||||
log.WithFields(logrus.Fields{
|
||||
"currentSlot": currentSlot,
|
||||
"currentEpoch": currentEpoch,
|
||||
"numValidAtts": validAttestationsCount,
|
||||
"numDeferredAtts": validInFutureAttestationsCount,
|
||||
"numDroppedAtts": numDropped,
|
||||
"attsQueueSize": queuedAttestationsCount,
|
||||
}).Info("Processing queued attestations for slashing detection")
|
||||
|
||||
// Check for attestatinos slashings (double, sourrounding, surrounded votes).
|
||||
slashings, err := s.checkSlashableAttestations(ctx, currentEpoch, validAttestations)
|
||||
if err != nil {
|
||||
log.WithError(err).Error(couldNotCheckSlashableAtt)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Process attester slashings by verifying their signatures, submitting
|
||||
// to the beacon node's operations pool, and logging them.
|
||||
processedAttesterSlashings, err := s.processAttesterSlashings(ctx, slashings)
|
||||
if err != nil {
|
||||
log.WithError(err).Error(couldNotProcessAttesterSlashings)
|
||||
return nil
|
||||
}
|
||||
|
||||
return processedAttesterSlashings
|
||||
}
|
||||
|
||||
// Process queued blocks every time an epoch ticker fires. We retrieve
|
||||
// these blocks from a queue, then perform double proposal detection.
|
||||
func (s *Service) processQueuedBlocks(ctx context.Context, slotTicker <-chan primitives.Slot) {
|
||||
|
||||
@@ -38,8 +38,8 @@ func TestSlasher_receiveAttestations_OK(t *testing.T) {
|
||||
}()
|
||||
firstIndices := []uint64{1, 2, 3}
|
||||
secondIndices := []uint64{4, 5, 6}
|
||||
att1 := createAttestationWrapper(t, 1, 2, firstIndices, nil)
|
||||
att2 := createAttestationWrapper(t, 1, 2, secondIndices, nil)
|
||||
att1 := createAttestationWrapperEmptySig(t, 1, 2, firstIndices, nil)
|
||||
att2 := createAttestationWrapperEmptySig(t, 1, 2, secondIndices, nil)
|
||||
indexedAttsChan <- att1.IndexedAttestation
|
||||
indexedAttsChan <- att2.IndexedAttestation
|
||||
cancel()
|
||||
@@ -65,14 +65,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{
|
||||
createAttestationWrapper(t, 0, 0, []uint64{0}, bytesutil.PadTo([]byte("0a"), 32)),
|
||||
createAttestationWrapper(t, 0, 0, []uint64{1}, bytesutil.PadTo([]byte("0b"), 32)),
|
||||
createAttestationWrapper(t, 0, 1, []uint64{0}, bytesutil.PadTo([]byte("1a"), 32)),
|
||||
createAttestationWrapper(t, 0, 1, []uint64{1}, bytesutil.PadTo([]byte("1b"), 32)),
|
||||
createAttestationWrapper(t, 0, 2, []uint64{0}, bytesutil.PadTo([]byte("2a"), 32)),
|
||||
createAttestationWrapper(t, 0, 2, []uint64{1}, bytesutil.PadTo([]byte("2b"), 32)),
|
||||
createAttestationWrapper(t, 0, 3, []uint64{0}, bytesutil.PadTo([]byte("3a"), 32)),
|
||||
createAttestationWrapper(t, 0, 3, []uint64{1}, bytesutil.PadTo([]byte("3b"), 32)),
|
||||
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)),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -93,8 +93,8 @@ func TestService_pruneSlasherDataWithinSlidingWindow_AttestationsPruned(t *testi
|
||||
|
||||
// Setup attestations for 2 validators at epoch 4.
|
||||
err = slasherDB.SaveAttestationRecordsForValidators(ctx, []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 4, []uint64{0}, bytesutil.PadTo([]byte("4a"), 32)),
|
||||
createAttestationWrapper(t, 0, 4, []uint64{1}, bytesutil.PadTo([]byte("4b"), 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 4, []uint64{0}, bytesutil.PadTo([]byte("4a"), 32)),
|
||||
createAttestationWrapperEmptySig(t, 0, 4, []uint64{1}, bytesutil.PadTo([]byte("4b"), 32)),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -222,7 +222,7 @@ func TestSlasher_receiveAttestations_OnlyValidAttestations(t *testing.T) {
|
||||
firstIndices := []uint64{1, 2, 3}
|
||||
secondIndices := []uint64{4, 5, 6}
|
||||
// Add a valid attestation.
|
||||
validAtt := createAttestationWrapper(t, 1, 2, firstIndices, nil)
|
||||
validAtt := createAttestationWrapperEmptySig(t, 1, 2, firstIndices, nil)
|
||||
indexedAttsChan <- validAtt.IndexedAttestation
|
||||
// Send an invalid, bad attestation which will not
|
||||
// pass integrity checks at it has invalid attestation data.
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package slasher
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// HighestAttestations committed for an input list of validator indices.
|
||||
func (s *Service) HighestAttestations(
|
||||
ctx context.Context, validatorIndices []primitives.ValidatorIndex,
|
||||
) ([]*ethpb.HighestAttestation, error) {
|
||||
atts, err := s.serviceCfg.Database.HighestAttestations(ctx, validatorIndices)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get highest attestations from database")
|
||||
}
|
||||
return atts, nil
|
||||
}
|
||||
|
||||
// IsSlashableBlock checks if an input block header is slashable
|
||||
// with respect to historical block proposal data.
|
||||
func (s *Service) IsSlashableBlock(
|
||||
ctx context.Context, block *ethpb.SignedBeaconBlockHeader,
|
||||
) (*ethpb.ProposerSlashing, error) {
|
||||
dataRoot, err := block.Header.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get block header hash tree root: %v", err)
|
||||
}
|
||||
signedBlockWrapper := &slashertypes.SignedBlockHeaderWrapper{
|
||||
SignedBeaconBlockHeader: block,
|
||||
SigningRoot: dataRoot,
|
||||
}
|
||||
proposerSlashings, err := s.detectProposerSlashings(ctx, []*slashertypes.SignedBlockHeaderWrapper{signedBlockWrapper})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if proposal is slashable: %v", err)
|
||||
}
|
||||
if len(proposerSlashings) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return proposerSlashings[0], nil
|
||||
}
|
||||
|
||||
// IsSlashableAttestation checks if an input indexed attestation is slashable
|
||||
// with respect to historical attestation data.
|
||||
func (s *Service) IsSlashableAttestation(
|
||||
ctx context.Context, attestation *ethpb.IndexedAttestation,
|
||||
) ([]*ethpb.AttesterSlashing, error) {
|
||||
dataRoot, err := attestation.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get attestation data hash tree root: %v", err)
|
||||
}
|
||||
indexedAttWrapper := &slashertypes.IndexedAttestationWrapper{
|
||||
IndexedAttestation: attestation,
|
||||
SigningRoot: dataRoot,
|
||||
}
|
||||
|
||||
currentEpoch := slots.EpochsSinceGenesis(s.genesisTime)
|
||||
attesterSlashings, err := s.checkSlashableAttestations(ctx, currentEpoch, []*slashertypes.IndexedAttestationWrapper{indexedAttWrapper})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if attestation is slashable: %v", err)
|
||||
}
|
||||
if len(attesterSlashings) == 0 {
|
||||
// If the incoming attestations are not slashable, we mark them as saved in
|
||||
// slasher's DB storage to help us with future detection.
|
||||
if err := s.serviceCfg.Database.SaveAttestationRecordsForValidators(
|
||||
ctx, []*slashertypes.IndexedAttestationWrapper{indexedAttWrapper},
|
||||
); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not save attestation records to DB: %v", err)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return attesterSlashings, nil
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
package slasher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
dbtest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
func TestIsSlashableBlock(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
slasherDB := dbtest.SetupSlasherDB(t)
|
||||
s := &Service{
|
||||
serviceCfg: &ServiceConfig{
|
||||
Database: slasherDB,
|
||||
},
|
||||
params: DefaultParams(),
|
||||
blksQueue: newBlocksQueue(),
|
||||
}
|
||||
err := slasherDB.SaveBlockProposals(ctx, []*slashertypes.SignedBlockHeaderWrapper{
|
||||
createProposalWrapper(t, 2, 3, []byte{1}),
|
||||
createProposalWrapper(t, 3, 3, []byte{1}),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
name string
|
||||
blockToCheck *slashertypes.SignedBlockHeaderWrapper
|
||||
shouldBeSlashable bool
|
||||
}{
|
||||
{
|
||||
name: "should not detect if same signing root",
|
||||
blockToCheck: createProposalWrapper(t, 2, 3, []byte{1}),
|
||||
shouldBeSlashable: false,
|
||||
},
|
||||
{
|
||||
name: "should not detect if different slot",
|
||||
blockToCheck: createProposalWrapper(t, 1, 3, []byte{2}),
|
||||
shouldBeSlashable: false,
|
||||
},
|
||||
{
|
||||
name: "should not detect if different validator index",
|
||||
blockToCheck: createProposalWrapper(t, 2, 4, []byte{2}),
|
||||
shouldBeSlashable: false,
|
||||
},
|
||||
{
|
||||
name: "detects differing signing root",
|
||||
blockToCheck: createProposalWrapper(t, 2, 3, []byte{2}),
|
||||
shouldBeSlashable: true,
|
||||
},
|
||||
{
|
||||
name: "should detect another slot",
|
||||
blockToCheck: createProposalWrapper(t, 3, 3, []byte{2}),
|
||||
shouldBeSlashable: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
proposerSlashing, err := s.IsSlashableBlock(ctx, tt.blockToCheck.SignedBeaconBlockHeader)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.shouldBeSlashable, proposerSlashing != nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSlashableAttestation(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
slasherDB := dbtest.SetupSlasherDB(t)
|
||||
|
||||
currentEpoch := primitives.Epoch(3)
|
||||
currentTime := time.Now()
|
||||
totalSlots := uint64(currentEpoch) * uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||
secondsSinceGenesis := time.Duration(totalSlots * params.BeaconConfig().SecondsPerSlot)
|
||||
genesisTime := currentTime.Add(-secondsSinceGenesis * time.Second)
|
||||
|
||||
s := &Service{
|
||||
serviceCfg: &ServiceConfig{
|
||||
Database: slasherDB,
|
||||
},
|
||||
params: DefaultParams(),
|
||||
blksQueue: newBlocksQueue(),
|
||||
genesisTime: genesisTime,
|
||||
latestEpochWrittenForValidator: map[primitives.ValidatorIndex]primitives.Epoch{},
|
||||
}
|
||||
prevAtts := []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 2, 3, []uint64{0}, []byte{1}),
|
||||
createAttestationWrapper(t, 2, 3, []uint64{1}, []byte{1}),
|
||||
}
|
||||
err := slasherDB.SaveAttestationRecordsForValidators(ctx, prevAtts)
|
||||
require.NoError(t, err)
|
||||
attesterSlashings, err := s.checkSlashableAttestations(ctx, currentEpoch, prevAtts)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(attesterSlashings))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
attToCheck *slashertypes.IndexedAttestationWrapper
|
||||
amtSlashable uint64
|
||||
}{
|
||||
{
|
||||
name: "should not detect if same attestation data",
|
||||
attToCheck: createAttestationWrapper(t, 2, 3, []uint64{1}, []byte{1}),
|
||||
amtSlashable: 0,
|
||||
},
|
||||
{
|
||||
name: "should not detect if different index",
|
||||
attToCheck: createAttestationWrapper(t, 0, 3, []uint64{2}, []byte{2}),
|
||||
amtSlashable: 0,
|
||||
},
|
||||
{
|
||||
name: "should detect double if same index",
|
||||
attToCheck: createAttestationWrapper(t, 0, 3, []uint64{0}, []byte{2}),
|
||||
amtSlashable: 1,
|
||||
},
|
||||
{
|
||||
name: "should detect multiple double if multiple same indices",
|
||||
attToCheck: createAttestationWrapper(t, 0, 3, []uint64{0, 1}, []byte{2}),
|
||||
amtSlashable: 2,
|
||||
},
|
||||
{
|
||||
name: "should detect multiple surround if multiple same indices",
|
||||
attToCheck: createAttestationWrapper(t, 1, 4, []uint64{0, 1}, []byte{2}),
|
||||
amtSlashable: 4,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
attesterSlashings, err = s.IsSlashableAttestation(ctx, tt.attToCheck.IndexedAttestation)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.amtSlashable, uint64(len(attesterSlashings)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_HighestAttestations(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
slasherDB := dbtest.SetupSlasherDB(t)
|
||||
|
||||
currentEpoch := primitives.Epoch(3)
|
||||
currentTime := time.Now()
|
||||
totalSlots := uint64(currentEpoch) * uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||
secondsSinceGenesis := time.Duration(totalSlots * params.BeaconConfig().SecondsPerSlot)
|
||||
genesisTime := currentTime.Add(-secondsSinceGenesis * time.Second)
|
||||
|
||||
s := &Service{
|
||||
serviceCfg: &ServiceConfig{
|
||||
Database: slasherDB,
|
||||
},
|
||||
params: DefaultParams(),
|
||||
blksQueue: newBlocksQueue(),
|
||||
genesisTime: genesisTime,
|
||||
}
|
||||
prevAtts := []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 1, []uint64{1}, []byte{1}),
|
||||
createAttestationWrapper(t, 2, 3, []uint64{2}, []byte{1}),
|
||||
}
|
||||
err := slasherDB.SaveAttestationRecordsForValidators(ctx, prevAtts)
|
||||
require.NoError(t, err)
|
||||
t.Run("single index not found", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{0})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(atts))
|
||||
})
|
||||
t.Run("single index case 1", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{1})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(atts))
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 1, HighestSourceEpoch: 0, HighestTargetEpoch: 1}, atts[0])
|
||||
})
|
||||
t.Run("single index case 2", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{2})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(atts))
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 2, HighestSourceEpoch: 2, HighestTargetEpoch: 3}, atts[0])
|
||||
})
|
||||
t.Run("multiple indices all found", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{1, 2})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(atts))
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 1, HighestSourceEpoch: 0, HighestTargetEpoch: 1}, atts[0])
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 2, HighestSourceEpoch: 2, HighestTargetEpoch: 3}, atts[1])
|
||||
})
|
||||
t.Run("multiple indices all not found", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{3, 4})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(atts))
|
||||
})
|
||||
t.Run("multiple indices some not found", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{1, 4})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(atts))
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 1, HighestSourceEpoch: 0, HighestTargetEpoch: 1}, atts[0])
|
||||
})
|
||||
}
|
||||
@@ -43,15 +43,6 @@ type ServiceConfig struct {
|
||||
ClockWaiter startup.ClockWaiter
|
||||
}
|
||||
|
||||
// SlashingChecker is an interface for defining services that the beacon node may interact with to provide slashing data.
|
||||
type SlashingChecker interface {
|
||||
IsSlashableBlock(ctx context.Context, proposal *ethpb.SignedBeaconBlockHeader) (*ethpb.ProposerSlashing, error)
|
||||
IsSlashableAttestation(ctx context.Context, attestation *ethpb.IndexedAttestation) ([]*ethpb.AttesterSlashing, error)
|
||||
HighestAttestations(
|
||||
ctx context.Context, indices []primitives.ValidatorIndex,
|
||||
) ([]*ethpb.HighestAttestation, error)
|
||||
}
|
||||
|
||||
// Service defining a slasher implementation as part of
|
||||
// the beacon node, able to detect eth2 slashable offenses.
|
||||
type Service struct {
|
||||
|
||||
@@ -19,8 +19,6 @@ import (
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
var _ = SlashingChecker(&Service{})
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetOutput(io.Discard)
|
||||
|
||||
@@ -15,19 +15,19 @@ const (
|
||||
)
|
||||
|
||||
// IndexedAttestationWrapper contains an indexed attestation with its
|
||||
// signing root to reduce duplicated computation.
|
||||
// data root to reduce duplicated computation.
|
||||
type IndexedAttestationWrapper struct {
|
||||
IndexedAttestation *ethpb.IndexedAttestation
|
||||
SigningRoot [32]byte
|
||||
DataRoot [32]byte
|
||||
}
|
||||
|
||||
// AttesterDoubleVote represents a double vote instance
|
||||
// which is a slashable event for attesters.
|
||||
type AttesterDoubleVote struct {
|
||||
Target primitives.Epoch
|
||||
ValidatorIndex primitives.ValidatorIndex
|
||||
PrevAttestationWrapper *IndexedAttestationWrapper
|
||||
AttestationWrapper *IndexedAttestationWrapper
|
||||
Target primitives.Epoch
|
||||
ValidatorIndex primitives.ValidatorIndex
|
||||
Wrapper_1 *IndexedAttestationWrapper
|
||||
Wrapper_2 *IndexedAttestationWrapper
|
||||
}
|
||||
|
||||
// DoubleBlockProposal containing an incoming and an existing proposal's signing root.
|
||||
@@ -39,10 +39,10 @@ type DoubleBlockProposal struct {
|
||||
}
|
||||
|
||||
// SignedBlockHeaderWrapper contains an signed beacon block header with its
|
||||
// signing root to reduce duplicated computation.
|
||||
// header root to reduce duplicated computation.
|
||||
type SignedBlockHeaderWrapper struct {
|
||||
SignedBeaconBlockHeader *ethpb.SignedBeaconBlockHeader
|
||||
SigningRoot [32]byte
|
||||
HeaderRoot [32]byte
|
||||
}
|
||||
|
||||
// AttestedEpochForValidator encapsulates a previously attested epoch
|
||||
|
||||
@@ -90,6 +90,7 @@ go_library(
|
||||
"//beacon-chain/startup:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/sync/backfill/coverage:go_default_library",
|
||||
"//beacon-chain/sync/verify:go_default_library",
|
||||
"//beacon-chain/verification:go_default_library",
|
||||
"//cache/lru:go_default_library",
|
||||
@@ -125,6 +126,7 @@ go_library(
|
||||
"@com_github_libp2p_go_libp2p//core/peer:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//core/protocol:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_pubsub//:go_default_library",
|
||||
"@com_github_libp2p_go_mplex//:go_default_library",
|
||||
"@com_github_patrickmn_go_cache//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
|
||||
@@ -3,9 +3,11 @@ package sync
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
libp2pcore "github.com/libp2p/go-libp2p/core"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
multiplex "github.com/libp2p/go-mplex"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/encoder"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/types"
|
||||
@@ -98,7 +100,7 @@ func readStatusCodeNoDeadline(stream network.Stream, encoding encoder.NetworkEnc
|
||||
func isValidStreamError(err error) bool {
|
||||
// check the error message itself as well as libp2p doesn't currently
|
||||
// return the correct error type from Close{Read,Write,}.
|
||||
return err != nil && !errors.Is(err, network.ErrReset) && err.Error() != network.ErrReset.Error()
|
||||
return err != nil && !isUnwantedError(err)
|
||||
}
|
||||
|
||||
func closeStream(stream network.Stream, log *logrus.Entry) {
|
||||
@@ -130,3 +132,12 @@ func closeStreamAndWait(stream network.Stream, log *logrus.Entry) {
|
||||
_err = stream.Close()
|
||||
_ = _err
|
||||
}
|
||||
|
||||
func isUnwantedError(err error) bool {
|
||||
for _, e := range []error{network.ErrReset, multiplex.ErrShutdown, io.EOF, types.ErrIODeadline} {
|
||||
if errors.Is(err, e) || err.Error() == e.Error() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const (
|
||||
skippedMachineTimeout = 10 * staleEpochTimeout
|
||||
// lookaheadSteps is a limit on how many forward steps are loaded into queue.
|
||||
// Each step is managed by assigned finite state machine. Must be >= 2.
|
||||
lookaheadSteps = 8
|
||||
lookaheadSteps = 4
|
||||
// noRequiredPeersErrMaxRetries defines number of retries when no required peers are found.
|
||||
noRequiredPeersErrMaxRetries = 1000
|
||||
// noRequiredPeersErrRefreshInterval defines interval for which queue will be paused before
|
||||
|
||||
@@ -874,7 +874,7 @@ func TestBlocksQueue_onProcessSkippedEvent(t *testing.T) {
|
||||
t.Run("ready to update machines - constrained mode", func(t *testing.T) {
|
||||
p := p2pt.NewTestP2P(t)
|
||||
connectPeers(t, p, []*peerData{
|
||||
{blocks: makeSequence(500, 628), finalizedEpoch: 16, headSlot: 600},
|
||||
{blocks: makeSequence(200, 320), finalizedEpoch: 8, headSlot: 300},
|
||||
}, p.Peers())
|
||||
fetcher := newBlocksFetcher(ctx, &blocksFetcherConfig{
|
||||
chain: mc,
|
||||
@@ -924,7 +924,7 @@ func TestBlocksQueue_onProcessSkippedEvent(t *testing.T) {
|
||||
t.Run("ready to update machines - unconstrained mode", func(t *testing.T) {
|
||||
p := p2pt.NewTestP2P(t)
|
||||
connectPeers(t, p, []*peerData{
|
||||
{blocks: makeSequence(500, 628), finalizedEpoch: 16, headSlot: 600},
|
||||
{blocks: makeSequence(200, 320), finalizedEpoch: 8, headSlot: 320},
|
||||
}, p.Peers())
|
||||
fetcher := newBlocksFetcher(ctx, &blocksFetcherConfig{
|
||||
chain: mc,
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/startup"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/backfill/coverage"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/verification"
|
||||
)
|
||||
|
||||
@@ -170,3 +171,12 @@ func WithVerifierWaiter(v *verification.InitializerWaiter) Option {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithAvailableBlocker allows the sync package to access the current
|
||||
// status of backfill.
|
||||
func WithAvailableBlocker(avb coverage.AvailableBlocker) Option {
|
||||
return func(s *Service) error {
|
||||
s.availableBlocker = avb
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,6 +244,9 @@ func (s *Service) registerRPC(baseTopic string, handle rpcHandler) {
|
||||
}
|
||||
|
||||
func logStreamErrors(err error, topic string) {
|
||||
if isUnwantedError(err) {
|
||||
return
|
||||
}
|
||||
if strings.Contains(topic, p2p.RPCGoodByeTopicV1) {
|
||||
log.WithError(err).WithField("topic", topic).Trace("Could not decode goodbye stream message")
|
||||
return
|
||||
|
||||
@@ -38,6 +38,13 @@ func (s *Service) beaconBlocksByRangeRPCHandler(ctx context.Context, msg interfa
|
||||
tracing.AnnotateError(span, err)
|
||||
return err
|
||||
}
|
||||
available := s.validateRangeAvailability(rp)
|
||||
if !available {
|
||||
log.Debug("error in validating range availability")
|
||||
s.writeErrorResponseToStream(responseCodeResourceUnavailable, p2ptypes.ErrResourceUnavailable.Error(), stream)
|
||||
tracing.AnnotateError(span, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
blockLimiter, err := s.rateLimiter.topicCollector(string(stream.Protocol()))
|
||||
if err != nil {
|
||||
@@ -126,6 +133,11 @@ func validateRangeRequest(r *pb.BeaconBlocksByRangeRequest, current primitives.S
|
||||
return rp, nil
|
||||
}
|
||||
|
||||
func (s *Service) validateRangeAvailability(rp rangeParams) bool {
|
||||
startBlock := rp.start
|
||||
return s.availableBlocker.AvailableBlock(startBlock)
|
||||
}
|
||||
|
||||
func (s *Service) writeBlockBatchToStream(ctx context.Context, batch blockBatch, stream libp2pcore.Stream) error {
|
||||
ctx, span := trace.StartSpan(ctx, "sync.WriteBlockRangeToStream")
|
||||
defer span.End()
|
||||
|
||||
@@ -64,7 +64,7 @@ func TestRPCBeaconBlocksByRange_RPCHandlerReturnsBlocks(t *testing.T) {
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
// Start service with 160 as allowed blocks capacity (and almost zero capacity recovery).
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
pcl := protocol.ID(p2p.RPCBlocksByRangeTopicV1)
|
||||
topic := string(pcl)
|
||||
r.rateLimiter.limiterMap[topic] = leakybucket.NewCollector(0.000001, int64(req.Count*10), time.Second, false)
|
||||
@@ -127,7 +127,7 @@ func TestRPCBeaconBlocksByRange_ReturnCorrectNumberBack(t *testing.T) {
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
// Start service with 160 as allowed blocks capacity (and almost zero capacity recovery).
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
pcl := protocol.ID(p2p.RPCBlocksByRangeTopicV1)
|
||||
topic := string(pcl)
|
||||
r.rateLimiter.limiterMap[topic] = leakybucket.NewCollector(0.000001, int64(req.Count*10), time.Second, false)
|
||||
@@ -244,7 +244,8 @@ func TestRPCBeaconBlocksByRange_ReconstructsPayloads(t *testing.T) {
|
||||
clock: clock,
|
||||
executionPayloadReconstructor: mockEngine,
|
||||
},
|
||||
rateLimiter: newRateLimiter(p1),
|
||||
rateLimiter: newRateLimiter(p1),
|
||||
availableBlocker: mockBlocker{avail: true},
|
||||
}
|
||||
pcl := protocol.ID(p2p.RPCBlocksByRangeTopicV1)
|
||||
topic := string(pcl)
|
||||
@@ -314,7 +315,7 @@ func TestRPCBeaconBlocksByRange_RPCHandlerReturnsSortedBlocks(t *testing.T) {
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
// Start service with 160 as allowed blocks capacity (and almost zero capacity recovery).
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
pcl := protocol.ID(p2p.RPCBlocksByRangeTopicV1)
|
||||
topic := string(pcl)
|
||||
r.rateLimiter.limiterMap[topic] = leakybucket.NewCollector(0.000001, int64(req.Count*10), time.Second, false)
|
||||
@@ -380,7 +381,7 @@ func TestRPCBeaconBlocksByRange_ReturnsGenesisBlock(t *testing.T) {
|
||||
}
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
pcl := protocol.ID(p2p.RPCBlocksByRangeTopicV1)
|
||||
topic := string(pcl)
|
||||
r.rateLimiter.limiterMap[topic] = leakybucket.NewCollector(10000, 10000, time.Second, false)
|
||||
@@ -472,7 +473,7 @@ func TestRPCBeaconBlocksByRange_RPCHandlerRateLimitOverflow(t *testing.T) {
|
||||
|
||||
capacity := int64(flags.Get().BlockBatchLimit * 3)
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
|
||||
pcl := protocol.ID(p2p.RPCBlocksByRangeTopicV1)
|
||||
topic := string(pcl)
|
||||
@@ -499,7 +500,7 @@ func TestRPCBeaconBlocksByRange_RPCHandlerRateLimitOverflow(t *testing.T) {
|
||||
|
||||
capacity := int64(flags.Get().BlockBatchLimit * 3)
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
|
||||
pcl := protocol.ID(p2p.RPCBlocksByRangeTopicV1)
|
||||
topic := string(pcl)
|
||||
@@ -530,7 +531,7 @@ func TestRPCBeaconBlocksByRange_RPCHandlerRateLimitOverflow(t *testing.T) {
|
||||
|
||||
capacity := int64(flags.Get().BlockBatchLimit * flags.Get().BlockBatchLimitBurstFactor)
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
pcl := protocol.ID(p2p.RPCBlocksByRangeTopicV1)
|
||||
topic := string(pcl)
|
||||
r.rateLimiter.limiterMap[topic] = leakybucket.NewCollector(0.000001, capacity, time.Second, false)
|
||||
@@ -722,7 +723,7 @@ func TestRPCBeaconBlocksByRange_EnforceResponseInvariants(t *testing.T) {
|
||||
assert.Equal(t, 1, len(p1.BHost.Network().Peers()), "Expected peers to be connected")
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
r.rateLimiter.limiterMap[string(pcl)] = leakybucket.NewCollector(0.000001, 640, time.Second, false)
|
||||
req := ðpb.BeaconBlocksByRangeRequest{
|
||||
StartSlot: 448,
|
||||
@@ -891,7 +892,7 @@ func TestRPCBeaconBlocksByRange_FilterBlocks(t *testing.T) {
|
||||
assert.Equal(t, 1, len(p1.BHost.Network().Peers()), "Expected peers to be connected")
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
r.rateLimiter.limiterMap[string(pcl)] = leakybucket.NewCollector(0.000001, 640, time.Second, false)
|
||||
req := ðpb.BeaconBlocksByRangeRequest{
|
||||
StartSlot: 1,
|
||||
@@ -923,7 +924,7 @@ func TestRPCBeaconBlocksByRange_FilterBlocks(t *testing.T) {
|
||||
assert.Equal(t, 1, len(p1.BHost.Network().Peers()), "Expected peers to be connected")
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, clock: clock, chain: &chainMock.ChainService{}}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
r.rateLimiter.limiterMap[string(pcl)] = leakybucket.NewCollector(0.000001, 640, time.Second, false)
|
||||
req := ðpb.BeaconBlocksByRangeRequest{
|
||||
StartSlot: 1,
|
||||
@@ -958,7 +959,7 @@ func TestRPCBeaconBlocksByRange_FilterBlocks(t *testing.T) {
|
||||
p1.Connect(p2)
|
||||
assert.Equal(t, 1, len(p1.BHost.Network().Peers()), "Expected peers to be connected")
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
r.rateLimiter.limiterMap[string(pcl)] = leakybucket.NewCollector(0.000001, 640, time.Second, false)
|
||||
req := ðpb.BeaconBlocksByRangeRequest{
|
||||
StartSlot: 1,
|
||||
@@ -994,7 +995,7 @@ func TestRPCBeaconBlocksByRange_FilterBlocks(t *testing.T) {
|
||||
assert.Equal(t, 1, len(p1.BHost.Network().Peers()), "Expected peers to be connected")
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
r.rateLimiter.limiterMap[string(pcl)] = leakybucket.NewCollector(0.000001, 640, time.Second, false)
|
||||
req := ðpb.BeaconBlocksByRangeRequest{
|
||||
StartSlot: 1,
|
||||
@@ -1035,7 +1036,7 @@ func TestRPCBeaconBlocksByRange_FilterBlocks(t *testing.T) {
|
||||
assert.Equal(t, 1, len(p1.BHost.Network().Peers()), "Expected peers to be connected")
|
||||
|
||||
clock := startup.NewClock(time.Unix(0, 0), [32]byte{})
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, rateLimiter: newRateLimiter(p1)}
|
||||
r := &Service{cfg: &config{p2p: p1, beaconDB: d, chain: &chainMock.ChainService{}, clock: clock}, availableBlocker: mockBlocker{avail: true}, rateLimiter: newRateLimiter(p1)}
|
||||
r.rateLimiter.limiterMap[string(pcl)] = leakybucket.NewCollector(0.000001, 640, time.Second, false)
|
||||
req := ðpb.BeaconBlocksByRangeRequest{
|
||||
StartSlot: 1,
|
||||
@@ -1105,3 +1106,11 @@ func TestRPCBeaconBlocksByRange_FilterBlocks_PreviousRoot(t *testing.T) {
|
||||
// pointer should reference a new root.
|
||||
require.NotEqual(t, cf.prevRoot, [32]byte{})
|
||||
}
|
||||
|
||||
type mockBlocker struct {
|
||||
avail bool
|
||||
}
|
||||
|
||||
func (m mockBlocker) AvailableBlock(_ primitives.Slot) bool {
|
||||
return m.avail
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ func (s *Service) reValidatePeer(ctx context.Context, id peer.ID) error {
|
||||
return err
|
||||
}
|
||||
// Do not return an error for ping requests.
|
||||
if err := s.sendPingRequest(ctx, id); err != nil {
|
||||
if err := s.sendPingRequest(ctx, id); err != nil && !isUnwantedError(err) {
|
||||
log.WithError(err).Debug("Could not ping peer")
|
||||
}
|
||||
return nil
|
||||
@@ -235,7 +235,7 @@ func (s *Service) statusRPCHandler(ctx context.Context, msg interface{}, stream
|
||||
resp, err := s.generateErrorResponse(respCode, err.Error())
|
||||
if err != nil {
|
||||
log.WithError(err).Debug("Could not generate a response error")
|
||||
} else if _, err := stream.Write(resp); err != nil {
|
||||
} else if _, err := stream.Write(resp); err != nil && !isUnwantedError(err) {
|
||||
// The peer may already be ignoring us, as we disagree on fork version, so log this as debug only.
|
||||
log.WithError(err).Debug("Could not write to stream")
|
||||
}
|
||||
@@ -273,7 +273,7 @@ func (s *Service) respondWithStatus(ctx context.Context, stream network.Stream)
|
||||
HeadSlot: s.cfg.chain.HeadSlot(),
|
||||
}
|
||||
|
||||
if _, err := stream.Write([]byte{responseCodeSuccess}); err != nil {
|
||||
if _, err := stream.Write([]byte{responseCodeSuccess}); err != nil && !isUnwantedError(err) {
|
||||
log.WithError(err).Debug("Could not write to stream")
|
||||
}
|
||||
_, err = s.cfg.p2p.Encoding().EncodeWithMaxLength(stream, resp)
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/startup"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/backfill/coverage"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/verification"
|
||||
lruwrpr "github.com/prysmaticlabs/prysm/v4/cache/lru"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
@@ -155,6 +156,7 @@ type Service struct {
|
||||
initialSyncComplete chan struct{}
|
||||
verifierWaiter *verification.InitializerWaiter
|
||||
newBlobVerifier verification.NewBlobVerifier
|
||||
availableBlocker coverage.AvailableBlocker
|
||||
}
|
||||
|
||||
// NewService initializes new regular sync service.
|
||||
|
||||
@@ -232,12 +232,28 @@ var (
|
||||
Usage: "Sets the minimum number of peers that a node will attempt to peer with that are subscribed to a subnet.",
|
||||
Value: 6,
|
||||
}
|
||||
|
||||
// SuggestedFeeRecipient specifies the fee recipient for the transaction fees.
|
||||
SuggestedFeeRecipient = &cli.StringFlag{
|
||||
Name: "suggested-fee-recipient",
|
||||
Usage: "Post bellatrix, this address will receive the transaction fees produced by any blocks from this node. Default to junk whilst bellatrix is in development state. Validator client can override this value through the preparebeaconproposer api.",
|
||||
Value: params.BeaconConfig().EthBurnAddressHex,
|
||||
}
|
||||
// ProposerSettingsFlag defines the path or URL to a file with proposer config.
|
||||
ProposerSettingsFlag = &cli.StringFlag{
|
||||
Name: "proposer-settings-file",
|
||||
Usage: `Sets path to a YAML or JSON file containing validator settings used when proposing blocks such as
|
||||
fee recipient and gas limit. File format found in docs.`,
|
||||
Value: "",
|
||||
}
|
||||
// ProposerSettingsURLFlag defines the path or URL to a file with proposer config.
|
||||
ProposerSettingsURLFlag = &cli.StringFlag{
|
||||
Name: "proposer-settings-url",
|
||||
Usage: `Sets URL to a REST endpoint containing validator settings used when proposing blocks such as
|
||||
fee recipient and gas limit. File format found in docs`,
|
||||
Value: "",
|
||||
}
|
||||
|
||||
// TerminalTotalDifficultyOverride specifies the total difficulty to manual overrides the `TERMINAL_TOTAL_DIFFICULTY` parameter.
|
||||
TerminalTotalDifficultyOverride = &cli.StringFlag{
|
||||
Name: "terminal-total-difficulty-override",
|
||||
|
||||
@@ -72,6 +72,8 @@ var appFlags = []cli.Flag{
|
||||
flags.Eth1HeaderReqLimit,
|
||||
flags.MinPeersPerSubnet,
|
||||
flags.SuggestedFeeRecipient,
|
||||
flags.ProposerSettingsFlag,
|
||||
flags.ProposerSettingsURLFlag,
|
||||
flags.TerminalTotalDifficultyOverride,
|
||||
flags.TerminalBlockHashOverride,
|
||||
flags.TerminalBlockHashActivationEpochOverride,
|
||||
|
||||
@@ -130,6 +130,9 @@ var appHelpFlagGroups = []flagGroup{
|
||||
flags.SlasherDirFlag,
|
||||
flags.LocalBlockValueBoost,
|
||||
flags.JwtId,
|
||||
flags.SuggestedFeeRecipient,
|
||||
flags.ProposerSettingsFlag,
|
||||
flags.ProposerSettingsURLFlag,
|
||||
checkpoint.BlockPath,
|
||||
checkpoint.StatePath,
|
||||
checkpoint.RemoteURL,
|
||||
@@ -145,7 +148,6 @@ var appHelpFlagGroups = []flagGroup{
|
||||
{
|
||||
Name: "merge",
|
||||
Flags: []cli.Flag{
|
||||
flags.SuggestedFeeRecipient,
|
||||
flags.TerminalTotalDifficultyOverride,
|
||||
flags.TerminalBlockHashOverride,
|
||||
flags.TerminalBlockHashActivationEpochOverride,
|
||||
|
||||
@@ -26,7 +26,7 @@ go_library(
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"//io/prompt:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"//proto/prysm/config:go_default_library",
|
||||
"//runtime/tos:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_logrusorgru_aurora//:go_default_library",
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/io/file"
|
||||
"github.com/prysmaticlabs/prysm/v4/io/prompt"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||
proposersettings "github.com/prysmaticlabs/prysm/v4/proto/prysm/config"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -68,25 +68,25 @@ func getProposerSettings(c *cli.Context, r io.Reader) error {
|
||||
|
||||
if c.IsSet(ProposerSettingsOutputFlag.Name) {
|
||||
log.Infof("The default fee recipient is set to %s", defaultFeeRecipient)
|
||||
var builderSettings *validatorpb.BuilderConfig
|
||||
var builderSettings *proposersettings.BuilderConfig
|
||||
if c.Bool(WithBuilderFlag.Name) {
|
||||
builderSettings = &validatorpb.BuilderConfig{
|
||||
builderSettings = &proposersettings.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorType.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
}
|
||||
} else {
|
||||
log.Infof("Default builder settings can be included with the `--%s` flag", WithBuilderFlag.Name)
|
||||
}
|
||||
proposerConfig := make(map[string]*validatorpb.ProposerOptionPayload)
|
||||
proposerConfig := make(map[string]*proposersettings.ProposerOptionPayload)
|
||||
for index, val := range validators {
|
||||
proposerConfig[val] = &validatorpb.ProposerOptionPayload{
|
||||
proposerConfig[val] = &proposersettings.ProposerOptionPayload{
|
||||
FeeRecipient: feeRecipients[index],
|
||||
Builder: builderSettings,
|
||||
}
|
||||
}
|
||||
fileConfig := &validatorpb.ProposerSettingsPayload{
|
||||
fileConfig := &proposersettings.ProposerSettingsPayload{
|
||||
ProposerConfig: proposerConfig,
|
||||
DefaultConfig: &validatorpb.ProposerOptionPayload{
|
||||
DefaultConfig: &proposersettings.ProposerOptionPayload{
|
||||
FeeRecipient: defaultFeeRecipient,
|
||||
Builder: builderSettings,
|
||||
},
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
config_setting(
|
||||
name = "mainnet",
|
||||
flag_values = {
|
||||
@@ -11,3 +13,15 @@ config_setting(
|
||||
"//proto:network": "minimal",
|
||||
},
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["util.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/config",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/util/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -12,37 +12,6 @@ var (
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedDisableVecHTR = &cli.BoolFlag{
|
||||
Name: "disable-vectorized-htr",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedEnableReorgLateBlocks = &cli.BoolFlag{
|
||||
Name: "enable-reorg-late-blocks",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedDisableGossipBatchAggregation = &cli.BoolFlag{
|
||||
Name: "disable-gossip-batch-aggregation",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedBuildBlockParallel = &cli.BoolFlag{
|
||||
Name: "build-block-parallel",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
deprecatedEnableRegistrationCache = &cli.BoolFlag{
|
||||
Name: "enable-registration-cache",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedAggregateParallel = &cli.BoolFlag{
|
||||
Name: "aggregate-parallel",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedEnableOptionalEngineMethods = &cli.BoolFlag{
|
||||
Name: "enable-optional-engine-methods",
|
||||
Usage: deprecatedUsage,
|
||||
@@ -83,12 +52,6 @@ var (
|
||||
// Deprecated flags for both the beacon node and validator client.
|
||||
var deprecatedFlags = []cli.Flag{
|
||||
exampleDeprecatedFeatureFlag,
|
||||
deprecatedDisableVecHTR,
|
||||
deprecatedEnableReorgLateBlocks,
|
||||
deprecatedDisableGossipBatchAggregation,
|
||||
deprecatedBuildBlockParallel,
|
||||
deprecatedEnableRegistrationCache,
|
||||
deprecatedAggregateParallel,
|
||||
deprecatedEnableOptionalEngineMethods,
|
||||
deprecatedDisableBuildBlockParallel,
|
||||
deprecatedDisableReorgLateBlocks,
|
||||
|
||||
@@ -27,6 +27,8 @@ var placeholderFields = []string{
|
||||
"EIP6110_FORK_VERSION",
|
||||
"EIP7002_FORK_EPOCH",
|
||||
"EIP7002_FORK_VERSION",
|
||||
"EIP7594_FORK_EPOCH",
|
||||
"EIP7594_FORK_VERSION",
|
||||
"MAX_BLOBS_PER_BLOCK",
|
||||
"REORG_HEAD_WEIGHT_THRESHOLD",
|
||||
"UPDATE_TIMEOUT",
|
||||
|
||||
@@ -3,16 +3,17 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["proposer_settings.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/config/validator/service",
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/config/proposer",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"//proto/prysm/config:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package validator_service_config
|
||||
package proposer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -9,11 +9,12 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||
proposersettings "github.com/prysmaticlabs/prysm/v4/proto/prysm/config"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ToSettings converts struct to ProposerSettings
|
||||
func ToSettings(ps *validatorpb.ProposerSettingsPayload) (*ProposerSettings, error) {
|
||||
func ToSettings(ps *proposersettings.ProposerSettingsPayload) (*ProposerSettings, error) {
|
||||
settings := &ProposerSettings{}
|
||||
if ps.ProposerConfig != nil {
|
||||
settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption)
|
||||
@@ -60,7 +61,7 @@ type BuilderConfig struct {
|
||||
}
|
||||
|
||||
// ToBuilderConfig converts protobuf to a builder config used in inmemory storage
|
||||
func ToBuilderConfig(from *validatorpb.BuilderConfig) *BuilderConfig {
|
||||
func ToBuilderConfig(from *proposersettings.BuilderConfig) *BuilderConfig {
|
||||
if from == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -78,7 +79,7 @@ func ToBuilderConfig(from *validatorpb.BuilderConfig) *BuilderConfig {
|
||||
}
|
||||
|
||||
// ProposerSettings is a Prysm internal representation of the fee recipient config on the validator client.
|
||||
// validatorpb.ProposerSettingsPayload maps to ProposerSettings on import through the CLI.
|
||||
// proposersettings.ProposerSettingsPayload maps to ProposerSettings on import through the CLI.
|
||||
type ProposerSettings struct {
|
||||
ProposeConfig map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption
|
||||
DefaultConfig *ProposerOption
|
||||
@@ -94,15 +95,15 @@ func (settings *ProposerSettings) ShouldBeSaved() bool {
|
||||
}
|
||||
|
||||
// ToPayload converts struct to ProposerSettingsPayload
|
||||
func (ps *ProposerSettings) ToPayload() *validatorpb.ProposerSettingsPayload {
|
||||
func (ps *ProposerSettings) ToPayload() *proposersettings.ProposerSettingsPayload {
|
||||
if ps == nil {
|
||||
return nil
|
||||
}
|
||||
payload := &validatorpb.ProposerSettingsPayload{}
|
||||
payload := &proposersettings.ProposerSettingsPayload{}
|
||||
if ps.ProposeConfig != nil {
|
||||
payload.ProposerConfig = make(map[string]*validatorpb.ProposerOptionPayload)
|
||||
payload.ProposerConfig = make(map[string]*proposersettings.ProposerOptionPayload)
|
||||
for key, option := range ps.ProposeConfig {
|
||||
p := &validatorpb.ProposerOptionPayload{}
|
||||
p := &proposersettings.ProposerOptionPayload{}
|
||||
if option.FeeRecipientConfig != nil {
|
||||
p.FeeRecipient = option.FeeRecipientConfig.FeeRecipient.Hex()
|
||||
}
|
||||
@@ -113,7 +114,7 @@ func (ps *ProposerSettings) ToPayload() *validatorpb.ProposerSettingsPayload {
|
||||
}
|
||||
}
|
||||
if ps.DefaultConfig != nil {
|
||||
p := &validatorpb.ProposerOptionPayload{}
|
||||
p := &proposersettings.ProposerOptionPayload{}
|
||||
if ps.DefaultConfig.FeeRecipientConfig != nil {
|
||||
p.FeeRecipient = ps.DefaultConfig.FeeRecipientConfig.FeeRecipient.Hex()
|
||||
}
|
||||
@@ -183,11 +184,11 @@ func (bc *BuilderConfig) Clone() *BuilderConfig {
|
||||
}
|
||||
|
||||
// ToPayload converts Builder Config to the protobuf object
|
||||
func (bc *BuilderConfig) ToPayload() *validatorpb.BuilderConfig {
|
||||
func (bc *BuilderConfig) ToPayload() *proposersettings.BuilderConfig {
|
||||
if bc == nil {
|
||||
return nil
|
||||
}
|
||||
config := &validatorpb.BuilderConfig{}
|
||||
config := &proposersettings.BuilderConfig{}
|
||||
config.Enabled = bc.Enabled
|
||||
var relays []string
|
||||
if bc.Relays != nil {
|
||||
@@ -213,3 +214,30 @@ func (po *ProposerOption) Clone() *ProposerOption {
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func VerifyOption(key string, option *proposersettings.ProposerOptionPayload) error {
|
||||
if option == nil {
|
||||
return fmt.Errorf("fee recipient is required for proposer %s", key)
|
||||
}
|
||||
if !common.IsHexAddress(option.FeeRecipient) {
|
||||
return errors.New("fee recipient is not a valid eth1 address")
|
||||
}
|
||||
if err := WarnNonChecksummedAddress(option.FeeRecipient); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func WarnNonChecksummedAddress(feeRecipient string) error {
|
||||
mixedcaseAddress, err := common.NewMixedcaseAddressFromString(feeRecipient)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not decode fee recipient %s", feeRecipient)
|
||||
}
|
||||
if !mixedcaseAddress.ValidChecksum() {
|
||||
log.Warnf("Fee recipient %s is not a checksum Ethereum address. "+
|
||||
"The checksummed address is %s and will be used as the fee recipient. "+
|
||||
"We recommend using a mixed-case address (checksum) "+
|
||||
"to prevent spelling mistakes in your fee recipient Ethereum address", feeRecipient, mixedcaseAddress.Address().Hex())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package validator_service_config
|
||||
package proposer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
65
config/util.go
Normal file
65
config/util.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
func UnmarshalFromURL(ctx context.Context, from string, to interface{}) error {
|
||||
u, err := url.ParseRequestURI(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if u.Scheme == "" || u.Host == "" {
|
||||
return fmt.Errorf("invalid URL: %s", from)
|
||||
}
|
||||
req, reqerr := http.NewRequestWithContext(ctx, http.MethodGet, from, nil)
|
||||
if reqerr != nil {
|
||||
return errors.Wrap(reqerr, "failed to create http request")
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, resperr := http.DefaultClient.Do(req)
|
||||
if resperr != nil {
|
||||
return errors.Wrap(resperr, "failed to send http request")
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
err = Body.Close()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("failed to close response body")
|
||||
}
|
||||
}(resp.Body)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return errors.Errorf("http request to %v failed with status code %d", from, resp.StatusCode)
|
||||
}
|
||||
if decodeerr := json.NewDecoder(resp.Body).Decode(&to); decodeerr != nil {
|
||||
return errors.Wrap(decodeerr, "failed to decode http response")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalFromFile(ctx context.Context, from string, to interface{}) error {
|
||||
if ctx == nil {
|
||||
return errors.New("node: nil context passed to unmarshalFromFile")
|
||||
}
|
||||
cleanpath := filepath.Clean(from)
|
||||
b, err := os.ReadFile(cleanpath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to open file")
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(b, to); err != nil {
|
||||
return errors.Wrap(err, "failed to unmarshal yaml file")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
2
go.mod
2
go.mod
@@ -47,6 +47,7 @@ require (
|
||||
github.com/libp2p/go-libp2p v0.32.1
|
||||
github.com/libp2p/go-libp2p-mplex v0.9.0
|
||||
github.com/libp2p/go-libp2p-pubsub v0.10.0
|
||||
github.com/libp2p/go-mplex v0.7.0
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/manifoldco/promptui v0.7.0
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
|
||||
@@ -171,7 +172,6 @@ require (
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
|
||||
github.com/libp2p/go-mplex v0.7.0 // indirect
|
||||
github.com/libp2p/go-msgio v0.3.0 // indirect
|
||||
github.com/libp2p/go-nat v0.2.0 // indirect
|
||||
github.com/libp2p/go-netroute v0.2.1 // indirect
|
||||
|
||||
@@ -215,15 +215,17 @@ message Withdrawal {
|
||||
message BlobsBundle {
|
||||
// The KZG commitments of the blobs.
|
||||
repeated bytes kzg_commitments = 1 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
|
||||
|
||||
// The proofs of the blobs.
|
||||
repeated bytes proofs = 2 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
|
||||
|
||||
// The blobs itself.
|
||||
repeated bytes blobs = 3 [(ethereum.eth.ext.ssz_size) = "?,131072", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
|
||||
repeated bytes blobs = 3 [(ethereum.eth.ext.ssz_size) = "?,blob.size", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
|
||||
}
|
||||
|
||||
// Blob contains the data that is to be committed on chain.
|
||||
message Blob {
|
||||
// Each blob consists of `BLS_FIELD_ELEMENT`(32) multiplies `FIELD_ELEMENTS_PER_BLOB`(4096)
|
||||
// The blob bytes.
|
||||
bytes data = 1 [(ethereum.eth.ext.ssz_size) = "blob.size"];
|
||||
}
|
||||
|
||||
|
||||
@@ -331,7 +331,7 @@ message BeaconBlockBodyBellatrix {
|
||||
// At most MAX_VOLUNTARY_EXITS.
|
||||
repeated v1.SignedVoluntaryExit voluntary_exits = 8 [(ethereum.eth.ext.ssz_max) = "16"];
|
||||
|
||||
// Sync aggregate object to track sync committee votes for light client support.
|
||||
// Sync aggregate object to track sync committee votes for light client support.
|
||||
v1.SyncAggregate sync_aggregate = 9;
|
||||
|
||||
// Execution payload: the embedded execution payload of the block [New in Bellatrix]
|
||||
@@ -523,7 +523,7 @@ message BeaconBlockBodyDeneb {
|
||||
// At most MAX_BLS_TO_EXECUTION_CHANGES. New in Capella network upgrade.
|
||||
repeated SignedBLSToExecutionChange bls_to_execution_changes = 11 [(ethereum.eth.ext.ssz_max) = "16"];
|
||||
|
||||
// At most MAX_BLOBS_PER_BLOCK. New in Deneb network upgrade.
|
||||
// At most MAX_BLOB_COMMITMENTS_PER_BLOCK. New in Deneb network upgrade.
|
||||
repeated bytes blob_kzg_commitments = 12 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
|
||||
}
|
||||
|
||||
|
||||
48
proto/prysm/config/BUILD.bazel
Normal file
48
proto/prysm/config/BUILD.bazel
Normal file
@@ -0,0 +1,48 @@
|
||||
##############################################################################
|
||||
# Common
|
||||
##############################################################################
|
||||
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
|
||||
##############################################################################
|
||||
# Go
|
||||
##############################################################################
|
||||
# gazelle:ignore
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
|
||||
|
||||
proto_library(
|
||||
name = "proposersettings_proto",
|
||||
srcs = ["proposer_settings.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//proto/eth/ext:proto",
|
||||
"@com_google_protobuf//:any_proto",
|
||||
"@com_google_protobuf//:descriptor_proto",
|
||||
"@com_google_protobuf//:empty_proto",
|
||||
"@com_google_protobuf//:timestamp_proto",
|
||||
"@googleapis//google/api:annotations_proto",
|
||||
],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "proposersettings_go_proto",
|
||||
compilers = [
|
||||
"@com_github_prysmaticlabs_protoc_gen_go_cast//:go_cast_grpc",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/proto/prysm/config",
|
||||
proto = ":proposersettings_proto",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//proto/eth/ext:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
embed = [":proposersettings_go_proto"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/proto/prysm/config",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
350
proto/prysm/config/proposer_settings.pb.go
generated
Executable file
350
proto/prysm/config/proposer_settings.pb.go
generated
Executable file
@@ -0,0 +1,350 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v4.25.1
|
||||
// source: proto/prysm/config/proposer_settings.proto
|
||||
|
||||
package proposersettings
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
|
||||
github_com_prysmaticlabs_prysm_v4_consensus_types_validator "github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
_ "github.com/prysmaticlabs/prysm/v4/proto/eth/ext"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ProposerOptionPayload struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
FeeRecipient string `protobuf:"bytes,1,opt,name=fee_recipient,json=feeRecipient,proto3" json:"fee_recipient,omitempty"`
|
||||
Builder *BuilderConfig `protobuf:"bytes,2,opt,name=builder,proto3" json:"builder,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) Reset() {
|
||||
*x = ProposerOptionPayload{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_config_proposer_settings_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ProposerOptionPayload) ProtoMessage() {}
|
||||
|
||||
func (x *ProposerOptionPayload) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_config_proposer_settings_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ProposerOptionPayload.ProtoReflect.Descriptor instead.
|
||||
func (*ProposerOptionPayload) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_config_proposer_settings_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) GetFeeRecipient() string {
|
||||
if x != nil {
|
||||
return x.FeeRecipient
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) GetBuilder() *BuilderConfig {
|
||||
if x != nil {
|
||||
return x.Builder
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BuilderConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
GasLimit github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64 `protobuf:"varint,2,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v4/consensus-types/validator.Uint64"`
|
||||
Relays []string `protobuf:"bytes,3,rep,name=relays,proto3" json:"relays,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) Reset() {
|
||||
*x = BuilderConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_config_proposer_settings_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BuilderConfig) ProtoMessage() {}
|
||||
|
||||
func (x *BuilderConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_config_proposer_settings_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BuilderConfig.ProtoReflect.Descriptor instead.
|
||||
func (*BuilderConfig) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_config_proposer_settings_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetEnabled() bool {
|
||||
if x != nil {
|
||||
return x.Enabled
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetGasLimit() github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64 {
|
||||
if x != nil {
|
||||
return x.GasLimit
|
||||
}
|
||||
return github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64(0)
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetRelays() []string {
|
||||
if x != nil {
|
||||
return x.Relays
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ProposerSettingsPayload struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ProposerConfig map[string]*ProposerOptionPayload `protobuf:"bytes,1,rep,name=proposer_config,json=proposerConfig,proto3" json:"proposer_config,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
DefaultConfig *ProposerOptionPayload `protobuf:"bytes,2,opt,name=default_config,json=defaultConfig,proto3" json:"default_config,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) Reset() {
|
||||
*x = ProposerSettingsPayload{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_config_proposer_settings_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ProposerSettingsPayload) ProtoMessage() {}
|
||||
|
||||
func (x *ProposerSettingsPayload) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_config_proposer_settings_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ProposerSettingsPayload.ProtoReflect.Descriptor instead.
|
||||
func (*ProposerSettingsPayload) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_config_proposer_settings_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) GetProposerConfig() map[string]*ProposerOptionPayload {
|
||||
if x != nil {
|
||||
return x.ProposerConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) GetDefaultConfig() *ProposerOptionPayload {
|
||||
if x != nil {
|
||||
return x.DefaultConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_proto_prysm_config_proposer_settings_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_prysm_config_proposer_settings_proto_rawDesc = []byte{
|
||||
0x0a, 0x2a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65,
|
||||
0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x1b, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f, 0x6f, 0x70, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x76, 0x0a, 0x15, 0x50, 0x72,
|
||||
0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c,
|
||||
0x6f, 0x61, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70,
|
||||
0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x52,
|
||||
0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c,
|
||||
0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75, 0x69, 0x6c,
|
||||
0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64,
|
||||
0x65, 0x72, 0x22, 0xa6, 0x01, 0x0a, 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x63,
|
||||
0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
|
||||
0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73,
|
||||
0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
|
||||
0x6f, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x22, 0xba, 0x02, 0x0a, 0x17,
|
||||
0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
|
||||
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x65, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f,
|
||||
0x73, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x3c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69,
|
||||
0x6e, 0x67, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f,
|
||||
0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e,
|
||||
0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4d,
|
||||
0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||
0x6d, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65,
|
||||
0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0d,
|
||||
0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x69, 0x0a,
|
||||
0x13, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72,
|
||||
0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x99, 0x01, 0x0a, 0x13, 0x6f, 0x72, 0x67,
|
||||
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x42, 0x15, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
||||
0x67, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c,
|
||||
0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3b,
|
||||
0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
|
||||
0xaa, 0x02, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0xca, 0x02, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_proto_prysm_config_proposer_settings_proto_rawDescOnce sync.Once
|
||||
file_proto_prysm_config_proposer_settings_proto_rawDescData = file_proto_prysm_config_proposer_settings_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_proto_prysm_config_proposer_settings_proto_rawDescGZIP() []byte {
|
||||
file_proto_prysm_config_proposer_settings_proto_rawDescOnce.Do(func() {
|
||||
file_proto_prysm_config_proposer_settings_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_prysm_config_proposer_settings_proto_rawDescData)
|
||||
})
|
||||
return file_proto_prysm_config_proposer_settings_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_prysm_config_proposer_settings_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_proto_prysm_config_proposer_settings_proto_goTypes = []interface{}{
|
||||
(*ProposerOptionPayload)(nil), // 0: ethereum.config.ProposerOptionPayload
|
||||
(*BuilderConfig)(nil), // 1: ethereum.config.BuilderConfig
|
||||
(*ProposerSettingsPayload)(nil), // 2: ethereum.config.ProposerSettingsPayload
|
||||
nil, // 3: ethereum.config.ProposerSettingsPayload.ProposerConfigEntry
|
||||
}
|
||||
var file_proto_prysm_config_proposer_settings_proto_depIdxs = []int32{
|
||||
1, // 0: ethereum.config.ProposerOptionPayload.builder:type_name -> ethereum.config.BuilderConfig
|
||||
3, // 1: ethereum.config.ProposerSettingsPayload.proposer_config:type_name -> ethereum.config.ProposerSettingsPayload.ProposerConfigEntry
|
||||
0, // 2: ethereum.config.ProposerSettingsPayload.default_config:type_name -> ethereum.config.ProposerOptionPayload
|
||||
0, // 3: ethereum.config.ProposerSettingsPayload.ProposerConfigEntry.value:type_name -> ethereum.config.ProposerOptionPayload
|
||||
4, // [4:4] is the sub-list for method output_type
|
||||
4, // [4:4] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_prysm_config_proposer_settings_proto_init() }
|
||||
func file_proto_prysm_config_proposer_settings_proto_init() {
|
||||
if File_proto_prysm_config_proposer_settings_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_prysm_config_proposer_settings_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ProposerOptionPayload); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_config_proposer_settings_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BuilderConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_config_proposer_settings_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ProposerSettingsPayload); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_prysm_config_proposer_settings_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_proto_prysm_config_proposer_settings_proto_goTypes,
|
||||
DependencyIndexes: file_proto_prysm_config_proposer_settings_proto_depIdxs,
|
||||
MessageInfos: file_proto_prysm_config_proposer_settings_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_prysm_config_proposer_settings_proto = out.File
|
||||
file_proto_prysm_config_proposer_settings_proto_rawDesc = nil
|
||||
file_proto_prysm_config_proposer_settings_proto_goTypes = nil
|
||||
file_proto_prysm_config_proposer_settings_proto_depIdxs = nil
|
||||
}
|
||||
30
proto/prysm/config/proposer_settings.proto
Normal file
30
proto/prysm/config/proposer_settings.proto
Normal file
@@ -0,0 +1,30 @@
|
||||
syntax = "proto3";
|
||||
package ethereum.config;
|
||||
|
||||
import "proto/eth/ext/options.proto";
|
||||
|
||||
option csharp_namespace = "Ethereum.Config";
|
||||
option go_package = "github.com/prysmaticlabs/prysm/v4/proto/prysm/config;proposersettings";
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "ProposerSettingsProto";
|
||||
option java_package = "org.ethereum.config";
|
||||
option php_namespace = "Ethereum\\config";
|
||||
|
||||
// ProposerOptionPayload is a property of ProposerSettingsPayload
|
||||
message ProposerOptionPayload {
|
||||
string fee_recipient = 1;
|
||||
BuilderConfig builder = 2;
|
||||
}
|
||||
|
||||
// BuilderConfig is a property of ProposerOptionPayload
|
||||
message BuilderConfig {
|
||||
bool enabled = 1;
|
||||
uint64 gas_limit = 2 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v4/consensus-types/validator.Uint64"];
|
||||
repeated string relays = 3;
|
||||
}
|
||||
|
||||
// ProposerSettingsPayload is used to unmarshal files sent from the validator flag as well as safe to bolt db bucket
|
||||
message ProposerSettingsPayload {
|
||||
map<string, ProposerOptionPayload> proposer_config = 1;
|
||||
ProposerOptionPayload default_config = 2;
|
||||
}
|
||||
@@ -35,8 +35,8 @@ proto_library(
|
||||
"@com_google_protobuf//:any_proto",
|
||||
"@com_google_protobuf//:descriptor_proto",
|
||||
"@com_google_protobuf//:empty_proto",
|
||||
"@com_google_protobuf//:wrappers_proto",
|
||||
"@com_google_protobuf//:timestamp_proto",
|
||||
"@com_google_protobuf//:wrappers_proto",
|
||||
"@googleapis//google/api:annotations_proto",
|
||||
],
|
||||
)
|
||||
@@ -130,6 +130,7 @@ ssz_gen_marshal(
|
||||
"BlobSidecar",
|
||||
"BlobSidecars",
|
||||
"BlobIdentifier",
|
||||
"DepositSnapshot",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -155,8 +156,8 @@ go_proto_library(
|
||||
"@org_golang_google_protobuf//runtime/protoimpl:go_default_library",
|
||||
"@org_golang_google_protobuf//types/descriptorpb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/wrapperspb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/wrapperspb:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -176,8 +177,8 @@ go_proto_library(
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@googleapis//google/api:annotations_go_proto",
|
||||
"@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
|
||||
"@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
|
||||
"@io_bazel_rules_go//proto/wkt:timestamp_go_proto",
|
||||
"@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
|
||||
"@org_golang_google_protobuf//types/descriptorpb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
],
|
||||
|
||||
@@ -710,7 +710,7 @@ message BlindedBeaconBlockBodyDeneb {
|
||||
// Execution payload header from the execution chain. New in Bellatrix network upgrade to accommodate MEV interaction.
|
||||
ethereum.engine.v1.ExecutionPayloadHeaderDeneb execution_payload_header = 10;
|
||||
|
||||
// At most MAX_BLS_TO_EXECUTION_CHANGES. New in Deneb network upgrade.
|
||||
// At most MAX_BLS_TO_EXECUTION_CHANGES. New in Capella network upgrade.
|
||||
repeated SignedBLSToExecutionChange bls_to_execution_changes = 11 [(ethereum.eth.ext.ssz_max) = "16"];
|
||||
|
||||
repeated bytes blob_kzg_commitments = 12 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: 28837d1c80ab7592d4877ebbd9881adf756b7da77c5614263c8442c2b3dea5c2
|
||||
// Hash: 277e239dcf280a4b2a1912458e9a7cd90ba4332d1fc1c6148c105fa481f9c66f
|
||||
package eth
|
||||
|
||||
import (
|
||||
@@ -15648,6 +15648,182 @@ func (b *BlobSidecarsByRangeRequest) HashTreeRootWith(hh *ssz.Hasher) (err error
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalSSZ ssz marshals the DepositSnapshot object
|
||||
func (d *DepositSnapshot) MarshalSSZ() ([]byte, error) {
|
||||
return ssz.MarshalSSZ(d)
|
||||
}
|
||||
|
||||
// MarshalSSZTo ssz marshals the DepositSnapshot object to a target array
|
||||
func (d *DepositSnapshot) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
||||
dst = buf
|
||||
offset := int(84)
|
||||
|
||||
// Offset (0) 'Finalized'
|
||||
dst = ssz.WriteOffset(dst, offset)
|
||||
offset += len(d.Finalized) * 32
|
||||
|
||||
// Field (1) 'DepositRoot'
|
||||
if size := len(d.DepositRoot); size != 32 {
|
||||
err = ssz.ErrBytesLengthFn("--.DepositRoot", size, 32)
|
||||
return
|
||||
}
|
||||
dst = append(dst, d.DepositRoot...)
|
||||
|
||||
// Field (2) 'DepositCount'
|
||||
dst = ssz.MarshalUint64(dst, d.DepositCount)
|
||||
|
||||
// Field (3) 'ExecutionHash'
|
||||
if size := len(d.ExecutionHash); size != 32 {
|
||||
err = ssz.ErrBytesLengthFn("--.ExecutionHash", size, 32)
|
||||
return
|
||||
}
|
||||
dst = append(dst, d.ExecutionHash...)
|
||||
|
||||
// Field (4) 'ExecutionDepth'
|
||||
dst = ssz.MarshalUint64(dst, d.ExecutionDepth)
|
||||
|
||||
// Field (0) 'Finalized'
|
||||
if size := len(d.Finalized); size > 32 {
|
||||
err = ssz.ErrListTooBigFn("--.Finalized", size, 32)
|
||||
return
|
||||
}
|
||||
for ii := 0; ii < len(d.Finalized); ii++ {
|
||||
if size := len(d.Finalized[ii]); size != 32 {
|
||||
err = ssz.ErrBytesLengthFn("--.Finalized[ii]", size, 32)
|
||||
return
|
||||
}
|
||||
dst = append(dst, d.Finalized[ii]...)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalSSZ ssz unmarshals the DepositSnapshot object
|
||||
func (d *DepositSnapshot) UnmarshalSSZ(buf []byte) error {
|
||||
var err error
|
||||
size := uint64(len(buf))
|
||||
if size < 84 {
|
||||
return ssz.ErrSize
|
||||
}
|
||||
|
||||
tail := buf
|
||||
var o0 uint64
|
||||
|
||||
// Offset (0) 'Finalized'
|
||||
if o0 = ssz.ReadOffset(buf[0:4]); o0 > size {
|
||||
return ssz.ErrOffset
|
||||
}
|
||||
|
||||
if o0 < 84 {
|
||||
return ssz.ErrInvalidVariableOffset
|
||||
}
|
||||
|
||||
// Field (1) 'DepositRoot'
|
||||
if cap(d.DepositRoot) == 0 {
|
||||
d.DepositRoot = make([]byte, 0, len(buf[4:36]))
|
||||
}
|
||||
d.DepositRoot = append(d.DepositRoot, buf[4:36]...)
|
||||
|
||||
// Field (2) 'DepositCount'
|
||||
d.DepositCount = ssz.UnmarshallUint64(buf[36:44])
|
||||
|
||||
// Field (3) 'ExecutionHash'
|
||||
if cap(d.ExecutionHash) == 0 {
|
||||
d.ExecutionHash = make([]byte, 0, len(buf[44:76]))
|
||||
}
|
||||
d.ExecutionHash = append(d.ExecutionHash, buf[44:76]...)
|
||||
|
||||
// Field (4) 'ExecutionDepth'
|
||||
d.ExecutionDepth = ssz.UnmarshallUint64(buf[76:84])
|
||||
|
||||
// Field (0) 'Finalized'
|
||||
{
|
||||
buf = tail[o0:]
|
||||
num, err := ssz.DivideInt2(len(buf), 32, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Finalized = make([][]byte, num)
|
||||
for ii := 0; ii < num; ii++ {
|
||||
if cap(d.Finalized[ii]) == 0 {
|
||||
d.Finalized[ii] = make([]byte, 0, len(buf[ii*32:(ii+1)*32]))
|
||||
}
|
||||
d.Finalized[ii] = append(d.Finalized[ii], buf[ii*32:(ii+1)*32]...)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// SizeSSZ returns the ssz encoded size in bytes for the DepositSnapshot object
|
||||
func (d *DepositSnapshot) SizeSSZ() (size int) {
|
||||
size = 84
|
||||
|
||||
// Field (0) 'Finalized'
|
||||
size += len(d.Finalized) * 32
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// HashTreeRoot ssz hashes the DepositSnapshot object
|
||||
func (d *DepositSnapshot) HashTreeRoot() ([32]byte, error) {
|
||||
return ssz.HashWithDefaultHasher(d)
|
||||
}
|
||||
|
||||
// HashTreeRootWith ssz hashes the DepositSnapshot object with a hasher
|
||||
func (d *DepositSnapshot) HashTreeRootWith(hh *ssz.Hasher) (err error) {
|
||||
indx := hh.Index()
|
||||
|
||||
// Field (0) 'Finalized'
|
||||
{
|
||||
if size := len(d.Finalized); size > 32 {
|
||||
err = ssz.ErrListTooBigFn("--.Finalized", size, 32)
|
||||
return
|
||||
}
|
||||
subIndx := hh.Index()
|
||||
for _, i := range d.Finalized {
|
||||
if len(i) != 32 {
|
||||
err = ssz.ErrBytesLength
|
||||
return
|
||||
}
|
||||
hh.Append(i)
|
||||
}
|
||||
|
||||
numItems := uint64(len(d.Finalized))
|
||||
if ssz.EnableVectorizedHTR {
|
||||
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 32)
|
||||
} else {
|
||||
hh.MerkleizeWithMixin(subIndx, numItems, 32)
|
||||
}
|
||||
}
|
||||
|
||||
// Field (1) 'DepositRoot'
|
||||
if size := len(d.DepositRoot); size != 32 {
|
||||
err = ssz.ErrBytesLengthFn("--.DepositRoot", size, 32)
|
||||
return
|
||||
}
|
||||
hh.PutBytes(d.DepositRoot)
|
||||
|
||||
// Field (2) 'DepositCount'
|
||||
hh.PutUint64(d.DepositCount)
|
||||
|
||||
// Field (3) 'ExecutionHash'
|
||||
if size := len(d.ExecutionHash); size != 32 {
|
||||
err = ssz.ErrBytesLengthFn("--.ExecutionHash", size, 32)
|
||||
return
|
||||
}
|
||||
hh.PutBytes(d.ExecutionHash)
|
||||
|
||||
// Field (4) 'ExecutionDepth'
|
||||
hh.PutUint64(d.ExecutionDepth)
|
||||
|
||||
if ssz.EnableVectorizedHTR {
|
||||
hh.MerkleizeVectorizedHTR(indx)
|
||||
} else {
|
||||
hh.Merkleize(indx)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalSSZ ssz marshals the SyncCommitteeMessage object
|
||||
func (s *SyncCommitteeMessage) MarshalSSZ() ([]byte, error) {
|
||||
return ssz.MarshalSSZ(s)
|
||||
|
||||
226
proto/prysm/v1alpha1/powchain.pb.go
generated
226
proto/prysm/v1alpha1/powchain.pb.go
generated
@@ -10,8 +10,10 @@ import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
|
||||
_ "github.com/prysmaticlabs/prysm/v4/proto/eth/ext"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
_ "google.golang.org/protobuf/types/descriptorpb"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -113,10 +115,10 @@ type DepositSnapshot struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Finalized [][]byte `protobuf:"bytes,1,rep,name=finalized,proto3" json:"finalized,omitempty"`
|
||||
DepositRoot []byte `protobuf:"bytes,2,opt,name=deposit_root,json=depositRoot,proto3" json:"deposit_root,omitempty"`
|
||||
Finalized [][]byte `protobuf:"bytes,1,rep,name=finalized,proto3" json:"finalized,omitempty" ssz-max:"32" ssz-size:"?,32"`
|
||||
DepositRoot []byte `protobuf:"bytes,2,opt,name=deposit_root,json=depositRoot,proto3" json:"deposit_root,omitempty" ssz-size:"32"`
|
||||
DepositCount uint64 `protobuf:"varint,3,opt,name=deposit_count,json=depositCount,proto3" json:"deposit_count,omitempty"`
|
||||
ExecutionHash []byte `protobuf:"bytes,4,opt,name=execution_hash,json=executionHash,proto3" json:"execution_hash,omitempty"`
|
||||
ExecutionHash []byte `protobuf:"bytes,4,opt,name=execution_hash,json=executionHash,proto3" json:"execution_hash,omitempty" ssz-size:"32"`
|
||||
ExecutionDepth uint64 `protobuf:"varint,5,opt,name=execution_depth,json=executionDepth,proto3" json:"execution_depth,omitempty"`
|
||||
}
|
||||
|
||||
@@ -524,115 +526,121 @@ var file_proto_prysm_v1alpha1_powchain_proto_rawDesc = []byte{
|
||||
0x0a, 0x23, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31,
|
||||
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x77, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x27, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79,
|
||||
0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63,
|
||||
0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1,
|
||||
0x03, 0x0a, 0x0d, 0x45, 0x54, 0x48, 0x31, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61,
|
||||
0x12, 0x51, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x74, 0x68, 0x31,
|
||||
0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65, 0x74,
|
||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x20, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65,
|
||||
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c,
|
||||
0x70, 0x68, 0x61, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70,
|
||||
0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x62, 0x65,
|
||||
0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x1a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f,
|
||||
0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1, 0x03,
|
||||
0x0a, 0x0d, 0x45, 0x54, 0x48, 0x31, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12,
|
||||
0x51, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x74, 0x68, 0x31, 0x5f,
|
||||
0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65, 0x74, 0x68,
|
||||
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x45, 0x54, 0x48, 0x31, 0x44, 0x61, 0x74,
|
||||
0x61, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x74, 0x68, 0x31, 0x44, 0x61,
|
||||
0x74, 0x61, 0x12, 0x4e, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74,
|
||||
0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
|
||||
0x68, 0x61, 0x31, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x45, 0x54, 0x48, 0x31, 0x44, 0x61,
|
||||
0x74, 0x61, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x74, 0x68, 0x31, 0x44,
|
||||
0x61, 0x74, 0x61, 0x12, 0x4e, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72,
|
||||
0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
|
||||
0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44,
|
||||
0x61, 0x74, 0x61, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44,
|
||||
0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x0c, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x74,
|
||||
0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
|
||||
0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x62,
|
||||
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x72,
|
||||
0x69, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||
0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61,
|
||||
0x74, 0x61, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61,
|
||||
0x74, 0x61, 0x12, 0x45, 0x0a, 0x0c, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61,
|
||||
0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
|
||||
0x2e, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x54, 0x72, 0x69,
|
||||
0x65, 0x52, 0x04, 0x74, 0x72, 0x69, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x11, 0x64, 0x65,
|
||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12,
|
||||
0x51, 0x0a, 0x10, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73,
|
||||
0x68, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
|
||||
0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
|
||||
0x74, 0x52, 0x0f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68,
|
||||
0x6f, 0x74, 0x22, 0xc7, 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e,
|
||||
0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69,
|
||||
0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c,
|
||||
0x69, 0x7a, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f,
|
||||
0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c,
|
||||
0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e,
|
||||
0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x48,
|
||||
0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x65, 0x78,
|
||||
0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x70, 0x74, 0x68, 0x22, 0xa3, 0x01, 0x0a,
|
||||
0x0e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x45, 0x54, 0x48, 0x31, 0x44, 0x61, 0x74, 0x61, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67,
|
||||
0x68, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68,
|
||||
0x12, 0x30, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12,
|
||||
0x6c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x8b, 0x02, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x72,
|
||||
0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74,
|
||||
0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x68, 0x61,
|
||||
0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x65, 0x6e,
|
||||
0x65, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x0b, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d,
|
||||
0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x12, 0x3c, 0x0a, 0x09, 0x65, 0x74, 0x68, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x74, 0x68,
|
||||
0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x65, 0x74, 0x68, 0x31, 0x44, 0x61, 0x74, 0x61, 0x12,
|
||||
0x4f, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x65,
|
||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
|
||||
0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x12, 0x63, 0x68,
|
||||
0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73,
|
||||
0x22, 0x89, 0x01, 0x0a, 0x10, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x65, 0x72, 0x6b, 0x6c,
|
||||
0x65, 0x54, 0x72, 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x38, 0x0a, 0x06, 0x6c,
|
||||
0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
|
||||
0x68, 0x61, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x06, 0x6c,
|
||||
0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61,
|
||||
0x6c, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x6f,
|
||||
0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x21, 0x0a, 0x09,
|
||||
0x54, 0x72, 0x69, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22,
|
||||
0xb1, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61,
|
||||
0x69, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x74,
|
||||
0x68, 0x31, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x65, 0x74, 0x68, 0x31, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x07, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69,
|
||||
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x62, 0x65,
|
||||
0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x72, 0x69,
|
||||
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
|
||||
0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x07, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
|
||||
0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52,
|
||||
0x6f, 0x6f, 0x74, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
|
||||
0x31, 0x42, 0x0d, 0x50, 0x6f, 0x77, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70,
|
||||
0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79,
|
||||
0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73,
|
||||
0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02,
|
||||
0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x56, 0x31,
|
||||
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||
0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x54, 0x72, 0x69, 0x65,
|
||||
0x52, 0x04, 0x74, 0x72, 0x69, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69,
|
||||
0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x11, 0x64, 0x65, 0x70,
|
||||
0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x51,
|
||||
0x0a, 0x10, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68,
|
||||
0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
|
||||
0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
|
||||
0x52, 0x0f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
|
||||
0x74, 0x22, 0xe7, 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e, 0x61,
|
||||
0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x2c, 0x0a, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a,
|
||||
0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0e, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c,
|
||||
0x33, 0x32, 0x92, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69,
|
||||
0x7a, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x72,
|
||||
0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33,
|
||||
0x32, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x23,
|
||||
0x0a, 0x0d, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x12, 0x2d, 0x0a, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
|
||||
0x02, 0x33, 0x32, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x61,
|
||||
0x73, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
|
||||
0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x65, 0x78, 0x65,
|
||||
0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x70, 0x74, 0x68, 0x22, 0xa3, 0x01, 0x0a, 0x0e,
|
||||
0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x45, 0x54, 0x48, 0x31, 0x44, 0x61, 0x74, 0x61, 0x12, 0x21,
|
||||
0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68,
|
||||
0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12,
|
||||
0x30, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65,
|
||||
0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x6c,
|
||||
0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x8b, 0x02, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74,
|
||||
0x44, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61,
|
||||
0x72, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x65, 0x6e, 0x65,
|
||||
0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,
|
||||
0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67,
|
||||
0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x12, 0x3c, 0x0a, 0x09, 0x65, 0x74, 0x68, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x74, 0x68, 0x31,
|
||||
0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x65, 0x74, 0x68, 0x31, 0x44, 0x61, 0x74, 0x61, 0x12, 0x4f,
|
||||
0x0a, 0x13, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x65, 0x70,
|
||||
0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
|
||||
0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x12, 0x63, 0x68, 0x61,
|
||||
0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x22,
|
||||
0x89, 0x01, 0x0a, 0x10, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65,
|
||||
0x54, 0x72, 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x38, 0x0a, 0x06, 0x6c, 0x61,
|
||||
0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x65, 0x74, 0x68,
|
||||
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x06, 0x6c, 0x61,
|
||||
0x79, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c,
|
||||
0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x6f, 0x72,
|
||||
0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x21, 0x0a, 0x09, 0x54,
|
||||
0x72, 0x69, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65,
|
||||
0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22, 0xb1,
|
||||
0x01, 0x0a, 0x10, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
|
||||
0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x74, 0x68,
|
||||
0x31, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x65, 0x74, 0x68, 0x31, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
|
||||
0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x07, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44,
|
||||
0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x07, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x6f,
|
||||
0x6f, 0x74, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
|
||||
0x42, 0x0d, 0x50, 0x6f, 0x77, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
|
||||
0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72,
|
||||
0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73,
|
||||
0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
|
||||
0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15,
|
||||
0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x56, 0x31, 0x61,
|
||||
0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||
0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -2,8 +2,10 @@ syntax = "proto3";
|
||||
|
||||
package ethereum.eth.v1alpha1;
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
import "proto/prysm/v1alpha1/beacon_block.proto";
|
||||
import "proto/prysm/v1alpha1/beacon_state.proto";
|
||||
import "proto/eth/ext/options.proto";
|
||||
|
||||
option csharp_namespace = "Ethereum.Eth.V1alpha1";
|
||||
option go_package = "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1;eth";
|
||||
@@ -25,12 +27,13 @@ message ETH1ChainData {
|
||||
|
||||
// DepositSnapshot represents an EIP-4881 deposit snapshot
|
||||
message DepositSnapshot {
|
||||
repeated bytes finalized = 1;
|
||||
bytes deposit_root = 2;
|
||||
repeated bytes finalized = 1 [(ethereum.eth.ext.ssz_size) = "?,32", (ethereum.eth.ext.ssz_max) = "32"];
|
||||
bytes deposit_root = 2 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
uint64 deposit_count = 3;
|
||||
bytes execution_hash = 4;
|
||||
bytes execution_hash = 4 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
uint64 execution_depth = 5;
|
||||
}
|
||||
|
||||
// LatestETH1Data contains the current state of the eth1 chain.
|
||||
message LatestETH1Data {
|
||||
uint64 block_height = 2;
|
||||
|
||||
358
proto/prysm/v1alpha1/validator-client/keymanager.pb.go
generated
358
proto/prysm/v1alpha1/validator-client/keymanager.pb.go
generated
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v4.23.3
|
||||
// protoc v4.25.1
|
||||
// source: proto/prysm/v1alpha1/validator-client/keymanager.proto
|
||||
|
||||
package validatorpb
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
sync "sync"
|
||||
|
||||
github_com_prysmaticlabs_prysm_v4_consensus_types_primitives "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
github_com_prysmaticlabs_prysm_v4_consensus_types_validator "github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
_ "github.com/prysmaticlabs/prysm/v4/proto/eth/ext"
|
||||
v1alpha1 "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
@@ -455,179 +454,6 @@ func (x *SignResponse) GetStatus() SignResponse_Status {
|
||||
return SignResponse_UNKNOWN
|
||||
}
|
||||
|
||||
type ProposerOptionPayload struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
FeeRecipient string `protobuf:"bytes,1,opt,name=fee_recipient,json=feeRecipient,proto3" json:"fee_recipient,omitempty"`
|
||||
Builder *BuilderConfig `protobuf:"bytes,2,opt,name=builder,proto3" json:"builder,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) Reset() {
|
||||
*x = ProposerOptionPayload{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ProposerOptionPayload) ProtoMessage() {}
|
||||
|
||||
func (x *ProposerOptionPayload) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ProposerOptionPayload.ProtoReflect.Descriptor instead.
|
||||
func (*ProposerOptionPayload) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) GetFeeRecipient() string {
|
||||
if x != nil {
|
||||
return x.FeeRecipient
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) GetBuilder() *BuilderConfig {
|
||||
if x != nil {
|
||||
return x.Builder
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BuilderConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
GasLimit github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64 `protobuf:"varint,2,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v4/consensus-types/validator.Uint64"`
|
||||
Relays []string `protobuf:"bytes,3,rep,name=relays,proto3" json:"relays,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) Reset() {
|
||||
*x = BuilderConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BuilderConfig) ProtoMessage() {}
|
||||
|
||||
func (x *BuilderConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BuilderConfig.ProtoReflect.Descriptor instead.
|
||||
func (*BuilderConfig) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetEnabled() bool {
|
||||
if x != nil {
|
||||
return x.Enabled
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetGasLimit() github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64 {
|
||||
if x != nil {
|
||||
return x.GasLimit
|
||||
}
|
||||
return github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64(0)
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetRelays() []string {
|
||||
if x != nil {
|
||||
return x.Relays
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ProposerSettingsPayload struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ProposerConfig map[string]*ProposerOptionPayload `protobuf:"bytes,1,rep,name=proposer_config,json=proposerConfig,proto3" json:"proposer_config,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
DefaultConfig *ProposerOptionPayload `protobuf:"bytes,2,opt,name=default_config,json=defaultConfig,proto3" json:"default_config,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) Reset() {
|
||||
*x = ProposerSettingsPayload{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ProposerSettingsPayload) ProtoMessage() {}
|
||||
|
||||
func (x *ProposerSettingsPayload) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ProposerSettingsPayload.ProtoReflect.Descriptor instead.
|
||||
func (*ProposerSettingsPayload) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) GetProposerConfig() map[string]*ProposerOptionPayload {
|
||||
if x != nil {
|
||||
return x.ProposerConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) GetDefaultConfig() *ProposerOptionPayload {
|
||||
if x != nil {
|
||||
return x.DefaultConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_proto_prysm_v1alpha1_validator_client_keymanager_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc = []byte{
|
||||
@@ -771,62 +597,20 @@ var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc = []byte
|
||||
0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d,
|
||||
0x0a, 0x09, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a,
|
||||
0x06, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49,
|
||||
0x4c, 0x45, 0x44, 0x10, 0x03, 0x22, 0x85, 0x01, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73,
|
||||
0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12,
|
||||
0x23, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70,
|
||||
0x69, 0x65, 0x6e, 0x74, 0x12, 0x47, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||
0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x22, 0xa6, 0x01,
|
||||
0x0a, 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x63, 0x0a, 0x09, 0x67, 0x61, 0x73,
|
||||
0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5,
|
||||
0x18, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79,
|
||||
0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
|
||||
0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79,
|
||||
0x70, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x55, 0x69,
|
||||
0x6e, 0x74, 0x36, 0x34, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
|
||||
0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x22, 0xe7, 0x02, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x70, 0x6f,
|
||||
0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f,
|
||||
0x61, 0x64, 0x12, 0x74, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x63,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x65, 0x74,
|
||||
0x4c, 0x45, 0x44, 0x10, 0x03, 0x42, 0xce, 0x01, 0x0a, 0x22, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
|
||||
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f,
|
||||
0x70, 0x6f, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x61, 0x79,
|
||||
0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5c, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61,
|
||||
0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69,
|
||||
0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
|
||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x78, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
|
||||
0x4b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35,
|
||||
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
|
||||
0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61,
|
||||
0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
|
||||
0x42, 0xce, 0x01, 0x0a, 0x22, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||
0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x42, 0x0f, 0x4b, 0x65, 0x79, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63,
|
||||
0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2d, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x3b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x70, 0x62, 0xaa,
|
||||
0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64,
|
||||
0x61, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x56, 0x32,
|
||||
0xca, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x56, 0x61, 0x6c, 0x69,
|
||||
0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56,
|
||||
0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x42, 0x0f, 0x4b, 0x65,
|
||||
0x79, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73,
|
||||
0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f,
|
||||
0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76,
|
||||
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
|
||||
0x72, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
|
||||
0x6f, 0x72, 0x70, 0x62, 0xaa, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x73, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||
0x5c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x73, 0x5c, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -842,55 +626,47 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP() [
|
||||
}
|
||||
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_goTypes = []interface{}{
|
||||
(SignResponse_Status)(0), // 0: ethereum.validator.accounts.v2.SignResponse.Status
|
||||
(*SignRequest)(nil), // 1: ethereum.validator.accounts.v2.SignRequest
|
||||
(*SignResponse)(nil), // 2: ethereum.validator.accounts.v2.SignResponse
|
||||
(*ProposerOptionPayload)(nil), // 3: ethereum.validator.accounts.v2.ProposerOptionPayload
|
||||
(*BuilderConfig)(nil), // 4: ethereum.validator.accounts.v2.BuilderConfig
|
||||
(*ProposerSettingsPayload)(nil), // 5: ethereum.validator.accounts.v2.ProposerSettingsPayload
|
||||
nil, // 6: ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry
|
||||
(*v1alpha1.BeaconBlock)(nil), // 7: ethereum.eth.v1alpha1.BeaconBlock
|
||||
(*v1alpha1.AttestationData)(nil), // 8: ethereum.eth.v1alpha1.AttestationData
|
||||
(*v1alpha1.AggregateAttestationAndProof)(nil), // 9: ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
(*v1alpha1.VoluntaryExit)(nil), // 10: ethereum.eth.v1alpha1.VoluntaryExit
|
||||
(*v1alpha1.BeaconBlockAltair)(nil), // 11: ethereum.eth.v1alpha1.BeaconBlockAltair
|
||||
(*v1alpha1.SyncAggregatorSelectionData)(nil), // 12: ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
(*v1alpha1.ContributionAndProof)(nil), // 13: ethereum.eth.v1alpha1.ContributionAndProof
|
||||
(*v1alpha1.BeaconBlockBellatrix)(nil), // 14: ethereum.eth.v1alpha1.BeaconBlockBellatrix
|
||||
(*v1alpha1.BlindedBeaconBlockBellatrix)(nil), // 15: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
|
||||
(*v1alpha1.ValidatorRegistrationV1)(nil), // 16: ethereum.eth.v1alpha1.ValidatorRegistrationV1
|
||||
(*v1alpha1.BeaconBlockCapella)(nil), // 17: ethereum.eth.v1alpha1.BeaconBlockCapella
|
||||
(*v1alpha1.BlindedBeaconBlockCapella)(nil), // 18: ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
|
||||
(*v1alpha1.BeaconBlockDeneb)(nil), // 19: ethereum.eth.v1alpha1.BeaconBlockDeneb
|
||||
(*v1alpha1.BlindedBeaconBlockDeneb)(nil), // 20: ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb
|
||||
(*v1alpha1.BeaconBlock)(nil), // 3: ethereum.eth.v1alpha1.BeaconBlock
|
||||
(*v1alpha1.AttestationData)(nil), // 4: ethereum.eth.v1alpha1.AttestationData
|
||||
(*v1alpha1.AggregateAttestationAndProof)(nil), // 5: ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
(*v1alpha1.VoluntaryExit)(nil), // 6: ethereum.eth.v1alpha1.VoluntaryExit
|
||||
(*v1alpha1.BeaconBlockAltair)(nil), // 7: ethereum.eth.v1alpha1.BeaconBlockAltair
|
||||
(*v1alpha1.SyncAggregatorSelectionData)(nil), // 8: ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
(*v1alpha1.ContributionAndProof)(nil), // 9: ethereum.eth.v1alpha1.ContributionAndProof
|
||||
(*v1alpha1.BeaconBlockBellatrix)(nil), // 10: ethereum.eth.v1alpha1.BeaconBlockBellatrix
|
||||
(*v1alpha1.BlindedBeaconBlockBellatrix)(nil), // 11: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
|
||||
(*v1alpha1.ValidatorRegistrationV1)(nil), // 12: ethereum.eth.v1alpha1.ValidatorRegistrationV1
|
||||
(*v1alpha1.BeaconBlockCapella)(nil), // 13: ethereum.eth.v1alpha1.BeaconBlockCapella
|
||||
(*v1alpha1.BlindedBeaconBlockCapella)(nil), // 14: ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
|
||||
(*v1alpha1.BeaconBlockDeneb)(nil), // 15: ethereum.eth.v1alpha1.BeaconBlockDeneb
|
||||
(*v1alpha1.BlindedBeaconBlockDeneb)(nil), // 16: ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb
|
||||
}
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_depIdxs = []int32{
|
||||
7, // 0: ethereum.validator.accounts.v2.SignRequest.block:type_name -> ethereum.eth.v1alpha1.BeaconBlock
|
||||
8, // 1: ethereum.validator.accounts.v2.SignRequest.attestation_data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
9, // 2: ethereum.validator.accounts.v2.SignRequest.aggregate_attestation_and_proof:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
10, // 3: ethereum.validator.accounts.v2.SignRequest.exit:type_name -> ethereum.eth.v1alpha1.VoluntaryExit
|
||||
11, // 4: ethereum.validator.accounts.v2.SignRequest.block_altair:type_name -> ethereum.eth.v1alpha1.BeaconBlockAltair
|
||||
12, // 5: ethereum.validator.accounts.v2.SignRequest.sync_aggregator_selection_data:type_name -> ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
13, // 6: ethereum.validator.accounts.v2.SignRequest.contribution_and_proof:type_name -> ethereum.eth.v1alpha1.ContributionAndProof
|
||||
14, // 7: ethereum.validator.accounts.v2.SignRequest.block_bellatrix:type_name -> ethereum.eth.v1alpha1.BeaconBlockBellatrix
|
||||
15, // 8: ethereum.validator.accounts.v2.SignRequest.blinded_block_bellatrix:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
|
||||
16, // 9: ethereum.validator.accounts.v2.SignRequest.registration:type_name -> ethereum.eth.v1alpha1.ValidatorRegistrationV1
|
||||
17, // 10: ethereum.validator.accounts.v2.SignRequest.block_capella:type_name -> ethereum.eth.v1alpha1.BeaconBlockCapella
|
||||
18, // 11: ethereum.validator.accounts.v2.SignRequest.blinded_block_capella:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
|
||||
19, // 12: ethereum.validator.accounts.v2.SignRequest.block_deneb:type_name -> ethereum.eth.v1alpha1.BeaconBlockDeneb
|
||||
20, // 13: ethereum.validator.accounts.v2.SignRequest.blinded_block_deneb:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb
|
||||
3, // 0: ethereum.validator.accounts.v2.SignRequest.block:type_name -> ethereum.eth.v1alpha1.BeaconBlock
|
||||
4, // 1: ethereum.validator.accounts.v2.SignRequest.attestation_data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
5, // 2: ethereum.validator.accounts.v2.SignRequest.aggregate_attestation_and_proof:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
6, // 3: ethereum.validator.accounts.v2.SignRequest.exit:type_name -> ethereum.eth.v1alpha1.VoluntaryExit
|
||||
7, // 4: ethereum.validator.accounts.v2.SignRequest.block_altair:type_name -> ethereum.eth.v1alpha1.BeaconBlockAltair
|
||||
8, // 5: ethereum.validator.accounts.v2.SignRequest.sync_aggregator_selection_data:type_name -> ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
9, // 6: ethereum.validator.accounts.v2.SignRequest.contribution_and_proof:type_name -> ethereum.eth.v1alpha1.ContributionAndProof
|
||||
10, // 7: ethereum.validator.accounts.v2.SignRequest.block_bellatrix:type_name -> ethereum.eth.v1alpha1.BeaconBlockBellatrix
|
||||
11, // 8: ethereum.validator.accounts.v2.SignRequest.blinded_block_bellatrix:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
|
||||
12, // 9: ethereum.validator.accounts.v2.SignRequest.registration:type_name -> ethereum.eth.v1alpha1.ValidatorRegistrationV1
|
||||
13, // 10: ethereum.validator.accounts.v2.SignRequest.block_capella:type_name -> ethereum.eth.v1alpha1.BeaconBlockCapella
|
||||
14, // 11: ethereum.validator.accounts.v2.SignRequest.blinded_block_capella:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
|
||||
15, // 12: ethereum.validator.accounts.v2.SignRequest.block_deneb:type_name -> ethereum.eth.v1alpha1.BeaconBlockDeneb
|
||||
16, // 13: ethereum.validator.accounts.v2.SignRequest.blinded_block_deneb:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb
|
||||
0, // 14: ethereum.validator.accounts.v2.SignResponse.status:type_name -> ethereum.validator.accounts.v2.SignResponse.Status
|
||||
4, // 15: ethereum.validator.accounts.v2.ProposerOptionPayload.builder:type_name -> ethereum.validator.accounts.v2.BuilderConfig
|
||||
6, // 16: ethereum.validator.accounts.v2.ProposerSettingsPayload.proposer_config:type_name -> ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry
|
||||
3, // 17: ethereum.validator.accounts.v2.ProposerSettingsPayload.default_config:type_name -> ethereum.validator.accounts.v2.ProposerOptionPayload
|
||||
3, // 18: ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry.value:type_name -> ethereum.validator.accounts.v2.ProposerOptionPayload
|
||||
19, // [19:19] is the sub-list for method output_type
|
||||
19, // [19:19] is the sub-list for method input_type
|
||||
19, // [19:19] is the sub-list for extension type_name
|
||||
19, // [19:19] is the sub-list for extension extendee
|
||||
0, // [0:19] is the sub-list for field type_name
|
||||
15, // [15:15] is the sub-list for method output_type
|
||||
15, // [15:15] is the sub-list for method input_type
|
||||
15, // [15:15] is the sub-list for extension type_name
|
||||
15, // [15:15] is the sub-list for extension extendee
|
||||
0, // [0:15] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() }
|
||||
@@ -923,42 +699,6 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ProposerOptionPayload); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BuilderConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ProposerSettingsPayload); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[0].OneofWrappers = []interface{}{
|
||||
(*SignRequest_Block)(nil),
|
||||
@@ -985,7 +725,7 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 6,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -81,23 +81,4 @@ message SignResponse {
|
||||
// to ensure different remote signing servers follow the
|
||||
// same conventions.
|
||||
Status status = 2;
|
||||
}
|
||||
|
||||
// ProposerOptionPayload is a property of ProposerSettingsPayload
|
||||
message ProposerOptionPayload {
|
||||
string fee_recipient = 1;
|
||||
BuilderConfig builder = 2;
|
||||
}
|
||||
|
||||
// BuilderConfig is a property of ProposerOptionPayload
|
||||
message BuilderConfig {
|
||||
bool enabled = 1;
|
||||
uint64 gas_limit = 2 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v4/consensus-types/validator.Uint64"];
|
||||
repeated string relays = 3;
|
||||
}
|
||||
|
||||
// ProposerSettingsPayload is used to unmarshal files sent from the validator flag as well as safe to bolt db bucket
|
||||
message ProposerSettingsPayload {
|
||||
map<string, ProposerOptionPayload> proposer_config = 1;
|
||||
ProposerOptionPayload default_config = 2;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ mainnet = {
|
||||
"sync_committee_aggregate_bytes.size": "16",
|
||||
"sync_committee_aggregate_bits.type": "github.com/prysmaticlabs/go-bitfield.Bitvector128",
|
||||
"withdrawal.size": "16",
|
||||
"blob.size": "131072",
|
||||
"blob.size": "131072", # BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB
|
||||
"logs_bloom.size": "256",
|
||||
"extra_data.size": "32",
|
||||
"max_blobs_per_block.size": "6",
|
||||
|
||||
@@ -31,7 +31,7 @@ go_library(
|
||||
"//config/params:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"//proto/prysm/config:go_default_library",
|
||||
"//runtime/interop:go_default_library",
|
||||
"//testing/endtoend/helpers:go_default_library",
|
||||
"//testing/endtoend/params:go_default_library",
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/io/file"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||
proposersettings "github.com/prysmaticlabs/prysm/v4/proto/prysm/config"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/interop"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/endtoend/helpers"
|
||||
e2e "github.com/prysmaticlabs/prysm/v4/testing/endtoend/params"
|
||||
@@ -340,16 +340,16 @@ func createProposerSettingsPath(pubkeys []string, nodeIdx int) (string, error) {
|
||||
if len(pubkeys) == 0 {
|
||||
return "", errors.New("number of validators must be greater than 0")
|
||||
}
|
||||
config := make(map[string]*validatorpb.ProposerOptionPayload)
|
||||
config := make(map[string]*proposersettings.ProposerOptionPayload)
|
||||
|
||||
for i, pubkey := range pubkeys {
|
||||
config[pubkeys[i]] = &validatorpb.ProposerOptionPayload{
|
||||
config[pubkeys[i]] = &proposersettings.ProposerOptionPayload{
|
||||
FeeRecipient: FeeRecipientFromPubkey(pubkey),
|
||||
}
|
||||
}
|
||||
proposerSettingsPayload := &validatorpb.ProposerSettingsPayload{
|
||||
proposerSettingsPayload := &proposersettings.ProposerSettingsPayload{
|
||||
ProposerConfig: config,
|
||||
DefaultConfig: &validatorpb.ProposerOptionPayload{
|
||||
DefaultConfig: &proposersettings.ProposerOptionPayload{
|
||||
FeeRecipient: DefaultFeeRecipientAddress,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ go_library(
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"math"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/signing"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
@@ -88,10 +90,31 @@ func (s *Simulator) generateAttestationsForSlot(
|
||||
}
|
||||
slashableAtt.Signature = aggSig.Marshal()
|
||||
slashedIndices = append(slashedIndices, slashableAtt.AttestingIndices...)
|
||||
slashings = append(slashings, ðpb.AttesterSlashing{
|
||||
|
||||
attDataRoot, err := att.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "cannot compte `att` hash tree root")
|
||||
}
|
||||
|
||||
slashableAttDataRoot, err := slashableAtt.Data.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,
|
||||
})
|
||||
}
|
||||
|
||||
// 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,
|
||||
}
|
||||
}
|
||||
|
||||
slashings = append(slashings, slashing)
|
||||
attestations = append(attestations, slashableAtt)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ func (acm *CLIManager) Delete(ctx context.Context) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
log.WithField("publicKeys", allAccountStr).Warn(
|
||||
log.WithField("pubkeys", allAccountStr).Warn(
|
||||
"Attempted to delete accounts. IMPORTANT: please run `validator accounts list` to ensure " +
|
||||
"the public keys are indeed deleted. If they are still there, please file an issue at " +
|
||||
"https://github.com/prysmaticlabs/prysm/issues/new")
|
||||
|
||||
@@ -154,9 +154,14 @@ func displayExitInfo(rawExitedKeys [][]byte, trimmedExitedKeys []string) {
|
||||
urlFormattedPubKeys := make([]string, len(rawExitedKeys))
|
||||
for i, key := range rawExitedKeys {
|
||||
var baseUrl string
|
||||
if params.BeaconConfig().ConfigName == params.PraterName || params.BeaconConfig().ConfigName == params.GoerliName {
|
||||
switch params.BeaconConfig().ConfigName {
|
||||
case params.PraterName, params.GoerliName:
|
||||
baseUrl = "https://goerli.beaconcha.in/validator/"
|
||||
} else {
|
||||
case params.HoleskyName:
|
||||
baseUrl = "https://holesky.beaconcha.in/validator/"
|
||||
case params.SepoliaName:
|
||||
baseUrl = "https://sepolia.beaconcha.in/validator/"
|
||||
default:
|
||||
baseUrl = "https://beaconcha.in/validator/"
|
||||
}
|
||||
// Remove '0x' prefix
|
||||
@@ -171,7 +176,7 @@ func displayExitInfo(rawExitedKeys [][]byte, trimmedExitedKeys []string) {
|
||||
info := fmt.Sprintf("Voluntary exit was successful for the accounts listed. "+
|
||||
"URLs where you can track each validator's exit:\n"+strings.Repeat("%s\n", len(ifaceKeys)), ifaceKeys...)
|
||||
|
||||
log.WithField("publicKeys", strings.Join(trimmedExitedKeys, ", ")).Info(info)
|
||||
log.WithField("pubkeys", strings.Join(trimmedExitedKeys, ", ")).Info(info)
|
||||
} else {
|
||||
log.Info("No successful voluntary exits")
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ go_library(
|
||||
"//validator:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//config/validator/service:go_default_library",
|
||||
"//config/proposer:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//validator/accounts/iface:go_default_library",
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
validatorserviceconfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/proposer"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts/iface"
|
||||
@@ -89,10 +89,10 @@ func (_ *Wallet) InitializeKeymanager(_ context.Context, _ iface.InitKeymanagerC
|
||||
|
||||
type Validator struct {
|
||||
Km keymanager.IKeymanager
|
||||
proposerSettings *validatorserviceconfig.ProposerSettings
|
||||
proposerSettings *proposer.ProposerSettings
|
||||
}
|
||||
|
||||
func (_ *Validator) LogSyncCommitteeMessagesSubmitted() {}
|
||||
func (_ *Validator) LogSubmittedSyncCommitteeMessages() {}
|
||||
|
||||
func (_ *Validator) Done() {
|
||||
panic("implement me")
|
||||
@@ -154,7 +154,7 @@ func (_ *Validator) SubmitSignedContributionAndProof(_ context.Context, _ primit
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (_ *Validator) LogAttestationsSubmitted() {
|
||||
func (_ *Validator) LogSubmittedAtts(_ primitives.Slot) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -203,12 +203,12 @@ func (_ *Validator) SignValidatorRegistrationRequest(_ context.Context, _ iface2
|
||||
}
|
||||
|
||||
// ProposerSettings for mocking
|
||||
func (m *Validator) ProposerSettings() *validatorserviceconfig.ProposerSettings {
|
||||
func (m *Validator) ProposerSettings() *proposer.ProposerSettings {
|
||||
return m.proposerSettings
|
||||
}
|
||||
|
||||
// SetProposerSettings for mocking
|
||||
func (m *Validator) SetProposerSettings(_ context.Context, settings *validatorserviceconfig.ProposerSettings) error {
|
||||
func (m *Validator) SetProposerSettings(_ context.Context, settings *proposer.ProposerSettings) error {
|
||||
m.proposerSettings = settings
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ go_library(
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//config/proposer:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
@@ -126,7 +126,7 @@ go_test(
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//config/proposer:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/blocks/testing:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
|
||||
@@ -124,7 +124,7 @@ func (v *validator) SubmitAggregateAndProof(ctx context.Context, slot primitives
|
||||
return
|
||||
}
|
||||
|
||||
if err := v.addIndicesToLog(duty); err != nil {
|
||||
if err := v.saveSubmittedAtt(res.AggregateAndProof.Aggregate.Data, pubKey[:], true); err != nil {
|
||||
log.WithError(err).Error("Could not add aggregator indices to logs")
|
||||
if v.emitAccountMetrics {
|
||||
ValidatorAggFailVec.WithLabelValues(fmtKey).Inc()
|
||||
@@ -216,16 +216,3 @@ func (v *validator) aggregateAndProofSig(ctx context.Context, pubKey [fieldparam
|
||||
|
||||
return sig.Marshal(), nil
|
||||
}
|
||||
|
||||
func (v *validator) addIndicesToLog(duty *ethpb.DutiesResponse_Duty) error {
|
||||
v.attLogsLock.Lock()
|
||||
defer v.attLogsLock.Unlock()
|
||||
|
||||
for _, log := range v.attLogs {
|
||||
if duty.CommitteeIndex == log.data.CommitteeIndex {
|
||||
log.aggregatorIndices = append(log.aggregatorIndices, duty.ValidatorIndex)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@ package client
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v4/async"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/signing"
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/monitoring/tracing"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -55,7 +54,7 @@ func (v *validator) SubmitAttestation(ctx context.Context, slot primitives.Slot,
|
||||
defer lock.Unlock()
|
||||
|
||||
fmtKey := fmt.Sprintf("%#x", pubKey[:])
|
||||
log := log.WithField("pubKey", fmt.Sprintf("%#x", bytesutil.Trunc(pubKey[:]))).WithField("slot", slot)
|
||||
log := log.WithField("pubkey", fmt.Sprintf("%#x", bytesutil.Trunc(pubKey[:]))).WithField("slot", slot)
|
||||
duty, err := v.duty(pubKey)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not fetch validator assignment")
|
||||
@@ -154,7 +153,7 @@ func (v *validator) SubmitAttestation(ctx context.Context, slot primitives.Slot,
|
||||
return
|
||||
}
|
||||
|
||||
if err := v.saveAttesterIndexToData(data, duty.ValidatorIndex); err != nil {
|
||||
if err := v.saveSubmittedAtt(data, pubKey[:], false); err != nil {
|
||||
log.WithError(err).Error("Could not save validator index for logging")
|
||||
if v.emitAccountMetrics {
|
||||
ValidatorAttestFailVec.WithLabelValues(fmtKey).Inc()
|
||||
@@ -228,25 +227,6 @@ func (v *validator) getDomainAndSigningRoot(ctx context.Context, data *ethpb.Att
|
||||
return domain, root, nil
|
||||
}
|
||||
|
||||
// For logging, this saves the last submitted attester index to its attestation data. The purpose of this
|
||||
// is to enhance attesting logs to be readable when multiple validator keys ran in a single client.
|
||||
func (v *validator) saveAttesterIndexToData(data *ethpb.AttestationData, index primitives.ValidatorIndex) error {
|
||||
v.attLogsLock.Lock()
|
||||
defer v.attLogsLock.Unlock()
|
||||
|
||||
h, err := hash.Proto(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v.attLogs[h] == nil {
|
||||
v.attLogs[h] = &attSubmitted{data, []primitives.ValidatorIndex{}, []primitives.ValidatorIndex{}}
|
||||
}
|
||||
v.attLogs[h] = &attSubmitted{data, append(v.attLogs[h].attesterIndices, index), []primitives.ValidatorIndex{}}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// highestSlot returns the highest slot with a valid block seen by the validator
|
||||
func (v *validator) highestSlot() primitives.Slot {
|
||||
v.highestValidSlotLock.Lock()
|
||||
@@ -313,14 +293,14 @@ func (v *validator) waitOneThirdOrValidBlock(ctx context.Context, slot primitive
|
||||
|
||||
func attestationLogFields(pubKey [fieldparams.BLSPubkeyLength]byte, indexedAtt *ethpb.IndexedAttestation) logrus.Fields {
|
||||
return logrus.Fields{
|
||||
"attesterPublicKey": fmt.Sprintf("%#x", pubKey),
|
||||
"attestationSlot": indexedAtt.Data.Slot,
|
||||
"committeeIndex": indexedAtt.Data.CommitteeIndex,
|
||||
"beaconBlockRoot": fmt.Sprintf("%#x", indexedAtt.Data.BeaconBlockRoot),
|
||||
"sourceEpoch": indexedAtt.Data.Source.Epoch,
|
||||
"sourceRoot": fmt.Sprintf("%#x", indexedAtt.Data.Source.Root),
|
||||
"targetEpoch": indexedAtt.Data.Target.Epoch,
|
||||
"targetRoot": fmt.Sprintf("%#x", indexedAtt.Data.Target.Root),
|
||||
"signature": fmt.Sprintf("%#x", indexedAtt.Signature),
|
||||
"pubkey": fmt.Sprintf("%#x", pubKey),
|
||||
"slot": indexedAtt.Data.Slot,
|
||||
"committeeIndex": indexedAtt.Data.CommitteeIndex,
|
||||
"blockRoot": fmt.Sprintf("%#x", indexedAtt.Data.BeaconBlockRoot),
|
||||
"sourceEpoch": indexedAtt.Data.Source.Epoch,
|
||||
"sourceRoot": fmt.Sprintf("%#x", indexedAtt.Data.Source.Root),
|
||||
"targetEpoch": indexedAtt.Data.Target.Epoch,
|
||||
"targetRoot": fmt.Sprintf("%#x", indexedAtt.Data.Target.Root),
|
||||
"signature": fmt.Sprintf("%#x", indexedAtt.Signature),
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user