mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 23:48:06 -05:00
<!-- Thanks for sending a PR! Before submitting: 1. If this is your first PR, check out our contribution guide here https://docs.prylabs.network/docs/contribute/contribution-guidelines You will then need to sign our Contributor License Agreement (CLA), which will show up as a comment from a bot in this pull request after you open it. We cannot review code without a signed CLA. 2. Please file an associated tracking issue if this pull request is non-trivial and requires context for our team to understand. All features and most bug fixes should have an associated issue with a design discussed and decided upon. Small bug fixes and documentation improvements don't need issues. 3. New features and bug fixes must have tests. Documentation may need to be updated. If you're unsure what to update, send the PR, and we'll discuss in review. 4. Note that PRs updating dependencies and new Go versions are not accepted. Please file an issue instead. 5. A changelog entry is required for user facing issues. --> **What type of PR is this?** Feature **What does this PR do? Why is it needed?** | Feature | Semi-Supernode | Supernode | | ----------------------- | ------------------------- | ------------------------ | | **Custody Groups** | 64 | 128 | | **Data Columns** | 64 | 128 | | **Storage** | ~50% | ~100% | | **Blob Reconstruction** | Yes (via Reed-Solomon) | No reconstruction needed | | **Flag** | `--semi-supernode` | `--supernode` | | **Can serve all blobs** | Yes (with reconstruction) | Yes (directly) | **note** if your validator total effective balance results in more custody than the semi-supernode it will override those those requirements. cgc=64 from @nalepae Pro: - We are useful to the network - Less disconnection likelihood - Straight forward to implement Con: - We cannot revert to a full node - We have to serve incoming RPC requests corresponding to 64 columns Tested the following using this kurtosis setup ``` participants: # Super-nodes - el_type: geth el_image: ethpandaops/geth:master cl_type: prysm vc_image: gcr.io/offchainlabs/prysm/validator:latest cl_image: gcr.io/offchainlabs/prysm/beacon-chain:latest count: 2 cl_extra_params: - --supernode vc_extra_params: - --verbosity=debug # Full-nodes - el_type: geth el_image: ethpandaops/geth:master cl_type: prysm vc_image: gcr.io/offchainlabs/prysm/validator:latest cl_image: gcr.io/offchainlabs/prysm/beacon-chain:latest count: 2 validator_count: 1 cl_extra_params: - --semi-supernode vc_extra_params: - --verbosity=debug additional_services: - dora - spamoor spamoor_params: image: ethpandaops/spamoor:master max_mem: 4000 spammers: - scenario: eoatx config: throughput: 200 - scenario: blobs config: throughput: 20 network_params: fulu_fork_epoch: 0 withdrawal_type: "0x02" preset: mainnet global_log_level: debug ``` ``` curl -H "Accept: application/json" http://127.0.0.1:32961/eth/v1/node/identity {"data":{"peer_id":"16Uiu2HAm7xzhnGwea8gkcxRSC6fzUkvryP6d9HdWNkoeTkj6RSqw","enr":"enr:-Ni4QIH5u2NQz17_pTe9DcCfUyG8TidDJJjIeBpJRRm4ACQzGBpCJdyUP9eGZzwwZ2HS1TnB9ACxFMQ5LP5njnMDLm-GAZqZEXjih2F0dG5ldHOIAAAAAAAwAACDY2djQIRldGgykLZy_whwAAA4__________-CaWSCdjSCaXCErBAAE4NuZmSEAAAAAIRxdWljgjLIiXNlY3AyNTZrMaECulJrXpSOBmCsQWcGYzQsst7r3-Owlc9iZbEcJTDkB6qIc3luY25ldHMFg3RjcIIyyIN1ZHCCLuA","p2p_addresses":["/ip4/172.16.0.19/tcp/13000/p2p/16Uiu2HAm7xzhnGwea8gkcxRSC6fzUkvryP6d9HdWNkoeTkj6RSqw","/ip4/172.16.0.19/udp/13000/quic-v1/p2p/16Uiu2HAm7xzhnGwea8gkcxRSC6fzUkvryP6d9HdWNkoeTkj6RSqw"],"discovery_addresses":["/ip4/172.16.0.19/udp/12000/p2p/16Uiu2HAm7xzhnGwea8gkcxRSC6fzUkvryP6d9HdWNkoeTkj6RSqw"],"metadata":{"seq_number":"3","attnets":"0x0000000000300000","syncnets":"0x05","custody_group_count":"64"}}} ``` ``` curl -s http://127.0.0.1:32961/eth/v1/debug/beacon/data_column_sidecars/head | jq '.data | length' 64 ``` ``` curl -X 'GET' \ 'http://127.0.0.1:32961/eth/v1/beacon/blobs/head' \ -H 'accept: application/json' ``` **Which issues(s) does this PR fix?** Fixes # **Other notes for review** **Acknowledgements** - [x] I have read [CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md). - [x] I have included a uniquely named [changelog fragment file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd). - [x] I have added a description to this PR with sufficient context for reviewers to understand this PR. --------- Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com> Co-authored-by: james-prysm <jhe@offchainlabs.com> Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
207 lines
10 KiB
Go
207 lines
10 KiB
Go
// Package iface defines the actual database interface used
|
|
// by a Prysm beacon node, also containing useful, scoped interfaces such as
|
|
// a ReadOnlyDatabase.
|
|
package iface
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
"github.com/OffchainLabs/prysm/v7/beacon-chain/db/filters"
|
|
slashertypes "github.com/OffchainLabs/prysm/v7/beacon-chain/slasher/types"
|
|
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/blocks"
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
|
|
"github.com/OffchainLabs/prysm/v7/monitoring/backup"
|
|
"github.com/OffchainLabs/prysm/v7/proto/dbval"
|
|
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
)
|
|
|
|
// ReadOnlyDatabase defines a struct which only has read access to database methods.
|
|
type ReadOnlyDatabase interface {
|
|
// Block related methods.
|
|
Block(ctx context.Context, blockRoot [32]byte) (interfaces.ReadOnlySignedBeaconBlock, error)
|
|
Blocks(ctx context.Context, f *filters.QueryFilter) ([]interfaces.ReadOnlySignedBeaconBlock, [][32]byte, error)
|
|
BlockRoots(ctx context.Context, f *filters.QueryFilter) ([][32]byte, error)
|
|
BlocksBySlot(ctx context.Context, slot primitives.Slot) ([]interfaces.ReadOnlySignedBeaconBlock, error)
|
|
BlockRootsBySlot(ctx context.Context, slot primitives.Slot) (bool, [][32]byte, error)
|
|
HasBlock(ctx context.Context, blockRoot [32]byte) bool
|
|
AvailableBlocks(ctx context.Context, blockRoots [][32]byte) map[[32]byte]bool
|
|
GenesisBlock(ctx context.Context) (interfaces.ReadOnlySignedBeaconBlock, error)
|
|
GenesisBlockRoot(ctx context.Context) ([32]byte, error)
|
|
IsFinalizedBlock(ctx context.Context, blockRoot [32]byte) bool
|
|
FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (interfaces.ReadOnlySignedBeaconBlock, error)
|
|
HighestRootsBelowSlot(ctx context.Context, slot primitives.Slot) (primitives.Slot, [][32]byte, error)
|
|
EarliestSlot(ctx context.Context) (primitives.Slot, error)
|
|
// State related methods.
|
|
State(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
|
StateOrError(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
|
GenesisState(ctx context.Context) (state.BeaconState, error)
|
|
HasState(ctx context.Context, blockRoot [32]byte) bool
|
|
StateSummary(ctx context.Context, blockRoot [32]byte) (*ethpb.StateSummary, error)
|
|
HasStateSummary(ctx context.Context, blockRoot [32]byte) bool
|
|
HighestSlotStatesBelow(ctx context.Context, slot primitives.Slot) ([]state.ReadOnlyBeaconState, error)
|
|
// Checkpoint operations.
|
|
JustifiedCheckpoint(ctx context.Context) (*ethpb.Checkpoint, error)
|
|
FinalizedCheckpoint(ctx context.Context) (*ethpb.Checkpoint, error)
|
|
ArchivedPointRoot(ctx context.Context, slot primitives.Slot) [32]byte
|
|
HasArchivedPoint(ctx context.Context, slot primitives.Slot) bool
|
|
LastArchivedRoot(ctx context.Context) [32]byte
|
|
LastArchivedSlot(ctx context.Context) (primitives.Slot, error)
|
|
LastValidatedCheckpoint(ctx context.Context) (*ethpb.Checkpoint, error)
|
|
// Deposit contract related handlers.
|
|
DepositContractAddress(ctx context.Context) ([]byte, error)
|
|
// ExecutionChainData operations.
|
|
ExecutionChainData(ctx context.Context) (*ethpb.ETH1ChainData, error)
|
|
// Fee recipients operations.
|
|
FeeRecipientByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (common.Address, error)
|
|
RegistrationByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (*ethpb.ValidatorRegistrationV1, error)
|
|
// Light client operations
|
|
LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]interfaces.LightClientUpdate, error)
|
|
LightClientUpdate(ctx context.Context, period uint64) (interfaces.LightClientUpdate, error)
|
|
LightClientBootstrap(ctx context.Context, blockRoot []byte) (interfaces.LightClientBootstrap, error)
|
|
// Origin checkpoint sync support
|
|
OriginCheckpointBlockRoot(ctx context.Context) ([32]byte, error)
|
|
BackfillStatus(context.Context) (*dbval.BackfillStatus, error)
|
|
|
|
// P2P Metadata operations.
|
|
MetadataSeqNum(ctx context.Context) (uint64, error)
|
|
}
|
|
|
|
// ReadOnlyDatabaseWithSeqNum defines a struct which has read access to database methods
|
|
// and also has read/write access to the p2p metadata sequence number.
|
|
// Only used for the p2p service.
|
|
type ReadOnlyDatabaseWithSeqNum interface {
|
|
ReadOnlyDatabase
|
|
|
|
SaveMetadataSeqNum(ctx context.Context, seqNum uint64) error
|
|
}
|
|
|
|
// NoHeadAccessDatabase defines a struct without access to chain head data.
|
|
type NoHeadAccessDatabase interface {
|
|
ReadOnlyDatabase
|
|
|
|
// Block related methods.
|
|
DeleteBlock(ctx context.Context, root [32]byte) error
|
|
SaveBlock(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) error
|
|
SaveBlocks(ctx context.Context, blocks []interfaces.ReadOnlySignedBeaconBlock) error
|
|
SaveROBlocks(ctx context.Context, blks []blocks.ROBlock, cache bool) error
|
|
SaveGenesisBlockRoot(ctx context.Context, blockRoot [32]byte) error
|
|
// State related methods.
|
|
SaveState(ctx context.Context, state state.ReadOnlyBeaconState, blockRoot [32]byte) error
|
|
SaveStates(ctx context.Context, states []state.ReadOnlyBeaconState, blockRoots [][32]byte) error
|
|
DeleteState(ctx context.Context, blockRoot [32]byte) error
|
|
DeleteStates(ctx context.Context, blockRoots [][32]byte) error
|
|
SaveStateSummary(ctx context.Context, summary *ethpb.StateSummary) error
|
|
SaveStateSummaries(ctx context.Context, summaries []*ethpb.StateSummary) error
|
|
// Checkpoint operations.
|
|
SaveJustifiedCheckpoint(ctx context.Context, checkpoint *ethpb.Checkpoint) error
|
|
SaveFinalizedCheckpoint(ctx context.Context, checkpoint *ethpb.Checkpoint) error
|
|
SaveLastValidatedCheckpoint(ctx context.Context, checkpoint *ethpb.Checkpoint) error
|
|
// Deposit contract related handlers.
|
|
SaveDepositContractAddress(ctx context.Context, addr common.Address) error
|
|
// SaveExecutionChainData operations.
|
|
SaveExecutionChainData(ctx context.Context, data *ethpb.ETH1ChainData) error
|
|
// Run any required database migrations.
|
|
RunMigrations(ctx context.Context) error
|
|
// Fee recipients operations.
|
|
SaveFeeRecipientsByValidatorIDs(ctx context.Context, ids []primitives.ValidatorIndex, addrs []common.Address) error
|
|
SaveRegistrationsByValidatorIDs(ctx context.Context, ids []primitives.ValidatorIndex, regs []*ethpb.ValidatorRegistrationV1) error
|
|
// light client operations
|
|
SaveLightClientUpdate(ctx context.Context, period uint64, update interfaces.LightClientUpdate) error
|
|
SaveLightClientBootstrap(ctx context.Context, blockRoot []byte, bootstrap interfaces.LightClientBootstrap) error
|
|
|
|
CleanUpDirtyStates(ctx context.Context, slotsPerArchivedPoint primitives.Slot) error
|
|
DeleteHistoricalDataBeforeSlot(ctx context.Context, slot primitives.Slot, batchSize int) (int, error)
|
|
|
|
// Genesis operations.
|
|
LoadGenesis(ctx context.Context, stateBytes []byte) error
|
|
SaveGenesisData(ctx context.Context, state state.BeaconState) error
|
|
EnsureEmbeddedGenesis(ctx context.Context) error
|
|
|
|
// Support for checkpoint sync and backfill.
|
|
SaveOriginCheckpointBlockRoot(ctx context.Context, blockRoot [32]byte) error
|
|
SaveOrigin(ctx context.Context, serState, serBlock []byte) error
|
|
SaveBackfillStatus(context.Context, *dbval.BackfillStatus) error
|
|
BackfillFinalizedIndex(ctx context.Context, blocks []blocks.ROBlock, finalizedChildRoot [32]byte) error
|
|
|
|
// Custody operations.
|
|
UpdateCustodyInfo(ctx context.Context, earliestAvailableSlot primitives.Slot, custodyGroupCount uint64) (primitives.Slot, uint64, error)
|
|
UpdateEarliestAvailableSlot(ctx context.Context, earliestAvailableSlot primitives.Slot) error
|
|
UpdateSubscribedToAllDataSubnets(ctx context.Context, subscribed bool) (bool, error)
|
|
|
|
// P2P Metadata operations.
|
|
SaveMetadataSeqNum(ctx context.Context, seqNum uint64) error
|
|
}
|
|
|
|
// HeadAccessDatabase defines a struct with access to reading chain head data.
|
|
type HeadAccessDatabase interface {
|
|
NoHeadAccessDatabase
|
|
|
|
// Block related methods.
|
|
HeadBlock(ctx context.Context) (interfaces.ReadOnlySignedBeaconBlock, error)
|
|
HeadBlockRoot() ([32]byte, error)
|
|
SaveHeadBlockRoot(ctx context.Context, blockRoot [32]byte) error
|
|
}
|
|
|
|
// SlasherDatabase interface for persisting data related to detecting slashable offenses on Ethereum.
|
|
type SlasherDatabase interface {
|
|
io.Closer
|
|
SaveLastEpochWrittenForValidators(
|
|
ctx context.Context, epochByValidator map[primitives.ValidatorIndex]primitives.Epoch,
|
|
) error
|
|
SaveAttestationRecordsForValidators(
|
|
ctx context.Context,
|
|
attestations []*slashertypes.IndexedAttestationWrapper,
|
|
) error
|
|
SaveSlasherChunks(
|
|
ctx context.Context, kind slashertypes.ChunkKind, chunkKeys [][]byte, chunks [][]uint16,
|
|
) error
|
|
SaveBlockProposals(
|
|
ctx context.Context, proposal []*slashertypes.SignedBlockHeaderWrapper,
|
|
) error
|
|
LastEpochWrittenForValidators(
|
|
ctx context.Context, validatorIndices []primitives.ValidatorIndex,
|
|
) ([]*slashertypes.AttestedEpochForValidator, error)
|
|
AttestationRecordForValidator(
|
|
ctx context.Context, validatorIdx primitives.ValidatorIndex, targetEpoch primitives.Epoch,
|
|
) (*slashertypes.IndexedAttestationWrapper, error)
|
|
BlockProposalForValidator(
|
|
ctx context.Context, validatorIdx primitives.ValidatorIndex, slot primitives.Slot,
|
|
) (*slashertypes.SignedBlockHeaderWrapper, error)
|
|
CheckAttesterDoubleVotes(
|
|
ctx context.Context, attestations []*slashertypes.IndexedAttestationWrapper,
|
|
) ([]*slashertypes.AttesterDoubleVote, error)
|
|
LoadSlasherChunks(
|
|
ctx context.Context, kind slashertypes.ChunkKind, diskKeys [][]byte,
|
|
) ([][]uint16, []bool, error)
|
|
CheckDoubleBlockProposals(
|
|
ctx context.Context, proposals []*slashertypes.SignedBlockHeaderWrapper,
|
|
) ([]*ethpb.ProposerSlashing, error)
|
|
PruneAttestationsAtEpoch(
|
|
ctx context.Context, maxEpoch primitives.Epoch,
|
|
) (numPruned uint, err error)
|
|
PruneProposalsAtEpoch(
|
|
ctx context.Context, maxEpoch primitives.Epoch,
|
|
) (numPruned uint, err error)
|
|
HighestAttestations(
|
|
ctx context.Context,
|
|
indices []primitives.ValidatorIndex,
|
|
) ([]*ethpb.HighestAttestation, error)
|
|
DatabasePath() string
|
|
ClearDB() error
|
|
Migrate(ctx context.Context, headEpoch, maxPruningEpoch primitives.Epoch, batchSize int) error
|
|
}
|
|
|
|
// Database interface with full access.
|
|
type Database interface {
|
|
io.Closer
|
|
backup.Exporter
|
|
HeadAccessDatabase
|
|
|
|
DatabasePath() string
|
|
ClearDB() error
|
|
}
|