mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
17 Commits
peerdas-af
...
v5.2.0-rc.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
008f157e17 | ||
|
|
7afb8c3c86 | ||
|
|
e925d35d55 | ||
|
|
1f2d8cfae9 | ||
|
|
63bc965ddc | ||
|
|
a0791d77eb | ||
|
|
0d810a1fd6 | ||
|
|
92bbf6344c | ||
|
|
df81fa3e9a | ||
|
|
30a136f1fb | ||
|
|
b23c562b67 | ||
|
|
ae36630ccd | ||
|
|
ac72fe2e0e | ||
|
|
d09885b7ce | ||
|
|
dc643c9f32 | ||
|
|
9fa49e7bc9 | ||
|
|
1139c90ab2 |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -30,6 +30,9 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
|
||||
- Better attestation packing for Electra. [PR](https://github.com/prysmaticlabs/prysm/pull/14534)
|
||||
- P2P: Add logs when a peer is (dis)connected. Add the reason of the disconnection when we initiate it.
|
||||
- Added a Prometheus error counter metric for HTTP requests to track beacon node requests.
|
||||
- Added a Prometheus error counter metric for SSE requests.
|
||||
- Save light client updates and bootstraps in DB.
|
||||
- Added more comprehensive tests for `BlockToLightClientHeader`. [PR](https://github.com/prysmaticlabs/prysm/pull/14699)
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -64,19 +67,29 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
|
||||
- Updated light client protobufs. [PR](https://github.com/prysmaticlabs/prysm/pull/14650)
|
||||
- Added `Eth-Consensus-Version` header to `ListAttestationsV2` and `GetAggregateAttestationV2` endpoints.
|
||||
- Updated light client consensus types. [PR](https://github.com/prysmaticlabs/prysm/pull/14652)
|
||||
- Update earliest exit epoch for upgrade to electra
|
||||
- Add missed exit checks to consolidation processing
|
||||
- Fixed pending deposits processing on Electra.
|
||||
- Modified `ListAttestationsV2`, `GetAttesterSlashingsV2` and `GetAggregateAttestationV2` endpoints to use slot to determine fork version.
|
||||
- Improvements to HTTP response handling. [pr](https://github.com/prysmaticlabs/prysm/pull/14673)
|
||||
- Updated `Blobs` endpoint to return additional metadata fields.
|
||||
- Made QUIC the default method to connect with peers.
|
||||
- Check kzg commitments align with blobs and proofs for beacon api end point.
|
||||
- Increase Max Payload Size in Gossip.
|
||||
- Revert "Proposer checks gas limit before accepting builder's bid".
|
||||
- Updated quic-go to v0.48.2 .
|
||||
|
||||
### Deprecated
|
||||
|
||||
- `/eth/v1alpha1/validator/activation/stream` grpc wait for activation stream is deprecated. [pr](https://github.com/prysmaticlabs/prysm/pull/14514)
|
||||
- `--interop-genesis-time` and `--interop-num-validators` have been deprecated in the beacon node as the functionality has been removed. These flags have no effect.
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed finalized validator index cache, no longer needed.
|
||||
- Removed validator queue position log on key reload and wait for activation.
|
||||
- Removed outdated spectest exclusions for EIP-6110.
|
||||
- Removed support for starting a beacon node with a deterministic interop genesis state via interop flags. Alteratively, create a genesis state with prysmctl and use `--genesis-state`. This removes about 9Mb (~11%) of unnecessary code and dependencies from the final production binary.
|
||||
- Removed kzg proof check from blob reconstructor.
|
||||
|
||||
### Fixed
|
||||
@@ -98,8 +111,13 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
|
||||
- corrects nil check on some interface attestation types
|
||||
- temporary solution to handling electra attesation and attester_slashing events. [pr](14655)
|
||||
- Diverse log improvements and comment additions.
|
||||
- Validate that each committee bitfield in an aggregate contains at least one non-zero bit
|
||||
- P2P: Avoid infinite loop when looking for peers in small networks.
|
||||
|
||||
- Fixed another rollback bug due to a context deadline.
|
||||
- Fix checkpoint sync bug on holesky. [pr](https://github.com/prysmaticlabs/prysm/pull/14689)
|
||||
- Fix proposer boost spec tests being flakey by adjusting start time from 3 to 2s into slot.
|
||||
- Fix segmentation fault in E2E when light-client feature flag is enabled. [PR](https://github.com/prysmaticlabs/prysm/pull/14699)
|
||||
- Fix `searchForPeers` infinite loop in small networks.
|
||||
|
||||
### Security
|
||||
|
||||
@@ -424,6 +442,7 @@ block profit. If you want to preserve the existing behavior, set --local-block-v
|
||||
- Set default LocalBlockValueBoost to 10
|
||||
- Add bid value metrics
|
||||
- REST VC metrics
|
||||
- `startDB`: Add log when checkpoint sync.
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
110
INTEROP.md
110
INTEROP.md
@@ -2,18 +2,21 @@
|
||||
|
||||
This README details how to setup Prysm for interop testing for usage with other Ethereum consensus clients.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This guide is likely to be outdated. The Prysm team does not have capacity to troubleshoot
|
||||
> outdated interop guides or instructions. If you experience issues with this guide, please file and
|
||||
> issue for visibility and propose fixes, if possible.
|
||||
|
||||
## Installation & Setup
|
||||
|
||||
1. Install [Bazel](https://docs.bazel.build/versions/master/install.html) **(Recommended)**
|
||||
2. `git clone https://github.com/prysmaticlabs/prysm && cd prysm`
|
||||
3. `bazel build //...`
|
||||
3. `bazel build //cmd/...`
|
||||
|
||||
## Starting from Genesis
|
||||
|
||||
Prysm supports a few ways to quickly launch a beacon node from basic configurations:
|
||||
|
||||
- `NumValidators + GenesisTime`: Launches a beacon node by deterministically generating a state from a num-validators flag along with a genesis time **(Recommended)**
|
||||
- `SSZ Genesis`: Launches a beacon node from a .ssz file containing a SSZ-encoded, genesis beacon state
|
||||
Prysm can be started from a built-in mainnet genesis state, or started with a provided genesis state by
|
||||
using the `--genesis-state` flag and providing a path to the genesis.ssz file.
|
||||
|
||||
## Generating a Genesis State
|
||||
|
||||
@@ -21,21 +24,34 @@ To setup the necessary files for these quick starts, Prysm provides a tool to ge
|
||||
a deterministically generated set of validator private keys following the official interop YAML format
|
||||
[here](https://github.com/ethereum/eth2.0-pm/blob/master/interop/mocked_start).
|
||||
|
||||
You can use `bazel run //tools/genesis-state-gen` to create a deterministic genesis state for interop.
|
||||
You can use `prysmctl` to create a deterministic genesis state for interop.
|
||||
|
||||
### Usage
|
||||
|
||||
- **--genesis-time** uint: Unix timestamp used as the genesis time in the generated genesis state (defaults to now)
|
||||
- **--num-validators** int: Number of validators to deterministically include in the generated genesis state
|
||||
- **--output-ssz** string: Output filename of the SSZ marshaling of the generated genesis state
|
||||
- **--config-name=interop** string: name of the beacon chain config to use when generating the state. ex mainnet|minimal|interop
|
||||
|
||||
The example below creates 64 validator keys, instantiates a genesis state with those 64 validators and with genesis unix timestamp 1567542540,
|
||||
and finally writes a ssz encoded output to ~/Desktop/genesis.ssz. This file can be used to kickstart the beacon chain in the next section. When using the `--interop-*` flags, the beacon node will assume the `interop` config should be used, unless a different config is specified on the command line.
|
||||
```sh
|
||||
# Download (or create) a chain config file.
|
||||
curl https://raw.githubusercontent.com/ethereum/consensus-specs/refs/heads/dev/configs/minimal.yaml -o /tmp/minimal.yaml
|
||||
|
||||
# Run prysmctl to generate genesis with a 2 minute genesis delay and 256 validators.
|
||||
bazel run //cmd/prysmctl --config=minimal -- \
|
||||
testnet generate-genesis \
|
||||
--genesis-time-delay=120 \
|
||||
--num-validators=256 \
|
||||
--output-ssz=/tmp/genesis.ssz \
|
||||
--chain-config-file=/tmp/minimal.yaml
|
||||
```
|
||||
bazel run //tools/genesis-state-gen -- --config-name interop --output-ssz ~/Desktop/genesis.ssz --num-validators 64 --genesis-time 1567542540
|
||||
```
|
||||
|
||||
The flags are explained below:
|
||||
- `bazel run //cmd/prysmctl` is the bazel command to compile and run prysmctl.
|
||||
- `--config=minimal` is a bazel build time configuration flag to compile Prysm with minimal state constants.
|
||||
- `--` is an argument divider to tell bazel that everything after this divider should be passed as arguments to prysmctl. Without this divider, it isn't clear to bazel if the arguments are meant to be build time arguments or runtime arguments so the operation complains and fails to build without this divider.
|
||||
- `testnet` is the primary command argument for prysmctl.
|
||||
- `generate-genesis` is the subcommand to `testnet` in prysmctl.
|
||||
- `--genesis-time-delay` uint: The number of seconds in the future to define genesis. Example: a value of 60 will set the genesis time to 1 minute in the future. This should be sufficiently large enough to allow for you to start the beacon node before the genesis time.
|
||||
- `--num-validators` int: Number of validators to deterministically include in the generated genesis state
|
||||
- `--output-ssz` string: Output filename of the SSZ marshaling of the generated genesis state
|
||||
- `--chain-config-file` string: Filepath to a chain config yaml file.
|
||||
|
||||
Note: This guide saves items to the `/tmp/` directory which will not persist if your machine is
|
||||
restarted. Consider tweaking the arguments if persistence is needed.
|
||||
|
||||
## Launching a Beacon Node + Validator Client
|
||||
|
||||
@@ -44,45 +60,33 @@ bazel run //tools/genesis-state-gen -- --config-name interop --output-ssz ~/Desk
|
||||
Open up two terminal windows, run:
|
||||
|
||||
```
|
||||
bazel run //beacon-chain -- \
|
||||
--bootstrap-node= \
|
||||
--deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \
|
||||
--datadir=/tmp/beacon-chain-interop \
|
||||
--force-clear-db \
|
||||
--min-sync-peers=0 \
|
||||
--interop-num-validators 64 \
|
||||
--interop-eth1data-votes
|
||||
bazel run //cmd/beacon-chain --config=minimal -- \
|
||||
--minimal-config \
|
||||
--bootstrap-node= \
|
||||
--deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \
|
||||
--datadir=/tmp/beacon-chain-minimal-devnet \
|
||||
--force-clear-db \
|
||||
--min-sync-peers=0 \
|
||||
--genesis-state=/tmp/genesis.ssz \
|
||||
--chain-config-file=/tmp/minimal.yaml
|
||||
```
|
||||
|
||||
This will deterministically generate a beacon genesis state and start
|
||||
the system with 64 validators and the genesis time set to the current unix timestamp.
|
||||
Wait a bit until your beacon chain starts, and in the other window:
|
||||
This will start the system with 256 validators. The flags used can be explained as such:
|
||||
|
||||
- `bazel run //cmd/beacon-chain --config=minimal` builds and runs the beacon node in minimal build configuration.
|
||||
- `--` is a flag divider to distingish between bazel flags and flags that should be passed to the application. All flags and arguments after this divider are passed to the beacon chain.
|
||||
- `--minimal-config` tells the beacon node to use minimal network configuration. This is different from the compile time state configuration flag `--config=minimal` and both are required.
|
||||
- `--bootstrap-node=` disables the default bootstrap nodes. This prevents the client from attempting to peer with mainnet nodes.
|
||||
- `--datadir=/tmp/beacon-chain-minimal-devnet` sets the data directory in a temporary location. Change this to your preferred destination.
|
||||
- `--force-clear-db` will delete the beaconchain.db file without confirming with the user. This is helpful for iteratively running local devnets without changing the datadir, but less helpful for one off runs where there was no database in the data directory.
|
||||
- `--min-sync-peers=0` allows the beacon node to skip initial sync without peers. This is essential because Prysm expects at least a few peers to start start the blockchain.
|
||||
- `--genesis-state=/tmp/genesis.ssz` defines the path to the generated genesis ssz file. The beacon node will use this as the initial genesis state.
|
||||
- `--chain-config-file=/tmp/minimal.yaml` defines the path to the yaml file with the chain configuration.
|
||||
|
||||
As soon as the beacon node has started, start the validator in the other terminal window.
|
||||
|
||||
```
|
||||
bazel run //validator -- --keymanager=interop --keymanageropts='{"keys":64}'
|
||||
bazel run //cmd/validator --config=minimal -- --datadir=/tmp/validator --interopt-num-validators=256 --minimal-config --suggested-fee-recipient=0x8A04d14125D0FDCDc742F4A05C051De07232EDa4
|
||||
```
|
||||
|
||||
This will launch and kickstart the system with your 64 validators performing their duties accordingly.
|
||||
|
||||
### Launching from `genesis.ssz`
|
||||
|
||||
Assuming you generated a `genesis.ssz` file with 64 validators, open up two terminal windows, run:
|
||||
|
||||
```
|
||||
bazel run //beacon-chain -- \
|
||||
--bootstrap-node= \
|
||||
--deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \
|
||||
--datadir=/tmp/beacon-chain-interop \
|
||||
--force-clear-db \
|
||||
--min-sync-peers=0 \
|
||||
--interop-genesis-state /path/to/genesis.ssz \
|
||||
--interop-eth1data-votes
|
||||
```
|
||||
|
||||
Wait a bit until your beacon chain starts, and in the other window:
|
||||
|
||||
```
|
||||
bazel run //validator -- --keymanager=interop --keymanageropts='{"keys":64}'
|
||||
```
|
||||
|
||||
This will launch and kickstart the system with your 64 validators performing their duties accordingly.
|
||||
This will launch and kickstart the system with your 256 validators performing their duties accordingly.
|
||||
|
||||
10
WORKSPACE
10
WORKSPACE
@@ -227,7 +227,7 @@ filegroup(
|
||||
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
|
||||
)
|
||||
|
||||
consensus_spec_version = "v1.5.0-alpha.8"
|
||||
consensus_spec_version = "v1.5.0-alpha.9"
|
||||
|
||||
bls_test_version = "v0.1.1"
|
||||
|
||||
@@ -243,7 +243,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
integrity = "sha256-BsGIbEyJuYrzhShGl0tHhR4lP5Qwno8R3k8a6YBR/DA=",
|
||||
integrity = "sha256-gHbvlnErUeJGWzW8/8JiVlk28JwmXSMhOzkynEIz+8g=",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -259,7 +259,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
integrity = "sha256-DkdvhPP2KiqUOpwFXQIFDCWCwsUDIC/xhTBD+TZevm0=",
|
||||
integrity = "sha256-hQkQdpm5ng4miGYa5WsOKWa0q8WtZu99Oqbv9QtBeJM=",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -275,7 +275,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
integrity = "sha256-vkZqV0HB8A2Uc56C1Us/p5G57iaHL+zw2No93Xt6M/4=",
|
||||
integrity = "sha256-33sBsmApnJpcyYfR3olKaPB+WC1q00ZKNzHa2TczIxk=",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -290,7 +290,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
integrity = "sha256-D/HPAW61lKqjoWwl7N0XvhdX+67dCEFAy8JxVzqBGtU=",
|
||||
integrity = "sha256-GQulBKLc2khpql2K/MxV+NG/d2kAhLXl+gLnKIg7rt4=",
|
||||
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
|
||||
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -11,8 +11,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
MaxBodySize int64 = 1 << 23 // 8MB default, WithMaxBodySize can override
|
||||
MaxErrBodySize int64 = 1 << 17 // 128KB
|
||||
MaxBodySize int64 = 1 << 23 // 8MB default, WithMaxBodySize can override
|
||||
MaxBodySizeState int64 = 1 << 29 // 512MB
|
||||
MaxErrBodySize int64 = 1 << 17 // 128KB
|
||||
)
|
||||
|
||||
// Client is a wrapper object around the HTTP client.
|
||||
|
||||
@@ -36,9 +36,8 @@ go_library(
|
||||
"//math:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/migration:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version: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",
|
||||
|
||||
@@ -1546,3 +1546,10 @@ func EventChainReorgFromV1(event *ethv1.EventChainReorg) *ChainReorgEvent {
|
||||
ExecutionOptimistic: event.ExecutionOptimistic,
|
||||
}
|
||||
}
|
||||
|
||||
func SyncAggregateFromConsensus(sa *eth.SyncAggregate) *SyncAggregate {
|
||||
return &SyncAggregate{
|
||||
SyncCommitteeBits: hexutil.Encode(sa.SyncCommitteeBits),
|
||||
SyncCommitteeSignature: hexutil.Encode(sa.SyncCommitteeSignature),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,125 +3,227 @@ package structs
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
|
||||
v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
"github.com/prysmaticlabs/prysm/v5/proto/migration"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
)
|
||||
|
||||
func LightClientUpdateFromConsensus(update *v2.LightClientUpdate) (*LightClientUpdate, error) {
|
||||
attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader)
|
||||
func LightClientUpdateFromConsensus(update interfaces.LightClientUpdate) (*LightClientUpdate, error) {
|
||||
attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not marshal attested light client header")
|
||||
}
|
||||
finalizedHeader, err := lightClientHeaderContainerToJSON(update.FinalizedHeader)
|
||||
finalizedHeader, err := lightClientHeaderToJSON(update.FinalizedHeader())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not marshal finalized light client header")
|
||||
}
|
||||
|
||||
var scBranch [][32]byte
|
||||
var finalityBranch [][32]byte
|
||||
if update.Version() >= version.Electra {
|
||||
scb, err := update.NextSyncCommitteeBranchElectra()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scBranch = scb[:]
|
||||
fb, err := update.FinalityBranchElectra()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
finalityBranch = fb[:]
|
||||
} else {
|
||||
scb, err := update.NextSyncCommitteeBranch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scBranch = scb[:]
|
||||
fb, err := update.FinalityBranch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
finalityBranch = fb[:]
|
||||
}
|
||||
|
||||
return &LightClientUpdate{
|
||||
AttestedHeader: attestedHeader,
|
||||
NextSyncCommittee: SyncCommitteeFromConsensus(migration.V2SyncCommitteeToV1Alpha1(update.NextSyncCommittee)),
|
||||
NextSyncCommitteeBranch: branchToJSON(update.NextSyncCommitteeBranch),
|
||||
NextSyncCommittee: SyncCommitteeFromConsensus(update.NextSyncCommittee()),
|
||||
NextSyncCommitteeBranch: branchToJSON(scBranch),
|
||||
FinalizedHeader: finalizedHeader,
|
||||
FinalityBranch: branchToJSON(update.FinalityBranch),
|
||||
SyncAggregate: syncAggregateToJSON(update.SyncAggregate),
|
||||
SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10),
|
||||
FinalityBranch: branchToJSON(finalityBranch),
|
||||
SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()),
|
||||
SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func LightClientFinalityUpdateFromConsensus(update *v2.LightClientFinalityUpdate) (*LightClientFinalityUpdate, error) {
|
||||
attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader)
|
||||
func LightClientFinalityUpdateFromConsensus(update interfaces.LightClientFinalityUpdate) (*LightClientFinalityUpdate, error) {
|
||||
attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not marshal attested light client header")
|
||||
}
|
||||
finalizedHeader, err := lightClientHeaderContainerToJSON(update.FinalizedHeader)
|
||||
finalizedHeader, err := lightClientHeaderToJSON(update.FinalizedHeader())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not marshal finalized light client header")
|
||||
}
|
||||
|
||||
var finalityBranch [][32]byte
|
||||
if update.Version() >= version.Electra {
|
||||
b, err := update.FinalityBranchElectra()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
finalityBranch = b[:]
|
||||
} else {
|
||||
b, err := update.FinalityBranch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
finalityBranch = b[:]
|
||||
}
|
||||
|
||||
return &LightClientFinalityUpdate{
|
||||
AttestedHeader: attestedHeader,
|
||||
FinalizedHeader: finalizedHeader,
|
||||
FinalityBranch: branchToJSON(update.FinalityBranch),
|
||||
SyncAggregate: syncAggregateToJSON(update.SyncAggregate),
|
||||
SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10),
|
||||
FinalityBranch: branchToJSON(finalityBranch),
|
||||
SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()),
|
||||
SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func LightClientOptimisticUpdateFromConsensus(update *v2.LightClientOptimisticUpdate) (*LightClientOptimisticUpdate, error) {
|
||||
attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader)
|
||||
func LightClientOptimisticUpdateFromConsensus(update interfaces.LightClientOptimisticUpdate) (*LightClientOptimisticUpdate, error) {
|
||||
attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not marshal attested light client header")
|
||||
}
|
||||
|
||||
return &LightClientOptimisticUpdate{
|
||||
AttestedHeader: attestedHeader,
|
||||
SyncAggregate: syncAggregateToJSON(update.SyncAggregate),
|
||||
SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10),
|
||||
SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()),
|
||||
SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func branchToJSON(branchBytes [][]byte) []string {
|
||||
func branchToJSON[S [][32]byte](branchBytes S) []string {
|
||||
if branchBytes == nil {
|
||||
return nil
|
||||
}
|
||||
branch := make([]string, len(branchBytes))
|
||||
for i, root := range branchBytes {
|
||||
branch[i] = hexutil.Encode(root)
|
||||
branch[i] = hexutil.Encode(root[:])
|
||||
}
|
||||
return branch
|
||||
}
|
||||
|
||||
func syncAggregateToJSON(input *v1.SyncAggregate) *SyncAggregate {
|
||||
return &SyncAggregate{
|
||||
SyncCommitteeBits: hexutil.Encode(input.SyncCommitteeBits),
|
||||
SyncCommitteeSignature: hexutil.Encode(input.SyncCommitteeSignature),
|
||||
}
|
||||
}
|
||||
|
||||
func lightClientHeaderContainerToJSON(container *v2.LightClientHeaderContainer) (json.RawMessage, error) {
|
||||
func lightClientHeaderToJSON(header interfaces.LightClientHeader) (json.RawMessage, error) {
|
||||
// In the case that a finalizedHeader is nil.
|
||||
if container == nil {
|
||||
if header == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
beacon, err := container.GetBeacon()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get beacon block header")
|
||||
}
|
||||
var result any
|
||||
|
||||
var header any
|
||||
|
||||
switch t := (container.Header).(type) {
|
||||
case *v2.LightClientHeaderContainer_HeaderAltair:
|
||||
header = &LightClientHeader{Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon))}
|
||||
case *v2.LightClientHeaderContainer_HeaderCapella:
|
||||
execution, err := ExecutionPayloadHeaderCapellaFromConsensus(t.HeaderCapella.Execution)
|
||||
switch v := header.Version(); v {
|
||||
case version.Altair:
|
||||
result = &LightClientHeader{Beacon: BeaconBlockHeaderFromConsensus(header.Beacon())}
|
||||
case version.Capella:
|
||||
exInterface, err := header.Execution()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
header = &LightClientHeaderCapella{
|
||||
Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon)),
|
||||
Execution: execution,
|
||||
ExecutionBranch: branchToJSON(t.HeaderCapella.ExecutionBranch),
|
||||
ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderCapella)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderCapella{})
|
||||
}
|
||||
case *v2.LightClientHeaderContainer_HeaderDeneb:
|
||||
execution, err := ExecutionPayloadHeaderDenebFromConsensus(t.HeaderDeneb.Execution)
|
||||
execution, err := ExecutionPayloadHeaderCapellaFromConsensus(ex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
header = &LightClientHeaderDeneb{
|
||||
Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon)),
|
||||
executionBranch, err := header.ExecutionBranch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = &LightClientHeaderCapella{
|
||||
Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()),
|
||||
Execution: execution,
|
||||
ExecutionBranch: branchToJSON(t.HeaderDeneb.ExecutionBranch),
|
||||
ExecutionBranch: branchToJSON(executionBranch[:]),
|
||||
}
|
||||
case version.Deneb:
|
||||
exInterface, err := header.Execution()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderDeneb)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderDeneb{})
|
||||
}
|
||||
execution, err := ExecutionPayloadHeaderDenebFromConsensus(ex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
executionBranch, err := header.ExecutionBranch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = &LightClientHeaderDeneb{
|
||||
Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()),
|
||||
Execution: execution,
|
||||
ExecutionBranch: branchToJSON(executionBranch[:]),
|
||||
}
|
||||
case version.Electra:
|
||||
exInterface, err := header.Execution()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderElectra)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderElectra{})
|
||||
}
|
||||
execution, err := ExecutionPayloadHeaderElectraFromConsensus(ex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
executionBranch, err := header.ExecutionBranch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = &LightClientHeaderDeneb{
|
||||
Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()),
|
||||
Execution: execution,
|
||||
ExecutionBranch: branchToJSON(executionBranch[:]),
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported header type %T", t)
|
||||
return nil, fmt.Errorf("unsupported header version %s", version.String(v))
|
||||
}
|
||||
|
||||
return json.Marshal(header)
|
||||
return json.Marshal(result)
|
||||
}
|
||||
|
||||
func LightClientBootstrapFromConsensus(bootstrap interfaces.LightClientBootstrap) (*LightClientBootstrap, error) {
|
||||
header, err := lightClientHeaderToJSON(bootstrap.Header())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not marshal light client header")
|
||||
}
|
||||
|
||||
var scBranch [][32]byte
|
||||
if bootstrap.Version() >= version.Electra {
|
||||
b, err := bootstrap.CurrentSyncCommitteeBranchElectra()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scBranch = b[:]
|
||||
} else {
|
||||
b, err := bootstrap.CurrentSyncCommitteeBranch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scBranch = b[:]
|
||||
}
|
||||
|
||||
return &LightClientBootstrap{
|
||||
Header: header,
|
||||
CurrentSyncCommittee: SyncCommitteeFromConsensus(bootstrap.CurrentSyncCommittee()),
|
||||
CurrentSyncCommitteeBranch: branchToJSON(scBranch),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package structs
|
||||
|
||||
type SidecarsResponse struct {
|
||||
Data []*Sidecar `json:"data"`
|
||||
Version string `json:"version"`
|
||||
Data []*Sidecar `json:"data"`
|
||||
ExecutionOptimistic bool `json:"execution_optimistic"`
|
||||
Finalized bool `json:"finalized"`
|
||||
}
|
||||
|
||||
type Sidecar struct {
|
||||
|
||||
@@ -84,7 +84,6 @@ go_library(
|
||||
"//monitoring/tracing/trace:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
consensus_blocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
@@ -39,7 +38,7 @@ func prepareForkchoiceState(
|
||||
payloadHash [32]byte,
|
||||
justified *ethpb.Checkpoint,
|
||||
finalized *ethpb.Checkpoint,
|
||||
) (state.BeaconState, consensus_blocks.ROBlock, error) {
|
||||
) (state.BeaconState, blocks.ROBlock, error) {
|
||||
blockHeader := ðpb.BeaconBlockHeader{
|
||||
ParentRoot: parentRoot[:],
|
||||
}
|
||||
@@ -61,7 +60,7 @@ func prepareForkchoiceState(
|
||||
base.BlockRoots[0] = append(base.BlockRoots[0], blockRoot[:]...)
|
||||
st, err := state_native.InitializeFromProtoBellatrix(base)
|
||||
if err != nil {
|
||||
return nil, consensus_blocks.ROBlock{}, err
|
||||
return nil, blocks.ROBlock{}, err
|
||||
}
|
||||
blk := ðpb.SignedBeaconBlockBellatrix{
|
||||
Block: ðpb.BeaconBlockBellatrix{
|
||||
@@ -76,9 +75,9 @@ func prepareForkchoiceState(
|
||||
}
|
||||
signed, err := blocks.NewSignedBeaconBlock(blk)
|
||||
if err != nil {
|
||||
return nil, consensus_blocks.ROBlock{}, err
|
||||
return nil, blocks.ROBlock{}, err
|
||||
}
|
||||
roblock, err := consensus_blocks.NewROBlockWithRoot(signed, blockRoot)
|
||||
roblock, err := blocks.NewROBlockWithRoot(signed, blockRoot)
|
||||
return st, roblock, err
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@ go_test(
|
||||
deps = [
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_consensys_gnark_crypto//ecc/bls12-381/fr:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_crate_crypto_go_kzg_4844//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,51 +1,14 @@
|
||||
package kzg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
||||
GoKZG "github.com/crate-crypto/go-kzg-4844"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/util"
|
||||
)
|
||||
|
||||
func deterministicRandomness(seed int64) [32]byte {
|
||||
// Converts an int64 to a byte slice
|
||||
buf := new(bytes.Buffer)
|
||||
err := binary.Write(buf, binary.BigEndian, seed)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("Failed to write int64 to bytes buffer")
|
||||
return [32]byte{}
|
||||
}
|
||||
bytes := buf.Bytes()
|
||||
|
||||
return sha256.Sum256(bytes)
|
||||
}
|
||||
|
||||
// Returns a serialized random field element in big-endian
|
||||
func GetRandFieldElement(seed int64) [32]byte {
|
||||
bytes := deterministicRandomness(seed)
|
||||
var r fr.Element
|
||||
r.SetBytes(bytes[:])
|
||||
|
||||
return GoKZG.SerializeScalar(r)
|
||||
}
|
||||
|
||||
// Returns a random blob using the passed seed as entropy
|
||||
func GetRandBlob(seed int64) GoKZG.Blob {
|
||||
var blob GoKZG.Blob
|
||||
bytesPerBlob := GoKZG.ScalarsPerBlob * GoKZG.SerializedScalarSize
|
||||
for i := 0; i < bytesPerBlob; i += GoKZG.SerializedScalarSize {
|
||||
fieldElementBytes := GetRandFieldElement(seed + int64(i))
|
||||
copy(blob[i:i+GoKZG.SerializedScalarSize], fieldElementBytes[:])
|
||||
}
|
||||
return blob
|
||||
}
|
||||
|
||||
func GenerateCommitmentAndProof(blob GoKZG.Blob) (GoKZG.KZGCommitment, GoKZG.KZGProof, error) {
|
||||
commitment, err := kzgContext.BlobToKZGCommitment(blob, 0)
|
||||
if err != nil {
|
||||
@@ -74,7 +37,7 @@ func TestBytesToAny(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGenerateCommitmentAndProof(t *testing.T) {
|
||||
blob := GetRandBlob(123)
|
||||
blob := util.GetRandBlob(123)
|
||||
commitment, proof, err := GenerateCommitmentAndProof(blob)
|
||||
require.NoError(t, err)
|
||||
expectedCommitment := GoKZG.KZGCommitment{180, 218, 156, 194, 59, 20, 10, 189, 186, 254, 132, 93, 7, 127, 104, 172, 238, 240, 237, 70, 83, 89, 1, 152, 99, 0, 165, 65, 143, 62, 20, 215, 230, 14, 205, 95, 28, 245, 54, 25, 160, 16, 178, 31, 232, 207, 38, 85}
|
||||
|
||||
@@ -67,7 +67,10 @@ func (s *Service) postBlockProcess(cfg *postBlockProcessConfig) error {
|
||||
if s.inRegularSync() {
|
||||
defer s.handleSecondFCUCall(cfg, fcuArgs)
|
||||
}
|
||||
defer s.sendLightClientFeeds(cfg)
|
||||
if features.Get().EnableLightClient && slots.ToEpoch(s.CurrentSlot()) >= params.BeaconConfig().AltairForkEpoch {
|
||||
defer s.processLightClientUpdates(cfg)
|
||||
defer s.saveLightClientUpdate(cfg)
|
||||
}
|
||||
defer s.sendStateFeedOnBlock(cfg)
|
||||
defer reportProcessingTime(startTime)
|
||||
defer reportAttestationInclusion(cfg.roblock.Block())
|
||||
@@ -404,10 +407,9 @@ func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interface
|
||||
return errors.Wrapf(err, "could not save block from slot %d", b.Block().Slot())
|
||||
}
|
||||
if err := s.cfg.StateGen.SaveState(ctx, r, st); err != nil {
|
||||
log.Warnf("Rolling back insertion of block with root %#x", r)
|
||||
if err := s.cfg.BeaconDB.DeleteBlock(ctx, r); err != nil {
|
||||
log.WithError(err).Errorf("Could not delete block with block root %#x", r)
|
||||
}
|
||||
// Do not use parent context in the event it deadlined
|
||||
ctx = trace.NewContext(context.Background(), span)
|
||||
s.rollbackBlock(ctx, r)
|
||||
return errors.Wrap(err, "could not save state")
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
forkchoicetypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/types"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
field_params "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
consensus_blocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
@@ -24,7 +23,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
mathutil "github.com/prysmaticlabs/prysm/v5/math"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -115,64 +113,123 @@ func (s *Service) sendStateFeedOnBlock(cfg *postBlockProcessConfig) {
|
||||
})
|
||||
}
|
||||
|
||||
// sendLightClientFeeds sends the light client feeds when feature flag is enabled.
|
||||
func (s *Service) sendLightClientFeeds(cfg *postBlockProcessConfig) {
|
||||
if features.Get().EnableLightClient {
|
||||
if _, err := s.sendLightClientOptimisticUpdate(cfg.ctx, cfg.roblock, cfg.postState); err != nil {
|
||||
log.WithError(err).Error("Failed to send light client optimistic update")
|
||||
}
|
||||
|
||||
// Get the finalized checkpoint
|
||||
finalized := s.ForkChoicer().FinalizedCheckpoint()
|
||||
|
||||
// LightClientFinalityUpdate needs super majority
|
||||
s.tryPublishLightClientFinalityUpdate(cfg.ctx, cfg.roblock, finalized, cfg.postState)
|
||||
func (s *Service) processLightClientUpdates(cfg *postBlockProcessConfig) {
|
||||
if err := s.processLightClientOptimisticUpdate(cfg.ctx, cfg.roblock, cfg.postState); err != nil {
|
||||
log.WithError(err).Error("Failed to process light client optimistic update")
|
||||
}
|
||||
if err := s.processLightClientFinalityUpdate(cfg.ctx, cfg.roblock, cfg.postState); err != nil {
|
||||
log.WithError(err).Error("Failed to process light client finality update")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) tryPublishLightClientFinalityUpdate(ctx context.Context, signed interfaces.ReadOnlySignedBeaconBlock, finalized *forkchoicetypes.Checkpoint, postState state.BeaconState) {
|
||||
if finalized.Epoch <= s.lastPublishedLightClientEpoch {
|
||||
return
|
||||
}
|
||||
|
||||
config := params.BeaconConfig()
|
||||
if finalized.Epoch < config.AltairForkEpoch {
|
||||
return
|
||||
}
|
||||
|
||||
syncAggregate, err := signed.Block().Body().SyncAggregate()
|
||||
if err != nil || syncAggregate == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// LightClientFinalityUpdate needs super majority
|
||||
if syncAggregate.SyncCommitteeBits.Count()*3 < config.SyncCommitteeSize*2 {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = s.sendLightClientFinalityUpdate(ctx, signed, postState)
|
||||
// saveLightClientUpdate saves the light client update for this block
|
||||
// if it's better than the already saved one, when feature flag is enabled.
|
||||
func (s *Service) saveLightClientUpdate(cfg *postBlockProcessConfig) {
|
||||
attestedRoot := cfg.roblock.Block().ParentRoot()
|
||||
attestedBlock, err := s.getBlock(cfg.ctx, attestedRoot)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to send light client finality update")
|
||||
log.WithError(err).Error("Saving light client update failed: Could not get attested block")
|
||||
return
|
||||
}
|
||||
if attestedBlock == nil || attestedBlock.IsNil() {
|
||||
log.Error("Saving light client update failed: Attested block is nil")
|
||||
return
|
||||
}
|
||||
attestedState, err := s.cfg.StateGen.StateByRoot(cfg.ctx, attestedRoot)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Saving light client update failed: Could not get attested state")
|
||||
return
|
||||
}
|
||||
if attestedState == nil || attestedState.IsNil() {
|
||||
log.Error("Saving light client update failed: Attested state is nil")
|
||||
return
|
||||
}
|
||||
|
||||
finalizedRoot := attestedState.FinalizedCheckpoint().Root
|
||||
finalizedBlock, err := s.getBlock(cfg.ctx, [32]byte(finalizedRoot))
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Saving light client update failed: Could not get finalized block")
|
||||
return
|
||||
}
|
||||
|
||||
update, err := lightclient.NewLightClientUpdateFromBeaconState(
|
||||
cfg.ctx,
|
||||
s.CurrentSlot(),
|
||||
cfg.postState,
|
||||
cfg.roblock,
|
||||
attestedState,
|
||||
attestedBlock,
|
||||
finalizedBlock,
|
||||
)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Saving light client update failed: Could not create light client update")
|
||||
return
|
||||
}
|
||||
|
||||
period := slots.SyncCommitteePeriod(slots.ToEpoch(attestedState.Slot()))
|
||||
|
||||
oldUpdate, err := s.cfg.BeaconDB.LightClientUpdate(cfg.ctx, period)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Saving light client update failed: Could not get current light client update")
|
||||
return
|
||||
}
|
||||
|
||||
if oldUpdate == nil {
|
||||
if err := s.cfg.BeaconDB.SaveLightClientUpdate(cfg.ctx, period, update); err != nil {
|
||||
log.WithError(err).Error("Saving light client update failed: Could not save light client update")
|
||||
} else {
|
||||
log.WithField("period", period).Debug("Saving light client update: Saved new update")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
isNewUpdateBetter, err := lightclient.IsBetterUpdate(update, oldUpdate)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Saving light client update failed: Could not compare light client updates")
|
||||
return
|
||||
}
|
||||
|
||||
if isNewUpdateBetter {
|
||||
if err := s.cfg.BeaconDB.SaveLightClientUpdate(cfg.ctx, period, update); err != nil {
|
||||
log.WithError(err).Error("Saving light client update failed: Could not save light client update")
|
||||
} else {
|
||||
log.WithField("period", period).Debug("Saving light client update: Saved new update")
|
||||
}
|
||||
} else {
|
||||
s.lastPublishedLightClientEpoch = finalized.Epoch
|
||||
log.WithField("period", period).Debug("Saving light client update: New update is not better than the current one. Skipping save.")
|
||||
}
|
||||
}
|
||||
|
||||
// sendLightClientFinalityUpdate sends a light client finality update notification to the state feed.
|
||||
func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed interfaces.ReadOnlySignedBeaconBlock,
|
||||
postState state.BeaconState) (int, error) {
|
||||
// Get attested state
|
||||
// saveLightClientBootstrap saves a light client bootstrap for this block
|
||||
// when feature flag is enabled.
|
||||
func (s *Service) saveLightClientBootstrap(cfg *postBlockProcessConfig) {
|
||||
blockRoot := cfg.roblock.Root()
|
||||
bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(cfg.ctx, s.CurrentSlot(), cfg.postState, cfg.roblock)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Saving light client bootstrap failed: Could not create light client bootstrap")
|
||||
return
|
||||
}
|
||||
err = s.cfg.BeaconDB.SaveLightClientBootstrap(cfg.ctx, blockRoot[:], bootstrap)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Saving light client bootstrap failed: Could not save light client bootstrap in DB")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) processLightClientFinalityUpdate(
|
||||
ctx context.Context,
|
||||
signed interfaces.ReadOnlySignedBeaconBlock,
|
||||
postState state.BeaconState,
|
||||
) error {
|
||||
attestedRoot := signed.Block().ParentRoot()
|
||||
attestedBlock, err := s.cfg.BeaconDB.Block(ctx, attestedRoot)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not get attested block")
|
||||
return errors.Wrap(err, "could not get attested block")
|
||||
}
|
||||
attestedState, err := s.cfg.StateGen.StateByRoot(ctx, attestedRoot)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not get attested state")
|
||||
return errors.Wrap(err, "could not get attested state")
|
||||
}
|
||||
|
||||
// Get finalized block
|
||||
var finalizedBlock interfaces.ReadOnlySignedBeaconBlock
|
||||
finalizedCheckPoint := attestedState.FinalizedCheckpoint()
|
||||
if finalizedCheckPoint != nil {
|
||||
@@ -185,6 +242,7 @@ func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed inte
|
||||
|
||||
update, err := lightclient.NewLightClientFinalityUpdateFromBeaconState(
|
||||
ctx,
|
||||
postState.Slot(),
|
||||
postState,
|
||||
signed,
|
||||
attestedState,
|
||||
@@ -193,38 +251,31 @@ func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed inte
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not create light client update")
|
||||
return errors.Wrap(err, "could not create light client finality update")
|
||||
}
|
||||
|
||||
// Return the result
|
||||
result := ðpbv2.LightClientFinalityUpdateWithVersion{
|
||||
Version: ethpbv2.Version(signed.Version()),
|
||||
Data: update,
|
||||
}
|
||||
|
||||
// Send event
|
||||
return s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.LightClientFinalityUpdate,
|
||||
Data: result,
|
||||
}), nil
|
||||
Data: update,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendLightClientOptimisticUpdate sends a light client optimistic update notification to the state feed.
|
||||
func (s *Service) sendLightClientOptimisticUpdate(ctx context.Context, signed interfaces.ReadOnlySignedBeaconBlock,
|
||||
postState state.BeaconState) (int, error) {
|
||||
// Get attested state
|
||||
func (s *Service) processLightClientOptimisticUpdate(ctx context.Context, signed interfaces.ReadOnlySignedBeaconBlock,
|
||||
postState state.BeaconState) error {
|
||||
attestedRoot := signed.Block().ParentRoot()
|
||||
attestedBlock, err := s.cfg.BeaconDB.Block(ctx, attestedRoot)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not get attested block")
|
||||
return errors.Wrap(err, "could not get attested block")
|
||||
}
|
||||
attestedState, err := s.cfg.StateGen.StateByRoot(ctx, attestedRoot)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not get attested state")
|
||||
return errors.Wrap(err, "could not get attested state")
|
||||
}
|
||||
|
||||
update, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState(
|
||||
ctx,
|
||||
postState.Slot(),
|
||||
postState,
|
||||
signed,
|
||||
attestedState,
|
||||
@@ -232,19 +283,15 @@ func (s *Service) sendLightClientOptimisticUpdate(ctx context.Context, signed in
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not create light client update")
|
||||
return errors.Wrap(err, "could not create light client optimistic update")
|
||||
}
|
||||
|
||||
// Return the result
|
||||
result := ðpbv2.LightClientOptimisticUpdateWithVersion{
|
||||
Version: ethpbv2.Version(signed.Version()),
|
||||
Data: update,
|
||||
}
|
||||
|
||||
return s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.LightClientOptimisticUpdate,
|
||||
Data: result,
|
||||
}), nil
|
||||
Data: update,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateCachesPostBlockProcessing updates the next slot cache and handles the epoch
|
||||
|
||||
@@ -40,6 +40,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/util"
|
||||
prysmTime "github.com/prysmaticlabs/prysm/v5/time"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
@@ -2352,6 +2353,62 @@ func TestRollbackBlock(t *testing.T) {
|
||||
require.Equal(t, false, hasState)
|
||||
}
|
||||
|
||||
func TestRollbackBlock_SavePostStateInfo_ContextDeadline(t *testing.T) {
|
||||
service, tr := minimalTestService(t)
|
||||
ctx := tr.ctx
|
||||
|
||||
st, keys := util.DeterministicGenesisState(t, 64)
|
||||
stateRoot, err := st.HashTreeRoot(ctx)
|
||||
require.NoError(t, err, "Could not hash genesis state")
|
||||
|
||||
require.NoError(t, service.saveGenesisData(ctx, st))
|
||||
|
||||
genesis := blocks.NewGenesisBlock(stateRoot[:])
|
||||
wsb, err := consensusblocks.NewSignedBeaconBlock(genesis)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wsb), "Could not save genesis block")
|
||||
parentRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err, "Could not get signing root")
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st, parentRoot), "Could not save genesis state")
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state")
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveJustifiedCheckpoint(ctx, ðpb.Checkpoint{Root: parentRoot[:]}))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveFinalizedCheckpoint(ctx, ðpb.Checkpoint{Root: parentRoot[:]}))
|
||||
|
||||
st, err = service.HeadState(ctx)
|
||||
require.NoError(t, err)
|
||||
b, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 128)
|
||||
require.NoError(t, err)
|
||||
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
root, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
preState, err := service.getBlockPreState(ctx, wsb.Block())
|
||||
require.NoError(t, err)
|
||||
postState, err := service.validateStateTransition(ctx, preState, wsb)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Save state summaries so that the cache is flushed and saved to disk
|
||||
// later.
|
||||
for i := 1; i <= 127; i++ {
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, ðpb.StateSummary{
|
||||
Slot: primitives.Slot(i),
|
||||
Root: bytesutil.Bytes32(uint64(i)),
|
||||
}))
|
||||
}
|
||||
|
||||
// Set deadlined context when saving block and state
|
||||
cancCtx, canc := context.WithCancel(ctx)
|
||||
canc()
|
||||
|
||||
require.ErrorContains(t, context.Canceled.Error(), service.savePostStateInfo(cancCtx, root, wsb, postState))
|
||||
|
||||
// The block should no longer exist.
|
||||
require.Equal(t, false, service.cfg.BeaconDB.HasBlock(ctx, root))
|
||||
hasState, err := service.cfg.StateGen.HasState(ctx, root)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, false, hasState)
|
||||
}
|
||||
|
||||
func TestRollbackBlock_ContextDeadline(t *testing.T) {
|
||||
service, tr := minimalTestService(t)
|
||||
ctx := tr.ctx
|
||||
@@ -2446,3 +2503,290 @@ func fakeResult(missing []uint64) map[uint64]struct{} {
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func TestSaveLightClientUpdate(t *testing.T) {
|
||||
s, tr := minimalTestService(t)
|
||||
ctx := tr.ctx
|
||||
|
||||
t.Run("Altair", func(t *testing.T) {
|
||||
featCfg := &features.Flags{}
|
||||
featCfg.EnableLightClient = true
|
||||
reset := features.InitWithReset(featCfg)
|
||||
|
||||
l := util.NewTestLightClient(t).SetupTestAltair()
|
||||
|
||||
s.genesisTime = time.Unix(time.Now().Unix()-(int64(params.BeaconConfig().AltairForkEpoch)*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot)), 0)
|
||||
|
||||
err := s.cfg.BeaconDB.SaveBlock(ctx, l.AttestedBlock)
|
||||
require.NoError(t, err)
|
||||
attestedBlockRoot, err := l.AttestedBlock.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.AttestedState, attestedBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
currentBlockRoot, err := l.Block.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
roblock, err := consensusblocks.NewROBlockWithRoot(l.Block, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, roblock)
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.State, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, l.FinalizedBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := &postBlockProcessConfig{
|
||||
ctx: ctx,
|
||||
roblock: roblock,
|
||||
postState: l.State,
|
||||
isValidPayload: true,
|
||||
}
|
||||
|
||||
s.saveLightClientUpdate(cfg)
|
||||
|
||||
// Check that the light client update is saved
|
||||
period := slots.SyncCommitteePeriod(slots.ToEpoch(l.AttestedState.Slot()))
|
||||
|
||||
u, err := s.cfg.BeaconDB.LightClientUpdate(ctx, period)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, u)
|
||||
attestedStateRoot, err := l.AttestedState.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, attestedStateRoot, [32]byte(u.AttestedHeader().Beacon().StateRoot))
|
||||
require.Equal(t, u.Version(), version.Altair)
|
||||
|
||||
reset()
|
||||
})
|
||||
|
||||
t.Run("Capella", func(t *testing.T) {
|
||||
featCfg := &features.Flags{}
|
||||
featCfg.EnableLightClient = true
|
||||
reset := features.InitWithReset(featCfg)
|
||||
|
||||
l := util.NewTestLightClient(t).SetupTestCapella(false)
|
||||
|
||||
s.genesisTime = time.Unix(time.Now().Unix()-(int64(params.BeaconConfig().CapellaForkEpoch)*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot)), 0)
|
||||
|
||||
err := s.cfg.BeaconDB.SaveBlock(ctx, l.AttestedBlock)
|
||||
require.NoError(t, err)
|
||||
attestedBlockRoot, err := l.AttestedBlock.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.AttestedState, attestedBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
currentBlockRoot, err := l.Block.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
roblock, err := consensusblocks.NewROBlockWithRoot(l.Block, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, roblock)
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.State, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, l.FinalizedBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := &postBlockProcessConfig{
|
||||
ctx: ctx,
|
||||
roblock: roblock,
|
||||
postState: l.State,
|
||||
isValidPayload: true,
|
||||
}
|
||||
|
||||
s.saveLightClientUpdate(cfg)
|
||||
|
||||
// Check that the light client update is saved
|
||||
period := slots.SyncCommitteePeriod(slots.ToEpoch(l.AttestedState.Slot()))
|
||||
u, err := s.cfg.BeaconDB.LightClientUpdate(ctx, period)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, u)
|
||||
attestedStateRoot, err := l.AttestedState.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, attestedStateRoot, [32]byte(u.AttestedHeader().Beacon().StateRoot))
|
||||
require.Equal(t, u.Version(), version.Capella)
|
||||
|
||||
reset()
|
||||
})
|
||||
|
||||
t.Run("Deneb", func(t *testing.T) {
|
||||
featCfg := &features.Flags{}
|
||||
featCfg.EnableLightClient = true
|
||||
reset := features.InitWithReset(featCfg)
|
||||
|
||||
l := util.NewTestLightClient(t).SetupTestDeneb(false)
|
||||
|
||||
s.genesisTime = time.Unix(time.Now().Unix()-(int64(params.BeaconConfig().DenebForkEpoch)*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot)), 0)
|
||||
|
||||
err := s.cfg.BeaconDB.SaveBlock(ctx, l.AttestedBlock)
|
||||
require.NoError(t, err)
|
||||
attestedBlockRoot, err := l.AttestedBlock.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.AttestedState, attestedBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
currentBlockRoot, err := l.Block.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
roblock, err := consensusblocks.NewROBlockWithRoot(l.Block, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, roblock)
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.State, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, l.FinalizedBlock)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := &postBlockProcessConfig{
|
||||
ctx: ctx,
|
||||
roblock: roblock,
|
||||
postState: l.State,
|
||||
isValidPayload: true,
|
||||
}
|
||||
|
||||
s.saveLightClientUpdate(cfg)
|
||||
|
||||
// Check that the light client update is saved
|
||||
period := slots.SyncCommitteePeriod(slots.ToEpoch(l.AttestedState.Slot()))
|
||||
u, err := s.cfg.BeaconDB.LightClientUpdate(ctx, period)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, u)
|
||||
attestedStateRoot, err := l.AttestedState.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, attestedStateRoot, [32]byte(u.AttestedHeader().Beacon().StateRoot))
|
||||
require.Equal(t, u.Version(), version.Deneb)
|
||||
|
||||
reset()
|
||||
})
|
||||
}
|
||||
|
||||
func TestSaveLightClientBootstrap(t *testing.T) {
|
||||
s, tr := minimalTestService(t)
|
||||
ctx := tr.ctx
|
||||
|
||||
t.Run("Altair", func(t *testing.T) {
|
||||
featCfg := &features.Flags{}
|
||||
featCfg.EnableLightClient = true
|
||||
reset := features.InitWithReset(featCfg)
|
||||
|
||||
l := util.NewTestLightClient(t).SetupTestAltair()
|
||||
|
||||
s.genesisTime = time.Unix(time.Now().Unix()-(int64(params.BeaconConfig().AltairForkEpoch)*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot)), 0)
|
||||
|
||||
currentBlockRoot, err := l.Block.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
roblock, err := consensusblocks.NewROBlockWithRoot(l.Block, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, roblock)
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.State, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := &postBlockProcessConfig{
|
||||
ctx: ctx,
|
||||
roblock: roblock,
|
||||
postState: l.State,
|
||||
isValidPayload: true,
|
||||
}
|
||||
|
||||
s.saveLightClientBootstrap(cfg)
|
||||
|
||||
// Check that the light client bootstrap is saved
|
||||
b, err := s.cfg.BeaconDB.LightClientBootstrap(ctx, currentBlockRoot[:])
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, b)
|
||||
|
||||
stateRoot, err := l.State.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, stateRoot, [32]byte(b.Header().Beacon().StateRoot))
|
||||
require.Equal(t, b.Version(), version.Altair)
|
||||
|
||||
reset()
|
||||
})
|
||||
|
||||
t.Run("Capella", func(t *testing.T) {
|
||||
featCfg := &features.Flags{}
|
||||
featCfg.EnableLightClient = true
|
||||
reset := features.InitWithReset(featCfg)
|
||||
|
||||
l := util.NewTestLightClient(t).SetupTestCapella(false)
|
||||
|
||||
s.genesisTime = time.Unix(time.Now().Unix()-(int64(params.BeaconConfig().CapellaForkEpoch)*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot)), 0)
|
||||
|
||||
currentBlockRoot, err := l.Block.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
roblock, err := consensusblocks.NewROBlockWithRoot(l.Block, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, roblock)
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.State, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := &postBlockProcessConfig{
|
||||
ctx: ctx,
|
||||
roblock: roblock,
|
||||
postState: l.State,
|
||||
isValidPayload: true,
|
||||
}
|
||||
|
||||
s.saveLightClientBootstrap(cfg)
|
||||
|
||||
// Check that the light client bootstrap is saved
|
||||
b, err := s.cfg.BeaconDB.LightClientBootstrap(ctx, currentBlockRoot[:])
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, b)
|
||||
|
||||
stateRoot, err := l.State.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, stateRoot, [32]byte(b.Header().Beacon().StateRoot))
|
||||
require.Equal(t, b.Version(), version.Capella)
|
||||
|
||||
reset()
|
||||
})
|
||||
|
||||
t.Run("Deneb", func(t *testing.T) {
|
||||
featCfg := &features.Flags{}
|
||||
featCfg.EnableLightClient = true
|
||||
reset := features.InitWithReset(featCfg)
|
||||
|
||||
l := util.NewTestLightClient(t).SetupTestDeneb(false)
|
||||
|
||||
s.genesisTime = time.Unix(time.Now().Unix()-(int64(params.BeaconConfig().DenebForkEpoch)*int64(params.BeaconConfig().SlotsPerEpoch)*int64(params.BeaconConfig().SecondsPerSlot)), 0)
|
||||
|
||||
currentBlockRoot, err := l.Block.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
roblock, err := consensusblocks.NewROBlockWithRoot(l.Block, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.cfg.BeaconDB.SaveBlock(ctx, roblock)
|
||||
require.NoError(t, err)
|
||||
err = s.cfg.BeaconDB.SaveState(ctx, l.State, currentBlockRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := &postBlockProcessConfig{
|
||||
ctx: ctx,
|
||||
roblock: roblock,
|
||||
postState: l.State,
|
||||
isValidPayload: true,
|
||||
}
|
||||
|
||||
s.saveLightClientBootstrap(cfg)
|
||||
|
||||
// Check that the light client bootstrap is saved
|
||||
b, err := s.cfg.BeaconDB.LightClientBootstrap(ctx, currentBlockRoot[:])
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, b)
|
||||
|
||||
stateRoot, err := l.State.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, stateRoot, [32]byte(b.Header().Beacon().StateRoot))
|
||||
require.Equal(t, b.Version(), version.Deneb)
|
||||
|
||||
reset()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
forkchoicetypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/types"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
consensus_blocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -87,9 +86,7 @@ func TestProcessAttestations_Ok(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
|
||||
attsToSave := make([]ethpb.Att, len(atts))
|
||||
for i, a := range atts {
|
||||
attsToSave[i] = a
|
||||
}
|
||||
copy(attsToSave, atts)
|
||||
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(attsToSave))
|
||||
service.processAttestations(ctx, 0)
|
||||
require.Equal(t, 0, len(service.cfg.AttPool.ForkchoiceAttestations()))
|
||||
@@ -119,7 +116,7 @@ func TestService_ProcessAttestationsAndUpdateHead(t *testing.T) {
|
||||
postState, err := service.validateStateTransition(ctx, preState, wsb)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.savePostStateInfo(ctx, tRoot, wsb, postState))
|
||||
roblock, err := consensus_blocks.NewROBlockWithRoot(wsb, tRoot)
|
||||
roblock, err := blocks.NewROBlockWithRoot(wsb, tRoot)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, roblock, [32]byte{}, postState, false}))
|
||||
copied, err = service.cfg.StateGen.StateByRoot(ctx, tRoot)
|
||||
@@ -131,9 +128,7 @@ func TestService_ProcessAttestationsAndUpdateHead(t *testing.T) {
|
||||
atts, err := util.GenerateAttestations(copied, pks, 1, 1, false)
|
||||
require.NoError(t, err)
|
||||
attsToSave := make([]ethpb.Att, len(atts))
|
||||
for i, a := range atts {
|
||||
attsToSave[i] = a
|
||||
}
|
||||
copy(attsToSave, atts)
|
||||
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(attsToSave))
|
||||
// Verify the target is in forkchoice
|
||||
require.Equal(t, true, fcs.HasNode(bytesutil.ToBytes32(atts[0].GetData().BeaconBlockRoot)))
|
||||
@@ -181,7 +176,7 @@ func TestService_UpdateHead_NoAtts(t *testing.T) {
|
||||
postState, err := service.validateStateTransition(ctx, preState, wsb)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.savePostStateInfo(ctx, tRoot, wsb, postState))
|
||||
roblock, err := consensus_blocks.NewROBlockWithRoot(wsb, tRoot)
|
||||
roblock, err := blocks.NewROBlockWithRoot(wsb, tRoot)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, roblock, [32]byte{}, postState, false}))
|
||||
require.Equal(t, 2, fcs.NodeCount())
|
||||
|
||||
@@ -17,8 +17,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
consensus_blocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
consensusblocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
@@ -85,7 +83,7 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.ReadOnlySig
|
||||
}
|
||||
|
||||
currentCheckpoints := s.saveCurrentCheckpoints(preState)
|
||||
roblock, err := consensus_blocks.NewROBlockWithRoot(blockCopy, blockRoot)
|
||||
roblock, err := blocks.NewROBlockWithRoot(blockCopy, blockRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -190,7 +188,7 @@ func (s *Service) updateCheckpoints(
|
||||
func (s *Service) validateExecutionAndConsensus(
|
||||
ctx context.Context,
|
||||
preState state.BeaconState,
|
||||
block consensusblocks.ROBlock,
|
||||
block blocks.ROBlock,
|
||||
) (state.BeaconState, bool, error) {
|
||||
preStateVersion, preStateHeader, err := getStateVersionAndPayload(preState)
|
||||
if err != nil {
|
||||
@@ -560,7 +558,7 @@ func (s *Service) sendBlockAttestationsToSlasher(signed interfaces.ReadOnlySigne
|
||||
}
|
||||
|
||||
// validateExecutionOnBlock notifies the engine of the incoming block execution payload and returns true if the payload is valid
|
||||
func (s *Service) validateExecutionOnBlock(ctx context.Context, ver int, header interfaces.ExecutionData, block consensusblocks.ROBlock) (bool, error) {
|
||||
func (s *Service) validateExecutionOnBlock(ctx context.Context, ver int, header interfaces.ExecutionData, block blocks.ROBlock) (bool, error) {
|
||||
isValidPayload, err := s.notifyNewPayload(ctx, ver, header, block)
|
||||
if err != nil {
|
||||
s.cfg.ForkChoiceStore.Lock()
|
||||
|
||||
@@ -36,9 +36,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
consensus_blocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -49,25 +47,24 @@ import (
|
||||
// Service represents a service that handles the internal
|
||||
// logic of managing the full PoS beacon chain.
|
||||
type Service struct {
|
||||
cfg *config
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
genesisTime time.Time
|
||||
head *head
|
||||
headLock sync.RWMutex
|
||||
originBlockRoot [32]byte // genesis root, or weak subjectivity checkpoint root, depending on how the node is initialized
|
||||
boundaryRoots [][32]byte
|
||||
checkpointStateCache *cache.CheckpointStateCache
|
||||
initSyncBlocks map[[32]byte]interfaces.ReadOnlySignedBeaconBlock
|
||||
initSyncBlocksLock sync.RWMutex
|
||||
wsVerifier *WeakSubjectivityVerifier
|
||||
clockSetter startup.ClockSetter
|
||||
clockWaiter startup.ClockWaiter
|
||||
syncComplete chan struct{}
|
||||
blobNotifiers *blobNotifierMap
|
||||
blockBeingSynced *currentlySyncingBlock
|
||||
blobStorage *filesystem.BlobStorage
|
||||
lastPublishedLightClientEpoch primitives.Epoch
|
||||
cfg *config
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
genesisTime time.Time
|
||||
head *head
|
||||
headLock sync.RWMutex
|
||||
originBlockRoot [32]byte // genesis root, or weak subjectivity checkpoint root, depending on how the node is initialized
|
||||
boundaryRoots [][32]byte
|
||||
checkpointStateCache *cache.CheckpointStateCache
|
||||
initSyncBlocks map[[32]byte]interfaces.ReadOnlySignedBeaconBlock
|
||||
initSyncBlocksLock sync.RWMutex
|
||||
wsVerifier *WeakSubjectivityVerifier
|
||||
clockSetter startup.ClockSetter
|
||||
clockWaiter startup.ClockWaiter
|
||||
syncComplete chan struct{}
|
||||
blobNotifiers *blobNotifierMap
|
||||
blockBeingSynced *currentlySyncingBlock
|
||||
blobStorage *filesystem.BlobStorage
|
||||
}
|
||||
|
||||
// config options for the service.
|
||||
@@ -308,7 +305,7 @@ func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint block")
|
||||
}
|
||||
roblock, err := consensus_blocks.NewROBlockWithRoot(finalizedBlock, fRoot)
|
||||
roblock, err := blocks.NewROBlockWithRoot(finalizedBlock, fRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -524,7 +521,7 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState state.Beacon
|
||||
|
||||
s.cfg.ForkChoiceStore.Lock()
|
||||
defer s.cfg.ForkChoiceStore.Unlock()
|
||||
gb, err := consensus_blocks.NewROBlockWithRoot(genesisBlk, genesisBlkRoot)
|
||||
gb, err := blocks.NewROBlockWithRoot(genesisBlk, genesisBlkRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ go_library(
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/math:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
@@ -156,6 +157,13 @@ func ProcessPendingConsolidations(ctx context.Context, st state.BeaconState) err
|
||||
// if target_validator.exit_epoch != FAR_FUTURE_EPOCH:
|
||||
// return
|
||||
//
|
||||
// # Verify the source has been active long enough
|
||||
// if current_epoch < source_validator.activation_epoch + SHARD_COMMITTEE_PERIOD:
|
||||
// return
|
||||
//
|
||||
// # Verify the source has no pending withdrawals in the queue
|
||||
// if get_pending_balance_to_withdraw(state, source_index) > 0:
|
||||
// return
|
||||
// # Initiate source validator exit and append pending consolidation
|
||||
// source_validator.exit_epoch = compute_consolidation_epoch_and_update_churn(
|
||||
// state, source_validator.effective_balance
|
||||
@@ -258,6 +266,23 @@ func ProcessConsolidationRequests(ctx context.Context, st state.BeaconState, req
|
||||
continue
|
||||
}
|
||||
|
||||
e, overflow := math.SafeAdd(uint64(srcV.ActivationEpoch), uint64(params.BeaconConfig().ShardCommitteePeriod))
|
||||
if overflow {
|
||||
log.Error("Overflow when adding activation epoch and shard committee period")
|
||||
continue
|
||||
}
|
||||
if uint64(curEpoch) < e {
|
||||
continue
|
||||
}
|
||||
bal, err := st.PendingBalanceToWithdraw(srcIdx)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("failed to fetch pending balance to withdraw")
|
||||
continue
|
||||
}
|
||||
if bal > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Initiate the exit of the source validator.
|
||||
exitEpoch, err := ComputeConsolidationEpochAndUpdateChurn(ctx, st, primitives.Gwei(srcV.EffectiveBalance))
|
||||
if err != nil {
|
||||
|
||||
@@ -213,6 +213,7 @@ func TestProcessConsolidationRequests(t *testing.T) {
|
||||
name: "one valid request",
|
||||
state: func() state.BeaconState {
|
||||
st := ð.BeaconStateElectra{
|
||||
Slot: params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod)),
|
||||
Validators: createValidatorsWithTotalActiveBalance(32000000000000000), // 32M ETH
|
||||
}
|
||||
// Validator scenario setup. See comments in reqs section.
|
||||
@@ -222,6 +223,12 @@ func TestProcessConsolidationRequests(t *testing.T) {
|
||||
st.Validators[12].ActivationEpoch = params.BeaconConfig().FarFutureEpoch
|
||||
st.Validators[13].ExitEpoch = 10
|
||||
st.Validators[16].ExitEpoch = 10
|
||||
st.PendingPartialWithdrawals = []*eth.PendingPartialWithdrawal{
|
||||
{
|
||||
Index: 17,
|
||||
Amount: 100,
|
||||
},
|
||||
}
|
||||
s, err := state_native.InitializeFromProtoElectra(st)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
@@ -287,6 +294,12 @@ func TestProcessConsolidationRequests(t *testing.T) {
|
||||
SourcePubkey: []byte("val_0"),
|
||||
TargetPubkey: []byte("val_0"),
|
||||
},
|
||||
// Has pending partial withdrawal
|
||||
{
|
||||
SourceAddress: append(bytesutil.PadTo(nil, 19), byte(0)),
|
||||
SourcePubkey: []byte("val_17"),
|
||||
TargetPubkey: []byte("val_1"),
|
||||
},
|
||||
// Valid consolidation request. This should be last to ensure invalid requests do
|
||||
// not end the processing early.
|
||||
{
|
||||
@@ -347,6 +360,7 @@ func TestProcessConsolidationRequests(t *testing.T) {
|
||||
name: "pending consolidations limit reached during processing",
|
||||
state: func() state.BeaconState {
|
||||
st := ð.BeaconStateElectra{
|
||||
Slot: params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod)),
|
||||
Validators: createValidatorsWithTotalActiveBalance(32000000000000000), // 32M ETH
|
||||
PendingConsolidations: make([]*eth.PendingConsolidation, params.BeaconConfig().PendingConsolidationsLimit-1),
|
||||
}
|
||||
|
||||
@@ -16,36 +16,20 @@ import (
|
||||
)
|
||||
|
||||
// UpgradeToElectra updates inputs a generic state to return the version Electra state.
|
||||
//
|
||||
// nolint:dupword
|
||||
// Spec code:
|
||||
// def upgrade_to_electra(pre: deneb.BeaconState) -> BeaconState:
|
||||
//
|
||||
// epoch = deneb.get_current_epoch(pre)
|
||||
// latest_execution_payload_header = ExecutionPayloadHeader(
|
||||
// parent_hash=pre.latest_execution_payload_header.parent_hash,
|
||||
// fee_recipient=pre.latest_execution_payload_header.fee_recipient,
|
||||
// state_root=pre.latest_execution_payload_header.state_root,
|
||||
// receipts_root=pre.latest_execution_payload_header.receipts_root,
|
||||
// logs_bloom=pre.latest_execution_payload_header.logs_bloom,
|
||||
// prev_randao=pre.latest_execution_payload_header.prev_randao,
|
||||
// block_number=pre.latest_execution_payload_header.block_number,
|
||||
// gas_limit=pre.latest_execution_payload_header.gas_limit,
|
||||
// gas_used=pre.latest_execution_payload_header.gas_used,
|
||||
// timestamp=pre.latest_execution_payload_header.timestamp,
|
||||
// extra_data=pre.latest_execution_payload_header.extra_data,
|
||||
// base_fee_per_gas=pre.latest_execution_payload_header.base_fee_per_gas,
|
||||
// block_hash=pre.latest_execution_payload_header.block_hash,
|
||||
// transactions_root=pre.latest_execution_payload_header.transactions_root,
|
||||
// withdrawals_root=pre.latest_execution_payload_header.withdrawals_root,
|
||||
// blob_gas_used=pre.latest_execution_payload_header.blob_gas_used,
|
||||
// excess_blob_gas=pre.latest_execution_payload_header.excess_blob_gas,
|
||||
// deposit_requests_root=Root(), # [New in Electra:EIP6110]
|
||||
// withdrawal_requests_root=Root(), # [New in Electra:EIP7002],
|
||||
// consolidation_requests_root=Root(), # [New in Electra:EIP7251]
|
||||
// )
|
||||
// latest_execution_payload_header = pre.latest_execution_payload_header
|
||||
//
|
||||
// exit_epochs = [v.exit_epoch for v in pre.validators if v.exit_epoch != FAR_FUTURE_EPOCH]
|
||||
// if not exit_epochs:
|
||||
// exit_epochs = [get_current_epoch(pre)]
|
||||
// earliest_exit_epoch = max(exit_epochs) + 1
|
||||
// earliest_exit_epoch = compute_activation_exit_epoch(get_current_epoch(pre))
|
||||
// for validator in pre.validators:
|
||||
// if validator.exit_epoch != FAR_FUTURE_EPOCH:
|
||||
// if validator.exit_epoch > earliest_exit_epoch:
|
||||
// earliest_exit_epoch = validator.exit_epoch
|
||||
// earliest_exit_epoch += Epoch(1)
|
||||
//
|
||||
// post = BeaconState(
|
||||
// # Versioning
|
||||
@@ -120,7 +104,20 @@ import (
|
||||
// ))
|
||||
//
|
||||
// for index in pre_activation:
|
||||
// queue_entire_balance_and_reset_validator(post, ValidatorIndex(index))
|
||||
// balance = post.balances[index]
|
||||
// post.balances[index] = 0
|
||||
// validator = post.validators[index]
|
||||
// validator.effective_balance = 0
|
||||
// validator.activation_eligibility_epoch = FAR_FUTURE_EPOCH
|
||||
// # Use bls.G2_POINT_AT_INFINITY as a signature field placeholder
|
||||
// # and GENESIS_SLOT to distinguish from a pending deposit request
|
||||
// post.pending_deposits.append(PendingDeposit(
|
||||
// pubkey=validator.pubkey,
|
||||
// withdrawal_credentials=validator.withdrawal_credentials,
|
||||
// amount=balance,
|
||||
// signature=bls.G2_POINT_AT_INFINITY,
|
||||
// slot=GENESIS_SLOT,
|
||||
// ))
|
||||
//
|
||||
// # Ensure early adopters of compounding credentials go through the activation churn
|
||||
// for index, validator in enumerate(post.validators):
|
||||
@@ -187,7 +184,7 @@ func UpgradeToElectra(beaconState state.BeaconState) (state.BeaconState, error)
|
||||
}
|
||||
|
||||
// [New in Electra:EIP7251]
|
||||
earliestExitEpoch := time.CurrentEpoch(beaconState)
|
||||
earliestExitEpoch := helpers.ActivationExitEpoch(time.CurrentEpoch(beaconState))
|
||||
preActivationIndices := make([]primitives.ValidatorIndex, 0)
|
||||
compoundWithdrawalIndices := make([]primitives.ValidatorIndex, 0)
|
||||
if err = beaconState.ReadFromEveryValidator(func(index int, val state.ReadOnlyValidator) error {
|
||||
|
||||
@@ -159,7 +159,7 @@ func TestUpgradeToElectra(t *testing.T) {
|
||||
|
||||
eee, err := mSt.EarliestExitEpoch()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, primitives.Epoch(1), eee)
|
||||
require.Equal(t, helpers.ActivationExitEpoch(primitives.Epoch(1)), eee)
|
||||
|
||||
cbtc, err := mSt.ConsolidationBalanceToConsume()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -12,13 +12,15 @@ go_library(
|
||||
"//consensus-types:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/light-client:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/ssz:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -28,10 +30,14 @@ go_test(
|
||||
deps = [
|
||||
":go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/light-client:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/ssz:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
@@ -12,79 +13,64 @@ import (
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/ssz"
|
||||
v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
const (
|
||||
FinalityBranchNumOfLeaves = 6
|
||||
executionBranchNumOfLeaves = 4
|
||||
)
|
||||
|
||||
func createLightClientFinalityUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2.LightClientFinalityUpdate {
|
||||
finalityUpdate := ðpbv2.LightClientFinalityUpdate{
|
||||
AttestedHeader: update.AttestedHeader,
|
||||
FinalizedHeader: update.FinalizedHeader,
|
||||
FinalityBranch: update.FinalityBranch,
|
||||
SyncAggregate: update.SyncAggregate,
|
||||
SignatureSlot: update.SignatureSlot,
|
||||
}
|
||||
|
||||
return finalityUpdate
|
||||
}
|
||||
|
||||
func createLightClientOptimisticUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2.LightClientOptimisticUpdate {
|
||||
optimisticUpdate := ðpbv2.LightClientOptimisticUpdate{
|
||||
AttestedHeader: update.AttestedHeader,
|
||||
SyncAggregate: update.SyncAggregate,
|
||||
SignatureSlot: update.SignatureSlot,
|
||||
}
|
||||
|
||||
return optimisticUpdate
|
||||
}
|
||||
|
||||
func NewLightClientFinalityUpdateFromBeaconState(
|
||||
ctx context.Context,
|
||||
currentSlot primitives.Slot,
|
||||
state state.BeaconState,
|
||||
block interfaces.ReadOnlySignedBeaconBlock,
|
||||
attestedState state.BeaconState,
|
||||
attestedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
finalizedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (*ethpbv2.LightClientFinalityUpdate, error) {
|
||||
update, err := NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock)
|
||||
) (interfaces.LightClientFinalityUpdate, error) {
|
||||
update, err := NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return createLightClientFinalityUpdate(update), nil
|
||||
return light_client.NewFinalityUpdateFromUpdate(update)
|
||||
}
|
||||
|
||||
func NewLightClientOptimisticUpdateFromBeaconState(
|
||||
ctx context.Context,
|
||||
currentSlot primitives.Slot,
|
||||
state state.BeaconState,
|
||||
block interfaces.ReadOnlySignedBeaconBlock,
|
||||
attestedState state.BeaconState,
|
||||
attestedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (*ethpbv2.LightClientOptimisticUpdate, error) {
|
||||
update, err := NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, nil)
|
||||
) (interfaces.LightClientOptimisticUpdate, error) {
|
||||
update, err := NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return createLightClientOptimisticUpdate(update), nil
|
||||
return light_client.NewOptimisticUpdateFromUpdate(update)
|
||||
}
|
||||
|
||||
// To form a LightClientUpdate, the following historical states and blocks are needed:
|
||||
// - state: the post state of any block with a post-Altair parent block
|
||||
// - block: the corresponding block
|
||||
// - attested_state: the post state of attested_block
|
||||
// - attested_block: the block referred to by block.parent_root
|
||||
// - finalized_block: the block referred to by attested_state.finalized_checkpoint.root,
|
||||
// if locally available (may be unavailable, e.g., when using checkpoint sync, or if it was pruned locally)
|
||||
func NewLightClientUpdateFromBeaconState(
|
||||
ctx context.Context,
|
||||
currentSlot primitives.Slot,
|
||||
state state.BeaconState,
|
||||
block interfaces.ReadOnlySignedBeaconBlock,
|
||||
attestedState state.BeaconState,
|
||||
attestedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
finalizedBlock interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientUpdate, error) {
|
||||
finalizedBlock interfaces.ReadOnlySignedBeaconBlock) (interfaces.LightClientUpdate, error) {
|
||||
// assert compute_epoch_at_slot(attested_state.slot) >= ALTAIR_FORK_EPOCH
|
||||
attestedEpoch := slots.ToEpoch(attestedState.Slot())
|
||||
if attestedEpoch < params.BeaconConfig().AltairForkEpoch {
|
||||
@@ -129,7 +115,11 @@ func NewLightClientUpdateFromBeaconState(
|
||||
|
||||
// assert attested_state.slot == attested_state.latest_block_header.slot
|
||||
if attestedState.Slot() != attestedState.LatestBlockHeader().Slot {
|
||||
return nil, fmt.Errorf("attested state slot %d not equal to attested latest block header slot %d", attestedState.Slot(), attestedState.LatestBlockHeader().Slot)
|
||||
return nil, fmt.Errorf(
|
||||
"attested state slot %d not equal to attested latest block header slot %d",
|
||||
attestedState.Slot(),
|
||||
attestedState.LatestBlockHeader().Slot,
|
||||
)
|
||||
}
|
||||
|
||||
// attested_header = attested_state.latest_block_header.copy()
|
||||
@@ -153,46 +143,58 @@ func NewLightClientUpdateFromBeaconState(
|
||||
}
|
||||
// assert hash_tree_root(attested_header) == hash_tree_root(attested_block.message) == block.message.parent_root
|
||||
if attestedHeaderRoot != block.Block().ParentRoot() || attestedHeaderRoot != attestedBlockRoot {
|
||||
return nil, fmt.Errorf("attested header root %#x not equal to block parent root %#x or attested block root %#x", attestedHeaderRoot, block.Block().ParentRoot(), attestedBlockRoot)
|
||||
return nil, fmt.Errorf(
|
||||
"attested header root %#x not equal to block parent root %#x or attested block root %#x",
|
||||
attestedHeaderRoot,
|
||||
block.Block().ParentRoot(),
|
||||
attestedBlockRoot,
|
||||
)
|
||||
}
|
||||
|
||||
// update_attested_period = compute_sync_committee_period_at_slot(attested_block.message.slot)
|
||||
updateAttestedPeriod := slots.SyncCommitteePeriod(slots.ToEpoch(attestedBlock.Block().Slot()))
|
||||
|
||||
// update = LightClientUpdate()
|
||||
result, err := createDefaultLightClientUpdate()
|
||||
result, err := CreateDefaultLightClientUpdate(currentSlot, attestedState)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not create default light client update")
|
||||
}
|
||||
|
||||
// update.attested_header = block_to_light_client_header(attested_block)
|
||||
attestedLightClientHeader, err := BlockToLightClientHeader(attestedBlock)
|
||||
attestedLightClientHeader, err := BlockToLightClientHeader(ctx, currentSlot, attestedBlock)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get attested light client header")
|
||||
}
|
||||
result.AttestedHeader = attestedLightClientHeader
|
||||
if err = result.SetAttestedHeader(attestedLightClientHeader); err != nil {
|
||||
return nil, errors.Wrap(err, "could not set attested header")
|
||||
}
|
||||
|
||||
// if update_attested_period == update_signature_period
|
||||
if updateAttestedPeriod == updateSignaturePeriod {
|
||||
// update.next_sync_committee = attested_state.next_sync_committee
|
||||
tempNextSyncCommittee, err := attestedState.NextSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get next sync committee")
|
||||
}
|
||||
nextSyncCommittee := ðpbv2.SyncCommittee{
|
||||
nextSyncCommittee := &pb.SyncCommittee{
|
||||
Pubkeys: tempNextSyncCommittee.Pubkeys,
|
||||
AggregatePubkey: tempNextSyncCommittee.AggregatePubkey,
|
||||
}
|
||||
result.SetNextSyncCommittee(nextSyncCommittee)
|
||||
|
||||
// update.next_sync_committee_branch = NextSyncCommitteeBranch(
|
||||
// compute_merkle_proof(attested_state, next_sync_committee_gindex_at_slot(attested_state.slot)))
|
||||
nextSyncCommitteeBranch, err := attestedState.NextSyncCommitteeProof(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get next sync committee proof")
|
||||
}
|
||||
|
||||
// update.next_sync_committee = attested_state.next_sync_committee
|
||||
result.NextSyncCommittee = nextSyncCommittee
|
||||
|
||||
// update.next_sync_committee_branch = NextSyncCommitteeBranch(
|
||||
// compute_merkle_proof(attested_state, next_sync_committee_gindex_at_slot(attested_state.slot)))
|
||||
result.NextSyncCommitteeBranch = nextSyncCommitteeBranch
|
||||
if attestedBlock.Version() >= version.Electra {
|
||||
if err = result.SetNextSyncCommitteeBranch(nextSyncCommitteeBranch); err != nil {
|
||||
return nil, errors.Wrap(err, "could not set next sync committee branch")
|
||||
}
|
||||
} else if err = result.SetNextSyncCommitteeBranch(nextSyncCommitteeBranch); err != nil {
|
||||
return nil, errors.Wrap(err, "could not set next sync committee branch")
|
||||
}
|
||||
}
|
||||
|
||||
// if finalized_block is not None
|
||||
@@ -200,11 +202,13 @@ func NewLightClientUpdateFromBeaconState(
|
||||
// if finalized_block.message.slot != GENESIS_SLOT
|
||||
if finalizedBlock.Block().Slot() != 0 {
|
||||
// update.finalized_header = block_to_light_client_header(finalized_block)
|
||||
finalizedLightClientHeader, err := BlockToLightClientHeader(finalizedBlock)
|
||||
finalizedLightClientHeader, err := BlockToLightClientHeader(ctx, currentSlot, finalizedBlock)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get finalized light client header")
|
||||
}
|
||||
result.FinalizedHeader = finalizedLightClientHeader
|
||||
if err = result.SetFinalizedHeader(finalizedLightClientHeader); err != nil {
|
||||
return nil, errors.Wrap(err, "could not set finalized header")
|
||||
}
|
||||
} else {
|
||||
// assert attested_state.finalized_checkpoint.root == Bytes32()
|
||||
if !bytes.Equal(attestedState.FinalizedCheckpoint().Root, make([]byte, 32)) {
|
||||
@@ -218,49 +222,120 @@ func NewLightClientUpdateFromBeaconState(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get finalized root proof")
|
||||
}
|
||||
result.FinalityBranch = finalityBranch
|
||||
if err = result.SetFinalityBranch(finalityBranch); err != nil {
|
||||
return nil, errors.Wrap(err, "could not set finality branch")
|
||||
}
|
||||
}
|
||||
|
||||
// update.sync_aggregate = block.message.body.sync_aggregate
|
||||
result.SyncAggregate = ðpbv1.SyncAggregate{
|
||||
result.SetSyncAggregate(&pb.SyncAggregate{
|
||||
SyncCommitteeBits: syncAggregate.SyncCommitteeBits,
|
||||
SyncCommitteeSignature: syncAggregate.SyncCommitteeSignature,
|
||||
}
|
||||
})
|
||||
|
||||
// update.signature_slot = block.message.slot
|
||||
result.SignatureSlot = block.Block().Slot()
|
||||
result.SetSignatureSlot(block.Block().Slot())
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func createDefaultLightClientUpdate() (*ethpbv2.LightClientUpdate, error) {
|
||||
func CreateDefaultLightClientUpdate(currentSlot primitives.Slot, attestedState state.BeaconState) (interfaces.LightClientUpdate, error) {
|
||||
currentEpoch := slots.ToEpoch(currentSlot)
|
||||
|
||||
syncCommitteeSize := params.BeaconConfig().SyncCommitteeSize
|
||||
pubKeys := make([][]byte, syncCommitteeSize)
|
||||
for i := uint64(0); i < syncCommitteeSize; i++ {
|
||||
pubKeys[i] = make([]byte, fieldparams.BLSPubkeyLength)
|
||||
}
|
||||
nextSyncCommittee := ðpbv2.SyncCommittee{
|
||||
nextSyncCommittee := &pb.SyncCommittee{
|
||||
Pubkeys: pubKeys,
|
||||
AggregatePubkey: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
}
|
||||
nextSyncCommitteeBranch := make([][]byte, fieldparams.SyncCommitteeBranchDepth)
|
||||
for i := 0; i < fieldparams.SyncCommitteeBranchDepth; i++ {
|
||||
|
||||
var nextSyncCommitteeBranch [][]byte
|
||||
if attestedState.Version() >= version.Electra {
|
||||
nextSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepthElectra)
|
||||
} else {
|
||||
nextSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepth)
|
||||
}
|
||||
for i := 0; i < len(nextSyncCommitteeBranch); i++ {
|
||||
nextSyncCommitteeBranch[i] = make([]byte, fieldparams.RootLength)
|
||||
}
|
||||
executionBranch := make([][]byte, executionBranchNumOfLeaves)
|
||||
for i := 0; i < executionBranchNumOfLeaves; i++ {
|
||||
|
||||
executionBranch := make([][]byte, fieldparams.ExecutionBranchDepth)
|
||||
for i := 0; i < fieldparams.ExecutionBranchDepth; i++ {
|
||||
executionBranch[i] = make([]byte, 32)
|
||||
}
|
||||
finalityBranch := make([][]byte, FinalityBranchNumOfLeaves)
|
||||
for i := 0; i < FinalityBranchNumOfLeaves; i++ {
|
||||
|
||||
var finalityBranch [][]byte
|
||||
if attestedState.Version() >= version.Electra {
|
||||
finalityBranch = make([][]byte, fieldparams.FinalityBranchDepthElectra)
|
||||
} else {
|
||||
finalityBranch = make([][]byte, fieldparams.FinalityBranchDepth)
|
||||
}
|
||||
for i := 0; i < len(finalityBranch); i++ {
|
||||
finalityBranch[i] = make([]byte, 32)
|
||||
}
|
||||
|
||||
return ðpbv2.LightClientUpdate{
|
||||
NextSyncCommittee: nextSyncCommittee,
|
||||
NextSyncCommitteeBranch: nextSyncCommitteeBranch,
|
||||
FinalityBranch: finalityBranch,
|
||||
}, nil
|
||||
var m proto.Message
|
||||
if currentEpoch < params.BeaconConfig().CapellaForkEpoch {
|
||||
m = &pb.LightClientUpdateAltair{
|
||||
AttestedHeader: &pb.LightClientHeaderAltair{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
},
|
||||
NextSyncCommittee: nextSyncCommittee,
|
||||
NextSyncCommitteeBranch: nextSyncCommitteeBranch,
|
||||
FinalityBranch: finalityBranch,
|
||||
}
|
||||
} else if currentEpoch < params.BeaconConfig().DenebForkEpoch {
|
||||
m = &pb.LightClientUpdateCapella{
|
||||
AttestedHeader: &pb.LightClientHeaderCapella{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
Execution: &enginev1.ExecutionPayloadHeaderCapella{},
|
||||
ExecutionBranch: executionBranch,
|
||||
},
|
||||
NextSyncCommittee: nextSyncCommittee,
|
||||
NextSyncCommitteeBranch: nextSyncCommitteeBranch,
|
||||
FinalityBranch: finalityBranch,
|
||||
}
|
||||
} else if currentEpoch < params.BeaconConfig().ElectraForkEpoch {
|
||||
m = &pb.LightClientUpdateDeneb{
|
||||
AttestedHeader: &pb.LightClientHeaderDeneb{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
Execution: &enginev1.ExecutionPayloadHeaderDeneb{},
|
||||
ExecutionBranch: executionBranch,
|
||||
},
|
||||
NextSyncCommittee: nextSyncCommittee,
|
||||
NextSyncCommitteeBranch: nextSyncCommitteeBranch,
|
||||
FinalityBranch: finalityBranch,
|
||||
}
|
||||
} else {
|
||||
if attestedState.Version() >= version.Electra {
|
||||
m = &pb.LightClientUpdateElectra{
|
||||
AttestedHeader: &pb.LightClientHeaderDeneb{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
Execution: &enginev1.ExecutionPayloadHeaderDeneb{},
|
||||
ExecutionBranch: executionBranch,
|
||||
},
|
||||
NextSyncCommittee: nextSyncCommittee,
|
||||
NextSyncCommitteeBranch: nextSyncCommitteeBranch,
|
||||
FinalityBranch: finalityBranch,
|
||||
}
|
||||
} else {
|
||||
m = &pb.LightClientUpdateDeneb{
|
||||
AttestedHeader: &pb.LightClientHeaderDeneb{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
Execution: &enginev1.ExecutionPayloadHeaderDeneb{},
|
||||
ExecutionBranch: executionBranch,
|
||||
},
|
||||
NextSyncCommittee: nextSyncCommittee,
|
||||
NextSyncCommitteeBranch: nextSyncCommitteeBranch,
|
||||
FinalityBranch: finalityBranch,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return light_client.NewWrappedUpdate(m)
|
||||
}
|
||||
|
||||
func ComputeTransactionsRoot(payload interfaces.ExecutionData) ([]byte, error) {
|
||||
@@ -299,48 +374,14 @@ func ComputeWithdrawalsRoot(payload interfaces.ExecutionData) ([]byte, error) {
|
||||
return withdrawalsRoot, nil
|
||||
}
|
||||
|
||||
func BlockToLightClientHeader(block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderContainer, error) {
|
||||
switch block.Version() {
|
||||
case version.Altair, version.Bellatrix:
|
||||
altairHeader, err := blockToLightClientHeaderAltair(block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get header")
|
||||
}
|
||||
return ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: altairHeader,
|
||||
},
|
||||
}, nil
|
||||
case version.Capella:
|
||||
capellaHeader, err := blockToLightClientHeaderCapella(context.Background(), block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get capella header")
|
||||
}
|
||||
return ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{
|
||||
HeaderCapella: capellaHeader,
|
||||
},
|
||||
}, nil
|
||||
case version.Deneb, version.Electra:
|
||||
denebHeader, err := blockToLightClientHeaderDeneb(context.Background(), block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get header")
|
||||
}
|
||||
return ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{
|
||||
HeaderDeneb: denebHeader,
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported block version %s", version.String(block.Version()))
|
||||
}
|
||||
}
|
||||
|
||||
func blockToLightClientHeaderAltair(block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeader, error) {
|
||||
if block.Version() < version.Altair {
|
||||
return nil, fmt.Errorf("block version is %s instead of Altair", version.String(block.Version()))
|
||||
}
|
||||
|
||||
func BlockToLightClientHeader(
|
||||
ctx context.Context,
|
||||
currentSlot primitives.Slot,
|
||||
block interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (interfaces.LightClientHeader, error) {
|
||||
var m proto.Message
|
||||
currentEpoch := slots.ToEpoch(currentSlot)
|
||||
blockEpoch := slots.ToEpoch(block.Block().Slot())
|
||||
parentRoot := block.Block().ParentRoot()
|
||||
stateRoot := block.Block().StateRoot()
|
||||
bodyRoot, err := block.Block().Body().HashTreeRoot()
|
||||
@@ -348,147 +389,434 @@ func blockToLightClientHeaderAltair(block interfaces.ReadOnlySignedBeaconBlock)
|
||||
return nil, errors.Wrap(err, "could not get body root")
|
||||
}
|
||||
|
||||
return ðpbv2.LightClientHeader{
|
||||
Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: block.Block().Slot(),
|
||||
ProposerIndex: block.Block().ProposerIndex(),
|
||||
ParentRoot: parentRoot[:],
|
||||
StateRoot: stateRoot[:],
|
||||
BodyRoot: bodyRoot[:],
|
||||
},
|
||||
}, nil
|
||||
if currentEpoch < params.BeaconConfig().CapellaForkEpoch {
|
||||
m = &pb.LightClientHeaderAltair{
|
||||
Beacon: &pb.BeaconBlockHeader{
|
||||
Slot: block.Block().Slot(),
|
||||
ProposerIndex: block.Block().ProposerIndex(),
|
||||
ParentRoot: parentRoot[:],
|
||||
StateRoot: stateRoot[:],
|
||||
BodyRoot: bodyRoot[:],
|
||||
},
|
||||
}
|
||||
} else if currentEpoch < params.BeaconConfig().DenebForkEpoch {
|
||||
var payloadHeader *enginev1.ExecutionPayloadHeaderCapella
|
||||
var payloadProof [][]byte
|
||||
|
||||
if blockEpoch < params.BeaconConfig().CapellaForkEpoch {
|
||||
payloadHeader = &enginev1.ExecutionPayloadHeaderCapella{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
TransactionsRoot: make([]byte, fieldparams.RootLength),
|
||||
WithdrawalsRoot: make([]byte, fieldparams.RootLength),
|
||||
}
|
||||
payloadProof = emptyPayloadProof()
|
||||
} else {
|
||||
payload, err := block.Block().Body().Execution()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload")
|
||||
}
|
||||
transactionsRoot, err := ComputeTransactionsRoot(payload)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get transactions root")
|
||||
}
|
||||
withdrawalsRoot, err := ComputeWithdrawalsRoot(payload)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get withdrawals root")
|
||||
}
|
||||
|
||||
payloadHeader = &enginev1.ExecutionPayloadHeaderCapella{
|
||||
ParentHash: payload.ParentHash(),
|
||||
FeeRecipient: payload.FeeRecipient(),
|
||||
StateRoot: payload.StateRoot(),
|
||||
ReceiptsRoot: payload.ReceiptsRoot(),
|
||||
LogsBloom: payload.LogsBloom(),
|
||||
PrevRandao: payload.PrevRandao(),
|
||||
BlockNumber: payload.BlockNumber(),
|
||||
GasLimit: payload.GasLimit(),
|
||||
GasUsed: payload.GasUsed(),
|
||||
Timestamp: payload.Timestamp(),
|
||||
ExtraData: payload.ExtraData(),
|
||||
BaseFeePerGas: payload.BaseFeePerGas(),
|
||||
BlockHash: payload.BlockHash(),
|
||||
TransactionsRoot: transactionsRoot,
|
||||
WithdrawalsRoot: withdrawalsRoot,
|
||||
}
|
||||
|
||||
payloadProof, err = blocks.PayloadProof(ctx, block.Block())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload proof")
|
||||
}
|
||||
}
|
||||
|
||||
m = &pb.LightClientHeaderCapella{
|
||||
Beacon: &pb.BeaconBlockHeader{
|
||||
Slot: block.Block().Slot(),
|
||||
ProposerIndex: block.Block().ProposerIndex(),
|
||||
ParentRoot: parentRoot[:],
|
||||
StateRoot: stateRoot[:],
|
||||
BodyRoot: bodyRoot[:],
|
||||
},
|
||||
Execution: payloadHeader,
|
||||
ExecutionBranch: payloadProof,
|
||||
}
|
||||
} else {
|
||||
var payloadHeader *enginev1.ExecutionPayloadHeaderDeneb
|
||||
var payloadProof [][]byte
|
||||
|
||||
if blockEpoch < params.BeaconConfig().CapellaForkEpoch {
|
||||
payloadHeader = &enginev1.ExecutionPayloadHeaderDeneb{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
TransactionsRoot: make([]byte, fieldparams.RootLength),
|
||||
WithdrawalsRoot: make([]byte, fieldparams.RootLength),
|
||||
}
|
||||
payloadProof = emptyPayloadProof()
|
||||
} else {
|
||||
payload, err := block.Block().Body().Execution()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload")
|
||||
}
|
||||
transactionsRoot, err := ComputeTransactionsRoot(payload)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get transactions root")
|
||||
}
|
||||
withdrawalsRoot, err := ComputeWithdrawalsRoot(payload)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get withdrawals root")
|
||||
}
|
||||
|
||||
var blobGasUsed uint64
|
||||
var excessBlobGas uint64
|
||||
|
||||
if blockEpoch >= params.BeaconConfig().DenebForkEpoch {
|
||||
blobGasUsed, err = payload.BlobGasUsed()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get blob gas used")
|
||||
}
|
||||
excessBlobGas, err = payload.ExcessBlobGas()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get excess blob gas")
|
||||
}
|
||||
}
|
||||
|
||||
payloadHeader = &enginev1.ExecutionPayloadHeaderDeneb{
|
||||
ParentHash: payload.ParentHash(),
|
||||
FeeRecipient: payload.FeeRecipient(),
|
||||
StateRoot: payload.StateRoot(),
|
||||
ReceiptsRoot: payload.ReceiptsRoot(),
|
||||
LogsBloom: payload.LogsBloom(),
|
||||
PrevRandao: payload.PrevRandao(),
|
||||
BlockNumber: payload.BlockNumber(),
|
||||
GasLimit: payload.GasLimit(),
|
||||
GasUsed: payload.GasUsed(),
|
||||
Timestamp: payload.Timestamp(),
|
||||
ExtraData: payload.ExtraData(),
|
||||
BaseFeePerGas: payload.BaseFeePerGas(),
|
||||
BlockHash: payload.BlockHash(),
|
||||
TransactionsRoot: transactionsRoot,
|
||||
WithdrawalsRoot: withdrawalsRoot,
|
||||
BlobGasUsed: blobGasUsed,
|
||||
ExcessBlobGas: excessBlobGas,
|
||||
}
|
||||
|
||||
payloadProof, err = blocks.PayloadProof(ctx, block.Block())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload proof")
|
||||
}
|
||||
}
|
||||
|
||||
m = &pb.LightClientHeaderDeneb{
|
||||
Beacon: &pb.BeaconBlockHeader{
|
||||
Slot: block.Block().Slot(),
|
||||
ProposerIndex: block.Block().ProposerIndex(),
|
||||
ParentRoot: parentRoot[:],
|
||||
StateRoot: stateRoot[:],
|
||||
BodyRoot: bodyRoot[:],
|
||||
},
|
||||
Execution: payloadHeader,
|
||||
ExecutionBranch: payloadProof,
|
||||
}
|
||||
}
|
||||
|
||||
return light_client.NewWrappedHeader(m)
|
||||
}
|
||||
|
||||
func blockToLightClientHeaderCapella(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderCapella, error) {
|
||||
if block.Version() < version.Capella {
|
||||
return nil, fmt.Errorf("block version is %s instead of Capella", version.String(block.Version()))
|
||||
func emptyPayloadProof() [][]byte {
|
||||
branch := interfaces.LightClientExecutionBranch{}
|
||||
proof := make([][]byte, len(branch))
|
||||
for i, b := range branch {
|
||||
proof[i] = b[:]
|
||||
}
|
||||
|
||||
payload, err := block.Block().Body().Execution()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload")
|
||||
}
|
||||
|
||||
transactionsRoot, err := ComputeTransactionsRoot(payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
withdrawalsRoot, err := ComputeWithdrawalsRoot(payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
executionHeader := &v11.ExecutionPayloadHeaderCapella{
|
||||
ParentHash: payload.ParentHash(),
|
||||
FeeRecipient: payload.FeeRecipient(),
|
||||
StateRoot: payload.StateRoot(),
|
||||
ReceiptsRoot: payload.ReceiptsRoot(),
|
||||
LogsBloom: payload.LogsBloom(),
|
||||
PrevRandao: payload.PrevRandao(),
|
||||
BlockNumber: payload.BlockNumber(),
|
||||
GasLimit: payload.GasLimit(),
|
||||
GasUsed: payload.GasUsed(),
|
||||
Timestamp: payload.Timestamp(),
|
||||
ExtraData: payload.ExtraData(),
|
||||
BaseFeePerGas: payload.BaseFeePerGas(),
|
||||
BlockHash: payload.BlockHash(),
|
||||
TransactionsRoot: transactionsRoot,
|
||||
WithdrawalsRoot: withdrawalsRoot,
|
||||
}
|
||||
|
||||
executionPayloadProof, err := blocks.PayloadProof(ctx, block.Block())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload proof")
|
||||
}
|
||||
|
||||
parentRoot := block.Block().ParentRoot()
|
||||
stateRoot := block.Block().StateRoot()
|
||||
bodyRoot, err := block.Block().Body().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get body root")
|
||||
}
|
||||
|
||||
return ðpbv2.LightClientHeaderCapella{
|
||||
Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: block.Block().Slot(),
|
||||
ProposerIndex: block.Block().ProposerIndex(),
|
||||
ParentRoot: parentRoot[:],
|
||||
StateRoot: stateRoot[:],
|
||||
BodyRoot: bodyRoot[:],
|
||||
},
|
||||
Execution: executionHeader,
|
||||
ExecutionBranch: executionPayloadProof,
|
||||
}, nil
|
||||
return proof
|
||||
}
|
||||
|
||||
func blockToLightClientHeaderDeneb(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderDeneb, error) {
|
||||
if block.Version() < version.Deneb {
|
||||
return nil, fmt.Errorf("block version is %s instead of Deneb/Electra", version.String(block.Version()))
|
||||
func HasRelevantSyncCommittee(update interfaces.LightClientUpdate) (bool, error) {
|
||||
if update.Version() >= version.Electra {
|
||||
branch, err := update.NextSyncCommitteeBranchElectra()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return !reflect.DeepEqual(branch, interfaces.LightClientSyncCommitteeBranchElectra{}), nil
|
||||
}
|
||||
|
||||
payload, err := block.Block().Body().Execution()
|
||||
branch, err := update.NextSyncCommitteeBranch()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload")
|
||||
return false, err
|
||||
}
|
||||
|
||||
transactionsRoot, err := ComputeTransactionsRoot(payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
withdrawalsRoot, err := ComputeWithdrawalsRoot(payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blobGasUsed, err := payload.BlobGasUsed()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get blob gas used")
|
||||
}
|
||||
excessBlobGas, err := payload.ExcessBlobGas()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get excess blob gas")
|
||||
}
|
||||
|
||||
executionHeader := &v11.ExecutionPayloadHeaderDeneb{
|
||||
ParentHash: payload.ParentHash(),
|
||||
FeeRecipient: payload.FeeRecipient(),
|
||||
StateRoot: payload.StateRoot(),
|
||||
ReceiptsRoot: payload.ReceiptsRoot(),
|
||||
LogsBloom: payload.LogsBloom(),
|
||||
PrevRandao: payload.PrevRandao(),
|
||||
BlockNumber: payload.BlockNumber(),
|
||||
GasLimit: payload.GasLimit(),
|
||||
GasUsed: payload.GasUsed(),
|
||||
Timestamp: payload.Timestamp(),
|
||||
ExtraData: payload.ExtraData(),
|
||||
BaseFeePerGas: payload.BaseFeePerGas(),
|
||||
BlockHash: payload.BlockHash(),
|
||||
TransactionsRoot: transactionsRoot,
|
||||
WithdrawalsRoot: withdrawalsRoot,
|
||||
BlobGasUsed: blobGasUsed,
|
||||
ExcessBlobGas: excessBlobGas,
|
||||
}
|
||||
|
||||
executionPayloadProof, err := blocks.PayloadProof(ctx, block.Block())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload proof")
|
||||
}
|
||||
|
||||
parentRoot := block.Block().ParentRoot()
|
||||
stateRoot := block.Block().StateRoot()
|
||||
bodyRoot, err := block.Block().Body().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get body root")
|
||||
}
|
||||
|
||||
return ðpbv2.LightClientHeaderDeneb{
|
||||
Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: block.Block().Slot(),
|
||||
ProposerIndex: block.Block().ProposerIndex(),
|
||||
ParentRoot: parentRoot[:],
|
||||
StateRoot: stateRoot[:],
|
||||
BodyRoot: bodyRoot[:],
|
||||
},
|
||||
Execution: executionHeader,
|
||||
ExecutionBranch: executionPayloadProof,
|
||||
}, nil
|
||||
return !reflect.DeepEqual(branch, interfaces.LightClientSyncCommitteeBranch{}), nil
|
||||
}
|
||||
|
||||
func HasFinality(update interfaces.LightClientUpdate) (bool, error) {
|
||||
if update.Version() >= version.Electra {
|
||||
b, err := update.FinalityBranchElectra()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return !reflect.DeepEqual(b, interfaces.LightClientFinalityBranchElectra{}), nil
|
||||
}
|
||||
|
||||
b, err := update.FinalityBranch()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return !reflect.DeepEqual(b, interfaces.LightClientFinalityBranch{}), nil
|
||||
}
|
||||
|
||||
func IsBetterUpdate(newUpdate, oldUpdate interfaces.LightClientUpdate) (bool, error) {
|
||||
maxActiveParticipants := newUpdate.SyncAggregate().SyncCommitteeBits.Len()
|
||||
newNumActiveParticipants := newUpdate.SyncAggregate().SyncCommitteeBits.Count()
|
||||
oldNumActiveParticipants := oldUpdate.SyncAggregate().SyncCommitteeBits.Count()
|
||||
newHasSupermajority := newNumActiveParticipants*3 >= maxActiveParticipants*2
|
||||
oldHasSupermajority := oldNumActiveParticipants*3 >= maxActiveParticipants*2
|
||||
|
||||
if newHasSupermajority != oldHasSupermajority {
|
||||
return newHasSupermajority, nil
|
||||
}
|
||||
if !newHasSupermajority && newNumActiveParticipants != oldNumActiveParticipants {
|
||||
return newNumActiveParticipants > oldNumActiveParticipants, nil
|
||||
}
|
||||
|
||||
newUpdateAttestedHeaderBeacon := newUpdate.AttestedHeader().Beacon()
|
||||
oldUpdateAttestedHeaderBeacon := oldUpdate.AttestedHeader().Beacon()
|
||||
|
||||
// Compare presence of relevant sync committee
|
||||
newHasRelevantSyncCommittee, err := HasRelevantSyncCommittee(newUpdate)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
newHasRelevantSyncCommittee = newHasRelevantSyncCommittee &&
|
||||
(slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot())))
|
||||
oldHasRelevantSyncCommittee, err := HasRelevantSyncCommittee(oldUpdate)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
oldHasRelevantSyncCommittee = oldHasRelevantSyncCommittee &&
|
||||
(slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot())))
|
||||
|
||||
if newHasRelevantSyncCommittee != oldHasRelevantSyncCommittee {
|
||||
return newHasRelevantSyncCommittee, nil
|
||||
}
|
||||
|
||||
// Compare indication of any finality
|
||||
newHasFinality, err := HasFinality(newUpdate)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
oldHasFinality, err := HasFinality(oldUpdate)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if newHasFinality != oldHasFinality {
|
||||
return newHasFinality, nil
|
||||
}
|
||||
|
||||
newUpdateFinalizedHeaderBeacon := newUpdate.FinalizedHeader().Beacon()
|
||||
oldUpdateFinalizedHeaderBeacon := oldUpdate.FinalizedHeader().Beacon()
|
||||
|
||||
// Compare sync committee finality
|
||||
if newHasFinality {
|
||||
newHasSyncCommitteeFinality :=
|
||||
slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateFinalizedHeaderBeacon.Slot)) ==
|
||||
slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot))
|
||||
oldHasSyncCommitteeFinality :=
|
||||
slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateFinalizedHeaderBeacon.Slot)) ==
|
||||
slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot))
|
||||
|
||||
if newHasSyncCommitteeFinality != oldHasSyncCommitteeFinality {
|
||||
return newHasSyncCommitteeFinality, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Tiebreaker 1: Sync committee participation beyond supermajority
|
||||
if newNumActiveParticipants != oldNumActiveParticipants {
|
||||
return newNumActiveParticipants > oldNumActiveParticipants, nil
|
||||
}
|
||||
|
||||
// Tiebreaker 2: Prefer older data (fewer changes to best)
|
||||
if newUpdateAttestedHeaderBeacon.Slot != oldUpdateAttestedHeaderBeacon.Slot {
|
||||
return newUpdateAttestedHeaderBeacon.Slot < oldUpdateAttestedHeaderBeacon.Slot, nil
|
||||
}
|
||||
|
||||
return newUpdate.SignatureSlot() < oldUpdate.SignatureSlot(), nil
|
||||
}
|
||||
|
||||
func NewLightClientBootstrapFromBeaconState(
|
||||
ctx context.Context,
|
||||
currentSlot primitives.Slot,
|
||||
state state.BeaconState,
|
||||
block interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (interfaces.LightClientBootstrap, error) {
|
||||
// assert compute_epoch_at_slot(state.slot) >= ALTAIR_FORK_EPOCH
|
||||
if slots.ToEpoch(state.Slot()) < params.BeaconConfig().AltairForkEpoch {
|
||||
return nil, fmt.Errorf("light client bootstrap is not supported before Altair, invalid slot %d", state.Slot())
|
||||
}
|
||||
|
||||
// assert state.slot == state.latest_block_header.slot
|
||||
latestBlockHeader := state.LatestBlockHeader()
|
||||
if state.Slot() != latestBlockHeader.Slot {
|
||||
return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot)
|
||||
}
|
||||
|
||||
// header.state_root = hash_tree_root(state)
|
||||
stateRoot, err := state.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get state root")
|
||||
}
|
||||
latestBlockHeader.StateRoot = stateRoot[:]
|
||||
|
||||
// assert hash_tree_root(header) == hash_tree_root(block.message)
|
||||
latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get latest block header root")
|
||||
}
|
||||
beaconBlockRoot, err := block.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get block root")
|
||||
}
|
||||
if latestBlockHeaderRoot != beaconBlockRoot {
|
||||
return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot)
|
||||
}
|
||||
|
||||
bootstrap, err := createDefaultLightClientBootstrap(currentSlot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not create default light client bootstrap")
|
||||
}
|
||||
|
||||
lightClientHeader, err := BlockToLightClientHeader(ctx, currentSlot, block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not convert block to light client header")
|
||||
}
|
||||
|
||||
err = bootstrap.SetHeader(lightClientHeader)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not set header")
|
||||
}
|
||||
|
||||
currentSyncCommittee, err := state.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current sync committee")
|
||||
}
|
||||
|
||||
err = bootstrap.SetCurrentSyncCommittee(currentSyncCommittee)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not set current sync committee")
|
||||
}
|
||||
|
||||
currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current sync committee proof")
|
||||
}
|
||||
|
||||
err = bootstrap.SetCurrentSyncCommitteeBranch(currentSyncCommitteeProof)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not set current sync committee proof")
|
||||
}
|
||||
|
||||
return bootstrap, nil
|
||||
}
|
||||
|
||||
func createDefaultLightClientBootstrap(currentSlot primitives.Slot) (interfaces.LightClientBootstrap, error) {
|
||||
currentEpoch := slots.ToEpoch(currentSlot)
|
||||
syncCommitteeSize := params.BeaconConfig().SyncCommitteeSize
|
||||
pubKeys := make([][]byte, syncCommitteeSize)
|
||||
for i := uint64(0); i < syncCommitteeSize; i++ {
|
||||
pubKeys[i] = make([]byte, fieldparams.BLSPubkeyLength)
|
||||
}
|
||||
currentSyncCommittee := &pb.SyncCommittee{
|
||||
Pubkeys: pubKeys,
|
||||
AggregatePubkey: make([]byte, fieldparams.BLSPubkeyLength),
|
||||
}
|
||||
|
||||
var currentSyncCommitteeBranch [][]byte
|
||||
if currentEpoch >= params.BeaconConfig().ElectraForkEpoch {
|
||||
currentSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepthElectra)
|
||||
} else {
|
||||
currentSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepth)
|
||||
}
|
||||
for i := 0; i < len(currentSyncCommitteeBranch); i++ {
|
||||
currentSyncCommitteeBranch[i] = make([]byte, fieldparams.RootLength)
|
||||
}
|
||||
|
||||
executionBranch := make([][]byte, fieldparams.ExecutionBranchDepth)
|
||||
for i := 0; i < fieldparams.ExecutionBranchDepth; i++ {
|
||||
executionBranch[i] = make([]byte, 32)
|
||||
}
|
||||
|
||||
// TODO: can this be based on the current epoch?
|
||||
var m proto.Message
|
||||
if currentEpoch < params.BeaconConfig().CapellaForkEpoch {
|
||||
m = &pb.LightClientBootstrapAltair{
|
||||
Header: &pb.LightClientHeaderAltair{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
},
|
||||
CurrentSyncCommittee: currentSyncCommittee,
|
||||
CurrentSyncCommitteeBranch: currentSyncCommitteeBranch,
|
||||
}
|
||||
} else if currentEpoch < params.BeaconConfig().DenebForkEpoch {
|
||||
m = &pb.LightClientBootstrapCapella{
|
||||
Header: &pb.LightClientHeaderCapella{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
Execution: &enginev1.ExecutionPayloadHeaderCapella{},
|
||||
ExecutionBranch: executionBranch,
|
||||
},
|
||||
CurrentSyncCommittee: currentSyncCommittee,
|
||||
CurrentSyncCommitteeBranch: currentSyncCommitteeBranch,
|
||||
}
|
||||
} else if currentEpoch < params.BeaconConfig().ElectraForkEpoch {
|
||||
m = &pb.LightClientBootstrapDeneb{
|
||||
Header: &pb.LightClientHeaderDeneb{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
Execution: &enginev1.ExecutionPayloadHeaderDeneb{},
|
||||
ExecutionBranch: executionBranch,
|
||||
},
|
||||
CurrentSyncCommittee: currentSyncCommittee,
|
||||
CurrentSyncCommitteeBranch: currentSyncCommitteeBranch,
|
||||
}
|
||||
} else {
|
||||
m = &pb.LightClientBootstrapElectra{
|
||||
Header: &pb.LightClientHeaderDeneb{
|
||||
Beacon: &pb.BeaconBlockHeader{},
|
||||
Execution: &enginev1.ExecutionPayloadHeaderDeneb{},
|
||||
ExecutionBranch: executionBranch,
|
||||
},
|
||||
CurrentSyncCommittee: currentSyncCommittee,
|
||||
CurrentSyncCommitteeBranch: currentSyncCommitteeBranch,
|
||||
}
|
||||
}
|
||||
|
||||
return light_client.NewWrappedBootstrap(m)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@ go_library(
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//monitoring/backup:go_default_library",
|
||||
"//proto/dbval:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
],
|
||||
|
||||
@@ -7,8 +7,6 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filters"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types"
|
||||
@@ -59,8 +57,9 @@ type ReadOnlyDatabase interface {
|
||||
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]*ethpbv2.LightClientUpdateWithVersion, error)
|
||||
LightClientUpdate(ctx context.Context, period uint64) (*ethpbv2.LightClientUpdateWithVersion, error)
|
||||
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)
|
||||
@@ -98,7 +97,8 @@ type NoHeadAccessDatabase interface {
|
||||
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 *ethpbv2.LightClientUpdateWithVersion) error
|
||||
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
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ go_library(
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/light-client:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
@@ -53,7 +54,6 @@ go_library(
|
||||
"//monitoring/tracing:go_default_library",
|
||||
"//monitoring/tracing/trace:go_default_library",
|
||||
"//proto/dbval:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//time:go_default_library",
|
||||
@@ -112,18 +112,18 @@ go_test(
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/light-client:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/dbval:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/testing:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_golang_snappy//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
|
||||
@@ -108,6 +108,7 @@ var Buckets = [][]byte{
|
||||
stateSummaryBucket,
|
||||
stateValidatorsBucket,
|
||||
lightClientUpdatesBucket,
|
||||
lightClientBootstrapBucket,
|
||||
// Indices buckets.
|
||||
blockSlotIndicesBucket,
|
||||
stateSlotIndicesBucket,
|
||||
|
||||
@@ -5,35 +5,126 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/snappy"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func (s *Store) SaveLightClientUpdate(ctx context.Context, period uint64, update *ethpbv2.LightClientUpdateWithVersion) error {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.saveLightClientUpdate")
|
||||
func (s *Store) SaveLightClientUpdate(ctx context.Context, period uint64, update interfaces.LightClientUpdate) error {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.SaveLightClientUpdate")
|
||||
defer span.End()
|
||||
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(lightClientUpdatesBucket)
|
||||
updateMarshalled, err := encode(ctx, update)
|
||||
enc, err := encodeLightClientUpdate(update)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return bkt.Put(bytesutil.Uint64ToBytesBigEndian(period), updateMarshalled)
|
||||
return bkt.Put(bytesutil.Uint64ToBytesBigEndian(period), enc)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]*ethpbv2.LightClientUpdateWithVersion, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdates")
|
||||
func (s *Store) SaveLightClientBootstrap(ctx context.Context, blockRoot []byte, bootstrap interfaces.LightClientBootstrap) error {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.SaveLightClientBootstrap")
|
||||
defer span.End()
|
||||
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(lightClientBootstrapBucket)
|
||||
enc, err := encodeLightClientBootstrap(bootstrap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return bkt.Put(blockRoot, enc)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) LightClientBootstrap(ctx context.Context, blockRoot []byte) (interfaces.LightClientBootstrap, error) {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.LightClientBootstrap")
|
||||
defer span.End()
|
||||
|
||||
var bootstrap interfaces.LightClientBootstrap
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(lightClientBootstrapBucket)
|
||||
enc := bkt.Get(blockRoot)
|
||||
if enc == nil {
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
bootstrap, err = decodeLightClientBootstrap(enc)
|
||||
return err
|
||||
})
|
||||
return bootstrap, err
|
||||
}
|
||||
|
||||
func encodeLightClientBootstrap(bootstrap interfaces.LightClientBootstrap) ([]byte, error) {
|
||||
key, err := keyForLightClientUpdate(bootstrap.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
enc, err := bootstrap.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not marshal light client bootstrap")
|
||||
}
|
||||
fullEnc := make([]byte, len(key)+len(enc))
|
||||
copy(fullEnc, key)
|
||||
copy(fullEnc[len(key):], enc)
|
||||
return snappy.Encode(nil, fullEnc), nil
|
||||
}
|
||||
|
||||
func decodeLightClientBootstrap(enc []byte) (interfaces.LightClientBootstrap, error) {
|
||||
var err error
|
||||
enc, err = snappy.Decode(nil, enc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not snappy decode light client bootstrap")
|
||||
}
|
||||
var m proto.Message
|
||||
switch {
|
||||
case hasAltairKey(enc):
|
||||
bootstrap := ðpb.LightClientBootstrapAltair{}
|
||||
if err := bootstrap.UnmarshalSSZ(enc[len(altairKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal Altair light client bootstrap")
|
||||
}
|
||||
m = bootstrap
|
||||
case hasCapellaKey(enc):
|
||||
bootstrap := ðpb.LightClientBootstrapCapella{}
|
||||
if err := bootstrap.UnmarshalSSZ(enc[len(capellaKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal Capella light client bootstrap")
|
||||
}
|
||||
m = bootstrap
|
||||
case hasDenebKey(enc):
|
||||
bootstrap := ðpb.LightClientBootstrapDeneb{}
|
||||
if err := bootstrap.UnmarshalSSZ(enc[len(denebKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal Deneb light client bootstrap")
|
||||
}
|
||||
m = bootstrap
|
||||
case hasElectraKey(enc):
|
||||
bootstrap := ðpb.LightClientBootstrapElectra{}
|
||||
if err := bootstrap.UnmarshalSSZ(enc[len(electraKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal Electra light client bootstrap")
|
||||
}
|
||||
m = bootstrap
|
||||
default:
|
||||
return nil, errors.New("decoding of saved light client bootstrap is unsupported")
|
||||
}
|
||||
return light_client.NewWrappedBootstrap(m)
|
||||
}
|
||||
|
||||
func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]interfaces.LightClientUpdate, error) {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdates")
|
||||
defer span.End()
|
||||
|
||||
if startPeriod > endPeriod {
|
||||
return nil, fmt.Errorf("start period %d is greater than end period %d", startPeriod, endPeriod)
|
||||
}
|
||||
|
||||
updates := make(map[uint64]*ethpbv2.LightClientUpdateWithVersion)
|
||||
updates := make(map[uint64]interfaces.LightClientUpdate)
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(lightClientUpdatesBucket)
|
||||
c := bkt.Cursor()
|
||||
@@ -46,11 +137,11 @@ func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod u
|
||||
for k, v := c.Seek(bytesutil.Uint64ToBytesBigEndian(startPeriod)); k != nil && binary.BigEndian.Uint64(k) <= endPeriod; k, v = c.Next() {
|
||||
currentPeriod := binary.BigEndian.Uint64(k)
|
||||
|
||||
var update ethpbv2.LightClientUpdateWithVersion
|
||||
if err := decode(ctx, v, &update); err != nil {
|
||||
update, err := decodeLightClientUpdate(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updates[currentPeriod] = &update
|
||||
updates[currentPeriod] = update
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -62,18 +153,88 @@ func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod u
|
||||
return updates, err
|
||||
}
|
||||
|
||||
func (s *Store) LightClientUpdate(ctx context.Context, period uint64) (*ethpbv2.LightClientUpdateWithVersion, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdate")
|
||||
func (s *Store) LightClientUpdate(ctx context.Context, period uint64) (interfaces.LightClientUpdate, error) {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdate")
|
||||
defer span.End()
|
||||
|
||||
var update ethpbv2.LightClientUpdateWithVersion
|
||||
var update interfaces.LightClientUpdate
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(lightClientUpdatesBucket)
|
||||
updateBytes := bkt.Get(bytesutil.Uint64ToBytesBigEndian(period))
|
||||
if updateBytes == nil {
|
||||
return nil
|
||||
}
|
||||
return decode(ctx, updateBytes, &update)
|
||||
var err error
|
||||
update, err = decodeLightClientUpdate(updateBytes)
|
||||
return err
|
||||
})
|
||||
return &update, err
|
||||
return update, err
|
||||
}
|
||||
|
||||
func encodeLightClientUpdate(update interfaces.LightClientUpdate) ([]byte, error) {
|
||||
key, err := keyForLightClientUpdate(update.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
enc, err := update.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not marshal light client update")
|
||||
}
|
||||
fullEnc := make([]byte, len(key)+len(enc))
|
||||
copy(fullEnc, key)
|
||||
copy(fullEnc[len(key):], enc)
|
||||
return snappy.Encode(nil, fullEnc), nil
|
||||
}
|
||||
|
||||
func decodeLightClientUpdate(enc []byte) (interfaces.LightClientUpdate, error) {
|
||||
var err error
|
||||
enc, err = snappy.Decode(nil, enc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not snappy decode light client update")
|
||||
}
|
||||
var m proto.Message
|
||||
switch {
|
||||
case hasAltairKey(enc):
|
||||
update := ðpb.LightClientUpdateAltair{}
|
||||
if err := update.UnmarshalSSZ(enc[len(altairKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal Altair light client update")
|
||||
}
|
||||
m = update
|
||||
case hasCapellaKey(enc):
|
||||
update := ðpb.LightClientUpdateCapella{}
|
||||
if err := update.UnmarshalSSZ(enc[len(capellaKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal Capella light client update")
|
||||
}
|
||||
m = update
|
||||
case hasDenebKey(enc):
|
||||
update := ðpb.LightClientUpdateDeneb{}
|
||||
if err := update.UnmarshalSSZ(enc[len(denebKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal Deneb light client update")
|
||||
}
|
||||
m = update
|
||||
case hasElectraKey(enc):
|
||||
update := ðpb.LightClientUpdateElectra{}
|
||||
if err := update.UnmarshalSSZ(enc[len(electraKey):]); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal Electra light client update")
|
||||
}
|
||||
m = update
|
||||
default:
|
||||
return nil, errors.New("decoding of saved light client update is unsupported")
|
||||
}
|
||||
return light_client.NewWrappedUpdate(m)
|
||||
}
|
||||
|
||||
func keyForLightClientUpdate(v int) ([]byte, error) {
|
||||
switch v {
|
||||
case version.Electra:
|
||||
return electraKey, nil
|
||||
case version.Deneb:
|
||||
return denebKey, nil
|
||||
case version.Capella:
|
||||
return capellaKey, nil
|
||||
case version.Altair:
|
||||
return altairKey, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported light client update version %s", version.String(v))
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,8 @@ var (
|
||||
registrationBucket = []byte("registration")
|
||||
|
||||
// Light Client Updates Bucket
|
||||
lightClientUpdatesBucket = []byte("light-client-updates")
|
||||
lightClientUpdatesBucket = []byte("light-client-updates")
|
||||
lightClientBootstrapBucket = []byte("light-client-bootstrap")
|
||||
|
||||
// Deprecated: This bucket was migrated in PR 6461. Do not use, except for migrations.
|
||||
slotsHasObjectBucket = []byte("slots-has-objects")
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"log.go",
|
||||
"service.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/deterministic-genesis",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/execution:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime:go_default_library",
|
||||
"//runtime/interop:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -1,7 +0,0 @@
|
||||
package interopcoldstart
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var log = logrus.WithField("prefix", "deterministic-genesis")
|
||||
@@ -1,206 +0,0 @@
|
||||
// Package interopcoldstart allows for spinning up a deterministic-genesis
|
||||
// local chain without the need for eth1 deposits useful for
|
||||
// local client development and interoperability testing.
|
||||
package interopcoldstart
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/execution"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/interop"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
)
|
||||
|
||||
var _ runtime.Service = (*Service)(nil)
|
||||
var _ cache.FinalizedFetcher = (*Service)(nil)
|
||||
var _ execution.ChainStartFetcher = (*Service)(nil)
|
||||
|
||||
// Service spins up an client interoperability service that handles responsibilities such
|
||||
// as kickstarting a genesis state for the beacon node from cli flags or a genesis.ssz file.
|
||||
type Service struct {
|
||||
cfg *Config
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
chainStartDeposits []*ethpb.Deposit
|
||||
}
|
||||
|
||||
// All of these methods are stubs as they are not used by a node running with deterministic-genesis.
|
||||
|
||||
func (s *Service) AllDepositContainers(ctx context.Context) []*ethpb.DepositContainer {
|
||||
log.Errorf("AllDepositContainers should not be called")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) InsertPendingDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) {
|
||||
log.Errorf("InsertPendingDeposit should not be called")
|
||||
}
|
||||
|
||||
func (s *Service) PendingDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
|
||||
log.Errorf("PendingDeposits should not be called")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) PendingContainers(ctx context.Context, untilBlk *big.Int) []*ethpb.DepositContainer {
|
||||
log.Errorf("PendingContainers should not be called")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) PrunePendingDeposits(ctx context.Context, merkleTreeIndex int64) {
|
||||
log.Errorf("PrunePendingDeposits should not be called")
|
||||
}
|
||||
|
||||
func (s *Service) PruneProofs(ctx context.Context, untilDepositIndex int64) error {
|
||||
log.Errorf("PruneProofs should not be called")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Config options for the interop service.
|
||||
type Config struct {
|
||||
GenesisTime uint64
|
||||
NumValidators uint64
|
||||
BeaconDB db.HeadAccessDatabase
|
||||
DepositCache cache.DepositCache
|
||||
GenesisPath string
|
||||
}
|
||||
|
||||
// NewService is an interoperability testing service to inject a deterministically generated genesis state
|
||||
// into the beacon chain database and running services at start up. This service should not be used in production
|
||||
// as it does not have any value other than ease of use for testing purposes.
|
||||
func NewService(ctx context.Context, cfg *Config) *Service {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
return &Service{
|
||||
cfg: cfg,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
}
|
||||
}
|
||||
|
||||
// Start initializes the genesis state from configured flags.
|
||||
func (s *Service) Start() {
|
||||
log.Warn("Saving generated genesis state in database for interop testing")
|
||||
|
||||
if s.cfg.GenesisPath != "" {
|
||||
data, err := os.ReadFile(s.cfg.GenesisPath)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Could not read pre-loaded state")
|
||||
}
|
||||
genesisState := ðpb.BeaconState{}
|
||||
if err := genesisState.UnmarshalSSZ(data); err != nil {
|
||||
log.WithError(err).Fatal("Could not unmarshal pre-loaded state")
|
||||
}
|
||||
genesisTrie, err := state_native.InitializeFromProtoPhase0(genesisState)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Could not get state trie")
|
||||
}
|
||||
if err := s.saveGenesisState(s.ctx, genesisTrie); err != nil {
|
||||
log.WithError(err).Fatal("Could not save interop genesis state")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Save genesis state in db
|
||||
genesisState, _, err := interop.GenerateGenesisState(s.ctx, s.cfg.GenesisTime, s.cfg.NumValidators)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Could not generate interop genesis state")
|
||||
}
|
||||
genesisTrie, err := state_native.InitializeFromProtoPhase0(genesisState)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Could not get state trie")
|
||||
}
|
||||
if s.cfg.GenesisTime == 0 {
|
||||
// Generated genesis time; fetch it
|
||||
s.cfg.GenesisTime = genesisTrie.GenesisTime()
|
||||
}
|
||||
gRoot, err := genesisTrie.HashTreeRoot(s.ctx)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Could not hash tree root genesis state")
|
||||
}
|
||||
go slots.CountdownToGenesis(s.ctx, time.Unix(int64(s.cfg.GenesisTime), 0), s.cfg.NumValidators, gRoot)
|
||||
|
||||
if err := s.saveGenesisState(s.ctx, genesisTrie); err != nil {
|
||||
log.WithError(err).Fatal("Could not save interop genesis state")
|
||||
}
|
||||
}
|
||||
|
||||
// Stop does nothing.
|
||||
func (_ *Service) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status always returns nil.
|
||||
func (_ *Service) Status() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllDeposits mocks out the deposit cache functionality for interop.
|
||||
func (_ *Service) AllDeposits(_ context.Context, _ *big.Int) []*ethpb.Deposit {
|
||||
return []*ethpb.Deposit{}
|
||||
}
|
||||
|
||||
// ChainStartEth1Data mocks out the powchain functionality for interop.
|
||||
func (_ *Service) ChainStartEth1Data() *ethpb.Eth1Data {
|
||||
return ðpb.Eth1Data{}
|
||||
}
|
||||
|
||||
// PreGenesisState returns an empty beacon state.
|
||||
func (_ *Service) PreGenesisState() state.BeaconState {
|
||||
s, err := state_native.InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||
if err != nil {
|
||||
panic("could not initialize state")
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// ClearPreGenesisData --
|
||||
func (_ *Service) ClearPreGenesisData() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
// DepositByPubkey mocks out the deposit cache functionality for interop.
|
||||
func (_ *Service) DepositByPubkey(_ context.Context, _ []byte) (*ethpb.Deposit, *big.Int) {
|
||||
return ðpb.Deposit{}, nil
|
||||
}
|
||||
|
||||
// DepositsNumberAndRootAtHeight mocks out the deposit cache functionality for interop.
|
||||
func (_ *Service) DepositsNumberAndRootAtHeight(_ context.Context, _ *big.Int) (uint64, [32]byte) {
|
||||
return 0, [32]byte{}
|
||||
}
|
||||
|
||||
// FinalizedDeposits mocks out the deposit cache functionality for interop.
|
||||
func (_ *Service) FinalizedDeposits(ctx context.Context) (cache.FinalizedDeposits, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NonFinalizedDeposits mocks out the deposit cache functionality for interop.
|
||||
func (_ *Service) NonFinalizedDeposits(_ context.Context, _ int64, _ *big.Int) []*ethpb.Deposit {
|
||||
return []*ethpb.Deposit{}
|
||||
}
|
||||
|
||||
func (s *Service) saveGenesisState(ctx context.Context, genesisState state.BeaconState) error {
|
||||
if err := s.cfg.BeaconDB.SaveGenesisData(ctx, genesisState); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.chainStartDeposits = make([]*ethpb.Deposit, genesisState.NumValidators())
|
||||
|
||||
for i := primitives.ValidatorIndex(0); uint64(i) < uint64(genesisState.NumValidators()); i++ {
|
||||
pk := genesisState.PubkeyAtIndex(i)
|
||||
s.chainStartDeposits[i] = ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: pk[:],
|
||||
},
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -801,7 +801,7 @@ func tDStringToUint256(td string) (*uint256.Int, error) {
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func buildEmptyExecutionPayload(v int) (proto.Message, error) {
|
||||
func EmptyExecutionPayload(v int) (proto.Message, error) {
|
||||
switch v {
|
||||
case version.Bellatrix:
|
||||
return &pb.ExecutionPayload{
|
||||
|
||||
@@ -205,7 +205,7 @@ func (r *blindedBlockReconstructor) requestBodiesByHash(ctx context.Context, cli
|
||||
func (r *blindedBlockReconstructor) payloadForHeader(header interfaces.ExecutionData, v int) (proto.Message, error) {
|
||||
bodyKey := bytesutil.ToBytes32(header.BlockHash())
|
||||
if bodyKey == params.BeaconConfig().ZeroHash {
|
||||
payload, err := buildEmptyExecutionPayload(v)
|
||||
payload, err := EmptyExecutionPayload(v)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to reconstruct payload for body hash %#x", bodyKey)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ go_library(
|
||||
"//beacon-chain/db/filesystem:go_default_library",
|
||||
"//beacon-chain/db/kv:go_default_library",
|
||||
"//beacon-chain/db/slasherkv:go_default_library",
|
||||
"//beacon-chain/deterministic-genesis:go_default_library",
|
||||
"//beacon-chain/execution:go_default_library",
|
||||
"//beacon-chain/forkchoice:go_default_library",
|
||||
"//beacon-chain/forkchoice/doubly-linked-tree:go_default_library",
|
||||
@@ -92,12 +91,9 @@ go_test(
|
||||
"//cmd:go_default_library",
|
||||
"//cmd/beacon-chain/flags:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime:go_default_library",
|
||||
"//runtime/interop:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
|
||||
@@ -144,23 +144,6 @@ func configureNetwork(cliCtx *cli.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func configureInteropConfig(cliCtx *cli.Context) error {
|
||||
// an explicit chain config was specified, don't mess with it
|
||||
if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) {
|
||||
return nil
|
||||
}
|
||||
genTimeIsSet := cliCtx.IsSet(flags.InteropGenesisTimeFlag.Name)
|
||||
numValsIsSet := cliCtx.IsSet(flags.InteropNumValidatorsFlag.Name)
|
||||
votesIsSet := cliCtx.IsSet(flags.InteropMockEth1DataVotesFlag.Name)
|
||||
|
||||
if genTimeIsSet || numValsIsSet || votesIsSet {
|
||||
if err := params.SetActive(params.InteropConfig().Copy()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func configureExecutionSetting(cliCtx *cli.Context) error {
|
||||
if cliCtx.IsSet(flags.TerminalTotalDifficultyOverride.Name) {
|
||||
c := params.BeaconConfig()
|
||||
|
||||
@@ -169,66 +169,6 @@ func TestConfigureNetwork_ConfigFile(t *testing.T) {
|
||||
require.NoError(t, os.Remove("flags_test.yaml"))
|
||||
}
|
||||
|
||||
func TestConfigureInterop(t *testing.T) {
|
||||
params.SetupTestConfigCleanup(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
flagSetter func() *cli.Context
|
||||
configName string
|
||||
}{
|
||||
{
|
||||
"nothing set",
|
||||
func() *cli.Context {
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
return cli.NewContext(&app, set, nil)
|
||||
},
|
||||
"mainnet",
|
||||
},
|
||||
{
|
||||
"mock votes set",
|
||||
func() *cli.Context {
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool(flags.InteropMockEth1DataVotesFlag.Name, false, "")
|
||||
assert.NoError(t, set.Set(flags.InteropMockEth1DataVotesFlag.Name, "true"))
|
||||
return cli.NewContext(&app, set, nil)
|
||||
},
|
||||
"interop",
|
||||
},
|
||||
{
|
||||
"validators set",
|
||||
func() *cli.Context {
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Uint64(flags.InteropNumValidatorsFlag.Name, 0, "")
|
||||
assert.NoError(t, set.Set(flags.InteropNumValidatorsFlag.Name, "20"))
|
||||
return cli.NewContext(&app, set, nil)
|
||||
},
|
||||
"interop",
|
||||
},
|
||||
{
|
||||
"genesis time set",
|
||||
func() *cli.Context {
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Uint64(flags.InteropGenesisTimeFlag.Name, 0, "")
|
||||
assert.NoError(t, set.Set(flags.InteropGenesisTimeFlag.Name, "200"))
|
||||
return cli.NewContext(&app, set, nil)
|
||||
},
|
||||
"interop",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
require.NoError(t, configureInteropConfig(tt.flagSetter()))
|
||||
assert.DeepEqual(t, tt.configName, params.BeaconConfig().ConfigName)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliasFlag(t *testing.T) {
|
||||
// Create a new app with the flag
|
||||
app := &cli.App{
|
||||
|
||||
@@ -30,7 +30,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filesystem"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/slasherkv"
|
||||
interopcoldstart "github.com/prysmaticlabs/prysm/v5/beacon-chain/deterministic-genesis"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/execution"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice"
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
@@ -261,10 +260,6 @@ func configureBeacon(cliCtx *cli.Context) error {
|
||||
|
||||
configureNetwork(cliCtx)
|
||||
|
||||
if err := configureInteropConfig(cliCtx); err != nil {
|
||||
return errors.Wrap(err, "could not configure interop config")
|
||||
}
|
||||
|
||||
if err := configureExecutionSetting(cliCtx); err != nil {
|
||||
return errors.Wrap(err, "could not configure execution setting")
|
||||
}
|
||||
@@ -324,11 +319,6 @@ func registerServices(cliCtx *cli.Context, beacon *BeaconNode, synchronizer *sta
|
||||
return errors.Wrap(err, "could not register attestation pool service")
|
||||
}
|
||||
|
||||
log.Debugln("Registering Deterministic Genesis Service")
|
||||
if err := beacon.registerDeterministicGenesisService(); err != nil {
|
||||
return errors.Wrap(err, "could not register deterministic genesis service")
|
||||
}
|
||||
|
||||
log.Debugln("Registering Blockchain Service")
|
||||
if err := beacon.registerBlockchainService(beacon.forkChoicer, synchronizer, beacon.initialSyncComplete); err != nil {
|
||||
return errors.Wrap(err, "could not register blockchain service")
|
||||
@@ -567,6 +557,7 @@ func (b *BeaconNode) startDB(cliCtx *cli.Context, depositAddress string) error {
|
||||
}
|
||||
|
||||
if b.CheckpointInitializer != nil {
|
||||
log.Info("Checkpoint sync - Downloading origin state and block")
|
||||
if err := b.CheckpointInitializer.Initialize(b.ctx, d); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -921,20 +912,8 @@ func (b *BeaconNode) registerRPCService(router *http.ServeMux) error {
|
||||
}
|
||||
}
|
||||
|
||||
genesisValidators := b.cliCtx.Uint64(flags.InteropNumValidatorsFlag.Name)
|
||||
var depositFetcher cache.DepositFetcher
|
||||
var chainStartFetcher execution.ChainStartFetcher
|
||||
if genesisValidators > 0 {
|
||||
var interopService *interopcoldstart.Service
|
||||
if err := b.services.FetchService(&interopService); err != nil {
|
||||
return err
|
||||
}
|
||||
depositFetcher = interopService
|
||||
chainStartFetcher = interopService
|
||||
} else {
|
||||
depositFetcher = b.depositCache
|
||||
chainStartFetcher = web3Service
|
||||
}
|
||||
depositFetcher := b.depositCache
|
||||
chainStartFetcher := web3Service
|
||||
|
||||
host := b.cliCtx.String(flags.RPCHost.Name)
|
||||
port := b.cliCtx.String(flags.RPCPort.Name)
|
||||
@@ -1056,32 +1035,6 @@ func (b *BeaconNode) registerHTTPService(router *http.ServeMux) error {
|
||||
return b.services.RegisterService(g)
|
||||
}
|
||||
|
||||
func (b *BeaconNode) registerDeterministicGenesisService() error {
|
||||
genesisTime := b.cliCtx.Uint64(flags.InteropGenesisTimeFlag.Name)
|
||||
genesisValidators := b.cliCtx.Uint64(flags.InteropNumValidatorsFlag.Name)
|
||||
|
||||
if genesisValidators > 0 {
|
||||
svc := interopcoldstart.NewService(b.ctx, &interopcoldstart.Config{
|
||||
GenesisTime: genesisTime,
|
||||
NumValidators: genesisValidators,
|
||||
BeaconDB: b.db,
|
||||
DepositCache: b.depositCache,
|
||||
})
|
||||
svc.Start()
|
||||
|
||||
// Register genesis state as start-up state when interop mode.
|
||||
// The start-up state gets reused across services.
|
||||
st, err := b.db.GenesisState(b.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.finalizedStateAtStartUp = st
|
||||
|
||||
return b.services.RegisterService(svc)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BeaconNode) registerValidatorMonitorService(initialSyncComplete chan struct{}) error {
|
||||
cliSlice := b.cliCtx.IntSlice(cmd.ValidatorMonitorIndicesFlag.Name)
|
||||
if cliSlice == nil {
|
||||
|
||||
@@ -6,9 +6,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -21,13 +19,8 @@ import (
|
||||
mockExecution "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/testing"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/monitor"
|
||||
"github.com/prysmaticlabs/prysm/v5/cmd"
|
||||
"github.com/prysmaticlabs/prysm/v5/cmd/beacon-chain/flags"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/interop"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
@@ -117,55 +110,6 @@ func TestNodeStart_SyncChecker(t *testing.T) {
|
||||
require.LogsContain(t, hook, "Starting beacon node")
|
||||
}
|
||||
|
||||
func TestNodeStart_Ok_registerDeterministicGenesisService(t *testing.T) {
|
||||
numValidators := uint64(1)
|
||||
hook := logTest.NewGlobal()
|
||||
app := cli.App{}
|
||||
tmp := fmt.Sprintf("%s/datadirtest2", t.TempDir())
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String("datadir", tmp, "node data directory")
|
||||
set.Uint64(flags.InteropNumValidatorsFlag.Name, numValidators, "")
|
||||
set.String("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", "fee recipient")
|
||||
require.NoError(t, set.Set("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A"))
|
||||
genesisState, _, err := interop.GenerateGenesisState(context.Background(), 0, numValidators)
|
||||
require.NoError(t, err, "Could not generate genesis beacon state")
|
||||
for i := uint64(1); i < 2; i++ {
|
||||
var someRoot [32]byte
|
||||
var someKey [fieldparams.BLSPubkeyLength]byte
|
||||
copy(someRoot[:], strconv.Itoa(int(i)))
|
||||
copy(someKey[:], strconv.Itoa(int(i)))
|
||||
genesisState.Validators = append(genesisState.Validators, ðpb.Validator{
|
||||
PublicKey: someKey[:],
|
||||
WithdrawalCredentials: someRoot[:],
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
Slashed: false,
|
||||
ActivationEligibilityEpoch: 1,
|
||||
ActivationEpoch: 1,
|
||||
ExitEpoch: 1,
|
||||
WithdrawableEpoch: 1,
|
||||
})
|
||||
genesisState.Balances = append(genesisState.Balances, params.BeaconConfig().MaxEffectiveBalance)
|
||||
}
|
||||
genesisBytes, err := genesisState.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, os.WriteFile("genesis_ssz.json", genesisBytes, 0666))
|
||||
set.String("genesis-state", "genesis_ssz.json", "")
|
||||
ctx, cancel := newCliContextWithCancel(&app, set)
|
||||
node, err := New(ctx, cancel, WithBlockchainFlagOptions([]blockchain.Option{}),
|
||||
WithBuilderFlagOptions([]builder.Option{}),
|
||||
WithExecutionChainOptions([]execution.Option{}),
|
||||
WithBlobStorage(filesystem.NewEphemeralBlobStorage(t)))
|
||||
require.NoError(t, err)
|
||||
node.services = &runtime.ServiceRegistry{}
|
||||
go func() {
|
||||
node.Start()
|
||||
}()
|
||||
time.Sleep(3 * time.Second)
|
||||
node.Close()
|
||||
require.LogsContain(t, hook, "Starting beacon node")
|
||||
require.NoError(t, os.Remove("genesis_ssz.json"))
|
||||
}
|
||||
|
||||
// TestClearDB tests clearing the database
|
||||
func TestClearDB(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
@@ -225,13 +225,6 @@ func TestService_BroadcastAttestationWithDiscoveryAttempts(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer bootListener.Close()
|
||||
|
||||
// Use smaller batch size for testing.
|
||||
currentBatchSize := batchSize
|
||||
batchSize = 2
|
||||
defer func() {
|
||||
batchSize = currentBatchSize
|
||||
}()
|
||||
|
||||
bootNode := bootListener.Self()
|
||||
subnet := uint64(5)
|
||||
|
||||
@@ -240,7 +233,7 @@ func TestService_BroadcastAttestationWithDiscoveryAttempts(t *testing.T) {
|
||||
// setup other nodes.
|
||||
cfg = &Config{
|
||||
Discv5BootStrapAddrs: []string{bootNode.String()},
|
||||
MaxPeers: 30,
|
||||
MaxPeers: 2,
|
||||
}
|
||||
// Setup 2 different hosts
|
||||
for i := 1; i <= 2; i++ {
|
||||
|
||||
@@ -329,7 +329,7 @@ func (s *Service) listenForNewNodes() {
|
||||
}
|
||||
|
||||
// Search for new peers.
|
||||
wantedNodes := searchForPeers(iterator, batchSize, missingPeerCount, s.filterPeer)
|
||||
wantedNodes := searchForPeers(iterator, batchPeriod, missingPeerCount, s.filterPeer)
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
for i := 0; i < len(wantedNodes); i++ {
|
||||
|
||||
@@ -18,6 +18,7 @@ var _ NetworkEncoding = (*SszNetworkEncoder)(nil)
|
||||
// MaxGossipSize allowed for gossip messages.
|
||||
var MaxGossipSize = params.BeaconConfig().GossipMaxSize // 10 Mib.
|
||||
var MaxChunkSize = params.BeaconConfig().MaxChunkSize // 10 Mib.
|
||||
var MaxUncompressedPayloadSize = 2 * MaxGossipSize // 20 Mib.
|
||||
|
||||
// This pool defines the sync pool for our buffered snappy writers, so that they
|
||||
// can be constantly reused.
|
||||
@@ -43,8 +44,8 @@ func (_ SszNetworkEncoder) EncodeGossip(w io.Writer, msg fastssz.Marshaler) (int
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if uint64(len(b)) > MaxGossipSize {
|
||||
return 0, errors.Errorf("gossip message exceeds max gossip size: %d bytes > %d bytes", len(b), MaxGossipSize)
|
||||
if uint64(len(b)) > MaxUncompressedPayloadSize {
|
||||
return 0, errors.Errorf("gossip message exceeds max gossip size: %d bytes > %d bytes", len(b), MaxUncompressedPayloadSize)
|
||||
}
|
||||
b = snappy.Encode(nil /*dst*/, b)
|
||||
return w.Write(b)
|
||||
@@ -81,7 +82,7 @@ func doDecode(b []byte, to fastssz.Unmarshaler) error {
|
||||
|
||||
// DecodeGossip decodes the bytes to the protobuf gossip message provided.
|
||||
func (_ SszNetworkEncoder) DecodeGossip(b []byte, to fastssz.Unmarshaler) error {
|
||||
b, err := DecodeSnappy(b, MaxGossipSize)
|
||||
b, err := DecodeSnappy(b, MaxUncompressedPayloadSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -555,7 +555,7 @@ func TestSszNetworkEncoder_FailsSnappyLength(t *testing.T) {
|
||||
e := &encoder.SszNetworkEncoder{}
|
||||
att := ðpb.Fork{}
|
||||
data := make([]byte, 32)
|
||||
binary.PutUvarint(data, encoder.MaxGossipSize+32)
|
||||
binary.PutUvarint(data, encoder.MaxUncompressedPayloadSize+32)
|
||||
err := e.DecodeGossip(data, att)
|
||||
require.ErrorContains(t, "snappy message exceeds max size", err)
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ var _ runtime.Service = (*Service)(nil)
|
||||
var pollingPeriod = 6 * time.Second
|
||||
|
||||
// When looking for new nodes, if not enough nodes are found,
|
||||
// we stop after this amount of iterations.
|
||||
var batchSize = 2_000
|
||||
// we stop after this spent time.
|
||||
var batchPeriod = 2 * time.Second
|
||||
|
||||
// Refresh rate of ENR set at twice per slot.
|
||||
var refreshRate = slots.DivideSlotBy(2)
|
||||
|
||||
@@ -66,12 +66,14 @@ func (s *Service) nodeFilter(topic string, index uint64) (func(node *enode.Node)
|
||||
// - Iterator is exhausted.
|
||||
func searchForPeers(
|
||||
iterator enode.Iterator,
|
||||
batchSize int,
|
||||
batchPeriod time.Duration,
|
||||
peersToFindCount uint,
|
||||
filter func(node *enode.Node) bool,
|
||||
) []*enode.Node {
|
||||
nodeFromNodeID := make(map[enode.ID]*enode.Node, batchSize)
|
||||
for i := 0; i < batchSize && uint(len(nodeFromNodeID)) <= peersToFindCount && iterator.Next(); i++ {
|
||||
nodeFromNodeID := make(map[enode.ID]*enode.Node)
|
||||
start := time.Now()
|
||||
|
||||
for time.Since(start) < batchPeriod && uint(len(nodeFromNodeID)) < peersToFindCount && iterator.Next() {
|
||||
node := iterator.Node()
|
||||
|
||||
// Filter out nodes that do not meet the criteria.
|
||||
@@ -191,7 +193,7 @@ func (s *Service) FindPeersWithSubnet(
|
||||
}
|
||||
|
||||
// Search for new peers in the network.
|
||||
nodes := searchForPeers(iterator, batchSize, uint(missingPeerCountForTopic), filter)
|
||||
nodes := searchForPeers(iterator, batchPeriod, uint(missingPeerCountForTopic), filter)
|
||||
|
||||
// Restrict dials if limit is applied.
|
||||
maxConcurrentDials := math.MaxInt
|
||||
|
||||
@@ -62,6 +62,13 @@ func (e *endpoint) handlerWithMiddleware() http.HandlerFunc {
|
||||
)
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// SSE errors are handled separately to avoid interference with the streaming
|
||||
// mechanism and ensure accurate error tracking.
|
||||
if e.template == "/eth/v1/events" {
|
||||
handler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
|
||||
handler.ServeHTTP(rw, r)
|
||||
|
||||
@@ -165,9 +172,11 @@ func (s *Service) builderEndpoints(stater lookup.Stater) []endpoint {
|
||||
}
|
||||
}
|
||||
|
||||
func (*Service) blobEndpoints(blocker lookup.Blocker) []endpoint {
|
||||
func (s *Service) blobEndpoints(blocker lookup.Blocker) []endpoint {
|
||||
server := &blob.Server{
|
||||
Blocker: blocker,
|
||||
Blocker: blocker,
|
||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||
FinalizationFetcher: s.cfg.FinalizationFetcher,
|
||||
}
|
||||
|
||||
const namespace = "blob"
|
||||
@@ -909,10 +918,11 @@ func (*Service) configEndpoints() []endpoint {
|
||||
|
||||
func (s *Service) lightClientEndpoints(blocker lookup.Blocker, stater lookup.Stater) []endpoint {
|
||||
server := &lightclient.Server{
|
||||
Blocker: blocker,
|
||||
Stater: stater,
|
||||
HeadFetcher: s.cfg.HeadFetcher,
|
||||
BeaconDB: s.cfg.BeaconDB,
|
||||
Blocker: blocker,
|
||||
Stater: stater,
|
||||
HeadFetcher: s.cfg.HeadFetcher,
|
||||
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
|
||||
BeaconDB: s.cfg.BeaconDB,
|
||||
}
|
||||
|
||||
const namespace = "lightclient"
|
||||
|
||||
@@ -58,6 +58,7 @@ go_library(
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//crypto/kzg4844:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
@@ -118,6 +119,7 @@ go_test(
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_crate_crypto_go_kzg_4844//:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||
"github.com/pkg/errors"
|
||||
ssz "github.com/prysmaticlabs/fastssz"
|
||||
"github.com/prysmaticlabs/prysm/v5/api"
|
||||
@@ -1032,21 +1033,17 @@ func unmarshalStrict(data []byte, v interface{}) error {
|
||||
func (s *Server) validateBroadcast(ctx context.Context, r *http.Request, blk *eth.GenericSignedBeaconBlock) error {
|
||||
switch r.URL.Query().Get(broadcastValidationQueryParam) {
|
||||
case broadcastValidationConsensus:
|
||||
b, err := blocks.NewSignedBeaconBlock(blk.Block)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not create signed beacon block")
|
||||
}
|
||||
if err = s.validateConsensus(ctx, b); err != nil {
|
||||
if err := s.validateConsensus(ctx, blk); err != nil {
|
||||
return errors.Wrap(err, "consensus validation failed")
|
||||
}
|
||||
case broadcastValidationConsensusAndEquivocation:
|
||||
if err := s.validateConsensus(r.Context(), blk); err != nil {
|
||||
return errors.Wrap(err, "consensus validation failed")
|
||||
}
|
||||
b, err := blocks.NewSignedBeaconBlock(blk.Block)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not create signed beacon block")
|
||||
}
|
||||
if err = s.validateConsensus(r.Context(), b); err != nil {
|
||||
return errors.Wrap(err, "consensus validation failed")
|
||||
}
|
||||
if err = s.validateEquivocation(b.Block()); err != nil {
|
||||
return errors.Wrap(err, "equivocation validation failed")
|
||||
}
|
||||
@@ -1056,7 +1053,12 @@ func (s *Server) validateBroadcast(ctx context.Context, r *http.Request, blk *et
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) validateConsensus(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) error {
|
||||
func (s *Server) validateConsensus(ctx context.Context, b *eth.GenericSignedBeaconBlock) error {
|
||||
blk, err := blocks.NewSignedBeaconBlock(b.Block)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not create signed beacon block")
|
||||
}
|
||||
|
||||
parentBlockRoot := blk.Block().ParentRoot()
|
||||
parentBlock, err := s.Blocker.Block(ctx, parentBlockRoot[:])
|
||||
if err != nil {
|
||||
@@ -1076,6 +1078,24 @@ func (s *Server) validateConsensus(ctx context.Context, blk interfaces.ReadOnlyS
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not execute state transition")
|
||||
}
|
||||
|
||||
var blobs [][]byte
|
||||
var proofs [][]byte
|
||||
switch {
|
||||
case blk.Version() == version.Electra:
|
||||
blobs = b.GetElectra().Blobs
|
||||
proofs = b.GetElectra().KzgProofs
|
||||
case blk.Version() == version.Deneb:
|
||||
blobs = b.GetDeneb().Blobs
|
||||
proofs = b.GetDeneb().KzgProofs
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := s.validateBlobSidecars(blk, blobs, proofs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1086,6 +1106,25 @@ func (s *Server) validateEquivocation(blk interfaces.ReadOnlyBeaconBlock) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) validateBlobSidecars(blk interfaces.SignedBeaconBlock, blobs [][]byte, proofs [][]byte) error {
|
||||
if blk.Version() < version.Deneb {
|
||||
return nil
|
||||
}
|
||||
kzgs, err := blk.Block().Body().BlobKzgCommitments()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get blob kzg commitments")
|
||||
}
|
||||
if len(blobs) != len(proofs) || len(blobs) != len(kzgs) {
|
||||
return errors.New("number of blobs, proofs, and commitments do not match")
|
||||
}
|
||||
for i, blob := range blobs {
|
||||
if err := kzg4844.VerifyBlobProof(kzg4844.Blob(blob), kzg4844.Commitment(kzgs[i]), kzg4844.Proof(proofs[i])); err != nil {
|
||||
return errors.Wrap(err, "could not verify blob proof")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBlockRoot retrieves the root of a block.
|
||||
func (s *Server) GetBlockRoot(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, span := trace.StartSpan(r.Context(), "beacon.GetBlockRoot")
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
GoKZG "github.com/crate-crypto/go-kzg-4844"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
@@ -33,6 +34,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -2922,8 +2924,6 @@ func TestValidateConsensus(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
block, err := util.GenerateFullBlock(st, privs, util.DefaultBlockGenConfig(), st.Slot())
|
||||
require.NoError(t, err)
|
||||
sbb, err := blocks.NewSignedBeaconBlock(block)
|
||||
require.NoError(t, err)
|
||||
parentRoot, err := parentSbb.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
server := &Server{
|
||||
@@ -2931,7 +2931,11 @@ func TestValidateConsensus(t *testing.T) {
|
||||
Stater: &testutil.MockStater{StatesByRoot: map[[32]byte]state.BeaconState{bytesutil.ToBytes32(parentBlock.Block.StateRoot): parentState}},
|
||||
}
|
||||
|
||||
require.NoError(t, server.validateConsensus(ctx, sbb))
|
||||
require.NoError(t, server.validateConsensus(ctx, ð.GenericSignedBeaconBlock{
|
||||
Block: ð.GenericSignedBeaconBlock_Phase0{
|
||||
Phase0: block,
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
func TestValidateEquivocation(t *testing.T) {
|
||||
@@ -4152,3 +4156,24 @@ func TestServer_broadcastBlobSidecars(t *testing.T) {
|
||||
require.NoError(t, server.broadcastSeenBlockSidecars(context.Background(), blk, b.GetDeneb().Blobs, b.GetDeneb().KzgProofs))
|
||||
require.LogsContain(t, hook, "Broadcasted blob sidecar for already seen block")
|
||||
}
|
||||
|
||||
func Test_validateBlobSidecars(t *testing.T) {
|
||||
blob := util.GetRandBlob(123)
|
||||
commitment := GoKZG.KZGCommitment{180, 218, 156, 194, 59, 20, 10, 189, 186, 254, 132, 93, 7, 127, 104, 172, 238, 240, 237, 70, 83, 89, 1, 152, 99, 0, 165, 65, 143, 62, 20, 215, 230, 14, 205, 95, 28, 245, 54, 25, 160, 16, 178, 31, 232, 207, 38, 85}
|
||||
proof := GoKZG.KZGProof{128, 110, 116, 170, 56, 111, 126, 87, 229, 234, 211, 42, 110, 150, 129, 206, 73, 142, 167, 243, 90, 149, 240, 240, 236, 204, 143, 182, 229, 249, 81, 27, 153, 171, 83, 70, 144, 250, 42, 1, 188, 215, 71, 235, 30, 7, 175, 86}
|
||||
blk := util.NewBeaconBlockDeneb()
|
||||
blk.Block.Body.BlobKzgCommitments = [][]byte{commitment[:]}
|
||||
b, err := blocks.NewSignedBeaconBlock(blk)
|
||||
require.NoError(t, err)
|
||||
s := &Server{}
|
||||
require.NoError(t, s.validateBlobSidecars(b, [][]byte{blob[:]}, [][]byte{proof[:]}))
|
||||
|
||||
require.ErrorContains(t, "number of blobs, proofs, and commitments do not match", s.validateBlobSidecars(b, [][]byte{blob[:]}, [][]byte{}))
|
||||
|
||||
sk, err := bls.RandKey()
|
||||
require.NoError(t, err)
|
||||
blk.Block.Body.BlobKzgCommitments = [][]byte{sk.PublicKey().Marshal()}
|
||||
b, err = blocks.NewSignedBeaconBlock(blk)
|
||||
require.NoError(t, err)
|
||||
require.ErrorContains(t, "could not verify blob proof: can't verify opening proof", s.validateBlobSidecars(b, [][]byte{blob[:]}, [][]byte{proof[:]}))
|
||||
}
|
||||
|
||||
@@ -10,12 +10,14 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/server/structs:go_default_library",
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/rpc/core:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//monitoring/tracing/trace:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
)
|
||||
|
||||
// Blobs is an HTTP handler for Beacon API getBlobs.
|
||||
@@ -59,7 +60,30 @@ func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
httputil.WriteJson(w, buildSidecarsJsonResponse(verifiedBlobs))
|
||||
blk, err := s.Blocker.Block(ctx, []byte(blockId))
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not fetch block: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
blkRoot, err := blk.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not hash block: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, blkRoot)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not check if block is optimistic: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
data := buildSidecarsJsonResponse(verifiedBlobs)
|
||||
resp := &structs.SidecarsResponse{
|
||||
Version: version.String(blk.Version()),
|
||||
Data: data,
|
||||
ExecutionOptimistic: isOptimistic,
|
||||
Finalized: s.FinalizationFetcher.IsFinalized(ctx, blkRoot),
|
||||
}
|
||||
httputil.WriteJson(w, resp)
|
||||
}
|
||||
|
||||
// parseIndices filters out invalid and duplicate blob indices
|
||||
@@ -92,14 +116,14 @@ loop:
|
||||
return indices, nil
|
||||
}
|
||||
|
||||
func buildSidecarsJsonResponse(verifiedBlobs []*blocks.VerifiedROBlob) *structs.SidecarsResponse {
|
||||
resp := &structs.SidecarsResponse{Data: make([]*structs.Sidecar, len(verifiedBlobs))}
|
||||
func buildSidecarsJsonResponse(verifiedBlobs []*blocks.VerifiedROBlob) []*structs.Sidecar {
|
||||
sidecars := make([]*structs.Sidecar, len(verifiedBlobs))
|
||||
for i, sc := range verifiedBlobs {
|
||||
proofs := make([]string, len(sc.CommitmentInclusionProof))
|
||||
for j := range sc.CommitmentInclusionProof {
|
||||
proofs[j] = hexutil.Encode(sc.CommitmentInclusionProof[j])
|
||||
}
|
||||
resp.Data[i] = &structs.Sidecar{
|
||||
sidecars[i] = &structs.Sidecar{
|
||||
Index: strconv.FormatUint(sc.Index, 10),
|
||||
Blob: hexutil.Encode(sc.Blob),
|
||||
KzgCommitment: hexutil.Encode(sc.KzgCommitment),
|
||||
@@ -108,7 +132,7 @@ func buildSidecarsJsonResponse(verifiedBlobs []*blocks.VerifiedROBlob) *structs.
|
||||
CommitmentInclusionProof: proofs,
|
||||
}
|
||||
}
|
||||
return resp
|
||||
return sidecars
|
||||
}
|
||||
|
||||
func buildSidecarsSSZResponse(verifiedBlobs []*blocks.VerifiedROBlob) ([]byte, error) {
|
||||
|
||||
@@ -46,16 +46,20 @@ func TestBlobs(t *testing.T) {
|
||||
}
|
||||
blockRoot := blobs[0].BlockRoot()
|
||||
|
||||
mockChainService := &mockChain.ChainService{
|
||||
FinalizedRoots: map[[32]byte]bool{},
|
||||
}
|
||||
s := &Server{
|
||||
OptimisticModeFetcher: mockChainService,
|
||||
FinalizationFetcher: mockChainService,
|
||||
}
|
||||
|
||||
t.Run("genesis", func(t *testing.T) {
|
||||
u := "http://foo.example/genesis"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
}
|
||||
|
||||
s.Blocker = &lookup.BeaconDbBlocker{}
|
||||
s.Blobs(writer, request)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, writer.Code)
|
||||
@@ -69,18 +73,14 @@ func TestBlobs(t *testing.T) {
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{Root: blockRoot[:]},
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{Root: blockRoot[:], Block: denebBlock},
|
||||
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)
|
||||
@@ -111,118 +111,96 @@ func TestBlobs(t *testing.T) {
|
||||
assert.Equal(t, hexutil.Encode(blobs[3].Blob), sidecar.Blob)
|
||||
assert.Equal(t, hexutil.Encode(blobs[3].KzgCommitment), sidecar.KzgCommitment)
|
||||
assert.Equal(t, hexutil.Encode(blobs[3].KzgProof), sidecar.KzgProof)
|
||||
|
||||
require.Equal(t, "deneb", resp.Version)
|
||||
require.Equal(t, false, resp.ExecutionOptimistic)
|
||||
require.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
t.Run("finalized", func(t *testing.T) {
|
||||
u := "http://foo.example/finalized"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}, Block: denebBlock},
|
||||
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, 4, len(resp.Data))
|
||||
})
|
||||
t.Run("justified", func(t *testing.T) {
|
||||
u := "http://foo.example/justified"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{CurrentJustifiedCheckPoint: ð.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, 4, len(resp.Data))
|
||||
require.Equal(t, "deneb", resp.Version)
|
||||
require.Equal(t, false, resp.ExecutionOptimistic)
|
||||
require.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
t.Run("root", func(t *testing.T) {
|
||||
u := "http://foo.example/" + hexutil.Encode(blockRoot[:])
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
BeaconDB: db,
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{Block: denebBlock},
|
||||
BeaconDB: db,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
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, 4, len(resp.Data))
|
||||
|
||||
require.Equal(t, "deneb", resp.Version)
|
||||
require.Equal(t, false, resp.ExecutionOptimistic)
|
||||
require.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
t.Run("slot", func(t *testing.T) {
|
||||
u := "http://foo.example/123"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
BeaconDB: db,
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{Block: denebBlock},
|
||||
BeaconDB: db,
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
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, 4, len(resp.Data))
|
||||
|
||||
require.Equal(t, "deneb", resp.Version)
|
||||
require.Equal(t, false, resp.ExecutionOptimistic)
|
||||
require.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
t.Run("one blob only", func(t *testing.T) {
|
||||
u := "http://foo.example/123?indices=2"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}, Block: denebBlock},
|
||||
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)
|
||||
@@ -235,45 +213,47 @@ func TestBlobs(t *testing.T) {
|
||||
assert.Equal(t, hexutil.Encode(blobs[2].Blob), sidecar.Blob)
|
||||
assert.Equal(t, hexutil.Encode(blobs[2].KzgCommitment), sidecar.KzgCommitment)
|
||||
assert.Equal(t, hexutil.Encode(blobs[2].KzgProof), sidecar.KzgProof)
|
||||
|
||||
require.Equal(t, "deneb", resp.Version)
|
||||
require.Equal(t, false, resp.ExecutionOptimistic)
|
||||
require.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
t.Run("no blobs returns an empty array", func(t *testing.T) {
|
||||
u := "http://foo.example/123"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}, Block: denebBlock},
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: filesystem.NewEphemeralBlobStorage(t), // new ephemeral storage
|
||||
}
|
||||
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, len(resp.Data), 0)
|
||||
|
||||
require.Equal(t, "deneb", resp.Version)
|
||||
require.Equal(t, false, resp.ExecutionOptimistic)
|
||||
require.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
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{
|
||||
moc := &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}, Block: denebBlock}
|
||||
s.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)
|
||||
|
||||
@@ -281,6 +261,10 @@ func TestBlobs(t *testing.T) {
|
||||
resp := &structs.SidecarsResponse{}
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||
require.Equal(t, 0, len(resp.Data))
|
||||
|
||||
require.Equal(t, "deneb", resp.Version)
|
||||
require.Equal(t, false, resp.ExecutionOptimistic)
|
||||
require.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
t.Run("block without commitments returns 200 w/empty list ", func(t *testing.T) {
|
||||
denebBlock, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, 333, 0)
|
||||
@@ -293,17 +277,14 @@ func TestBlobs(t *testing.T) {
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}, Block: denebBlock},
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
},
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
}
|
||||
|
||||
s.Blobs(writer, request)
|
||||
|
||||
@@ -311,16 +292,17 @@ func TestBlobs(t *testing.T) {
|
||||
resp := &structs.SidecarsResponse{}
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
|
||||
require.Equal(t, 0, len(resp.Data))
|
||||
|
||||
require.Equal(t, "deneb", resp.Version)
|
||||
require.Equal(t, false, resp.ExecutionOptimistic)
|
||||
require.Equal(t, false, resp.Finalized)
|
||||
})
|
||||
t.Run("slot before Deneb fork", func(t *testing.T) {
|
||||
u := "http://foo.example/31"
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
}
|
||||
s.Blocker = &lookup.BeaconDbBlocker{}
|
||||
|
||||
s.Blobs(writer, request)
|
||||
|
||||
@@ -335,11 +317,7 @@ func TestBlobs(t *testing.T) {
|
||||
request := httptest.NewRequest("GET", u, nil)
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
}
|
||||
|
||||
s.Blocker = &lookup.BeaconDbBlocker{}
|
||||
s.Blobs(writer, request)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, writer.Code)
|
||||
@@ -354,7 +332,7 @@ func TestBlobs(t *testing.T) {
|
||||
request.Header.Add("Accept", "application/octet-stream")
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
@@ -362,10 +340,8 @@ func TestBlobs(t *testing.T) {
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
}
|
||||
s.Blobs(writer, request)
|
||||
|
||||
assert.Equal(t, http.StatusOK, writer.Code)
|
||||
require.Equal(t, len(writer.Body.Bytes()), fieldparams.BlobSidecarSize) // size of each sidecar
|
||||
// can directly unmarshal to sidecar since there's only 1
|
||||
@@ -379,7 +355,7 @@ func TestBlobs(t *testing.T) {
|
||||
request.Header.Add("Accept", "application/octet-stream")
|
||||
writer := httptest.NewRecorder()
|
||||
writer.Body = &bytes.Buffer{}
|
||||
blocker := &lookup.BeaconDbBlocker{
|
||||
s.Blocker = &lookup.BeaconDbBlocker{
|
||||
ChainInfoFetcher: &mockChain.ChainService{FinalizedCheckPoint: ð.Checkpoint{Root: blockRoot[:]}},
|
||||
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
|
||||
Genesis: time.Now(),
|
||||
@@ -387,10 +363,8 @@ func TestBlobs(t *testing.T) {
|
||||
BeaconDB: db,
|
||||
BlobStorage: bs,
|
||||
}
|
||||
s := &Server{
|
||||
Blocker: blocker,
|
||||
}
|
||||
s.Blobs(writer, request)
|
||||
|
||||
assert.Equal(t, http.StatusOK, writer.Code)
|
||||
require.Equal(t, len(writer.Body.Bytes()), fieldparams.BlobSidecarSize*4) // size of each sidecar
|
||||
})
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package blob
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/lookup"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Blocker lookup.Blocker
|
||||
Blocker lookup.Blocker
|
||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||
FinalizationFetcher blockchain.FinalizationFetcher
|
||||
}
|
||||
|
||||
@@ -20,18 +20,20 @@ go_library(
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/time:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/payload-attribute:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//monitoring/tracing/trace:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prysmaticlabs/prysm/v5/api"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed"
|
||||
@@ -20,13 +22,13 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
chaintime "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
payloadattribute "github.com/prysmaticlabs/prysm/v5/consensus-types/payload-attribute"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
||||
engine "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
@@ -76,6 +78,14 @@ var (
|
||||
errWriterUnusable = errors.New("http response writer is unusable")
|
||||
)
|
||||
|
||||
var httpSSEErrorCount = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "http_sse_error_count",
|
||||
Help: "Total HTTP errors for server sent events endpoint",
|
||||
},
|
||||
[]string{"endpoint", "error"},
|
||||
)
|
||||
|
||||
// The eventStreamer uses lazyReaders to defer serialization until the moment the value is ready to be written to the client.
|
||||
type lazyReader func() io.Reader
|
||||
|
||||
@@ -145,6 +155,13 @@ func newTopicRequest(topics []string) (*topicRequest, error) {
|
||||
// Servers may send SSE comments beginning with ':' for any purpose,
|
||||
// including to keep the event stream connection alive in the presence of proxy servers.
|
||||
func (s *Server) StreamEvents(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
httpSSEErrorCount.WithLabelValues(r.URL.Path, err.Error()).Inc()
|
||||
}
|
||||
}()
|
||||
|
||||
log.Debug("Starting StreamEvents handler")
|
||||
ctx, span := trace.StartSpan(r.Context(), "events.StreamEvents")
|
||||
defer span.End()
|
||||
@@ -174,7 +191,7 @@ func (s *Server) StreamEvents(w http.ResponseWriter, r *http.Request) {
|
||||
defer cancel()
|
||||
es := newEventStreamer(buffSize, ka)
|
||||
|
||||
go es.outboxWriteLoop(ctx, cancel, sw)
|
||||
go es.outboxWriteLoop(ctx, cancel, sw, r.URL.Path)
|
||||
if err := es.recvEventLoop(ctx, cancel, topics, s); err != nil {
|
||||
log.WithError(err).Debug("Shutting down StreamEvents handler.")
|
||||
}
|
||||
@@ -264,11 +281,12 @@ func newlineReader() io.Reader {
|
||||
|
||||
// outboxWriteLoop runs in a separate goroutine. Its job is to write the values in the outbox to
|
||||
// the client as fast as the client can read them.
|
||||
func (es *eventStreamer) outboxWriteLoop(ctx context.Context, cancel context.CancelFunc, w *streamingResponseWriterController) {
|
||||
func (es *eventStreamer) outboxWriteLoop(ctx context.Context, cancel context.CancelFunc, w *streamingResponseWriterController, endpoint string) {
|
||||
var err error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
log.WithError(err).Debug("Event streamer shutting down due to error.")
|
||||
httpSSEErrorCount.WithLabelValues(endpoint, err.Error()).Inc()
|
||||
}
|
||||
es.exit()
|
||||
}()
|
||||
@@ -413,9 +431,9 @@ func topicForEvent(event *feed.Event) string {
|
||||
return HeadTopic
|
||||
case *ethpb.EventFinalizedCheckpoint:
|
||||
return FinalizedCheckpointTopic
|
||||
case *ethpbv2.LightClientFinalityUpdateWithVersion:
|
||||
case interfaces.LightClientFinalityUpdate:
|
||||
return LightClientFinalityUpdateTopic
|
||||
case *ethpbv2.LightClientOptimisticUpdateWithVersion:
|
||||
case interfaces.LightClientOptimisticUpdate:
|
||||
return LightClientOptimisticUpdateTopic
|
||||
case *ethpb.EventChainReorg:
|
||||
return ChainReorgTopic
|
||||
@@ -509,25 +527,25 @@ func (s *Server) lazyReaderForEvent(ctx context.Context, event *feed.Event, topi
|
||||
return func() io.Reader {
|
||||
return jsonMarshalReader(eventName, structs.FinalizedCheckpointEventFromV1(v))
|
||||
}, nil
|
||||
case *ethpbv2.LightClientFinalityUpdateWithVersion:
|
||||
cv, err := structs.LightClientFinalityUpdateFromConsensus(v.Data)
|
||||
case interfaces.LightClientFinalityUpdate:
|
||||
cv, err := structs.LightClientFinalityUpdateFromConsensus(v)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "LightClientFinalityUpdateWithVersion event conversion failure")
|
||||
return nil, errors.Wrap(err, "LightClientFinalityUpdate conversion failure")
|
||||
}
|
||||
ev := &structs.LightClientFinalityUpdateEvent{
|
||||
Version: version.String(int(v.Version)),
|
||||
Version: version.String(v.Version()),
|
||||
Data: cv,
|
||||
}
|
||||
return func() io.Reader {
|
||||
return jsonMarshalReader(eventName, ev)
|
||||
}, nil
|
||||
case *ethpbv2.LightClientOptimisticUpdateWithVersion:
|
||||
cv, err := structs.LightClientOptimisticUpdateFromConsensus(v.Data)
|
||||
case interfaces.LightClientOptimisticUpdate:
|
||||
cv, err := structs.LightClientOptimisticUpdateFromConsensus(v)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "LightClientOptimisticUpdateWithVersion event conversion failure")
|
||||
return nil, errors.Wrap(err, "LightClientOptimisticUpdate conversion failure")
|
||||
}
|
||||
ev := &structs.LightClientOptimisticUpdateEvent{
|
||||
Version: version.String(int(v.Version)),
|
||||
Version: version.String(v.Version()),
|
||||
Data: cv,
|
||||
}
|
||||
return func() io.Reader {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
statefeed "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed/state"
|
||||
)
|
||||
|
||||
// Server defines a server implementation of the gRPC events service,
|
||||
// Server defines a server implementation of the http events service,
|
||||
// providing RPC endpoints to subscribe to events from the beacon node.
|
||||
type Server struct {
|
||||
StateNotifier statefeed.Notifier
|
||||
|
||||
@@ -18,16 +18,12 @@ go_library(
|
||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//monitoring/tracing/trace:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/migration:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_wealdtech_go_bytesutil//:go_default_library",
|
||||
@@ -46,17 +42,18 @@ go_test(
|
||||
"//beacon-chain/blockchain/testing:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/light-client:go_default_library",
|
||||
"//beacon-chain/db/testing:go_default_library",
|
||||
"//beacon-chain/rpc/testutil:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/light-client:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
|
||||
@@ -10,11 +10,10 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
types "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
@@ -47,18 +46,32 @@ func (s *Server) GetLightClientBootstrap(w http.ResponseWriter, req *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
bootstrap, err := createLightClientBootstrap(ctx, state, blk)
|
||||
bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(ctx, s.ChainInfoFetcher.CurrentSlot(), state, blk)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "could not get light client bootstrap: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response := &structs.LightClientBootstrapResponse{
|
||||
Version: version.String(blk.Version()),
|
||||
Data: bootstrap,
|
||||
}
|
||||
w.Header().Set(api.VersionHeader, version.String(version.Deneb))
|
||||
w.Header().Set(api.VersionHeader, version.String(bootstrap.Version()))
|
||||
|
||||
httputil.WriteJson(w, response)
|
||||
if httputil.RespondWithSsz(req) {
|
||||
ssz, err := bootstrap.MarshalSSZ()
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "could not marshal bootstrap to SSZ: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
httputil.WriteSsz(w, ssz, "light_client_bootstrap.ssz")
|
||||
} else {
|
||||
data, err := structs.LightClientBootstrapFromConsensus(bootstrap)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "could not marshal bootstrap to JSON: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response := &structs.LightClientBootstrapResponse{
|
||||
Version: version.String(bootstrap.Version()),
|
||||
Data: data,
|
||||
}
|
||||
httputil.WriteJson(w, response)
|
||||
}
|
||||
}
|
||||
|
||||
// GetLightClientUpdatesByRange - implements https://github.com/ethereum/beacon-APIs/blob/263f4ed6c263c967f13279c7a9f5629b51c5fc55/apis/beacon/light_client/updates.yaml
|
||||
@@ -117,110 +130,33 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R
|
||||
endPeriod = maxSlot / slotsPerPeriod
|
||||
}
|
||||
|
||||
// Populate updates
|
||||
var updates []*structs.LightClientUpdateResponse
|
||||
for period := startPeriod; period <= endPeriod; period++ {
|
||||
// Get the last known state of the period,
|
||||
// 1. We wish the block has a parent in the same period if possible
|
||||
// 2. We wish the block has a state in the same period
|
||||
lastSlotInPeriod := period*slotsPerPeriod + slotsPerPeriod - 1
|
||||
if lastSlotInPeriod > maxSlot {
|
||||
lastSlotInPeriod = maxSlot
|
||||
}
|
||||
firstSlotInPeriod := period * slotsPerPeriod
|
||||
|
||||
// Let's not use the first slot in the period, otherwise the attested header will be in previous period
|
||||
firstSlotInPeriod++
|
||||
|
||||
var state state.BeaconState
|
||||
var block interfaces.ReadOnlySignedBeaconBlock
|
||||
for slot := lastSlotInPeriod; slot >= firstSlotInPeriod; slot-- {
|
||||
state, err = s.Stater.StateBySlot(ctx, types.Slot(slot))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get the block
|
||||
latestBlockHeader := state.LatestBlockHeader()
|
||||
latestStateRoot, err := state.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
latestBlockHeader.StateRoot = latestStateRoot[:]
|
||||
blockRoot, err := latestBlockHeader.HashTreeRoot()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
block, err = s.Blocker.Block(ctx, blockRoot[:])
|
||||
if err != nil || block == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
syncAggregate, err := block.Block().Body().SyncAggregate()
|
||||
if err != nil || syncAggregate == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if syncAggregate.SyncCommitteeBits.Count()*3 < config.SyncCommitteeSize*2 {
|
||||
// Not enough votes
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
if block == nil {
|
||||
// No valid block found for the period
|
||||
continue
|
||||
}
|
||||
|
||||
// Get attested state
|
||||
attestedRoot := block.Block().ParentRoot()
|
||||
attestedBlock, err := s.Blocker.Block(ctx, attestedRoot[:])
|
||||
if err != nil || attestedBlock == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
attestedSlot := attestedBlock.Block().Slot()
|
||||
attestedState, err := s.Stater.StateBySlot(ctx, attestedSlot)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get finalized block
|
||||
var finalizedBlock interfaces.ReadOnlySignedBeaconBlock
|
||||
finalizedCheckPoint := attestedState.FinalizedCheckpoint()
|
||||
if finalizedCheckPoint != nil {
|
||||
finalizedRoot := bytesutil.ToBytes32(finalizedCheckPoint.Root)
|
||||
finalizedBlock, err = s.Blocker.Block(ctx, finalizedRoot[:])
|
||||
if err != nil {
|
||||
finalizedBlock = nil
|
||||
}
|
||||
}
|
||||
|
||||
update, err := newLightClientUpdateFromBeaconState(
|
||||
ctx,
|
||||
state,
|
||||
block,
|
||||
attestedState,
|
||||
attestedBlock,
|
||||
finalizedBlock,
|
||||
)
|
||||
|
||||
if err == nil {
|
||||
updates = append(updates, &structs.LightClientUpdateResponse{
|
||||
Version: version.String(attestedState.Version()),
|
||||
Data: update,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(updates) == 0 {
|
||||
httputil.HandleError(w, "no updates found", http.StatusNotFound)
|
||||
// get updates
|
||||
updatesMap, err := s.BeaconDB.LightClientUpdates(ctx, startPeriod, endPeriod)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not get light client updates from DB: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
updates := make([]*structs.LightClientUpdateResponse, 0, len(updatesMap))
|
||||
|
||||
for i := startPeriod; i <= endPeriod; i++ {
|
||||
update, ok := updatesMap[i]
|
||||
if !ok {
|
||||
// Only return the first contiguous range of updates
|
||||
break
|
||||
}
|
||||
|
||||
updateJson, err := structs.LightClientUpdateFromConsensus(update)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not convert light client update: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
updateResponse := &structs.LightClientUpdateResponse{
|
||||
Version: version.String(update.Version()),
|
||||
Data: updateJson,
|
||||
}
|
||||
updates = append(updates, updateResponse)
|
||||
}
|
||||
httputil.WriteJson(w, updates)
|
||||
}
|
||||
|
||||
@@ -268,7 +204,7 @@ func (s *Server) GetLightClientFinalityUpdate(w http.ResponseWriter, req *http.R
|
||||
return
|
||||
}
|
||||
|
||||
update, err := newLightClientFinalityUpdateFromBeaconState(ctx, st, block, attestedState, attestedBlock, finalizedBlock)
|
||||
update, err := newLightClientFinalityUpdateFromBeaconState(ctx, s.ChainInfoFetcher.CurrentSlot(), st, block, attestedState, attestedBlock, finalizedBlock)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not get light client finality update: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
@@ -313,7 +249,7 @@ func (s *Server) GetLightClientOptimisticUpdate(w http.ResponseWriter, req *http
|
||||
return
|
||||
}
|
||||
|
||||
update, err := newLightClientOptimisticUpdateFromBeaconState(ctx, st, block, attestedState, attestedBlock)
|
||||
update, err := newLightClientOptimisticUpdateFromBeaconState(ctx, s.ChainInfoFetcher.CurrentSlot(), st, block, attestedState, attestedBlock)
|
||||
if err != nil {
|
||||
httputil.HandleError(w, "Could not get light client optimistic update: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,274 +2,25 @@ package lightclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/proto/migration"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
|
||||
lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
)
|
||||
|
||||
func createLightClientBootstrap(ctx context.Context, state state.BeaconState, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) {
|
||||
switch blk.Version() {
|
||||
case version.Phase0:
|
||||
return nil, fmt.Errorf("light client bootstrap is not supported for phase0")
|
||||
case version.Altair, version.Bellatrix:
|
||||
return createLightClientBootstrapAltair(ctx, state, blk)
|
||||
case version.Capella:
|
||||
return createLightClientBootstrapCapella(ctx, state, blk)
|
||||
case version.Deneb, version.Electra:
|
||||
return createLightClientBootstrapDeneb(ctx, state, blk)
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported block version %s", version.String(blk.Version()))
|
||||
}
|
||||
|
||||
func createLightClientBootstrapAltair(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) {
|
||||
// assert compute_epoch_at_slot(state.slot) >= ALTAIR_FORK_EPOCH
|
||||
if slots.ToEpoch(state.Slot()) < params.BeaconConfig().AltairForkEpoch {
|
||||
return nil, fmt.Errorf("light client bootstrap is not supported before Altair, invalid slot %d", state.Slot())
|
||||
}
|
||||
|
||||
// assert state.slot == state.latest_block_header.slot
|
||||
latestBlockHeader := state.LatestBlockHeader()
|
||||
if state.Slot() != latestBlockHeader.Slot {
|
||||
return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot)
|
||||
}
|
||||
|
||||
// header.state_root = hash_tree_root(state)
|
||||
stateRoot, err := state.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get state root")
|
||||
}
|
||||
latestBlockHeader.StateRoot = stateRoot[:]
|
||||
|
||||
// assert hash_tree_root(header) == hash_tree_root(block.message)
|
||||
latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get latest block header root")
|
||||
}
|
||||
beaconBlockRoot, err := block.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get block root")
|
||||
}
|
||||
if latestBlockHeaderRoot != beaconBlockRoot {
|
||||
return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot)
|
||||
}
|
||||
|
||||
lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not convert block to light client header")
|
||||
}
|
||||
lightClientHeader := lightClientHeaderContainer.GetHeaderAltair()
|
||||
|
||||
apiLightClientHeader := &structs.LightClientHeader{
|
||||
Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)),
|
||||
}
|
||||
|
||||
headerJSON, err := json.Marshal(apiLightClientHeader)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not convert header to raw message")
|
||||
}
|
||||
currentSyncCommittee, err := state.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current sync committee")
|
||||
}
|
||||
currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current sync committee proof")
|
||||
}
|
||||
|
||||
branch := make([]string, fieldparams.SyncCommitteeBranchDepth)
|
||||
for i, proof := range currentSyncCommitteeProof {
|
||||
branch[i] = hexutil.Encode(proof)
|
||||
}
|
||||
result := &structs.LightClientBootstrap{
|
||||
Header: headerJSON,
|
||||
CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee),
|
||||
CurrentSyncCommitteeBranch: branch,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func createLightClientBootstrapCapella(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) {
|
||||
// assert compute_epoch_at_slot(state.slot) >= CAPELLA_FORK_EPOCH
|
||||
if slots.ToEpoch(state.Slot()) < params.BeaconConfig().CapellaForkEpoch {
|
||||
return nil, fmt.Errorf("creating Capella light client bootstrap is not supported before Capella, invalid slot %d", state.Slot())
|
||||
}
|
||||
|
||||
// assert state.slot == state.latest_block_header.slot
|
||||
latestBlockHeader := state.LatestBlockHeader()
|
||||
if state.Slot() != latestBlockHeader.Slot {
|
||||
return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot)
|
||||
}
|
||||
|
||||
// header.state_root = hash_tree_root(state)
|
||||
stateRoot, err := state.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get state root")
|
||||
}
|
||||
latestBlockHeader.StateRoot = stateRoot[:]
|
||||
|
||||
// assert hash_tree_root(header) == hash_tree_root(block.message)
|
||||
latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get latest block header root")
|
||||
}
|
||||
beaconBlockRoot, err := block.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get block root")
|
||||
}
|
||||
if latestBlockHeaderRoot != beaconBlockRoot {
|
||||
return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot)
|
||||
}
|
||||
|
||||
lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not convert block to light client header")
|
||||
}
|
||||
lightClientHeader := lightClientHeaderContainer.GetHeaderCapella()
|
||||
|
||||
apiLightClientHeader := &structs.LightClientHeader{
|
||||
Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)),
|
||||
}
|
||||
|
||||
headerJSON, err := json.Marshal(apiLightClientHeader)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not convert header to raw message")
|
||||
}
|
||||
currentSyncCommittee, err := state.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current sync committee")
|
||||
}
|
||||
currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current sync committee proof")
|
||||
}
|
||||
|
||||
branch := make([]string, fieldparams.SyncCommitteeBranchDepth)
|
||||
for i, proof := range currentSyncCommitteeProof {
|
||||
branch[i] = hexutil.Encode(proof)
|
||||
}
|
||||
result := &structs.LightClientBootstrap{
|
||||
Header: headerJSON,
|
||||
CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee),
|
||||
CurrentSyncCommitteeBranch: branch,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func createLightClientBootstrapDeneb(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) {
|
||||
// assert compute_epoch_at_slot(state.slot) >= DENEB_FORK_EPOCH
|
||||
if slots.ToEpoch(state.Slot()) < params.BeaconConfig().DenebForkEpoch {
|
||||
return nil, fmt.Errorf("creating Deneb light client bootstrap is not supported before Deneb, invalid slot %d", state.Slot())
|
||||
}
|
||||
|
||||
// assert state.slot == state.latest_block_header.slot
|
||||
latestBlockHeader := state.LatestBlockHeader()
|
||||
if state.Slot() != latestBlockHeader.Slot {
|
||||
return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot)
|
||||
}
|
||||
|
||||
// header.state_root = hash_tree_root(state)
|
||||
stateRoot, err := state.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get state root")
|
||||
}
|
||||
latestBlockHeader.StateRoot = stateRoot[:]
|
||||
|
||||
// assert hash_tree_root(header) == hash_tree_root(block.message)
|
||||
latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get latest block header root")
|
||||
}
|
||||
beaconBlockRoot, err := block.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get block root")
|
||||
}
|
||||
if latestBlockHeaderRoot != beaconBlockRoot {
|
||||
return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot)
|
||||
}
|
||||
|
||||
lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not convert block to light client header")
|
||||
}
|
||||
lightClientHeader := lightClientHeaderContainer.GetHeaderDeneb()
|
||||
|
||||
apiLightClientHeader := &structs.LightClientHeader{
|
||||
Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)),
|
||||
}
|
||||
|
||||
headerJSON, err := json.Marshal(apiLightClientHeader)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not convert header to raw message")
|
||||
}
|
||||
currentSyncCommittee, err := state.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current sync committee")
|
||||
}
|
||||
currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get current sync committee proof")
|
||||
}
|
||||
var branch []string
|
||||
switch block.Version() {
|
||||
case version.Deneb:
|
||||
branch = make([]string, fieldparams.SyncCommitteeBranchDepth)
|
||||
case version.Electra:
|
||||
branch = make([]string, fieldparams.SyncCommitteeBranchDepthElectra)
|
||||
}
|
||||
for i, proof := range currentSyncCommitteeProof {
|
||||
branch[i] = hexutil.Encode(proof)
|
||||
}
|
||||
result := &structs.LightClientBootstrap{
|
||||
Header: headerJSON,
|
||||
CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee),
|
||||
CurrentSyncCommitteeBranch: branch,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func newLightClientUpdateFromBeaconState(
|
||||
ctx context.Context,
|
||||
state state.BeaconState,
|
||||
block interfaces.ReadOnlySignedBeaconBlock,
|
||||
attestedState state.BeaconState,
|
||||
attestedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
finalizedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (*structs.LightClientUpdate, error) {
|
||||
result, err := lightclient.NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return structs.LightClientUpdateFromConsensus(result)
|
||||
}
|
||||
|
||||
func newLightClientFinalityUpdateFromBeaconState(
|
||||
ctx context.Context,
|
||||
currentSlot primitives.Slot,
|
||||
state state.BeaconState,
|
||||
block interfaces.ReadOnlySignedBeaconBlock,
|
||||
attestedState state.BeaconState,
|
||||
attestedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
finalizedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (*structs.LightClientFinalityUpdate, error) {
|
||||
result, err := lightclient.NewLightClientFinalityUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock)
|
||||
result, err := lightclient.NewLightClientFinalityUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -279,94 +30,16 @@ func newLightClientFinalityUpdateFromBeaconState(
|
||||
|
||||
func newLightClientOptimisticUpdateFromBeaconState(
|
||||
ctx context.Context,
|
||||
currentSlot primitives.Slot,
|
||||
state state.BeaconState,
|
||||
block interfaces.ReadOnlySignedBeaconBlock,
|
||||
attestedState state.BeaconState,
|
||||
attestedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (*structs.LightClientOptimisticUpdate, error) {
|
||||
result, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock)
|
||||
result, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return structs.LightClientOptimisticUpdateFromConsensus(result)
|
||||
}
|
||||
|
||||
func IsSyncCommitteeUpdate(update *v2.LightClientUpdate) bool {
|
||||
nextSyncCommitteeBranch := make([][]byte, fieldparams.SyncCommitteeBranchDepth)
|
||||
return !reflect.DeepEqual(update.NextSyncCommitteeBranch, nextSyncCommitteeBranch)
|
||||
}
|
||||
|
||||
func IsFinalityUpdate(update *v2.LightClientUpdate) bool {
|
||||
finalityBranch := make([][]byte, lightclient.FinalityBranchNumOfLeaves)
|
||||
return !reflect.DeepEqual(update.FinalityBranch, finalityBranch)
|
||||
}
|
||||
|
||||
func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) (bool, error) {
|
||||
maxActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Len()
|
||||
newNumActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Count()
|
||||
oldNumActiveParticipants := oldUpdate.SyncAggregate.SyncCommitteeBits.Count()
|
||||
newHasSupermajority := newNumActiveParticipants*3 >= maxActiveParticipants*2
|
||||
oldHasSupermajority := oldNumActiveParticipants*3 >= maxActiveParticipants*2
|
||||
|
||||
if newHasSupermajority != oldHasSupermajority {
|
||||
return newHasSupermajority, nil
|
||||
}
|
||||
if !newHasSupermajority && newNumActiveParticipants != oldNumActiveParticipants {
|
||||
return newNumActiveParticipants > oldNumActiveParticipants, nil
|
||||
}
|
||||
|
||||
newUpdateAttestedHeaderBeacon, err := newUpdate.AttestedHeader.GetBeacon()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not get attested header beacon")
|
||||
}
|
||||
oldUpdateAttestedHeaderBeacon, err := oldUpdate.AttestedHeader.GetBeacon()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not get attested header beacon")
|
||||
}
|
||||
|
||||
// Compare presence of relevant sync committee
|
||||
newHasRelevantSyncCommittee := IsSyncCommitteeUpdate(newUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot)))
|
||||
oldHasRelevantSyncCommittee := IsSyncCommitteeUpdate(oldUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot)))
|
||||
|
||||
if newHasRelevantSyncCommittee != oldHasRelevantSyncCommittee {
|
||||
return newHasRelevantSyncCommittee, nil
|
||||
}
|
||||
|
||||
// Compare indication of any finality
|
||||
newHasFinality := IsFinalityUpdate(newUpdate)
|
||||
oldHasFinality := IsFinalityUpdate(oldUpdate)
|
||||
if newHasFinality != oldHasFinality {
|
||||
return newHasFinality, nil
|
||||
}
|
||||
|
||||
newUpdateFinalizedHeaderBeacon, err := newUpdate.FinalizedHeader.GetBeacon()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not get finalized header beacon")
|
||||
}
|
||||
oldUpdateFinalizedHeaderBeacon, err := oldUpdate.FinalizedHeader.GetBeacon()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not get finalized header beacon")
|
||||
}
|
||||
|
||||
// Compare sync committee finality
|
||||
if newHasFinality {
|
||||
newHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateFinalizedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot))
|
||||
oldHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateFinalizedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot))
|
||||
|
||||
if newHasSyncCommitteeFinality != oldHasSyncCommitteeFinality {
|
||||
return newHasSyncCommitteeFinality, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Tiebreaker 1: Sync committee participation beyond supermajority
|
||||
if newNumActiveParticipants != oldNumActiveParticipants {
|
||||
return newNumActiveParticipants > oldNumActiveParticipants, nil
|
||||
}
|
||||
|
||||
// Tiebreaker 2: Prefer older data (fewer changes to best)
|
||||
if newUpdateAttestedHeaderBeacon.Slot != oldUpdateAttestedHeaderBeacon.Slot {
|
||||
return newUpdateAttestedHeaderBeacon.Slot < oldUpdateAttestedHeaderBeacon.Slot, nil
|
||||
}
|
||||
return newUpdate.SignatureSlot < oldUpdate.SignatureSlot, nil
|
||||
}
|
||||
|
||||
@@ -1,616 +1 @@
|
||||
package lightclient
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client"
|
||||
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
)
|
||||
|
||||
// When the update has relevant sync committee
|
||||
func createNonEmptySyncCommitteeBranch() [][]byte {
|
||||
res := make([][]byte, fieldparams.SyncCommitteeBranchDepth)
|
||||
res[0] = []byte("xyz")
|
||||
return res
|
||||
}
|
||||
|
||||
// When the update has finality
|
||||
func createNonEmptyFinalityBranch() [][]byte {
|
||||
res := make([][]byte, lightclient.FinalityBranchNumOfLeaves)
|
||||
res[0] = []byte("xyz")
|
||||
return res
|
||||
}
|
||||
|
||||
func TestIsBetterUpdate(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
oldUpdate *ethpbv2.LightClientUpdate
|
||||
newUpdate *ethpbv2.LightClientUpdate
|
||||
expectedResult bool
|
||||
}{
|
||||
{
|
||||
name: "new has supermajority but old doesn't",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b11111100, 0b1}, // [0,0,1,1,1,1,1,1]
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "old has supermajority but new doesn't",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b11111100, 0b1}, // [0,0,1,1,1,1,1,1]
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
||||
},
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "new doesn't have supermajority and newNumActiveParticipants is greater than oldNumActiveParticipants",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "new doesn't have supermajority and newNumActiveParticipants is lesser than oldNumActiveParticipants",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0]
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "new has relevant sync committee but old doesn't",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: make([][]byte, fieldparams.SyncCommitteeBranchDepth),
|
||||
SignatureSlot: 9999,
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000001,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 1000000,
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "old has relevant sync committee but new doesn't",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000001,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 1000000,
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: make([][]byte, fieldparams.SyncCommitteeBranchDepth),
|
||||
SignatureSlot: 9999,
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "new has finality but old doesn't",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: make([][]byte, lightclient.FinalityBranchNumOfLeaves),
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "old has finality but new doesn't",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: make([][]byte, lightclient.FinalityBranchNumOfLeaves),
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "new has finality and sync committee finality both but old doesn't have sync committee finality",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 999999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 999999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "new has finality but doesn't have sync committee finality and old has sync committee finality",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 999999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 999999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "new has more active participants than old",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "new has less active participants than old",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "new's attested header's slot is lesser than old's attested header's slot",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 999999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "new's attested header's slot is greater than old's attested header's slot",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 999999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
{
|
||||
name: "none of the above conditions are met and new signature's slot is less than old signature's slot",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9998,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
name: "none of the above conditions are met and new signature's slot is greater than old signature's slot",
|
||||
oldUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9998,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
newUpdate: ðpbv2.LightClientUpdate{
|
||||
SyncAggregate: ðpbv1.SyncAggregate{
|
||||
SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
|
||||
},
|
||||
AttestedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 1000000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
|
||||
SignatureSlot: 9999,
|
||||
FinalityBranch: createNonEmptyFinalityBranch(),
|
||||
FinalizedHeader: ðpbv2.LightClientHeaderContainer{
|
||||
Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{
|
||||
HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{
|
||||
Slot: 9999,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
result, err := IsBetterUpdate(testCase.newUpdate, testCase.oldUpdate)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testCase.expectedResult, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ import (
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Blocker lookup.Blocker
|
||||
Stater lookup.Stater
|
||||
HeadFetcher blockchain.HeadFetcher
|
||||
BeaconDB db.HeadAccessDatabase
|
||||
Blocker lookup.Blocker
|
||||
Stater lookup.Stater
|
||||
HeadFetcher blockchain.HeadFetcher
|
||||
ChainInfoFetcher blockchain.ChainInfoFetcher
|
||||
BeaconDB db.HeadAccessDatabase
|
||||
}
|
||||
|
||||
@@ -765,6 +765,8 @@ func TestServer_ListIndexedAttestationsElectra(t *testing.T) {
|
||||
cb := primitives.NewAttestationCommitteeBits()
|
||||
cb.SetBitAt(0, true)
|
||||
blockExample := util.NewBeaconBlockElectra()
|
||||
ab := bitfield.NewBitlist(128 / uint64(params.BeaconConfig().SlotsPerEpoch))
|
||||
ab.SetBitAt(0, true)
|
||||
blockExample.Block.Body.Attestations = []*ethpb.AttestationElectra{
|
||||
{
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
@@ -778,7 +780,7 @@ func TestServer_ListIndexedAttestationsElectra(t *testing.T) {
|
||||
},
|
||||
Slot: i,
|
||||
},
|
||||
AggregationBits: bitfield.NewBitlist(128 / uint64(params.BeaconConfig().SlotsPerEpoch)),
|
||||
AggregationBits: ab,
|
||||
CommitteeBits: cb,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -243,15 +243,6 @@ func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot primitiv
|
||||
return nil, fmt.Errorf("incorrect parent hash %#x != %#x", header.ParentHash(), h.BlockHash())
|
||||
}
|
||||
|
||||
reg, err := vs.BlockBuilder.RegistrationByValidatorID(ctx, idx)
|
||||
if err != nil {
|
||||
log.WithError(err).Warn("Proposer: failed to get registration by validator ID, could not check gas limit")
|
||||
} else {
|
||||
if reg.GasLimit != header.GasLimit() {
|
||||
return nil, fmt.Errorf("incorrect header gas limit %d != %d", reg.GasLimit, header.GasLimit())
|
||||
}
|
||||
}
|
||||
|
||||
t, err := slots.ToTime(uint64(vs.TimeFetcher.GenesisTime().Unix()), slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -720,29 +720,6 @@ func TestServer_getPayloadHeader(t *testing.T) {
|
||||
Signature: sk.Sign(srCapella[:]).Marshal(),
|
||||
}
|
||||
|
||||
incorrectGasLimitBid := ðpb.BuilderBid{
|
||||
Header: &v1.ExecutionPayloadHeader{
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
TransactionsRoot: bytesutil.PadTo([]byte{1}, fieldparams.RootLength),
|
||||
ParentHash: params.BeaconConfig().ZeroHash[:],
|
||||
Timestamp: uint64(tiCapella.Unix()),
|
||||
GasLimit: 100,
|
||||
},
|
||||
Pubkey: sk.PublicKey().Marshal(),
|
||||
Value: bytesutil.PadTo([]byte{1, 2, 3}, 32),
|
||||
}
|
||||
signedIncorrectGasLimitBid :=
|
||||
ðpb.SignedBuilderBid{
|
||||
Message: incorrectGasLimitBid,
|
||||
Signature: sk.Sign(srCapella[:]).Marshal(),
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -855,21 +832,6 @@ func TestServer_getPayloadHeader(t *testing.T) {
|
||||
},
|
||||
err: "is different from head block version",
|
||||
},
|
||||
{
|
||||
name: "incorrect gas limit",
|
||||
mock: &builderTest.MockBuilderService{
|
||||
Bid: signedIncorrectGasLimitBid,
|
||||
},
|
||||
fetcher: &blockchainTest.ChainService{
|
||||
Block: func() interfaces.ReadOnlySignedBeaconBlock {
|
||||
wb, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlockBellatrix())
|
||||
require.NoError(t, err)
|
||||
wb.SetSlot(primitives.Slot(params.BeaconConfig().BellatrixForkEpoch) * params.BeaconConfig().SlotsPerEpoch)
|
||||
return wb
|
||||
}(),
|
||||
},
|
||||
err: "incorrect header gas limit 0 != 100",
|
||||
},
|
||||
{
|
||||
name: "different bid version during hard fork",
|
||||
mock: &builderTest.MockBuilderService{
|
||||
@@ -888,18 +850,9 @@ func TestServer_getPayloadHeader(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
vs := &Server{BeaconDB: dbTest.SetupDB(t), BlockBuilder: tc.mock, HeadFetcher: tc.fetcher, TimeFetcher: &blockchainTest.ChainService{
|
||||
vs := &Server{BlockBuilder: tc.mock, HeadFetcher: tc.fetcher, TimeFetcher: &blockchainTest.ChainService{
|
||||
Genesis: genesis,
|
||||
}}
|
||||
regCache := cache.NewRegistrationCache()
|
||||
regCache.UpdateIndexToRegisteredMap(context.Background(), map[primitives.ValidatorIndex]*ethpb.ValidatorRegistrationV1{
|
||||
0: {
|
||||
GasLimit: 0,
|
||||
FeeRecipient: make([]byte, 20),
|
||||
Pubkey: make([]byte, 48),
|
||||
},
|
||||
})
|
||||
tc.mock.RegistrationCache = regCache
|
||||
hb, err := vs.HeadFetcher.HeadBlock(context.Background())
|
||||
require.NoError(t, err)
|
||||
bid, err := vs.getPayloadHeaderFromBuilder(context.Background(), hb.Block().Slot(), 0)
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
)
|
||||
|
||||
const stateSizeLimit int64 = 1 << 29 // 512MB
|
||||
|
||||
// APIInitializer manages initializing the beacon node using checkpoint sync, retrieving the checkpoint state and root
|
||||
// from the remote beacon node api.
|
||||
type APIInitializer struct {
|
||||
@@ -21,7 +19,7 @@ type APIInitializer struct {
|
||||
// NewAPIInitializer creates an APIInitializer, handling the set up of a beacon node api client
|
||||
// using the provided host string.
|
||||
func NewAPIInitializer(beaconNodeHost string) (*APIInitializer, error) {
|
||||
c, err := beacon.NewClient(beaconNodeHost, client.WithMaxBodySize(stateSizeLimit))
|
||||
c, err := beacon.NewClient(beaconNodeHost, client.WithMaxBodySize(client.MaxBodySizeState))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to parse beacon node url or hostname - %s", beaconNodeHost)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/sync/genesis",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/client:go_default_library",
|
||||
"//api/client/beacon:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db"
|
||||
)
|
||||
@@ -17,7 +18,7 @@ type APIInitializer struct {
|
||||
// NewAPIInitializer creates an APIInitializer, handling the set up of a beacon node api client
|
||||
// using the provided host string.
|
||||
func NewAPIInitializer(beaconNodeHost string) (*APIInitializer, error) {
|
||||
c, err := beacon.NewClient(beaconNodeHost)
|
||||
c, err := beacon.NewClient(beaconNodeHost, client.WithMaxBodySize(client.MaxBodySizeState))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to parse beacon node url or hostname - %s", beaconNodeHost)
|
||||
}
|
||||
|
||||
@@ -10,16 +10,4 @@ var (
|
||||
Name: "interop-eth1data-votes",
|
||||
Usage: "Enable mocking of eth1 data votes for proposers to package into blocks",
|
||||
}
|
||||
|
||||
// InteropGenesisTimeFlag specifies genesis time for state generation.
|
||||
InteropGenesisTimeFlag = &cli.Uint64Flag{
|
||||
Name: "interop-genesis-time",
|
||||
Usage: "Specify the genesis time for interop genesis state generation. Must be used with " +
|
||||
"--interop-num-validators",
|
||||
}
|
||||
// InteropNumValidatorsFlag specifies number of genesis validators for state generation.
|
||||
InteropNumValidatorsFlag = &cli.Uint64Flag{
|
||||
Name: "interop-num-validators",
|
||||
Usage: "Specify number of genesis validators to generate for interop. Must be used with --interop-genesis-time",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -60,8 +60,6 @@ var appFlags = []cli.Flag{
|
||||
flags.BlobBatchLimit,
|
||||
flags.BlobBatchLimitBurstFactor,
|
||||
flags.InteropMockEth1DataVotesFlag,
|
||||
flags.InteropNumValidatorsFlag,
|
||||
flags.InteropGenesisTimeFlag,
|
||||
flags.SlotsPerArchivedPoint,
|
||||
flags.DisableDebugRPCEndpoints,
|
||||
flags.SubscribeToAllSubnets,
|
||||
|
||||
@@ -184,14 +184,6 @@ var appHelpFlagGroups = []flagGroup{
|
||||
Name: "features",
|
||||
Flags: features.ActiveFlags(features.BeaconChainFlags),
|
||||
},
|
||||
{
|
||||
Name: "interop",
|
||||
Flags: []cli.Flag{
|
||||
genesis.StatePath,
|
||||
flags.InteropGenesisTimeFlag,
|
||||
flags.InteropNumValidatorsFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "deprecated",
|
||||
Flags: []cli.Flag{
|
||||
|
||||
@@ -22,7 +22,6 @@ go_library(
|
||||
go_binary(
|
||||
name = "prysmctl",
|
||||
embed = [":go_default_library"],
|
||||
gotags = ["noMainnetGenesis"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
|
||||
@@ -42,13 +42,11 @@ var downloadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
const stateSizeLimit int64 = 1 << 29 // 512MB to accommodate future state growth
|
||||
|
||||
func cliActionDownload(_ *cli.Context) error {
|
||||
ctx := context.Background()
|
||||
f := downloadFlags
|
||||
|
||||
opts := []client.ClientOpt{client.WithTimeout(f.Timeout), client.WithMaxBodySize(stateSizeLimit)}
|
||||
opts := []client.ClientOpt{client.WithTimeout(f.Timeout), client.WithMaxBodySize(client.MaxBodySizeState)}
|
||||
client, err := beacon.NewClient(downloadFlags.BeaconNodeHost, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -31,7 +31,6 @@ var (
|
||||
generateGenesisStateFlags = struct {
|
||||
DepositJsonFile string
|
||||
ChainConfigFile string
|
||||
ConfigName string
|
||||
NumValidators uint64
|
||||
GenesisTime uint64
|
||||
GenesisTimeDelay uint64
|
||||
@@ -83,12 +82,6 @@ var (
|
||||
Destination: &generateGenesisStateFlags.DepositJsonFile,
|
||||
Usage: "Path to deposit_data.json file generated by the staking-deposit-cli tool for optionally specifying validators in genesis state",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "config-name",
|
||||
Usage: "Config kind to be used for generating the genesis state. Default: mainnet. Options include mainnet, interop, minimal, sepolia, holesky. --chain-config-file will override this flag.",
|
||||
Destination: &generateGenesisStateFlags.ConfigName,
|
||||
Value: params.MainnetName,
|
||||
},
|
||||
&cli.Uint64Flag{
|
||||
Name: "num-validators",
|
||||
Usage: "Number of validators to deterministically generate in the genesis state",
|
||||
@@ -216,11 +209,7 @@ func setGlobalParams() error {
|
||||
log.Infof("Specified a chain config file: %s", chainConfigFile)
|
||||
return params.LoadChainConfigFile(chainConfigFile, nil)
|
||||
}
|
||||
cfg, err := params.ByName(generateGenesisStateFlags.ConfigName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to find config using name %s: %w", generateGenesisStateFlags.ConfigName, err)
|
||||
}
|
||||
return params.SetActive(cfg.Copy())
|
||||
return errors.New("No chain config file was provided. Use `--chain-config-file` to provide a chain config.")
|
||||
}
|
||||
|
||||
func generateGenesis(ctx context.Context) (state.BeaconState, error) {
|
||||
|
||||
@@ -254,9 +254,10 @@ func ConfigureBeaconChain(ctx *cli.Context) error {
|
||||
logEnabled(BlobSaveFsync)
|
||||
cfg.BlobSaveFsync = true
|
||||
}
|
||||
if ctx.IsSet(EnableQUIC.Name) {
|
||||
logEnabled(EnableQUIC)
|
||||
cfg.EnableQUIC = true
|
||||
cfg.EnableQUIC = true
|
||||
if ctx.IsSet(DisableQUIC.Name) {
|
||||
logDisabled(DisableQUIC)
|
||||
cfg.EnableQUIC = false
|
||||
}
|
||||
if ctx.IsSet(DisableCommitteeAwarePacking.Name) {
|
||||
logEnabled(DisableCommitteeAwarePacking)
|
||||
|
||||
@@ -83,6 +83,21 @@ var (
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedInteropGenesisTimeFlag = &cli.Uint64Flag{
|
||||
Name: "interop-genesis-time",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedInteropNumValidatorsFlag = &cli.Uint64Flag{
|
||||
Name: "interop-num-validators",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedEnableQuic = &cli.BoolFlag{
|
||||
Name: "enable-quic",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
)
|
||||
|
||||
// Deprecated flags for both the beacon node and validator client.
|
||||
@@ -101,8 +116,12 @@ var deprecatedFlags = []cli.Flag{
|
||||
deprecatedDisableGRPCGateway,
|
||||
deprecatedEnableExperimentalState,
|
||||
deprecatedEnableCommitteeAwarePacking,
|
||||
deprecatedInteropGenesisTimeFlag,
|
||||
deprecatedEnableQuic,
|
||||
}
|
||||
|
||||
// deprecatedBeaconFlags contains flags that are still used by other components
|
||||
// and therefore cannot be added to deprecatedFlags
|
||||
var deprecatedBeaconFlags []cli.Flag
|
||||
var deprecatedBeaconFlags = []cli.Flag{
|
||||
deprecatedInteropNumValidatorsFlag,
|
||||
}
|
||||
|
||||
@@ -161,10 +161,10 @@ var (
|
||||
Name: "blob-save-fsync",
|
||||
Usage: "Forces new blob files to be fysnc'd before continuing, ensuring durable blob writes.",
|
||||
}
|
||||
// EnableQUIC enables connection using the QUIC protocol for peers which support it.
|
||||
EnableQUIC = &cli.BoolFlag{
|
||||
Name: "enable-quic",
|
||||
Usage: "Enables connection using the QUIC protocol for peers which support it.",
|
||||
// DisableQUIC disables connecting to peers using the QUIC protocol.
|
||||
DisableQUIC = &cli.BoolFlag{
|
||||
Name: "disable-quic",
|
||||
Usage: "Disables connecting using the QUIC protocol with peers.",
|
||||
}
|
||||
DisableCommitteeAwarePacking = &cli.BoolFlag{
|
||||
Name: "disable-committee-aware-packing",
|
||||
@@ -179,7 +179,6 @@ var (
|
||||
// devModeFlags holds list of flags that are set when development mode is on.
|
||||
var devModeFlags = []cli.Flag{
|
||||
backfill.EnableExperimentalBackfill,
|
||||
EnableQUIC,
|
||||
}
|
||||
|
||||
// ValidatorFlags contains a list of all the feature flags that apply to the validator client.
|
||||
@@ -229,7 +228,7 @@ var BeaconChainFlags = append(deprecatedBeaconFlags, append(deprecatedFlags, []c
|
||||
DisableRegistrationCache,
|
||||
EnableLightClient,
|
||||
BlobSaveFsync,
|
||||
EnableQUIC,
|
||||
DisableQUIC,
|
||||
DisableCommitteeAwarePacking,
|
||||
EnableDiscoveryReboot,
|
||||
}...)...)
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
// These are variables that we don't use in Prysm. (i.e. future hardfork, light client... etc)
|
||||
// IMPORTANT: Use one field per line and sort these alphabetically to reduce conflicts.
|
||||
var placeholderFields = []string{
|
||||
"BLOB_SIDECAR_SUBNET_COUNT_EIP7594",
|
||||
"BYTES_PER_LOGS_BLOOM", // Compile time constant on ExecutionPayload.logs_bloom.
|
||||
"EIP6110_FORK_EPOCH",
|
||||
"EIP6110_FORK_VERSION",
|
||||
@@ -35,11 +36,13 @@ var placeholderFields = []string{
|
||||
"FIELD_ELEMENTS_PER_BLOB", // Compile time constant.
|
||||
"KZG_COMMITMENT_INCLUSION_PROOF_DEPTH", // Compile time constant on BlobSidecar.commitment_inclusion_proof.
|
||||
"MAX_BLOBS_PER_BLOCK",
|
||||
"MAX_BLOBS_PER_BLOCK_EIP7594",
|
||||
"MAX_BLOB_COMMITMENTS_PER_BLOCK", // Compile time constant on BeaconBlockBodyDeneb.blob_kzg_commitments.
|
||||
"MAX_BYTES_PER_TRANSACTION", // Used for ssz of EL transactions. Unused in Prysm.
|
||||
"MAX_EXTRA_DATA_BYTES", // Compile time constant on ExecutionPayload.extra_data.
|
||||
"MAX_REQUEST_PAYLOADS", // Compile time constant on BeaconBlockBody.ExecutionRequests
|
||||
"MAX_TRANSACTIONS_PER_PAYLOAD", // Compile time constant on ExecutionPayload.transactions.
|
||||
"MAX_REQUEST_BLOB_SIDECARS_EIP7594",
|
||||
"MAX_REQUEST_PAYLOADS", // Compile time constant on BeaconBlockBody.ExecutionRequests
|
||||
"MAX_TRANSACTIONS_PER_PAYLOAD", // Compile time constant on ExecutionPayload.transactions.
|
||||
"REORG_HEAD_WEIGHT_THRESHOLD",
|
||||
"TARGET_NUMBER_OF_PEERS",
|
||||
"UPDATE_TIMEOUT",
|
||||
|
||||
@@ -240,23 +240,13 @@ func PayloadProof(ctx context.Context, block interfaces.ReadOnlyBeaconBlock) ([]
|
||||
return nil, errors.New("failed to cast block body")
|
||||
}
|
||||
|
||||
blockBodyFieldRoots, err := ComputeBlockBodyFieldRoots(ctx, blockBody)
|
||||
fieldRoots, err := ComputeBlockBodyFieldRoots(ctx, blockBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockBodyFieldRootsTrie := stateutil.Merkleize(blockBodyFieldRoots)
|
||||
blockBodyProof := trie.ProofFromMerkleLayers(blockBodyFieldRootsTrie, payloadFieldIndex)
|
||||
fieldRootsTrie := stateutil.Merkleize(fieldRoots)
|
||||
proof := trie.ProofFromMerkleLayers(fieldRootsTrie, payloadFieldIndex)
|
||||
|
||||
beaconBlockFieldRoots, err := ComputeBlockFieldRoots(ctx, block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
beaconBlockFieldRootsTrie := stateutil.Merkleize(beaconBlockFieldRoots)
|
||||
beaconBlockProof := trie.ProofFromMerkleLayers(beaconBlockFieldRootsTrie, bodyFieldIndex)
|
||||
|
||||
finalProof := append(blockBodyProof, beaconBlockProof...)
|
||||
|
||||
return finalProof, nil
|
||||
return proof, nil
|
||||
}
|
||||
|
||||
@@ -27,9 +27,12 @@ type LightClientBootstrap interface {
|
||||
ssz.Marshaler
|
||||
Version() int
|
||||
Header() LightClientHeader
|
||||
SetHeader(header LightClientHeader) error
|
||||
CurrentSyncCommittee() *pb.SyncCommittee
|
||||
SetCurrentSyncCommittee(sc *pb.SyncCommittee) error
|
||||
CurrentSyncCommitteeBranch() (LightClientSyncCommitteeBranch, error)
|
||||
CurrentSyncCommitteeBranchElectra() (LightClientSyncCommitteeBranchElectra, error)
|
||||
SetCurrentSyncCommitteeBranch(branch [][]byte) error
|
||||
}
|
||||
|
||||
type LightClientUpdate interface {
|
||||
@@ -56,6 +59,7 @@ type LightClientUpdate interface {
|
||||
|
||||
type LightClientFinalityUpdate interface {
|
||||
ssz.Marshaler
|
||||
ssz.Unmarshaler
|
||||
Proto() proto.Message
|
||||
Version() int
|
||||
AttestedHeader() LightClientHeader
|
||||
@@ -68,6 +72,7 @@ type LightClientFinalityUpdate interface {
|
||||
|
||||
type LightClientOptimisticUpdate interface {
|
||||
ssz.Marshaler
|
||||
ssz.Unmarshaler
|
||||
Proto() proto.Message
|
||||
Version() int
|
||||
AttestedHeader() LightClientHeader
|
||||
|
||||
@@ -41,10 +41,16 @@ func NewWrappedBootstrapAltair(p *pb.LightClientBootstrapAltair) (interfaces.Lig
|
||||
if p == nil {
|
||||
return nil, consensustypes.ErrNilObjectWrapped
|
||||
}
|
||||
header, err := NewWrappedHeader(p.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
var header interfaces.LightClientHeader
|
||||
var err error
|
||||
if p.Header != nil {
|
||||
header, err = NewWrappedHeader(p.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
branch, err := createBranch[interfaces.LightClientSyncCommitteeBranch](
|
||||
"sync committee",
|
||||
p.CurrentSyncCommitteeBranch,
|
||||
@@ -81,14 +87,42 @@ func (h *bootstrapAltair) Header() interfaces.LightClientHeader {
|
||||
return h.header
|
||||
}
|
||||
|
||||
func (h *bootstrapAltair) SetHeader(header interfaces.LightClientHeader) error {
|
||||
p, ok := (header.Proto()).(*pb.LightClientHeaderAltair)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderAltair{})
|
||||
}
|
||||
h.p.Header = p
|
||||
h.header = header
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapAltair) CurrentSyncCommittee() *pb.SyncCommittee {
|
||||
return h.p.CurrentSyncCommittee
|
||||
}
|
||||
|
||||
func (h *bootstrapAltair) SetCurrentSyncCommittee(sc *pb.SyncCommittee) error {
|
||||
h.p.CurrentSyncCommittee = sc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapAltair) CurrentSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) {
|
||||
return h.currentSyncCommitteeBranch, nil
|
||||
}
|
||||
|
||||
func (h *bootstrapAltair) SetCurrentSyncCommitteeBranch(branch [][]byte) error {
|
||||
if len(branch) != fieldparams.SyncCommitteeBranchDepth {
|
||||
return fmt.Errorf("branch length %d is not %d", len(branch), fieldparams.SyncCommitteeBranchDepth)
|
||||
}
|
||||
newBranch := [fieldparams.SyncCommitteeBranchDepth][32]byte{}
|
||||
for i, root := range branch {
|
||||
copy(newBranch[i][:], root)
|
||||
}
|
||||
h.currentSyncCommitteeBranch = newBranch
|
||||
h.p.CurrentSyncCommitteeBranch = branch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapAltair) CurrentSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) {
|
||||
return [6][32]byte{}, consensustypes.ErrNotSupported("CurrentSyncCommitteeBranchElectra", version.Altair)
|
||||
}
|
||||
@@ -105,10 +139,16 @@ func NewWrappedBootstrapCapella(p *pb.LightClientBootstrapCapella) (interfaces.L
|
||||
if p == nil {
|
||||
return nil, consensustypes.ErrNilObjectWrapped
|
||||
}
|
||||
header, err := NewWrappedHeader(p.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
var header interfaces.LightClientHeader
|
||||
var err error
|
||||
if p.Header != nil {
|
||||
header, err = NewWrappedHeader(p.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
branch, err := createBranch[interfaces.LightClientSyncCommitteeBranch](
|
||||
"sync committee",
|
||||
p.CurrentSyncCommitteeBranch,
|
||||
@@ -145,14 +185,42 @@ func (h *bootstrapCapella) Header() interfaces.LightClientHeader {
|
||||
return h.header
|
||||
}
|
||||
|
||||
func (h *bootstrapCapella) SetHeader(header interfaces.LightClientHeader) error {
|
||||
p, ok := (header.Proto()).(*pb.LightClientHeaderCapella)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderCapella{})
|
||||
}
|
||||
h.p.Header = p
|
||||
h.header = header
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapCapella) CurrentSyncCommittee() *pb.SyncCommittee {
|
||||
return h.p.CurrentSyncCommittee
|
||||
}
|
||||
|
||||
func (h *bootstrapCapella) SetCurrentSyncCommittee(sc *pb.SyncCommittee) error {
|
||||
h.p.CurrentSyncCommittee = sc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapCapella) CurrentSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) {
|
||||
return h.currentSyncCommitteeBranch, nil
|
||||
}
|
||||
|
||||
func (h *bootstrapCapella) SetCurrentSyncCommitteeBranch(branch [][]byte) error {
|
||||
if len(branch) != fieldparams.SyncCommitteeBranchDepth {
|
||||
return fmt.Errorf("branch length %d is not %d", len(branch), fieldparams.SyncCommitteeBranchDepth)
|
||||
}
|
||||
newBranch := [fieldparams.SyncCommitteeBranchDepth][32]byte{}
|
||||
for i, root := range branch {
|
||||
copy(newBranch[i][:], root)
|
||||
}
|
||||
h.currentSyncCommitteeBranch = newBranch
|
||||
h.p.CurrentSyncCommitteeBranch = branch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapCapella) CurrentSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) {
|
||||
return [6][32]byte{}, consensustypes.ErrNotSupported("CurrentSyncCommitteeBranchElectra", version.Capella)
|
||||
}
|
||||
@@ -169,10 +237,16 @@ func NewWrappedBootstrapDeneb(p *pb.LightClientBootstrapDeneb) (interfaces.Light
|
||||
if p == nil {
|
||||
return nil, consensustypes.ErrNilObjectWrapped
|
||||
}
|
||||
header, err := NewWrappedHeader(p.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
var header interfaces.LightClientHeader
|
||||
var err error
|
||||
if p.Header != nil {
|
||||
header, err = NewWrappedHeader(p.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
branch, err := createBranch[interfaces.LightClientSyncCommitteeBranch](
|
||||
"sync committee",
|
||||
p.CurrentSyncCommitteeBranch,
|
||||
@@ -209,14 +283,42 @@ func (h *bootstrapDeneb) Header() interfaces.LightClientHeader {
|
||||
return h.header
|
||||
}
|
||||
|
||||
func (h *bootstrapDeneb) SetHeader(header interfaces.LightClientHeader) error {
|
||||
p, ok := (header.Proto()).(*pb.LightClientHeaderDeneb)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderDeneb{})
|
||||
}
|
||||
h.p.Header = p
|
||||
h.header = header
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapDeneb) CurrentSyncCommittee() *pb.SyncCommittee {
|
||||
return h.p.CurrentSyncCommittee
|
||||
}
|
||||
|
||||
func (h *bootstrapDeneb) SetCurrentSyncCommittee(sc *pb.SyncCommittee) error {
|
||||
h.p.CurrentSyncCommittee = sc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapDeneb) CurrentSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) {
|
||||
return h.currentSyncCommitteeBranch, nil
|
||||
}
|
||||
|
||||
func (h *bootstrapDeneb) SetCurrentSyncCommitteeBranch(branch [][]byte) error {
|
||||
if len(branch) != fieldparams.SyncCommitteeBranchDepth {
|
||||
return fmt.Errorf("branch length %d is not %d", len(branch), fieldparams.SyncCommitteeBranchDepth)
|
||||
}
|
||||
newBranch := [fieldparams.SyncCommitteeBranchDepth][32]byte{}
|
||||
for i, root := range branch {
|
||||
copy(newBranch[i][:], root)
|
||||
}
|
||||
h.currentSyncCommitteeBranch = newBranch
|
||||
h.p.CurrentSyncCommitteeBranch = branch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapDeneb) CurrentSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) {
|
||||
return [6][32]byte{}, consensustypes.ErrNotSupported("CurrentSyncCommitteeBranchElectra", version.Deneb)
|
||||
}
|
||||
@@ -233,10 +335,16 @@ func NewWrappedBootstrapElectra(p *pb.LightClientBootstrapElectra) (interfaces.L
|
||||
if p == nil {
|
||||
return nil, consensustypes.ErrNilObjectWrapped
|
||||
}
|
||||
header, err := NewWrappedHeader(p.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
var header interfaces.LightClientHeader
|
||||
var err error
|
||||
if p.Header != nil {
|
||||
header, err = NewWrappedHeader(p.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
branch, err := createBranch[interfaces.LightClientSyncCommitteeBranchElectra](
|
||||
"sync committee",
|
||||
p.CurrentSyncCommitteeBranch,
|
||||
@@ -273,14 +381,42 @@ func (h *bootstrapElectra) Header() interfaces.LightClientHeader {
|
||||
return h.header
|
||||
}
|
||||
|
||||
func (h *bootstrapElectra) SetHeader(header interfaces.LightClientHeader) error {
|
||||
p, ok := (header.Proto()).(*pb.LightClientHeaderDeneb)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderDeneb{})
|
||||
}
|
||||
h.p.Header = p
|
||||
h.header = header
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapElectra) CurrentSyncCommittee() *pb.SyncCommittee {
|
||||
return h.p.CurrentSyncCommittee
|
||||
}
|
||||
|
||||
func (h *bootstrapElectra) SetCurrentSyncCommittee(sc *pb.SyncCommittee) error {
|
||||
h.p.CurrentSyncCommittee = sc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapElectra) CurrentSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) {
|
||||
return [5][32]byte{}, consensustypes.ErrNotSupported("CurrentSyncCommitteeBranch", version.Electra)
|
||||
}
|
||||
|
||||
func (h *bootstrapElectra) SetCurrentSyncCommitteeBranch(branch [][]byte) error {
|
||||
if len(branch) != fieldparams.SyncCommitteeBranchDepthElectra {
|
||||
return fmt.Errorf("branch length %d is not %d", len(branch), fieldparams.SyncCommitteeBranchDepthElectra)
|
||||
}
|
||||
newBranch := [fieldparams.SyncCommitteeBranchDepthElectra][32]byte{}
|
||||
for i, root := range branch {
|
||||
copy(newBranch[i][:], root)
|
||||
}
|
||||
h.currentSyncCommitteeBranch = newBranch
|
||||
h.p.CurrentSyncCommitteeBranch = branch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *bootstrapElectra) CurrentSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) {
|
||||
return h.currentSyncCommitteeBranch, nil
|
||||
}
|
||||
|
||||
@@ -139,6 +139,23 @@ func (u *finalityUpdateAltair) SizeSSZ() int {
|
||||
return u.p.SizeSSZ()
|
||||
}
|
||||
|
||||
func (u *finalityUpdateAltair) UnmarshalSSZ(buf []byte) error {
|
||||
p := &pb.LightClientFinalityUpdateAltair{}
|
||||
if err := p.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
updateInterface, err := NewWrappedFinalityUpdateAltair(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
update, ok := updateInterface.(*finalityUpdateAltair)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected update type %T", updateInterface)
|
||||
}
|
||||
*u = *update
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *finalityUpdateAltair) Proto() proto.Message {
|
||||
return u.p
|
||||
}
|
||||
@@ -221,6 +238,23 @@ func (u *finalityUpdateCapella) SizeSSZ() int {
|
||||
return u.p.SizeSSZ()
|
||||
}
|
||||
|
||||
func (u *finalityUpdateCapella) UnmarshalSSZ(buf []byte) error {
|
||||
p := &pb.LightClientFinalityUpdateCapella{}
|
||||
if err := p.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
updateInterface, err := NewWrappedFinalityUpdateCapella(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
update, ok := updateInterface.(*finalityUpdateCapella)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected update type %T", updateInterface)
|
||||
}
|
||||
*u = *update
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *finalityUpdateCapella) Proto() proto.Message {
|
||||
return u.p
|
||||
}
|
||||
@@ -303,6 +337,23 @@ func (u *finalityUpdateDeneb) SizeSSZ() int {
|
||||
return u.p.SizeSSZ()
|
||||
}
|
||||
|
||||
func (u *finalityUpdateDeneb) UnmarshalSSZ(buf []byte) error {
|
||||
p := &pb.LightClientFinalityUpdateDeneb{}
|
||||
if err := p.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
updateInterface, err := NewWrappedFinalityUpdateDeneb(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
update, ok := updateInterface.(*finalityUpdateDeneb)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected update type %T", updateInterface)
|
||||
}
|
||||
*u = *update
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *finalityUpdateDeneb) Proto() proto.Message {
|
||||
return u.p
|
||||
}
|
||||
@@ -386,6 +437,23 @@ func (u *finalityUpdateElectra) SizeSSZ() int {
|
||||
return u.p.SizeSSZ()
|
||||
}
|
||||
|
||||
func (u *finalityUpdateElectra) UnmarshalSSZ(buf []byte) error {
|
||||
p := &pb.LightClientFinalityUpdateElectra{}
|
||||
if err := p.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
updateInterface, err := NewWrappedFinalityUpdateElectra(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
update, ok := updateInterface.(*finalityUpdateElectra)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected update type %T", updateInterface)
|
||||
}
|
||||
*u = *update
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *finalityUpdateElectra) Proto() proto.Message {
|
||||
return u.p
|
||||
}
|
||||
|
||||
@@ -104,6 +104,23 @@ func (u *optimisticUpdateAltair) SizeSSZ() int {
|
||||
return u.p.SizeSSZ()
|
||||
}
|
||||
|
||||
func (u *optimisticUpdateAltair) UnmarshalSSZ(buf []byte) error {
|
||||
p := &pb.LightClientOptimisticUpdateAltair{}
|
||||
if err := p.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
updateInterface, err := NewWrappedOptimisticUpdateAltair(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
update, ok := updateInterface.(*optimisticUpdateAltair)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected update type %T", updateInterface)
|
||||
}
|
||||
*u = *update
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *optimisticUpdateAltair) Proto() proto.Message {
|
||||
return u.p
|
||||
}
|
||||
@@ -158,6 +175,23 @@ func (u *optimisticUpdateCapella) SizeSSZ() int {
|
||||
return u.p.SizeSSZ()
|
||||
}
|
||||
|
||||
func (u *optimisticUpdateCapella) UnmarshalSSZ(buf []byte) error {
|
||||
p := &pb.LightClientOptimisticUpdateCapella{}
|
||||
if err := p.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
updateInterface, err := NewWrappedOptimisticUpdateCapella(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
update, ok := updateInterface.(*optimisticUpdateCapella)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected update type %T", updateInterface)
|
||||
}
|
||||
*u = *update
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *optimisticUpdateCapella) Proto() proto.Message {
|
||||
return u.p
|
||||
}
|
||||
@@ -212,6 +246,23 @@ func (u *optimisticUpdateDeneb) SizeSSZ() int {
|
||||
return u.p.SizeSSZ()
|
||||
}
|
||||
|
||||
func (u *optimisticUpdateDeneb) UnmarshalSSZ(buf []byte) error {
|
||||
p := &pb.LightClientOptimisticUpdateDeneb{}
|
||||
if err := p.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
updateInterface, err := NewWrappedOptimisticUpdateDeneb(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
update, ok := updateInterface.(*optimisticUpdateDeneb)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected update type %T", updateInterface)
|
||||
}
|
||||
*u = *update
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *optimisticUpdateDeneb) Proto() proto.Message {
|
||||
return u.p
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ func (u *updateAltair) AttestedHeader() interfaces.LightClientHeader {
|
||||
func (u *updateAltair) SetAttestedHeader(header interfaces.LightClientHeader) error {
|
||||
proto, ok := header.Proto().(*pb.LightClientHeaderAltair)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderAltair{})
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderAltair{})
|
||||
}
|
||||
u.p.AttestedHeader = proto
|
||||
u.attestedHeader = header
|
||||
@@ -157,7 +157,7 @@ func (u *updateAltair) FinalizedHeader() interfaces.LightClientHeader {
|
||||
func (u *updateAltair) SetFinalizedHeader(header interfaces.LightClientHeader) error {
|
||||
proto, ok := header.Proto().(*pb.LightClientHeaderAltair)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderAltair{})
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderAltair{})
|
||||
}
|
||||
u.p.FinalizedHeader = proto
|
||||
u.finalizedHeader = header
|
||||
@@ -168,6 +168,10 @@ func (u *updateAltair) FinalityBranch() (interfaces.LightClientFinalityBranch, e
|
||||
return u.finalityBranch, nil
|
||||
}
|
||||
|
||||
func (u *updateAltair) FinalityBranchElectra() (interfaces.LightClientFinalityBranchElectra, error) {
|
||||
return interfaces.LightClientFinalityBranchElectra{}, consensustypes.ErrNotSupported("FinalityBranchElectra", version.Altair)
|
||||
}
|
||||
|
||||
func (u *updateAltair) SetFinalityBranch(branch [][]byte) error {
|
||||
b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth)
|
||||
if err != nil {
|
||||
@@ -178,10 +182,6 @@ func (u *updateAltair) SetFinalityBranch(branch [][]byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *updateAltair) FinalityBranchElectra() (interfaces.LightClientFinalityBranchElectra, error) {
|
||||
return interfaces.LightClientFinalityBranchElectra{}, consensustypes.ErrNotSupported("FinalityBranchElectra", version.Altair)
|
||||
}
|
||||
|
||||
func (u *updateAltair) SyncAggregate() *pb.SyncAggregate {
|
||||
return u.p.SyncAggregate
|
||||
}
|
||||
@@ -282,7 +282,7 @@ func (u *updateCapella) AttestedHeader() interfaces.LightClientHeader {
|
||||
func (u *updateCapella) SetAttestedHeader(header interfaces.LightClientHeader) error {
|
||||
proto, ok := header.Proto().(*pb.LightClientHeaderCapella)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderCapella{})
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderCapella{})
|
||||
}
|
||||
u.p.AttestedHeader = proto
|
||||
u.attestedHeader = header
|
||||
@@ -324,7 +324,7 @@ func (u *updateCapella) FinalizedHeader() interfaces.LightClientHeader {
|
||||
func (u *updateCapella) SetFinalizedHeader(header interfaces.LightClientHeader) error {
|
||||
proto, ok := header.Proto().(*pb.LightClientHeaderCapella)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderCapella{})
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderCapella{})
|
||||
}
|
||||
u.p.FinalizedHeader = proto
|
||||
u.finalizedHeader = header
|
||||
@@ -335,6 +335,10 @@ func (u *updateCapella) FinalityBranch() (interfaces.LightClientFinalityBranch,
|
||||
return u.finalityBranch, nil
|
||||
}
|
||||
|
||||
func (u *updateCapella) FinalityBranchElectra() (interfaces.LightClientFinalityBranchElectra, error) {
|
||||
return interfaces.LightClientFinalityBranchElectra{}, consensustypes.ErrNotSupported("FinalityBranchElectra", u.Version())
|
||||
}
|
||||
|
||||
func (u *updateCapella) SetFinalityBranch(branch [][]byte) error {
|
||||
b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth)
|
||||
if err != nil {
|
||||
@@ -345,10 +349,6 @@ func (u *updateCapella) SetFinalityBranch(branch [][]byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *updateCapella) FinalityBranchElectra() (interfaces.LightClientFinalityBranchElectra, error) {
|
||||
return interfaces.LightClientFinalityBranchElectra{}, consensustypes.ErrNotSupported("FinalityBranchElectra", u.Version())
|
||||
}
|
||||
|
||||
func (u *updateCapella) SyncAggregate() *pb.SyncAggregate {
|
||||
return u.p.SyncAggregate
|
||||
}
|
||||
@@ -449,7 +449,7 @@ func (u *updateDeneb) AttestedHeader() interfaces.LightClientHeader {
|
||||
func (u *updateDeneb) SetAttestedHeader(header interfaces.LightClientHeader) error {
|
||||
proto, ok := header.Proto().(*pb.LightClientHeaderDeneb)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{})
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderDeneb{})
|
||||
}
|
||||
u.p.AttestedHeader = proto
|
||||
u.attestedHeader = header
|
||||
@@ -491,7 +491,7 @@ func (u *updateDeneb) FinalizedHeader() interfaces.LightClientHeader {
|
||||
func (u *updateDeneb) SetFinalizedHeader(header interfaces.LightClientHeader) error {
|
||||
proto, ok := header.Proto().(*pb.LightClientHeaderDeneb)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{})
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderDeneb{})
|
||||
}
|
||||
u.p.FinalizedHeader = proto
|
||||
u.finalizedHeader = header
|
||||
@@ -502,6 +502,10 @@ func (u *updateDeneb) FinalityBranch() (interfaces.LightClientFinalityBranch, er
|
||||
return u.finalityBranch, nil
|
||||
}
|
||||
|
||||
func (u *updateDeneb) FinalityBranchElectra() (interfaces.LightClientFinalityBranchElectra, error) {
|
||||
return interfaces.LightClientFinalityBranchElectra{}, consensustypes.ErrNotSupported("FinalityBranchElectra", u.Version())
|
||||
}
|
||||
|
||||
func (u *updateDeneb) SetFinalityBranch(branch [][]byte) error {
|
||||
b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth)
|
||||
if err != nil {
|
||||
@@ -512,10 +516,6 @@ func (u *updateDeneb) SetFinalityBranch(branch [][]byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *updateDeneb) FinalityBranchElectra() (interfaces.LightClientFinalityBranchElectra, error) {
|
||||
return interfaces.LightClientFinalityBranchElectra{}, consensustypes.ErrNotSupported("FinalityBranchElectra", u.Version())
|
||||
}
|
||||
|
||||
func (u *updateDeneb) SyncAggregate() *pb.SyncAggregate {
|
||||
return u.p.SyncAggregate
|
||||
}
|
||||
@@ -617,7 +617,7 @@ func (u *updateElectra) AttestedHeader() interfaces.LightClientHeader {
|
||||
func (u *updateElectra) SetAttestedHeader(header interfaces.LightClientHeader) error {
|
||||
proto, ok := header.Proto().(*pb.LightClientHeaderDeneb)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{})
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderDeneb{})
|
||||
}
|
||||
u.p.AttestedHeader = proto
|
||||
u.attestedHeader = header
|
||||
@@ -659,7 +659,7 @@ func (u *updateElectra) FinalizedHeader() interfaces.LightClientHeader {
|
||||
func (u *updateElectra) SetFinalizedHeader(header interfaces.LightClientHeader) error {
|
||||
proto, ok := header.Proto().(*pb.LightClientHeaderDeneb)
|
||||
if !ok {
|
||||
return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{})
|
||||
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderDeneb{})
|
||||
}
|
||||
u.p.FinalizedHeader = proto
|
||||
u.finalizedHeader = header
|
||||
@@ -670,6 +670,10 @@ func (u *updateElectra) FinalityBranch() (interfaces.LightClientFinalityBranch,
|
||||
return interfaces.LightClientFinalityBranch{}, consensustypes.ErrNotSupported("FinalityBranch", u.Version())
|
||||
}
|
||||
|
||||
func (u *updateElectra) FinalityBranchElectra() (interfaces.LightClientFinalityBranchElectra, error) {
|
||||
return u.finalityBranch, nil
|
||||
}
|
||||
|
||||
func (u *updateElectra) SetFinalityBranch(branch [][]byte) error {
|
||||
b, err := createBranch[interfaces.LightClientFinalityBranchElectra]("finality", branch, fieldparams.FinalityBranchDepthElectra)
|
||||
if err != nil {
|
||||
@@ -680,10 +684,6 @@ func (u *updateElectra) SetFinalityBranch(branch [][]byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *updateElectra) FinalityBranchElectra() (interfaces.LightClientFinalityBranchElectra, error) {
|
||||
return u.finalityBranch, nil
|
||||
}
|
||||
|
||||
func (u *updateElectra) SyncAggregate() *pb.SyncAggregate {
|
||||
return u.p.SyncAggregate
|
||||
}
|
||||
|
||||
20
deps.bzl
20
deps.bzl
@@ -1931,8 +1931,8 @@ def prysm_deps():
|
||||
],
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "github.com/libp2p/go-libp2p",
|
||||
sum = "h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U=",
|
||||
version = "v0.36.2",
|
||||
sum = "h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g=",
|
||||
version = "v0.36.5",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_asn_util",
|
||||
@@ -2286,8 +2286,8 @@ def prysm_deps():
|
||||
go_repository(
|
||||
name = "com_github_multiformats_go_multiaddr_dns",
|
||||
importpath = "github.com/multiformats/go-multiaddr-dns",
|
||||
sum = "h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=",
|
||||
version = "v0.3.1",
|
||||
sum = "h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU=",
|
||||
version = "v0.4.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_multiformats_go_multiaddr_fmt",
|
||||
@@ -2814,8 +2814,8 @@ def prysm_deps():
|
||||
"gazelle:exclude tools.go",
|
||||
],
|
||||
importpath = "github.com/quic-go/qpack",
|
||||
sum = "h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=",
|
||||
version = "v0.4.0",
|
||||
sum = "h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=",
|
||||
version = "v0.5.1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_quic_go_quic_go",
|
||||
@@ -2824,14 +2824,14 @@ def prysm_deps():
|
||||
"gazelle:exclude tools.go",
|
||||
],
|
||||
importpath = "github.com/quic-go/quic-go",
|
||||
sum = "h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=",
|
||||
version = "v0.46.0",
|
||||
sum = "h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=",
|
||||
version = "v0.48.2",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_quic_go_webtransport_go",
|
||||
importpath = "github.com/quic-go/webtransport-go",
|
||||
sum = "h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=",
|
||||
version = "v0.8.0",
|
||||
sum = "h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=",
|
||||
version = "v0.8.1-0.20241018022711-4ac2c9250e66",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_r3labs_sse_v2",
|
||||
|
||||
10
go.mod
10
go.mod
@@ -42,7 +42,7 @@ require (
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213
|
||||
github.com/kr/pretty v0.3.1
|
||||
github.com/libp2p/go-libp2p v0.36.2
|
||||
github.com/libp2p/go-libp2p v0.36.5
|
||||
github.com/libp2p/go-libp2p-mplex v0.9.0
|
||||
github.com/libp2p/go-libp2p-pubsub v0.12.0
|
||||
github.com/libp2p/go-mplex v0.7.0
|
||||
@@ -199,7 +199,7 @@ require (
|
||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||
github.com/multiformats/go-base36 v0.2.0 // indirect
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
|
||||
github.com/multiformats/go-multiaddr-dns v0.4.0 // indirect
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
|
||||
github.com/multiformats/go-multibase v0.2.0 // indirect
|
||||
github.com/multiformats/go-multicodec v0.9.0 // indirect
|
||||
@@ -232,9 +232,9 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/quic-go v0.46.0 // indirect
|
||||
github.com/quic-go/webtransport-go v0.8.0 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.48.2 // indirect
|
||||
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
|
||||
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
|
||||
24
go.sum
24
go.sum
@@ -582,8 +582,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
|
||||
github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U=
|
||||
github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY=
|
||||
github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g=
|
||||
github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
|
||||
github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8=
|
||||
@@ -653,7 +653,6 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1f
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
|
||||
@@ -704,11 +703,10 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg
|
||||
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
|
||||
github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
|
||||
github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ=
|
||||
github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
|
||||
github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU=
|
||||
github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
|
||||
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||
@@ -720,7 +718,6 @@ github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7B
|
||||
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
||||
github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE=
|
||||
github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA=
|
||||
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
@@ -908,12 +905,12 @@ github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c h1:9PHRCuO
|
||||
github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c/go.mod h1:ZRws458tYHS/Zs936OQ6oCrL+Ict5O4Xpwve1UQ6C9M=
|
||||
github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294 h1:q9wE0ZZRdTUAAeyFP/w0SwBEnCqlVy2+on6X2/e+eAU=
|
||||
github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=
|
||||
github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
|
||||
github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=
|
||||
github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
|
||||
github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
|
||||
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
|
||||
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
|
||||
github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0=
|
||||
github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I=
|
||||
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
||||
@@ -1359,7 +1356,6 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
"""
|
||||
2019/09/08 -- Interop start script.
|
||||
This script is intended for dockerfile deployment for interop testing.
|
||||
This script is fragile and subject to break as flags change.
|
||||
Use at your own risk!
|
||||
|
||||
|
||||
Use with interop.Dockerfile from the workspace root:
|
||||
|
||||
docker build -f interop.Dockerfile .
|
||||
"""
|
||||
|
||||
# Flags
|
||||
IDENTITY="" # P2P private key
|
||||
PEERS="" # Comma separated list of peers
|
||||
GEN_STATE="" # filepath to ssz encoded state.
|
||||
PORT="8000" # port to serve p2p traffic
|
||||
RPCPORT="8001" # port to serve rpc traffic
|
||||
YAML_KEY_FILE="" # Path to yaml keyfile as defined here: https://github.com/ethereum/eth2.0-pm/tree/master/interop/mocked_start
|
||||
|
||||
# Constants
|
||||
BEACON_LOG_FILE="/tmp/beacon.log"
|
||||
VALIDATOR_LOG_FILE="/tmp/validator.log"
|
||||
|
||||
usage() {
|
||||
echo "--identity=<identity>"
|
||||
echo "--peer=<peer>"
|
||||
echo "--num-validators=<number>"
|
||||
echo "--gen-state=<file path>"
|
||||
echo "--port=<port number>"
|
||||
echo "--rpcport=<port number>"
|
||||
}
|
||||
|
||||
while [ "$1" != "" ];
|
||||
do
|
||||
PARAM=`echo $1 | awk -F= '{print $1}'`
|
||||
VALUE=`echo $1 | sed 's/^[^=]*=//g'`
|
||||
|
||||
case $PARAM in
|
||||
--identity)
|
||||
IDENTITY=$VALUE
|
||||
;;
|
||||
--peers)
|
||||
[ -z "$PEERS" ] && PEERS+=","
|
||||
PEERS+="$VALUE"
|
||||
;;
|
||||
--validator-keys)
|
||||
YAML_KEY_FILE=$VALUE
|
||||
;;
|
||||
--gen-state)
|
||||
GEN_STATE=$VALUE
|
||||
;;
|
||||
--port)
|
||||
PORT=$VALUE
|
||||
;;
|
||||
--rpcport)
|
||||
RPCPORT=$VALUE
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown parameter \"$PARAM\""
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
echo "Converting hex yaml keys to a format that Prysm understands"
|
||||
|
||||
# Expect YAML keys in hex encoded format. Convert this into the format the validator already understands.
|
||||
./convert-keys $YAML_KEY_FILE /tmp/keys.json
|
||||
|
||||
echo "Starting beacon chain and logging to $BEACON_LOG_FILE"
|
||||
|
||||
echo -n "$IDENTITY" > /tmp/id.key
|
||||
|
||||
|
||||
|
||||
BEACON_FLAGS="--bootstrap-node= \
|
||||
--deposit-contract=0xD775140349E6A5D12524C6ccc3d6A1d4519D4029 \
|
||||
--p2p-port=$PORT \
|
||||
--http-port=$RPCPORT \
|
||||
--peer=$PEERS \
|
||||
--interop-genesis-state=$GEN_STATE \
|
||||
--p2p-priv-key=/tmp/id.key \
|
||||
--log-file=$BEACON_LOG_FILE"
|
||||
|
||||
./beacon-chain $BEACON_FLAGS &
|
||||
|
||||
echo "Starting validator client and logging to $VALIDATOR_LOG_FILE"
|
||||
|
||||
VALIDATOR_FLAGS="--monitoring-port=9091 \
|
||||
--unencrypted-keys /tmp/keys.json \
|
||||
--log-file=$VALIDATOR_LOG_FILE
|
||||
|
||||
./validator- $VALIDATOR_FLAGS &
|
||||
|
||||
@@ -172,6 +172,7 @@ ssz_electra_objs = [
|
||||
"SignedBeaconBlockElectra",
|
||||
"SignedBlindedBeaconBlockElectra",
|
||||
"SignedConsolidation",
|
||||
"SingleAttestation",
|
||||
]
|
||||
|
||||
ssz_fulu_objs = [
|
||||
|
||||
385
proto/prysm/v1alpha1/attestation.pb.go
generated
385
proto/prysm/v1alpha1/attestation.pb.go
generated
@@ -158,6 +158,77 @@ func (x *AttestationElectra) GetCommitteeBits() github_com_prysmaticlabs_go_bitf
|
||||
return github_com_prysmaticlabs_go_bitfield.Bitvector64(nil)
|
||||
}
|
||||
|
||||
type SingleAttestation struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
CommitteeId github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.CommitteeIndex `protobuf:"varint,1,opt,name=committee_id,json=committeeId,proto3" json:"committee_id,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.CommitteeIndex"`
|
||||
AttesterIndex github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex `protobuf:"varint,2,opt,name=attester_index,json=attesterIndex,proto3" json:"attester_index,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.ValidatorIndex"`
|
||||
Data *AttestationData `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
|
||||
Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty" ssz-size:"96"`
|
||||
}
|
||||
|
||||
func (x *SingleAttestation) Reset() {
|
||||
*x = SingleAttestation{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SingleAttestation) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SingleAttestation) ProtoMessage() {}
|
||||
|
||||
func (x *SingleAttestation) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_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 SingleAttestation.ProtoReflect.Descriptor instead.
|
||||
func (*SingleAttestation) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *SingleAttestation) GetCommitteeId() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.CommitteeIndex {
|
||||
if x != nil {
|
||||
return x.CommitteeId
|
||||
}
|
||||
return github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.CommitteeIndex(0)
|
||||
}
|
||||
|
||||
func (x *SingleAttestation) GetAttesterIndex() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex {
|
||||
if x != nil {
|
||||
return x.AttesterIndex
|
||||
}
|
||||
return github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex(0)
|
||||
}
|
||||
|
||||
func (x *SingleAttestation) GetData() *AttestationData {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SingleAttestation) GetSignature() []byte {
|
||||
if x != nil {
|
||||
return x.Signature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AggregateAttestationAndProof struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -171,7 +242,7 @@ type AggregateAttestationAndProof struct {
|
||||
func (x *AggregateAttestationAndProof) Reset() {
|
||||
*x = AggregateAttestationAndProof{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[2]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -184,7 +255,7 @@ func (x *AggregateAttestationAndProof) String() string {
|
||||
func (*AggregateAttestationAndProof) ProtoMessage() {}
|
||||
|
||||
func (x *AggregateAttestationAndProof) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[2]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -197,7 +268,7 @@ func (x *AggregateAttestationAndProof) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use AggregateAttestationAndProof.ProtoReflect.Descriptor instead.
|
||||
func (*AggregateAttestationAndProof) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{2}
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *AggregateAttestationAndProof) GetAggregatorIndex() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex {
|
||||
@@ -234,7 +305,7 @@ type AggregateAttestationAndProofElectra struct {
|
||||
func (x *AggregateAttestationAndProofElectra) Reset() {
|
||||
*x = AggregateAttestationAndProofElectra{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[3]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -247,7 +318,7 @@ func (x *AggregateAttestationAndProofElectra) String() string {
|
||||
func (*AggregateAttestationAndProofElectra) ProtoMessage() {}
|
||||
|
||||
func (x *AggregateAttestationAndProofElectra) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[3]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -260,7 +331,7 @@ func (x *AggregateAttestationAndProofElectra) ProtoReflect() protoreflect.Messag
|
||||
|
||||
// Deprecated: Use AggregateAttestationAndProofElectra.ProtoReflect.Descriptor instead.
|
||||
func (*AggregateAttestationAndProofElectra) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{3}
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *AggregateAttestationAndProofElectra) GetAggregatorIndex() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex {
|
||||
@@ -296,7 +367,7 @@ type SignedAggregateAttestationAndProof struct {
|
||||
func (x *SignedAggregateAttestationAndProof) Reset() {
|
||||
*x = SignedAggregateAttestationAndProof{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[4]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -309,7 +380,7 @@ func (x *SignedAggregateAttestationAndProof) String() string {
|
||||
func (*SignedAggregateAttestationAndProof) ProtoMessage() {}
|
||||
|
||||
func (x *SignedAggregateAttestationAndProof) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[4]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -322,7 +393,7 @@ func (x *SignedAggregateAttestationAndProof) ProtoReflect() protoreflect.Message
|
||||
|
||||
// Deprecated: Use SignedAggregateAttestationAndProof.ProtoReflect.Descriptor instead.
|
||||
func (*SignedAggregateAttestationAndProof) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{4}
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *SignedAggregateAttestationAndProof) GetMessage() *AggregateAttestationAndProof {
|
||||
@@ -351,7 +422,7 @@ type SignedAggregateAttestationAndProofElectra struct {
|
||||
func (x *SignedAggregateAttestationAndProofElectra) Reset() {
|
||||
*x = SignedAggregateAttestationAndProofElectra{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[5]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -364,7 +435,7 @@ func (x *SignedAggregateAttestationAndProofElectra) String() string {
|
||||
func (*SignedAggregateAttestationAndProofElectra) ProtoMessage() {}
|
||||
|
||||
func (x *SignedAggregateAttestationAndProofElectra) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[5]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -377,7 +448,7 @@ func (x *SignedAggregateAttestationAndProofElectra) ProtoReflect() protoreflect.
|
||||
|
||||
// Deprecated: Use SignedAggregateAttestationAndProofElectra.ProtoReflect.Descriptor instead.
|
||||
func (*SignedAggregateAttestationAndProofElectra) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{5}
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *SignedAggregateAttestationAndProofElectra) GetMessage() *AggregateAttestationAndProofElectra {
|
||||
@@ -409,7 +480,7 @@ type AttestationData struct {
|
||||
func (x *AttestationData) Reset() {
|
||||
*x = AttestationData{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[6]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -422,7 +493,7 @@ func (x *AttestationData) String() string {
|
||||
func (*AttestationData) ProtoMessage() {}
|
||||
|
||||
func (x *AttestationData) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[6]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -435,7 +506,7 @@ func (x *AttestationData) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use AttestationData.ProtoReflect.Descriptor instead.
|
||||
func (*AttestationData) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{6}
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *AttestationData) GetSlot() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Slot {
|
||||
@@ -485,7 +556,7 @@ type Checkpoint struct {
|
||||
func (x *Checkpoint) Reset() {
|
||||
*x = Checkpoint{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[7]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -498,7 +569,7 @@ func (x *Checkpoint) String() string {
|
||||
func (*Checkpoint) ProtoMessage() {}
|
||||
|
||||
func (x *Checkpoint) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[7]
|
||||
mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -511,7 +582,7 @@ func (x *Checkpoint) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Checkpoint.ProtoReflect.Descriptor instead.
|
||||
func (*Checkpoint) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{7}
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *Checkpoint) GetEpoch() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Epoch {
|
||||
@@ -570,106 +641,128 @@ var file_proto_prysm_v1alpha1_attestation_proto_rawDesc = []byte{
|
||||
0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x67, 0x6f, 0x2d, 0x62, 0x69, 0x74,
|
||||
0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x42, 0x69, 0x74, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x36,
|
||||
0x34, 0x8a, 0xb5, 0x18, 0x01, 0x38, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
|
||||
0x65, 0x42, 0x69, 0x74, 0x73, 0x22, 0x8d, 0x02, 0x0a, 0x1c, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
|
||||
0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e,
|
||||
0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x7a, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67,
|
||||
0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
|
||||
0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 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, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75,
|
||||
0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76,
|
||||
0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x12, 0x40, 0x0a, 0x09, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 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, 0x41, 0x74,
|
||||
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x61, 0x67, 0x67, 0x72, 0x65,
|
||||
0x67, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a,
|
||||
0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x9b, 0x02, 0x0a, 0x23, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
|
||||
0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e,
|
||||
0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0x7a, 0x0a,
|
||||
0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 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, 0x35, 0x2f, 0x63,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70,
|
||||
0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
|
||||
0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67,
|
||||
0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x47, 0x0a, 0x09, 0x61, 0x67, 0x67,
|
||||
0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
|
||||
0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x09, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
|
||||
0x74, 0x65, 0x12, 0x2f, 0x0a, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
|
||||
0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
|
||||
0x02, 0x39, 0x36, 0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72,
|
||||
0x6f, 0x6f, 0x66, 0x22, 0x99, 0x01, 0x0a, 0x22, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67,
|
||||
0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x4d, 0x0a, 0x07, 0x6d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
|
||||
0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74,
|
||||
0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66,
|
||||
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5,
|
||||
0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22,
|
||||
0xa7, 0x01, 0x0a, 0x29, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
|
||||
0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e,
|
||||
0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0x54, 0x0a,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a,
|
||||
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
|
||||
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65,
|
||||
0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72,
|
||||
0x6f, 0x6f, 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x90, 0x03, 0x0a, 0x0f, 0x41, 0x74,
|
||||
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x59, 0x0a,
|
||||
0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18,
|
||||
0x41, 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, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70,
|
||||
0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c,
|
||||
0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x78, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x65, 0x42, 0x69, 0x74, 0x73, 0x22, 0xe1, 0x02, 0x0a, 0x11, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65,
|
||||
0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x72, 0x0a, 0x0c, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 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, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73,
|
||||
0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69,
|
||||
0x76, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x12, 0x32, 0x0a, 0x11, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a,
|
||||
0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 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, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x12, 0x39, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x21, 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, 0x65, 0x63, 0x6b, 0x70,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x86, 0x01, 0x0a,
|
||||
0x0a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x05, 0x65,
|
||||
0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 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,
|
||||
0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65,
|
||||
0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f,
|
||||
0x63, 0x68, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x1a, 0x0a, 0x04, 0x72, 0x6f, 0x6f,
|
||||
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52,
|
||||
0x04, 0x72, 0x6f, 0x6f, 0x74, 0x42, 0x9b, 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, 0x10, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 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, 0x35, 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, 0x76, 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,
|
||||
0x65, 0x78, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x64, 0x12,
|
||||
0x76, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 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, 0x35, 0x2f, 0x63,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70,
|
||||
0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
|
||||
0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74,
|
||||
0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x3a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
|
||||
0x03, 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, 0x41, 0x74,
|
||||
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64,
|
||||
0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x8d, 0x02, 0x0a, 0x1c, 0x41, 0x67,
|
||||
0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x7a, 0x0a, 0x10, 0x61, 0x67,
|
||||
0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 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, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d,
|
||||
0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
|
||||
0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f,
|
||||
0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x40, 0x0a, 0x09, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67,
|
||||
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, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x61,
|
||||
0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x0f, 0x73, 0x65, 0x6c, 0x65,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x9b, 0x02, 0x0a, 0x23, 0x41, 0x67,
|
||||
0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72,
|
||||
0x61, 0x12, 0x7a, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f,
|
||||
0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18,
|
||||
0x4b, 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, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70,
|
||||
0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61,
|
||||
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0f, 0x61, 0x67,
|
||||
0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x47, 0x0a,
|
||||
0x09, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
|
||||
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x09, 0x61, 0x67, 0x67,
|
||||
0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42,
|
||||
0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x99, 0x01, 0x0a, 0x22, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73,
|
||||
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x4d,
|
||||
0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
||||
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74,
|
||||
0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a,
|
||||
0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x29, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67,
|
||||
0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72,
|
||||
0x61, 0x12, 0x54, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65,
|
||||
0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41,
|
||||
0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x07,
|
||||
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61,
|
||||
0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02,
|
||||
0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x90, 0x03,
|
||||
0x0a, 0x0f, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74,
|
||||
0x61, 0x12, 0x59, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42,
|
||||
0x45, 0x82, 0xb5, 0x18, 0x41, 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, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73,
|
||||
0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65,
|
||||
0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x78, 0x0a, 0x0f,
|
||||
0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 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, 0x35, 0x2f, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
|
||||
0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
|
||||
0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x32, 0x0a, 0x11, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e,
|
||||
0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f,
|
||||
0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 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, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 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,
|
||||
0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x22, 0x86, 0x01, 0x0a, 0x0a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12,
|
||||
0x5c, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 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, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d,
|
||||
0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73,
|
||||
0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x1a, 0x0a,
|
||||
0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
|
||||
0x02, 0x33, 0x32, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x42, 0x9b, 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, 0x10, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61,
|
||||
0x74, 0x69, 0x6f, 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, 0x35, 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, 0x76, 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 (
|
||||
@@ -684,31 +777,33 @@ func file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP() []byte {
|
||||
return file_proto_prysm_v1alpha1_attestation_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_prysm_v1alpha1_attestation_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_proto_prysm_v1alpha1_attestation_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
var file_proto_prysm_v1alpha1_attestation_proto_goTypes = []interface{}{
|
||||
(*Attestation)(nil), // 0: ethereum.eth.v1alpha1.Attestation
|
||||
(*AttestationElectra)(nil), // 1: ethereum.eth.v1alpha1.AttestationElectra
|
||||
(*AggregateAttestationAndProof)(nil), // 2: ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
(*AggregateAttestationAndProofElectra)(nil), // 3: ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra
|
||||
(*SignedAggregateAttestationAndProof)(nil), // 4: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProof
|
||||
(*SignedAggregateAttestationAndProofElectra)(nil), // 5: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofElectra
|
||||
(*AttestationData)(nil), // 6: ethereum.eth.v1alpha1.AttestationData
|
||||
(*Checkpoint)(nil), // 7: ethereum.eth.v1alpha1.Checkpoint
|
||||
(*SingleAttestation)(nil), // 2: ethereum.eth.v1alpha1.SingleAttestation
|
||||
(*AggregateAttestationAndProof)(nil), // 3: ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
(*AggregateAttestationAndProofElectra)(nil), // 4: ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra
|
||||
(*SignedAggregateAttestationAndProof)(nil), // 5: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProof
|
||||
(*SignedAggregateAttestationAndProofElectra)(nil), // 6: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofElectra
|
||||
(*AttestationData)(nil), // 7: ethereum.eth.v1alpha1.AttestationData
|
||||
(*Checkpoint)(nil), // 8: ethereum.eth.v1alpha1.Checkpoint
|
||||
}
|
||||
var file_proto_prysm_v1alpha1_attestation_proto_depIdxs = []int32{
|
||||
6, // 0: ethereum.eth.v1alpha1.Attestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
6, // 1: ethereum.eth.v1alpha1.AttestationElectra.data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
0, // 2: ethereum.eth.v1alpha1.AggregateAttestationAndProof.aggregate:type_name -> ethereum.eth.v1alpha1.Attestation
|
||||
1, // 3: ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra.aggregate:type_name -> ethereum.eth.v1alpha1.AttestationElectra
|
||||
2, // 4: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProof.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
3, // 5: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofElectra.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra
|
||||
7, // 6: ethereum.eth.v1alpha1.AttestationData.source:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
7, // 7: ethereum.eth.v1alpha1.AttestationData.target:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
8, // [8:8] is the sub-list for method output_type
|
||||
8, // [8:8] is the sub-list for method input_type
|
||||
8, // [8:8] is the sub-list for extension type_name
|
||||
8, // [8:8] is the sub-list for extension extendee
|
||||
0, // [0:8] is the sub-list for field type_name
|
||||
7, // 0: ethereum.eth.v1alpha1.Attestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
7, // 1: ethereum.eth.v1alpha1.AttestationElectra.data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
7, // 2: ethereum.eth.v1alpha1.SingleAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
0, // 3: ethereum.eth.v1alpha1.AggregateAttestationAndProof.aggregate:type_name -> ethereum.eth.v1alpha1.Attestation
|
||||
1, // 4: ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra.aggregate:type_name -> ethereum.eth.v1alpha1.AttestationElectra
|
||||
3, // 5: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProof.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
4, // 6: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofElectra.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra
|
||||
8, // 7: ethereum.eth.v1alpha1.AttestationData.source:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
8, // 8: ethereum.eth.v1alpha1.AttestationData.target:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
9, // [9:9] is the sub-list for method output_type
|
||||
9, // [9:9] is the sub-list for method input_type
|
||||
9, // [9:9] is the sub-list for extension type_name
|
||||
9, // [9:9] is the sub-list for extension extendee
|
||||
0, // [0:9] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_prysm_v1alpha1_attestation_proto_init() }
|
||||
@@ -742,7 +837,7 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_attestation_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AggregateAttestationAndProof); i {
|
||||
switch v := v.(*SingleAttestation); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -754,7 +849,7 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_attestation_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AggregateAttestationAndProofElectra); i {
|
||||
switch v := v.(*AggregateAttestationAndProof); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -766,7 +861,7 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_attestation_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SignedAggregateAttestationAndProof); i {
|
||||
switch v := v.(*AggregateAttestationAndProofElectra); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -778,7 +873,7 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_attestation_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SignedAggregateAttestationAndProofElectra); i {
|
||||
switch v := v.(*SignedAggregateAttestationAndProof); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -790,7 +885,7 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_attestation_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AttestationData); i {
|
||||
switch v := v.(*SignedAggregateAttestationAndProofElectra); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -802,6 +897,18 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_attestation_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AttestationData); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_attestation_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Checkpoint); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -820,7 +927,7 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_prysm_v1alpha1_attestation_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 8,
|
||||
NumMessages: 9,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -49,6 +49,13 @@ message AttestationElectra {
|
||||
bytes committee_bits = 4 [(ethereum.eth.ext.ssz_size) = "committee_bits.size", (ethereum.eth.ext.cast_type) = "committee_bits.type"];
|
||||
}
|
||||
|
||||
message SingleAttestation {
|
||||
uint64 committee_id = 1 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.CommitteeIndex"];
|
||||
uint64 attester_index = 2 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.ValidatorIndex"];
|
||||
AttestationData data = 3;
|
||||
bytes signature = 4 [(ethereum.eth.ext.ssz_size) = "96"];
|
||||
}
|
||||
|
||||
message AggregateAttestationAndProof {
|
||||
// The aggregator index that submitted this aggregated attestation and proof.
|
||||
uint64 aggregator_index = 1 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.ValidatorIndex"];
|
||||
|
||||
@@ -113,6 +113,9 @@ func AttestingIndices(att ethpb.Att, committees ...[]primitives.ValidatorIndex)
|
||||
committeeAttesters = append(committeeAttesters, uint64(vi))
|
||||
}
|
||||
}
|
||||
if len(committeeAttesters) == 0 {
|
||||
return nil, fmt.Errorf("no attesting indices found in committee %v", c)
|
||||
}
|
||||
attesters = append(attesters, committeeAttesters...)
|
||||
committeeOffset += len(c)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: bce36d386a65c91018c9a1edaacd2ed0f09cc4dce59fdc5f014fbd9e05bfee77
|
||||
// Hash: 2e826c1b9ac62c64b47fcf15d0fe029e986c1afccd33e10a84f041ffd0c7f161
|
||||
package eth
|
||||
|
||||
import (
|
||||
@@ -157,6 +157,107 @@ func (a *AttestationElectra) HashTreeRootWith(hh *ssz.Hasher) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalSSZ ssz marshals the SingleAttestation object
|
||||
func (s *SingleAttestation) MarshalSSZ() ([]byte, error) {
|
||||
return ssz.MarshalSSZ(s)
|
||||
}
|
||||
|
||||
// MarshalSSZTo ssz marshals the SingleAttestation object to a target array
|
||||
func (s *SingleAttestation) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
||||
dst = buf
|
||||
|
||||
// Field (0) 'CommitteeId'
|
||||
dst = ssz.MarshalUint64(dst, uint64(s.CommitteeId))
|
||||
|
||||
// Field (1) 'AttesterIndex'
|
||||
dst = ssz.MarshalUint64(dst, uint64(s.AttesterIndex))
|
||||
|
||||
// Field (2) 'Data'
|
||||
if s.Data == nil {
|
||||
s.Data = new(AttestationData)
|
||||
}
|
||||
if dst, err = s.Data.MarshalSSZTo(dst); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Field (3) 'Signature'
|
||||
if size := len(s.Signature); size != 96 {
|
||||
err = ssz.ErrBytesLengthFn("--.Signature", size, 96)
|
||||
return
|
||||
}
|
||||
dst = append(dst, s.Signature...)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalSSZ ssz unmarshals the SingleAttestation object
|
||||
func (s *SingleAttestation) UnmarshalSSZ(buf []byte) error {
|
||||
var err error
|
||||
size := uint64(len(buf))
|
||||
if size != 240 {
|
||||
return ssz.ErrSize
|
||||
}
|
||||
|
||||
// Field (0) 'CommitteeId'
|
||||
s.CommitteeId = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.CommitteeIndex(ssz.UnmarshallUint64(buf[0:8]))
|
||||
|
||||
// Field (1) 'AttesterIndex'
|
||||
s.AttesterIndex = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex(ssz.UnmarshallUint64(buf[8:16]))
|
||||
|
||||
// Field (2) 'Data'
|
||||
if s.Data == nil {
|
||||
s.Data = new(AttestationData)
|
||||
}
|
||||
if err = s.Data.UnmarshalSSZ(buf[16:144]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Field (3) 'Signature'
|
||||
if cap(s.Signature) == 0 {
|
||||
s.Signature = make([]byte, 0, len(buf[144:240]))
|
||||
}
|
||||
s.Signature = append(s.Signature, buf[144:240]...)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// SizeSSZ returns the ssz encoded size in bytes for the SingleAttestation object
|
||||
func (s *SingleAttestation) SizeSSZ() (size int) {
|
||||
size = 240
|
||||
return
|
||||
}
|
||||
|
||||
// HashTreeRoot ssz hashes the SingleAttestation object
|
||||
func (s *SingleAttestation) HashTreeRoot() ([32]byte, error) {
|
||||
return ssz.HashWithDefaultHasher(s)
|
||||
}
|
||||
|
||||
// HashTreeRootWith ssz hashes the SingleAttestation object with a hasher
|
||||
func (s *SingleAttestation) HashTreeRootWith(hh *ssz.Hasher) (err error) {
|
||||
indx := hh.Index()
|
||||
|
||||
// Field (0) 'CommitteeId'
|
||||
hh.PutUint64(uint64(s.CommitteeId))
|
||||
|
||||
// Field (1) 'AttesterIndex'
|
||||
hh.PutUint64(uint64(s.AttesterIndex))
|
||||
|
||||
// Field (2) 'Data'
|
||||
if err = s.Data.HashTreeRootWith(hh); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Field (3) 'Signature'
|
||||
if size := len(s.Signature); size != 96 {
|
||||
err = ssz.ErrBytesLengthFn("--.Signature", size, 96)
|
||||
return
|
||||
}
|
||||
hh.PutBytes(s.Signature)
|
||||
|
||||
hh.Merkleize(indx)
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalSSZ ssz marshals the AggregateAttestationAndProofElectra object
|
||||
func (a *AggregateAttestationAndProofElectra) MarshalSSZ() ([]byte, error) {
|
||||
return ssz.MarshalSSZ(a)
|
||||
|
||||
@@ -342,7 +342,7 @@ func (s *PremineGenesisConfig) setFork(g state.BeaconState) error {
|
||||
case version.Deneb:
|
||||
pv, cv = params.BeaconConfig().CapellaForkVersion, params.BeaconConfig().DenebForkVersion
|
||||
case version.Electra:
|
||||
pv, cv = params.BeaconConfig().ElectraForkVersion, params.BeaconConfig().ElectraForkVersion
|
||||
pv, cv = params.BeaconConfig().DenebForkVersion, params.BeaconConfig().ElectraForkVersion
|
||||
default:
|
||||
return errUnsupportedVersion
|
||||
}
|
||||
@@ -665,8 +665,8 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error {
|
||||
BlockHash: gb.Hash().Bytes(),
|
||||
Transactions: make([][]byte, 0),
|
||||
Withdrawals: make([]*enginev1.Withdrawal, 0),
|
||||
ExcessBlobGas: *gb.ExcessBlobGas(),
|
||||
BlobGasUsed: *gb.BlobGasUsed(),
|
||||
ExcessBlobGas: unwrapUint64Ptr(gb.ExcessBlobGas()),
|
||||
BlobGasUsed: unwrapUint64Ptr(gb.BlobGasUsed()),
|
||||
}
|
||||
wep, err := blocks.WrappedExecutionPayloadDeneb(payload)
|
||||
if err != nil {
|
||||
@@ -718,6 +718,13 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error {
|
||||
return g.SetLatestExecutionPayloadHeader(ed)
|
||||
}
|
||||
|
||||
func unwrapUint64Ptr(u *uint64) uint64 {
|
||||
if u == nil {
|
||||
return 0
|
||||
}
|
||||
return *u
|
||||
}
|
||||
|
||||
func nZeroRoots(n uint64) [][]byte {
|
||||
roots := make([][]byte, n)
|
||||
zh := params.BeaconConfig().ZeroHash[:]
|
||||
|
||||
@@ -275,7 +275,6 @@ func (node *BeaconNode) Start(ctx context.Context) error {
|
||||
"--" + cmdshared.ValidatorMonitorIndicesFlag.Name + "=2",
|
||||
"--" + cmdshared.ForceClearDB.Name,
|
||||
"--" + cmdshared.AcceptTosFlag.Name,
|
||||
"--" + features.EnableQUIC.Name,
|
||||
}
|
||||
if config.UsePprof {
|
||||
args = append(args, "--pprof", fmt.Sprintf("--pprofport=%d", e2e.TestParams.Ports.PrysmBeaconNodePprofPort+index))
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/verification"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -25,6 +27,13 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/util"
|
||||
)
|
||||
|
||||
// These are proposer boost spec tests that assume the clock starts 3 seconds into the slot.
|
||||
// Example: Tick is 51, which corresponds to 3 seconds into slot 4.
|
||||
var proposerBoostTests3s = []string{
|
||||
"proposer_boost_is_first_block",
|
||||
"proposer_boost",
|
||||
}
|
||||
|
||||
func init() {
|
||||
transition.SkipSlotCache.Disable()
|
||||
}
|
||||
@@ -97,7 +106,18 @@ func runTest(t *testing.T, config string, fork int, basePath string) { // nolint
|
||||
|
||||
for _, step := range steps {
|
||||
if step.Tick != nil {
|
||||
builder.Tick(t, int64(*step.Tick))
|
||||
tick := int64(*step.Tick)
|
||||
// If the test is for proposer boost starting 3 seconds into the slot and the tick aligns with this,
|
||||
// we provide an additional second buffer. Instead of starting 3 seconds into the slot, we start 2 seconds in to avoid missing the proposer boost.
|
||||
// A 1-second buffer has proven insufficient during parallel spec test runs, as the likelihood of missing the proposer boost increases significantly,
|
||||
// often extending to 4 seconds. Starting 2 seconds into the slot ensures close to a 100% pass rate.
|
||||
if slices.Contains(proposerBoostTests3s, folder.Name()) {
|
||||
deadline := params.BeaconConfig().SecondsPerSlot / params.BeaconConfig().IntervalsPerSlot
|
||||
if uint64(tick)%params.BeaconConfig().SecondsPerSlot == deadline-1 {
|
||||
tick--
|
||||
}
|
||||
}
|
||||
builder.Tick(t, tick)
|
||||
}
|
||||
var beaconBlock interfaces.ReadOnlySignedBeaconBlock
|
||||
if step.Block != nil {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user