mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-02-01 08:35:24 -05:00
Compare commits
35 Commits
e2e-debugg
...
checkpoint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77f96f76b5 | ||
|
|
6516e95ebc | ||
|
|
4790430fb7 | ||
|
|
2daded945c | ||
|
|
e53d9dfc15 | ||
|
|
83e29dcabb | ||
|
|
a16afff75a | ||
|
|
fb8ac308ec | ||
|
|
9341b7d167 | ||
|
|
386e747c74 | ||
|
|
44f4fea2e3 | ||
|
|
d99aae264a | ||
|
|
82fbf93720 | ||
|
|
a8ddf23e6a | ||
|
|
6b5e042865 | ||
|
|
78926f0729 | ||
|
|
cbab0b63df | ||
|
|
5c838747e7 | ||
|
|
86ca70d84f | ||
|
|
564d0213fc | ||
|
|
0ec276b7c2 | ||
|
|
a18cf8d59b | ||
|
|
784a349fff | ||
|
|
c658c08f8f | ||
|
|
213031b4b6 | ||
|
|
a3f0a53f02 | ||
|
|
154b451754 | ||
|
|
eb6ad5266c | ||
|
|
d817099f72 | ||
|
|
c38844a891 | ||
|
|
c0384ec30a | ||
|
|
5d66e57d65 | ||
|
|
2186ec4671 | ||
|
|
c712a40a22 | ||
|
|
1ee09fc88c |
42
api/client/beacon/BUILD.bazel
Normal file
42
api/client/beacon/BUILD.bazel
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"checkpoint.go",
|
||||||
|
"client.go",
|
||||||
|
"doc.go",
|
||||||
|
"errors.go",
|
||||||
|
],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/api/client/beacon",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//beacon-chain/core/helpers:go_default_library",
|
||||||
|
"//beacon-chain/rpc/apimiddleware:go_default_library",
|
||||||
|
"//beacon-chain/state:go_default_library",
|
||||||
|
"//config/params:go_default_library",
|
||||||
|
"//encoding/bytesutil:go_default_library",
|
||||||
|
"//proto/detect:go_default_library",
|
||||||
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
|
"//proto/prysm/v1alpha1/block: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_prysmaticlabs_eth2_types//:go_default_library",
|
||||||
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
|
"@org_golang_x_mod//semver:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = [
|
||||||
|
"checkpoint_test.go",
|
||||||
|
"client_test.go",
|
||||||
|
],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//testing/require:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
279
api/client/beacon/checkpoint.go
Normal file
279
api/client/beacon/checkpoint.go
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
package beacon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/proto/detect"
|
||||||
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
||||||
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WeakSubjectivityData represents the state root, block root and epoch of the BeaconState + SignedBeaconBlock
|
||||||
|
// that falls at the beginning of the current weak subjectivity period. These values can be used to construct
|
||||||
|
// a weak subjectivity checkpoint, or to download a BeaconState+SignedBeaconBlock pair that can be used to bootstrap
|
||||||
|
// a new Beacon Node using Checkpoint Sync.
|
||||||
|
type WeakSubjectivityData struct {
|
||||||
|
BlockRoot [32]byte
|
||||||
|
StateRoot [32]byte
|
||||||
|
Epoch types.Epoch
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckpointString returns the standard string representation of a Checkpoint for the block root and epoch to which the
|
||||||
|
// WeakSubjectivityData value refers.
|
||||||
|
// The format is a a hex-encoded block root, followed by the epoch of the block, separated by a colon. For example:
|
||||||
|
// "0x1c35540cac127315fabb6bf29181f2ae0de1a3fc909d2e76ba771e61312cc49a:74888"
|
||||||
|
func (wsd *WeakSubjectivityData) CheckpointString() string {
|
||||||
|
return fmt.Sprintf("%#x:%d", wsd.BlockRoot, wsd.Epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OriginData represents the BeaconState and SignedBeaconBlock necessary to start an empty Beacon Node
|
||||||
|
// using Checkpoint Sync.
|
||||||
|
type OriginData struct {
|
||||||
|
wsd *WeakSubjectivityData
|
||||||
|
sb []byte
|
||||||
|
bb []byte
|
||||||
|
st state.BeaconState
|
||||||
|
b block.SignedBeaconBlock
|
||||||
|
cf *detect.ConfigFork
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeakSubjectivity returns the WeakSubjectivityData determined by DownloadOriginData.
|
||||||
|
func (od *OriginData) WeakSubjectivity() *WeakSubjectivityData {
|
||||||
|
return od.wsd
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveBlock saves the downloaded block to a unique file in the given path.
|
||||||
|
// For readability and collision avoidance, the file name includes: type, config name, slot and root
|
||||||
|
func (od *OriginData) SaveBlock(dir string) (string, error) {
|
||||||
|
statePath := path.Join(dir, fname("state", od.cf, od.st.Slot(), od.wsd.BlockRoot))
|
||||||
|
return statePath, os.WriteFile(statePath, od.sb, 0600)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveState saves the downloaded state to a unique file in the given path.
|
||||||
|
// For readability and collision avoidance, the file name includes: type, config name, slot and root
|
||||||
|
func (od *OriginData) SaveState(dir string) (string, error) {
|
||||||
|
statePath := path.Join(dir, fname("state", od.cf, od.st.Slot(), od.wsd.StateRoot))
|
||||||
|
return statePath, os.WriteFile(statePath, od.sb, 0600)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateBytes returns the ssz-encoded bytes of the downloaded BeaconState value.
|
||||||
|
func (od *OriginData) StateBytes() []byte {
|
||||||
|
return od.sb
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockBytes returns the ssz-encoded bytes of the downloaded SignedBeaconBlock value.
|
||||||
|
func (od *OriginData) BlockBytes() []byte {
|
||||||
|
return od.bb
|
||||||
|
}
|
||||||
|
|
||||||
|
func fname(prefix string, cf *detect.ConfigFork, slot types.Slot, root [32]byte) string {
|
||||||
|
return fmt.Sprintf("%s_%s_%s_%d-%#x.ssz", prefix, cf.ConfigName.String(), cf.Fork.String(), slot, root)
|
||||||
|
}
|
||||||
|
|
||||||
|
// this method downloads the head state, which can be used to find the correct chain config
|
||||||
|
// and use prysm's helper methods to compute the latest weak subjectivity epoch.
|
||||||
|
func getWeakSubjectivityEpochFromHead(ctx context.Context, client *Client) (types.Epoch, error) {
|
||||||
|
headBytes, err := client.GetState(ctx, IdHead)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
cf, err := detect.ByState(headBytes)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "error detecting chain config for beacon state")
|
||||||
|
}
|
||||||
|
log.Printf("detected supported config in remote head state, name=%s, fork=%s", cf.ConfigName.String(), cf.Fork)
|
||||||
|
headState, err := cf.UnmarshalBeaconState(headBytes)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "error unmarshaling state to correct version")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LatestWeakSubjectivityEpoch uses package-level vars from the params package, so we need to override it
|
||||||
|
params.OverrideBeaconConfig(cf.Config)
|
||||||
|
epoch, err := helpers.LatestWeakSubjectivityEpoch(ctx, headState)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "error computing the weak subjectivity epoch from head state")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("(computed client-side) weak subjectivity epoch = %d", epoch)
|
||||||
|
return epoch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
prysmMinimumVersion = "v2.0.7"
|
||||||
|
prysmImplementationName = "Prysm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrUnsupportedPrysmCheckpointVersion indicates remote beacon node can't be used for checkpoint retrieval.
|
||||||
|
var ErrUnsupportedPrysmCheckpointVersion = errors.New("node does not meet minimum version requirements for checkpoint retrieval")
|
||||||
|
|
||||||
|
// for older endpoints or clients that do not support the weak_subjectivity api method (only prysm at release time)
|
||||||
|
// we gather the necessary data for a checkpoint sync by:
|
||||||
|
// - inspecting the remote server's head state and computing the weak subjectivity epoch locally
|
||||||
|
// - requesting the state at the first slot of the epoch
|
||||||
|
// - using hash_tree_root(state.latest_block_header) to compute the block the state integrates
|
||||||
|
// - requesting that block by its root
|
||||||
|
func downloadBackwardsCompatible(ctx context.Context, client *Client) (*OriginData, error) {
|
||||||
|
log.Print("falling back to generic checkpoint derivation, weak_subjectivity API not supported by server")
|
||||||
|
nv, err := client.GetNodeVersion(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unable to proceed with fallback method without confirming node version")
|
||||||
|
}
|
||||||
|
if nv.implementation == prysmImplementationName && semver.Compare(nv.semver, prysmMinimumVersion) < 0 {
|
||||||
|
return nil, errors.Wrapf(ErrUnsupportedPrysmCheckpointVersion, "%s < minimum (%s)", nv.semver, prysmMinimumVersion)
|
||||||
|
}
|
||||||
|
epoch, err := getWeakSubjectivityEpochFromHead(ctx, client)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error computing weak subjectivity epoch via head state inspection")
|
||||||
|
}
|
||||||
|
|
||||||
|
// use first slot of the epoch for the state slot
|
||||||
|
slot, err := slots.EpochStart(epoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "Error computing first slot of epoch=%d", epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("requesting checkpoint state at slot %d", slot)
|
||||||
|
// get the state at the first slot of the epoch
|
||||||
|
stateBytes, err := client.GetState(ctx, IdFromSlot(slot))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to request state by slot from api, slot=%d", slot)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigFork is used to unmarshal the BeaconState so we can read the block root in latest_block_header
|
||||||
|
cf, err := detect.ByState(stateBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error detecting chain config for beacon state")
|
||||||
|
}
|
||||||
|
log.Printf("detected supported config in checkpoint state, name=%s, fork=%s", cf.ConfigName.String(), cf.Fork)
|
||||||
|
|
||||||
|
st, err := cf.UnmarshalBeaconState(stateBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error using detected config fork to unmarshal state bytes")
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute state and block roots
|
||||||
|
stateRoot, err := st.HashTreeRoot(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error computing hash_tree_root of state")
|
||||||
|
}
|
||||||
|
|
||||||
|
header := st.LatestBlockHeader()
|
||||||
|
header.StateRoot = stateRoot[:]
|
||||||
|
computedBlockRoot, err := header.HashTreeRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error while computing block root using state data")
|
||||||
|
}
|
||||||
|
|
||||||
|
blockBytes, err := client.GetBlock(ctx, IdFromRoot(computedBlockRoot))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error requesting block by slot = %d", slot)
|
||||||
|
}
|
||||||
|
block, err := cf.UnmarshalBeaconBlock(blockBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unable to unmarshal block to a supported type using the detected fork schedule")
|
||||||
|
}
|
||||||
|
blockRoot, err := block.Block().HashTreeRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error computing hash_tree_root for block obtained via root")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("BeaconState slot=%d, Block slot=%d", st.Slot(), block.Block().Slot())
|
||||||
|
log.Printf("BeaconState htr=%#xd, Block state_root=%#x", stateRoot, block.Block().StateRoot())
|
||||||
|
log.Printf("BeaconBlock root computed from state=%#x, Block HTR=%#x", computedBlockRoot, blockRoot)
|
||||||
|
|
||||||
|
return &OriginData{
|
||||||
|
wsd: &WeakSubjectivityData{
|
||||||
|
BlockRoot: blockRoot,
|
||||||
|
StateRoot: stateRoot,
|
||||||
|
Epoch: epoch,
|
||||||
|
},
|
||||||
|
st: st,
|
||||||
|
sb: stateBytes,
|
||||||
|
b: block,
|
||||||
|
bb: blockBytes,
|
||||||
|
cf: cf,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DownloadOriginData attempts to use the proposed weak_subjectivity beacon node api
|
||||||
|
// to obtain the weak_subjectivity metadata (epoch, block_root, state_root) needed to sync
|
||||||
|
// a beacon node from the canonical weak subjectivity checkpoint. As this is a proposed API
|
||||||
|
// that will only be supported by prysm at first, in the event of a 404 we fallback to using a
|
||||||
|
// different technique where we first download the head state which can be used to compute the
|
||||||
|
// weak subjectivity epoch on the client side.
|
||||||
|
func DownloadOriginData(ctx context.Context, client *Client) (*OriginData, error) {
|
||||||
|
ws, err := client.GetWeakSubjectivity(ctx)
|
||||||
|
if err != nil {
|
||||||
|
// a 404 is expected if querying an endpoint that doesn't support the weak subjectivity checkpoint api
|
||||||
|
if !errors.Is(err, ErrNotFound) {
|
||||||
|
return nil, errors.Wrap(err, "unexpected API response for prysm-only weak subjectivity checkpoint API")
|
||||||
|
}
|
||||||
|
// ok so it's a 404, use the head state method
|
||||||
|
return downloadBackwardsCompatible(ctx, client)
|
||||||
|
}
|
||||||
|
log.Printf("server weak subjectivity checkpoint response - epoch=%d, block_root=%#x, state_root=%#x", ws.Epoch, ws.BlockRoot, ws.StateRoot)
|
||||||
|
|
||||||
|
// use first slot of the epoch for the block slot
|
||||||
|
slot, err := slots.EpochStart(ws.Epoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "Error computing first slot of epoch=%d", ws.Epoch)
|
||||||
|
}
|
||||||
|
log.Printf("requesting checkpoint state at slot %d", slot)
|
||||||
|
|
||||||
|
stateBytes, err := client.GetState(ctx, IdFromSlot(slot))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to request state by slot from api, slot=%d", slot)
|
||||||
|
}
|
||||||
|
cf, err := detect.ByState(stateBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error detecting chain config for beacon state")
|
||||||
|
}
|
||||||
|
log.Printf("detected supported config in checkpoint state, name=%s, fork=%s", cf.ConfigName.String(), cf.Fork)
|
||||||
|
|
||||||
|
state, err := cf.UnmarshalBeaconState(stateBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error using detected config fork to unmarshal state bytes")
|
||||||
|
}
|
||||||
|
stateRoot, err := state.HashTreeRoot(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to compute htr for state at slot=%d", slot)
|
||||||
|
}
|
||||||
|
|
||||||
|
blockRoot, err := state.LatestBlockHeader().HashTreeRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error computing hash_tree_root of latest_block_header")
|
||||||
|
}
|
||||||
|
blockBytes, err := client.GetBlock(ctx, IdFromRoot(ws.BlockRoot))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error requesting block by slot = %d", slot)
|
||||||
|
}
|
||||||
|
block, err := cf.UnmarshalBeaconBlock(blockBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unable to unmarshal block to a supported type using the detected fork schedule")
|
||||||
|
}
|
||||||
|
realBlockRoot, err := block.Block().HashTreeRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error computing hash_tree_root of retrieved block")
|
||||||
|
}
|
||||||
|
log.Printf("BeaconState slot=%d, Block slot=%d", state.Slot(), block.Block().Slot())
|
||||||
|
log.Printf("BeaconState htr=%#xd, Block state_root=%#x", stateRoot, block.Block().StateRoot())
|
||||||
|
log.Printf("BeaconState latest_block_header htr=%#xd, block htr=%#x", blockRoot, realBlockRoot)
|
||||||
|
return &OriginData{
|
||||||
|
wsd: ws,
|
||||||
|
st: state,
|
||||||
|
b: block,
|
||||||
|
sb: stateBytes,
|
||||||
|
bb: blockBytes,
|
||||||
|
cf: cf,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
84
api/client/beacon/checkpoint_test.go
Normal file
84
api/client/beacon/checkpoint_test.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package beacon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testRT struct {
|
||||||
|
rt func(*http.Request) (*http.Response, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rt *testRT) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
if rt.rt != nil {
|
||||||
|
return rt.rt(req)
|
||||||
|
}
|
||||||
|
return nil, errors.New("RoundTripper not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ http.RoundTripper = &testRT{}
|
||||||
|
|
||||||
|
func marshalToEnvelope(val interface{}) ([]byte, error) {
|
||||||
|
raw, err := json.Marshal(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error marsaling value to place in data envelope")
|
||||||
|
}
|
||||||
|
env := struct {
|
||||||
|
Data json.RawMessage `json:"data"`
|
||||||
|
}{
|
||||||
|
Data: raw,
|
||||||
|
}
|
||||||
|
return json.Marshal(env)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMarshalToEnvelope(t *testing.T) {
|
||||||
|
d := struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
}{
|
||||||
|
Version: "Prysm/v2.0.5 (linux amd64)",
|
||||||
|
}
|
||||||
|
encoded, err := marshalToEnvelope(d)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := `{"data":{"version":"Prysm/v2.0.5 (linux amd64)"}}`
|
||||||
|
require.Equal(t, expected, string(encoded))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFallbackVersionCheck(t *testing.T) {
|
||||||
|
c := &Client{
|
||||||
|
hc: &http.Client{},
|
||||||
|
host: "localhost:3500",
|
||||||
|
scheme: "http",
|
||||||
|
}
|
||||||
|
c.hc.Transport = &testRT{rt: func(req *http.Request) (*http.Response, error) {
|
||||||
|
res := &http.Response{Request: req}
|
||||||
|
switch req.URL.Path {
|
||||||
|
case get_node_version_path:
|
||||||
|
res.StatusCode = http.StatusOK
|
||||||
|
b := bytes.NewBuffer(nil)
|
||||||
|
d := struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
}{
|
||||||
|
Version: "Prysm/v2.0.5 (linux amd64)",
|
||||||
|
}
|
||||||
|
encoded, err := marshalToEnvelope(d)
|
||||||
|
require.NoError(t, err)
|
||||||
|
b.Write(encoded)
|
||||||
|
res.Body = io.NopCloser(b)
|
||||||
|
case get_weak_subjectivity_path:
|
||||||
|
res.StatusCode = http.StatusNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
_, err := DownloadOriginData(ctx, c)
|
||||||
|
require.ErrorIs(t, err, ErrUnsupportedPrysmCheckpointVersion)
|
||||||
|
}
|
||||||
418
api/client/beacon/client.go
Normal file
418
api/client/beacon/client.go
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
package beacon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/apimiddleware"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
get_signed_block_path = "/eth/v2/beacon/blocks"
|
||||||
|
get_block_root_path = "/eth/v1/beacon/blocks/{{.Id}}/root"
|
||||||
|
get_fork_for_state_path = "/eth/v1/beacon/states/{{.Id}}/fork"
|
||||||
|
get_weak_subjectivity_path = "/eth/v1/beacon/weak_subjectivity"
|
||||||
|
get_fork_schedule_path = "/eth/v1/config/fork_schedule"
|
||||||
|
get_state_path = "/eth/v2/debug/beacon/states"
|
||||||
|
get_node_version_path = "/eth/v1/node/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StateOrBlockId represents the block_id / state_id parameters that several of the Eth Beacon API methods accept.
|
||||||
|
// StateOrBlockId constants are defined for named identifiers, and helper methods are provided
|
||||||
|
// for slot and root identifiers. Example text from the Eth Beacon Node API documentation:
|
||||||
|
//
|
||||||
|
// "Block identifier can be one of: "head" (canonical head in node's view), "genesis", "finalized",
|
||||||
|
// <slot>, <hex encoded blockRoot with 0x prefix>."
|
||||||
|
type StateOrBlockId string
|
||||||
|
|
||||||
|
const (
|
||||||
|
IdFinalized StateOrBlockId = "finalized"
|
||||||
|
IdGenesis StateOrBlockId = "genesis"
|
||||||
|
IdHead StateOrBlockId = "head"
|
||||||
|
IdJustified StateOrBlockId = "finalized"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IdFromRoot encodes a block root in the format expected by the API in places where a root can be used to identify
|
||||||
|
// a BeaconState or SignedBeaconBlock.
|
||||||
|
func IdFromRoot(r [32]byte) StateOrBlockId {
|
||||||
|
return StateOrBlockId(fmt.Sprintf("%#x", r))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IdFromRoot encodes a Slot in the format expected by the API in places where a slot can be used to identify
|
||||||
|
// a BeaconState or SignedBeaconBlock.
|
||||||
|
func IdFromSlot(s types.Slot) StateOrBlockId {
|
||||||
|
return StateOrBlockId(strconv.FormatUint(uint64(s), 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
// idTemplate is used to create template functions that can interpolate StateOrBlockId values.
|
||||||
|
func idTemplate(ts string) func(StateOrBlockId) string {
|
||||||
|
t := template.Must(template.New("").Parse(ts))
|
||||||
|
f := func(id StateOrBlockId) string {
|
||||||
|
b := bytes.NewBuffer(nil)
|
||||||
|
err := t.Execute(b, struct{ Id string }{Id: string(id)})
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("invalid idTemplate: %s", ts))
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
// run the template to ensure that it is valid
|
||||||
|
// this should happen load time (using package scoped vars) to ensure runtime errors aren't possible
|
||||||
|
_ = f(IdGenesis)
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientOpt is a functional option for the Client type (http.Client wrapper)
|
||||||
|
type ClientOpt func(*Client)
|
||||||
|
|
||||||
|
// WithTimeout sets the .Timeout attribute of the wrapped http.Client.
|
||||||
|
func WithTimeout(timeout time.Duration) ClientOpt {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.hc.Timeout = timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client provides a collection of helper methods for calling the Eth Beacon Node API endpoints.
|
||||||
|
type Client struct {
|
||||||
|
hc *http.Client
|
||||||
|
host string
|
||||||
|
scheme string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient constructs a new client with the provided options (ex WithTimeout).
|
||||||
|
// `host` is the base host + port used to construct request urls. This value can be
|
||||||
|
// a URL string, or NewClient will assume an http endpoint if just `host:port` is used.
|
||||||
|
func NewClient(host string, opts ...ClientOpt) (*Client, error) {
|
||||||
|
host, err := validHostname(host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c := &Client{
|
||||||
|
hc: &http.Client{},
|
||||||
|
scheme: "http",
|
||||||
|
host: host,
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(c)
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validHostname(h string) (string, error) {
|
||||||
|
// try to parse as url (being permissive)
|
||||||
|
u, err := url.Parse(h)
|
||||||
|
if err == nil && u.Host != "" {
|
||||||
|
return u.Host, nil
|
||||||
|
}
|
||||||
|
// try to parse as host:port
|
||||||
|
host, port, err := net.SplitHostPort(h)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s:%s", host, port), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) urlForPath(methodPath string) *url.URL {
|
||||||
|
u := &url.URL{
|
||||||
|
Scheme: c.scheme,
|
||||||
|
Host: c.host,
|
||||||
|
}
|
||||||
|
u.Path = path.Join(u.Path, methodPath)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
type reqOption func(*http.Request)
|
||||||
|
|
||||||
|
func withSSZEncoding() reqOption {
|
||||||
|
return func(req *http.Request) {
|
||||||
|
req.Header.Set("Accept", "application/octet-stream")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get is a generic, opinionated GET function to reduce boilerplate amongst the getters in this package.
|
||||||
|
func (c *Client) get(ctx context.Context, path string, opts ...reqOption) ([]byte, error) {
|
||||||
|
u := c.urlForPath(path)
|
||||||
|
log.Printf("requesting %s", u.String())
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(req)
|
||||||
|
}
|
||||||
|
r, err := c.hc.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err = r.Body.Close()
|
||||||
|
}()
|
||||||
|
if r.StatusCode != http.StatusOK {
|
||||||
|
return nil, non200Err(r)
|
||||||
|
}
|
||||||
|
b, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error reading http response body from GetBlock")
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlock retrieves the SignedBeaconBlock for the given block id.
|
||||||
|
// Block identifier can be one of: "head" (canonical head in node's view), "genesis", "finalized",
|
||||||
|
// <slot>, <hex encoded blockRoot with 0x prefix>. Variables of type StateOrBlockId are exported by this package
|
||||||
|
// for the named identifiers.
|
||||||
|
// The return value contains the ssz-encoded bytes.
|
||||||
|
func (c *Client) GetBlock(ctx context.Context, blockId StateOrBlockId) ([]byte, error) {
|
||||||
|
blockPath := path.Join(get_signed_block_path, string(blockId))
|
||||||
|
b, err := c.get(ctx, blockPath, withSSZEncoding())
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error requesting state by id = %s", blockId)
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var getBlockRootTpl = idTemplate(get_block_root_path)
|
||||||
|
|
||||||
|
// GetBlockRoot retrieves the hash_tree_root of the BeaconBlock for the given block id.
|
||||||
|
// Block identifier can be one of: "head" (canonical head in node's view), "genesis", "finalized",
|
||||||
|
// <slot>, <hex encoded blockRoot with 0x prefix>. Variables of type StateOrBlockId are exported by this package
|
||||||
|
// for the named identifiers.
|
||||||
|
func (c *Client) GetBlockRoot(ctx context.Context, blockId StateOrBlockId) ([32]byte, error) {
|
||||||
|
rootPath := getBlockRootTpl(blockId)
|
||||||
|
b, err := c.get(ctx, rootPath)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, errors.Wrapf(err, "error requesting block root by id = %s", blockId)
|
||||||
|
}
|
||||||
|
jsonr := &struct{ Data struct{ Root string } }{}
|
||||||
|
err = json.Unmarshal(b, jsonr)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, errors.Wrap(err, "error decoding json data from get block root response")
|
||||||
|
}
|
||||||
|
rs, err := hexutil.Decode(jsonr.Data.Root)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, errors.Wrap(err, fmt.Sprintf("error decoding hex-encoded value %s", jsonr.Data.Root))
|
||||||
|
}
|
||||||
|
return bytesutil.ToBytes32(rs), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var getForkTpl = idTemplate(get_fork_for_state_path)
|
||||||
|
|
||||||
|
// GetFork queries the Beacon Node API for the Fork from the state identified by stateId.
|
||||||
|
// Block identifier can be one of: "head" (canonical head in node's view), "genesis", "finalized",
|
||||||
|
// <slot>, <hex encoded blockRoot with 0x prefix>. Variables of type StateOrBlockId are exported by this package
|
||||||
|
// for the named identifiers.
|
||||||
|
func (c *Client) GetFork(ctx context.Context, stateId StateOrBlockId) (*ethpb.Fork, error) {
|
||||||
|
body, err := c.get(ctx, getForkTpl(stateId))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error requesting fork by state id = %s", stateId)
|
||||||
|
}
|
||||||
|
fr := &forkResponse{}
|
||||||
|
dataWrapper := &struct{ Data *forkResponse }{Data: fr}
|
||||||
|
err = json.Unmarshal(body, dataWrapper)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error decoding json response in GetFork")
|
||||||
|
}
|
||||||
|
|
||||||
|
return fr.Fork()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetForkSchedule retrieve all forks, past present and future, of which this node is aware.
|
||||||
|
func (c *Client) GetForkSchedule(ctx context.Context) (params.OrderedForkSchedule, error) {
|
||||||
|
body, err := c.get(ctx, get_fork_schedule_path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error requesting fork schedule")
|
||||||
|
}
|
||||||
|
fsr := &forkScheduleResponse{}
|
||||||
|
err = json.Unmarshal(body, fsr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ofs, err := fsr.OrderedForkSchedule()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, fmt.Sprintf("problem unmarshaling %s response", get_fork_schedule_path))
|
||||||
|
}
|
||||||
|
return ofs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeVersion struct {
|
||||||
|
implementation string
|
||||||
|
semver string
|
||||||
|
systemInfo string
|
||||||
|
}
|
||||||
|
|
||||||
|
var versionRE = regexp.MustCompile(`^(\w+)\/(v\d+\.\d+\.\d+) \((.*)\)$`)
|
||||||
|
|
||||||
|
func parseNodeVersion(v string) (*NodeVersion, error) {
|
||||||
|
groups := versionRE.FindStringSubmatch(v)
|
||||||
|
if len(groups) != 4 {
|
||||||
|
return nil, errors.Wrapf(ErrInvalidNodeVersion, "could not be parsed: %s", v)
|
||||||
|
}
|
||||||
|
return &NodeVersion{
|
||||||
|
implementation: groups[1],
|
||||||
|
semver: groups[2],
|
||||||
|
systemInfo: groups[3],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNodeVersion requests that the beacon node identify information about its implementation in a format
|
||||||
|
// similar to a HTTP User-Agent field. ex: Lighthouse/v0.1.5 (Linux x86_64)
|
||||||
|
func (c *Client) GetNodeVersion(ctx context.Context) (*NodeVersion, error) {
|
||||||
|
b, err := c.get(ctx, get_node_version_path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error requesting node version")
|
||||||
|
}
|
||||||
|
d := struct {
|
||||||
|
Data struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
} `json:"data"`
|
||||||
|
}{}
|
||||||
|
err = json.Unmarshal(b, &d)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error unmarshaling response body: %s", string(b))
|
||||||
|
}
|
||||||
|
return parseNodeVersion(d.Data.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetState retrieves the BeaconState for the given state id.
|
||||||
|
// State identifier can be one of: "head" (canonical head in node's view), "genesis", "finalized",
|
||||||
|
// <slot>, <hex encoded stateRoot with 0x prefix>. Variables of type StateOrBlockId are exported by this package
|
||||||
|
// for the named identifiers.
|
||||||
|
// The return value contains the ssz-encoded bytes.
|
||||||
|
func (c *Client) GetState(ctx context.Context, stateId StateOrBlockId) ([]byte, error) {
|
||||||
|
statePath := path.Join(get_state_path, string(stateId))
|
||||||
|
b, err := c.get(ctx, statePath, withSSZEncoding())
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error requesting state by id = %s", stateId)
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWeakSubjectivity calls a proposed API endpoint that is unique to prysm
|
||||||
|
// This api method does the following:
|
||||||
|
// - computes weak subjectivity epoch
|
||||||
|
// - finds the highest non-skipped block preceding the epoch
|
||||||
|
// - returns the htr of the found block and returns this + the value of state_root from the block
|
||||||
|
func (c *Client) GetWeakSubjectivity(ctx context.Context) (*WeakSubjectivityData, error) {
|
||||||
|
body, err := c.get(ctx, get_weak_subjectivity_path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
v := &apimiddleware.WeakSubjectivityResponse{}
|
||||||
|
err = json.Unmarshal(body, v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
epoch, err := strconv.ParseUint(v.Data.Checkpoint.Epoch, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
blockRoot, err := hexutil.Decode(v.Data.Checkpoint.Root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stateRoot, err := hexutil.Decode(v.Data.StateRoot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &WeakSubjectivityData{
|
||||||
|
Epoch: types.Epoch(epoch),
|
||||||
|
BlockRoot: bytesutil.ToBytes32(blockRoot),
|
||||||
|
StateRoot: bytesutil.ToBytes32(stateRoot),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func non200Err(response *http.Response) error {
|
||||||
|
bodyBytes, err := ioutil.ReadAll(response.Body)
|
||||||
|
var body string
|
||||||
|
if err != nil {
|
||||||
|
body = "(Unable to read response body.)"
|
||||||
|
} else {
|
||||||
|
body = "response body:\n" + string(bodyBytes)
|
||||||
|
}
|
||||||
|
msg := fmt.Sprintf("code=%d, url=%s, body=%s", response.StatusCode, response.Request.URL, body)
|
||||||
|
switch response.StatusCode {
|
||||||
|
case 404:
|
||||||
|
return errors.Wrap(ErrNotFound, msg)
|
||||||
|
default:
|
||||||
|
return errors.Wrap(ErrNotOK, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type forkResponse struct {
|
||||||
|
PreviousVersion string `json:"previous_version"`
|
||||||
|
CurrentVersion string `json:"current_version"`
|
||||||
|
Epoch string `json:"epoch"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *forkResponse) Fork() (*ethpb.Fork, error) {
|
||||||
|
epoch, err := strconv.ParseUint(f.Epoch, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cSlice, err := hexutil.Decode(f.CurrentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(cSlice) != 4 {
|
||||||
|
return nil, fmt.Errorf("got %d byte version for CurrentVersion, expected 4 bytes. hex=%s", len(cSlice), f.CurrentVersion)
|
||||||
|
}
|
||||||
|
pSlice, err := hexutil.Decode(f.PreviousVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(pSlice) != 4 {
|
||||||
|
return nil, fmt.Errorf("got %d byte version, expected 4 bytes. version hex=%s", len(pSlice), f.PreviousVersion)
|
||||||
|
}
|
||||||
|
return ðpb.Fork{
|
||||||
|
CurrentVersion: cSlice,
|
||||||
|
PreviousVersion: pSlice,
|
||||||
|
Epoch: types.Epoch(epoch),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type forkScheduleResponse struct {
|
||||||
|
Data []forkResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fsr *forkScheduleResponse) OrderedForkSchedule() (params.OrderedForkSchedule, error) {
|
||||||
|
ofs := make(params.OrderedForkSchedule, 0)
|
||||||
|
for _, d := range fsr.Data {
|
||||||
|
epoch, err := strconv.Atoi(d.Epoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vSlice, err := hexutil.Decode(d.CurrentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(vSlice) != 4 {
|
||||||
|
return nil, fmt.Errorf("got %d byte version, expected 4 bytes. version hex=%s", len(vSlice), d.CurrentVersion)
|
||||||
|
}
|
||||||
|
version := bytesutil.ToBytes4(vSlice)
|
||||||
|
ofs = append(ofs, params.ForkScheduleEntry{
|
||||||
|
Version: version,
|
||||||
|
Epoch: types.Epoch(uint64(epoch)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sort.Sort(ofs)
|
||||||
|
return ofs, nil
|
||||||
|
}
|
||||||
58
api/client/beacon/client_test.go
Normal file
58
api/client/beacon/client_test.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package beacon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseNodeVersion(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
v string
|
||||||
|
err error
|
||||||
|
nv *NodeVersion
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty string",
|
||||||
|
v: "",
|
||||||
|
err: ErrInvalidNodeVersion,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Prysm as the version string",
|
||||||
|
v: "Prysm",
|
||||||
|
err: ErrInvalidNodeVersion,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "semver only",
|
||||||
|
v: "v2.0.6",
|
||||||
|
err: ErrInvalidNodeVersion,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "implementation and semver only",
|
||||||
|
v: "Prysm/v2.0.6",
|
||||||
|
err: ErrInvalidNodeVersion,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "complete version",
|
||||||
|
v: "Prysm/v2.0.6 (linux amd64)",
|
||||||
|
nv: &NodeVersion{
|
||||||
|
implementation: "Prysm",
|
||||||
|
semver: "v2.0.6",
|
||||||
|
systemInfo: "linux amd64",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
nv, err := parseNodeVersion(c.v)
|
||||||
|
if c.err != nil {
|
||||||
|
require.ErrorIs(t, err, c.err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.DeepEqual(t, c.nv, nv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
6
api/client/beacon/doc.go
Normal file
6
api/client/beacon/doc.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*
|
||||||
|
Package beacon provides a client for interacting with the standard Eth Beacon Node API.
|
||||||
|
Interactive swagger documentation for the API is available here: https://ethereum.github.io/beacon-APIs/
|
||||||
|
|
||||||
|
*/
|
||||||
|
package beacon
|
||||||
12
api/client/beacon/errors.go
Normal file
12
api/client/beacon/errors.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package beacon
|
||||||
|
|
||||||
|
import "github.com/pkg/errors"
|
||||||
|
|
||||||
|
// ErrNotOK is used to indicate when an HTTP request to the Beacon Node API failed with any non-2xx response code.
|
||||||
|
// More specific errors may be returned, but an error in reaction to a non-2xx response will always wrap ErrNotOK.
|
||||||
|
var ErrNotOK = errors.New("did not receive 2xx response from API")
|
||||||
|
|
||||||
|
// ErrNotFound specifically means that a '404 - NOT FOUND' response was received from the API.
|
||||||
|
var ErrNotFound = errors.Wrap(ErrNotOK, "recv 404 NotFound response from API")
|
||||||
|
|
||||||
|
var ErrInvalidNodeVersion = errors.New("invalid node version response")
|
||||||
@@ -233,7 +233,7 @@ func (s *Service) startFromSavedState(saved state.BeaconState) error {
|
|||||||
|
|
||||||
func (s *Service) originRootFromSavedState(ctx context.Context) ([32]byte, error) {
|
func (s *Service) originRootFromSavedState(ctx context.Context) ([32]byte, error) {
|
||||||
// first check if we have started from checkpoint sync and have a root
|
// first check if we have started from checkpoint sync and have a root
|
||||||
originRoot, err := s.cfg.BeaconDB.OriginBlockRoot(ctx)
|
originRoot, err := s.cfg.BeaconDB.OriginCheckpointBlockRoot(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return originRoot, nil
|
return originRoot, nil
|
||||||
}
|
}
|
||||||
@@ -241,7 +241,7 @@ func (s *Service) originRootFromSavedState(ctx context.Context) ([32]byte, error
|
|||||||
return originRoot, errors.Wrap(err, "could not retrieve checkpoint sync chain origin data from db")
|
return originRoot, errors.Wrap(err, "could not retrieve checkpoint sync chain origin data from db")
|
||||||
}
|
}
|
||||||
|
|
||||||
// we got here because OriginBlockRoot gave us an ErrNotFound. this means the node was started from a genesis state,
|
// we got here because OriginCheckpointBlockRoot gave us an ErrNotFound. this means the node was started from a genesis state,
|
||||||
// so we should have a value for GenesisBlock
|
// so we should have a value for GenesisBlock
|
||||||
genesisBlock, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
genesisBlock, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ func NewWeakSubjectivityVerifier(wsc *ethpb.Checkpoint, db weakSubjectivityDB) (
|
|||||||
// per 7342, a nil checkpoint, zero-root or zero-epoch should all fail validation
|
// per 7342, a nil checkpoint, zero-root or zero-epoch should all fail validation
|
||||||
// and return an error instead of creating a WeakSubjectivityVerifier that permits any chain history.
|
// and return an error instead of creating a WeakSubjectivityVerifier that permits any chain history.
|
||||||
if wsc == nil || len(wsc.Root) == 0 || wsc.Epoch == 0 {
|
if wsc == nil || len(wsc.Root) == 0 || wsc.Epoch == 0 {
|
||||||
|
log.Warn("No valid weak subjectivity checkpoint specified, running without weak subjectivity verification")
|
||||||
return &WeakSubjectivityVerifier{
|
return &WeakSubjectivityVerifier{
|
||||||
enabled: false,
|
enabled: false,
|
||||||
}, nil
|
}, nil
|
||||||
@@ -81,13 +82,14 @@ func (v *WeakSubjectivityVerifier) VerifyWeakSubjectivity(ctx context.Context, f
|
|||||||
}
|
}
|
||||||
filter := filters.NewFilter().SetStartSlot(v.slot).SetEndSlot(v.slot + params.BeaconConfig().SlotsPerEpoch)
|
filter := filters.NewFilter().SetStartSlot(v.slot).SetEndSlot(v.slot + params.BeaconConfig().SlotsPerEpoch)
|
||||||
// A node should have the weak subjectivity block corresponds to the correct epoch in the DB.
|
// A node should have the weak subjectivity block corresponds to the correct epoch in the DB.
|
||||||
|
log.Infof("Searching block roots index for weak subjectivity root=%#x", v.root)
|
||||||
roots, err := v.db.BlockRoots(ctx, filter)
|
roots, err := v.db.BlockRoots(ctx, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "error while retrieving block roots to verify weak subjectivity")
|
return errors.Wrap(err, "error while retrieving block roots to verify weak subjectivity")
|
||||||
}
|
}
|
||||||
for _, root := range roots {
|
for _, root := range roots {
|
||||||
if v.root == root {
|
if v.root == root {
|
||||||
log.Info("Weak subjectivity check has passed")
|
log.Info("Weak subjectivity check has passed!!")
|
||||||
v.verified = true
|
v.verified = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,58 +14,62 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
|
func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
|
||||||
beaconDB := testDB.SetupDB(t)
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
|
||||||
b := util.NewBeaconBlock()
|
b := util.NewBeaconBlock()
|
||||||
b.Block.Slot = 32
|
b.Block.Slot = 1792480
|
||||||
|
blockEpoch := slots.ToEpoch(b.Block.Slot)
|
||||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
|
require.NoError(t, beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
|
||||||
r, err := b.Block.HashTreeRoot()
|
r, err := b.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
wsVerified bool
|
wsVerified bool
|
||||||
|
disabled bool
|
||||||
wantErr error
|
wantErr error
|
||||||
checkpt *ethpb.Checkpoint
|
checkpt *ethpb.Checkpoint
|
||||||
finalizedEpoch types.Epoch
|
finalizedEpoch types.Epoch
|
||||||
name string
|
name string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "nil root and epoch",
|
name: "nil root and epoch",
|
||||||
},
|
disabled: true,
|
||||||
{
|
|
||||||
name: "already verified",
|
|
||||||
checkpt: ðpb.Checkpoint{Epoch: 2},
|
|
||||||
finalizedEpoch: 2,
|
|
||||||
wsVerified: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "not yet to verify, ws epoch higher than finalized epoch",
|
name: "not yet to verify, ws epoch higher than finalized epoch",
|
||||||
checkpt: ðpb.Checkpoint{Epoch: 2},
|
checkpt: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, 32), Epoch: blockEpoch},
|
||||||
finalizedEpoch: 1,
|
finalizedEpoch: blockEpoch - 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "can't find the block in DB",
|
name: "can't find the block in DB",
|
||||||
checkpt: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength), Epoch: 1},
|
checkpt: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength), Epoch: 1},
|
||||||
finalizedEpoch: 3,
|
finalizedEpoch: blockEpoch + 1,
|
||||||
wantErr: errWSBlockNotFound,
|
wantErr: errWSBlockNotFound,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "can't find the block corresponds to ws epoch in DB",
|
name: "can't find the block corresponds to ws epoch in DB",
|
||||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: 2}, // Root belongs in epoch 1.
|
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch - 2}, // Root belongs in epoch 1.
|
||||||
finalizedEpoch: 3,
|
finalizedEpoch: blockEpoch - 1,
|
||||||
wantErr: errWSBlockNotFoundInEpoch,
|
wantErr: errWSBlockNotFoundInEpoch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "can verify and pass",
|
name: "can verify and pass",
|
||||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: 1},
|
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch},
|
||||||
finalizedEpoch: 3,
|
finalizedEpoch: blockEpoch + 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "equal epoch",
|
||||||
|
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch},
|
||||||
|
finalizedEpoch: blockEpoch,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
wv, err := NewWeakSubjectivityVerifier(tt.checkpt, beaconDB)
|
wv, err := NewWeakSubjectivityVerifier(tt.checkpt, beaconDB)
|
||||||
|
require.Equal(t, !tt.disabled, wv.enabled)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s := &Service{
|
s := &Service{
|
||||||
cfg: &config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt},
|
cfg: &config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt},
|
||||||
|
|||||||
@@ -15,25 +15,7 @@ go_library(
|
|||||||
"weak_subjectivity.go",
|
"weak_subjectivity.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers",
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers",
|
||||||
visibility = [
|
visibility = ["//visibility:public"],
|
||||||
"//beacon-chain:__subpackages__",
|
|
||||||
"//cmd/beacon-chain:__subpackages__",
|
|
||||||
"//contracts/deposit:__pkg__",
|
|
||||||
"//crypto/keystore:__pkg__",
|
|
||||||
"//network/forks:__pkg__",
|
|
||||||
"//proto/prysm/v1alpha1:__subpackages__",
|
|
||||||
"//proto/prysm/v1alpha1/attestation:__pkg__",
|
|
||||||
"//runtime/interop:__pkg__",
|
|
||||||
"//slasher:__subpackages__",
|
|
||||||
"//testing/altair:__pkg__",
|
|
||||||
"//testing/benchmark/benchmark_files:__subpackages__",
|
|
||||||
"//testing/endtoend/evaluators:__pkg__",
|
|
||||||
"//testing/slasher/simulator:__pkg__",
|
|
||||||
"//testing/spectest:__subpackages__",
|
|
||||||
"//testing/util:__pkg__",
|
|
||||||
"//tools:__subpackages__",
|
|
||||||
"//validator:__subpackages__",
|
|
||||||
],
|
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/cache:go_default_library",
|
"//beacon-chain/cache:go_default_library",
|
||||||
"//beacon-chain/core/time:go_default_library",
|
"//beacon-chain/core/time:go_default_library",
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package helpers
|
package helpers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -13,8 +12,9 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
"github.com/prysmaticlabs/prysm/math"
|
"github.com/prysmaticlabs/prysm/math"
|
||||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
v1alpha1 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -122,20 +122,20 @@ func ComputeWeakSubjectivityPeriod(ctx context.Context, st state.ReadOnlyBeaconS
|
|||||||
// current_epoch = compute_epoch_at_slot(get_current_slot(store))
|
// current_epoch = compute_epoch_at_slot(get_current_slot(store))
|
||||||
// return current_epoch <= ws_state_epoch + ws_period
|
// return current_epoch <= ws_state_epoch + ws_period
|
||||||
func IsWithinWeakSubjectivityPeriod(
|
func IsWithinWeakSubjectivityPeriod(
|
||||||
ctx context.Context, currentEpoch types.Epoch, wsState state.ReadOnlyBeaconState, wsCheckpoint *eth.WeakSubjectivityCheckpoint) (bool, error) {
|
ctx context.Context, currentEpoch types.Epoch, wsState state.ReadOnlyBeaconState, wsStateRoot [32]byte, wsEpoch types.Epoch) (bool, error) {
|
||||||
// Make sure that incoming objects are not nil.
|
// Make sure that incoming objects are not nil.
|
||||||
if wsState == nil || wsState.IsNil() || wsState.LatestBlockHeader() == nil || wsCheckpoint == nil {
|
if wsState == nil || wsState.IsNil() || wsState.LatestBlockHeader() == nil {
|
||||||
return false, errors.New("invalid weak subjectivity state or checkpoint")
|
return false, errors.New("invalid weak subjectivity state or checkpoint")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert that state and checkpoint have the same root and epoch.
|
// Assert that state and checkpoint have the same root and epoch.
|
||||||
if !bytes.Equal(wsState.LatestBlockHeader().StateRoot, wsCheckpoint.StateRoot) {
|
if bytesutil.ToBytes32(wsState.LatestBlockHeader().StateRoot) != wsStateRoot {
|
||||||
return false, fmt.Errorf("state (%#x) and checkpoint (%#x) roots do not match",
|
return false, fmt.Errorf("state (%#x) and checkpoint (%#x) roots do not match",
|
||||||
wsState.LatestBlockHeader().StateRoot, wsCheckpoint.StateRoot)
|
wsState.LatestBlockHeader().StateRoot, wsStateRoot)
|
||||||
}
|
}
|
||||||
if slots.ToEpoch(wsState.Slot()) != wsCheckpoint.Epoch {
|
if slots.ToEpoch(wsState.Slot()) != wsEpoch {
|
||||||
return false, fmt.Errorf("state (%v) and checkpoint (%v) epochs do not match",
|
return false, fmt.Errorf("state (%v) and checkpoint (%v) epochs do not match",
|
||||||
slots.ToEpoch(wsState.Slot()), wsCheckpoint.Epoch)
|
slots.ToEpoch(wsState.Slot()), wsEpoch)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare given epoch to state epoch + weak subjectivity period.
|
// Compare given epoch to state epoch + weak subjectivity period.
|
||||||
@@ -164,7 +164,7 @@ func LatestWeakSubjectivityEpoch(ctx context.Context, st state.ReadOnlyBeaconSta
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseWeakSubjectivityInputString parses "blocks_root:epoch_number" string into a checkpoint.
|
// ParseWeakSubjectivityInputString parses "blocks_root:epoch_number" string into a checkpoint.
|
||||||
func ParseWeakSubjectivityInputString(wsCheckpointString string) (*eth.Checkpoint, error) {
|
func ParseWeakSubjectivityInputString(wsCheckpointString string) (*v1alpha1.Checkpoint, error) {
|
||||||
if wsCheckpointString == "" {
|
if wsCheckpointString == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ func ParseWeakSubjectivityInputString(wsCheckpointString string) (*eth.Checkpoin
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ð.Checkpoint{
|
return &v1alpha1.Checkpoint{
|
||||||
Epoch: types.Epoch(epoch),
|
Epoch: types.Epoch(epoch),
|
||||||
Root: bRoot,
|
Root: bRoot,
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -54,12 +54,15 @@ func TestWeakSubjectivity_ComputeWeakSubjectivityPeriod(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mockWsCheckpoint func() (stateRoot [32]byte, blockRoot [32]byte, e types.Epoch)
|
||||||
|
|
||||||
func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
epoch types.Epoch
|
epoch types.Epoch
|
||||||
genWsState func() state.ReadOnlyBeaconState
|
genWsState func() state.ReadOnlyBeaconState
|
||||||
genWsCheckpoint func() *ethpb.WeakSubjectivityCheckpoint
|
genWsCheckpoint mockWsCheckpoint
|
||||||
want bool
|
want bool
|
||||||
wantedErr string
|
wantedErr string
|
||||||
}{
|
}{
|
||||||
@@ -68,22 +71,8 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
|||||||
genWsState: func() state.ReadOnlyBeaconState {
|
genWsState: func() state.ReadOnlyBeaconState {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||||
return ðpb.WeakSubjectivityCheckpoint{
|
return [32]byte{}, [32]byte{}, 42
|
||||||
BlockRoot: make([]byte, 32),
|
|
||||||
StateRoot: make([]byte, 32),
|
|
||||||
Epoch: 42,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
wantedErr: "invalid weak subjectivity state or checkpoint",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "nil weak subjectivity checkpoint",
|
|
||||||
genWsState: func() state.ReadOnlyBeaconState {
|
|
||||||
return genState(t, 128, 32)
|
|
||||||
},
|
|
||||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
wantedErr: "invalid weak subjectivity state or checkpoint",
|
wantedErr: "invalid weak subjectivity state or checkpoint",
|
||||||
},
|
},
|
||||||
@@ -99,11 +88,10 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return beaconState
|
return beaconState
|
||||||
},
|
},
|
||||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||||
return ðpb.WeakSubjectivityCheckpoint{
|
var sr [32]byte
|
||||||
StateRoot: bytesutil.PadTo([]byte("stateroot2"), 32),
|
copy(sr[:], bytesutil.PadTo([]byte("stateroot2"), 32))
|
||||||
Epoch: 42,
|
return sr, [32]byte{}, 42
|
||||||
}
|
|
||||||
},
|
},
|
||||||
wantedErr: fmt.Sprintf("state (%#x) and checkpoint (%#x) roots do not match",
|
wantedErr: fmt.Sprintf("state (%#x) and checkpoint (%#x) roots do not match",
|
||||||
bytesutil.PadTo([]byte("stateroot1"), 32), bytesutil.PadTo([]byte("stateroot2"), 32)),
|
bytesutil.PadTo([]byte("stateroot1"), 32), bytesutil.PadTo([]byte("stateroot2"), 32)),
|
||||||
@@ -120,11 +108,10 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return beaconState
|
return beaconState
|
||||||
},
|
},
|
||||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||||
return ðpb.WeakSubjectivityCheckpoint{
|
var sr [32]byte
|
||||||
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
|
copy(sr[:], bytesutil.PadTo([]byte("stateroot"), 32))
|
||||||
Epoch: 43,
|
return sr, [32]byte{}, 43
|
||||||
}
|
|
||||||
},
|
},
|
||||||
wantedErr: "state (42) and checkpoint (43) epochs do not match",
|
wantedErr: "state (42) and checkpoint (43) epochs do not match",
|
||||||
},
|
},
|
||||||
@@ -140,11 +127,10 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return beaconState
|
return beaconState
|
||||||
},
|
},
|
||||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||||
return ðpb.WeakSubjectivityCheckpoint{
|
var sr [32]byte
|
||||||
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
|
copy(sr[:], bytesutil.PadTo([]byte("stateroot"), 32))
|
||||||
Epoch: 42,
|
return sr, [32]byte{}, 42
|
||||||
}
|
|
||||||
},
|
},
|
||||||
wantedErr: "cannot compute weak subjectivity period: no active validators found",
|
wantedErr: "cannot compute weak subjectivity period: no active validators found",
|
||||||
},
|
},
|
||||||
@@ -161,11 +147,10 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return beaconState
|
return beaconState
|
||||||
},
|
},
|
||||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||||
return ðpb.WeakSubjectivityCheckpoint{
|
var sr [32]byte
|
||||||
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
|
copy(sr[:], bytesutil.PadTo([]byte("stateroot"), 32))
|
||||||
Epoch: 42,
|
return sr, [32]byte{}, 42
|
||||||
}
|
|
||||||
},
|
},
|
||||||
want: false,
|
want: false,
|
||||||
},
|
},
|
||||||
@@ -182,18 +167,18 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return beaconState
|
return beaconState
|
||||||
},
|
},
|
||||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||||
return ðpb.WeakSubjectivityCheckpoint{
|
var sr [32]byte
|
||||||
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
|
copy(sr[:], bytesutil.PadTo([]byte("stateroot"), 32))
|
||||||
Epoch: 42,
|
return sr, [32]byte{}, 42
|
||||||
}
|
|
||||||
},
|
},
|
||||||
want: true,
|
want: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
got, err := helpers.IsWithinWeakSubjectivityPeriod(context.Background(), tt.epoch, tt.genWsState(), tt.genWsCheckpoint())
|
sr, _, e := tt.genWsCheckpoint()
|
||||||
|
got, err := helpers.IsWithinWeakSubjectivityPeriod(context.Background(), tt.epoch, tt.genWsState(), sr, e)
|
||||||
if tt.wantedErr != "" {
|
if tt.wantedErr != "" {
|
||||||
assert.Equal(t, false, got)
|
assert.Equal(t, false, got)
|
||||||
assert.ErrorContains(t, tt.wantedErr, err)
|
assert.ErrorContains(t, tt.wantedErr, err)
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ type ReadOnlyDatabase interface {
|
|||||||
// Fee reicipients operations.
|
// Fee reicipients operations.
|
||||||
FeeRecipientByValidatorID(ctx context.Context, id types.ValidatorIndex) (common.Address, error)
|
FeeRecipientByValidatorID(ctx context.Context, id types.ValidatorIndex) (common.Address, error)
|
||||||
// origin checkpoint sync support
|
// origin checkpoint sync support
|
||||||
OriginBlockRoot(ctx context.Context) ([32]byte, error)
|
OriginCheckpointBlockRoot(ctx context.Context) ([32]byte, error)
|
||||||
|
LowestSyncedBlockSlot(ctx context.Context) (types.Slot, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoHeadAccessDatabase defines a struct without access to chain head data.
|
// NoHeadAccessDatabase defines a struct without access to chain head data.
|
||||||
@@ -100,7 +101,7 @@ type HeadAccessDatabase interface {
|
|||||||
EnsureEmbeddedGenesis(ctx context.Context) error
|
EnsureEmbeddedGenesis(ctx context.Context) error
|
||||||
|
|
||||||
// initialization method needed for origin checkpoint sync
|
// initialization method needed for origin checkpoint sync
|
||||||
SaveOrigin(ctx context.Context, state io.Reader, block io.Reader) error
|
SaveOrigin(ctx context.Context, state []byte, block []byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// SlasherDatabase interface for persisting data related to detecting slashable offenses on Ethereum.
|
// SlasherDatabase interface for persisting data related to detecting slashable offenses on Ethereum.
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ go_library(
|
|||||||
"//io/file:go_default_library",
|
"//io/file:go_default_library",
|
||||||
"//monitoring/progress:go_default_library",
|
"//monitoring/progress:go_default_library",
|
||||||
"//monitoring/tracing:go_default_library",
|
"//monitoring/tracing:go_default_library",
|
||||||
|
"//proto/detect:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/block:go_default_library",
|
"//proto/prysm/v1alpha1/block:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
|
|
||||||
// used to represent errors for inconsistent slot ranges.
|
// used to represent errors for inconsistent slot ranges.
|
||||||
var errInvalidSlotRange = errors.New("invalid end slot and start slot provided")
|
var errInvalidSlotRange = errors.New("invalid end slot and start slot provided")
|
||||||
|
var errEmptyBucket = errors.New("unexpectedly empty bucket")
|
||||||
|
|
||||||
// Block retrieval by root.
|
// Block retrieval by root.
|
||||||
func (s *Store) Block(ctx context.Context, blockRoot [32]byte) (block.SignedBeaconBlock, error) {
|
func (s *Store) Block(ctx context.Context, blockRoot [32]byte) (block.SignedBeaconBlock, error) {
|
||||||
@@ -47,18 +48,18 @@ func (s *Store) Block(ctx context.Context, blockRoot [32]byte) (block.SignedBeac
|
|||||||
return blk, err
|
return blk, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// OriginBlockRoot returns the value written to the db in SaveOriginBlockRoot
|
// OriginCheckpointBlockRoot returns the value written to the db in SaveOriginCheckpointBlockRoot
|
||||||
// This is the root of a finalized block within the weak subjectivity period
|
// This is the root of a finalized block within the weak subjectivity period
|
||||||
// at the time the chain was started, used to initialize the database and chain
|
// at the time the chain was started, used to initialize the database and chain
|
||||||
// without syncing from genesis.
|
// without syncing from genesis.
|
||||||
func (s *Store) OriginBlockRoot(ctx context.Context) ([32]byte, error) {
|
func (s *Store) OriginCheckpointBlockRoot(ctx context.Context) ([32]byte, error) {
|
||||||
_, span := trace.StartSpan(ctx, "BeaconDB.OriginBlockRoot")
|
_, span := trace.StartSpan(ctx, "BeaconDB.OriginCheckpointBlockRoot")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
var root [32]byte
|
var root [32]byte
|
||||||
err := s.db.View(func(tx *bolt.Tx) error {
|
err := s.db.View(func(tx *bolt.Tx) error {
|
||||||
bkt := tx.Bucket(blocksBucket)
|
bkt := tx.Bucket(blocksBucket)
|
||||||
rootSlice := bkt.Get(originBlockRootKey)
|
rootSlice := bkt.Get(originCheckpointBlockRootKey)
|
||||||
if rootSlice == nil {
|
if rootSlice == nil {
|
||||||
return ErrNotFoundOriginBlockRoot
|
return ErrNotFoundOriginBlockRoot
|
||||||
}
|
}
|
||||||
@@ -69,6 +70,26 @@ func (s *Store) OriginBlockRoot(ctx context.Context) ([32]byte, error) {
|
|||||||
return root, err
|
return root, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LowestSyncedBlockSlot returns the lowest slot number in the block root index
|
||||||
|
func (s *Store) LowestSyncedBlockSlot(ctx context.Context) (types.Slot, error) {
|
||||||
|
ctx, span := trace.StartSpan(ctx, "BeaconDB.LowestSyncedBlockSlot")
|
||||||
|
defer span.End()
|
||||||
|
// start scan at zero, which will yield the lowest key in the collection.
|
||||||
|
var slot types.Slot
|
||||||
|
err := s.db.View(func(tx *bolt.Tx) error {
|
||||||
|
// Iterate through the index, which is in byte sorted order.
|
||||||
|
bkt := tx.Bucket(blockSlotIndicesBucket)
|
||||||
|
c := bkt.Cursor()
|
||||||
|
k, _ := c.First()
|
||||||
|
if k == nil {
|
||||||
|
return errors.Wrapf(errEmptyBucket, "'%s' bucket is empty", string(blockSlotIndicesBucket))
|
||||||
|
}
|
||||||
|
slot = bytesutil.BytesToSlotBigEndian(k)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return slot, err
|
||||||
|
}
|
||||||
|
|
||||||
// HeadBlock returns the latest canonical block in the Ethereum Beacon Chain.
|
// HeadBlock returns the latest canonical block in the Ethereum Beacon Chain.
|
||||||
func (s *Store) HeadBlock(ctx context.Context) (block.SignedBeaconBlock, error) {
|
func (s *Store) HeadBlock(ctx context.Context) (block.SignedBeaconBlock, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.HeadBlock")
|
ctx, span := trace.StartSpan(ctx, "BeaconDB.HeadBlock")
|
||||||
@@ -334,16 +355,16 @@ func (s *Store) SaveGenesisBlockRoot(ctx context.Context, blockRoot [32]byte) er
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveOriginBlockRoot is used to keep track of the block root used for origin sync.
|
// SaveOriginCheckpointBlockRoot is used to keep track of the block root used for syncing from a checkpoint origin.
|
||||||
// This should be a finalized block from within the current weak subjectivity period.
|
// This should be a finalized block from within the current weak subjectivity period.
|
||||||
// This value is used by a running beacon chain node to locate the state at the beginning
|
// This value is used by a running beacon chain node to locate the state at the beginning
|
||||||
// of the chain history, in places where genesis would typically be used.
|
// of the chain history, in places where genesis would typically be used.
|
||||||
func (s *Store) SaveOriginBlockRoot(ctx context.Context, blockRoot [32]byte) error {
|
func (s *Store) SaveOriginCheckpointBlockRoot(ctx context.Context, blockRoot [32]byte) error {
|
||||||
_, span := trace.StartSpan(ctx, "BeaconDB.SaveOriginBlockRoot")
|
_, span := trace.StartSpan(ctx, "BeaconDB.SaveOriginCheckpointBlockRoot")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
return s.db.Update(func(tx *bolt.Tx) error {
|
return s.db.Update(func(tx *bolt.Tx) error {
|
||||||
bucket := tx.Bucket(blocksBucket)
|
bucket := tx.Bucket(blocksBucket)
|
||||||
return bucket.Put(originBlockRootKey, blockRoot[:])
|
return bucket.Put(originCheckpointBlockRootKey, blockRoot[:])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,30 @@ var blockTests = []struct {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStore_LowestSyncedBlockSlot(t *testing.T) {
|
||||||
|
// test case: make sure expected error is returned w/ an empty bucket
|
||||||
|
db := setupDB(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
_, err := db.LowestSyncedBlockSlot(ctx)
|
||||||
|
require.ErrorIs(t, err, errEmptyBucket)
|
||||||
|
|
||||||
|
// test case: make sure that the right value is returned using a non-zero key
|
||||||
|
block := util.NewBeaconBlock()
|
||||||
|
block.Block.Slot = types.Slot(1 << 32)
|
||||||
|
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block)))
|
||||||
|
slot, err := db.LowestSyncedBlockSlot(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, slot, block.Block.Slot)
|
||||||
|
|
||||||
|
// test case: write a lower value and make sure that it is returned instead of the existing value
|
||||||
|
zero := util.NewBeaconBlock()
|
||||||
|
zero.Block.Slot = types.Slot(0)
|
||||||
|
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(zero)))
|
||||||
|
zslot, err := db.LowestSyncedBlockSlot(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, zslot, zero.Block.Slot)
|
||||||
|
}
|
||||||
|
|
||||||
func TestStore_SaveBlock_NoDuplicates(t *testing.T) {
|
func TestStore_SaveBlock_NoDuplicates(t *testing.T) {
|
||||||
BlockCacheSize = 1
|
BlockCacheSize = 1
|
||||||
slot := types.Slot(20)
|
slot := types.Slot(20)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ func (s *Store) updateFinalizedBlockRoots(ctx context.Context, tx *bolt.Tx, chec
|
|||||||
root := checkpoint.Root
|
root := checkpoint.Root
|
||||||
var previousRoot []byte
|
var previousRoot []byte
|
||||||
genesisRoot := tx.Bucket(blocksBucket).Get(genesisBlockRootKey)
|
genesisRoot := tx.Bucket(blocksBucket).Get(genesisBlockRootKey)
|
||||||
|
initCheckpointRoot := tx.Bucket(blocksBucket).Get(originCheckpointBlockRootKey)
|
||||||
|
|
||||||
// De-index recent finalized block roots, to be re-indexed.
|
// De-index recent finalized block roots, to be re-indexed.
|
||||||
previousFinalizedCheckpoint := ðpb.Checkpoint{}
|
previousFinalizedCheckpoint := ðpb.Checkpoint{}
|
||||||
@@ -74,7 +75,7 @@ func (s *Store) updateFinalizedBlockRoots(ctx context.Context, tx *bolt.Tx, chec
|
|||||||
// Walk up the ancestry chain until we reach a block root present in the finalized block roots
|
// Walk up the ancestry chain until we reach a block root present in the finalized block roots
|
||||||
// index bucket or genesis block root.
|
// index bucket or genesis block root.
|
||||||
for {
|
for {
|
||||||
if bytes.Equal(root, genesisRoot) {
|
if bytes.Equal(root, genesisRoot) || bytes.Equal(root, initCheckpointRoot) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ var (
|
|||||||
altairKey = []byte("altair")
|
altairKey = []byte("altair")
|
||||||
bellatrixKey = []byte("merge")
|
bellatrixKey = []byte("merge")
|
||||||
// block root included in the beacon state used by weak subjectivity initial sync
|
// block root included in the beacon state used by weak subjectivity initial sync
|
||||||
originBlockRootKey = []byte("origin-block-root")
|
originCheckpointBlockRootKey = []byte("origin-checkpoint-block-root")
|
||||||
|
|
||||||
// Deprecated: This index key was migrated in PR 6461. Do not use, except for migrations.
|
// Deprecated: This index key was migrated in PR 6461. Do not use, except for migrations.
|
||||||
lastArchivedIndexKey = []byte("last-archived")
|
lastArchivedIndexKey = []byte("last-archived")
|
||||||
|
|||||||
@@ -2,56 +2,58 @@ package kv
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
statev2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/proto/detect"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SaveOrigin loads an ssz serialized Block & BeaconState from an io.Reader
|
// SaveOrigin loads an ssz serialized Block & BeaconState from an io.Reader
|
||||||
// (ex: an open file) prepares the database so that the beacon node can begin
|
// (ex: an open file) prepares the database so that the beacon node can begin
|
||||||
// syncing, using the provided values as their point of origin. This is an alternative
|
// syncing, using the provided values as their point of origin. This is an alternative
|
||||||
// to syncing from genesis, and should only be run on an empty database.
|
// to syncing from genesis, and should only be run on an empty database.
|
||||||
func (s *Store) SaveOrigin(ctx context.Context, stateReader, blockReader io.Reader) error {
|
func (s *Store) SaveOrigin(ctx context.Context, serState, serBlock []byte) error {
|
||||||
// unmarshal both block and state before trying to save anything
|
cf, err := detect.ByState(serState)
|
||||||
// so that we fail early if there is any issue with the ssz data
|
|
||||||
blk := ðpb.SignedBeaconBlockAltair{}
|
|
||||||
bb, err := ioutil.ReadAll(blockReader)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "error reading block given to SaveOrigin")
|
return errors.Wrap(err, "could not sniff config+fork for origin state bytes")
|
||||||
}
|
}
|
||||||
if err := blk.UnmarshalSSZ(bb); err != nil {
|
_, ok := params.BeaconConfig().ForkVersionSchedule[cf.Version]
|
||||||
return errors.Wrap(err, "could not unmarshal checkpoint block")
|
if !ok {
|
||||||
}
|
return fmt.Errorf("config mismatch, beacon node configured to connect to %s, detected state is for %s", params.BeaconConfig().ConfigName, cf.ConfigName.String())
|
||||||
wblk, err := wrapper.WrappedAltairSignedBeaconBlock(blk)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not wrap checkpoint block")
|
|
||||||
}
|
|
||||||
bs, err := statev2.InitializeFromSSZReader(stateReader)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not initialize checkpoint state from reader")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save block
|
log.Printf("detected supported config for state & block version detection, name=%s, fork=%s", cf.ConfigName.String(), cf.Fork)
|
||||||
if err := s.SaveBlock(ctx, wblk); err != nil {
|
state, err := cf.UnmarshalBeaconState(serState)
|
||||||
return errors.Wrap(err, "could not save checkpoint block")
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to initialize origin state w/ bytes + config+fork")
|
||||||
}
|
}
|
||||||
blockRoot, err := blk.Block.HashTreeRoot()
|
|
||||||
|
wblk, err := cf.UnmarshalBeaconBlock(serBlock)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to initialize origin block w/ bytes + config+fork")
|
||||||
|
}
|
||||||
|
blk := wblk.Block()
|
||||||
|
|
||||||
|
// save block
|
||||||
|
blockRoot, err := blk.HashTreeRoot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not compute HashTreeRoot of checkpoint block")
|
return errors.Wrap(err, "could not compute HashTreeRoot of checkpoint block")
|
||||||
}
|
}
|
||||||
|
log.Infof("saving checkpoint block to db, w/ root=%#x", blockRoot)
|
||||||
|
if err := s.SaveBlock(ctx, wblk); err != nil {
|
||||||
|
return errors.Wrap(err, "could not save checkpoint block")
|
||||||
|
}
|
||||||
|
|
||||||
// save state
|
// save state
|
||||||
if err = s.SaveState(ctx, bs, blockRoot); err != nil {
|
log.Infof("calling SaveState w/ blockRoot=%x", blockRoot)
|
||||||
|
if err = s.SaveState(ctx, state, blockRoot); err != nil {
|
||||||
return errors.Wrap(err, "could not save state")
|
return errors.Wrap(err, "could not save state")
|
||||||
}
|
}
|
||||||
if err = s.SaveStateSummary(ctx, ðpb.StateSummary{
|
if err = s.SaveStateSummary(ctx, ðpb.StateSummary{
|
||||||
Slot: bs.Slot(),
|
Slot: state.Slot(),
|
||||||
Root: blockRoot[:],
|
Root: blockRoot[:],
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return errors.Wrap(err, "could not save state summary")
|
return errors.Wrap(err, "could not save state summary")
|
||||||
@@ -59,7 +61,7 @@ func (s *Store) SaveOrigin(ctx context.Context, stateReader, blockReader io.Read
|
|||||||
|
|
||||||
// save origin block root in special key, to be used when the canonical
|
// save origin block root in special key, to be used when the canonical
|
||||||
// origin (start of chain, ie alternative to genesis) block or state is needed
|
// origin (start of chain, ie alternative to genesis) block or state is needed
|
||||||
if err = s.SaveOriginBlockRoot(ctx, blockRoot); err != nil {
|
if err = s.SaveOriginCheckpointBlockRoot(ctx, blockRoot); err != nil {
|
||||||
return errors.Wrap(err, "could not save origin block root")
|
return errors.Wrap(err, "could not save origin block root")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +72,7 @@ func (s *Store) SaveOrigin(ctx context.Context, stateReader, blockReader io.Read
|
|||||||
|
|
||||||
// rebuild the checkpoint from the block
|
// rebuild the checkpoint from the block
|
||||||
// use it to mark the block as justified and finalized
|
// use it to mark the block as justified and finalized
|
||||||
slotEpoch, err := blk.Block.Slot.SafeDivSlot(params.BeaconConfig().SlotsPerEpoch)
|
slotEpoch, err := blk.Slot().SafeDivSlot(params.BeaconConfig().SlotsPerEpoch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ go_library(
|
|||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/stategen:go_default_library",
|
"//beacon-chain/state/stategen:go_default_library",
|
||||||
"//beacon-chain/sync:go_default_library",
|
"//beacon-chain/sync:go_default_library",
|
||||||
|
"//beacon-chain/sync/checkpoint:go_default_library",
|
||||||
"//beacon-chain/sync/initial-sync:go_default_library",
|
"//beacon-chain/sync/initial-sync:go_default_library",
|
||||||
"//cmd:go_default_library",
|
"//cmd:go_default_library",
|
||||||
"//cmd/beacon-chain/flags:go_default_library",
|
"//cmd/beacon-chain/flags:go_default_library",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func configureTracing(cliCtx *cli.Context) error {
|
|||||||
func configureChainConfig(cliCtx *cli.Context) {
|
func configureChainConfig(cliCtx *cli.Context) {
|
||||||
if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) {
|
if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) {
|
||||||
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
|
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
|
||||||
params.LoadChainConfigFile(chainConfigFileName)
|
params.LoadChainConfigFile(chainConfigFileName, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
regularsync "github.com/prysmaticlabs/prysm/beacon-chain/sync"
|
regularsync "github.com/prysmaticlabs/prysm/beacon-chain/sync"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/sync/checkpoint"
|
||||||
initialsync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync"
|
initialsync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync"
|
||||||
"github.com/prysmaticlabs/prysm/cmd"
|
"github.com/prysmaticlabs/prysm/cmd"
|
||||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
||||||
@@ -101,6 +102,8 @@ type BeaconNode struct {
|
|||||||
slasherAttestationsFeed *event.Feed
|
slasherAttestationsFeed *event.Feed
|
||||||
finalizedStateAtStartUp state.BeaconState
|
finalizedStateAtStartUp state.BeaconState
|
||||||
serviceFlagOpts *serviceFlagOpts
|
serviceFlagOpts *serviceFlagOpts
|
||||||
|
blockchainFlagOpts []blockchain.Option
|
||||||
|
CheckpointInitializer checkpoint.Initializer
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new node instance, sets up configuration options, and registers
|
// New creates a new node instance, sets up configuration options, and registers
|
||||||
@@ -239,7 +242,7 @@ func New(cliCtx *cli.Context, opts ...Option) (*BeaconNode, error) {
|
|||||||
|
|
||||||
// db.DatabasePath is the path to the containing directory
|
// db.DatabasePath is the path to the containing directory
|
||||||
// db.NewDBFilename expands that to the canonical full path using
|
// db.NewDBFilename expands that to the canonical full path using
|
||||||
// the same constuction as NewDB()
|
// the same construction as NewDB()
|
||||||
c, err := newBeaconNodePromCollector(db.NewDBFilename(beacon.db.DatabasePath()))
|
c, err := newBeaconNodePromCollector(db.NewDBFilename(beacon.db.DatabasePath()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -396,6 +399,13 @@ func (b *BeaconNode) startDB(cliCtx *cli.Context, depositAddress string) error {
|
|||||||
if err := b.db.EnsureEmbeddedGenesis(b.ctx); err != nil {
|
if err := b.db.EnsureEmbeddedGenesis(b.ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.CheckpointInitializer != nil {
|
||||||
|
if err := b.CheckpointInitializer.Initialize(b.ctx, d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
knownContract, err := b.db.DepositContractAddress(b.ctx)
|
knownContract, err := b.db.DepositContractAddress(b.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -464,7 +474,29 @@ func (b *BeaconNode) startSlasherDB(cliCtx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *BeaconNode) startStateGen() error {
|
func (b *BeaconNode) startStateGen() error {
|
||||||
b.stateGen = stategen.New(b.db)
|
o := make([]stategen.StateGenOption, 0)
|
||||||
|
_, err := b.db.OriginCheckpointBlockRoot(b.ctx)
|
||||||
|
if err == nil {
|
||||||
|
// we'll get a db.ErrNotFound if the db was not initialized with a checkpoint
|
||||||
|
// so if err == nil, the node was initialized with checkpoint init.
|
||||||
|
o = append(o, stategen.WithInitType(stategen.BeaconDBInitTypeCheckpoint))
|
||||||
|
lowestSlot, err := b.db.LowestSyncedBlockSlot(b.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error searching for lowest block slot on checkpoint-initialized node")
|
||||||
|
}
|
||||||
|
o = append(o, stategen.WithMinimumSlot(lowestSlot))
|
||||||
|
} else {
|
||||||
|
if errors.Is(err, db.ErrNotFound) {
|
||||||
|
// error is ErrNotFound, so we can assume the node was initialized with a genesis state (or via powchain)
|
||||||
|
o = append(o, stategen.WithInitType(stategen.BeaconDBInitTypeGenesisState))
|
||||||
|
} else {
|
||||||
|
// if the error is not an ErrNotFound, we failed to query the db for some reason,
|
||||||
|
// can't be confident how it was initialized.
|
||||||
|
return errors.Wrap(err, "could not retrieve checkpoint sync chain origin data from db")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sg := stategen.New(b.db, o...)
|
||||||
|
|
||||||
cp, err := b.db.FinalizedCheckpoint(b.ctx)
|
cp, err := b.db.FinalizedCheckpoint(b.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -474,6 +506,12 @@ func (b *BeaconNode) startStateGen() error {
|
|||||||
r := bytesutil.ToBytes32(cp.Root)
|
r := bytesutil.ToBytes32(cp.Root)
|
||||||
// Consider edge case where finalized root are zeros instead of genesis root hash.
|
// Consider edge case where finalized root are zeros instead of genesis root hash.
|
||||||
if r == params.BeaconConfig().ZeroHash {
|
if r == params.BeaconConfig().ZeroHash {
|
||||||
|
if sg.MinimumSlot() > 0 {
|
||||||
|
// using checkpoint sync the minimum slot will be > 0, but the checkpoint block is marked as finalized,
|
||||||
|
// so if it is equal to ZeroHash, this is likely an error (and the genesis block won't be available).
|
||||||
|
msg := fmt.Sprintf("unable to retrieve genesis block, no slots before %d in db", sg.MinimumSlot())
|
||||||
|
return errors.Wrap(err, msg)
|
||||||
|
}
|
||||||
genesisBlock, err := b.db.GenesisBlock(b.ctx)
|
genesisBlock, err := b.db.GenesisBlock(b.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -486,10 +524,12 @@ func (b *BeaconNode) startStateGen() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b.finalizedStateAtStartUp, err = b.stateGen.StateByRoot(b.ctx, r)
|
b.finalizedStateAtStartUp, err = sg.StateByRoot(b.ctx, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.stateGen = sg
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ go_library(
|
|||||||
"structs_marshalling.go",
|
"structs_marshalling.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/rpc/apimiddleware",
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/rpc/apimiddleware",
|
||||||
visibility = ["//beacon-chain:__subpackages__"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//api/gateway/apimiddleware:go_default_library",
|
"//api/gateway/apimiddleware:go_default_library",
|
||||||
"//api/grpc:go_default_library",
|
"//api/grpc:go_default_library",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ func (_ *BeaconEndpointFactory) Paths() []string {
|
|||||||
"/eth/v1/beacon/pool/proposer_slashings",
|
"/eth/v1/beacon/pool/proposer_slashings",
|
||||||
"/eth/v1/beacon/pool/voluntary_exits",
|
"/eth/v1/beacon/pool/voluntary_exits",
|
||||||
"/eth/v1/beacon/pool/sync_committees",
|
"/eth/v1/beacon/pool/sync_committees",
|
||||||
|
"/eth/v1/beacon/weak_subjectivity",
|
||||||
"/eth/v1/node/identity",
|
"/eth/v1/node/identity",
|
||||||
"/eth/v1/node/peers",
|
"/eth/v1/node/peers",
|
||||||
"/eth/v1/node/peers/{peer_id}",
|
"/eth/v1/node/peers/{peer_id}",
|
||||||
@@ -141,6 +142,8 @@ func (_ *BeaconEndpointFactory) Create(path string) (*apimiddleware.Endpoint, er
|
|||||||
endpoint.Hooks = apimiddleware.HookCollection{
|
endpoint.Hooks = apimiddleware.HookCollection{
|
||||||
OnPreDeserializeRequestBodyIntoContainer: wrapSyncCommitteeSignaturesArray,
|
OnPreDeserializeRequestBodyIntoContainer: wrapSyncCommitteeSignaturesArray,
|
||||||
}
|
}
|
||||||
|
case "/eth/v1/beacon/weak_subjectivity":
|
||||||
|
endpoint.GetResponse = &WeakSubjectivityResponse{}
|
||||||
case "/eth/v1/node/identity":
|
case "/eth/v1/node/identity":
|
||||||
endpoint.GetResponse = &identityResponseJson{}
|
endpoint.GetResponse = &identityResponseJson{}
|
||||||
case "/eth/v1/node/peers":
|
case "/eth/v1/node/peers":
|
||||||
|
|||||||
@@ -19,6 +19,15 @@ type genesisResponse_GenesisJson struct {
|
|||||||
GenesisForkVersion string `json:"genesis_fork_version" hex:"true"`
|
GenesisForkVersion string `json:"genesis_fork_version" hex:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WeakSubjectivityResponse is used to marshal/unmarshal the response for the
|
||||||
|
// /eth/v1/beacon/weak_subjectivity endpoint.
|
||||||
|
type WeakSubjectivityResponse struct {
|
||||||
|
Data *struct {
|
||||||
|
Checkpoint *checkpointJson `json:"ws_checkpoint"`
|
||||||
|
StateRoot string `json:"state_root" hex:"true"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
// stateRootResponseJson is used in /beacon/states/{state_id}/root API endpoint.
|
// stateRootResponseJson is used in /beacon/states/{state_id}/root API endpoint.
|
||||||
type stateRootResponseJson struct {
|
type stateRootResponseJson struct {
|
||||||
Data *stateRootResponse_StateRootJson `json:"data"`
|
Data *stateRootResponse_StateRootJson `json:"data"`
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/ptypes/empty"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||||
@@ -17,6 +18,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/proto/migration"
|
"github.com/prysmaticlabs/prysm/proto/migration"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
||||||
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
@@ -40,6 +42,43 @@ func (e *blockIdParseError) Error() string {
|
|||||||
return e.message
|
return e.message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetWeakSubjectivity computes the starting epoch of the current weak subjectivity period, and then also
|
||||||
|
// determines the best block root and state root to use for a Checkpoint Sync starting from that point.
|
||||||
|
func (bs *Server) GetWeakSubjectivity(ctx context.Context, _ *empty.Empty) (*ethpbv1.WeakSubjectivityResponse, error) {
|
||||||
|
hs, err := bs.HeadFetcher.HeadState(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, "could not get head state")
|
||||||
|
}
|
||||||
|
wsEpoch, err := helpers.LatestWeakSubjectivityEpoch(ctx, hs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "could not get weak subjectivity epoch: %v", err)
|
||||||
|
}
|
||||||
|
wsSlot, err := slots.EpochStart(wsEpoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "could not get weak subjectivity slot: %v", err)
|
||||||
|
}
|
||||||
|
blks, err := bs.BeaconDB.HighestSlotBlocksBelow(ctx, wsSlot+1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, fmt.Sprintf("could not find highest block below slot %d", wsSlot))
|
||||||
|
}
|
||||||
|
block := blks[0]
|
||||||
|
blockRoot, err := block.Block().HashTreeRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, fmt.Sprintf("failed to compute hash_tree_root for block at slot=%d", block.Block().Slot()))
|
||||||
|
}
|
||||||
|
stateRoot := bytesutil.ToBytes32(block.Block().StateRoot())
|
||||||
|
log.Printf("weak subjectivity checkpoint reported as epoch=%d, block root=%#x, state root=%#x", wsEpoch, blockRoot, stateRoot)
|
||||||
|
return ðpbv1.WeakSubjectivityResponse{
|
||||||
|
Data: ðpbv1.WeakSubjectivityData{
|
||||||
|
WsCheckpoint: ðpbv1.Checkpoint{
|
||||||
|
Epoch: wsEpoch,
|
||||||
|
Root: blockRoot[:],
|
||||||
|
},
|
||||||
|
StateRoot: stateRoot[:],
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlockHeader retrieves block header for given block id.
|
// GetBlockHeader retrieves block header for given block id.
|
||||||
func (bs *Server) GetBlockHeader(ctx context.Context, req *ethpbv1.BlockRequest) (*ethpbv1.BlockHeaderResponse, error) {
|
func (bs *Server) GetBlockHeader(ctx context.Context, req *ethpbv1.BlockRequest) (*ethpbv1.BlockHeaderResponse, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockHeader")
|
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockHeader")
|
||||||
@@ -48,7 +87,7 @@ func (bs *Server) GetBlockHeader(ctx context.Context, req *ethpbv1.BlockRequest)
|
|||||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||||
err = handleGetBlockError(blk, err)
|
err = handleGetBlockError(blk, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "GetBlockHeader")
|
||||||
}
|
}
|
||||||
v1alpha1Header, err := blk.Header()
|
v1alpha1Header, err := blk.Header()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -267,7 +306,7 @@ func (bs *Server) GetBlock(ctx context.Context, req *ethpbv1.BlockRequest) (*eth
|
|||||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||||
err = handleGetBlockError(blk, err)
|
err = handleGetBlockError(blk, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "GetBlock")
|
||||||
}
|
}
|
||||||
signedBeaconBlock, err := migration.SignedBeaconBlock(blk)
|
signedBeaconBlock, err := migration.SignedBeaconBlock(blk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -290,7 +329,7 @@ func (bs *Server) GetBlockSSZ(ctx context.Context, req *ethpbv1.BlockRequest) (*
|
|||||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||||
err = handleGetBlockError(blk, err)
|
err = handleGetBlockError(blk, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "GetBlockSSZ")
|
||||||
}
|
}
|
||||||
signedBeaconBlock, err := migration.SignedBeaconBlock(blk)
|
signedBeaconBlock, err := migration.SignedBeaconBlock(blk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -312,7 +351,7 @@ func (bs *Server) GetBlockV2(ctx context.Context, req *ethpbv2.BlockRequestV2) (
|
|||||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||||
err = handleGetBlockError(blk, err)
|
err = handleGetBlockError(blk, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "GetBlockV2")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = blk.PbPhase0Block()
|
_, err = blk.PbPhase0Block()
|
||||||
@@ -389,7 +428,7 @@ func (bs *Server) GetBlockSSZV2(ctx context.Context, req *ethpbv2.BlockRequestV2
|
|||||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||||
err = handleGetBlockError(blk, err)
|
err = handleGetBlockError(blk, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "GetBlockSSZV2")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = blk.PbPhase0Block()
|
_, err = blk.PbPhase0Block()
|
||||||
|
|||||||
@@ -117,12 +117,7 @@ func (bs *Server) GetFinalityCheckpoints(ctx context.Context, req *ethpb.StateRe
|
|||||||
|
|
||||||
st, err = bs.StateFetcher.State(ctx, req.StateId)
|
st, err = bs.StateFetcher.State(ctx, req.StateId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||||
return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
|
||||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
|
||||||
}
|
|
||||||
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ðpb.StateFinalityCheckpointResponse{
|
return ðpb.StateFinalityCheckpointResponse{
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ go_library(
|
|||||||
"//beacon-chain/blockchain:go_default_library",
|
"//beacon-chain/blockchain:go_default_library",
|
||||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
|
"//beacon-chain/state/stategen:go_default_library",
|
||||||
"//beacon-chain/sync:go_default_library",
|
"//beacon-chain/sync:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
"//proto/eth/v1:go_default_library",
|
"//proto/eth/v1:go_default_library",
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package helpers
|
package helpers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/statefetcher"
|
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/statefetcher"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
@@ -9,9 +12,13 @@ import (
|
|||||||
// PrepareStateFetchGRPCError returns an appropriate gRPC error based on the supplied argument.
|
// PrepareStateFetchGRPCError returns an appropriate gRPC error based on the supplied argument.
|
||||||
// The argument error should be a result of fetching state.
|
// The argument error should be a result of fetching state.
|
||||||
func PrepareStateFetchGRPCError(err error) error {
|
func PrepareStateFetchGRPCError(err error) error {
|
||||||
|
if errors.Is(err, stategen.ErrSlotBeforeOrigin) {
|
||||||
|
return status.Errorf(codes.NotFound, "lacking historical data needed to fulfill request")
|
||||||
|
}
|
||||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||||
return status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
return status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
||||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
}
|
||||||
|
if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||||
return status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
return status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||||
}
|
}
|
||||||
return status.Errorf(codes.Internal, "Invalid state ID: %v", err)
|
return status.Errorf(codes.Internal, "Invalid state ID: %v", err)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package beacon
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -397,11 +396,6 @@ func (bs *Server) chainHeadRetrieval(ctx context.Context) (*ethpb.ChainHead, err
|
|||||||
isGenesis := func(cp *ethpb.Checkpoint) bool {
|
isGenesis := func(cp *ethpb.Checkpoint) bool {
|
||||||
return bytesutil.ToBytes32(cp.Root) == params.BeaconConfig().ZeroHash && cp.Epoch == 0
|
return bytesutil.ToBytes32(cp.Root) == params.BeaconConfig().ZeroHash && cp.Epoch == 0
|
||||||
}
|
}
|
||||||
// Retrieve genesis block in the event we have genesis checkpoints.
|
|
||||||
genBlock, err := bs.BeaconDB.GenesisBlock(ctx)
|
|
||||||
if err != nil || genBlock == nil || genBlock.IsNil() || genBlock.Block().IsNil() {
|
|
||||||
return nil, status.Error(codes.Internal, "Could not get genesis block")
|
|
||||||
}
|
|
||||||
|
|
||||||
finalizedCheckpoint := bs.FinalizationFetcher.FinalizedCheckpt()
|
finalizedCheckpoint := bs.FinalizationFetcher.FinalizedCheckpt()
|
||||||
if !isGenesis(finalizedCheckpoint) {
|
if !isGenesis(finalizedCheckpoint) {
|
||||||
@@ -463,40 +457,3 @@ func (bs *Server) chainHeadRetrieval(ctx context.Context) (*ethpb.ChainHead, err
|
|||||||
PreviousJustifiedBlockRoot: prevJustifiedCheckpoint.Root,
|
PreviousJustifiedBlockRoot: prevJustifiedCheckpoint.Root,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWeakSubjectivityCheckpoint retrieves weak subjectivity state root, block root, and epoch.
|
|
||||||
func (bs *Server) GetWeakSubjectivityCheckpoint(ctx context.Context, _ *emptypb.Empty) (*ethpb.WeakSubjectivityCheckpoint, error) {
|
|
||||||
hs, err := bs.HeadFetcher.HeadState(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.Internal, "Could not get head state")
|
|
||||||
}
|
|
||||||
wsEpoch, err := helpers.LatestWeakSubjectivityEpoch(ctx, hs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.Internal, "Could not get weak subjectivity epoch")
|
|
||||||
}
|
|
||||||
wsSlot, err := slots.EpochStart(wsEpoch)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.Internal, "Could not get weak subjectivity slot")
|
|
||||||
}
|
|
||||||
|
|
||||||
wsState, err := bs.ReplayerBuilder.ForSlot(wsSlot).ReplayBlocks(ctx)
|
|
||||||
if err != nil {
|
|
||||||
msg := fmt.Sprintf("error replaying blocks for state at slot %d: %v", wsSlot, err)
|
|
||||||
return nil, status.Error(codes.Internal, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
stateRoot, err := wsState.HashTreeRoot(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.Internal, "Could not get weak subjectivity state root")
|
|
||||||
}
|
|
||||||
blkRoot, err := wsState.LatestBlockHeader().HashTreeRoot()
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.Internal, "Could not get weak subjectivity block root")
|
|
||||||
}
|
|
||||||
|
|
||||||
return ðpb.WeakSubjectivityCheckpoint{
|
|
||||||
BlockRoot: blkRoot[:],
|
|
||||||
StateRoot: stateRoot[:],
|
|
||||||
Epoch: wsEpoch,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ func (p *StateProvider) State(ctx context.Context, stateId []byte) (state.Beacon
|
|||||||
return nil, errors.Wrap(err, "could not get head state")
|
return nil, errors.Wrap(err, "could not get head state")
|
||||||
}
|
}
|
||||||
case "genesis":
|
case "genesis":
|
||||||
s, err = p.BeaconDB.GenesisState(ctx)
|
s, err = p.StateBySlot(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get genesis state")
|
return nil, errors.Wrap(err, "could not get genesis state")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,8 +73,11 @@ func TestGetState(t *testing.T) {
|
|||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, r))
|
require.NoError(t, db.SaveGenesisBlockRoot(ctx, r))
|
||||||
require.NoError(t, db.SaveState(ctx, bs, r))
|
require.NoError(t, db.SaveState(ctx, bs, r))
|
||||||
|
|
||||||
|
cc := &mockstategen.MockCanonicalChecker{Is: true}
|
||||||
|
cs := &mockstategen.MockCurrentSlotter{Slot: bs.Slot() + 1}
|
||||||
p := StateProvider{
|
p := StateProvider{
|
||||||
BeaconDB: db,
|
BeaconDB: db,
|
||||||
|
ReplayerBuilder: stategen.NewCanonicalBuilder(db, cc, cs),
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := p.State(ctx, []byte("genesis"))
|
s, err := p.State(ctx, []byte("genesis"))
|
||||||
|
|||||||
@@ -10,21 +10,7 @@ go_library(
|
|||||||
"prometheus.go",
|
"prometheus.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state",
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state",
|
||||||
visibility = [
|
visibility = ["//visibility:public"],
|
||||||
"//beacon-chain:__subpackages__",
|
|
||||||
"//contracts/deposit:__subpackages__",
|
|
||||||
"//proto/migration:__pkg__",
|
|
||||||
"//proto/prysm/v1alpha1:__subpackages__",
|
|
||||||
"//proto/testing:__subpackages__",
|
|
||||||
"//slasher/rpc:__subpackages__",
|
|
||||||
"//testing/benchmark:__pkg__",
|
|
||||||
"//testing/slasher/simulator:__pkg__",
|
|
||||||
"//testing/spectest:__subpackages__",
|
|
||||||
"//testing/util:__pkg__",
|
|
||||||
"//tools/benchmark-files-gen:__pkg__",
|
|
||||||
"//tools/exploredb:__pkg__",
|
|
||||||
"//tools/pcli:__pkg__",
|
|
||||||
],
|
|
||||||
deps = [
|
deps = [
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
@@ -30,27 +28,6 @@ func InitializeFromProto(st *ethpb.BeaconStateAltair) (state.BeaconStateAltair,
|
|||||||
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconStateAltair))
|
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconStateAltair))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitializeFromSSZReader can be used when the source for a serialized BeaconState object
|
|
||||||
// is an io.Reader. This allows client code to remain agnostic about whether the data comes
|
|
||||||
// from the network or a file without needing to read the entire state into mem as a large byte slice.
|
|
||||||
func InitializeFromSSZReader(r io.Reader) (state.BeaconStateAltair, error) {
|
|
||||||
b, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return InitializeFromSSZBytes(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitializeFromSSZBytes is a convenience method to obtain a BeaconState by unmarshaling
|
|
||||||
// a slice of bytes containing the ssz-serialized representation of the state.
|
|
||||||
func InitializeFromSSZBytes(marshaled []byte) (*BeaconState, error) {
|
|
||||||
st := ðpb.BeaconStateAltair{}
|
|
||||||
if err := st.UnmarshalSSZ(marshaled); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return InitializeFromProtoUnsafe(st)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitializeFromProtoUnsafe directly uses the beacon state protobuf fields
|
// InitializeFromProtoUnsafe directly uses the beacon state protobuf fields
|
||||||
// and sets them as fields of the BeaconState type.
|
// and sets them as fields of the BeaconState type.
|
||||||
func InitializeFromProtoUnsafe(st *ethpb.BeaconStateAltair) (*BeaconState, error) {
|
func InitializeFromProtoUnsafe(st *ethpb.BeaconStateAltair) (*BeaconState, error) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package stategen
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
@@ -13,6 +14,8 @@ import (
|
|||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrSlotBeforeOrigin = errors.New("cannot retrieve data for slots before sync origin")
|
||||||
|
|
||||||
// HasState returns true if the state exists in cache or in DB.
|
// HasState returns true if the state exists in cache or in DB.
|
||||||
func (s *State) HasState(ctx context.Context, blockRoot [32]byte) (bool, error) {
|
func (s *State) HasState(ctx context.Context, blockRoot [32]byte) (bool, error) {
|
||||||
has, err := s.HasStateInCache(ctx, blockRoot)
|
has, err := s.HasStateInCache(ctx, blockRoot)
|
||||||
@@ -53,6 +56,9 @@ func (s *State) StateByRoot(ctx context.Context, blockRoot [32]byte) (state.Beac
|
|||||||
|
|
||||||
// Genesis case. If block root is zero hash, short circuit to use genesis cachedState stored in DB.
|
// Genesis case. If block root is zero hash, short circuit to use genesis cachedState stored in DB.
|
||||||
if blockRoot == params.BeaconConfig().ZeroHash {
|
if blockRoot == params.BeaconConfig().ZeroHash {
|
||||||
|
if s.MinimumSlot() > 0 {
|
||||||
|
return nil, errors.Wrapf(ErrSlotBeforeOrigin, "cannot retrieve genesis state, lowest block in db is slot %d", s.MinimumSlot())
|
||||||
|
}
|
||||||
return s.beaconDB.GenesisState(ctx)
|
return s.beaconDB.GenesisState(ctx)
|
||||||
}
|
}
|
||||||
return s.loadStateByRoot(ctx, blockRoot)
|
return s.loadStateByRoot(ctx, blockRoot)
|
||||||
@@ -66,6 +72,9 @@ func (s *State) StateByRoot(ctx context.Context, blockRoot [32]byte) (state.Beac
|
|||||||
func (s *State) StateByRootInitialSync(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error) {
|
func (s *State) StateByRootInitialSync(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error) {
|
||||||
// Genesis case. If block root is zero hash, short circuit to use genesis state stored in DB.
|
// Genesis case. If block root is zero hash, short circuit to use genesis state stored in DB.
|
||||||
if blockRoot == params.BeaconConfig().ZeroHash {
|
if blockRoot == params.BeaconConfig().ZeroHash {
|
||||||
|
if s.beaconDBInitType == BeaconDBInitTypeCheckpoint {
|
||||||
|
return nil, fmt.Errorf("node initialized through checkpoint sync received invalid (zero value) block root")
|
||||||
|
}
|
||||||
return s.beaconDB.GenesisState(ctx)
|
return s.beaconDB.GenesisState(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +222,10 @@ func (s *State) loadStateBySlot(ctx context.Context, slot types.Slot) (state.Bea
|
|||||||
ctx, span := trace.StartSpan(ctx, "stateGen.loadStateBySlot")
|
ctx, span := trace.StartSpan(ctx, "stateGen.loadStateBySlot")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
if slot < s.MinimumSlot() {
|
||||||
|
return nil, errors.Wrapf(ErrSlotBeforeOrigin, "no data from before slot %d", s.MinimumSlot())
|
||||||
|
}
|
||||||
|
|
||||||
// Return genesis state if slot is 0.
|
// Return genesis state if slot is 0.
|
||||||
if slot == 0 {
|
if slot == 0 {
|
||||||
return s.beaconDB.GenesisState(ctx)
|
return s.beaconDB.GenesisState(ctx)
|
||||||
@@ -266,6 +279,11 @@ func (s *State) LastAncestorState(ctx context.Context, root [32]byte) (state.Bea
|
|||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return an error if we have rewound to before the checkpoint sync slot
|
||||||
|
if (b.Block().Slot() - 1) < s.MinimumSlot() {
|
||||||
|
return nil, errors.Wrapf(ErrSlotBeforeOrigin, "no blocks in db prior to slot %d", s.MinimumSlot())
|
||||||
|
}
|
||||||
// Is the state a genesis state.
|
// Is the state a genesis state.
|
||||||
parentRoot := bytesutil.ToBytes32(b.Block().ParentRoot())
|
parentRoot := bytesutil.ToBytes32(b.Block().ParentRoot())
|
||||||
if parentRoot == params.BeaconConfig().ZeroHash {
|
if parentRoot == params.BeaconConfig().ZeroHash {
|
||||||
|
|||||||
@@ -242,9 +242,17 @@ func (s *State) lastSavedBlock(ctx context.Context, slot types.Slot) ([32]byte,
|
|||||||
ctx, span := trace.StartSpan(ctx, "stateGen.lastSavedBlock")
|
ctx, span := trace.StartSpan(ctx, "stateGen.lastSavedBlock")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
if slot < s.MinimumSlot() {
|
||||||
|
return [32]byte{}, 0, errors.Wrapf(ErrSlotBeforeOrigin, "no data from before slot %d", s.MinimumSlot())
|
||||||
|
}
|
||||||
|
|
||||||
// Handle the genesis case where the input slot is 0.
|
// Handle the genesis case where the input slot is 0.
|
||||||
if slot == 0 {
|
if slot == 0 {
|
||||||
gRoot, err := s.genesisRoot(ctx)
|
gb, err := s.beaconDB.GenesisBlock(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, 0, err
|
||||||
|
}
|
||||||
|
gRoot, err := gb.Block().HashTreeRoot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return [32]byte{}, 0, err
|
return [32]byte{}, 0, err
|
||||||
}
|
}
|
||||||
@@ -278,6 +286,10 @@ func (s *State) lastSavedState(ctx context.Context, slot types.Slot) (state.Read
|
|||||||
ctx, span := trace.StartSpan(ctx, "stateGen.lastSavedState")
|
ctx, span := trace.StartSpan(ctx, "stateGen.lastSavedState")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
if slot < s.MinimumSlot() {
|
||||||
|
return nil, errors.Wrapf(ErrSlotBeforeOrigin, "no data from before slot %d", s.MinimumSlot())
|
||||||
|
}
|
||||||
|
|
||||||
// Handle the genesis case where the input slot is 0.
|
// Handle the genesis case where the input slot is 0.
|
||||||
if slot == 0 {
|
if slot == 0 {
|
||||||
return s.beaconDB.GenesisState(ctx)
|
return s.beaconDB.GenesisState(ctx)
|
||||||
@@ -299,15 +311,6 @@ func (s *State) lastSavedState(ctx context.Context, slot types.Slot) (state.Read
|
|||||||
return lastSaved[0], nil
|
return lastSaved[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This returns the genesis root.
|
|
||||||
func (s *State) genesisRoot(ctx context.Context) ([32]byte, error) {
|
|
||||||
b, err := s.beaconDB.GenesisBlock(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
return b.Block().HashTreeRoot()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given the start slot and the end slot, this returns the finalized beacon blocks in between.
|
// Given the start slot and the end slot, this returns the finalized beacon blocks in between.
|
||||||
// Since hot states don't have finalized blocks, this should ONLY be used for replaying cold state.
|
// Since hot states don't have finalized blocks, this should ONLY be used for replaying cold state.
|
||||||
func (s *State) loadFinalizedBlocks(ctx context.Context, startSlot, endSlot types.Slot) ([]block.SignedBeaconBlock, error) {
|
func (s *State) loadFinalizedBlocks(ctx context.Context, startSlot, endSlot types.Slot) ([]block.SignedBeaconBlock, error) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package stategen
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
@@ -49,6 +50,8 @@ type State struct {
|
|||||||
finalizedInfo *finalizedInfo
|
finalizedInfo *finalizedInfo
|
||||||
epochBoundaryStateCache *epochBoundaryState
|
epochBoundaryStateCache *epochBoundaryState
|
||||||
saveHotStateDB *saveHotStateDbConfig
|
saveHotStateDB *saveHotStateDbConfig
|
||||||
|
minimumSlot types.Slot
|
||||||
|
beaconDBInitType BeaconDBInitType
|
||||||
}
|
}
|
||||||
|
|
||||||
// This tracks the config in the event of long non-finality,
|
// This tracks the config in the event of long non-finality,
|
||||||
@@ -70,9 +73,31 @@ type finalizedInfo struct {
|
|||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithMinimumSlot(min types.Slot) StateGenOption {
|
||||||
|
return func(s *State) {
|
||||||
|
s.minimumSlot = min
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type BeaconDBInitType uint
|
||||||
|
|
||||||
|
const (
|
||||||
|
BeaconDBInitTypeGenesisState = iota
|
||||||
|
BeaconDBInitTypeCheckpoint
|
||||||
|
)
|
||||||
|
|
||||||
|
func WithInitType(t BeaconDBInitType) StateGenOption {
|
||||||
|
return func(s *State) {
|
||||||
|
s.beaconDBInitType = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateGenOption is a functional option for controlling the initialization of a *State value
|
||||||
|
type StateGenOption func(*State)
|
||||||
|
|
||||||
// New returns a new state management object.
|
// New returns a new state management object.
|
||||||
func New(beaconDB db.NoHeadAccessDatabase) *State {
|
func New(beaconDB db.NoHeadAccessDatabase, opts ...StateGenOption) *State {
|
||||||
return &State{
|
s := &State{
|
||||||
beaconDB: beaconDB,
|
beaconDB: beaconDB,
|
||||||
hotStateCache: newHotStateCache(),
|
hotStateCache: newHotStateCache(),
|
||||||
finalizedInfo: &finalizedInfo{slot: 0, root: params.BeaconConfig().ZeroHash},
|
finalizedInfo: &finalizedInfo{slot: 0, root: params.BeaconConfig().ZeroHash},
|
||||||
@@ -81,7 +106,13 @@ func New(beaconDB db.NoHeadAccessDatabase) *State {
|
|||||||
saveHotStateDB: &saveHotStateDbConfig{
|
saveHotStateDB: &saveHotStateDbConfig{
|
||||||
duration: defaultHotStateDBInterval,
|
duration: defaultHotStateDBInterval,
|
||||||
},
|
},
|
||||||
|
// defaults to minimumSlot of zero (genesis), overridden by checkpoint sync
|
||||||
|
minimumSlot: types.Slot(0),
|
||||||
}
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(s)
|
||||||
|
}
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resume resumes a new state management object from previously saved finalized check point in DB.
|
// Resume resumes a new state management object from previously saved finalized check point in DB.
|
||||||
@@ -96,6 +127,9 @@ func (s *State) Resume(ctx context.Context, fState state.BeaconState) (state.Bea
|
|||||||
fRoot := bytesutil.ToBytes32(c.Root)
|
fRoot := bytesutil.ToBytes32(c.Root)
|
||||||
// Resume as genesis state if last finalized root is zero hashes.
|
// Resume as genesis state if last finalized root is zero hashes.
|
||||||
if fRoot == params.BeaconConfig().ZeroHash {
|
if fRoot == params.BeaconConfig().ZeroHash {
|
||||||
|
if s.MinimumSlot() > 0 {
|
||||||
|
return nil, fmt.Errorf("no finalized checkpoint, and history before slot %d not currently available", s.MinimumSlot())
|
||||||
|
}
|
||||||
return s.beaconDB.GenesisState(ctx)
|
return s.beaconDB.GenesisState(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,3 +172,7 @@ func (s *State) finalizedState() state.BeaconState {
|
|||||||
defer s.finalizedInfo.lock.RUnlock()
|
defer s.finalizedInfo.lock.RUnlock()
|
||||||
return s.finalizedInfo.state.Copy()
|
return s.finalizedInfo.state.Copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *State) MinimumSlot() types.Slot {
|
||||||
|
return s.minimumSlot
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,20 +29,7 @@ go_library(
|
|||||||
"unsupported_setters.go",
|
"unsupported_setters.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v1",
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v1",
|
||||||
visibility = [
|
visibility = ["//visibility:public"],
|
||||||
"//beacon-chain:__subpackages__",
|
|
||||||
"//contracts/deposit:__subpackages__",
|
|
||||||
"//proto/migration:__subpackages__",
|
|
||||||
"//proto/prysm/v1alpha1:__subpackages__",
|
|
||||||
"//proto/testing:__subpackages__",
|
|
||||||
"//runtime/interop:__subpackages__",
|
|
||||||
"//slasher/rpc:__subpackages__",
|
|
||||||
"//testing/benchmark:__pkg__",
|
|
||||||
"//testing/spectest:__subpackages__",
|
|
||||||
"//testing/util:__pkg__",
|
|
||||||
"//tools/benchmark-files-gen:__pkg__",
|
|
||||||
"//tools/pcli:__pkg__",
|
|
||||||
],
|
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/fieldtrie:go_default_library",
|
"//beacon-chain/state/fieldtrie:go_default_library",
|
||||||
|
|||||||
@@ -31,6 +31,16 @@ func InitializeFromProto(st *ethpb.BeaconState) (state.BeaconState, error) {
|
|||||||
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconState))
|
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconState))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitializeFromSSZBytes is a convenience method to obtain a BeaconState by unmarshaling
|
||||||
|
// a slice of bytes containing the ssz-serialized representation of the state.
|
||||||
|
func InitializeFromSSZBytes(marshaled []byte) (state.BeaconState, error) {
|
||||||
|
st := ðpb.BeaconState{}
|
||||||
|
if err := st.UnmarshalSSZ(marshaled); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return InitializeFromProtoUnsafe(st)
|
||||||
|
}
|
||||||
|
|
||||||
// InitializeFromProtoUnsafe directly uses the beacon state protobuf pointer
|
// InitializeFromProtoUnsafe directly uses the beacon state protobuf pointer
|
||||||
// and sets it as the inner state of the BeaconState type.
|
// and sets it as the inner state of the BeaconState type.
|
||||||
func InitializeFromProtoUnsafe(st *ethpb.BeaconState) (state.BeaconState, error) {
|
func InitializeFromProtoUnsafe(st *ethpb.BeaconState) (state.BeaconState, error) {
|
||||||
|
|||||||
@@ -29,12 +29,7 @@ go_library(
|
|||||||
"types.go",
|
"types.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v2",
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v2",
|
||||||
visibility = [
|
visibility = ["//visibility:public"],
|
||||||
"//beacon-chain:__subpackages__",
|
|
||||||
"//proto/migration:__subpackages__",
|
|
||||||
"//testing/spectest:__subpackages__",
|
|
||||||
"//testing/util:__pkg__",
|
|
||||||
],
|
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/fieldtrie:go_default_library",
|
"//beacon-chain/state/fieldtrie:go_default_library",
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
@@ -33,26 +31,9 @@ func InitializeFromProto(st *ethpb.BeaconStateAltair) (state.BeaconStateAltair,
|
|||||||
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconStateAltair))
|
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconStateAltair))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitializeFromSSZReader can be used when the source for a serialized BeaconState object
|
|
||||||
// is an io.Reader. This allows client code to remain agnostic about whether the data comes
|
|
||||||
// from the network or a file without needing to read the entire state into mem as a large byte slice.
|
|
||||||
func InitializeFromSSZReader(r io.Reader) (state.BeaconStateAltair, error) {
|
|
||||||
if features.Get().EnableNativeState {
|
|
||||||
return statenative.InitializeFromSSZReader(r)
|
|
||||||
}
|
|
||||||
b, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return InitializeFromSSZBytes(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitializeFromSSZBytes is a convenience method to obtain a BeaconState by unmarshaling
|
// InitializeFromSSZBytes is a convenience method to obtain a BeaconState by unmarshaling
|
||||||
// a slice of bytes containing the ssz-serialized representation of the state.
|
// a slice of bytes containing the ssz-serialized representation of the state.
|
||||||
func InitializeFromSSZBytes(marshaled []byte) (state.BeaconStateAltair, error) {
|
func InitializeFromSSZBytes(marshaled []byte) (state.BeaconStateAltair, error) {
|
||||||
if features.Get().EnableNativeState {
|
|
||||||
return statenative.InitializeFromSSZBytes(marshaled)
|
|
||||||
}
|
|
||||||
st := ðpb.BeaconStateAltair{}
|
st := ðpb.BeaconStateAltair{}
|
||||||
if err := st.UnmarshalSSZ(marshaled); err != nil {
|
if err := st.UnmarshalSSZ(marshaled); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -31,11 +31,7 @@ go_library(
|
|||||||
"types.go",
|
"types.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v3",
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v3",
|
||||||
visibility = [
|
visibility = ["//visibility:public"],
|
||||||
"//beacon-chain:__subpackages__",
|
|
||||||
"//testing/spectest:__subpackages__",
|
|
||||||
"//testing/util:__pkg__",
|
|
||||||
],
|
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/fieldtrie:go_default_library",
|
"//beacon-chain/state/fieldtrie:go_default_library",
|
||||||
|
|||||||
@@ -31,6 +31,16 @@ func InitializeFromProto(st *ethpb.BeaconStateBellatrix) (state.BeaconStateBella
|
|||||||
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconStateBellatrix))
|
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconStateBellatrix))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitializeFromSSZBytes is a convenience method to obtain a BeaconState by unmarshaling
|
||||||
|
// a slice of bytes containing the ssz-serialized representation of the state.
|
||||||
|
func InitializeFromSSZBytes(marshaled []byte) (state.BeaconState, error) {
|
||||||
|
st := ðpb.BeaconStateBellatrix{}
|
||||||
|
if err := st.UnmarshalSSZ(marshaled); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return InitializeFromProtoUnsafe(st)
|
||||||
|
}
|
||||||
|
|
||||||
// InitializeFromProtoUnsafe directly uses the beacon state protobuf pointer
|
// InitializeFromProtoUnsafe directly uses the beacon state protobuf pointer
|
||||||
// and sets it as the inner state of the BeaconState type.
|
// and sets it as the inner state of the BeaconState type.
|
||||||
func InitializeFromProtoUnsafe(st *ethpb.BeaconStateBellatrix) (state.BeaconStateBellatrix, error) {
|
func InitializeFromProtoUnsafe(st *ethpb.BeaconStateBellatrix) (state.BeaconStateBellatrix, error) {
|
||||||
|
|||||||
17
beacon-chain/sync/checkpoint/BUILD.bazel
Normal file
17
beacon-chain/sync/checkpoint/BUILD.bazel
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"api.go",
|
||||||
|
"file.go",
|
||||||
|
],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/sync/checkpoint",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//api/client/beacon:go_default_library",
|
||||||
|
"//beacon-chain/db:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
29
beacon-chain/sync/checkpoint/api.go
Normal file
29
beacon-chain/sync/checkpoint/api.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package checkpoint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/api/client/beacon"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
type APIInitializer struct {
|
||||||
|
c *beacon.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAPIInitializer(beaconNodeHost string) (*APIInitializer, error) {
|
||||||
|
c, err := beacon.NewClient(beaconNodeHost)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "unable to parse beacon node url or hostname - %s", beaconNodeHost)
|
||||||
|
}
|
||||||
|
return &APIInitializer{c: c}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dl *APIInitializer) Initialize(ctx context.Context, d db.Database) error {
|
||||||
|
od, err := beacon.DownloadOriginData(ctx, dl.c)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Error retrieving checkpoint origin state and block")
|
||||||
|
}
|
||||||
|
return d.SaveOrigin(ctx, od.StateBytes(), od.BlockBytes())
|
||||||
|
}
|
||||||
84
beacon-chain/sync/checkpoint/file.go
Normal file
84
beacon-chain/sync/checkpoint/file.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package checkpoint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Initializer interface {
|
||||||
|
Initialize(ctx context.Context, d db.Database) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileInitializer(blockPath string, statePath string) (*FileInitializer, error) {
|
||||||
|
var err error
|
||||||
|
if err = existsAndIsFile(blockPath); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = existsAndIsFile(statePath); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// stat just to make sure it actually exists and is a file
|
||||||
|
return &FileInitializer{blockPath: blockPath, statePath: statePath}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileInitializer initializes a beacon-node database to use checkpoint sync,
|
||||||
|
// using ssz-encoded block and state data stored in files on the local filesystem.
|
||||||
|
type FileInitializer struct {
|
||||||
|
blockPath string
|
||||||
|
statePath string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize is called in the BeaconNode db startup code if an Initializer is present.
|
||||||
|
// Initialize does what is needed to prepare the beacon node database for syncing from the weak subjectivity checkpoint.
|
||||||
|
func (fi *FileInitializer) Initialize(ctx context.Context, d db.Database) error {
|
||||||
|
blockFH, err := os.Open(fi.blockPath)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error opening block file %s for checkpoint sync initialization", fi.blockPath)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := blockFH.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("error while closing checkpoint block input stream: %s", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
serBlock, err := ioutil.ReadAll(blockFH)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error reading block file %s for checkpoint sync initialization", fi.blockPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
stateFH, err := os.Open(fi.statePath)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error reading state file %s for checkpoint sync initialization", fi.statePath)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := stateFH.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("error while closing checkpoint state input stream: %s", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
serState, err := ioutil.ReadAll(stateFH)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error reading block file %s for checkpoint sync initialization", fi.statePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.SaveOrigin(ctx, serState, serBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Initializer = &FileInitializer{}
|
||||||
|
|
||||||
|
func existsAndIsFile(path string) error {
|
||||||
|
info, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error checking existence of ssz-encoded file %s for checkpoint sync init", path)
|
||||||
|
}
|
||||||
|
if info.IsDir() {
|
||||||
|
return fmt.Errorf("%s is a directory, please specify full path to file", path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -234,7 +234,7 @@ func (s *Service) processBlock(
|
|||||||
s.logSyncStatus(genesis, blk.Block(), blkRoot)
|
s.logSyncStatus(genesis, blk.Block(), blkRoot)
|
||||||
parentRoot := bytesutil.ToBytes32(blk.Block().ParentRoot())
|
parentRoot := bytesutil.ToBytes32(blk.Block().ParentRoot())
|
||||||
if !s.cfg.DB.HasBlock(ctx, parentRoot) && !s.cfg.Chain.HasInitSyncBlock(parentRoot) {
|
if !s.cfg.DB.HasBlock(ctx, parentRoot) && !s.cfg.Chain.HasInitSyncBlock(parentRoot) {
|
||||||
return fmt.Errorf("%w: %#x", errParentDoesNotExist, blk.Block().ParentRoot())
|
return fmt.Errorf("%w: (in processBlock, slot=%d) %#x", errParentDoesNotExist, blk.Block().Slot(), blk.Block().ParentRoot())
|
||||||
}
|
}
|
||||||
return blockReceiver(ctx, blk, blkRoot)
|
return blockReceiver(ctx, blk, blkRoot)
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ func (s *Service) processBatchedBlocks(ctx context.Context, genesis time.Time,
|
|||||||
s.logBatchSyncStatus(genesis, blks, blkRoot)
|
s.logBatchSyncStatus(genesis, blks, blkRoot)
|
||||||
parentRoot := bytesutil.ToBytes32(firstBlock.Block().ParentRoot())
|
parentRoot := bytesutil.ToBytes32(firstBlock.Block().ParentRoot())
|
||||||
if !s.cfg.DB.HasBlock(ctx, parentRoot) && !s.cfg.Chain.HasInitSyncBlock(parentRoot) {
|
if !s.cfg.DB.HasBlock(ctx, parentRoot) && !s.cfg.Chain.HasInitSyncBlock(parentRoot) {
|
||||||
return fmt.Errorf("%w: %#x", errParentDoesNotExist, firstBlock.Block().ParentRoot())
|
return fmt.Errorf("%w: %#x (in processBatchedBlocks, slot=%d)", errParentDoesNotExist, firstBlock.Block().ParentRoot(), firstBlock.Block().Slot())
|
||||||
}
|
}
|
||||||
blockRoots := make([][32]byte, len(blks))
|
blockRoots := make([][32]byte, len(blks))
|
||||||
blockRoots[0] = blkRoot
|
blockRoots[0] = blkRoot
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ go_library(
|
|||||||
"//cmd/beacon-chain/db:go_default_library",
|
"//cmd/beacon-chain/db:go_default_library",
|
||||||
"//cmd/beacon-chain/flags:go_default_library",
|
"//cmd/beacon-chain/flags:go_default_library",
|
||||||
"//cmd/beacon-chain/powchain:go_default_library",
|
"//cmd/beacon-chain/powchain:go_default_library",
|
||||||
|
"//cmd/beacon-chain/sync/checkpoint:go_default_library",
|
||||||
"//config/features:go_default_library",
|
"//config/features:go_default_library",
|
||||||
"//io/file:go_default_library",
|
"//io/file:go_default_library",
|
||||||
"//io/logs:go_default_library",
|
"//io/logs:go_default_library",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
// FlagOptions for blockchain service flag configurations.
|
// FlagOptions for blockchain service flag configurations.
|
||||||
func FlagOptions(c *cli.Context) ([]blockchain.Option, error) {
|
func FlagOptions(c *cli.Context) ([]blockchain.Option, error) {
|
||||||
wsp := c.String(flags.WeakSubjectivityCheckpt.Name)
|
wsp := c.String(flags.WeakSubjectivityCheckpoint.Name)
|
||||||
wsCheckpt, err := helpers.ParseWeakSubjectivityInputString(wsp)
|
wsCheckpt, err := helpers.ParseWeakSubjectivityInputString(wsp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -191,13 +191,6 @@ var (
|
|||||||
Name: "network-id",
|
Name: "network-id",
|
||||||
Usage: "Sets the network id of the beacon chain.",
|
Usage: "Sets the network id of the beacon chain.",
|
||||||
}
|
}
|
||||||
// WeakSubjectivityCheckpt defines the weak subjectivity checkpoint the node must sync through to defend against long range attacks.
|
|
||||||
WeakSubjectivityCheckpt = &cli.StringFlag{
|
|
||||||
Name: "weak-subjectivity-checkpoint",
|
|
||||||
Usage: "Input in `block_root:epoch_number` format. This guarantees that syncing leads to the given Weak Subjectivity Checkpoint along the canonical chain. " +
|
|
||||||
"If such a sync is not possible, the node will treat it a critical and irrecoverable failure",
|
|
||||||
Value: "",
|
|
||||||
}
|
|
||||||
// Eth1HeaderReqLimit defines a flag to set the maximum number of headers that a deposit log query can fetch. If none is set, 1000 will be the limit.
|
// Eth1HeaderReqLimit defines a flag to set the maximum number of headers that a deposit log query can fetch. If none is set, 1000 will be the limit.
|
||||||
Eth1HeaderReqLimit = &cli.Uint64Flag{
|
Eth1HeaderReqLimit = &cli.Uint64Flag{
|
||||||
Name: "eth1-header-req-limit",
|
Name: "eth1-header-req-limit",
|
||||||
@@ -210,6 +203,14 @@ var (
|
|||||||
Usage: "Load a genesis state from ssz file. Testnet genesis files can be found in the " +
|
Usage: "Load a genesis state from ssz file. Testnet genesis files can be found in the " +
|
||||||
"eth2-clients/eth2-testnets repository on github.",
|
"eth2-clients/eth2-testnets repository on github.",
|
||||||
}
|
}
|
||||||
|
// WeakSubjectivityCheckpoint defines the weak subjectivity checkpoint the node must sync through to defend against long range attacks.
|
||||||
|
WeakSubjectivityCheckpoint = &cli.StringFlag{
|
||||||
|
Name: "weak-subjectivity-checkpoint",
|
||||||
|
Usage: "Input in `block_root:epoch_number` format." +
|
||||||
|
" This guarantees that syncing leads to the given Weak Subjectivity Checkpoint along the canonical chain. " +
|
||||||
|
"If such a sync is not possible, the node will treat it as a critical and irrecoverable failure",
|
||||||
|
Value: "",
|
||||||
|
}
|
||||||
// MinPeersPerSubnet defines a flag to set the minimum number of peers that a node will attempt to peer with for a subnet.
|
// MinPeersPerSubnet defines a flag to set the minimum number of peers that a node will attempt to peer with for a subnet.
|
||||||
MinPeersPerSubnet = &cli.Uint64Flag{
|
MinPeersPerSubnet = &cli.Uint64Flag{
|
||||||
Name: "minimum-peers-per-subnet",
|
Name: "minimum-peers-per-subnet",
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
runtimeDebug "runtime/debug"
|
runtimeDebug "runtime/debug"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/sync/checkpoint"
|
||||||
|
|
||||||
gethlog "github.com/ethereum/go-ethereum/log"
|
gethlog "github.com/ethereum/go-ethereum/log"
|
||||||
golog "github.com/ipfs/go-log/v2"
|
golog "github.com/ipfs/go-log/v2"
|
||||||
joonix "github.com/joonix/log"
|
joonix "github.com/joonix/log"
|
||||||
@@ -63,7 +65,7 @@ var appFlags = []cli.Flag{
|
|||||||
flags.HistoricalSlasherNode,
|
flags.HistoricalSlasherNode,
|
||||||
flags.ChainID,
|
flags.ChainID,
|
||||||
flags.NetworkID,
|
flags.NetworkID,
|
||||||
flags.WeakSubjectivityCheckpt,
|
flags.WeakSubjectivityCheckpoint,
|
||||||
flags.Eth1HeaderReqLimit,
|
flags.Eth1HeaderReqLimit,
|
||||||
flags.GenesisStatePath,
|
flags.GenesisStatePath,
|
||||||
flags.MinPeersPerSubnet,
|
flags.MinPeersPerSubnet,
|
||||||
@@ -119,6 +121,9 @@ var appFlags = []cli.Flag{
|
|||||||
cmd.BoltMMapInitialSizeFlag,
|
cmd.BoltMMapInitialSizeFlag,
|
||||||
cmd.ValidatorMonitorIndicesFlag,
|
cmd.ValidatorMonitorIndicesFlag,
|
||||||
cmd.ApiTimeoutFlag,
|
cmd.ApiTimeoutFlag,
|
||||||
|
checkpoint.BlockPath,
|
||||||
|
checkpoint.StatePath,
|
||||||
|
checkpoint.RemoteURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -243,6 +248,13 @@ func startNode(ctx *cli.Context) error {
|
|||||||
node.WithBlockchainFlagOptions(blockchainFlagOpts),
|
node.WithBlockchainFlagOptions(blockchainFlagOpts),
|
||||||
node.WithPowchainFlagOptions(powchainFlagOpts),
|
node.WithPowchainFlagOptions(powchainFlagOpts),
|
||||||
}
|
}
|
||||||
|
cptOpts, err := checkpoint.BeaconNodeOptions(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if cptOpts != nil {
|
||||||
|
opts = append(opts, cptOpts)
|
||||||
|
}
|
||||||
beacon, err := node.New(ctx, opts...)
|
beacon, err := node.New(ctx, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
14
cmd/beacon-chain/sync/checkpoint/BUILD.bazel
Normal file
14
cmd/beacon-chain/sync/checkpoint/BUILD.bazel
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["options.go"],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/cmd/beacon-chain/sync/checkpoint",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//beacon-chain/node:go_default_library",
|
||||||
|
"//beacon-chain/sync/checkpoint:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
|
"@com_github_urfave_cli_v2//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
68
cmd/beacon-chain/sync/checkpoint/options.go
Normal file
68
cmd/beacon-chain/sync/checkpoint/options.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package checkpoint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/node"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/sync/checkpoint"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// StatePath defines a flag to start the beacon chain from a give genesis state file.
|
||||||
|
StatePath = &cli.PathFlag{
|
||||||
|
Name: "checkpoint-state",
|
||||||
|
Usage: "Rather than syncing from genesis, you can start processing from a ssz-serialized BeaconState+Block." +
|
||||||
|
" This flag allows you to specify a local file containing the checkpoint BeaconState to load.",
|
||||||
|
}
|
||||||
|
// BlockPath is required when using StatePath to also provide the latest integrated block.
|
||||||
|
BlockPath = &cli.PathFlag{
|
||||||
|
Name: "checkpoint-block",
|
||||||
|
Usage: "Rather than syncing from genesis, you can start processing from a ssz-serialized BeaconState+Block." +
|
||||||
|
" This flag allows you to specify a local file containing the checkpoint Block to load.",
|
||||||
|
}
|
||||||
|
RemoteURL = &cli.StringFlag{
|
||||||
|
Name: "checkpoint-sync-url",
|
||||||
|
Usage: "URL of a synced beacon node to trust in obtaining checkpoint sync data. " +
|
||||||
|
"as an additional safety measure, it is strongly recommended to only use this option in conjunction with " +
|
||||||
|
"--weak-subjectivity-checkpoint flag",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// BeaconNodeOptions is responsible for determining if the checkpoint sync options have been used, and if so,
|
||||||
|
// reading the block and state ssz-serialized values from the filesystem locations specified and preparing a
|
||||||
|
// checkpoint.Initializer, which uses the provided io.ReadClosers to initialize the beacon node database.
|
||||||
|
func BeaconNodeOptions(c *cli.Context) (node.Option, error) {
|
||||||
|
blockPath := c.Path(BlockPath.Name)
|
||||||
|
statePath := c.Path(StatePath.Name)
|
||||||
|
remoteURL := c.String(RemoteURL.Name)
|
||||||
|
if remoteURL != "" {
|
||||||
|
return func(node *node.BeaconNode) error {
|
||||||
|
var err error
|
||||||
|
node.CheckpointInitializer, err = checkpoint.NewAPIInitializer(remoteURL)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error while constructing beacon node api client for checkpoint sync")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if blockPath == "" && statePath == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if blockPath != "" && statePath == "" {
|
||||||
|
return nil, fmt.Errorf("--checkpoint-block specified, but not --checkpoint-state. both are required")
|
||||||
|
}
|
||||||
|
if blockPath == "" && statePath != "" {
|
||||||
|
return nil, fmt.Errorf("--checkpoint-state specified, but not --checkpoint-block. both are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(node *node.BeaconNode) (err error) {
|
||||||
|
node.CheckpointInitializer, err = checkpoint.NewFileInitializer(blockPath, statePath)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error preparing to initialize checkpoint from local ssz files")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/cmd"
|
"github.com/prysmaticlabs/prysm/cmd"
|
||||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
||||||
|
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/sync/checkpoint"
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
"github.com/prysmaticlabs/prysm/config/features"
|
||||||
"github.com/prysmaticlabs/prysm/runtime/debug"
|
"github.com/prysmaticlabs/prysm/runtime/debug"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@@ -75,6 +76,9 @@ var appHelpFlagGroups = []flagGroup{
|
|||||||
cmd.BoltMMapInitialSizeFlag,
|
cmd.BoltMMapInitialSizeFlag,
|
||||||
cmd.ValidatorMonitorIndicesFlag,
|
cmd.ValidatorMonitorIndicesFlag,
|
||||||
cmd.ApiTimeoutFlag,
|
cmd.ApiTimeoutFlag,
|
||||||
|
checkpoint.BlockPath,
|
||||||
|
checkpoint.StatePath,
|
||||||
|
checkpoint.RemoteURL,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -122,7 +126,7 @@ var appHelpFlagGroups = []flagGroup{
|
|||||||
flags.HistoricalSlasherNode,
|
flags.HistoricalSlasherNode,
|
||||||
flags.ChainID,
|
flags.ChainID,
|
||||||
flags.NetworkID,
|
flags.NetworkID,
|
||||||
flags.WeakSubjectivityCheckpt,
|
flags.WeakSubjectivityCheckpoint,
|
||||||
flags.Eth1HeaderReqLimit,
|
flags.Eth1HeaderReqLimit,
|
||||||
flags.GenesisStatePath,
|
flags.GenesisStatePath,
|
||||||
flags.MinPeersPerSubnet,
|
flags.MinPeersPerSubnet,
|
||||||
|
|||||||
20
cmd/prysmctl/BUILD.bazel
Normal file
20
cmd/prysmctl/BUILD.bazel
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
|
||||||
|
load("@prysm//tools/go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["main.go"],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/cmd/prysmctl",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = [
|
||||||
|
"//cmd/prysmctl/checkpoint:go_default_library",
|
||||||
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
|
"@com_github_urfave_cli_v2//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_binary(
|
||||||
|
name = "prysmctl",
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
17
cmd/prysmctl/checkpoint/BUILD.bazel
Normal file
17
cmd/prysmctl/checkpoint/BUILD.bazel
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"checkpoint.go",
|
||||||
|
"latest.go",
|
||||||
|
"save.go",
|
||||||
|
],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/cmd/prysmctl/checkpoint",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//api/client/beacon:go_default_library",
|
||||||
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
|
"@com_github_urfave_cli_v2//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
15
cmd/prysmctl/checkpoint/checkpoint.go
Normal file
15
cmd/prysmctl/checkpoint/checkpoint.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package checkpoint
|
||||||
|
|
||||||
|
import "github.com/urfave/cli/v2"
|
||||||
|
|
||||||
|
var Commands = []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "checkpoint",
|
||||||
|
Aliases: []string{"cpt"},
|
||||||
|
Usage: "commands for managing checkpoint syncing",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
latestCmd,
|
||||||
|
saveCmd,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
59
cmd/prysmctl/checkpoint/latest.go
Normal file
59
cmd/prysmctl/checkpoint/latest.go
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package checkpoint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/api/client/beacon"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var latestFlags = struct {
|
||||||
|
BeaconNodeHost string
|
||||||
|
Timeout string
|
||||||
|
}{}
|
||||||
|
|
||||||
|
var latestCmd = &cli.Command{
|
||||||
|
Name: "latest",
|
||||||
|
Usage: "Compute the latest weak subjectivity checkpoint (block_root:epoch) using trusted server data.",
|
||||||
|
Action: cliActionLatest,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "beacon-node-host",
|
||||||
|
Usage: "host:port for beacon node to query",
|
||||||
|
Destination: &latestFlags.BeaconNodeHost,
|
||||||
|
Value: "http://localhost:3500",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "http-timeout",
|
||||||
|
Usage: "timeout for http requests made to beacon-node-url (uses duration format, ex: 2m31s). default: 2m",
|
||||||
|
Destination: &latestFlags.Timeout,
|
||||||
|
Value: "2m",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func cliActionLatest(_ *cli.Context) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
f := latestFlags
|
||||||
|
|
||||||
|
timeout, err := time.ParseDuration(f.Timeout)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
opts := []beacon.ClientOpt{beacon.WithTimeout(timeout)}
|
||||||
|
client, err := beacon.NewClient(latestFlags.BeaconNodeHost, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
od, err := beacon.DownloadOriginData(ctx, client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("\nUse the following flag when starting a prysm Beacon Node to ensure the chain history " +
|
||||||
|
"includes the Weak Subjectivity Checkpoint: ")
|
||||||
|
fmt.Printf("--weak-subjectivity-checkpoint=%s\n\n", od.WeakSubjectivity().CheckpointString())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
75
cmd/prysmctl/checkpoint/save.go
Normal file
75
cmd/prysmctl/checkpoint/save.go
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package checkpoint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/api/client/beacon"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var saveFlags = struct {
|
||||||
|
BeaconNodeHost string
|
||||||
|
Timeout string
|
||||||
|
}{}
|
||||||
|
|
||||||
|
var saveCmd = &cli.Command{
|
||||||
|
Name: "save",
|
||||||
|
Usage: "query for the current weak subjectivity period epoch, then download the corresponding state and block. To be used for checkpoint sync.",
|
||||||
|
Action: cliActionSave,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "beacon-node-host",
|
||||||
|
Usage: "host:port for beacon node connection",
|
||||||
|
Destination: &saveFlags.BeaconNodeHost,
|
||||||
|
Value: "localhost:3500",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "http-timeout",
|
||||||
|
Usage: "timeout for http requests made to beacon-node-url (uses duration format, ex: 2m31s). default: 2m",
|
||||||
|
Destination: &saveFlags.Timeout,
|
||||||
|
Value: "4m",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func cliActionSave(_ *cli.Context) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
f := saveFlags
|
||||||
|
|
||||||
|
timeout, err := time.ParseDuration(f.Timeout)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
opts := []beacon.ClientOpt{beacon.WithTimeout(timeout)}
|
||||||
|
client, err := beacon.NewClient(saveFlags.BeaconNodeHost, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
od, err := beacon.DownloadOriginData(ctx, client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
blockPath, err := od.SaveBlock(cwd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("saved ssz-encoded block to to %s", blockPath)
|
||||||
|
|
||||||
|
statePath, err := od.SaveState(cwd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("saved ssz-encoded state to to %s", statePath)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
25
cmd/prysmctl/main.go
Normal file
25
cmd/prysmctl/main.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/cmd/prysmctl/checkpoint"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var prysmctlCommands []*cli.Command
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := &cli.App{
|
||||||
|
Commands: prysmctlCommands,
|
||||||
|
}
|
||||||
|
err := app.Run(os.Args)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
prysmctlCommands = append(prysmctlCommands, checkpoint.Commands...)
|
||||||
|
}
|
||||||
@@ -30,6 +30,8 @@ func WrapFlags(flags []cli.Flag) []cli.Flag {
|
|||||||
f = altsrc.NewUint64Flag(t)
|
f = altsrc.NewUint64Flag(t)
|
||||||
case *cli.UintFlag:
|
case *cli.UintFlag:
|
||||||
f = altsrc.NewUintFlag(t)
|
f = altsrc.NewUintFlag(t)
|
||||||
|
case *cli.PathFlag:
|
||||||
|
f = altsrc.NewPathFlag(t)
|
||||||
case *cli.Int64Flag:
|
case *cli.Int64Flag:
|
||||||
// Int64Flag does not work. See https://github.com/prysmaticlabs/prysm/issues/6478
|
// Int64Flag does not work. See https://github.com/prysmaticlabs/prysm/issues/6478
|
||||||
panic(fmt.Sprintf("unsupported flag type type %T", f))
|
panic(fmt.Sprintf("unsupported flag type type %T", f))
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ go_library(
|
|||||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//params:go_default_library",
|
"@com_github_ethereum_go_ethereum//params:go_default_library",
|
||||||
"@com_github_mohae_deepcopy//:go_default_library",
|
"@com_github_mohae_deepcopy//:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@in_gopkg_yaml_v2//:go_default_library",
|
"@in_gopkg_yaml_v2//:go_default_library",
|
||||||
@@ -54,6 +55,7 @@ go_test(
|
|||||||
"//io/file:go_default_library",
|
"//io/file:go_default_library",
|
||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
|
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@in_gopkg_yaml_v2//:go_default_library",
|
"@in_gopkg_yaml_v2//:go_default_library",
|
||||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
package params
|
package params
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
)
|
)
|
||||||
@@ -201,3 +203,56 @@ func (b *BeaconChainConfig) InitializeForkSchedule() {
|
|||||||
// Set Bellatrix fork data.
|
// Set Bellatrix fork data.
|
||||||
b.ForkVersionSchedule[bytesutil.ToBytes4(b.BellatrixForkVersion)] = b.BellatrixForkEpoch
|
b.ForkVersionSchedule[bytesutil.ToBytes4(b.BellatrixForkVersion)] = b.BellatrixForkEpoch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForkScheduleEntry is a Version+Epoch tuple for sorted storage in an OrderedForkSchedule
|
||||||
|
type ForkScheduleEntry struct {
|
||||||
|
Version [4]byte
|
||||||
|
Epoch types.Epoch
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrderedForkSchedule provides a type that can be used to sort the fork schedule and find the Version
|
||||||
|
// the chain should be at for a given epoch (via VersionForEpoch).
|
||||||
|
type OrderedForkSchedule []ForkScheduleEntry
|
||||||
|
|
||||||
|
// Len implements the Len method of sort.Interface
|
||||||
|
func (o OrderedForkSchedule) Len() int { return len(o) }
|
||||||
|
|
||||||
|
// Swap implements the Swap method of sort.Interface
|
||||||
|
func (o OrderedForkSchedule) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||||
|
|
||||||
|
// Less implements the Less method of sort.Interface
|
||||||
|
func (o OrderedForkSchedule) Less(i, j int) bool { return o[i].Epoch < o[j].Epoch }
|
||||||
|
|
||||||
|
var VersionForEpochNotFound = errors.New("could not find an entry in the ForkVersionSchedule")
|
||||||
|
|
||||||
|
// VersionForEpoch finds the Version of the last entry in the last that comes before the given epoch
|
||||||
|
func (o OrderedForkSchedule) VersionForEpoch(epoch types.Epoch) ([4]byte, error) {
|
||||||
|
for i := range o {
|
||||||
|
// moving from lowest to highest, only consider epochs that start at or before the slot
|
||||||
|
if epoch < o[i].Epoch {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// `i+1 == len(o)`: at last element, don't need to check if there is another fork schedule entry in between
|
||||||
|
// `o[i+1].Epoch > fse.Epoch`: next version's epoch is past the epoch in question, so `i` is correct
|
||||||
|
if i+1 == len(o) || epoch < o[i+1].Epoch {
|
||||||
|
return o[i].Version, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var nope [4]byte
|
||||||
|
return nope, errors.Wrapf(VersionForEpochNotFound, "no epoch in list <= %d", epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts the ForkVersionSchedule map into a list of Version+Epoch values, ordered by Epoch from lowest to highest.
|
||||||
|
// See docs for OrderedForkSchedule for more detail on what you can do with this type.
|
||||||
|
func (b *BeaconChainConfig) OrderedForkSchedule() OrderedForkSchedule {
|
||||||
|
ofs := make(OrderedForkSchedule, 0)
|
||||||
|
for version, epoch := range b.ForkVersionSchedule {
|
||||||
|
fse := ForkScheduleEntry{
|
||||||
|
Version: version,
|
||||||
|
Epoch: epoch,
|
||||||
|
}
|
||||||
|
ofs = append(ofs, fse)
|
||||||
|
}
|
||||||
|
sort.Sort(ofs)
|
||||||
|
return ofs
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package params_test
|
package params_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test cases can be executed in an arbitrary order. TestOverrideBeaconConfigTestTeardown checks
|
// Test cases can be executed in an arbitrary order. TestOverrideBeaconConfigTestTeardown checks
|
||||||
@@ -44,3 +47,97 @@ func TestConfig_DataRace(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOrderedConfigSchedule(t *testing.T) {
|
||||||
|
params.SetupTestConfigCleanup(t)
|
||||||
|
for name, cfg := range params.AllConfigs() {
|
||||||
|
t.Run(name.String(), func(t *testing.T) {
|
||||||
|
prevVersion := [4]byte{0, 0, 0, 0}
|
||||||
|
// epoch 0 is genesis, and it's a uint so can't make it -1
|
||||||
|
// so we use a pointer to detect the boundary condition and skip it
|
||||||
|
var prevEpoch *types.Epoch
|
||||||
|
for _, fse := range cfg.OrderedForkSchedule() {
|
||||||
|
// copy loop variable so we can take the address of fields
|
||||||
|
f := fse
|
||||||
|
if prevEpoch == nil {
|
||||||
|
prevEpoch = &f.Epoch
|
||||||
|
prevVersion = f.Version
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if *prevEpoch > f.Epoch {
|
||||||
|
t.Errorf("Epochs out of order! %#x/%d before %#x/%d", f.Version, f.Epoch, prevVersion, prevEpoch)
|
||||||
|
}
|
||||||
|
prevEpoch = &f.Epoch
|
||||||
|
prevVersion = f.Version
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
bc := testForkVersionScheduleBCC()
|
||||||
|
ofs := bc.OrderedForkSchedule()
|
||||||
|
for i := range ofs {
|
||||||
|
if ofs[i].Epoch != types.Epoch(math.Pow(2, float64(i))) {
|
||||||
|
t.Errorf("expected %dth element of list w/ epoch=%d, got=%d. list=%v", i, types.Epoch(2^i), ofs[i].Epoch, ofs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVersionForEpoch(t *testing.T) {
|
||||||
|
bc := testForkVersionScheduleBCC()
|
||||||
|
ofs := bc.OrderedForkSchedule()
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
version [4]byte
|
||||||
|
epoch types.Epoch
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "found between versions",
|
||||||
|
version: [4]byte{2, 1, 2, 3},
|
||||||
|
epoch: types.Epoch(7),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "found at end",
|
||||||
|
version: [4]byte{4, 1, 2, 3},
|
||||||
|
epoch: types.Epoch(100),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "found at start",
|
||||||
|
version: [4]byte{0, 1, 2, 3},
|
||||||
|
epoch: types.Epoch(1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "found at boundary",
|
||||||
|
version: [4]byte{1, 1, 2, 3},
|
||||||
|
epoch: types.Epoch(2),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not found before",
|
||||||
|
epoch: types.Epoch(0),
|
||||||
|
err: params.VersionForEpochNotFound,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
v, err := ofs.VersionForEpoch(tc.epoch)
|
||||||
|
if tc.err == nil {
|
||||||
|
require.NoError(t, err)
|
||||||
|
} else {
|
||||||
|
require.ErrorIs(t, err, tc.err)
|
||||||
|
}
|
||||||
|
require.Equal(t, tc.version, v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testForkVersionScheduleBCC() *params.BeaconChainConfig {
|
||||||
|
return ¶ms.BeaconChainConfig{
|
||||||
|
ForkVersionSchedule: map[[4]byte]types.Epoch{
|
||||||
|
{1, 1, 2, 3}: types.Epoch(2),
|
||||||
|
{0, 1, 2, 3}: types.Epoch(1),
|
||||||
|
{4, 1, 2, 3}: types.Epoch(16),
|
||||||
|
{3, 1, 2, 3}: types.Epoch(8),
|
||||||
|
{2, 1, 2, 3}: types.Epoch(4),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,19 +12,37 @@ import (
|
|||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func isMinimal(lines []string) bool {
|
||||||
|
for _, l := range lines {
|
||||||
|
if strings.HasPrefix(l, "PRESET_BASE: 'minimal'") ||
|
||||||
|
strings.HasPrefix(l, `PRESET_BASE: "minimal"`) ||
|
||||||
|
strings.HasPrefix(l, "PRESET_BASE: minimal") ||
|
||||||
|
strings.HasPrefix(l, "# Minimal preset") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// LoadChainConfigFile load, convert hex values into valid param yaml format,
|
// LoadChainConfigFile load, convert hex values into valid param yaml format,
|
||||||
// unmarshal , and apply beacon chain config file.
|
// unmarshal , and apply beacon chain config file.
|
||||||
func LoadChainConfigFile(chainConfigFileName string) {
|
func LoadChainConfigFile(chainConfigFileName string, conf *BeaconChainConfig) {
|
||||||
yamlFile, err := ioutil.ReadFile(chainConfigFileName) // #nosec G304
|
yamlFile, err := ioutil.ReadFile(chainConfigFileName) // #nosec G304
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Fatal("Failed to read chain config file.")
|
log.WithError(err).Fatal("Failed to read chain config file.")
|
||||||
}
|
}
|
||||||
// Default to using mainnet.
|
|
||||||
conf := MainnetConfig().Copy()
|
|
||||||
// To track if config name is defined inside config file.
|
// To track if config name is defined inside config file.
|
||||||
hasConfigName := false
|
hasConfigName := false
|
||||||
// Convert 0x hex inputs to fixed bytes arrays
|
// Convert 0x hex inputs to fixed bytes arrays
|
||||||
lines := strings.Split(string(yamlFile), "\n")
|
lines := strings.Split(string(yamlFile), "\n")
|
||||||
|
if conf == nil {
|
||||||
|
if isMinimal(lines) {
|
||||||
|
conf = MinimalSpecConfig().Copy()
|
||||||
|
} else {
|
||||||
|
// Default to using mainnet.
|
||||||
|
conf = MainnetConfig().Copy()
|
||||||
|
}
|
||||||
|
}
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
// No need to convert the deposit contract address to byte array (as config expects a string).
|
// No need to convert the deposit contract address to byte array (as config expects a string).
|
||||||
if strings.HasPrefix(line, "DEPOSIT_CONTRACT_ADDRESS") {
|
if strings.HasPrefix(line, "DEPOSIT_CONTRACT_ADDRESS") {
|
||||||
@@ -33,12 +51,6 @@ func LoadChainConfigFile(chainConfigFileName string) {
|
|||||||
if strings.HasPrefix(line, "CONFIG_NAME") {
|
if strings.HasPrefix(line, "CONFIG_NAME") {
|
||||||
hasConfigName = true
|
hasConfigName = true
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(line, "PRESET_BASE: 'minimal'") ||
|
|
||||||
strings.HasPrefix(line, `PRESET_BASE: "minimal"`) ||
|
|
||||||
strings.HasPrefix(line, "PRESET_BASE: minimal") ||
|
|
||||||
strings.HasPrefix(line, "# Minimal preset") {
|
|
||||||
conf = MinimalSpecConfig().Copy()
|
|
||||||
}
|
|
||||||
if !strings.HasPrefix(line, "#") && strings.Contains(line, "0x") {
|
if !strings.HasPrefix(line, "#") && strings.Contains(line, "0x") {
|
||||||
parts := ReplaceHexStringWithYAMLFormat(line)
|
parts := ReplaceHexStringWithYAMLFormat(line)
|
||||||
lines[i] = strings.Join(parts, "\n")
|
lines[i] = strings.Join(parts, "\n")
|
||||||
|
|||||||
@@ -111,10 +111,10 @@ func TestLoadConfigFileMainnet(t *testing.T) {
|
|||||||
t.Run("mainnet", func(t *testing.T) {
|
t.Run("mainnet", func(t *testing.T) {
|
||||||
mainnetPresetsFiles := presetsFilePath(t, "mainnet")
|
mainnetPresetsFiles := presetsFilePath(t, "mainnet")
|
||||||
for _, fp := range mainnetPresetsFiles {
|
for _, fp := range mainnetPresetsFiles {
|
||||||
params.LoadChainConfigFile(fp)
|
params.LoadChainConfigFile(fp, nil)
|
||||||
}
|
}
|
||||||
mainnetConfigFile := configFilePath(t, "mainnet")
|
mainnetConfigFile := configFilePath(t, "mainnet")
|
||||||
params.LoadChainConfigFile(mainnetConfigFile)
|
params.LoadChainConfigFile(mainnetConfigFile, nil)
|
||||||
fields := fieldsFromYamls(t, append(mainnetPresetsFiles, mainnetConfigFile))
|
fields := fieldsFromYamls(t, append(mainnetPresetsFiles, mainnetConfigFile))
|
||||||
assertVals("mainnet", fields, params.MainnetConfig(), params.BeaconConfig())
|
assertVals("mainnet", fields, params.MainnetConfig(), params.BeaconConfig())
|
||||||
})
|
})
|
||||||
@@ -122,10 +122,10 @@ func TestLoadConfigFileMainnet(t *testing.T) {
|
|||||||
t.Run("minimal", func(t *testing.T) {
|
t.Run("minimal", func(t *testing.T) {
|
||||||
minimalPresetsFiles := presetsFilePath(t, "minimal")
|
minimalPresetsFiles := presetsFilePath(t, "minimal")
|
||||||
for _, fp := range minimalPresetsFiles {
|
for _, fp := range minimalPresetsFiles {
|
||||||
params.LoadChainConfigFile(fp)
|
params.LoadChainConfigFile(fp, nil)
|
||||||
}
|
}
|
||||||
minimalConfigFile := configFilePath(t, "minimal")
|
minimalConfigFile := configFilePath(t, "minimal")
|
||||||
params.LoadChainConfigFile(minimalConfigFile)
|
params.LoadChainConfigFile(minimalConfigFile, nil)
|
||||||
fields := fieldsFromYamls(t, append(minimalPresetsFiles, minimalConfigFile))
|
fields := fieldsFromYamls(t, append(minimalPresetsFiles, minimalConfigFile))
|
||||||
assertVals("minimal", fields, params.MinimalSpecConfig(), params.BeaconConfig())
|
assertVals("minimal", fields, params.MinimalSpecConfig(), params.BeaconConfig())
|
||||||
})
|
})
|
||||||
@@ -138,7 +138,7 @@ func TestLoadConfigFile_OverwriteCorrectly(t *testing.T) {
|
|||||||
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
||||||
|
|
||||||
// load empty config file, so that it defaults to mainnet values
|
// load empty config file, so that it defaults to mainnet values
|
||||||
params.LoadChainConfigFile(file.Name())
|
params.LoadChainConfigFile(file.Name(), nil)
|
||||||
if params.BeaconConfig().MinGenesisTime != params.MainnetConfig().MinGenesisTime {
|
if params.BeaconConfig().MinGenesisTime != params.MainnetConfig().MinGenesisTime {
|
||||||
t.Errorf("Expected MinGenesisTime to be set to mainnet value: %d found: %d",
|
t.Errorf("Expected MinGenesisTime to be set to mainnet value: %d found: %d",
|
||||||
params.MainnetConfig().MinGenesisTime,
|
params.MainnetConfig().MinGenesisTime,
|
||||||
@@ -230,7 +230,7 @@ func TestConfigParityYaml(t *testing.T) {
|
|||||||
yamlObj := params.ConfigToYaml(testCfg)
|
yamlObj := params.ConfigToYaml(testCfg)
|
||||||
assert.NoError(t, file.WriteFile(yamlDir, yamlObj))
|
assert.NoError(t, file.WriteFile(yamlDir, yamlObj))
|
||||||
|
|
||||||
params.LoadChainConfigFile(yamlDir)
|
params.LoadChainConfigFile(yamlDir, params.E2ETestConfig().Copy())
|
||||||
assert.DeepEqual(t, params.BeaconConfig(), testCfg)
|
assert.DeepEqual(t, params.BeaconConfig(), testCfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,6 @@ func TestE2EConfigParity(t *testing.T) {
|
|||||||
yamlObj := params.E2EMainnetConfigYaml()
|
yamlObj := params.E2EMainnetConfigYaml()
|
||||||
assert.NoError(t, file.WriteFile(yamlDir, yamlObj))
|
assert.NoError(t, file.WriteFile(yamlDir, yamlObj))
|
||||||
|
|
||||||
params.LoadChainConfigFile(yamlDir)
|
params.LoadChainConfigFile(yamlDir, nil)
|
||||||
assert.DeepEqual(t, params.BeaconConfig(), testCfg)
|
assert.DeepEqual(t, params.BeaconConfig(), testCfg)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
package params
|
package params
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
altairE2EForkEpoch = 6
|
altairE2EForkEpoch = 6
|
||||||
bellatrixE2EForkEpoch = 8 //nolint:deadcode
|
bellatrixE2EForkEpoch = 8 //nolint:deadcode
|
||||||
@@ -51,6 +57,18 @@ func E2ETestConfig() *BeaconChainConfig {
|
|||||||
// Prysm constants.
|
// Prysm constants.
|
||||||
e2eConfig.ConfigName = ConfigNames[EndToEnd]
|
e2eConfig.ConfigName = ConfigNames[EndToEnd]
|
||||||
|
|
||||||
|
e2eConfig.GenesisForkVersion = []byte{0x00, 0x00, 0xFF, 0xFF}
|
||||||
|
e2eConfig.AltairForkVersion = []byte{0x1, 0x0, 0xFF, 0xFF}
|
||||||
|
e2eConfig.ShardingForkVersion = []byte{0x3, 0x0, 0xFF, 0xFF}
|
||||||
|
e2eConfig.BellatrixForkVersion = []byte{0x2, 0x0, 0xFF, 0xFF}
|
||||||
|
|
||||||
|
e2eConfig.ForkVersionSchedule = map[[4]byte]types.Epoch{
|
||||||
|
{0x00, 0x00, 0xFF, 0xFF}: 0,
|
||||||
|
{0x1, 0x0, 0xFF, 0xFF}: math.MaxUint64,
|
||||||
|
{0x3, 0x0, 0xFF, 0xFF}: math.MaxUint64,
|
||||||
|
{0x2, 0x0, 0xFF, 0xFF}: math.MaxUint64,
|
||||||
|
}
|
||||||
|
|
||||||
return e2eConfig
|
return e2eConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import (
|
|||||||
func TestPraterConfigMatchesUpstreamYaml(t *testing.T) {
|
func TestPraterConfigMatchesUpstreamYaml(t *testing.T) {
|
||||||
presetFPs := presetsFilePath(t, "mainnet")
|
presetFPs := presetsFilePath(t, "mainnet")
|
||||||
for _, fp := range presetFPs {
|
for _, fp := range presetFPs {
|
||||||
params.LoadChainConfigFile(fp)
|
params.LoadChainConfigFile(fp, nil)
|
||||||
}
|
}
|
||||||
configFP := testnetConfigFilePath(t, "prater")
|
configFP := testnetConfigFilePath(t, "prater")
|
||||||
params.LoadChainConfigFile(configFP)
|
params.LoadChainConfigFile(configFP, nil)
|
||||||
fields := fieldsFromYamls(t, append(presetFPs, configFP))
|
fields := fieldsFromYamls(t, append(presetFPs, configFP))
|
||||||
assertYamlFieldsMatch(t, "prater", fields, params.BeaconConfig(), params.PraterConfig())
|
assertYamlFieldsMatch(t, "prater", fields, params.BeaconConfig(), params.PraterConfig())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,56 @@ var ConfigNames = map[ConfigName]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConfigName enum describes the type of known network in use.
|
// ConfigName enum describes the type of known network in use.
|
||||||
type ConfigName = int
|
type ConfigName int
|
||||||
|
|
||||||
|
func (n ConfigName) String() string {
|
||||||
|
s, ok := ConfigNames[n]
|
||||||
|
if !ok {
|
||||||
|
return "undefined"
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllConfigs() map[ConfigName]*BeaconChainConfig {
|
||||||
|
all := make(map[ConfigName]*BeaconChainConfig)
|
||||||
|
for name := range ConfigNames {
|
||||||
|
var cfg *BeaconChainConfig
|
||||||
|
switch name {
|
||||||
|
case Mainnet:
|
||||||
|
cfg = MainnetConfig()
|
||||||
|
case Prater:
|
||||||
|
cfg = PraterConfig()
|
||||||
|
case Pyrmont:
|
||||||
|
cfg = PyrmontConfig()
|
||||||
|
case Minimal:
|
||||||
|
cfg = MinimalSpecConfig()
|
||||||
|
case EndToEnd:
|
||||||
|
cfg = E2ETestConfig()
|
||||||
|
}
|
||||||
|
cfg = cfg.Copy()
|
||||||
|
cfg.InitializeForkSchedule()
|
||||||
|
all[name] = cfg
|
||||||
|
}
|
||||||
|
return all
|
||||||
|
}
|
||||||
|
|
||||||
|
type ForkName int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ForkGenesis ForkName = iota
|
||||||
|
ForkAltair
|
||||||
|
ForkBellatrix
|
||||||
|
)
|
||||||
|
|
||||||
|
func (n ForkName) String() string {
|
||||||
|
switch n {
|
||||||
|
case ForkGenesis:
|
||||||
|
return "genesis"
|
||||||
|
case ForkAltair:
|
||||||
|
return "altair"
|
||||||
|
case ForkBellatrix:
|
||||||
|
return "bellatrix"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "undefined"
|
||||||
|
}
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -221,7 +221,6 @@ require (
|
|||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
go.uber.org/multierr v1.7.0 // indirect
|
go.uber.org/multierr v1.7.0 // indirect
|
||||||
go.uber.org/zap v1.19.0 // indirect
|
go.uber.org/zap v1.19.0 // indirect
|
||||||
golang.org/x/mod v0.5.1 // indirect
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
|
||||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c // indirect
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c // indirect
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||||
@@ -255,6 +254,7 @@ require (
|
|||||||
github.com/peterh/liner v1.2.0 // indirect
|
github.com/peterh/liner v1.2.0 // indirect
|
||||||
github.com/prometheus/tsdb v0.10.0 // indirect
|
github.com/prometheus/tsdb v0.10.0 // indirect
|
||||||
github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220303211031-f753e083138c
|
github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220303211031-f753e083138c
|
||||||
|
golang.org/x/mod v0.5.1
|
||||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect
|
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect
|
||||||
google.golang.org/api v0.34.0 // indirect
|
google.golang.org/api v0.34.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
|||||||
35
proto/detect/BUILD.bazel
Normal file
35
proto/detect/BUILD.bazel
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["configfork.go"],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/proto/detect",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//beacon-chain/state:go_default_library",
|
||||||
|
"//beacon-chain/state/v1:go_default_library",
|
||||||
|
"//beacon-chain/state/v2:go_default_library",
|
||||||
|
"//beacon-chain/state/v3:go_default_library",
|
||||||
|
"//config/params:go_default_library",
|
||||||
|
"//encoding/bytesutil:go_default_library",
|
||||||
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
|
"//proto/prysm/v1alpha1/block:go_default_library",
|
||||||
|
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
||||||
|
"//time/slots:go_default_library",
|
||||||
|
"@com_github_ferranbt_fastssz//:go_default_library",
|
||||||
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
|
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["configfork_test.go"],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//proto/engine/v1:go_default_library",
|
||||||
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
|
"//testing/require:go_default_library",
|
||||||
|
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
221
proto/detect/configfork.go
Normal file
221
proto/detect/configfork.go
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
package detect
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
ssz "github.com/ferranbt/fastssz"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
|
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
|
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
||||||
|
v1alpha1 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
||||||
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
||||||
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
|
|
||||||
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fieldType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeUint64 fieldType = iota
|
||||||
|
TypeBytes4
|
||||||
|
)
|
||||||
|
|
||||||
|
type fieldSpec struct {
|
||||||
|
offset int
|
||||||
|
size int
|
||||||
|
t fieldType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fieldSpec) Uint64(state []byte) (uint64, error) {
|
||||||
|
if f.t != TypeUint64 {
|
||||||
|
return 0, fmt.Errorf("Uint64 called on non-uint64 field: %v", f)
|
||||||
|
}
|
||||||
|
s, err := f.slice(state)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return binary.LittleEndian.Uint64(s), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fieldSpec) Bytes4(state []byte) ([4]byte, error) {
|
||||||
|
var b4 [4]byte
|
||||||
|
if f.t != TypeBytes4 {
|
||||||
|
return b4, fmt.Errorf("Bytes4 called on non-bytes4 field %v", f)
|
||||||
|
}
|
||||||
|
if f.size != 4 {
|
||||||
|
return b4, fmt.Errorf("Bytes4 types must have a size of 4, invalid fieldSpec %v", f)
|
||||||
|
}
|
||||||
|
val, err := f.slice(state)
|
||||||
|
if err != nil {
|
||||||
|
return b4, err
|
||||||
|
}
|
||||||
|
return bytesutil.ToBytes4(val), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fieldSpec) slice(value []byte) ([]byte, error) {
|
||||||
|
if len(value) < f.offset+f.size {
|
||||||
|
return nil, fmt.Errorf("cannot pull bytes from value; offset=%d, size=%d, so value must be at least %d bytes (actual=%d)", f.offset, f.size, f.offset+f.size, len(value))
|
||||||
|
}
|
||||||
|
return value[f.offset : f.offset+f.size], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigFork represents the intersection of Configuration (eg mainnet, testnet) and Fork (eg phase0, altair).
|
||||||
|
// Using a detected ConfigFork, a BeaconState or SignedBeaconBlock can be correctly unmarshaled without the need to
|
||||||
|
// hard code a concrete type in paths where only the marshaled bytes, or marshaled bytes and a version, are available.
|
||||||
|
type ConfigFork struct {
|
||||||
|
ConfigName params.ConfigName
|
||||||
|
Config *params.BeaconChainConfig
|
||||||
|
Fork params.ForkName
|
||||||
|
Version [4]byte
|
||||||
|
Epoch types.Epoch
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByVersion uses a lookup table to resolve a Version (from a beacon node api for instance, or obtained by peeking at
|
||||||
|
// the bytes of a marshaled BeaconState) to a ConfigFork.
|
||||||
|
func ByVersion(cv [4]byte) (*ConfigFork, error) {
|
||||||
|
cf := &ConfigFork{
|
||||||
|
Version: cv,
|
||||||
|
}
|
||||||
|
for name, cfg := range params.AllConfigs() {
|
||||||
|
genesis := bytesutil.ToBytes4(cfg.GenesisForkVersion)
|
||||||
|
altair := bytesutil.ToBytes4(cfg.AltairForkVersion)
|
||||||
|
merge := bytesutil.ToBytes4(cfg.BellatrixForkVersion)
|
||||||
|
for v, e := range cfg.ForkVersionSchedule {
|
||||||
|
if v == cv {
|
||||||
|
cf.ConfigName = name
|
||||||
|
cf.Config = cfg
|
||||||
|
cf.Epoch = e
|
||||||
|
switch v {
|
||||||
|
case genesis:
|
||||||
|
cf.Fork = params.ForkGenesis
|
||||||
|
case altair:
|
||||||
|
cf.Fork = params.ForkAltair
|
||||||
|
case merge:
|
||||||
|
cf.Fork = params.ForkBellatrix
|
||||||
|
default:
|
||||||
|
return cf, fmt.Errorf("unrecognized fork for config name=%s, BeaconState.fork.current_version=%#x", name.String(), cv)
|
||||||
|
}
|
||||||
|
return cf, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cf, fmt.Errorf("could not find a config+fork match with version=%#x", cv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var beaconStateCurrentVersion = fieldSpec{
|
||||||
|
// 52 = 8 (genesis_time) + 32 (genesis_validators_root) + 8 (slot) + 4 (previous_version)
|
||||||
|
offset: 52,
|
||||||
|
size: 4,
|
||||||
|
t: TypeBytes4,
|
||||||
|
}
|
||||||
|
|
||||||
|
var beaconStateEpoch = fieldSpec{
|
||||||
|
// 52 = 8 (genesis_time) + 32 (genesis_validators_root) + 8 (slot) + 4 (previous_version) + 4 (current_version)
|
||||||
|
offset: 56,
|
||||||
|
size: 8,
|
||||||
|
t: TypeUint64,
|
||||||
|
}
|
||||||
|
|
||||||
|
func currentVersionFromState(marshaled []byte) ([4]byte, error) {
|
||||||
|
return beaconStateCurrentVersion.Bytes4(marshaled)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByState exploits the fixed-size lower-order bytes in a BeaconState as a heuristic to obtain the value of the
|
||||||
|
// state.version field without first unmarshaling the BeaconState. The Version is then internally used to lookup
|
||||||
|
// the correct ConfigVersion.
|
||||||
|
func ByState(marshaled []byte) (*ConfigFork, error) {
|
||||||
|
cv, err := currentVersionFromState(marshaled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ByVersion(cv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBeaconState uses internal knowledge in the ConfigFork to pick the right concrete BeaconState type,
|
||||||
|
// then Unmarshal()s the type and returns an instance of state.BeaconState if successful.
|
||||||
|
func (cf *ConfigFork) UnmarshalBeaconState(marshaled []byte) (s state.BeaconState, err error) {
|
||||||
|
switch cf.Fork {
|
||||||
|
case params.ForkGenesis:
|
||||||
|
s, err = v1.InitializeFromSSZBytes(marshaled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "InitializeFromSSZBytes for ForkGenesis failed")
|
||||||
|
}
|
||||||
|
case params.ForkAltair:
|
||||||
|
s, err = v2.InitializeFromSSZBytes(marshaled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "InitializeFromSSZBytes for ForkAltair failed")
|
||||||
|
}
|
||||||
|
case params.ForkBellatrix:
|
||||||
|
s, err = v3.InitializeFromSSZBytes(marshaled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "InitializeFromSSZBytes for ForkMerge failed")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unable to initialize BeaconState for fork version=%s", cf.Fork.String())
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var beaconBlockSlot = fieldSpec{
|
||||||
|
// ssz variable length offset (not to be confused with the fieldSpec offest) is a uint32
|
||||||
|
// variable length offsets come before fixed length data, so that's 4 bytes at the beginning
|
||||||
|
// then signature is 96 bytes, 4+96 = 100
|
||||||
|
offset: 100,
|
||||||
|
size: 8,
|
||||||
|
t: TypeUint64,
|
||||||
|
}
|
||||||
|
|
||||||
|
func slotFromBlock(marshaled []byte) (types.Slot, error) {
|
||||||
|
slot, err := beaconBlockSlot.Uint64(marshaled)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return types.Slot(slot), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBeaconBlock uses internal knowledge in the ConfigFork to pick the right concrete SignedBeaconBlock type,
|
||||||
|
// then Unmarshal()s the type and returns an instance of block.SignedBeaconBlock if successful.
|
||||||
|
func (cf *ConfigFork) UnmarshalBeaconBlock(marshaled []byte) (block.SignedBeaconBlock, error) {
|
||||||
|
slot, err := slotFromBlock(marshaled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// heuristic to make sure block is from the same version as the state
|
||||||
|
// based on the fork schedule for the Config detected from the state
|
||||||
|
// get the version that corresponds to the epoch the block is from according to the fork choice schedule
|
||||||
|
// and make sure that the version is the same one that was pulled from the state
|
||||||
|
epoch := slots.ToEpoch(slot)
|
||||||
|
fs := cf.Config.OrderedForkSchedule()
|
||||||
|
ver, err := fs.VersionForEpoch(epoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if ver != cf.Version {
|
||||||
|
return nil, fmt.Errorf("cannot sniff block schema, block (slot=%d, epoch=%d) is on a different fork", slot, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
var blk ssz.Unmarshaler
|
||||||
|
switch cf.Fork {
|
||||||
|
case params.ForkGenesis:
|
||||||
|
blk = &v1alpha1.SignedBeaconBlock{}
|
||||||
|
case params.ForkAltair:
|
||||||
|
blk = &v1alpha1.SignedBeaconBlockAltair{}
|
||||||
|
case params.ForkBellatrix:
|
||||||
|
blk = &v1alpha1.SignedBeaconBlockBellatrix{}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unable to initialize BeaconBlock for fork version=%s at slot=%d", cf.Fork.String(), slot)
|
||||||
|
}
|
||||||
|
err = blk.UnmarshalSSZ(marshaled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to unmarshal SignedBeaconBlock in BlockFromSSZReader")
|
||||||
|
}
|
||||||
|
return wrapper.WrappedSignedBeaconBlock(blk)
|
||||||
|
}
|
||||||
135
proto/detect/configfork_test.go
Normal file
135
proto/detect/configfork_test.go
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package detect
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
|
v1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSlotFromBlock(t *testing.T) {
|
||||||
|
b := testBlock()
|
||||||
|
var slot types.Slot = 3
|
||||||
|
b.Block.Slot = slot
|
||||||
|
bb, err := b.MarshalSSZ()
|
||||||
|
require.NoError(t, err)
|
||||||
|
sfb, err := slotFromBlock(bb)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, slot, sfb)
|
||||||
|
|
||||||
|
ba := testBlockAltair()
|
||||||
|
ba.Block.Slot = slot
|
||||||
|
bab, err := ba.MarshalSSZ()
|
||||||
|
require.NoError(t, err)
|
||||||
|
sfba, err := slotFromBlock(bab)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, slot, sfba)
|
||||||
|
|
||||||
|
bm := testBlockMerge()
|
||||||
|
bm.Block.Slot = slot
|
||||||
|
bmb, err := ba.MarshalSSZ()
|
||||||
|
require.NoError(t, err)
|
||||||
|
sfbm, err := slotFromBlock(bmb)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, slot, sfbm)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBlock() *ethpb.SignedBeaconBlock {
|
||||||
|
return ðpb.SignedBeaconBlock{
|
||||||
|
Block: ðpb.BeaconBlock{
|
||||||
|
ProposerIndex: types.ValidatorIndex(0),
|
||||||
|
ParentRoot: make([]byte, 32),
|
||||||
|
StateRoot: make([]byte, 32),
|
||||||
|
Body: ðpb.BeaconBlockBody{
|
||||||
|
RandaoReveal: make([]byte, 96),
|
||||||
|
Graffiti: make([]byte, 32),
|
||||||
|
ProposerSlashings: []*ethpb.ProposerSlashing{},
|
||||||
|
AttesterSlashings: []*ethpb.AttesterSlashing{},
|
||||||
|
Attestations: []*ethpb.Attestation{},
|
||||||
|
Deposits: []*ethpb.Deposit{},
|
||||||
|
VoluntaryExits: []*ethpb.SignedVoluntaryExit{},
|
||||||
|
Eth1Data: ðpb.Eth1Data{
|
||||||
|
DepositRoot: make([]byte, 32),
|
||||||
|
DepositCount: 0,
|
||||||
|
BlockHash: make([]byte, 32),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBlockAltair() *ethpb.SignedBeaconBlockAltair {
|
||||||
|
return ðpb.SignedBeaconBlockAltair{
|
||||||
|
Block: ðpb.BeaconBlockAltair{
|
||||||
|
ProposerIndex: types.ValidatorIndex(0),
|
||||||
|
ParentRoot: make([]byte, 32),
|
||||||
|
StateRoot: make([]byte, 32),
|
||||||
|
Body: ðpb.BeaconBlockBodyAltair{
|
||||||
|
RandaoReveal: make([]byte, 96),
|
||||||
|
Eth1Data: ðpb.Eth1Data{
|
||||||
|
DepositRoot: make([]byte, 32),
|
||||||
|
DepositCount: 0,
|
||||||
|
BlockHash: make([]byte, 32),
|
||||||
|
},
|
||||||
|
Graffiti: make([]byte, 32),
|
||||||
|
ProposerSlashings: []*ethpb.ProposerSlashing{},
|
||||||
|
AttesterSlashings: []*ethpb.AttesterSlashing{},
|
||||||
|
Attestations: []*ethpb.Attestation{},
|
||||||
|
Deposits: []*ethpb.Deposit{},
|
||||||
|
VoluntaryExits: []*ethpb.SignedVoluntaryExit{},
|
||||||
|
SyncAggregate: ðpb.SyncAggregate{
|
||||||
|
SyncCommitteeBits: make([]byte, 64),
|
||||||
|
SyncCommitteeSignature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBlockMerge() *ethpb.SignedBeaconBlockBellatrix {
|
||||||
|
return ðpb.SignedBeaconBlockBellatrix{
|
||||||
|
Block: ðpb.BeaconBlockBellatrix{
|
||||||
|
ProposerIndex: types.ValidatorIndex(0),
|
||||||
|
ParentRoot: make([]byte, 32),
|
||||||
|
StateRoot: make([]byte, 32),
|
||||||
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
|
RandaoReveal: make([]byte, 96),
|
||||||
|
Eth1Data: ðpb.Eth1Data{
|
||||||
|
DepositRoot: make([]byte, 32),
|
||||||
|
DepositCount: 0,
|
||||||
|
BlockHash: make([]byte, 32),
|
||||||
|
},
|
||||||
|
Graffiti: make([]byte, 32),
|
||||||
|
ProposerSlashings: []*ethpb.ProposerSlashing{},
|
||||||
|
AttesterSlashings: []*ethpb.AttesterSlashing{},
|
||||||
|
Attestations: []*ethpb.Attestation{},
|
||||||
|
Deposits: []*ethpb.Deposit{},
|
||||||
|
VoluntaryExits: []*ethpb.SignedVoluntaryExit{},
|
||||||
|
SyncAggregate: ðpb.SyncAggregate{
|
||||||
|
SyncCommitteeBits: make([]byte, 64),
|
||||||
|
SyncCommitteeSignature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
ExecutionPayload: &v1.ExecutionPayload{
|
||||||
|
ParentHash: make([]byte, 32),
|
||||||
|
FeeRecipient: make([]byte, 20),
|
||||||
|
StateRoot: make([]byte, 32),
|
||||||
|
ReceiptsRoot: make([]byte, 32),
|
||||||
|
LogsBloom: make([]byte, 256),
|
||||||
|
BlockNumber: 0,
|
||||||
|
GasLimit: 0,
|
||||||
|
GasUsed: 0,
|
||||||
|
Timestamp: 0,
|
||||||
|
ExtraData: make([]byte, 32),
|
||||||
|
BaseFeePerGas: make([]byte, 32),
|
||||||
|
BlockHash: make([]byte, 32),
|
||||||
|
Transactions: make([][]byte, 0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
}
|
||||||
|
}
|
||||||
757
proto/eth/service/beacon_chain_service.pb.go
generated
757
proto/eth/service/beacon_chain_service.pb.go
generated
@@ -50,7 +50,7 @@ var file_proto_eth_service_beacon_chain_service_proto_rawDesc = []byte{
|
|||||||
0x32, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70,
|
0x32, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70,
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f,
|
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f,
|
||||||
0x76, 0x32, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
|
0x76, 0x32, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
|
||||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xe8, 0x22, 0x0a, 0x0b, 0x42, 0x65, 0x61, 0x63,
|
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xf6, 0x23, 0x0a, 0x0b, 0x42, 0x65, 0x61, 0x63,
|
||||||
0x6f, 0x6e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x6f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x47, 0x65,
|
0x6f, 0x6e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x6f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x47, 0x65,
|
||||||
0x6e, 0x65, 0x73, 0x69, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
0x6e, 0x65, 0x73, 0x69, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e,
|
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e,
|
||||||
@@ -58,288 +58,296 @@ var file_proto_eth_service_beacon_chain_service_proto_rawDesc = []byte{
|
|||||||
0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||||
0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||||
0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e,
|
0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e,
|
||||||
0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x12, 0x89, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74,
|
0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x12, 0x8b, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74,
|
||||||
0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
0x57, 0x65, 0x61, 0x6b, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79,
|
||||||
|
0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||||
|
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||||
|
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x61, 0x6b, 0x53,
|
||||||
|
0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||||
|
0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, 0x29, 0x2f, 0x69, 0x6e,
|
||||||
|
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65,
|
||||||
|
0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x77, 0x65, 0x61, 0x6b, 0x5f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63,
|
||||||
|
0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x89, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x74,
|
||||||
|
0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||||
|
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52,
|
||||||
|
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||||
|
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f,
|
||||||
|
0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93,
|
||||||
|
0x02, 0x30, 0x12, 0x2e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74,
|
||||||
|
0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74,
|
||||||
|
0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f,
|
||||||
|
0x6f, 0x74, 0x12, 0x89, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46,
|
||||||
|
0x6f, 0x72, 0x6b, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
|
||||||
|
0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
|
0x73, 0x74, 0x1a, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
||||||
|
0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6b, 0x52, 0x65,
|
||||||
|
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x12, 0x2e,
|
||||||
|
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31,
|
||||||
|
0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b,
|
||||||
|
0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x6f, 0x72, 0x6b, 0x12, 0xb1,
|
||||||
|
0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x68,
|
||||||
|
0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
||||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||||
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65,
|
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65,
|
||||||
0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3,
|
0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69,
|
||||||
0xe4, 0x93, 0x02, 0x30, 0x12, 0x2e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
|
0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x82, 0xd3, 0xe4, 0x93,
|
||||||
0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74,
|
0x02, 0x40, 0x12, 0x3e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74,
|
||||||
0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
|
|
||||||
0x72, 0x6f, 0x6f, 0x74, 0x12, 0x89, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74,
|
|
||||||
0x65, 0x46, 0x6f, 0x72, 0x6b, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
|
||||||
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
|
|
||||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
|
||||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6b,
|
|
||||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30,
|
|
||||||
0x12, 0x2e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f,
|
|
||||||
0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73,
|
|
||||||
0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x6f, 0x72, 0x6b,
|
|
||||||
0x12, 0xb1, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79,
|
|
||||||
0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x2e, 0x65, 0x74,
|
|
||||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74,
|
|
||||||
0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x65, 0x74, 0x68,
|
|
||||||
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61,
|
|
||||||
0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70,
|
|
||||||
0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x82, 0xd3,
|
|
||||||
0xe4, 0x93, 0x02, 0x40, 0x12, 0x3e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
|
|
||||||
0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74,
|
|
||||||
0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
|
|
||||||
0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f,
|
|
||||||
0x69, 0x6e, 0x74, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c,
|
|
||||||
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
|
||||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
|
|
||||||
0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
|
||||||
0x1a, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
|
|
||||||
0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
|
|
||||||
0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93,
|
|
||||||
0x02, 0x36, 0x12, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74,
|
|
||||||
0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74,
|
0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74,
|
||||||
0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61,
|
0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69,
|
||||||
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0xac, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74,
|
0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e,
|
||||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
0x74, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64,
|
||||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||||
0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c,
|
||||||
0x74, 0x1a, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
|
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28,
|
||||||
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
|
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
|
||||||
0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x82, 0xd3, 0xe4, 0x93,
|
0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73,
|
||||||
0x02, 0x45, 0x12, 0x43, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74,
|
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36,
|
||||||
0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74,
|
0x12, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f,
|
||||||
0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61,
|
|
||||||
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
|
|
||||||
0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xb4, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74,
|
|
||||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
|
|
||||||
0x73, 0x12, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
|
|
||||||
0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x61, 0x6c,
|
|
||||||
0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x65,
|
|
||||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x56,
|
|
||||||
0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73,
|
|
||||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3e,
|
|
||||||
0x12, 0x3c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f,
|
|
||||||
0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73,
|
0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73,
|
||||||
0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x69,
|
0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x69,
|
||||||
0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0xa1,
|
0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0xac, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x56, 0x61,
|
||||||
0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65,
|
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||||
0x73, 0x12, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
|
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
|
||||||
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74,
|
0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||||
0x65, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x65, 0x74, 0x68,
|
0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
||||||
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61,
|
0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
|
||||||
0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x45,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x12, 0x34, 0x2f, 0x69,
|
0x12, 0x43, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f,
|
||||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62,
|
0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73,
|
||||||
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74,
|
0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x69,
|
||||||
0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
|
0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
|
||||||
0x65, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43,
|
0x72, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xb4, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61,
|
||||||
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12,
|
||||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
||||||
0x65, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52,
|
0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e,
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x65, 0x74, 0x68,
|
||||||
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79,
|
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c,
|
||||||
0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x12, 0x39, 0x2f, 0x69,
|
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3e, 0x12, 0x3c,
|
||||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62,
|
|
||||||
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74,
|
|
||||||
0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d,
|
|
||||||
0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74,
|
|
||||||
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x24, 0x2e, 0x65,
|
|
||||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42,
|
|
||||||
0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
|
||||||
0x73, 0x74, 0x1a, 0x25, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
|
||||||
0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
|
|
||||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
|
||||||
0x21, 0x12, 0x1f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68,
|
|
||||||
0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65,
|
|
||||||
0x72, 0x73, 0x12, 0x89, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
|
|
||||||
0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
|
||||||
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71,
|
|
||||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
|
||||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64,
|
|
||||||
0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93,
|
|
||||||
0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74,
|
|
||||||
0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64,
|
|
||||||
0x65, 0x72, 0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7f,
|
|
||||||
0x0a, 0x0b, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2d, 0x2e,
|
|
||||||
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e,
|
|
||||||
0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
|
|
||||||
0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x56, 0x32, 0x1a, 0x16, 0x2e, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
|
|
||||||
0x6d, 0x70, 0x74, 0x79, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x22, 0x1e, 0x2f, 0x69,
|
|
||||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62,
|
|
||||||
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x3a, 0x01, 0x2a, 0x12,
|
|
||||||
0x89, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74,
|
|
||||||
0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
|
|
||||||
0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
|
||||||
0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
|
||||||
0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
|
||||||
0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x12, 0x2e, 0x2f, 0x69, 0x6e,
|
|
||||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65,
|
|
||||||
0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f,
|
|
||||||
0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x12, 0x7c, 0x0a, 0x08, 0x47,
|
|
||||||
0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
|
||||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52,
|
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
|
||||||
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65,
|
|
||||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, 0x29,
|
|
||||||
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31,
|
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31,
|
||||||
0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x7b,
|
0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b,
|
||||||
0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x86, 0x01, 0x0a, 0x0b, 0x47, 0x65,
|
0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
|
||||||
0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x53, 0x5a, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
0x74, 0x6f, 0x72, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0xa1, 0x01, 0x0a,
|
||||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63,
|
0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x12,
|
||||||
0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
||||||
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65,
|
||||||
0x53, 0x53, 0x5a, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4,
|
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||||
0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65,
|
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65,
|
||||||
0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f,
|
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||||
0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73,
|
0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x12, 0x34, 0x2f, 0x69, 0x6e, 0x74,
|
||||||
0x73, 0x7a, 0x12, 0x82, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56,
|
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61,
|
||||||
0x32, 0x12, 0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
|
0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74,
|
||||||
0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73,
|
||||||
0x56, 0x32, 0x1a, 0x20, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
0x12, 0xb2, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d,
|
||||||
0x68, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||||
0x73, 0x65, 0x56, 0x32, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, 0x29, 0x2f, 0x69,
|
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53,
|
||||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x2f, 0x62,
|
0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52, 0x65, 0x71,
|
||||||
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c,
|
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||||
0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x8c, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x42,
|
0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63,
|
||||||
0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x53, 0x5a, 0x56, 0x32, 0x12, 0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63,
|
0x73, 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x12, 0x39, 0x2f, 0x69, 0x6e, 0x74,
|
||||||
0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, 0x1a, 0x23, 0x2e, 0x65, 0x74, 0x68,
|
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61,
|
||||||
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f,
|
0x63, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74,
|
||||||
0x63, 0x6b, 0x53, 0x53, 0x5a, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x22,
|
0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
|
||||||
0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
0x74, 0x74, 0x65, 0x65, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c,
|
||||||
0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e,
|
0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x24, 0x2e, 0x65, 0x74, 0x68,
|
||||||
0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69,
|
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f,
|
||||||
0x64, 0x7d, 0x2f, 0x73, 0x73, 0x7a, 0x12, 0xa2, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x42,
|
0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||||
0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
0x1a, 0x25, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
|
||||||
0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
|
0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x52,
|
||||||
0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12,
|
||||||
0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
0x1f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76,
|
||||||
0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
|
0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73,
|
||||||
0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3e, 0x82, 0xd3, 0xe4,
|
0x12, 0x89, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61,
|
||||||
0x93, 0x02, 0x38, 0x12, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65,
|
0x64, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
|
||||||
0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f,
|
0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61,
|
0x73, 0x74, 0x1a, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
||||||
0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x14,
|
0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
|
||||||
0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74,
|
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c,
|
||||||
0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
0x12, 0x2a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f,
|
||||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
|
0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72,
|
||||||
0x6f, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29,
|
0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7f, 0x0a, 0x0b,
|
||||||
|
0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2d, 0x2e, 0x65, 0x74,
|
||||||
|
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69,
|
||||||
|
0x67, 0x6e, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43,
|
||||||
|
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x56, 0x32, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
|
||||||
|
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
|
||||||
|
0x74, 0x79, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x22, 0x1e, 0x2f, 0x69, 0x6e, 0x74,
|
||||||
|
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61,
|
||||||
|
0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x89, 0x01,
|
||||||
|
0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d,
|
||||||
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
|
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
|
||||||
0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x6f, 0x6f,
|
0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e,
|
||||||
0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e,
|
||||||
0x2b, 0x12, 0x29, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68,
|
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f,
|
0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x12, 0x2e, 0x2f, 0x69, 0x6e, 0x74, 0x65,
|
||||||
0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x8e, 0x01, 0x0a,
|
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63,
|
||||||
0x12, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
|
0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
|
||||||
0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
|
0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x12, 0x7c, 0x0a, 0x08, 0x47, 0x65, 0x74,
|
||||||
0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65,
|
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||||
0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71,
|
||||||
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||||
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x22,
|
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70,
|
||||||
|
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, 0x29, 0x2f, 0x69,
|
||||||
|
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62,
|
||||||
|
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c,
|
||||||
|
0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x86, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42,
|
||||||
|
0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x53, 0x5a, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||||
|
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52,
|
||||||
|
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||||
|
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x53,
|
||||||
|
0x5a, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||||
|
0x2f, 0x12, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68,
|
||||||
|
0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
|
||||||
|
0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x73, 0x7a,
|
||||||
|
0x12, 0x82, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x32, 0x12,
|
||||||
|
0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
||||||
|
0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x32,
|
||||||
|
0x1a, 0x20, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
|
||||||
|
0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||||
|
0x56, 0x32, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, 0x29, 0x2f, 0x69, 0x6e, 0x74,
|
||||||
|
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x65, 0x61,
|
||||||
|
0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63,
|
||||||
|
0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x8c, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f,
|
||||||
|
0x63, 0x6b, 0x53, 0x53, 0x5a, 0x56, 0x32, 0x12, 0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||||
|
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52,
|
||||||
|
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, 0x1a, 0x23, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||||
|
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||||
|
0x53, 0x53, 0x5a, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x22, 0x35, 0x82,
|
||||||
|
0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||||
|
0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62,
|
||||||
|
0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d,
|
||||||
|
0x2f, 0x73, 0x73, 0x7a, 0x12, 0xa2, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f,
|
||||||
|
0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d,
|
||||||
|
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
|
||||||
|
0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e,
|
||||||
|
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e,
|
||||||
|
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
|
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3e, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||||
|
0x38, 0x12, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68,
|
||||||
|
0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
|
||||||
|
0x73, 0x2f, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x74, 0x74,
|
||||||
|
0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x14, 0x4c, 0x69,
|
||||||
|
0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f,
|
||||||
|
0x6e, 0x73, 0x12, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
||||||
|
0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
|
0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x65,
|
||||||
|
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41,
|
||||||
|
0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x52,
|
||||||
|
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12,
|
||||||
0x29, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76,
|
0x29, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76,
|
||||||
0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x61, 0x74,
|
0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x61, 0x74,
|
||||||
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x9c, 0x01,
|
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x12, 0x53,
|
||||||
0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74,
|
0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
0x65, 0x72, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f,
|
0x73, 0x12, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
|
||||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
|
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74,
|
||||||
0x70, 0x74, 0x79, 0x1a, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
|
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
|
||||||
0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x53, 0x6c,
|
|
||||||
0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
|
||||||
0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x12, 0x2f, 0x2f, 0x69, 0x6e,
|
|
||||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65,
|
|
||||||
0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74,
|
|
||||||
0x65, 0x72, 0x5f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x8f, 0x01, 0x0a,
|
|
||||||
0x16, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x53,
|
|
||||||
0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
|
||||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74,
|
|
||||||
0x65, 0x72, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
|
|
||||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
|
|
||||||
0x74, 0x79, 0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x22, 0x2f, 0x2f, 0x69, 0x6e, 0x74,
|
|
||||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61,
|
|
||||||
0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65,
|
|
||||||
0x72, 0x5f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x9b,
|
|
||||||
0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x6f,
|
|
||||||
0x73, 0x65, 0x72, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x16, 0x2e, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
|
|
||||||
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
|
||||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x53,
|
|
||||||
0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
|
||||||
0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x12, 0x2f, 0x2f, 0x69, 0x6e,
|
|
||||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65,
|
|
||||||
0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73,
|
|
||||||
0x65, 0x72, 0x5f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x8f, 0x01, 0x0a,
|
|
||||||
0x16, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x53,
|
|
||||||
0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
|
||||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73,
|
|
||||||
0x65, 0x72, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
|
|
||||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
|
|
||||||
0x74, 0x79, 0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x22, 0x2f, 0x2f, 0x69, 0x6e, 0x74,
|
|
||||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61,
|
|
||||||
0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65,
|
|
||||||
0x72, 0x5f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x93,
|
|
||||||
0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x56, 0x6f, 0x6c, 0x75, 0x6e,
|
|
||||||
0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
|
||||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
|
||||||
0x79, 0x1a, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
|
|
||||||
0x2e, 0x76, 0x31, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69,
|
|
||||||
0x74, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34,
|
|
||||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
|
||||||
0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f,
|
|
||||||
0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x65,
|
|
||||||
0x78, 0x69, 0x74, 0x73, 0x12, 0x8c, 0x01, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x56,
|
|
||||||
0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x12, 0x24, 0x2e, 0x65,
|
|
||||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53,
|
|
||||||
0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78,
|
|
||||||
0x69, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
|
||||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93,
|
|
||||||
0x02, 0x31, 0x22, 0x2c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74,
|
|
||||||
0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c,
|
|
||||||
0x2f, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x73,
|
|
||||||
0x3a, 0x01, 0x2a, 0x12, 0xa8, 0x01, 0x0a, 0x21, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x50, 0x6f,
|
|
||||||
0x6f, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x53,
|
|
||||||
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
|
||||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x75, 0x62, 0x6d,
|
|
||||||
0x69, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
|
|
||||||
0x74, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x1a, 0x16, 0x2e,
|
|
||||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x22, 0x2c, 0x2f,
|
0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x22, 0x29, 0x2f,
|
||||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f,
|
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f,
|
||||||
0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x73, 0x79, 0x6e, 0x63,
|
0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x65,
|
||||||
0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x7f,
|
0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x9c, 0x01, 0x0a, 0x19,
|
||||||
0x0a, 0x0f, 0x47, 0x65, 0x74, 0x46, 0x6f, 0x72, 0x6b, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
|
0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72,
|
||||||
0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
0x53, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||||
0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x25, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b,
|
0x79, 0x1a, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
|
||||||
0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x53, 0x6c, 0x61, 0x73,
|
||||||
0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
0x68, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x12, 0x2f, 0x2f, 0x69, 0x6e, 0x74, 0x65,
|
||||||
0x67, 0x2f, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12,
|
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63,
|
||||||
0x66, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
|
0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72,
|
||||||
|
0x5f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x8f, 0x01, 0x0a, 0x16, 0x53,
|
||||||
|
0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x53, 0x6c, 0x61,
|
||||||
|
0x73, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||||
|
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72,
|
||||||
|
0x53, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||||
|
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||||
|
0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x22, 0x2f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||||
|
0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f,
|
||||||
|
0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x5f,
|
||||||
|
0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x9b, 0x01, 0x0a,
|
||||||
|
0x19, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65,
|
||||||
|
0x72, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
|
||||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
|
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
|
||||||
0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
0x74, 0x79, 0x1a, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
|
||||||
0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x53, 0x6c, 0x61,
|
||||||
0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x69, 0x6e, 0x74, 0x65,
|
0x73, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66,
|
0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x12, 0x2f, 0x2f, 0x69, 0x6e, 0x74, 0x65,
|
||||||
0x69, 0x67, 0x2f, 0x73, 0x70, 0x65, 0x63, 0x12, 0x88, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x44,
|
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63,
|
||||||
0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x16,
|
0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72,
|
||||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
0x5f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x8f, 0x01, 0x0a, 0x16, 0x53,
|
||||||
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
0x75, 0x62, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x53, 0x6c, 0x61,
|
||||||
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
|
0x73, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||||
0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72,
|
||||||
0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
0x53, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||||
0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||||
0x67, 0x2f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61,
|
0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x22, 0x2f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||||
0x63, 0x74, 0x42, 0x95, 0x01, 0x0a, 0x18, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f,
|
||||||
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42,
|
0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f,
|
||||||
0x17, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76,
|
0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x93, 0x01, 0x0a,
|
||||||
0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68,
|
0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61,
|
||||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63,
|
0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||||
0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
|
||||||
0x2f, 0x65, 0x74, 0x68, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xaa, 0x02, 0x14, 0x45,
|
0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
||||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x53, 0x65, 0x72, 0x76,
|
0x31, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x73,
|
||||||
0x69, 0x63, 0x65, 0xca, 0x02, 0x14, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45,
|
0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3,
|
||||||
0x74, 0x68, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
|
||||||
0x6f, 0x33,
|
0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f,
|
||||||
|
0x6f, 0x6c, 0x2f, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, 0x69,
|
||||||
|
0x74, 0x73, 0x12, 0x8c, 0x01, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x56, 0x6f, 0x6c,
|
||||||
|
0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x12, 0x24, 0x2e, 0x65, 0x74, 0x68,
|
||||||
|
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67,
|
||||||
|
0x6e, 0x65, 0x64, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74,
|
||||||
|
0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||||
|
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31,
|
||||||
|
0x22, 0x2c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f,
|
||||||
|
0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x76,
|
||||||
|
0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x73, 0x3a, 0x01,
|
||||||
|
0x2a, 0x12, 0xa8, 0x01, 0x0a, 0x21, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x50, 0x6f, 0x6f, 0x6c,
|
||||||
|
0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x53, 0x69, 0x67,
|
||||||
|
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||||
|
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74,
|
||||||
|
0x50, 0x6f, 0x6f, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
|
||||||
|
0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
|
||||||
|
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
|
||||||
|
0x70, 0x74, 0x79, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x22, 0x2c, 0x2f, 0x69, 0x6e,
|
||||||
|
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65,
|
||||||
|
0x61, 0x63, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63,
|
||||||
|
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x7f, 0x0a, 0x0f,
|
||||||
|
0x47, 0x65, 0x74, 0x46, 0x6f, 0x72, 0x6b, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12,
|
||||||
|
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||||
|
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x25, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||||
|
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x53, 0x63,
|
||||||
|
0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d,
|
||||||
|
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||||
|
0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f,
|
||||||
|
0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x66, 0x0a,
|
||||||
|
0x07, 0x47, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||||
|
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||||
|
0x1a, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
|
||||||
|
0x76, 0x31, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||||
|
0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||||
|
0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||||
|
0x2f, 0x73, 0x70, 0x65, 0x63, 0x12, 0x88, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70,
|
||||||
|
0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x67,
|
||||||
|
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
|
||||||
|
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||||
|
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f,
|
||||||
|
0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30,
|
||||||
|
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||||
|
0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f,
|
||||||
|
0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74,
|
||||||
|
0x42, 0x95, 0x01, 0x0a, 0x18, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||||
|
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x17, 0x42,
|
||||||
|
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||||
|
0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 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, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65,
|
||||||
|
0x74, 0x68, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xaa, 0x02, 0x14, 0x45, 0x74, 0x68,
|
||||||
|
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||||
|
0x65, 0xca, 0x02, 0x14, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68,
|
||||||
|
0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_proto_eth_service_beacon_chain_service_proto_goTypes = []interface{}{
|
var file_proto_eth_service_beacon_chain_service_proto_goTypes = []interface{}{
|
||||||
@@ -361,93 +369,96 @@ var file_proto_eth_service_beacon_chain_service_proto_goTypes = []interface{}{
|
|||||||
(*v1.SignedVoluntaryExit)(nil), // 15: ethereum.eth.v1.SignedVoluntaryExit
|
(*v1.SignedVoluntaryExit)(nil), // 15: ethereum.eth.v1.SignedVoluntaryExit
|
||||||
(*v2.SubmitPoolSyncCommitteeSignatures)(nil), // 16: ethereum.eth.v2.SubmitPoolSyncCommitteeSignatures
|
(*v2.SubmitPoolSyncCommitteeSignatures)(nil), // 16: ethereum.eth.v2.SubmitPoolSyncCommitteeSignatures
|
||||||
(*v1.GenesisResponse)(nil), // 17: ethereum.eth.v1.GenesisResponse
|
(*v1.GenesisResponse)(nil), // 17: ethereum.eth.v1.GenesisResponse
|
||||||
(*v1.StateRootResponse)(nil), // 18: ethereum.eth.v1.StateRootResponse
|
(*v1.WeakSubjectivityResponse)(nil), // 18: ethereum.eth.v1.WeakSubjectivityResponse
|
||||||
(*v1.StateForkResponse)(nil), // 19: ethereum.eth.v1.StateForkResponse
|
(*v1.StateRootResponse)(nil), // 19: ethereum.eth.v1.StateRootResponse
|
||||||
(*v1.StateFinalityCheckpointResponse)(nil), // 20: ethereum.eth.v1.StateFinalityCheckpointResponse
|
(*v1.StateForkResponse)(nil), // 20: ethereum.eth.v1.StateForkResponse
|
||||||
(*v1.StateValidatorsResponse)(nil), // 21: ethereum.eth.v1.StateValidatorsResponse
|
(*v1.StateFinalityCheckpointResponse)(nil), // 21: ethereum.eth.v1.StateFinalityCheckpointResponse
|
||||||
(*v1.StateValidatorResponse)(nil), // 22: ethereum.eth.v1.StateValidatorResponse
|
(*v1.StateValidatorsResponse)(nil), // 22: ethereum.eth.v1.StateValidatorsResponse
|
||||||
(*v1.ValidatorBalancesResponse)(nil), // 23: ethereum.eth.v1.ValidatorBalancesResponse
|
(*v1.StateValidatorResponse)(nil), // 23: ethereum.eth.v1.StateValidatorResponse
|
||||||
(*v1.StateCommitteesResponse)(nil), // 24: ethereum.eth.v1.StateCommitteesResponse
|
(*v1.ValidatorBalancesResponse)(nil), // 24: ethereum.eth.v1.ValidatorBalancesResponse
|
||||||
(*v2.StateSyncCommitteesResponse)(nil), // 25: ethereum.eth.v2.StateSyncCommitteesResponse
|
(*v1.StateCommitteesResponse)(nil), // 25: ethereum.eth.v1.StateCommitteesResponse
|
||||||
(*v1.BlockHeadersResponse)(nil), // 26: ethereum.eth.v1.BlockHeadersResponse
|
(*v2.StateSyncCommitteesResponse)(nil), // 26: ethereum.eth.v2.StateSyncCommitteesResponse
|
||||||
(*v1.BlockHeaderResponse)(nil), // 27: ethereum.eth.v1.BlockHeaderResponse
|
(*v1.BlockHeadersResponse)(nil), // 27: ethereum.eth.v1.BlockHeadersResponse
|
||||||
(*v1.BlockRootResponse)(nil), // 28: ethereum.eth.v1.BlockRootResponse
|
(*v1.BlockHeaderResponse)(nil), // 28: ethereum.eth.v1.BlockHeaderResponse
|
||||||
(*v1.BlockResponse)(nil), // 29: ethereum.eth.v1.BlockResponse
|
(*v1.BlockRootResponse)(nil), // 29: ethereum.eth.v1.BlockRootResponse
|
||||||
(*v1.BlockSSZResponse)(nil), // 30: ethereum.eth.v1.BlockSSZResponse
|
(*v1.BlockResponse)(nil), // 30: ethereum.eth.v1.BlockResponse
|
||||||
(*v2.BlockResponseV2)(nil), // 31: ethereum.eth.v2.BlockResponseV2
|
(*v1.BlockSSZResponse)(nil), // 31: ethereum.eth.v1.BlockSSZResponse
|
||||||
(*v2.BlockSSZResponseV2)(nil), // 32: ethereum.eth.v2.BlockSSZResponseV2
|
(*v2.BlockResponseV2)(nil), // 32: ethereum.eth.v2.BlockResponseV2
|
||||||
(*v1.BlockAttestationsResponse)(nil), // 33: ethereum.eth.v1.BlockAttestationsResponse
|
(*v2.BlockSSZResponseV2)(nil), // 33: ethereum.eth.v2.BlockSSZResponseV2
|
||||||
(*v1.AttestationsPoolResponse)(nil), // 34: ethereum.eth.v1.AttestationsPoolResponse
|
(*v1.BlockAttestationsResponse)(nil), // 34: ethereum.eth.v1.BlockAttestationsResponse
|
||||||
(*v1.AttesterSlashingsPoolResponse)(nil), // 35: ethereum.eth.v1.AttesterSlashingsPoolResponse
|
(*v1.AttestationsPoolResponse)(nil), // 35: ethereum.eth.v1.AttestationsPoolResponse
|
||||||
(*v1.ProposerSlashingPoolResponse)(nil), // 36: ethereum.eth.v1.ProposerSlashingPoolResponse
|
(*v1.AttesterSlashingsPoolResponse)(nil), // 36: ethereum.eth.v1.AttesterSlashingsPoolResponse
|
||||||
(*v1.VoluntaryExitsPoolResponse)(nil), // 37: ethereum.eth.v1.VoluntaryExitsPoolResponse
|
(*v1.ProposerSlashingPoolResponse)(nil), // 37: ethereum.eth.v1.ProposerSlashingPoolResponse
|
||||||
(*v1.ForkScheduleResponse)(nil), // 38: ethereum.eth.v1.ForkScheduleResponse
|
(*v1.VoluntaryExitsPoolResponse)(nil), // 38: ethereum.eth.v1.VoluntaryExitsPoolResponse
|
||||||
(*v1.SpecResponse)(nil), // 39: ethereum.eth.v1.SpecResponse
|
(*v1.ForkScheduleResponse)(nil), // 39: ethereum.eth.v1.ForkScheduleResponse
|
||||||
(*v1.DepositContractResponse)(nil), // 40: ethereum.eth.v1.DepositContractResponse
|
(*v1.SpecResponse)(nil), // 40: ethereum.eth.v1.SpecResponse
|
||||||
|
(*v1.DepositContractResponse)(nil), // 41: ethereum.eth.v1.DepositContractResponse
|
||||||
}
|
}
|
||||||
var file_proto_eth_service_beacon_chain_service_proto_depIdxs = []int32{
|
var file_proto_eth_service_beacon_chain_service_proto_depIdxs = []int32{
|
||||||
0, // 0: ethereum.eth.service.BeaconChain.GetGenesis:input_type -> google.protobuf.Empty
|
0, // 0: ethereum.eth.service.BeaconChain.GetGenesis:input_type -> google.protobuf.Empty
|
||||||
1, // 1: ethereum.eth.service.BeaconChain.GetStateRoot:input_type -> ethereum.eth.v1.StateRequest
|
0, // 1: ethereum.eth.service.BeaconChain.GetWeakSubjectivity:input_type -> google.protobuf.Empty
|
||||||
1, // 2: ethereum.eth.service.BeaconChain.GetStateFork:input_type -> ethereum.eth.v1.StateRequest
|
1, // 2: ethereum.eth.service.BeaconChain.GetStateRoot:input_type -> ethereum.eth.v1.StateRequest
|
||||||
1, // 3: ethereum.eth.service.BeaconChain.GetFinalityCheckpoints:input_type -> ethereum.eth.v1.StateRequest
|
1, // 3: ethereum.eth.service.BeaconChain.GetStateFork:input_type -> ethereum.eth.v1.StateRequest
|
||||||
2, // 4: ethereum.eth.service.BeaconChain.ListValidators:input_type -> ethereum.eth.v1.StateValidatorsRequest
|
1, // 4: ethereum.eth.service.BeaconChain.GetFinalityCheckpoints:input_type -> ethereum.eth.v1.StateRequest
|
||||||
3, // 5: ethereum.eth.service.BeaconChain.GetValidator:input_type -> ethereum.eth.v1.StateValidatorRequest
|
2, // 5: ethereum.eth.service.BeaconChain.ListValidators:input_type -> ethereum.eth.v1.StateValidatorsRequest
|
||||||
4, // 6: ethereum.eth.service.BeaconChain.ListValidatorBalances:input_type -> ethereum.eth.v1.ValidatorBalancesRequest
|
3, // 6: ethereum.eth.service.BeaconChain.GetValidator:input_type -> ethereum.eth.v1.StateValidatorRequest
|
||||||
5, // 7: ethereum.eth.service.BeaconChain.ListCommittees:input_type -> ethereum.eth.v1.StateCommitteesRequest
|
4, // 7: ethereum.eth.service.BeaconChain.ListValidatorBalances:input_type -> ethereum.eth.v1.ValidatorBalancesRequest
|
||||||
6, // 8: ethereum.eth.service.BeaconChain.ListSyncCommittees:input_type -> ethereum.eth.v2.StateSyncCommitteesRequest
|
5, // 8: ethereum.eth.service.BeaconChain.ListCommittees:input_type -> ethereum.eth.v1.StateCommitteesRequest
|
||||||
7, // 9: ethereum.eth.service.BeaconChain.ListBlockHeaders:input_type -> ethereum.eth.v1.BlockHeadersRequest
|
6, // 9: ethereum.eth.service.BeaconChain.ListSyncCommittees:input_type -> ethereum.eth.v2.StateSyncCommitteesRequest
|
||||||
8, // 10: ethereum.eth.service.BeaconChain.GetBlockHeader:input_type -> ethereum.eth.v1.BlockRequest
|
7, // 10: ethereum.eth.service.BeaconChain.ListBlockHeaders:input_type -> ethereum.eth.v1.BlockHeadersRequest
|
||||||
9, // 11: ethereum.eth.service.BeaconChain.SubmitBlock:input_type -> ethereum.eth.v2.SignedBeaconBlockContainerV2
|
8, // 11: ethereum.eth.service.BeaconChain.GetBlockHeader:input_type -> ethereum.eth.v1.BlockRequest
|
||||||
8, // 12: ethereum.eth.service.BeaconChain.GetBlockRoot:input_type -> ethereum.eth.v1.BlockRequest
|
9, // 12: ethereum.eth.service.BeaconChain.SubmitBlock:input_type -> ethereum.eth.v2.SignedBeaconBlockContainerV2
|
||||||
8, // 13: ethereum.eth.service.BeaconChain.GetBlock:input_type -> ethereum.eth.v1.BlockRequest
|
8, // 13: ethereum.eth.service.BeaconChain.GetBlockRoot:input_type -> ethereum.eth.v1.BlockRequest
|
||||||
8, // 14: ethereum.eth.service.BeaconChain.GetBlockSSZ:input_type -> ethereum.eth.v1.BlockRequest
|
8, // 14: ethereum.eth.service.BeaconChain.GetBlock:input_type -> ethereum.eth.v1.BlockRequest
|
||||||
10, // 15: ethereum.eth.service.BeaconChain.GetBlockV2:input_type -> ethereum.eth.v2.BlockRequestV2
|
8, // 15: ethereum.eth.service.BeaconChain.GetBlockSSZ:input_type -> ethereum.eth.v1.BlockRequest
|
||||||
10, // 16: ethereum.eth.service.BeaconChain.GetBlockSSZV2:input_type -> ethereum.eth.v2.BlockRequestV2
|
10, // 16: ethereum.eth.service.BeaconChain.GetBlockV2:input_type -> ethereum.eth.v2.BlockRequestV2
|
||||||
8, // 17: ethereum.eth.service.BeaconChain.ListBlockAttestations:input_type -> ethereum.eth.v1.BlockRequest
|
10, // 17: ethereum.eth.service.BeaconChain.GetBlockSSZV2:input_type -> ethereum.eth.v2.BlockRequestV2
|
||||||
11, // 18: ethereum.eth.service.BeaconChain.ListPoolAttestations:input_type -> ethereum.eth.v1.AttestationsPoolRequest
|
8, // 18: ethereum.eth.service.BeaconChain.ListBlockAttestations:input_type -> ethereum.eth.v1.BlockRequest
|
||||||
12, // 19: ethereum.eth.service.BeaconChain.SubmitAttestations:input_type -> ethereum.eth.v1.SubmitAttestationsRequest
|
11, // 19: ethereum.eth.service.BeaconChain.ListPoolAttestations:input_type -> ethereum.eth.v1.AttestationsPoolRequest
|
||||||
0, // 20: ethereum.eth.service.BeaconChain.ListPoolAttesterSlashings:input_type -> google.protobuf.Empty
|
12, // 20: ethereum.eth.service.BeaconChain.SubmitAttestations:input_type -> ethereum.eth.v1.SubmitAttestationsRequest
|
||||||
13, // 21: ethereum.eth.service.BeaconChain.SubmitAttesterSlashing:input_type -> ethereum.eth.v1.AttesterSlashing
|
0, // 21: ethereum.eth.service.BeaconChain.ListPoolAttesterSlashings:input_type -> google.protobuf.Empty
|
||||||
0, // 22: ethereum.eth.service.BeaconChain.ListPoolProposerSlashings:input_type -> google.protobuf.Empty
|
13, // 22: ethereum.eth.service.BeaconChain.SubmitAttesterSlashing:input_type -> ethereum.eth.v1.AttesterSlashing
|
||||||
14, // 23: ethereum.eth.service.BeaconChain.SubmitProposerSlashing:input_type -> ethereum.eth.v1.ProposerSlashing
|
0, // 23: ethereum.eth.service.BeaconChain.ListPoolProposerSlashings:input_type -> google.protobuf.Empty
|
||||||
0, // 24: ethereum.eth.service.BeaconChain.ListPoolVoluntaryExits:input_type -> google.protobuf.Empty
|
14, // 24: ethereum.eth.service.BeaconChain.SubmitProposerSlashing:input_type -> ethereum.eth.v1.ProposerSlashing
|
||||||
15, // 25: ethereum.eth.service.BeaconChain.SubmitVoluntaryExit:input_type -> ethereum.eth.v1.SignedVoluntaryExit
|
0, // 25: ethereum.eth.service.BeaconChain.ListPoolVoluntaryExits:input_type -> google.protobuf.Empty
|
||||||
16, // 26: ethereum.eth.service.BeaconChain.SubmitPoolSyncCommitteeSignatures:input_type -> ethereum.eth.v2.SubmitPoolSyncCommitteeSignatures
|
15, // 26: ethereum.eth.service.BeaconChain.SubmitVoluntaryExit:input_type -> ethereum.eth.v1.SignedVoluntaryExit
|
||||||
0, // 27: ethereum.eth.service.BeaconChain.GetForkSchedule:input_type -> google.protobuf.Empty
|
16, // 27: ethereum.eth.service.BeaconChain.SubmitPoolSyncCommitteeSignatures:input_type -> ethereum.eth.v2.SubmitPoolSyncCommitteeSignatures
|
||||||
0, // 28: ethereum.eth.service.BeaconChain.GetSpec:input_type -> google.protobuf.Empty
|
0, // 28: ethereum.eth.service.BeaconChain.GetForkSchedule:input_type -> google.protobuf.Empty
|
||||||
0, // 29: ethereum.eth.service.BeaconChain.GetDepositContract:input_type -> google.protobuf.Empty
|
0, // 29: ethereum.eth.service.BeaconChain.GetSpec:input_type -> google.protobuf.Empty
|
||||||
17, // 30: ethereum.eth.service.BeaconChain.GetGenesis:output_type -> ethereum.eth.v1.GenesisResponse
|
0, // 30: ethereum.eth.service.BeaconChain.GetDepositContract:input_type -> google.protobuf.Empty
|
||||||
18, // 31: ethereum.eth.service.BeaconChain.GetStateRoot:output_type -> ethereum.eth.v1.StateRootResponse
|
17, // 31: ethereum.eth.service.BeaconChain.GetGenesis:output_type -> ethereum.eth.v1.GenesisResponse
|
||||||
19, // 32: ethereum.eth.service.BeaconChain.GetStateFork:output_type -> ethereum.eth.v1.StateForkResponse
|
18, // 32: ethereum.eth.service.BeaconChain.GetWeakSubjectivity:output_type -> ethereum.eth.v1.WeakSubjectivityResponse
|
||||||
20, // 33: ethereum.eth.service.BeaconChain.GetFinalityCheckpoints:output_type -> ethereum.eth.v1.StateFinalityCheckpointResponse
|
19, // 33: ethereum.eth.service.BeaconChain.GetStateRoot:output_type -> ethereum.eth.v1.StateRootResponse
|
||||||
21, // 34: ethereum.eth.service.BeaconChain.ListValidators:output_type -> ethereum.eth.v1.StateValidatorsResponse
|
20, // 34: ethereum.eth.service.BeaconChain.GetStateFork:output_type -> ethereum.eth.v1.StateForkResponse
|
||||||
22, // 35: ethereum.eth.service.BeaconChain.GetValidator:output_type -> ethereum.eth.v1.StateValidatorResponse
|
21, // 35: ethereum.eth.service.BeaconChain.GetFinalityCheckpoints:output_type -> ethereum.eth.v1.StateFinalityCheckpointResponse
|
||||||
23, // 36: ethereum.eth.service.BeaconChain.ListValidatorBalances:output_type -> ethereum.eth.v1.ValidatorBalancesResponse
|
22, // 36: ethereum.eth.service.BeaconChain.ListValidators:output_type -> ethereum.eth.v1.StateValidatorsResponse
|
||||||
24, // 37: ethereum.eth.service.BeaconChain.ListCommittees:output_type -> ethereum.eth.v1.StateCommitteesResponse
|
23, // 37: ethereum.eth.service.BeaconChain.GetValidator:output_type -> ethereum.eth.v1.StateValidatorResponse
|
||||||
25, // 38: ethereum.eth.service.BeaconChain.ListSyncCommittees:output_type -> ethereum.eth.v2.StateSyncCommitteesResponse
|
24, // 38: ethereum.eth.service.BeaconChain.ListValidatorBalances:output_type -> ethereum.eth.v1.ValidatorBalancesResponse
|
||||||
26, // 39: ethereum.eth.service.BeaconChain.ListBlockHeaders:output_type -> ethereum.eth.v1.BlockHeadersResponse
|
25, // 39: ethereum.eth.service.BeaconChain.ListCommittees:output_type -> ethereum.eth.v1.StateCommitteesResponse
|
||||||
27, // 40: ethereum.eth.service.BeaconChain.GetBlockHeader:output_type -> ethereum.eth.v1.BlockHeaderResponse
|
26, // 40: ethereum.eth.service.BeaconChain.ListSyncCommittees:output_type -> ethereum.eth.v2.StateSyncCommitteesResponse
|
||||||
0, // 41: ethereum.eth.service.BeaconChain.SubmitBlock:output_type -> google.protobuf.Empty
|
27, // 41: ethereum.eth.service.BeaconChain.ListBlockHeaders:output_type -> ethereum.eth.v1.BlockHeadersResponse
|
||||||
28, // 42: ethereum.eth.service.BeaconChain.GetBlockRoot:output_type -> ethereum.eth.v1.BlockRootResponse
|
28, // 42: ethereum.eth.service.BeaconChain.GetBlockHeader:output_type -> ethereum.eth.v1.BlockHeaderResponse
|
||||||
29, // 43: ethereum.eth.service.BeaconChain.GetBlock:output_type -> ethereum.eth.v1.BlockResponse
|
0, // 43: ethereum.eth.service.BeaconChain.SubmitBlock:output_type -> google.protobuf.Empty
|
||||||
30, // 44: ethereum.eth.service.BeaconChain.GetBlockSSZ:output_type -> ethereum.eth.v1.BlockSSZResponse
|
29, // 44: ethereum.eth.service.BeaconChain.GetBlockRoot:output_type -> ethereum.eth.v1.BlockRootResponse
|
||||||
31, // 45: ethereum.eth.service.BeaconChain.GetBlockV2:output_type -> ethereum.eth.v2.BlockResponseV2
|
30, // 45: ethereum.eth.service.BeaconChain.GetBlock:output_type -> ethereum.eth.v1.BlockResponse
|
||||||
32, // 46: ethereum.eth.service.BeaconChain.GetBlockSSZV2:output_type -> ethereum.eth.v2.BlockSSZResponseV2
|
31, // 46: ethereum.eth.service.BeaconChain.GetBlockSSZ:output_type -> ethereum.eth.v1.BlockSSZResponse
|
||||||
33, // 47: ethereum.eth.service.BeaconChain.ListBlockAttestations:output_type -> ethereum.eth.v1.BlockAttestationsResponse
|
32, // 47: ethereum.eth.service.BeaconChain.GetBlockV2:output_type -> ethereum.eth.v2.BlockResponseV2
|
||||||
34, // 48: ethereum.eth.service.BeaconChain.ListPoolAttestations:output_type -> ethereum.eth.v1.AttestationsPoolResponse
|
33, // 48: ethereum.eth.service.BeaconChain.GetBlockSSZV2:output_type -> ethereum.eth.v2.BlockSSZResponseV2
|
||||||
0, // 49: ethereum.eth.service.BeaconChain.SubmitAttestations:output_type -> google.protobuf.Empty
|
34, // 49: ethereum.eth.service.BeaconChain.ListBlockAttestations:output_type -> ethereum.eth.v1.BlockAttestationsResponse
|
||||||
35, // 50: ethereum.eth.service.BeaconChain.ListPoolAttesterSlashings:output_type -> ethereum.eth.v1.AttesterSlashingsPoolResponse
|
35, // 50: ethereum.eth.service.BeaconChain.ListPoolAttestations:output_type -> ethereum.eth.v1.AttestationsPoolResponse
|
||||||
0, // 51: ethereum.eth.service.BeaconChain.SubmitAttesterSlashing:output_type -> google.protobuf.Empty
|
0, // 51: ethereum.eth.service.BeaconChain.SubmitAttestations:output_type -> google.protobuf.Empty
|
||||||
36, // 52: ethereum.eth.service.BeaconChain.ListPoolProposerSlashings:output_type -> ethereum.eth.v1.ProposerSlashingPoolResponse
|
36, // 52: ethereum.eth.service.BeaconChain.ListPoolAttesterSlashings:output_type -> ethereum.eth.v1.AttesterSlashingsPoolResponse
|
||||||
0, // 53: ethereum.eth.service.BeaconChain.SubmitProposerSlashing:output_type -> google.protobuf.Empty
|
0, // 53: ethereum.eth.service.BeaconChain.SubmitAttesterSlashing:output_type -> google.protobuf.Empty
|
||||||
37, // 54: ethereum.eth.service.BeaconChain.ListPoolVoluntaryExits:output_type -> ethereum.eth.v1.VoluntaryExitsPoolResponse
|
37, // 54: ethereum.eth.service.BeaconChain.ListPoolProposerSlashings:output_type -> ethereum.eth.v1.ProposerSlashingPoolResponse
|
||||||
0, // 55: ethereum.eth.service.BeaconChain.SubmitVoluntaryExit:output_type -> google.protobuf.Empty
|
0, // 55: ethereum.eth.service.BeaconChain.SubmitProposerSlashing:output_type -> google.protobuf.Empty
|
||||||
0, // 56: ethereum.eth.service.BeaconChain.SubmitPoolSyncCommitteeSignatures:output_type -> google.protobuf.Empty
|
38, // 56: ethereum.eth.service.BeaconChain.ListPoolVoluntaryExits:output_type -> ethereum.eth.v1.VoluntaryExitsPoolResponse
|
||||||
38, // 57: ethereum.eth.service.BeaconChain.GetForkSchedule:output_type -> ethereum.eth.v1.ForkScheduleResponse
|
0, // 57: ethereum.eth.service.BeaconChain.SubmitVoluntaryExit:output_type -> google.protobuf.Empty
|
||||||
39, // 58: ethereum.eth.service.BeaconChain.GetSpec:output_type -> ethereum.eth.v1.SpecResponse
|
0, // 58: ethereum.eth.service.BeaconChain.SubmitPoolSyncCommitteeSignatures:output_type -> google.protobuf.Empty
|
||||||
40, // 59: ethereum.eth.service.BeaconChain.GetDepositContract:output_type -> ethereum.eth.v1.DepositContractResponse
|
39, // 59: ethereum.eth.service.BeaconChain.GetForkSchedule:output_type -> ethereum.eth.v1.ForkScheduleResponse
|
||||||
30, // [30:60] is the sub-list for method output_type
|
40, // 60: ethereum.eth.service.BeaconChain.GetSpec:output_type -> ethereum.eth.v1.SpecResponse
|
||||||
0, // [0:30] is the sub-list for method input_type
|
41, // 61: ethereum.eth.service.BeaconChain.GetDepositContract:output_type -> ethereum.eth.v1.DepositContractResponse
|
||||||
|
31, // [31:62] is the sub-list for method output_type
|
||||||
|
0, // [0:31] is the sub-list for method input_type
|
||||||
0, // [0:0] is the sub-list for extension type_name
|
0, // [0:0] is the sub-list for extension type_name
|
||||||
0, // [0:0] is the sub-list for extension extendee
|
0, // [0:0] is the sub-list for extension extendee
|
||||||
0, // [0:0] is the sub-list for field type_name
|
0, // [0:0] is the sub-list for field type_name
|
||||||
@@ -490,6 +501,7 @@ const _ = grpc.SupportPackageIsVersion6
|
|||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||||
type BeaconChainClient interface {
|
type BeaconChainClient interface {
|
||||||
GetGenesis(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*v1.GenesisResponse, error)
|
GetGenesis(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*v1.GenesisResponse, error)
|
||||||
|
GetWeakSubjectivity(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*v1.WeakSubjectivityResponse, error)
|
||||||
GetStateRoot(ctx context.Context, in *v1.StateRequest, opts ...grpc.CallOption) (*v1.StateRootResponse, error)
|
GetStateRoot(ctx context.Context, in *v1.StateRequest, opts ...grpc.CallOption) (*v1.StateRootResponse, error)
|
||||||
GetStateFork(ctx context.Context, in *v1.StateRequest, opts ...grpc.CallOption) (*v1.StateForkResponse, error)
|
GetStateFork(ctx context.Context, in *v1.StateRequest, opts ...grpc.CallOption) (*v1.StateForkResponse, error)
|
||||||
GetFinalityCheckpoints(ctx context.Context, in *v1.StateRequest, opts ...grpc.CallOption) (*v1.StateFinalityCheckpointResponse, error)
|
GetFinalityCheckpoints(ctx context.Context, in *v1.StateRequest, opts ...grpc.CallOption) (*v1.StateFinalityCheckpointResponse, error)
|
||||||
@@ -538,6 +550,15 @@ func (c *beaconChainClient) GetGenesis(ctx context.Context, in *empty.Empty, opt
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *beaconChainClient) GetWeakSubjectivity(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*v1.WeakSubjectivityResponse, error) {
|
||||||
|
out := new(v1.WeakSubjectivityResponse)
|
||||||
|
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconChain/GetWeakSubjectivity", in, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *beaconChainClient) GetStateRoot(ctx context.Context, in *v1.StateRequest, opts ...grpc.CallOption) (*v1.StateRootResponse, error) {
|
func (c *beaconChainClient) GetStateRoot(ctx context.Context, in *v1.StateRequest, opts ...grpc.CallOption) (*v1.StateRootResponse, error) {
|
||||||
out := new(v1.StateRootResponse)
|
out := new(v1.StateRootResponse)
|
||||||
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconChain/GetStateRoot", in, out, opts...)
|
err := c.cc.Invoke(ctx, "/ethereum.eth.service.BeaconChain/GetStateRoot", in, out, opts...)
|
||||||
@@ -802,6 +823,7 @@ func (c *beaconChainClient) GetDepositContract(ctx context.Context, in *empty.Em
|
|||||||
// BeaconChainServer is the server API for BeaconChain service.
|
// BeaconChainServer is the server API for BeaconChain service.
|
||||||
type BeaconChainServer interface {
|
type BeaconChainServer interface {
|
||||||
GetGenesis(context.Context, *empty.Empty) (*v1.GenesisResponse, error)
|
GetGenesis(context.Context, *empty.Empty) (*v1.GenesisResponse, error)
|
||||||
|
GetWeakSubjectivity(context.Context, *empty.Empty) (*v1.WeakSubjectivityResponse, error)
|
||||||
GetStateRoot(context.Context, *v1.StateRequest) (*v1.StateRootResponse, error)
|
GetStateRoot(context.Context, *v1.StateRequest) (*v1.StateRootResponse, error)
|
||||||
GetStateFork(context.Context, *v1.StateRequest) (*v1.StateForkResponse, error)
|
GetStateFork(context.Context, *v1.StateRequest) (*v1.StateForkResponse, error)
|
||||||
GetFinalityCheckpoints(context.Context, *v1.StateRequest) (*v1.StateFinalityCheckpointResponse, error)
|
GetFinalityCheckpoints(context.Context, *v1.StateRequest) (*v1.StateFinalityCheckpointResponse, error)
|
||||||
@@ -840,6 +862,9 @@ type UnimplementedBeaconChainServer struct {
|
|||||||
func (*UnimplementedBeaconChainServer) GetGenesis(context.Context, *empty.Empty) (*v1.GenesisResponse, error) {
|
func (*UnimplementedBeaconChainServer) GetGenesis(context.Context, *empty.Empty) (*v1.GenesisResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetGenesis not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method GetGenesis not implemented")
|
||||||
}
|
}
|
||||||
|
func (*UnimplementedBeaconChainServer) GetWeakSubjectivity(context.Context, *empty.Empty) (*v1.WeakSubjectivityResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetWeakSubjectivity not implemented")
|
||||||
|
}
|
||||||
func (*UnimplementedBeaconChainServer) GetStateRoot(context.Context, *v1.StateRequest) (*v1.StateRootResponse, error) {
|
func (*UnimplementedBeaconChainServer) GetStateRoot(context.Context, *v1.StateRequest) (*v1.StateRootResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetStateRoot not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method GetStateRoot not implemented")
|
||||||
}
|
}
|
||||||
@@ -950,6 +975,24 @@ func _BeaconChain_GetGenesis_Handler(srv interface{}, ctx context.Context, dec f
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _BeaconChain_GetWeakSubjectivity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(empty.Empty)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(BeaconChainServer).GetWeakSubjectivity(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/ethereum.eth.service.BeaconChain/GetWeakSubjectivity",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(BeaconChainServer).GetWeakSubjectivity(ctx, req.(*empty.Empty))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func _BeaconChain_GetStateRoot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _BeaconChain_GetStateRoot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(v1.StateRequest)
|
in := new(v1.StateRequest)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
@@ -1480,6 +1523,10 @@ var _BeaconChain_serviceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "GetGenesis",
|
MethodName: "GetGenesis",
|
||||||
Handler: _BeaconChain_GetGenesis_Handler,
|
Handler: _BeaconChain_GetGenesis_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetWeakSubjectivity",
|
||||||
|
Handler: _BeaconChain_GetWeakSubjectivity_Handler,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MethodName: "GetStateRoot",
|
MethodName: "GetStateRoot",
|
||||||
Handler: _BeaconChain_GetStateRoot_Handler,
|
Handler: _BeaconChain_GetStateRoot_Handler,
|
||||||
|
|||||||
@@ -57,6 +57,24 @@ func local_request_BeaconChain_GetGenesis_0(ctx context.Context, marshaler runti
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func request_BeaconChain_GetWeakSubjectivity_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq emptypb.Empty
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
msg, err := client.GetWeakSubjectivity(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_BeaconChain_GetWeakSubjectivity_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq emptypb.Empty
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
msg, err := server.GetWeakSubjectivity(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func request_BeaconChain_GetStateRoot_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_BeaconChain_GetStateRoot_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var protoReq v1.StateRequest
|
var protoReq v1.StateRequest
|
||||||
var metadata runtime.ServerMetadata
|
var metadata runtime.ServerMetadata
|
||||||
@@ -1374,6 +1392,29 @@ func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET", pattern_BeaconChain_GetWeakSubjectivity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetWeakSubjectivity")
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_BeaconChain_GetWeakSubjectivity_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_BeaconChain_GetWeakSubjectivity_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("GET", pattern_BeaconChain_GetStateRoot_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("GET", pattern_BeaconChain_GetStateRoot_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -2102,6 +2143,26 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET", pattern_BeaconChain_GetWeakSubjectivity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetWeakSubjectivity")
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_BeaconChain_GetWeakSubjectivity_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||||
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_BeaconChain_GetWeakSubjectivity_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("GET", pattern_BeaconChain_GetStateRoot_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("GET", pattern_BeaconChain_GetStateRoot_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -2688,6 +2749,8 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
|||||||
var (
|
var (
|
||||||
pattern_BeaconChain_GetGenesis_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "beacon", "genesis"}, ""))
|
pattern_BeaconChain_GetGenesis_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "beacon", "genesis"}, ""))
|
||||||
|
|
||||||
|
pattern_BeaconChain_GetWeakSubjectivity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "beacon", "weak_subjectivity"}, ""))
|
||||||
|
|
||||||
pattern_BeaconChain_GetStateRoot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "root"}, ""))
|
pattern_BeaconChain_GetStateRoot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "root"}, ""))
|
||||||
|
|
||||||
pattern_BeaconChain_GetStateFork_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "fork"}, ""))
|
pattern_BeaconChain_GetStateFork_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "fork"}, ""))
|
||||||
@@ -2750,6 +2813,8 @@ var (
|
|||||||
var (
|
var (
|
||||||
forward_BeaconChain_GetGenesis_0 = runtime.ForwardResponseMessage
|
forward_BeaconChain_GetGenesis_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_BeaconChain_GetWeakSubjectivity_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_BeaconChain_GetStateRoot_0 = runtime.ForwardResponseMessage
|
forward_BeaconChain_GetStateRoot_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_BeaconChain_GetStateFork_0 = runtime.ForwardResponseMessage
|
forward_BeaconChain_GetStateFork_0 = runtime.ForwardResponseMessage
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ service BeaconChain {
|
|||||||
option (google.api.http) = { get: "/internal/eth/v1/beacon/genesis" };
|
option (google.api.http) = { get: "/internal/eth/v1/beacon/genesis" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetWeakSubjectivity is a new proposed endpoint to retrieve the details necessary to download
|
||||||
|
// the ssz data needed to start a beacon node - checkpoint(epoch + blocK_root) and state_root
|
||||||
|
rpc GetWeakSubjectivity(google.protobuf.Empty) returns (v1.WeakSubjectivityResponse) {
|
||||||
|
option (google.api.http) = { get: "/internal/eth/v1/beacon/weak_subjectivity" };
|
||||||
|
}
|
||||||
|
|
||||||
// GetStateRoot calculates HashTreeRoot for state with given 'stateId'. If stateId is root, same value will be returned.
|
// GetStateRoot calculates HashTreeRoot for state with given 'stateId'. If stateId is root, same value will be returned.
|
||||||
rpc GetStateRoot(v1.StateRequest) returns (v1.StateRootResponse) {
|
rpc GetStateRoot(v1.StateRequest) returns (v1.StateRootResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
|
|||||||
251
proto/eth/v1/beacon_chain.pb.go
generated
251
proto/eth/v1/beacon_chain.pb.go
generated
@@ -1837,6 +1837,108 @@ func (x *DepositContract) GetAddress() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WeakSubjectivityResponse struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Data *WeakSubjectivityData `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityResponse) Reset() {
|
||||||
|
*x = WeakSubjectivityResponse{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[36]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityResponse) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*WeakSubjectivityResponse) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityResponse) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[36]
|
||||||
|
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 WeakSubjectivityResponse.ProtoReflect.Descriptor instead.
|
||||||
|
func (*WeakSubjectivityResponse) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_eth_v1_beacon_chain_proto_rawDescGZIP(), []int{36}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityResponse) GetData() *WeakSubjectivityData {
|
||||||
|
if x != nil {
|
||||||
|
return x.Data
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type WeakSubjectivityData struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
WsCheckpoint *Checkpoint `protobuf:"bytes,1,opt,name=ws_checkpoint,json=wsCheckpoint,proto3" json:"ws_checkpoint,omitempty"`
|
||||||
|
StateRoot []byte `protobuf:"bytes,2,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityData) Reset() {
|
||||||
|
*x = WeakSubjectivityData{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[37]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityData) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*WeakSubjectivityData) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityData) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[37]
|
||||||
|
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 WeakSubjectivityData.ProtoReflect.Descriptor instead.
|
||||||
|
func (*WeakSubjectivityData) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_eth_v1_beacon_chain_proto_rawDescGZIP(), []int{37}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityData) GetWsCheckpoint() *Checkpoint {
|
||||||
|
if x != nil {
|
||||||
|
return x.WsCheckpoint
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *WeakSubjectivityData) GetStateRoot() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.StateRoot
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type GenesisResponse_Genesis struct {
|
type GenesisResponse_Genesis struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@@ -1850,7 +1952,7 @@ type GenesisResponse_Genesis struct {
|
|||||||
func (x *GenesisResponse_Genesis) Reset() {
|
func (x *GenesisResponse_Genesis) Reset() {
|
||||||
*x = GenesisResponse_Genesis{}
|
*x = GenesisResponse_Genesis{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[36]
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[38]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -1863,7 +1965,7 @@ func (x *GenesisResponse_Genesis) String() string {
|
|||||||
func (*GenesisResponse_Genesis) ProtoMessage() {}
|
func (*GenesisResponse_Genesis) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GenesisResponse_Genesis) ProtoReflect() protoreflect.Message {
|
func (x *GenesisResponse_Genesis) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[36]
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[38]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -1911,7 +2013,7 @@ type StateRootResponse_StateRoot struct {
|
|||||||
func (x *StateRootResponse_StateRoot) Reset() {
|
func (x *StateRootResponse_StateRoot) Reset() {
|
||||||
*x = StateRootResponse_StateRoot{}
|
*x = StateRootResponse_StateRoot{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[37]
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[39]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -1924,7 +2026,7 @@ func (x *StateRootResponse_StateRoot) String() string {
|
|||||||
func (*StateRootResponse_StateRoot) ProtoMessage() {}
|
func (*StateRootResponse_StateRoot) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *StateRootResponse_StateRoot) ProtoReflect() protoreflect.Message {
|
func (x *StateRootResponse_StateRoot) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[37]
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[39]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -1960,7 +2062,7 @@ type StateFinalityCheckpointResponse_StateFinalityCheckpoint struct {
|
|||||||
func (x *StateFinalityCheckpointResponse_StateFinalityCheckpoint) Reset() {
|
func (x *StateFinalityCheckpointResponse_StateFinalityCheckpoint) Reset() {
|
||||||
*x = StateFinalityCheckpointResponse_StateFinalityCheckpoint{}
|
*x = StateFinalityCheckpointResponse_StateFinalityCheckpoint{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[38]
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[40]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -1973,7 +2075,7 @@ func (x *StateFinalityCheckpointResponse_StateFinalityCheckpoint) String() strin
|
|||||||
func (*StateFinalityCheckpointResponse_StateFinalityCheckpoint) ProtoMessage() {}
|
func (*StateFinalityCheckpointResponse_StateFinalityCheckpoint) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *StateFinalityCheckpointResponse_StateFinalityCheckpoint) ProtoReflect() protoreflect.Message {
|
func (x *StateFinalityCheckpointResponse_StateFinalityCheckpoint) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[38]
|
mi := &file_proto_eth_v1_beacon_chain_proto_msgTypes[40]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -2281,7 +2383,20 @@ var file_proto_eth_v1_beacon_chain_proto_rawDesc = []byte{
|
|||||||
0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68,
|
0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68,
|
||||||
0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, 0x68,
|
0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, 0x68,
|
||||||
0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22,
|
||||||
|
0x55, 0x0a, 0x18, 0x57, 0x65, 0x61, 0x6b, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76,
|
||||||
|
0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x04, 0x64,
|
||||||
|
0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||||
|
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x61, 0x6b,
|
||||||
|
0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x61, 0x74, 0x61,
|
||||||
|
0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x77, 0x0a, 0x14, 0x57, 0x65, 0x61, 0x6b, 0x53, 0x75,
|
||||||
|
0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x40,
|
||||||
|
0x0a, 0x0d, 0x77, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18,
|
||||||
|
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||||
|
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69,
|
||||||
|
0x6e, 0x74, 0x52, 0x0c, 0x77, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74,
|
||||||
|
0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02,
|
||||||
|
0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x42,
|
||||||
0x7a, 0x0a, 0x13, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
0x7a, 0x0a, 0x13, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x43, 0x68,
|
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x43, 0x68,
|
||||||
0x61, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68,
|
0x61, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68,
|
||||||
@@ -2305,7 +2420,7 @@ func file_proto_eth_v1_beacon_chain_proto_rawDescGZIP() []byte {
|
|||||||
return file_proto_eth_v1_beacon_chain_proto_rawDescData
|
return file_proto_eth_v1_beacon_chain_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_proto_eth_v1_beacon_chain_proto_msgTypes = make([]protoimpl.MessageInfo, 40)
|
var file_proto_eth_v1_beacon_chain_proto_msgTypes = make([]protoimpl.MessageInfo, 42)
|
||||||
var file_proto_eth_v1_beacon_chain_proto_goTypes = []interface{}{
|
var file_proto_eth_v1_beacon_chain_proto_goTypes = []interface{}{
|
||||||
(*GenesisResponse)(nil), // 0: ethereum.eth.v1.GenesisResponse
|
(*GenesisResponse)(nil), // 0: ethereum.eth.v1.GenesisResponse
|
||||||
(*StateRequest)(nil), // 1: ethereum.eth.v1.StateRequest
|
(*StateRequest)(nil), // 1: ethereum.eth.v1.StateRequest
|
||||||
@@ -2343,58 +2458,62 @@ var file_proto_eth_v1_beacon_chain_proto_goTypes = []interface{}{
|
|||||||
(*SpecResponse)(nil), // 33: ethereum.eth.v1.SpecResponse
|
(*SpecResponse)(nil), // 33: ethereum.eth.v1.SpecResponse
|
||||||
(*DepositContractResponse)(nil), // 34: ethereum.eth.v1.DepositContractResponse
|
(*DepositContractResponse)(nil), // 34: ethereum.eth.v1.DepositContractResponse
|
||||||
(*DepositContract)(nil), // 35: ethereum.eth.v1.DepositContract
|
(*DepositContract)(nil), // 35: ethereum.eth.v1.DepositContract
|
||||||
(*GenesisResponse_Genesis)(nil), // 36: ethereum.eth.v1.GenesisResponse.Genesis
|
(*WeakSubjectivityResponse)(nil), // 36: ethereum.eth.v1.WeakSubjectivityResponse
|
||||||
(*StateRootResponse_StateRoot)(nil), // 37: ethereum.eth.v1.StateRootResponse.StateRoot
|
(*WeakSubjectivityData)(nil), // 37: ethereum.eth.v1.WeakSubjectivityData
|
||||||
(*StateFinalityCheckpointResponse_StateFinalityCheckpoint)(nil), // 38: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint
|
(*GenesisResponse_Genesis)(nil), // 38: ethereum.eth.v1.GenesisResponse.Genesis
|
||||||
nil, // 39: ethereum.eth.v1.SpecResponse.DataEntry
|
(*StateRootResponse_StateRoot)(nil), // 39: ethereum.eth.v1.StateRootResponse.StateRoot
|
||||||
(*Fork)(nil), // 40: ethereum.eth.v1.Fork
|
(*StateFinalityCheckpointResponse_StateFinalityCheckpoint)(nil), // 40: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint
|
||||||
(ValidatorStatus)(0), // 41: ethereum.eth.v1.ValidatorStatus
|
nil, // 41: ethereum.eth.v1.SpecResponse.DataEntry
|
||||||
(*ValidatorContainer)(nil), // 42: ethereum.eth.v1.ValidatorContainer
|
(*Fork)(nil), // 42: ethereum.eth.v1.Fork
|
||||||
(*Committee)(nil), // 43: ethereum.eth.v1.Committee
|
(ValidatorStatus)(0), // 43: ethereum.eth.v1.ValidatorStatus
|
||||||
(*Attestation)(nil), // 44: ethereum.eth.v1.Attestation
|
(*ValidatorContainer)(nil), // 44: ethereum.eth.v1.ValidatorContainer
|
||||||
(*BeaconBlockHeader)(nil), // 45: ethereum.eth.v1.BeaconBlockHeader
|
(*Committee)(nil), // 45: ethereum.eth.v1.Committee
|
||||||
(*BeaconBlock)(nil), // 46: ethereum.eth.v1.BeaconBlock
|
(*Attestation)(nil), // 46: ethereum.eth.v1.Attestation
|
||||||
(*AttesterSlashing)(nil), // 47: ethereum.eth.v1.AttesterSlashing
|
(*BeaconBlockHeader)(nil), // 47: ethereum.eth.v1.BeaconBlockHeader
|
||||||
(*ProposerSlashing)(nil), // 48: ethereum.eth.v1.ProposerSlashing
|
(*BeaconBlock)(nil), // 48: ethereum.eth.v1.BeaconBlock
|
||||||
(*SignedVoluntaryExit)(nil), // 49: ethereum.eth.v1.SignedVoluntaryExit
|
(*AttesterSlashing)(nil), // 49: ethereum.eth.v1.AttesterSlashing
|
||||||
(*timestamppb.Timestamp)(nil), // 50: google.protobuf.Timestamp
|
(*ProposerSlashing)(nil), // 50: ethereum.eth.v1.ProposerSlashing
|
||||||
(*Checkpoint)(nil), // 51: ethereum.eth.v1.Checkpoint
|
(*SignedVoluntaryExit)(nil), // 51: ethereum.eth.v1.SignedVoluntaryExit
|
||||||
|
(*Checkpoint)(nil), // 52: ethereum.eth.v1.Checkpoint
|
||||||
|
(*timestamppb.Timestamp)(nil), // 53: google.protobuf.Timestamp
|
||||||
}
|
}
|
||||||
var file_proto_eth_v1_beacon_chain_proto_depIdxs = []int32{
|
var file_proto_eth_v1_beacon_chain_proto_depIdxs = []int32{
|
||||||
36, // 0: ethereum.eth.v1.GenesisResponse.data:type_name -> ethereum.eth.v1.GenesisResponse.Genesis
|
38, // 0: ethereum.eth.v1.GenesisResponse.data:type_name -> ethereum.eth.v1.GenesisResponse.Genesis
|
||||||
37, // 1: ethereum.eth.v1.StateRootResponse.data:type_name -> ethereum.eth.v1.StateRootResponse.StateRoot
|
39, // 1: ethereum.eth.v1.StateRootResponse.data:type_name -> ethereum.eth.v1.StateRootResponse.StateRoot
|
||||||
40, // 2: ethereum.eth.v1.StateForkResponse.data:type_name -> ethereum.eth.v1.Fork
|
42, // 2: ethereum.eth.v1.StateForkResponse.data:type_name -> ethereum.eth.v1.Fork
|
||||||
38, // 3: ethereum.eth.v1.StateFinalityCheckpointResponse.data:type_name -> ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint
|
40, // 3: ethereum.eth.v1.StateFinalityCheckpointResponse.data:type_name -> ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint
|
||||||
41, // 4: ethereum.eth.v1.StateValidatorsRequest.status:type_name -> ethereum.eth.v1.ValidatorStatus
|
43, // 4: ethereum.eth.v1.StateValidatorsRequest.status:type_name -> ethereum.eth.v1.ValidatorStatus
|
||||||
42, // 5: ethereum.eth.v1.StateValidatorsResponse.data:type_name -> ethereum.eth.v1.ValidatorContainer
|
44, // 5: ethereum.eth.v1.StateValidatorsResponse.data:type_name -> ethereum.eth.v1.ValidatorContainer
|
||||||
9, // 6: ethereum.eth.v1.ValidatorBalancesResponse.data:type_name -> ethereum.eth.v1.ValidatorBalance
|
9, // 6: ethereum.eth.v1.ValidatorBalancesResponse.data:type_name -> ethereum.eth.v1.ValidatorBalance
|
||||||
42, // 7: ethereum.eth.v1.StateValidatorResponse.data:type_name -> ethereum.eth.v1.ValidatorContainer
|
44, // 7: ethereum.eth.v1.StateValidatorResponse.data:type_name -> ethereum.eth.v1.ValidatorContainer
|
||||||
43, // 8: ethereum.eth.v1.StateCommitteesResponse.data:type_name -> ethereum.eth.v1.Committee
|
45, // 8: ethereum.eth.v1.StateCommitteesResponse.data:type_name -> ethereum.eth.v1.Committee
|
||||||
44, // 9: ethereum.eth.v1.BlockAttestationsResponse.data:type_name -> ethereum.eth.v1.Attestation
|
46, // 9: ethereum.eth.v1.BlockAttestationsResponse.data:type_name -> ethereum.eth.v1.Attestation
|
||||||
15, // 10: ethereum.eth.v1.BlockRootResponse.data:type_name -> ethereum.eth.v1.BlockRootContainer
|
15, // 10: ethereum.eth.v1.BlockRootResponse.data:type_name -> ethereum.eth.v1.BlockRootContainer
|
||||||
21, // 11: ethereum.eth.v1.BlockHeadersResponse.data:type_name -> ethereum.eth.v1.BlockHeaderContainer
|
21, // 11: ethereum.eth.v1.BlockHeadersResponse.data:type_name -> ethereum.eth.v1.BlockHeaderContainer
|
||||||
21, // 12: ethereum.eth.v1.BlockHeaderResponse.data:type_name -> ethereum.eth.v1.BlockHeaderContainer
|
21, // 12: ethereum.eth.v1.BlockHeaderResponse.data:type_name -> ethereum.eth.v1.BlockHeaderContainer
|
||||||
22, // 13: ethereum.eth.v1.BlockHeaderContainer.header:type_name -> ethereum.eth.v1.BeaconBlockHeaderContainer
|
22, // 13: ethereum.eth.v1.BlockHeaderContainer.header:type_name -> ethereum.eth.v1.BeaconBlockHeaderContainer
|
||||||
45, // 14: ethereum.eth.v1.BeaconBlockHeaderContainer.message:type_name -> ethereum.eth.v1.BeaconBlockHeader
|
47, // 14: ethereum.eth.v1.BeaconBlockHeaderContainer.message:type_name -> ethereum.eth.v1.BeaconBlockHeader
|
||||||
25, // 15: ethereum.eth.v1.BlockResponse.data:type_name -> ethereum.eth.v1.BeaconBlockContainer
|
25, // 15: ethereum.eth.v1.BlockResponse.data:type_name -> ethereum.eth.v1.BeaconBlockContainer
|
||||||
46, // 16: ethereum.eth.v1.BeaconBlockContainer.message:type_name -> ethereum.eth.v1.BeaconBlock
|
48, // 16: ethereum.eth.v1.BeaconBlockContainer.message:type_name -> ethereum.eth.v1.BeaconBlock
|
||||||
44, // 17: ethereum.eth.v1.SubmitAttestationsRequest.data:type_name -> ethereum.eth.v1.Attestation
|
46, // 17: ethereum.eth.v1.SubmitAttestationsRequest.data:type_name -> ethereum.eth.v1.Attestation
|
||||||
44, // 18: ethereum.eth.v1.AttestationsPoolResponse.data:type_name -> ethereum.eth.v1.Attestation
|
46, // 18: ethereum.eth.v1.AttestationsPoolResponse.data:type_name -> ethereum.eth.v1.Attestation
|
||||||
47, // 19: ethereum.eth.v1.AttesterSlashingsPoolResponse.data:type_name -> ethereum.eth.v1.AttesterSlashing
|
49, // 19: ethereum.eth.v1.AttesterSlashingsPoolResponse.data:type_name -> ethereum.eth.v1.AttesterSlashing
|
||||||
48, // 20: ethereum.eth.v1.ProposerSlashingPoolResponse.data:type_name -> ethereum.eth.v1.ProposerSlashing
|
50, // 20: ethereum.eth.v1.ProposerSlashingPoolResponse.data:type_name -> ethereum.eth.v1.ProposerSlashing
|
||||||
49, // 21: ethereum.eth.v1.VoluntaryExitsPoolResponse.data:type_name -> ethereum.eth.v1.SignedVoluntaryExit
|
51, // 21: ethereum.eth.v1.VoluntaryExitsPoolResponse.data:type_name -> ethereum.eth.v1.SignedVoluntaryExit
|
||||||
40, // 22: ethereum.eth.v1.ForkScheduleResponse.data:type_name -> ethereum.eth.v1.Fork
|
42, // 22: ethereum.eth.v1.ForkScheduleResponse.data:type_name -> ethereum.eth.v1.Fork
|
||||||
39, // 23: ethereum.eth.v1.SpecResponse.data:type_name -> ethereum.eth.v1.SpecResponse.DataEntry
|
41, // 23: ethereum.eth.v1.SpecResponse.data:type_name -> ethereum.eth.v1.SpecResponse.DataEntry
|
||||||
35, // 24: ethereum.eth.v1.DepositContractResponse.data:type_name -> ethereum.eth.v1.DepositContract
|
35, // 24: ethereum.eth.v1.DepositContractResponse.data:type_name -> ethereum.eth.v1.DepositContract
|
||||||
50, // 25: ethereum.eth.v1.GenesisResponse.Genesis.genesis_time:type_name -> google.protobuf.Timestamp
|
37, // 25: ethereum.eth.v1.WeakSubjectivityResponse.data:type_name -> ethereum.eth.v1.WeakSubjectivityData
|
||||||
51, // 26: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.previous_justified:type_name -> ethereum.eth.v1.Checkpoint
|
52, // 26: ethereum.eth.v1.WeakSubjectivityData.ws_checkpoint:type_name -> ethereum.eth.v1.Checkpoint
|
||||||
51, // 27: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.current_justified:type_name -> ethereum.eth.v1.Checkpoint
|
53, // 27: ethereum.eth.v1.GenesisResponse.Genesis.genesis_time:type_name -> google.protobuf.Timestamp
|
||||||
51, // 28: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.finalized:type_name -> ethereum.eth.v1.Checkpoint
|
52, // 28: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.previous_justified:type_name -> ethereum.eth.v1.Checkpoint
|
||||||
29, // [29:29] is the sub-list for method output_type
|
52, // 29: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.current_justified:type_name -> ethereum.eth.v1.Checkpoint
|
||||||
29, // [29:29] is the sub-list for method input_type
|
52, // 30: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.finalized:type_name -> ethereum.eth.v1.Checkpoint
|
||||||
29, // [29:29] is the sub-list for extension type_name
|
31, // [31:31] is the sub-list for method output_type
|
||||||
29, // [29:29] is the sub-list for extension extendee
|
31, // [31:31] is the sub-list for method input_type
|
||||||
0, // [0:29] is the sub-list for field type_name
|
31, // [31:31] is the sub-list for extension type_name
|
||||||
|
31, // [31:31] is the sub-list for extension extendee
|
||||||
|
0, // [0:31] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_proto_eth_v1_beacon_chain_proto_init() }
|
func init() { file_proto_eth_v1_beacon_chain_proto_init() }
|
||||||
@@ -2840,7 +2959,7 @@ func file_proto_eth_v1_beacon_chain_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_proto_eth_v1_beacon_chain_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
|
file_proto_eth_v1_beacon_chain_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*GenesisResponse_Genesis); i {
|
switch v := v.(*WeakSubjectivityResponse); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
case 1:
|
case 1:
|
||||||
@@ -2852,7 +2971,7 @@ func file_proto_eth_v1_beacon_chain_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_proto_eth_v1_beacon_chain_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
|
file_proto_eth_v1_beacon_chain_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*StateRootResponse_StateRoot); i {
|
switch v := v.(*WeakSubjectivityData); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
case 1:
|
case 1:
|
||||||
@@ -2864,6 +2983,30 @@ func file_proto_eth_v1_beacon_chain_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_proto_eth_v1_beacon_chain_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
|
file_proto_eth_v1_beacon_chain_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*GenesisResponse_Genesis); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_proto_eth_v1_beacon_chain_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*StateRootResponse_StateRoot); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_proto_eth_v1_beacon_chain_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*StateFinalityCheckpointResponse_StateFinalityCheckpoint); i {
|
switch v := v.(*StateFinalityCheckpointResponse_StateFinalityCheckpoint); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@@ -2885,7 +3028,7 @@ func file_proto_eth_v1_beacon_chain_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_proto_eth_v1_beacon_chain_proto_rawDesc,
|
RawDescriptor: file_proto_eth_v1_beacon_chain_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 40,
|
NumMessages: 42,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -270,3 +270,12 @@ message DepositContract {
|
|||||||
// The address of the deployed deposit contract in use.
|
// The address of the deployed deposit contract in use.
|
||||||
string address = 2;
|
string address = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message WeakSubjectivityResponse {
|
||||||
|
WeakSubjectivityData data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WeakSubjectivityData {
|
||||||
|
ethereum.eth.v1.Checkpoint ws_checkpoint = 1;
|
||||||
|
bytes state_root = 2;
|
||||||
|
}
|
||||||
|
|||||||
817
proto/prysm/v1alpha1/beacon_chain.pb.go
generated
817
proto/prysm/v1alpha1/beacon_chain.pb.go
generated
File diff suppressed because it is too large
Load Diff
@@ -314,24 +314,6 @@ func local_request_BeaconChain_GetChainHead_0(ctx context.Context, marshaler run
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func request_BeaconChain_GetWeakSubjectivityCheckpoint_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
|
||||||
var protoReq emptypb.Empty
|
|
||||||
var metadata runtime.ServerMetadata
|
|
||||||
|
|
||||||
msg, err := client.GetWeakSubjectivityCheckpoint(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
|
||||||
return msg, metadata, err
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func local_request_BeaconChain_GetWeakSubjectivityCheckpoint_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
|
||||||
var protoReq emptypb.Empty
|
|
||||||
var metadata runtime.ServerMetadata
|
|
||||||
|
|
||||||
msg, err := server.GetWeakSubjectivityCheckpoint(ctx, &protoReq)
|
|
||||||
return msg, metadata, err
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
filter_BeaconChain_ListBeaconCommittees_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
filter_BeaconChain_ListBeaconCommittees_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||||
)
|
)
|
||||||
@@ -988,29 +970,6 @@ func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
mux.Handle("GET", pattern_BeaconChain_GetWeakSubjectivityCheckpoint_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
|
||||||
defer cancel()
|
|
||||||
var stream runtime.ServerTransportStream
|
|
||||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
|
||||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/GetWeakSubjectivityCheckpoint")
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, md, err := local_request_BeaconChain_GetWeakSubjectivityCheckpoint_0(rctx, inboundMarshaler, server, req, pathParams)
|
|
||||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
|
||||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_BeaconChain_GetWeakSubjectivityCheckpoint_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
mux.Handle("GET", pattern_BeaconChain_ListBeaconCommittees_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("GET", pattern_BeaconChain_ListBeaconCommittees_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -1558,26 +1517,6 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
mux.Handle("GET", pattern_BeaconChain_GetWeakSubjectivityCheckpoint_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
|
||||||
defer cancel()
|
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
|
||||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/GetWeakSubjectivityCheckpoint")
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, md, err := request_BeaconChain_GetWeakSubjectivityCheckpoint_0(rctx, inboundMarshaler, client, req, pathParams)
|
|
||||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
|
||||||
if err != nil {
|
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_BeaconChain_GetWeakSubjectivityCheckpoint_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
mux.Handle("GET", pattern_BeaconChain_ListBeaconCommittees_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("GET", pattern_BeaconChain_ListBeaconCommittees_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -1882,8 +1821,6 @@ var (
|
|||||||
|
|
||||||
pattern_BeaconChain_GetChainHead_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "chainhead"}, ""))
|
pattern_BeaconChain_GetChainHead_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "chainhead"}, ""))
|
||||||
|
|
||||||
pattern_BeaconChain_GetWeakSubjectivityCheckpoint_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "weak_subjectivity_checkpoint"}, ""))
|
|
||||||
|
|
||||||
pattern_BeaconChain_ListBeaconCommittees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "committees"}, ""))
|
pattern_BeaconChain_ListBeaconCommittees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "committees"}, ""))
|
||||||
|
|
||||||
pattern_BeaconChain_ListValidatorBalances_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "validators", "balances"}, ""))
|
pattern_BeaconChain_ListValidatorBalances_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "validators", "balances"}, ""))
|
||||||
@@ -1934,8 +1871,6 @@ var (
|
|||||||
|
|
||||||
forward_BeaconChain_GetChainHead_0 = runtime.ForwardResponseMessage
|
forward_BeaconChain_GetChainHead_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_BeaconChain_GetWeakSubjectivityCheckpoint_0 = runtime.ForwardResponseMessage
|
|
||||||
|
|
||||||
forward_BeaconChain_ListBeaconCommittees_0 = runtime.ForwardResponseMessage
|
forward_BeaconChain_ListBeaconCommittees_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_BeaconChain_ListValidatorBalances_0 = runtime.ForwardResponseMessage
|
forward_BeaconChain_ListValidatorBalances_0 = runtime.ForwardResponseMessage
|
||||||
|
|||||||
@@ -150,16 +150,6 @@ service BeaconChain {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve information about the weak subjectivity of the beacon chain from the view of
|
|
||||||
// the beacon chain node.
|
|
||||||
//
|
|
||||||
// This includes the weak subjectivity block root, state root and epoch number.
|
|
||||||
rpc GetWeakSubjectivityCheckpoint(google.protobuf.Empty) returns (WeakSubjectivityCheckpoint) {
|
|
||||||
option (google.api.http) = {
|
|
||||||
get: "/eth/v1alpha1/beacon/weak_subjectivity_checkpoint"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the beacon chain committees for a given epoch.
|
// Retrieve the beacon chain committees for a given epoch.
|
||||||
//
|
//
|
||||||
// If no filter criteria is specified, the response returns
|
// If no filter criteria is specified, the response returns
|
||||||
@@ -907,13 +897,4 @@ message IndividualVotesRespond {
|
|||||||
}
|
}
|
||||||
|
|
||||||
repeated IndividualVote individual_votes = 1;
|
repeated IndividualVote individual_votes = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WeakSubjectivityCheckpoint {
|
|
||||||
// The block root of weak subjectivity checkpoint.
|
|
||||||
bytes block_root = 1;
|
|
||||||
// The state root of weak subjectivity checkpoint.
|
|
||||||
bytes state_root = 2;
|
|
||||||
// The epoch of weak subjectivity checkpoint.
|
|
||||||
uint64 epoch = 3 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/eth2-types.Epoch"];
|
|
||||||
}
|
|
||||||
@@ -37,6 +37,11 @@ go_test(
|
|||||||
"//beacon-chain/state/stategen/mock:go_default_library",
|
"//beacon-chain/state/stategen/mock:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
"//crypto/bls:go_default_library",
|
"//crypto/bls:go_default_library",
|
||||||
|
"//encoding/bytesutil:go_default_library",
|
||||||
|
"//proto/detect:go_default_library",
|
||||||
|
"//proto/eth/service:go_default_library",
|
||||||
|
"//proto/eth/v1:go_default_library",
|
||||||
|
"//proto/eth/v2:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/endtoend/components:go_default_library",
|
"//testing/endtoend/components:go_default_library",
|
||||||
@@ -48,11 +53,14 @@ go_test(
|
|||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
"//testing/slasher/simulator:go_default_library",
|
"//testing/slasher/simulator:go_default_library",
|
||||||
"//testing/util:go_default_library",
|
"//testing/util:go_default_library",
|
||||||
|
"//time/slots:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||||
"@org_golang_google_grpc//:go_default_library",
|
"@org_golang_google_grpc//:go_default_library",
|
||||||
|
"@org_golang_google_grpc//codes:go_default_library",
|
||||||
|
"@org_golang_google_grpc//status:go_default_library",
|
||||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||||
"@org_golang_x_sync//errgroup:go_default_library",
|
"@org_golang_x_sync//errgroup:go_default_library",
|
||||||
],
|
],
|
||||||
@@ -91,7 +99,12 @@ go_test(
|
|||||||
"//beacon-chain/state/stategen:go_default_library",
|
"//beacon-chain/state/stategen:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
"//crypto/bls:go_default_library",
|
"//crypto/bls:go_default_library",
|
||||||
|
"//encoding/bytesutil:go_default_library",
|
||||||
|
"//proto/eth/service:go_default_library",
|
||||||
|
"//proto/eth/v1:go_default_library",
|
||||||
|
"//proto/eth/v2:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
|
"//proto/sniff:go_default_library",
|
||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/endtoend/components:go_default_library",
|
"//testing/endtoend/components:go_default_library",
|
||||||
"//testing/endtoend/components/eth1:go_default_library",
|
"//testing/endtoend/components/eth1:go_default_library",
|
||||||
@@ -102,11 +115,14 @@ go_test(
|
|||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
"//testing/slasher/simulator:go_default_library",
|
"//testing/slasher/simulator:go_default_library",
|
||||||
"//testing/util:go_default_library",
|
"//testing/util:go_default_library",
|
||||||
|
"//time/slots:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||||
"@org_golang_google_grpc//:go_default_library",
|
"@org_golang_google_grpc//:go_default_library",
|
||||||
|
"@org_golang_google_grpc//codes:go_default_library",
|
||||||
|
"@org_golang_google_grpc//status:go_default_library",
|
||||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||||
"@org_golang_x_sync//errgroup:go_default_library",
|
"@org_golang_x_sync//errgroup:go_default_library",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ var _ e2etypes.BeaconNodeSet = (*BeaconNodeSet)(nil)
|
|||||||
|
|
||||||
// BeaconNodeSet represents set of beacon nodes.
|
// BeaconNodeSet represents set of beacon nodes.
|
||||||
type BeaconNodeSet struct {
|
type BeaconNodeSet struct {
|
||||||
e2etypes.ComponentRunner
|
started chan struct{}
|
||||||
config *e2etypes.E2EConfig
|
config *e2etypes.E2EConfig
|
||||||
enr string
|
enr string
|
||||||
ids []string
|
e2etypes.ComponentRunner
|
||||||
started chan struct{}
|
ids []string
|
||||||
|
flags []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetENR assigns ENR to the set of beacon nodes.
|
// SetENR assigns ENR to the set of beacon nodes.
|
||||||
@@ -40,10 +41,11 @@ func (s *BeaconNodeSet) SetENR(enr string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewBeaconNodes creates and returns a set of beacon nodes.
|
// NewBeaconNodes creates and returns a set of beacon nodes.
|
||||||
func NewBeaconNodes(config *e2etypes.E2EConfig) *BeaconNodeSet {
|
func NewBeaconNodes(flags []string, config *e2etypes.E2EConfig) *BeaconNodeSet {
|
||||||
return &BeaconNodeSet{
|
return &BeaconNodeSet{
|
||||||
config: config,
|
flags: flags,
|
||||||
started: make(chan struct{}, 1),
|
started: make(chan struct{}, 1),
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ func (s *BeaconNodeSet) Start(ctx context.Context) error {
|
|||||||
// Create beacon nodes.
|
// Create beacon nodes.
|
||||||
nodes := make([]e2etypes.ComponentRunner, e2e.TestParams.BeaconNodeCount)
|
nodes := make([]e2etypes.ComponentRunner, e2e.TestParams.BeaconNodeCount)
|
||||||
for i := 0; i < e2e.TestParams.BeaconNodeCount; i++ {
|
for i := 0; i < e2e.TestParams.BeaconNodeCount; i++ {
|
||||||
nodes[i] = NewBeaconNode(s.config, i, s.enr)
|
nodes[i] = NewBeaconNode(i, s.enr, s.flags, s.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for all nodes to finish their job (blocking).
|
// Wait for all nodes to finish their job (blocking).
|
||||||
@@ -82,19 +84,21 @@ func (s *BeaconNodeSet) Started() <-chan struct{} {
|
|||||||
type BeaconNode struct {
|
type BeaconNode struct {
|
||||||
e2etypes.ComponentRunner
|
e2etypes.ComponentRunner
|
||||||
config *e2etypes.E2EConfig
|
config *e2etypes.E2EConfig
|
||||||
started chan struct{}
|
|
||||||
index int
|
index int
|
||||||
|
flags []string
|
||||||
|
started chan struct{}
|
||||||
enr string
|
enr string
|
||||||
peerID string
|
peerID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBeaconNode creates and returns a beacon node.
|
// NewBeaconNode creates and returns a beacon node.
|
||||||
func NewBeaconNode(config *e2etypes.E2EConfig, index int, enr string) *BeaconNode {
|
func NewBeaconNode(index int, enr string, flags []string, config *e2etypes.E2EConfig) *BeaconNode {
|
||||||
return &BeaconNode{
|
return &BeaconNode{
|
||||||
config: config,
|
|
||||||
index: index,
|
index: index,
|
||||||
enr: enr,
|
enr: enr,
|
||||||
started: make(chan struct{}, 1),
|
started: make(chan struct{}, 1),
|
||||||
|
flags: flags,
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +110,7 @@ func (node *BeaconNode) Start(ctx context.Context) error {
|
|||||||
return errors.New("beacon chain binary not found")
|
return errors.New("beacon chain binary not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
config, index, enr := node.config, node.index, node.enr
|
config, nodeFlags, index, enr := node.config, node.flags, node.index, node.enr
|
||||||
stdOutFile, err := helpers.DeleteAndCreateFile(e2e.TestParams.LogPath, fmt.Sprintf(e2e.BeaconNodeLogFileName, index))
|
stdOutFile, err := helpers.DeleteAndCreateFile(e2e.TestParams.LogPath, fmt.Sprintf(e2e.BeaconNodeLogFileName, index))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -146,6 +150,7 @@ func (node *BeaconNode) Start(ctx context.Context) error {
|
|||||||
args = append(args, features.E2EBeaconChainFlags...)
|
args = append(args, features.E2EBeaconChainFlags...)
|
||||||
}
|
}
|
||||||
args = append(args, config.BeaconFlags...)
|
args = append(args, config.BeaconFlags...)
|
||||||
|
args = append(args, nodeFlags...)
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx, binaryPath, args...) // #nosec G204 -- Safe
|
cmd := exec.CommandContext(ctx, binaryPath, args...) // #nosec G204 -- Safe
|
||||||
// Write stdout and stderr to log files.
|
// Write stdout and stderr to log files.
|
||||||
@@ -176,7 +181,7 @@ func (node *BeaconNode) Start(ctx context.Context) error {
|
|||||||
return fmt.Errorf("could not find multiaddr for node %d, this means the node had issues starting: %w", index, err)
|
return fmt.Errorf("could not find multiaddr for node %d, this means the node had issues starting: %w", index, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.UseFixedPeerIDs {
|
if node.config.UseFixedPeerIDs {
|
||||||
peerId, err := helpers.FindFollowingTextInFile(stdOutFile, "Running node with peer id of ")
|
peerId, err := helpers.FindFollowingTextInFile(stdOutFile, "Running node with peer id of ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not find peer id: %w", err)
|
return fmt.Errorf("could not find peer id: %w", err)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/testing/endtoend/helpers"
|
"github.com/prysmaticlabs/prysm/testing/endtoend/helpers"
|
||||||
e2e "github.com/prysmaticlabs/prysm/testing/endtoend/params"
|
e2e "github.com/prysmaticlabs/prysm/testing/endtoend/params"
|
||||||
e2etypes "github.com/prysmaticlabs/prysm/testing/endtoend/types"
|
e2etypes "github.com/prysmaticlabs/prysm/testing/endtoend/types"
|
||||||
@@ -48,10 +49,12 @@ func (node *BootNode) Start(ctx context.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg := params.E2ETestConfig()
|
||||||
args := []string{
|
args := []string{
|
||||||
fmt.Sprintf("--log-file=%s", stdOutFile.Name()),
|
fmt.Sprintf("--log-file=%s", stdOutFile.Name()),
|
||||||
fmt.Sprintf("--discv5-port=%d", e2e.TestParams.Ports.BootNodePort),
|
fmt.Sprintf("--discv5-port=%d", e2e.TestParams.Ports.BootNodePort),
|
||||||
fmt.Sprintf("--metrics-port=%d", e2e.TestParams.Ports.BootNodeMetricsPort),
|
fmt.Sprintf("--metrics-port=%d", e2e.TestParams.Ports.BootNodeMetricsPort),
|
||||||
|
fmt.Sprintf("--fork-version=%#x", cfg.GenesisForkVersion),
|
||||||
"--debug",
|
"--debug",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ import (
|
|||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
"github.com/prysmaticlabs/prysm/proto/detect"
|
||||||
|
"github.com/prysmaticlabs/prysm/proto/eth/service"
|
||||||
|
v1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||||
|
eth2 "github.com/prysmaticlabs/prysm/proto/eth/v2"
|
||||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/endtoend/components"
|
"github.com/prysmaticlabs/prysm/testing/endtoend/components"
|
||||||
@@ -27,9 +32,12 @@ import (
|
|||||||
e2e "github.com/prysmaticlabs/prysm/testing/endtoend/params"
|
e2e "github.com/prysmaticlabs/prysm/testing/endtoend/params"
|
||||||
e2etypes "github.com/prysmaticlabs/prysm/testing/endtoend/types"
|
e2etypes "github.com/prysmaticlabs/prysm/testing/endtoend/types"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -48,15 +56,23 @@ func init() {
|
|||||||
|
|
||||||
// testRunner abstracts E2E test configuration and running.
|
// testRunner abstracts E2E test configuration and running.
|
||||||
type testRunner struct {
|
type testRunner struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
config *e2etypes.E2EConfig
|
config *e2etypes.E2EConfig
|
||||||
|
ctx context.Context
|
||||||
|
doneChan context.CancelFunc
|
||||||
|
group *errgroup.Group
|
||||||
}
|
}
|
||||||
|
|
||||||
// newTestRunner creates E2E test runner.
|
// newTestRunner creates E2E test runner.
|
||||||
func newTestRunner(t *testing.T, config *e2etypes.E2EConfig) *testRunner {
|
func newTestRunner(t *testing.T, config *e2etypes.E2EConfig) *testRunner {
|
||||||
|
ctx, done := context.WithCancel(context.Background())
|
||||||
|
g, ctx := errgroup.WithContext(ctx)
|
||||||
return &testRunner{
|
return &testRunner{
|
||||||
t: t,
|
ctx: ctx,
|
||||||
config: config,
|
doneChan: done,
|
||||||
|
group: g,
|
||||||
|
t: t,
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,14 +83,18 @@ func (r *testRunner) run() {
|
|||||||
t.Logf("Starting time: %s\n", time.Now().String())
|
t.Logf("Starting time: %s\n", time.Now().String())
|
||||||
t.Logf("Log Path: %s\n", e2e.TestParams.LogPath)
|
t.Logf("Log Path: %s\n", e2e.TestParams.LogPath)
|
||||||
|
|
||||||
|
// we need debug turned on and max ssz payload bumped up when running checkpoint sync tests
|
||||||
|
if config.TestSync {
|
||||||
|
config.BeaconFlags = appendDebugEndpoints(config.BeaconFlags)
|
||||||
|
}
|
||||||
minGenesisActiveCount := int(params.BeaconConfig().MinGenesisActiveValidatorCount)
|
minGenesisActiveCount := int(params.BeaconConfig().MinGenesisActiveValidatorCount)
|
||||||
multiClientActive := e2e.TestParams.LighthouseBeaconNodeCount > 0
|
multiClientActive := e2e.TestParams.LighthouseBeaconNodeCount > 0
|
||||||
var keyGen, lighthouseValidatorNodes e2etypes.ComponentRunner
|
var keyGen, lighthouseValidatorNodes e2etypes.ComponentRunner
|
||||||
var lighthouseNodes *components.LighthouseBeaconNodeSet
|
var lighthouseNodes *components.LighthouseBeaconNodeSet
|
||||||
|
|
||||||
ctx, done := context.WithCancel(context.Background())
|
ctx := r.ctx
|
||||||
g, ctx := errgroup.WithContext(ctx)
|
g := r.group
|
||||||
|
done := r.doneChan
|
||||||
tracingSink := components.NewTracingSink(config.TracingSinkEndpoint)
|
tracingSink := components.NewTracingSink(config.TracingSinkEndpoint)
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
return tracingSink.Start(ctx)
|
return tracingSink.Start(ctx)
|
||||||
@@ -134,7 +154,7 @@ func (r *testRunner) run() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Beacon nodes.
|
// Beacon nodes.
|
||||||
beaconNodes := components.NewBeaconNodes(config)
|
beaconNodes := components.NewBeaconNodes(config.BeaconFlags, config)
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
if err := helpers.ComponentsStarted(ctx, []e2etypes.ComponentRunner{eth1Nodes, bootNode}); err != nil {
|
if err := helpers.ComponentsStarted(ctx, []e2etypes.ComponentRunner{eth1Nodes, bootNode}); err != nil {
|
||||||
return errors.Wrap(err, "beacon nodes require ETH1 and boot node to run")
|
return errors.Wrap(err, "beacon nodes require ETH1 and boot node to run")
|
||||||
@@ -269,6 +289,10 @@ func (r *testRunner) run() {
|
|||||||
if err := r.testBeaconChainSync(ctx, g, conns, tickingStartTime, bootNode.ENR(), eth1Miner.ENR()); err != nil {
|
if err := r.testBeaconChainSync(ctx, g, conns, tickingStartTime, bootNode.ENR(), eth1Miner.ENR()); err != nil {
|
||||||
return errors.Wrap(err, "beacon chain sync test failed")
|
return errors.Wrap(err, "beacon chain sync test failed")
|
||||||
}
|
}
|
||||||
|
index := e2e.TestParams.BeaconNodeCount
|
||||||
|
if err := r.testCheckpointSync(index+1, conns, bootNode.ENR()); err != nil {
|
||||||
|
return errors.Wrap(err, "checkpoint sync test failed")
|
||||||
|
}
|
||||||
if err := r.testDoppelGangerProtection(ctx); err != nil {
|
if err := r.testDoppelGangerProtection(ctx); err != nil {
|
||||||
return errors.Wrap(err, "doppel ganger protection check failed")
|
return errors.Wrap(err, "doppel ganger protection check failed")
|
||||||
}
|
}
|
||||||
@@ -284,6 +308,14 @@ func (r *testRunner) run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func appendDebugEndpoints(flags []string) []string {
|
||||||
|
debugFlags := []string{
|
||||||
|
"--enable-debug-rpc-endpoints",
|
||||||
|
"--grpc-max-msg-size=65568081",
|
||||||
|
}
|
||||||
|
return append(flags, debugFlags...)
|
||||||
|
}
|
||||||
|
|
||||||
// waitForChainStart allows to wait up until beacon nodes are started.
|
// waitForChainStart allows to wait up until beacon nodes are started.
|
||||||
func (r *testRunner) waitForChainStart() {
|
func (r *testRunner) waitForChainStart() {
|
||||||
// Sleep depending on the count of validators, as generating the genesis state could take some time.
|
// Sleep depending on the count of validators, as generating the genesis state could take some time.
|
||||||
@@ -351,16 +383,284 @@ func (r *testRunner) testDeposits(ctx context.Context, g *errgroup.Group,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type saveable interface {
|
||||||
|
MarshalSSZ() ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveSSZBytes(filePath string, value saveable) (err error) {
|
||||||
|
b, err := value.MarshalSSZ()
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "saveSSZBytes/MarshalSSZ")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fh, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "saveSSZBytes/os.Create")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err = errors.Wrap(err, "saveSSZBytes/defered close")
|
||||||
|
err = fh.Close()
|
||||||
|
}()
|
||||||
|
_, err = fh.Write(b)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "saveSSZBytes/fh.Write")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveBlock(ctx context.Context, conn *grpc.ClientConn, cf *detect.ConfigFork, root [32]byte, basePath string) (string, error) {
|
||||||
|
v1Client := service.NewBeaconChainClient(conn)
|
||||||
|
//blockId := fmt.Sprintf("%#x", root)
|
||||||
|
bResp, err := v1Client.GetBlockSSZV2(ctx, ð2.BlockRequestV2{BlockId: root[:]})
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "saveBlock/GetBeaconBlock")
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
sb, err := cf.UnmarshalBeaconBlock(bResp.GetData())
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "saveBlock/GetBeaconBlock")
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
p := path.Join(basePath, fmt.Sprintf("block_%d_%x.ssz", sb.Block().Slot(), root))
|
||||||
|
err = saveSSZBytes(p, sb)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "saveBlock/saveSSZBytes")
|
||||||
|
}
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConfigFork(ctx context.Context, conn *grpc.ClientConn, slot types.Slot) (*detect.ConfigFork, error) {
|
||||||
|
ofs, err := getOrderedForkSchedule(ctx, conn)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "getConfigFork/getOrderedForkSchedule")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
epoch := slots.ToEpoch(slot)
|
||||||
|
version, err := ofs.VersionForEpoch(epoch)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "getConfigFork/VersionForEpoch")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cf, err := detect.ByVersion(version)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "getConfigFork/ByVersion")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cf, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveState(ctx context.Context, conn *grpc.ClientConn, cf *detect.ConfigFork, slot types.Slot, basePath string) (string, [32]byte, error) {
|
||||||
|
debugClient := service.NewBeaconDebugClient(conn)
|
||||||
|
stateId := []byte(fmt.Sprintf("%d", slot))
|
||||||
|
sResp, err := debugClient.GetBeaconStateSSZV2(ctx, ð2.StateRequestV2{StateId: stateId})
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "saveState/GetBeaconState")
|
||||||
|
return "", [32]byte{}, err
|
||||||
|
}
|
||||||
|
state, err := cf.UnmarshalBeaconState(sResp.Data)
|
||||||
|
if err != nil {
|
||||||
|
return "", [32]byte{}, errors.Wrap(err, "saveState/BeaconStateForConfigFork")
|
||||||
|
}
|
||||||
|
stateRoot, err := state.HashTreeRoot(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", [32]byte{}, errors.Wrap(err, "saveState/BeaconStateForConfigFork")
|
||||||
|
}
|
||||||
|
|
||||||
|
p := path.Join(basePath, fmt.Sprintf("state_%d_%x.ssz", state.Slot(), stateRoot))
|
||||||
|
err = saveSSZBytes(p, state)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "saveState/saveSSZBytes")
|
||||||
|
}
|
||||||
|
return p, stateRoot, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type checkpoint struct {
|
||||||
|
statePath string
|
||||||
|
stateRoot [32]byte
|
||||||
|
blockPath string
|
||||||
|
blockRoot [32]byte
|
||||||
|
headRoot [32]byte
|
||||||
|
epoch types.Epoch
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkpoint) flags() []string {
|
||||||
|
return []string{
|
||||||
|
fmt.Sprintf("--checkpoint-state=%s", c.statePath),
|
||||||
|
fmt.Sprintf("--checkpoint-block=%s", c.blockPath),
|
||||||
|
fmt.Sprintf("--weak-subjectivity-checkpoint=%x:%d", c.blockRoot, c.epoch),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOrderedForkSchedule(ctx context.Context, conn *grpc.ClientConn) (params.OrderedForkSchedule, error) {
|
||||||
|
v1Client := service.NewBeaconChainClient(conn)
|
||||||
|
fsResp, err := v1Client.GetForkSchedule(ctx, &emptypb.Empty{})
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "getOrderedForkSchedule:GetForkSchedule")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ofs := make(params.OrderedForkSchedule, 0)
|
||||||
|
for _, f := range fsResp.Data {
|
||||||
|
ofs = append(ofs, params.ForkScheduleEntry{
|
||||||
|
Version: bytesutil.ToBytes4(f.CurrentVersion),
|
||||||
|
Epoch: f.Epoch,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ofs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHeadBlockRoot(ctx context.Context, conn *grpc.ClientConn) ([32]byte, error) {
|
||||||
|
v1Client := service.NewBeaconChainClient(conn)
|
||||||
|
bResp, err := v1Client.GetBlockRoot(ctx, &v1.BlockRequest{BlockId: []byte("head")})
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "getHeadBlockRoot:GetBlockRoot")
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
return bytesutil.ToBytes32(bResp.Data.Root), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadCheckpoint(ctx context.Context, conn *grpc.ClientConn) (*checkpoint, error) {
|
||||||
|
v1Client := service.NewBeaconChainClient(conn)
|
||||||
|
resp, err := v1Client.GetWeakSubjectivity(ctx, &emptypb.Empty{})
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "downloadCheckpoint:GetWeakSubjectivityCheckpointEpoch")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ws := resp.Data
|
||||||
|
cp := &checkpoint{
|
||||||
|
epoch: ws.WsCheckpoint.Epoch,
|
||||||
|
stateRoot: bytesutil.ToBytes32(ws.StateRoot),
|
||||||
|
blockRoot: bytesutil.ToBytes32(ws.WsCheckpoint.Root),
|
||||||
|
}
|
||||||
|
|
||||||
|
headRoot, err := getHeadBlockRoot(ctx, conn)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "downloadCheckpoint:getHeadBlockRoot")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cp.headRoot = headRoot
|
||||||
|
|
||||||
|
// save the block at epoch start slot
|
||||||
|
wsSlot, err := slots.EpochStart(cp.epoch)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "downloadCheckpoint:EpochStart")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch the state for the slot immediately following (and therefore integrating) the block
|
||||||
|
cf, err := getConfigFork(ctx, conn, wsSlot)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "downloadCheckpoint:getConfigFork")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cp.blockPath, err = saveBlock(ctx, conn, cf, cp.blockRoot, e2e.TestParams.TestPath)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "downloadCheckpoint:saveBlock")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var sr [32]byte
|
||||||
|
cp.statePath, sr, err = saveState(ctx, conn, cf, wsSlot, e2e.TestParams.TestPath)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "downloadCheckpoint:saveState")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if sr != cp.stateRoot {
|
||||||
|
err = fmt.Errorf("state htr (%#x) at slot %d != weak_subjectivity response (%#x)", cp.stateRoot, wsSlot, sr)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *testRunner) waitForSentinelBlock(ctx context.Context, conn *grpc.ClientConn, root [32]byte) error {
|
||||||
|
// sleep hack copied from testBeaconChainSync
|
||||||
|
// Sleep a second for every 4 blocks that need to be synced for the newly started node.
|
||||||
|
secondsPerEpoch := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
|
extraSecondsToSync := (r.config.EpochsToRun)*secondsPerEpoch + uint64(params.BeaconConfig().SlotsPerEpoch.Div(4).Mul(r.config.EpochsToRun))
|
||||||
|
ctx, cancel := context.WithDeadline(r.ctx, time.Now().Add(time.Second*time.Duration(extraSecondsToSync)))
|
||||||
|
defer cancel()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
// deadline ensures that the test eventually exits when beacon node fails to sync in a resonable timeframe
|
||||||
|
return fmt.Errorf("deadline exceeded waiting for known good block to appear in checkpoint-synced node")
|
||||||
|
case <-time.After(time.Second * 1):
|
||||||
|
v1Client := service.NewBeaconChainClient(conn)
|
||||||
|
bResp, err := v1Client.GetBlockRoot(ctx, &v1.BlockRequest{BlockId: []byte("head")})
|
||||||
|
if err != nil {
|
||||||
|
errStatus, ok := status.FromError(err)
|
||||||
|
// in the happy path we expect NotFound results until the node has synced
|
||||||
|
if ok && errStatus.Code() == codes.NotFound {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("error requesting block w/ root '%x' = %s", root, err)
|
||||||
|
}
|
||||||
|
// we have a match, sentinel block found
|
||||||
|
if bytesutil.ToBytes32(bResp.Data.Root) == root {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *testRunner) testCheckpointSync(i int, conns []*grpc.ClientConn, enr string) error {
|
||||||
|
conn := conns[0]
|
||||||
|
cp, err := downloadCheckpoint(r.ctx, conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
flags := append(r.config.BeaconFlags, cp.flags()...)
|
||||||
|
// zero-indexed, so next value would be len of list
|
||||||
|
cpsyncer := components.NewBeaconNode(i, enr, flags, r.config)
|
||||||
|
r.group.Go(func() error {
|
||||||
|
return cpsyncer.Start(r.ctx)
|
||||||
|
})
|
||||||
|
if err := helpers.ComponentsStarted(r.ctx, []e2etypes.ComponentRunner{cpsyncer}); err != nil {
|
||||||
|
return fmt.Errorf("checkpoint sync beacon node not ready: %w", err)
|
||||||
|
}
|
||||||
|
c, err := grpc.Dial(fmt.Sprintf("127.0.0.1:%d", e2e.TestParams.Ports.PrysmBeaconNodeRPCPort+i), grpc.WithInsecure())
|
||||||
|
require.NoError(r.t, err, "Failed to dial")
|
||||||
|
|
||||||
|
// this is so that the syncEvaluators checks can run on the checkpoint sync'd node
|
||||||
|
conns = append(conns, c)
|
||||||
|
err = r.waitForSentinelBlock(r.ctx, conn, cp.headRoot)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
syncLogFile, err := os.Open(path.Join(e2e.TestParams.LogPath, fmt.Sprintf(e2e.BeaconNodeLogFileName, i)))
|
||||||
|
require.NoError(r.t, err)
|
||||||
|
defer helpers.LogErrorOutput(r.t, syncLogFile, "beacon chain node", i)
|
||||||
|
r.t.Run("sync completed", func(t *testing.T) {
|
||||||
|
assert.NoError(t, helpers.WaitForTextInFile(syncLogFile, "Synced up to"), "Failed to sync")
|
||||||
|
})
|
||||||
|
if r.t.Failed() {
|
||||||
|
return errors.New("cannot sync beacon node")
|
||||||
|
}
|
||||||
|
|
||||||
|
syncEvaluators := []e2etypes.Evaluator{ev.FinishedSyncing, ev.AllNodesHaveSameHead}
|
||||||
|
for _, evaluator := range syncEvaluators {
|
||||||
|
r.t.Run(evaluator.Name, func(t *testing.T) {
|
||||||
|
assert.NoError(t, evaluator.Evaluation(conns...), "Evaluation failed for sync node")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// testBeaconChainSync creates another beacon node, and tests whether it can sync to head using previous nodes.
|
// testBeaconChainSync creates another beacon node, and tests whether it can sync to head using previous nodes.
|
||||||
func (r *testRunner) testBeaconChainSync(ctx context.Context, g *errgroup.Group,
|
func (r *testRunner) testBeaconChainSync(ctx context.Context, g *errgroup.Group,
|
||||||
conns []*grpc.ClientConn, tickingStartTime time.Time, bootnodeEnr, minerEnr string) error {
|
conns []*grpc.ClientConn, tickingStartTime time.Time, bootnodeEnr, minerEnr string) error {
|
||||||
t, config := r.t, r.config
|
|
||||||
index := e2e.TestParams.BeaconNodeCount
|
index := e2e.TestParams.BeaconNodeCount
|
||||||
|
t, config := r.t, r.config
|
||||||
ethNode := eth1.NewNode(index, minerEnr)
|
ethNode := eth1.NewNode(index, minerEnr)
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
return ethNode.Start(ctx)
|
return ethNode.Start(ctx)
|
||||||
})
|
})
|
||||||
syncBeaconNode := components.NewBeaconNode(config, index, bootnodeEnr)
|
syncBeaconNode := components.NewBeaconNode(index, bootnodeEnr, r.config.BeaconFlags, config)
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
return syncBeaconNode.Start(ctx)
|
return syncBeaconNode.Start(ctx)
|
||||||
})
|
})
|
||||||
@@ -373,17 +673,17 @@ func (r *testRunner) testBeaconChainSync(ctx context.Context, g *errgroup.Group,
|
|||||||
|
|
||||||
// Sleep a second for every 4 blocks that need to be synced for the newly started node.
|
// Sleep a second for every 4 blocks that need to be synced for the newly started node.
|
||||||
secondsPerEpoch := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
secondsPerEpoch := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||||
extraSecondsToSync := (config.EpochsToRun)*secondsPerEpoch + uint64(params.BeaconConfig().SlotsPerEpoch.Div(4).Mul(config.EpochsToRun))
|
extraSecondsToSync := (r.config.EpochsToRun)*secondsPerEpoch + uint64(params.BeaconConfig().SlotsPerEpoch.Div(4).Mul(r.config.EpochsToRun))
|
||||||
waitForSync := tickingStartTime.Add(time.Duration(extraSecondsToSync) * time.Second)
|
waitForSync := tickingStartTime.Add(time.Duration(extraSecondsToSync) * time.Second)
|
||||||
time.Sleep(time.Until(waitForSync))
|
time.Sleep(time.Until(waitForSync))
|
||||||
|
|
||||||
syncLogFile, err := os.Open(path.Join(e2e.TestParams.LogPath, fmt.Sprintf(e2e.BeaconNodeLogFileName, index)))
|
syncLogFile, err := os.Open(path.Join(e2e.TestParams.LogPath, fmt.Sprintf(e2e.BeaconNodeLogFileName, index)))
|
||||||
require.NoError(t, err)
|
require.NoError(r.t, err)
|
||||||
defer helpers.LogErrorOutput(t, syncLogFile, "beacon chain node", index)
|
defer helpers.LogErrorOutput(r.t, syncLogFile, "beacon chain node", index)
|
||||||
t.Run("sync completed", func(t *testing.T) {
|
r.t.Run("sync completed", func(t *testing.T) {
|
||||||
assert.NoError(t, helpers.WaitForTextInFile(syncLogFile, "Synced up to"), "Failed to sync")
|
assert.NoError(t, helpers.WaitForTextInFile(syncLogFile, "Synced up to"), "Failed to sync")
|
||||||
})
|
})
|
||||||
if t.Failed() {
|
if r.t.Failed() {
|
||||||
return errors.New("cannot sync beacon node")
|
return errors.New("cannot sync beacon node")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,7 +691,7 @@ func (r *testRunner) testBeaconChainSync(ctx context.Context, g *errgroup.Group,
|
|||||||
time.Sleep(time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
|
time.Sleep(time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
|
||||||
syncEvaluators := []e2etypes.Evaluator{ev.FinishedSyncing, ev.AllNodesHaveSameHead}
|
syncEvaluators := []e2etypes.Evaluator{ev.FinishedSyncing, ev.AllNodesHaveSameHead}
|
||||||
for _, evaluator := range syncEvaluators {
|
for _, evaluator := range syncEvaluators {
|
||||||
t.Run(evaluator.Name, func(t *testing.T) {
|
r.t.Run(evaluator.Name, func(t *testing.T) {
|
||||||
assert.NoError(t, evaluator.Evaluation(conns...), "Evaluation failed for sync node")
|
assert.NoError(t, evaluator.Evaluation(conns...), "Evaluation failed for sync node")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
20
testing/mock/beacon_service_mock.go
generated
20
testing/mock/beacon_service_mock.go
generated
@@ -218,26 +218,6 @@ func (mr *MockBeaconChainClientMockRecorder) GetValidatorQueue(arg0, arg1 interf
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorQueue", reflect.TypeOf((*MockBeaconChainClient)(nil).GetValidatorQueue), varargs...)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorQueue", reflect.TypeOf((*MockBeaconChainClient)(nil).GetValidatorQueue), varargs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWeakSubjectivityCheckpoint mocks base method
|
|
||||||
func (m *MockBeaconChainClient) GetWeakSubjectivityCheckpoint(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc.CallOption) (*eth.WeakSubjectivityCheckpoint, error) {
|
|
||||||
m.ctrl.T.Helper()
|
|
||||||
varargs := []interface{}{arg0, arg1}
|
|
||||||
for _, a := range arg2 {
|
|
||||||
varargs = append(varargs, a)
|
|
||||||
}
|
|
||||||
ret := m.ctrl.Call(m, "GetWeakSubjectivityCheckpoint", varargs...)
|
|
||||||
ret0, _ := ret[0].(*eth.WeakSubjectivityCheckpoint)
|
|
||||||
ret1, _ := ret[1].(error)
|
|
||||||
return ret0, ret1
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetWeakSubjectivityCheckpoint indicates an expected call of GetWeakSubjectivityCheckpoint
|
|
||||||
func (mr *MockBeaconChainClientMockRecorder) GetWeakSubjectivityCheckpoint(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
|
|
||||||
mr.mock.ctrl.T.Helper()
|
|
||||||
varargs := append([]interface{}{arg0, arg1}, arg2...)
|
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWeakSubjectivityCheckpoint", reflect.TypeOf((*MockBeaconChainClient)(nil).GetWeakSubjectivityCheckpoint), varargs...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListAttestations mocks base method
|
// ListAttestations mocks base method
|
||||||
func (m *MockBeaconChainClient) ListAttestations(arg0 context.Context, arg1 *eth.ListAttestationsRequest, arg2 ...grpc.CallOption) (*eth.ListAttestationsResponse, error) {
|
func (m *MockBeaconChainClient) ListAttestations(arg0 context.Context, arg1 *eth.ListAttestationsRequest, arg2 ...grpc.CallOption) (*eth.ListAttestationsResponse, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
|||||||
@@ -192,8 +192,12 @@ func createLocalNode(privKey *ecdsa.PrivateKey, ipAddr net.IP, port int) (*enode
|
|||||||
external = ipAddr
|
external = ipAddr
|
||||||
}
|
}
|
||||||
fVersion := params.BeaconConfig().GenesisForkVersion
|
fVersion := params.BeaconConfig().GenesisForkVersion
|
||||||
if *forkVersion != "" {
|
fv := *forkVersion
|
||||||
fVersion, err = hex.DecodeString(*forkVersion)
|
if fv != "" {
|
||||||
|
if fv[0:2] == "0x" {
|
||||||
|
fv = fv[2:]
|
||||||
|
}
|
||||||
|
fVersion, err = hex.DecodeString(fv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Could not retrieve fork version")
|
return nil, errors.Wrap(err, "Could not retrieve fork version")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func NewValidatorClient(cliCtx *cli.Context) (*ValidatorClient, error) {
|
|||||||
|
|
||||||
if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) {
|
if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) {
|
||||||
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
|
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
|
||||||
params.LoadChainConfigFile(chainConfigFileName)
|
params.LoadChainConfigFile(chainConfigFileName, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the --web flag is enabled to administer the validator
|
// If the --web flag is enabled to administer the validator
|
||||||
@@ -125,7 +125,7 @@ func NewValidatorClient(cliCtx *cli.Context) (*ValidatorClient, error) {
|
|||||||
|
|
||||||
if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) {
|
if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) {
|
||||||
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
|
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
|
||||||
params.LoadChainConfigFile(chainConfigFileName)
|
params.LoadChainConfigFile(chainConfigFileName, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes any forks here.
|
// Initializes any forks here.
|
||||||
|
|||||||
Reference in New Issue
Block a user