mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
Compare commits
35 Commits
integrate-
...
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) {
|
||||
// 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 {
|
||||
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")
|
||||
}
|
||||
|
||||
// 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
|
||||
genesisBlock, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
||||
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
|
||||
// and return an error instead of creating a WeakSubjectivityVerifier that permits any chain history.
|
||||
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{
|
||||
enabled: false,
|
||||
}, 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)
|
||||
// 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)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error while retrieving block roots to verify weak subjectivity")
|
||||
}
|
||||
for _, root := range roots {
|
||||
if v.root == root {
|
||||
log.Info("Weak subjectivity check has passed")
|
||||
log.Info("Weak subjectivity check has passed!!")
|
||||
v.verified = true
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -14,58 +14,62 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/testing/util"
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
)
|
||||
|
||||
func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
|
||||
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)))
|
||||
r, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
wsVerified bool
|
||||
disabled bool
|
||||
wantErr error
|
||||
checkpt *ethpb.Checkpoint
|
||||
finalizedEpoch types.Epoch
|
||||
name string
|
||||
}{
|
||||
{
|
||||
name: "nil root and epoch",
|
||||
},
|
||||
{
|
||||
name: "already verified",
|
||||
checkpt: ðpb.Checkpoint{Epoch: 2},
|
||||
finalizedEpoch: 2,
|
||||
wsVerified: true,
|
||||
name: "nil root and epoch",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
name: "not yet to verify, ws epoch higher than finalized epoch",
|
||||
checkpt: ðpb.Checkpoint{Epoch: 2},
|
||||
finalizedEpoch: 1,
|
||||
checkpt: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, 32), Epoch: blockEpoch},
|
||||
finalizedEpoch: blockEpoch - 1,
|
||||
},
|
||||
{
|
||||
name: "can't find the block in DB",
|
||||
checkpt: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength), Epoch: 1},
|
||||
finalizedEpoch: 3,
|
||||
finalizedEpoch: blockEpoch + 1,
|
||||
wantErr: errWSBlockNotFound,
|
||||
},
|
||||
{
|
||||
name: "can't find the block corresponds to ws epoch in DB",
|
||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: 2}, // Root belongs in epoch 1.
|
||||
finalizedEpoch: 3,
|
||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch - 2}, // Root belongs in epoch 1.
|
||||
finalizedEpoch: blockEpoch - 1,
|
||||
wantErr: errWSBlockNotFoundInEpoch,
|
||||
},
|
||||
{
|
||||
name: "can verify and pass",
|
||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: 1},
|
||||
finalizedEpoch: 3,
|
||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch},
|
||||
finalizedEpoch: blockEpoch + 1,
|
||||
},
|
||||
{
|
||||
name: "equal epoch",
|
||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch},
|
||||
finalizedEpoch: blockEpoch,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
wv, err := NewWeakSubjectivityVerifier(tt.checkpt, beaconDB)
|
||||
require.Equal(t, !tt.disabled, wv.enabled)
|
||||
require.NoError(t, err)
|
||||
s := &Service{
|
||||
cfg: &config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt},
|
||||
|
||||
@@ -15,25 +15,7 @@ go_library(
|
||||
"weak_subjectivity.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers",
|
||||
visibility = [
|
||||
"//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__",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/core/time:go_default_library",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
@@ -13,8 +12,9 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -122,20 +122,20 @@ func ComputeWeakSubjectivityPeriod(ctx context.Context, st state.ReadOnlyBeaconS
|
||||
// current_epoch = compute_epoch_at_slot(get_current_slot(store))
|
||||
// return current_epoch <= ws_state_epoch + ws_period
|
||||
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.
|
||||
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")
|
||||
}
|
||||
|
||||
// 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",
|
||||
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",
|
||||
slots.ToEpoch(wsState.Slot()), wsCheckpoint.Epoch)
|
||||
slots.ToEpoch(wsState.Slot()), wsEpoch)
|
||||
}
|
||||
|
||||
// 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.
|
||||
func ParseWeakSubjectivityInputString(wsCheckpointString string) (*eth.Checkpoint, error) {
|
||||
func ParseWeakSubjectivityInputString(wsCheckpointString string) (*v1alpha1.Checkpoint, error) {
|
||||
if wsCheckpointString == "" {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -197,7 +197,7 @@ func ParseWeakSubjectivityInputString(wsCheckpointString string) (*eth.Checkpoin
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ð.Checkpoint{
|
||||
return &v1alpha1.Checkpoint{
|
||||
Epoch: types.Epoch(epoch),
|
||||
Root: bRoot,
|
||||
}, 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) {
|
||||
tests := []struct {
|
||||
name string
|
||||
epoch types.Epoch
|
||||
genWsState func() state.ReadOnlyBeaconState
|
||||
genWsCheckpoint func() *ethpb.WeakSubjectivityCheckpoint
|
||||
genWsCheckpoint mockWsCheckpoint
|
||||
want bool
|
||||
wantedErr string
|
||||
}{
|
||||
@@ -68,22 +71,8 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
||||
genWsState: func() state.ReadOnlyBeaconState {
|
||||
return nil
|
||||
},
|
||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
||||
return ðpb.WeakSubjectivityCheckpoint{
|
||||
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
|
||||
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||
return [32]byte{}, [32]byte{}, 42
|
||||
},
|
||||
wantedErr: "invalid weak subjectivity state or checkpoint",
|
||||
},
|
||||
@@ -99,11 +88,10 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
return beaconState
|
||||
},
|
||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
||||
return ðpb.WeakSubjectivityCheckpoint{
|
||||
StateRoot: bytesutil.PadTo([]byte("stateroot2"), 32),
|
||||
Epoch: 42,
|
||||
}
|
||||
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||
var sr [32]byte
|
||||
copy(sr[:], bytesutil.PadTo([]byte("stateroot2"), 32))
|
||||
return sr, [32]byte{}, 42
|
||||
},
|
||||
wantedErr: fmt.Sprintf("state (%#x) and checkpoint (%#x) roots do not match",
|
||||
bytesutil.PadTo([]byte("stateroot1"), 32), bytesutil.PadTo([]byte("stateroot2"), 32)),
|
||||
@@ -120,11 +108,10 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
return beaconState
|
||||
},
|
||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
||||
return ðpb.WeakSubjectivityCheckpoint{
|
||||
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
|
||||
Epoch: 43,
|
||||
}
|
||||
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||
var sr [32]byte
|
||||
copy(sr[:], bytesutil.PadTo([]byte("stateroot"), 32))
|
||||
return sr, [32]byte{}, 43
|
||||
},
|
||||
wantedErr: "state (42) and checkpoint (43) epochs do not match",
|
||||
},
|
||||
@@ -140,11 +127,10 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
return beaconState
|
||||
},
|
||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
||||
return ðpb.WeakSubjectivityCheckpoint{
|
||||
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
|
||||
Epoch: 42,
|
||||
}
|
||||
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||
var sr [32]byte
|
||||
copy(sr[:], bytesutil.PadTo([]byte("stateroot"), 32))
|
||||
return sr, [32]byte{}, 42
|
||||
},
|
||||
wantedErr: "cannot compute weak subjectivity period: no active validators found",
|
||||
},
|
||||
@@ -161,11 +147,10 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
return beaconState
|
||||
},
|
||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
||||
return ðpb.WeakSubjectivityCheckpoint{
|
||||
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
|
||||
Epoch: 42,
|
||||
}
|
||||
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||
var sr [32]byte
|
||||
copy(sr[:], bytesutil.PadTo([]byte("stateroot"), 32))
|
||||
return sr, [32]byte{}, 42
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
@@ -182,18 +167,18 @@ func TestWeakSubjectivity_IsWithinWeakSubjectivityPeriod(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
return beaconState
|
||||
},
|
||||
genWsCheckpoint: func() *ethpb.WeakSubjectivityCheckpoint {
|
||||
return ðpb.WeakSubjectivityCheckpoint{
|
||||
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
|
||||
Epoch: 42,
|
||||
}
|
||||
genWsCheckpoint: func() ([32]byte, [32]byte, types.Epoch) {
|
||||
var sr [32]byte
|
||||
copy(sr[:], bytesutil.PadTo([]byte("stateroot"), 32))
|
||||
return sr, [32]byte{}, 42
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
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 != "" {
|
||||
assert.Equal(t, false, got)
|
||||
assert.ErrorContains(t, tt.wantedErr, err)
|
||||
|
||||
@@ -52,7 +52,8 @@ type ReadOnlyDatabase interface {
|
||||
// Fee reicipients operations.
|
||||
FeeRecipientByValidatorID(ctx context.Context, id types.ValidatorIndex) (common.Address, error)
|
||||
// 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.
|
||||
@@ -100,7 +101,7 @@ type HeadAccessDatabase interface {
|
||||
EnsureEmbeddedGenesis(ctx context.Context) error
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -49,6 +49,7 @@ go_library(
|
||||
"//io/file:go_default_library",
|
||||
"//monitoring/progress:go_default_library",
|
||||
"//monitoring/tracing:go_default_library",
|
||||
"//proto/detect:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/block:go_default_library",
|
||||
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
// used to represent errors for inconsistent slot ranges.
|
||||
var errInvalidSlotRange = errors.New("invalid end slot and start slot provided")
|
||||
var errEmptyBucket = errors.New("unexpectedly empty bucket")
|
||||
|
||||
// Block retrieval by root.
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
// at the time the chain was started, used to initialize the database and chain
|
||||
// without syncing from genesis.
|
||||
func (s *Store) OriginBlockRoot(ctx context.Context) ([32]byte, error) {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.OriginBlockRoot")
|
||||
func (s *Store) OriginCheckpointBlockRoot(ctx context.Context) ([32]byte, error) {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.OriginCheckpointBlockRoot")
|
||||
defer span.End()
|
||||
|
||||
var root [32]byte
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(blocksBucket)
|
||||
rootSlice := bkt.Get(originBlockRootKey)
|
||||
rootSlice := bkt.Get(originCheckpointBlockRootKey)
|
||||
if rootSlice == nil {
|
||||
return ErrNotFoundOriginBlockRoot
|
||||
}
|
||||
@@ -69,6 +70,26 @@ func (s *Store) OriginBlockRoot(ctx context.Context) ([32]byte, error) {
|
||||
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.
|
||||
func (s *Store) HeadBlock(ctx context.Context) (block.SignedBeaconBlock, error) {
|
||||
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 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.
|
||||
func (s *Store) SaveOriginBlockRoot(ctx context.Context, blockRoot [32]byte) error {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.SaveOriginBlockRoot")
|
||||
func (s *Store) SaveOriginCheckpointBlockRoot(ctx context.Context, blockRoot [32]byte) error {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.SaveOriginCheckpointBlockRoot")
|
||||
defer span.End()
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
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) {
|
||||
BlockCacheSize = 1
|
||||
slot := types.Slot(20)
|
||||
|
||||
@@ -46,6 +46,7 @@ func (s *Store) updateFinalizedBlockRoots(ctx context.Context, tx *bolt.Tx, chec
|
||||
root := checkpoint.Root
|
||||
var previousRoot []byte
|
||||
genesisRoot := tx.Bucket(blocksBucket).Get(genesisBlockRootKey)
|
||||
initCheckpointRoot := tx.Bucket(blocksBucket).Get(originCheckpointBlockRootKey)
|
||||
|
||||
// De-index recent finalized block roots, to be re-indexed.
|
||||
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
|
||||
// index bucket or genesis block root.
|
||||
for {
|
||||
if bytes.Equal(root, genesisRoot) {
|
||||
if bytes.Equal(root, genesisRoot) || bytes.Equal(root, initCheckpointRoot) {
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ var (
|
||||
altairKey = []byte("altair")
|
||||
bellatrixKey = []byte("merge")
|
||||
// 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.
|
||||
lastArchivedIndexKey = []byte("last-archived")
|
||||
|
||||
@@ -2,56 +2,58 @@ package kv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
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/proto/detect"
|
||||
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
|
||||
// (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
|
||||
// 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 {
|
||||
// unmarshal both block and state before trying to save anything
|
||||
// so that we fail early if there is any issue with the ssz data
|
||||
blk := ðpb.SignedBeaconBlockAltair{}
|
||||
bb, err := ioutil.ReadAll(blockReader)
|
||||
func (s *Store) SaveOrigin(ctx context.Context, serState, serBlock []byte) error {
|
||||
cf, err := detect.ByState(serState)
|
||||
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 {
|
||||
return errors.Wrap(err, "could not unmarshal checkpoint block")
|
||||
}
|
||||
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")
|
||||
_, ok := params.BeaconConfig().ForkVersionSchedule[cf.Version]
|
||||
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())
|
||||
}
|
||||
|
||||
// save block
|
||||
if err := s.SaveBlock(ctx, wblk); err != nil {
|
||||
return errors.Wrap(err, "could not save checkpoint block")
|
||||
log.Printf("detected supported config for state & block version detection, name=%s, fork=%s", cf.ConfigName.String(), cf.Fork)
|
||||
state, err := cf.UnmarshalBeaconState(serState)
|
||||
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 {
|
||||
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
|
||||
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")
|
||||
}
|
||||
if err = s.SaveStateSummary(ctx, ðpb.StateSummary{
|
||||
Slot: bs.Slot(),
|
||||
Slot: state.Slot(),
|
||||
Root: blockRoot[:],
|
||||
}); err != nil {
|
||||
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
|
||||
// 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")
|
||||
}
|
||||
|
||||
@@ -70,7 +72,7 @@ func (s *Store) SaveOrigin(ctx context.Context, stateReader, blockReader io.Read
|
||||
|
||||
// rebuild the checkpoint from the block
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ go_library(
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
"//beacon-chain/sync/checkpoint:go_default_library",
|
||||
"//beacon-chain/sync/initial-sync:go_default_library",
|
||||
"//cmd: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) {
|
||||
if cliCtx.IsSet(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/stategen"
|
||||
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"
|
||||
"github.com/prysmaticlabs/prysm/cmd"
|
||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
||||
@@ -101,6 +102,8 @@ type BeaconNode struct {
|
||||
slasherAttestationsFeed *event.Feed
|
||||
finalizedStateAtStartUp state.BeaconState
|
||||
serviceFlagOpts *serviceFlagOpts
|
||||
blockchainFlagOpts []blockchain.Option
|
||||
CheckpointInitializer checkpoint.Initializer
|
||||
}
|
||||
|
||||
// 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.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()))
|
||||
if err != nil {
|
||||
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 {
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -464,7 +474,29 @@ func (b *BeaconNode) startSlasherDB(cliCtx *cli.Context) 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)
|
||||
if err != nil {
|
||||
@@ -474,6 +506,12 @@ func (b *BeaconNode) startStateGen() error {
|
||||
r := bytesutil.ToBytes32(cp.Root)
|
||||
// Consider edge case where finalized root are zeros instead of genesis root hash.
|
||||
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)
|
||||
if err != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
b.stateGen = sg
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ go_library(
|
||||
"structs_marshalling.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/rpc/apimiddleware",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/gateway/apimiddleware: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/voluntary_exits",
|
||||
"/eth/v1/beacon/pool/sync_committees",
|
||||
"/eth/v1/beacon/weak_subjectivity",
|
||||
"/eth/v1/node/identity",
|
||||
"/eth/v1/node/peers",
|
||||
"/eth/v1/node/peers/{peer_id}",
|
||||
@@ -141,6 +142,8 @@ func (_ *BeaconEndpointFactory) Create(path string) (*apimiddleware.Endpoint, er
|
||||
endpoint.Hooks = apimiddleware.HookCollection{
|
||||
OnPreDeserializeRequestBodyIntoContainer: wrapSyncCommitteeSignaturesArray,
|
||||
}
|
||||
case "/eth/v1/beacon/weak_subjectivity":
|
||||
endpoint.GetResponse = &WeakSubjectivityResponse{}
|
||||
case "/eth/v1/node/identity":
|
||||
endpoint.GetResponse = &identityResponseJson{}
|
||||
case "/eth/v1/node/peers":
|
||||
|
||||
@@ -19,6 +19,15 @@ type genesisResponse_GenesisJson struct {
|
||||
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.
|
||||
type stateRootResponseJson struct {
|
||||
Data *stateRootResponse_StateRootJson `json:"data"`
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/proto/migration"
|
||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
"go.opencensus.io/trace"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
@@ -40,6 +42,43 @@ func (e *blockIdParseError) Error() string {
|
||||
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.
|
||||
func (bs *Server) GetBlockHeader(ctx context.Context, req *ethpbv1.BlockRequest) (*ethpbv1.BlockHeaderResponse, error) {
|
||||
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)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "GetBlockHeader")
|
||||
}
|
||||
v1alpha1Header, err := blk.Header()
|
||||
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)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "GetBlock")
|
||||
}
|
||||
signedBeaconBlock, err := migration.SignedBeaconBlock(blk)
|
||||
if err != nil {
|
||||
@@ -290,7 +329,7 @@ func (bs *Server) GetBlockSSZ(ctx context.Context, req *ethpbv1.BlockRequest) (*
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "GetBlockSSZ")
|
||||
}
|
||||
signedBeaconBlock, err := migration.SignedBeaconBlock(blk)
|
||||
if err != nil {
|
||||
@@ -312,7 +351,7 @@ func (bs *Server) GetBlockV2(ctx context.Context, req *ethpbv2.BlockRequestV2) (
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "GetBlockV2")
|
||||
}
|
||||
|
||||
_, err = blk.PbPhase0Block()
|
||||
@@ -389,7 +428,7 @@ func (bs *Server) GetBlockSSZV2(ctx context.Context, req *ethpbv2.BlockRequestV2
|
||||
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
|
||||
err = handleGetBlockError(blk, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "GetBlockSSZV2")
|
||||
}
|
||||
|
||||
_, 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)
|
||||
if err != nil {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
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 nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
|
||||
return ðpb.StateFinalityCheckpointResponse{
|
||||
|
||||
@@ -14,6 +14,7 @@ go_library(
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"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/status"
|
||||
)
|
||||
@@ -9,9 +12,13 @@ import (
|
||||
// PrepareStateFetchGRPCError returns an appropriate gRPC error based on the supplied argument.
|
||||
// The argument error should be a result of fetching state.
|
||||
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 {
|
||||
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.Internal, "Invalid state ID: %v", err)
|
||||
|
||||
@@ -2,7 +2,6 @@ package beacon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -397,11 +396,6 @@ func (bs *Server) chainHeadRetrieval(ctx context.Context) (*ethpb.ChainHead, err
|
||||
isGenesis := func(cp *ethpb.Checkpoint) bool {
|
||||
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()
|
||||
if !isGenesis(finalizedCheckpoint) {
|
||||
@@ -463,40 +457,3 @@ func (bs *Server) chainHeadRetrieval(ctx context.Context) (*ethpb.ChainHead, err
|
||||
PreviousJustifiedBlockRoot: prevJustifiedCheckpoint.Root,
|
||||
}, 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")
|
||||
}
|
||||
case "genesis":
|
||||
s, err = p.BeaconDB.GenesisState(ctx)
|
||||
s, err = p.StateBySlot(ctx, 0)
|
||||
if err != nil {
|
||||
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.SaveState(ctx, bs, r))
|
||||
|
||||
cc := &mockstategen.MockCanonicalChecker{Is: true}
|
||||
cs := &mockstategen.MockCurrentSlotter{Slot: bs.Slot() + 1}
|
||||
p := StateProvider{
|
||||
BeaconDB: db,
|
||||
BeaconDB: db,
|
||||
ReplayerBuilder: stategen.NewCanonicalBuilder(db, cc, cs),
|
||||
}
|
||||
|
||||
s, err := p.State(ctx, []byte("genesis"))
|
||||
|
||||
@@ -10,21 +10,7 @@ go_library(
|
||||
"prometheus.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state",
|
||||
visibility = [
|
||||
"//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__",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
|
||||
@@ -2,8 +2,6 @@ package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
"sort"
|
||||
|
||||
@@ -30,27 +28,6 @@ func InitializeFromProto(st *ethpb.BeaconStateAltair) (state.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
|
||||
// and sets them as fields of the BeaconState type.
|
||||
func InitializeFromProtoUnsafe(st *ethpb.BeaconStateAltair) (*BeaconState, error) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package stategen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
@@ -13,6 +14,8 @@ import (
|
||||
"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.
|
||||
func (s *State) HasState(ctx context.Context, blockRoot [32]byte) (bool, error) {
|
||||
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.
|
||||
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.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) {
|
||||
// Genesis case. If block root is zero hash, short circuit to use genesis state stored in DB.
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -213,6 +222,10 @@ func (s *State) loadStateBySlot(ctx context.Context, slot types.Slot) (state.Bea
|
||||
ctx, span := trace.StartSpan(ctx, "stateGen.loadStateBySlot")
|
||||
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.
|
||||
if slot == 0 {
|
||||
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 {
|
||||
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.
|
||||
parentRoot := bytesutil.ToBytes32(b.Block().ParentRoot())
|
||||
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")
|
||||
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.
|
||||
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 {
|
||||
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")
|
||||
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.
|
||||
if slot == 0 {
|
||||
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
|
||||
}
|
||||
|
||||
// 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.
|
||||
// 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) {
|
||||
|
||||
@@ -6,6 +6,7 @@ package stategen
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
@@ -49,6 +50,8 @@ type State struct {
|
||||
finalizedInfo *finalizedInfo
|
||||
epochBoundaryStateCache *epochBoundaryState
|
||||
saveHotStateDB *saveHotStateDbConfig
|
||||
minimumSlot types.Slot
|
||||
beaconDBInitType BeaconDBInitType
|
||||
}
|
||||
|
||||
// This tracks the config in the event of long non-finality,
|
||||
@@ -70,9 +73,31 @@ type finalizedInfo struct {
|
||||
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.
|
||||
func New(beaconDB db.NoHeadAccessDatabase) *State {
|
||||
return &State{
|
||||
func New(beaconDB db.NoHeadAccessDatabase, opts ...StateGenOption) *State {
|
||||
s := &State{
|
||||
beaconDB: beaconDB,
|
||||
hotStateCache: newHotStateCache(),
|
||||
finalizedInfo: &finalizedInfo{slot: 0, root: params.BeaconConfig().ZeroHash},
|
||||
@@ -81,7 +106,13 @@ func New(beaconDB db.NoHeadAccessDatabase) *State {
|
||||
saveHotStateDB: &saveHotStateDbConfig{
|
||||
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.
|
||||
@@ -96,6 +127,9 @@ func (s *State) Resume(ctx context.Context, fState state.BeaconState) (state.Bea
|
||||
fRoot := bytesutil.ToBytes32(c.Root)
|
||||
// Resume as genesis state if last finalized root is zero hashes.
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -138,3 +172,7 @@ func (s *State) finalizedState() state.BeaconState {
|
||||
defer s.finalizedInfo.lock.RUnlock()
|
||||
return s.finalizedInfo.state.Copy()
|
||||
}
|
||||
|
||||
func (s *State) MinimumSlot() types.Slot {
|
||||
return s.minimumSlot
|
||||
}
|
||||
|
||||
@@ -29,20 +29,7 @@ go_library(
|
||||
"unsupported_setters.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v1",
|
||||
visibility = [
|
||||
"//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__",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/state: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))
|
||||
}
|
||||
|
||||
// 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
|
||||
// and sets it as the inner state of the BeaconState type.
|
||||
func InitializeFromProtoUnsafe(st *ethpb.BeaconState) (state.BeaconState, error) {
|
||||
|
||||
@@ -29,12 +29,7 @@ go_library(
|
||||
"types.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v2",
|
||||
visibility = [
|
||||
"//beacon-chain:__subpackages__",
|
||||
"//proto/migration:__subpackages__",
|
||||
"//testing/spectest:__subpackages__",
|
||||
"//testing/util:__pkg__",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/fieldtrie:go_default_library",
|
||||
|
||||
@@ -2,8 +2,6 @@ package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
"sort"
|
||||
|
||||
@@ -33,26 +31,9 @@ func InitializeFromProto(st *ethpb.BeaconStateAltair) (state.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
|
||||
// a slice of bytes containing the ssz-serialized representation of the state.
|
||||
func InitializeFromSSZBytes(marshaled []byte) (state.BeaconStateAltair, error) {
|
||||
if features.Get().EnableNativeState {
|
||||
return statenative.InitializeFromSSZBytes(marshaled)
|
||||
}
|
||||
st := ðpb.BeaconStateAltair{}
|
||||
if err := st.UnmarshalSSZ(marshaled); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -31,11 +31,7 @@ go_library(
|
||||
"types.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v3",
|
||||
visibility = [
|
||||
"//beacon-chain:__subpackages__",
|
||||
"//testing/spectest:__subpackages__",
|
||||
"//testing/util:__pkg__",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/state: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))
|
||||
}
|
||||
|
||||
// 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
|
||||
// and sets it as the inner state of the BeaconState type.
|
||||
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)
|
||||
parentRoot := bytesutil.ToBytes32(blk.Block().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)
|
||||
}
|
||||
@@ -264,7 +264,7 @@ func (s *Service) processBatchedBlocks(ctx context.Context, genesis time.Time,
|
||||
s.logBatchSyncStatus(genesis, blks, blkRoot)
|
||||
parentRoot := bytesutil.ToBytes32(firstBlock.Block().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[0] = blkRoot
|
||||
|
||||
@@ -21,6 +21,7 @@ go_library(
|
||||
"//cmd/beacon-chain/db:go_default_library",
|
||||
"//cmd/beacon-chain/flags:go_default_library",
|
||||
"//cmd/beacon-chain/powchain:go_default_library",
|
||||
"//cmd/beacon-chain/sync/checkpoint:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"//io/logs:go_default_library",
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
// FlagOptions for blockchain service flag configurations.
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -191,13 +191,6 @@ var (
|
||||
Name: "network-id",
|
||||
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 = &cli.Uint64Flag{
|
||||
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 " +
|
||||
"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 = &cli.Uint64Flag{
|
||||
Name: "minimum-peers-per-subnet",
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"runtime"
|
||||
runtimeDebug "runtime/debug"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/sync/checkpoint"
|
||||
|
||||
gethlog "github.com/ethereum/go-ethereum/log"
|
||||
golog "github.com/ipfs/go-log/v2"
|
||||
joonix "github.com/joonix/log"
|
||||
@@ -63,7 +65,7 @@ var appFlags = []cli.Flag{
|
||||
flags.HistoricalSlasherNode,
|
||||
flags.ChainID,
|
||||
flags.NetworkID,
|
||||
flags.WeakSubjectivityCheckpt,
|
||||
flags.WeakSubjectivityCheckpoint,
|
||||
flags.Eth1HeaderReqLimit,
|
||||
flags.GenesisStatePath,
|
||||
flags.MinPeersPerSubnet,
|
||||
@@ -119,6 +121,9 @@ var appFlags = []cli.Flag{
|
||||
cmd.BoltMMapInitialSizeFlag,
|
||||
cmd.ValidatorMonitorIndicesFlag,
|
||||
cmd.ApiTimeoutFlag,
|
||||
checkpoint.BlockPath,
|
||||
checkpoint.StatePath,
|
||||
checkpoint.RemoteURL,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -243,6 +248,13 @@ func startNode(ctx *cli.Context) error {
|
||||
node.WithBlockchainFlagOptions(blockchainFlagOpts),
|
||||
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...)
|
||||
if err != nil {
|
||||
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/beacon-chain/flags"
|
||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/sync/checkpoint"
|
||||
"github.com/prysmaticlabs/prysm/config/features"
|
||||
"github.com/prysmaticlabs/prysm/runtime/debug"
|
||||
"github.com/urfave/cli/v2"
|
||||
@@ -75,6 +76,9 @@ var appHelpFlagGroups = []flagGroup{
|
||||
cmd.BoltMMapInitialSizeFlag,
|
||||
cmd.ValidatorMonitorIndicesFlag,
|
||||
cmd.ApiTimeoutFlag,
|
||||
checkpoint.BlockPath,
|
||||
checkpoint.StatePath,
|
||||
checkpoint.RemoteURL,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -122,7 +126,7 @@ var appHelpFlagGroups = []flagGroup{
|
||||
flags.HistoricalSlasherNode,
|
||||
flags.ChainID,
|
||||
flags.NetworkID,
|
||||
flags.WeakSubjectivityCheckpt,
|
||||
flags.WeakSubjectivityCheckpoint,
|
||||
flags.Eth1HeaderReqLimit,
|
||||
flags.GenesisStatePath,
|
||||
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)
|
||||
case *cli.UintFlag:
|
||||
f = altsrc.NewUintFlag(t)
|
||||
case *cli.PathFlag:
|
||||
f = altsrc.NewPathFlag(t)
|
||||
case *cli.Int64Flag:
|
||||
// Int64Flag does not work. See https://github.com/prysmaticlabs/prysm/issues/6478
|
||||
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//params: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_sirupsen_logrus//:go_default_library",
|
||||
"@in_gopkg_yaml_v2//:go_default_library",
|
||||
@@ -54,6 +55,7 @@ go_test(
|
||||
"//io/file:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@in_gopkg_yaml_v2//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
)
|
||||
@@ -201,3 +203,56 @@ func (b *BeaconChainConfig) InitializeForkSchedule() {
|
||||
// Set Bellatrix fork data.
|
||||
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
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
)
|
||||
|
||||
// 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"
|
||||
)
|
||||
|
||||
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,
|
||||
// unmarshal , and apply beacon chain config file.
|
||||
func LoadChainConfigFile(chainConfigFileName string) {
|
||||
func LoadChainConfigFile(chainConfigFileName string, conf *BeaconChainConfig) {
|
||||
yamlFile, err := ioutil.ReadFile(chainConfigFileName) // #nosec G304
|
||||
if err != nil {
|
||||
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.
|
||||
hasConfigName := false
|
||||
// Convert 0x hex inputs to fixed bytes arrays
|
||||
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 {
|
||||
// No need to convert the deposit contract address to byte array (as config expects a string).
|
||||
if strings.HasPrefix(line, "DEPOSIT_CONTRACT_ADDRESS") {
|
||||
@@ -33,12 +51,6 @@ func LoadChainConfigFile(chainConfigFileName string) {
|
||||
if strings.HasPrefix(line, "CONFIG_NAME") {
|
||||
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") {
|
||||
parts := ReplaceHexStringWithYAMLFormat(line)
|
||||
lines[i] = strings.Join(parts, "\n")
|
||||
|
||||
@@ -111,10 +111,10 @@ func TestLoadConfigFileMainnet(t *testing.T) {
|
||||
t.Run("mainnet", func(t *testing.T) {
|
||||
mainnetPresetsFiles := presetsFilePath(t, "mainnet")
|
||||
for _, fp := range mainnetPresetsFiles {
|
||||
params.LoadChainConfigFile(fp)
|
||||
params.LoadChainConfigFile(fp, nil)
|
||||
}
|
||||
mainnetConfigFile := configFilePath(t, "mainnet")
|
||||
params.LoadChainConfigFile(mainnetConfigFile)
|
||||
params.LoadChainConfigFile(mainnetConfigFile, nil)
|
||||
fields := fieldsFromYamls(t, append(mainnetPresetsFiles, mainnetConfigFile))
|
||||
assertVals("mainnet", fields, params.MainnetConfig(), params.BeaconConfig())
|
||||
})
|
||||
@@ -122,10 +122,10 @@ func TestLoadConfigFileMainnet(t *testing.T) {
|
||||
t.Run("minimal", func(t *testing.T) {
|
||||
minimalPresetsFiles := presetsFilePath(t, "minimal")
|
||||
for _, fp := range minimalPresetsFiles {
|
||||
params.LoadChainConfigFile(fp)
|
||||
params.LoadChainConfigFile(fp, nil)
|
||||
}
|
||||
minimalConfigFile := configFilePath(t, "minimal")
|
||||
params.LoadChainConfigFile(minimalConfigFile)
|
||||
params.LoadChainConfigFile(minimalConfigFile, nil)
|
||||
fields := fieldsFromYamls(t, append(minimalPresetsFiles, minimalConfigFile))
|
||||
assertVals("minimal", fields, params.MinimalSpecConfig(), params.BeaconConfig())
|
||||
})
|
||||
@@ -138,7 +138,7 @@ func TestLoadConfigFile_OverwriteCorrectly(t *testing.T) {
|
||||
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
||||
|
||||
// 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 {
|
||||
t.Errorf("Expected MinGenesisTime to be set to mainnet value: %d found: %d",
|
||||
params.MainnetConfig().MinGenesisTime,
|
||||
@@ -230,7 +230,7 @@ func TestConfigParityYaml(t *testing.T) {
|
||||
yamlObj := params.ConfigToYaml(testCfg)
|
||||
assert.NoError(t, file.WriteFile(yamlDir, yamlObj))
|
||||
|
||||
params.LoadChainConfigFile(yamlDir)
|
||||
params.LoadChainConfigFile(yamlDir, params.E2ETestConfig().Copy())
|
||||
assert.DeepEqual(t, params.BeaconConfig(), testCfg)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,6 @@ func TestE2EConfigParity(t *testing.T) {
|
||||
yamlObj := params.E2EMainnetConfigYaml()
|
||||
assert.NoError(t, file.WriteFile(yamlDir, yamlObj))
|
||||
|
||||
params.LoadChainConfigFile(yamlDir)
|
||||
params.LoadChainConfigFile(yamlDir, nil)
|
||||
assert.DeepEqual(t, params.BeaconConfig(), testCfg)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
)
|
||||
|
||||
const (
|
||||
altairE2EForkEpoch = 6
|
||||
bellatrixE2EForkEpoch = 8 //nolint:deadcode
|
||||
@@ -51,6 +57,18 @@ func E2ETestConfig() *BeaconChainConfig {
|
||||
// Prysm constants.
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
func TestPraterConfigMatchesUpstreamYaml(t *testing.T) {
|
||||
presetFPs := presetsFilePath(t, "mainnet")
|
||||
for _, fp := range presetFPs {
|
||||
params.LoadChainConfigFile(fp)
|
||||
params.LoadChainConfigFile(fp, nil)
|
||||
}
|
||||
configFP := testnetConfigFilePath(t, "prater")
|
||||
params.LoadChainConfigFile(configFP)
|
||||
params.LoadChainConfigFile(configFP, nil)
|
||||
fields := fieldsFromYamls(t, append(presetFPs, configFP))
|
||||
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.
|
||||
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/multierr v1.7.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/oauth2 v0.0.0-20210514164344-f6687ab2804c // 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/prometheus/tsdb v0.10.0 // indirect
|
||||
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
|
||||
google.golang.org/api v0.34.0 // 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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
@@ -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,
|
||||
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, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x12, 0x89, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74,
|
||||
0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||
0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x12, 0x8b, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74,
|
||||
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,
|
||||
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,
|
||||
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, 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,
|
||||
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, 0x76, 0x61,
|
||||
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0xac, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74,
|
||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x26, 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, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 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, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x45, 0x12, 0x43, 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, 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,
|
||||
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, 0x65, 0x73,
|
||||
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,
|
||||
0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65,
|
||||
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, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74,
|
||||
0x65, 0x65, 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, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 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, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74,
|
||||
0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
|
||||
0x65, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43,
|
||||
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
||||
0x65, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79,
|
||||
0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x12, 0x39, 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, 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,
|
||||
0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0xac, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x56, 0x61,
|
||||
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x26, 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, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
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,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x45,
|
||||
0x12, 0x43, 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, 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, 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,
|
||||
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, 0x64, 0x61,
|
||||
0x74, 0x6f, 0x72, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0xa1, 0x01, 0x0a,
|
||||
0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 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, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65,
|
||||
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,
|
||||
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 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, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74,
|
||||
0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73,
|
||||
0x12, 0xb2, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d,
|
||||
0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53,
|
||||
0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63,
|
||||
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x12, 0x39, 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, 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, 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, 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, 0x12, 0x8e, 0x01, 0x0a,
|
||||
0x12, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65,
|
||||
0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 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, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x22,
|
||||
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, 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,
|
||||
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,
|
||||
0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74,
|
||||
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, 0x2e, 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, 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,
|
||||
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x12, 0x53,
|
||||
0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x12, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 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,
|
||||
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,
|
||||
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,
|
||||
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, 0x0a, 0x19,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 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, 0x2e, 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, 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, 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,
|
||||
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, 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{}{
|
||||
@@ -361,93 +369,96 @@ var file_proto_eth_service_beacon_chain_service_proto_goTypes = []interface{}{
|
||||
(*v1.SignedVoluntaryExit)(nil), // 15: ethereum.eth.v1.SignedVoluntaryExit
|
||||
(*v2.SubmitPoolSyncCommitteeSignatures)(nil), // 16: ethereum.eth.v2.SubmitPoolSyncCommitteeSignatures
|
||||
(*v1.GenesisResponse)(nil), // 17: ethereum.eth.v1.GenesisResponse
|
||||
(*v1.StateRootResponse)(nil), // 18: ethereum.eth.v1.StateRootResponse
|
||||
(*v1.StateForkResponse)(nil), // 19: ethereum.eth.v1.StateForkResponse
|
||||
(*v1.StateFinalityCheckpointResponse)(nil), // 20: ethereum.eth.v1.StateFinalityCheckpointResponse
|
||||
(*v1.StateValidatorsResponse)(nil), // 21: ethereum.eth.v1.StateValidatorsResponse
|
||||
(*v1.StateValidatorResponse)(nil), // 22: ethereum.eth.v1.StateValidatorResponse
|
||||
(*v1.ValidatorBalancesResponse)(nil), // 23: ethereum.eth.v1.ValidatorBalancesResponse
|
||||
(*v1.StateCommitteesResponse)(nil), // 24: ethereum.eth.v1.StateCommitteesResponse
|
||||
(*v2.StateSyncCommitteesResponse)(nil), // 25: ethereum.eth.v2.StateSyncCommitteesResponse
|
||||
(*v1.BlockHeadersResponse)(nil), // 26: ethereum.eth.v1.BlockHeadersResponse
|
||||
(*v1.BlockHeaderResponse)(nil), // 27: ethereum.eth.v1.BlockHeaderResponse
|
||||
(*v1.BlockRootResponse)(nil), // 28: ethereum.eth.v1.BlockRootResponse
|
||||
(*v1.BlockResponse)(nil), // 29: ethereum.eth.v1.BlockResponse
|
||||
(*v1.BlockSSZResponse)(nil), // 30: ethereum.eth.v1.BlockSSZResponse
|
||||
(*v2.BlockResponseV2)(nil), // 31: ethereum.eth.v2.BlockResponseV2
|
||||
(*v2.BlockSSZResponseV2)(nil), // 32: ethereum.eth.v2.BlockSSZResponseV2
|
||||
(*v1.BlockAttestationsResponse)(nil), // 33: ethereum.eth.v1.BlockAttestationsResponse
|
||||
(*v1.AttestationsPoolResponse)(nil), // 34: ethereum.eth.v1.AttestationsPoolResponse
|
||||
(*v1.AttesterSlashingsPoolResponse)(nil), // 35: ethereum.eth.v1.AttesterSlashingsPoolResponse
|
||||
(*v1.ProposerSlashingPoolResponse)(nil), // 36: ethereum.eth.v1.ProposerSlashingPoolResponse
|
||||
(*v1.VoluntaryExitsPoolResponse)(nil), // 37: ethereum.eth.v1.VoluntaryExitsPoolResponse
|
||||
(*v1.ForkScheduleResponse)(nil), // 38: ethereum.eth.v1.ForkScheduleResponse
|
||||
(*v1.SpecResponse)(nil), // 39: ethereum.eth.v1.SpecResponse
|
||||
(*v1.DepositContractResponse)(nil), // 40: ethereum.eth.v1.DepositContractResponse
|
||||
(*v1.WeakSubjectivityResponse)(nil), // 18: ethereum.eth.v1.WeakSubjectivityResponse
|
||||
(*v1.StateRootResponse)(nil), // 19: ethereum.eth.v1.StateRootResponse
|
||||
(*v1.StateForkResponse)(nil), // 20: ethereum.eth.v1.StateForkResponse
|
||||
(*v1.StateFinalityCheckpointResponse)(nil), // 21: ethereum.eth.v1.StateFinalityCheckpointResponse
|
||||
(*v1.StateValidatorsResponse)(nil), // 22: ethereum.eth.v1.StateValidatorsResponse
|
||||
(*v1.StateValidatorResponse)(nil), // 23: ethereum.eth.v1.StateValidatorResponse
|
||||
(*v1.ValidatorBalancesResponse)(nil), // 24: ethereum.eth.v1.ValidatorBalancesResponse
|
||||
(*v1.StateCommitteesResponse)(nil), // 25: ethereum.eth.v1.StateCommitteesResponse
|
||||
(*v2.StateSyncCommitteesResponse)(nil), // 26: ethereum.eth.v2.StateSyncCommitteesResponse
|
||||
(*v1.BlockHeadersResponse)(nil), // 27: ethereum.eth.v1.BlockHeadersResponse
|
||||
(*v1.BlockHeaderResponse)(nil), // 28: ethereum.eth.v1.BlockHeaderResponse
|
||||
(*v1.BlockRootResponse)(nil), // 29: ethereum.eth.v1.BlockRootResponse
|
||||
(*v1.BlockResponse)(nil), // 30: ethereum.eth.v1.BlockResponse
|
||||
(*v1.BlockSSZResponse)(nil), // 31: ethereum.eth.v1.BlockSSZResponse
|
||||
(*v2.BlockResponseV2)(nil), // 32: ethereum.eth.v2.BlockResponseV2
|
||||
(*v2.BlockSSZResponseV2)(nil), // 33: ethereum.eth.v2.BlockSSZResponseV2
|
||||
(*v1.BlockAttestationsResponse)(nil), // 34: ethereum.eth.v1.BlockAttestationsResponse
|
||||
(*v1.AttestationsPoolResponse)(nil), // 35: ethereum.eth.v1.AttestationsPoolResponse
|
||||
(*v1.AttesterSlashingsPoolResponse)(nil), // 36: ethereum.eth.v1.AttesterSlashingsPoolResponse
|
||||
(*v1.ProposerSlashingPoolResponse)(nil), // 37: ethereum.eth.v1.ProposerSlashingPoolResponse
|
||||
(*v1.VoluntaryExitsPoolResponse)(nil), // 38: ethereum.eth.v1.VoluntaryExitsPoolResponse
|
||||
(*v1.ForkScheduleResponse)(nil), // 39: ethereum.eth.v1.ForkScheduleResponse
|
||||
(*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{
|
||||
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
|
||||
1, // 2: ethereum.eth.service.BeaconChain.GetStateFork:input_type -> ethereum.eth.v1.StateRequest
|
||||
1, // 3: ethereum.eth.service.BeaconChain.GetFinalityCheckpoints:input_type -> ethereum.eth.v1.StateRequest
|
||||
2, // 4: ethereum.eth.service.BeaconChain.ListValidators:input_type -> ethereum.eth.v1.StateValidatorsRequest
|
||||
3, // 5: ethereum.eth.service.BeaconChain.GetValidator:input_type -> ethereum.eth.v1.StateValidatorRequest
|
||||
4, // 6: ethereum.eth.service.BeaconChain.ListValidatorBalances:input_type -> ethereum.eth.v1.ValidatorBalancesRequest
|
||||
5, // 7: ethereum.eth.service.BeaconChain.ListCommittees:input_type -> ethereum.eth.v1.StateCommitteesRequest
|
||||
6, // 8: ethereum.eth.service.BeaconChain.ListSyncCommittees:input_type -> ethereum.eth.v2.StateSyncCommitteesRequest
|
||||
7, // 9: ethereum.eth.service.BeaconChain.ListBlockHeaders:input_type -> ethereum.eth.v1.BlockHeadersRequest
|
||||
8, // 10: ethereum.eth.service.BeaconChain.GetBlockHeader:input_type -> ethereum.eth.v1.BlockRequest
|
||||
9, // 11: ethereum.eth.service.BeaconChain.SubmitBlock:input_type -> ethereum.eth.v2.SignedBeaconBlockContainerV2
|
||||
8, // 12: ethereum.eth.service.BeaconChain.GetBlockRoot:input_type -> ethereum.eth.v1.BlockRequest
|
||||
8, // 13: ethereum.eth.service.BeaconChain.GetBlock:input_type -> ethereum.eth.v1.BlockRequest
|
||||
8, // 14: ethereum.eth.service.BeaconChain.GetBlockSSZ:input_type -> ethereum.eth.v1.BlockRequest
|
||||
10, // 15: ethereum.eth.service.BeaconChain.GetBlockV2:input_type -> ethereum.eth.v2.BlockRequestV2
|
||||
10, // 16: ethereum.eth.service.BeaconChain.GetBlockSSZV2:input_type -> ethereum.eth.v2.BlockRequestV2
|
||||
8, // 17: ethereum.eth.service.BeaconChain.ListBlockAttestations:input_type -> ethereum.eth.v1.BlockRequest
|
||||
11, // 18: ethereum.eth.service.BeaconChain.ListPoolAttestations:input_type -> ethereum.eth.v1.AttestationsPoolRequest
|
||||
12, // 19: ethereum.eth.service.BeaconChain.SubmitAttestations:input_type -> ethereum.eth.v1.SubmitAttestationsRequest
|
||||
0, // 20: ethereum.eth.service.BeaconChain.ListPoolAttesterSlashings:input_type -> google.protobuf.Empty
|
||||
13, // 21: ethereum.eth.service.BeaconChain.SubmitAttesterSlashing:input_type -> ethereum.eth.v1.AttesterSlashing
|
||||
0, // 22: ethereum.eth.service.BeaconChain.ListPoolProposerSlashings:input_type -> google.protobuf.Empty
|
||||
14, // 23: ethereum.eth.service.BeaconChain.SubmitProposerSlashing:input_type -> ethereum.eth.v1.ProposerSlashing
|
||||
0, // 24: ethereum.eth.service.BeaconChain.ListPoolVoluntaryExits:input_type -> google.protobuf.Empty
|
||||
15, // 25: ethereum.eth.service.BeaconChain.SubmitVoluntaryExit:input_type -> ethereum.eth.v1.SignedVoluntaryExit
|
||||
16, // 26: ethereum.eth.service.BeaconChain.SubmitPoolSyncCommitteeSignatures:input_type -> ethereum.eth.v2.SubmitPoolSyncCommitteeSignatures
|
||||
0, // 27: ethereum.eth.service.BeaconChain.GetForkSchedule:input_type -> google.protobuf.Empty
|
||||
0, // 28: ethereum.eth.service.BeaconChain.GetSpec:input_type -> google.protobuf.Empty
|
||||
0, // 29: ethereum.eth.service.BeaconChain.GetDepositContract:input_type -> google.protobuf.Empty
|
||||
17, // 30: ethereum.eth.service.BeaconChain.GetGenesis:output_type -> ethereum.eth.v1.GenesisResponse
|
||||
18, // 31: ethereum.eth.service.BeaconChain.GetStateRoot:output_type -> ethereum.eth.v1.StateRootResponse
|
||||
19, // 32: ethereum.eth.service.BeaconChain.GetStateFork:output_type -> ethereum.eth.v1.StateForkResponse
|
||||
20, // 33: ethereum.eth.service.BeaconChain.GetFinalityCheckpoints:output_type -> ethereum.eth.v1.StateFinalityCheckpointResponse
|
||||
21, // 34: ethereum.eth.service.BeaconChain.ListValidators:output_type -> ethereum.eth.v1.StateValidatorsResponse
|
||||
22, // 35: ethereum.eth.service.BeaconChain.GetValidator:output_type -> ethereum.eth.v1.StateValidatorResponse
|
||||
23, // 36: ethereum.eth.service.BeaconChain.ListValidatorBalances:output_type -> ethereum.eth.v1.ValidatorBalancesResponse
|
||||
24, // 37: ethereum.eth.service.BeaconChain.ListCommittees:output_type -> ethereum.eth.v1.StateCommitteesResponse
|
||||
25, // 38: ethereum.eth.service.BeaconChain.ListSyncCommittees:output_type -> ethereum.eth.v2.StateSyncCommitteesResponse
|
||||
26, // 39: ethereum.eth.service.BeaconChain.ListBlockHeaders:output_type -> ethereum.eth.v1.BlockHeadersResponse
|
||||
27, // 40: ethereum.eth.service.BeaconChain.GetBlockHeader:output_type -> ethereum.eth.v1.BlockHeaderResponse
|
||||
0, // 41: ethereum.eth.service.BeaconChain.SubmitBlock:output_type -> google.protobuf.Empty
|
||||
28, // 42: ethereum.eth.service.BeaconChain.GetBlockRoot:output_type -> ethereum.eth.v1.BlockRootResponse
|
||||
29, // 43: ethereum.eth.service.BeaconChain.GetBlock:output_type -> ethereum.eth.v1.BlockResponse
|
||||
30, // 44: ethereum.eth.service.BeaconChain.GetBlockSSZ:output_type -> ethereum.eth.v1.BlockSSZResponse
|
||||
31, // 45: ethereum.eth.service.BeaconChain.GetBlockV2:output_type -> ethereum.eth.v2.BlockResponseV2
|
||||
32, // 46: ethereum.eth.service.BeaconChain.GetBlockSSZV2:output_type -> ethereum.eth.v2.BlockSSZResponseV2
|
||||
33, // 47: ethereum.eth.service.BeaconChain.ListBlockAttestations:output_type -> ethereum.eth.v1.BlockAttestationsResponse
|
||||
34, // 48: ethereum.eth.service.BeaconChain.ListPoolAttestations:output_type -> ethereum.eth.v1.AttestationsPoolResponse
|
||||
0, // 49: ethereum.eth.service.BeaconChain.SubmitAttestations:output_type -> google.protobuf.Empty
|
||||
35, // 50: ethereum.eth.service.BeaconChain.ListPoolAttesterSlashings:output_type -> ethereum.eth.v1.AttesterSlashingsPoolResponse
|
||||
0, // 51: ethereum.eth.service.BeaconChain.SubmitAttesterSlashing:output_type -> google.protobuf.Empty
|
||||
36, // 52: ethereum.eth.service.BeaconChain.ListPoolProposerSlashings:output_type -> ethereum.eth.v1.ProposerSlashingPoolResponse
|
||||
0, // 53: ethereum.eth.service.BeaconChain.SubmitProposerSlashing:output_type -> google.protobuf.Empty
|
||||
37, // 54: ethereum.eth.service.BeaconChain.ListPoolVoluntaryExits:output_type -> ethereum.eth.v1.VoluntaryExitsPoolResponse
|
||||
0, // 55: ethereum.eth.service.BeaconChain.SubmitVoluntaryExit:output_type -> google.protobuf.Empty
|
||||
0, // 56: ethereum.eth.service.BeaconChain.SubmitPoolSyncCommitteeSignatures:output_type -> google.protobuf.Empty
|
||||
38, // 57: ethereum.eth.service.BeaconChain.GetForkSchedule:output_type -> ethereum.eth.v1.ForkScheduleResponse
|
||||
39, // 58: ethereum.eth.service.BeaconChain.GetSpec:output_type -> ethereum.eth.v1.SpecResponse
|
||||
40, // 59: ethereum.eth.service.BeaconChain.GetDepositContract:output_type -> ethereum.eth.v1.DepositContractResponse
|
||||
30, // [30:60] is the sub-list for method output_type
|
||||
0, // [0:30] is the sub-list for method input_type
|
||||
0, // 1: ethereum.eth.service.BeaconChain.GetWeakSubjectivity:input_type -> google.protobuf.Empty
|
||||
1, // 2: ethereum.eth.service.BeaconChain.GetStateRoot:input_type -> ethereum.eth.v1.StateRequest
|
||||
1, // 3: ethereum.eth.service.BeaconChain.GetStateFork:input_type -> ethereum.eth.v1.StateRequest
|
||||
1, // 4: ethereum.eth.service.BeaconChain.GetFinalityCheckpoints:input_type -> ethereum.eth.v1.StateRequest
|
||||
2, // 5: ethereum.eth.service.BeaconChain.ListValidators:input_type -> ethereum.eth.v1.StateValidatorsRequest
|
||||
3, // 6: ethereum.eth.service.BeaconChain.GetValidator:input_type -> ethereum.eth.v1.StateValidatorRequest
|
||||
4, // 7: ethereum.eth.service.BeaconChain.ListValidatorBalances:input_type -> ethereum.eth.v1.ValidatorBalancesRequest
|
||||
5, // 8: ethereum.eth.service.BeaconChain.ListCommittees:input_type -> ethereum.eth.v1.StateCommitteesRequest
|
||||
6, // 9: ethereum.eth.service.BeaconChain.ListSyncCommittees:input_type -> ethereum.eth.v2.StateSyncCommitteesRequest
|
||||
7, // 10: ethereum.eth.service.BeaconChain.ListBlockHeaders:input_type -> ethereum.eth.v1.BlockHeadersRequest
|
||||
8, // 11: ethereum.eth.service.BeaconChain.GetBlockHeader: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.GetBlockRoot:input_type -> ethereum.eth.v1.BlockRequest
|
||||
8, // 14: ethereum.eth.service.BeaconChain.GetBlock:input_type -> ethereum.eth.v1.BlockRequest
|
||||
8, // 15: ethereum.eth.service.BeaconChain.GetBlockSSZ:input_type -> ethereum.eth.v1.BlockRequest
|
||||
10, // 16: ethereum.eth.service.BeaconChain.GetBlockV2:input_type -> ethereum.eth.v2.BlockRequestV2
|
||||
10, // 17: ethereum.eth.service.BeaconChain.GetBlockSSZV2:input_type -> ethereum.eth.v2.BlockRequestV2
|
||||
8, // 18: ethereum.eth.service.BeaconChain.ListBlockAttestations:input_type -> ethereum.eth.v1.BlockRequest
|
||||
11, // 19: ethereum.eth.service.BeaconChain.ListPoolAttestations:input_type -> ethereum.eth.v1.AttestationsPoolRequest
|
||||
12, // 20: ethereum.eth.service.BeaconChain.SubmitAttestations:input_type -> ethereum.eth.v1.SubmitAttestationsRequest
|
||||
0, // 21: ethereum.eth.service.BeaconChain.ListPoolAttesterSlashings:input_type -> google.protobuf.Empty
|
||||
13, // 22: ethereum.eth.service.BeaconChain.SubmitAttesterSlashing:input_type -> ethereum.eth.v1.AttesterSlashing
|
||||
0, // 23: ethereum.eth.service.BeaconChain.ListPoolProposerSlashings:input_type -> google.protobuf.Empty
|
||||
14, // 24: ethereum.eth.service.BeaconChain.SubmitProposerSlashing:input_type -> ethereum.eth.v1.ProposerSlashing
|
||||
0, // 25: ethereum.eth.service.BeaconChain.ListPoolVoluntaryExits:input_type -> google.protobuf.Empty
|
||||
15, // 26: ethereum.eth.service.BeaconChain.SubmitVoluntaryExit:input_type -> ethereum.eth.v1.SignedVoluntaryExit
|
||||
16, // 27: ethereum.eth.service.BeaconChain.SubmitPoolSyncCommitteeSignatures:input_type -> ethereum.eth.v2.SubmitPoolSyncCommitteeSignatures
|
||||
0, // 28: ethereum.eth.service.BeaconChain.GetForkSchedule:input_type -> google.protobuf.Empty
|
||||
0, // 29: ethereum.eth.service.BeaconChain.GetSpec:input_type -> google.protobuf.Empty
|
||||
0, // 30: ethereum.eth.service.BeaconChain.GetDepositContract:input_type -> google.protobuf.Empty
|
||||
17, // 31: ethereum.eth.service.BeaconChain.GetGenesis:output_type -> ethereum.eth.v1.GenesisResponse
|
||||
18, // 32: ethereum.eth.service.BeaconChain.GetWeakSubjectivity:output_type -> ethereum.eth.v1.WeakSubjectivityResponse
|
||||
19, // 33: ethereum.eth.service.BeaconChain.GetStateRoot:output_type -> ethereum.eth.v1.StateRootResponse
|
||||
20, // 34: ethereum.eth.service.BeaconChain.GetStateFork:output_type -> ethereum.eth.v1.StateForkResponse
|
||||
21, // 35: ethereum.eth.service.BeaconChain.GetFinalityCheckpoints:output_type -> ethereum.eth.v1.StateFinalityCheckpointResponse
|
||||
22, // 36: ethereum.eth.service.BeaconChain.ListValidators:output_type -> ethereum.eth.v1.StateValidatorsResponse
|
||||
23, // 37: ethereum.eth.service.BeaconChain.GetValidator:output_type -> ethereum.eth.v1.StateValidatorResponse
|
||||
24, // 38: ethereum.eth.service.BeaconChain.ListValidatorBalances:output_type -> ethereum.eth.v1.ValidatorBalancesResponse
|
||||
25, // 39: ethereum.eth.service.BeaconChain.ListCommittees:output_type -> ethereum.eth.v1.StateCommitteesResponse
|
||||
26, // 40: ethereum.eth.service.BeaconChain.ListSyncCommittees:output_type -> ethereum.eth.v2.StateSyncCommitteesResponse
|
||||
27, // 41: ethereum.eth.service.BeaconChain.ListBlockHeaders:output_type -> ethereum.eth.v1.BlockHeadersResponse
|
||||
28, // 42: ethereum.eth.service.BeaconChain.GetBlockHeader:output_type -> ethereum.eth.v1.BlockHeaderResponse
|
||||
0, // 43: ethereum.eth.service.BeaconChain.SubmitBlock:output_type -> google.protobuf.Empty
|
||||
29, // 44: ethereum.eth.service.BeaconChain.GetBlockRoot:output_type -> ethereum.eth.v1.BlockRootResponse
|
||||
30, // 45: ethereum.eth.service.BeaconChain.GetBlock:output_type -> ethereum.eth.v1.BlockResponse
|
||||
31, // 46: ethereum.eth.service.BeaconChain.GetBlockSSZ:output_type -> ethereum.eth.v1.BlockSSZResponse
|
||||
32, // 47: ethereum.eth.service.BeaconChain.GetBlockV2:output_type -> ethereum.eth.v2.BlockResponseV2
|
||||
33, // 48: ethereum.eth.service.BeaconChain.GetBlockSSZV2:output_type -> ethereum.eth.v2.BlockSSZResponseV2
|
||||
34, // 49: ethereum.eth.service.BeaconChain.ListBlockAttestations:output_type -> ethereum.eth.v1.BlockAttestationsResponse
|
||||
35, // 50: ethereum.eth.service.BeaconChain.ListPoolAttestations:output_type -> ethereum.eth.v1.AttestationsPoolResponse
|
||||
0, // 51: ethereum.eth.service.BeaconChain.SubmitAttestations:output_type -> google.protobuf.Empty
|
||||
36, // 52: ethereum.eth.service.BeaconChain.ListPoolAttesterSlashings:output_type -> ethereum.eth.v1.AttesterSlashingsPoolResponse
|
||||
0, // 53: ethereum.eth.service.BeaconChain.SubmitAttesterSlashing:output_type -> google.protobuf.Empty
|
||||
37, // 54: ethereum.eth.service.BeaconChain.ListPoolProposerSlashings:output_type -> ethereum.eth.v1.ProposerSlashingPoolResponse
|
||||
0, // 55: ethereum.eth.service.BeaconChain.SubmitProposerSlashing:output_type -> google.protobuf.Empty
|
||||
38, // 56: ethereum.eth.service.BeaconChain.ListPoolVoluntaryExits:output_type -> ethereum.eth.v1.VoluntaryExitsPoolResponse
|
||||
0, // 57: ethereum.eth.service.BeaconChain.SubmitVoluntaryExit:output_type -> google.protobuf.Empty
|
||||
0, // 58: ethereum.eth.service.BeaconChain.SubmitPoolSyncCommitteeSignatures:output_type -> google.protobuf.Empty
|
||||
39, // 59: ethereum.eth.service.BeaconChain.GetForkSchedule:output_type -> ethereum.eth.v1.ForkScheduleResponse
|
||||
40, // 60: ethereum.eth.service.BeaconChain.GetSpec:output_type -> ethereum.eth.v1.SpecResponse
|
||||
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 extendee
|
||||
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.
|
||||
type BeaconChainClient interface {
|
||||
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)
|
||||
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)
|
||||
@@ -538,6 +550,15 @@ func (c *beaconChainClient) GetGenesis(ctx context.Context, in *empty.Empty, opt
|
||||
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) {
|
||||
out := new(v1.StateRootResponse)
|
||||
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.
|
||||
type BeaconChainServer interface {
|
||||
GetGenesis(context.Context, *empty.Empty) (*v1.GenesisResponse, error)
|
||||
GetWeakSubjectivity(context.Context, *empty.Empty) (*v1.WeakSubjectivityResponse, error)
|
||||
GetStateRoot(context.Context, *v1.StateRequest) (*v1.StateRootResponse, error)
|
||||
GetStateFork(context.Context, *v1.StateRequest) (*v1.StateForkResponse, 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) {
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
in := new(v1.StateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -1480,6 +1523,10 @@ var _BeaconChain_serviceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GetGenesis",
|
||||
Handler: _BeaconChain_GetGenesis_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetWeakSubjectivity",
|
||||
Handler: _BeaconChain_GetWeakSubjectivity_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetStateRoot",
|
||||
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) {
|
||||
var protoReq v1.StateRequest
|
||||
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) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
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) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -2688,6 +2749,8 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
||||
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_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_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 (
|
||||
forward_BeaconChain_GetGenesis_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_BeaconChain_GetWeakSubjectivity_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_BeaconChain_GetStateRoot_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" };
|
||||
}
|
||||
|
||||
// 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.
|
||||
rpc GetStateRoot(v1.StateRequest) returns (v1.StateRootResponse) {
|
||||
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 ""
|
||||
}
|
||||
|
||||
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 {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -1850,7 +1952,7 @@ type GenesisResponse_Genesis struct {
|
||||
func (x *GenesisResponse_Genesis) Reset() {
|
||||
*x = GenesisResponse_Genesis{}
|
||||
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.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1863,7 +1965,7 @@ func (x *GenesisResponse_Genesis) String() string {
|
||||
func (*GenesisResponse_Genesis) ProtoMessage() {}
|
||||
|
||||
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 {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1911,7 +2013,7 @@ type StateRootResponse_StateRoot struct {
|
||||
func (x *StateRootResponse_StateRoot) Reset() {
|
||||
*x = StateRootResponse_StateRoot{}
|
||||
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.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1924,7 +2026,7 @@ func (x *StateRootResponse_StateRoot) String() string {
|
||||
func (*StateRootResponse_StateRoot) ProtoMessage() {}
|
||||
|
||||
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 {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1960,7 +2062,7 @@ type StateFinalityCheckpointResponse_StateFinalityCheckpoint struct {
|
||||
func (x *StateFinalityCheckpointResponse_StateFinalityCheckpoint) Reset() {
|
||||
*x = StateFinalityCheckpointResponse_StateFinalityCheckpoint{}
|
||||
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.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1973,7 +2075,7 @@ func (x *StateFinalityCheckpointResponse_StateFinalityCheckpoint) String() strin
|
||||
func (*StateFinalityCheckpointResponse_StateFinalityCheckpoint) ProtoMessage() {}
|
||||
|
||||
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 {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
@@ -2305,7 +2420,7 @@ func file_proto_eth_v1_beacon_chain_proto_rawDescGZIP() []byte {
|
||||
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{}{
|
||||
(*GenesisResponse)(nil), // 0: ethereum.eth.v1.GenesisResponse
|
||||
(*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
|
||||
(*DepositContractResponse)(nil), // 34: ethereum.eth.v1.DepositContractResponse
|
||||
(*DepositContract)(nil), // 35: ethereum.eth.v1.DepositContract
|
||||
(*GenesisResponse_Genesis)(nil), // 36: ethereum.eth.v1.GenesisResponse.Genesis
|
||||
(*StateRootResponse_StateRoot)(nil), // 37: ethereum.eth.v1.StateRootResponse.StateRoot
|
||||
(*StateFinalityCheckpointResponse_StateFinalityCheckpoint)(nil), // 38: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint
|
||||
nil, // 39: ethereum.eth.v1.SpecResponse.DataEntry
|
||||
(*Fork)(nil), // 40: ethereum.eth.v1.Fork
|
||||
(ValidatorStatus)(0), // 41: ethereum.eth.v1.ValidatorStatus
|
||||
(*ValidatorContainer)(nil), // 42: ethereum.eth.v1.ValidatorContainer
|
||||
(*Committee)(nil), // 43: ethereum.eth.v1.Committee
|
||||
(*Attestation)(nil), // 44: ethereum.eth.v1.Attestation
|
||||
(*BeaconBlockHeader)(nil), // 45: ethereum.eth.v1.BeaconBlockHeader
|
||||
(*BeaconBlock)(nil), // 46: ethereum.eth.v1.BeaconBlock
|
||||
(*AttesterSlashing)(nil), // 47: ethereum.eth.v1.AttesterSlashing
|
||||
(*ProposerSlashing)(nil), // 48: ethereum.eth.v1.ProposerSlashing
|
||||
(*SignedVoluntaryExit)(nil), // 49: ethereum.eth.v1.SignedVoluntaryExit
|
||||
(*timestamppb.Timestamp)(nil), // 50: google.protobuf.Timestamp
|
||||
(*Checkpoint)(nil), // 51: ethereum.eth.v1.Checkpoint
|
||||
(*WeakSubjectivityResponse)(nil), // 36: ethereum.eth.v1.WeakSubjectivityResponse
|
||||
(*WeakSubjectivityData)(nil), // 37: ethereum.eth.v1.WeakSubjectivityData
|
||||
(*GenesisResponse_Genesis)(nil), // 38: ethereum.eth.v1.GenesisResponse.Genesis
|
||||
(*StateRootResponse_StateRoot)(nil), // 39: ethereum.eth.v1.StateRootResponse.StateRoot
|
||||
(*StateFinalityCheckpointResponse_StateFinalityCheckpoint)(nil), // 40: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint
|
||||
nil, // 41: ethereum.eth.v1.SpecResponse.DataEntry
|
||||
(*Fork)(nil), // 42: ethereum.eth.v1.Fork
|
||||
(ValidatorStatus)(0), // 43: ethereum.eth.v1.ValidatorStatus
|
||||
(*ValidatorContainer)(nil), // 44: ethereum.eth.v1.ValidatorContainer
|
||||
(*Committee)(nil), // 45: ethereum.eth.v1.Committee
|
||||
(*Attestation)(nil), // 46: ethereum.eth.v1.Attestation
|
||||
(*BeaconBlockHeader)(nil), // 47: ethereum.eth.v1.BeaconBlockHeader
|
||||
(*BeaconBlock)(nil), // 48: ethereum.eth.v1.BeaconBlock
|
||||
(*AttesterSlashing)(nil), // 49: ethereum.eth.v1.AttesterSlashing
|
||||
(*ProposerSlashing)(nil), // 50: ethereum.eth.v1.ProposerSlashing
|
||||
(*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{
|
||||
36, // 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
|
||||
40, // 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
|
||||
41, // 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
|
||||
38, // 0: ethereum.eth.v1.GenesisResponse.data:type_name -> ethereum.eth.v1.GenesisResponse.Genesis
|
||||
39, // 1: ethereum.eth.v1.StateRootResponse.data:type_name -> ethereum.eth.v1.StateRootResponse.StateRoot
|
||||
42, // 2: ethereum.eth.v1.StateForkResponse.data:type_name -> ethereum.eth.v1.Fork
|
||||
40, // 3: ethereum.eth.v1.StateFinalityCheckpointResponse.data:type_name -> ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint
|
||||
43, // 4: ethereum.eth.v1.StateValidatorsRequest.status:type_name -> ethereum.eth.v1.ValidatorStatus
|
||||
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
|
||||
42, // 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
|
||||
44, // 9: ethereum.eth.v1.BlockAttestationsResponse.data:type_name -> ethereum.eth.v1.Attestation
|
||||
44, // 7: ethereum.eth.v1.StateValidatorResponse.data:type_name -> ethereum.eth.v1.ValidatorContainer
|
||||
45, // 8: ethereum.eth.v1.StateCommitteesResponse.data:type_name -> ethereum.eth.v1.Committee
|
||||
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
|
||||
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
|
||||
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
|
||||
46, // 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
|
||||
44, // 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
|
||||
48, // 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
|
||||
40, // 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
|
||||
48, // 16: ethereum.eth.v1.BeaconBlockContainer.message:type_name -> ethereum.eth.v1.BeaconBlock
|
||||
46, // 17: ethereum.eth.v1.SubmitAttestationsRequest.data:type_name -> ethereum.eth.v1.Attestation
|
||||
46, // 18: ethereum.eth.v1.AttestationsPoolResponse.data:type_name -> ethereum.eth.v1.Attestation
|
||||
49, // 19: ethereum.eth.v1.AttesterSlashingsPoolResponse.data:type_name -> ethereum.eth.v1.AttesterSlashing
|
||||
50, // 20: ethereum.eth.v1.ProposerSlashingPoolResponse.data:type_name -> ethereum.eth.v1.ProposerSlashing
|
||||
51, // 21: ethereum.eth.v1.VoluntaryExitsPoolResponse.data:type_name -> ethereum.eth.v1.SignedVoluntaryExit
|
||||
42, // 22: ethereum.eth.v1.ForkScheduleResponse.data:type_name -> ethereum.eth.v1.Fork
|
||||
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
|
||||
50, // 25: ethereum.eth.v1.GenesisResponse.Genesis.genesis_time:type_name -> google.protobuf.Timestamp
|
||||
51, // 26: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.previous_justified:type_name -> ethereum.eth.v1.Checkpoint
|
||||
51, // 27: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.current_justified:type_name -> ethereum.eth.v1.Checkpoint
|
||||
51, // 28: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.finalized:type_name -> ethereum.eth.v1.Checkpoint
|
||||
29, // [29:29] is the sub-list for method output_type
|
||||
29, // [29:29] is the sub-list for method input_type
|
||||
29, // [29:29] is the sub-list for extension type_name
|
||||
29, // [29:29] is the sub-list for extension extendee
|
||||
0, // [0:29] is the sub-list for field type_name
|
||||
37, // 25: ethereum.eth.v1.WeakSubjectivityResponse.data:type_name -> ethereum.eth.v1.WeakSubjectivityData
|
||||
52, // 26: ethereum.eth.v1.WeakSubjectivityData.ws_checkpoint:type_name -> ethereum.eth.v1.Checkpoint
|
||||
53, // 27: ethereum.eth.v1.GenesisResponse.Genesis.genesis_time:type_name -> google.protobuf.Timestamp
|
||||
52, // 28: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.previous_justified:type_name -> ethereum.eth.v1.Checkpoint
|
||||
52, // 29: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.current_justified:type_name -> ethereum.eth.v1.Checkpoint
|
||||
52, // 30: ethereum.eth.v1.StateFinalityCheckpointResponse.StateFinalityCheckpoint.finalized:type_name -> ethereum.eth.v1.Checkpoint
|
||||
31, // [31:31] is the sub-list for method output_type
|
||||
31, // [31:31] is the sub-list for method input_type
|
||||
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() }
|
||||
@@ -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{} {
|
||||
switch v := v.(*GenesisResponse_Genesis); i {
|
||||
switch v := v.(*WeakSubjectivityResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
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{} {
|
||||
switch v := v.(*StateRootResponse_StateRoot); i {
|
||||
switch v := v.(*WeakSubjectivityData); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
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{} {
|
||||
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 {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -2885,7 +3028,7 @@ func file_proto_eth_v1_beacon_chain_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_eth_v1_beacon_chain_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 40,
|
||||
NumMessages: 42,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -270,3 +270,12 @@ message DepositContract {
|
||||
// The address of the deployed deposit contract in use.
|
||||
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 (
|
||||
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) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
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) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
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_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_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_GetWeakSubjectivityCheckpoint_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_BeaconChain_ListBeaconCommittees_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.
|
||||
//
|
||||
// If no filter criteria is specified, the response returns
|
||||
@@ -907,13 +897,4 @@ message IndividualVotesRespond {
|
||||
}
|
||||
|
||||
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",
|
||||
"//config/params: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",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/endtoend/components:go_default_library",
|
||||
@@ -48,11 +53,14 @@ go_test(
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/slasher/simulator:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//time/slots: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",
|
||||
"@com_github_sirupsen_logrus//hooks/test: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_x_sync//errgroup:go_default_library",
|
||||
],
|
||||
@@ -91,7 +99,12 @@ go_test(
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//config/params: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/sniff:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/endtoend/components:go_default_library",
|
||||
"//testing/endtoend/components/eth1:go_default_library",
|
||||
@@ -102,11 +115,14 @@ go_test(
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/slasher/simulator:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//time/slots: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",
|
||||
"@com_github_sirupsen_logrus//hooks/test: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_x_sync//errgroup:go_default_library",
|
||||
],
|
||||
|
||||
@@ -27,11 +27,12 @@ var _ e2etypes.BeaconNodeSet = (*BeaconNodeSet)(nil)
|
||||
|
||||
// BeaconNodeSet represents set of beacon nodes.
|
||||
type BeaconNodeSet struct {
|
||||
e2etypes.ComponentRunner
|
||||
started chan struct{}
|
||||
config *e2etypes.E2EConfig
|
||||
enr string
|
||||
ids []string
|
||||
started chan struct{}
|
||||
e2etypes.ComponentRunner
|
||||
ids []string
|
||||
flags []string
|
||||
}
|
||||
|
||||
// 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.
|
||||
func NewBeaconNodes(config *e2etypes.E2EConfig) *BeaconNodeSet {
|
||||
func NewBeaconNodes(flags []string, config *e2etypes.E2EConfig) *BeaconNodeSet {
|
||||
return &BeaconNodeSet{
|
||||
config: config,
|
||||
flags: flags,
|
||||
started: make(chan struct{}, 1),
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +58,7 @@ func (s *BeaconNodeSet) Start(ctx context.Context) error {
|
||||
// Create beacon nodes.
|
||||
nodes := make([]e2etypes.ComponentRunner, e2e.TestParams.BeaconNodeCount)
|
||||
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).
|
||||
@@ -82,19 +84,21 @@ func (s *BeaconNodeSet) Started() <-chan struct{} {
|
||||
type BeaconNode struct {
|
||||
e2etypes.ComponentRunner
|
||||
config *e2etypes.E2EConfig
|
||||
started chan struct{}
|
||||
index int
|
||||
flags []string
|
||||
started chan struct{}
|
||||
enr string
|
||||
peerID string
|
||||
}
|
||||
|
||||
// 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{
|
||||
config: config,
|
||||
index: index,
|
||||
enr: enr,
|
||||
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")
|
||||
}
|
||||
|
||||
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))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -146,6 +150,7 @@ func (node *BeaconNode) Start(ctx context.Context) error {
|
||||
args = append(args, features.E2EBeaconChainFlags...)
|
||||
}
|
||||
args = append(args, config.BeaconFlags...)
|
||||
args = append(args, nodeFlags...)
|
||||
|
||||
cmd := exec.CommandContext(ctx, binaryPath, args...) // #nosec G204 -- Safe
|
||||
// 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)
|
||||
}
|
||||
|
||||
if config.UseFixedPeerIDs {
|
||||
if node.config.UseFixedPeerIDs {
|
||||
peerId, err := helpers.FindFollowingTextInFile(stdOutFile, "Running node with peer id of ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find peer id: %w", err)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/testing/endtoend/helpers"
|
||||
e2e "github.com/prysmaticlabs/prysm/testing/endtoend/params"
|
||||
e2etypes "github.com/prysmaticlabs/prysm/testing/endtoend/types"
|
||||
@@ -48,10 +49,12 @@ func (node *BootNode) Start(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := params.E2ETestConfig()
|
||||
args := []string{
|
||||
fmt.Sprintf("--log-file=%s", stdOutFile.Name()),
|
||||
fmt.Sprintf("--discv5-port=%d", e2e.TestParams.Ports.BootNodePort),
|
||||
fmt.Sprintf("--metrics-port=%d", e2e.TestParams.Ports.BootNodeMetricsPort),
|
||||
fmt.Sprintf("--fork-version=%#x", cfg.GenesisForkVersion),
|
||||
"--debug",
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,11 @@ import (
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||
"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"
|
||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/testing/endtoend/components"
|
||||
@@ -27,9 +32,12 @@ import (
|
||||
e2e "github.com/prysmaticlabs/prysm/testing/endtoend/params"
|
||||
e2etypes "github.com/prysmaticlabs/prysm/testing/endtoend/types"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
@@ -48,15 +56,23 @@ func init() {
|
||||
|
||||
// testRunner abstracts E2E test configuration and running.
|
||||
type testRunner struct {
|
||||
t *testing.T
|
||||
config *e2etypes.E2EConfig
|
||||
t *testing.T
|
||||
config *e2etypes.E2EConfig
|
||||
ctx context.Context
|
||||
doneChan context.CancelFunc
|
||||
group *errgroup.Group
|
||||
}
|
||||
|
||||
// newTestRunner creates E2E test runner.
|
||||
func newTestRunner(t *testing.T, config *e2etypes.E2EConfig) *testRunner {
|
||||
ctx, done := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
return &testRunner{
|
||||
t: t,
|
||||
config: config,
|
||||
ctx: ctx,
|
||||
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("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)
|
||||
multiClientActive := e2e.TestParams.LighthouseBeaconNodeCount > 0
|
||||
var keyGen, lighthouseValidatorNodes e2etypes.ComponentRunner
|
||||
var lighthouseNodes *components.LighthouseBeaconNodeSet
|
||||
|
||||
ctx, done := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
ctx := r.ctx
|
||||
g := r.group
|
||||
done := r.doneChan
|
||||
tracingSink := components.NewTracingSink(config.TracingSinkEndpoint)
|
||||
g.Go(func() error {
|
||||
return tracingSink.Start(ctx)
|
||||
@@ -134,7 +154,7 @@ func (r *testRunner) run() {
|
||||
})
|
||||
|
||||
// Beacon nodes.
|
||||
beaconNodes := components.NewBeaconNodes(config)
|
||||
beaconNodes := components.NewBeaconNodes(config.BeaconFlags, config)
|
||||
g.Go(func() error {
|
||||
if err := helpers.ComponentsStarted(ctx, []e2etypes.ComponentRunner{eth1Nodes, bootNode}); err != nil {
|
||||
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 {
|
||||
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 {
|
||||
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.
|
||||
func (r *testRunner) waitForChainStart() {
|
||||
// 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.
|
||||
func (r *testRunner) testBeaconChainSync(ctx context.Context, g *errgroup.Group,
|
||||
conns []*grpc.ClientConn, tickingStartTime time.Time, bootnodeEnr, minerEnr string) error {
|
||||
t, config := r.t, r.config
|
||||
index := e2e.TestParams.BeaconNodeCount
|
||||
t, config := r.t, r.config
|
||||
ethNode := eth1.NewNode(index, minerEnr)
|
||||
g.Go(func() error {
|
||||
return ethNode.Start(ctx)
|
||||
})
|
||||
syncBeaconNode := components.NewBeaconNode(config, index, bootnodeEnr)
|
||||
syncBeaconNode := components.NewBeaconNode(index, bootnodeEnr, r.config.BeaconFlags, config)
|
||||
g.Go(func() error {
|
||||
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.
|
||||
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)
|
||||
time.Sleep(time.Until(waitForSync))
|
||||
|
||||
syncLogFile, err := os.Open(path.Join(e2e.TestParams.LogPath, fmt.Sprintf(e2e.BeaconNodeLogFileName, index)))
|
||||
require.NoError(t, err)
|
||||
defer helpers.LogErrorOutput(t, syncLogFile, "beacon chain node", index)
|
||||
t.Run("sync completed", func(t *testing.T) {
|
||||
require.NoError(r.t, err)
|
||||
defer helpers.LogErrorOutput(r.t, syncLogFile, "beacon chain node", index)
|
||||
r.t.Run("sync completed", func(t *testing.T) {
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -391,7 +691,7 @@ func (r *testRunner) testBeaconChainSync(ctx context.Context, g *errgroup.Group,
|
||||
time.Sleep(time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
|
||||
syncEvaluators := []e2etypes.Evaluator{ev.FinishedSyncing, ev.AllNodesHaveSameHead}
|
||||
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")
|
||||
})
|
||||
}
|
||||
|
||||
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...)
|
||||
}
|
||||
|
||||
// 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
|
||||
func (m *MockBeaconChainClient) ListAttestations(arg0 context.Context, arg1 *eth.ListAttestationsRequest, arg2 ...grpc.CallOption) (*eth.ListAttestationsResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -192,8 +192,12 @@ func createLocalNode(privKey *ecdsa.PrivateKey, ipAddr net.IP, port int) (*enode
|
||||
external = ipAddr
|
||||
}
|
||||
fVersion := params.BeaconConfig().GenesisForkVersion
|
||||
if *forkVersion != "" {
|
||||
fVersion, err = hex.DecodeString(*forkVersion)
|
||||
fv := *forkVersion
|
||||
if fv != "" {
|
||||
if fv[0:2] == "0x" {
|
||||
fv = fv[2:]
|
||||
}
|
||||
fVersion, err = hex.DecodeString(fv)
|
||||
if err != nil {
|
||||
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) {
|
||||
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
|
||||
params.LoadChainConfigFile(chainConfigFileName)
|
||||
params.LoadChainConfigFile(chainConfigFileName, nil)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
chainConfigFileName := cliCtx.String(cmd.ChainConfigFileFlag.Name)
|
||||
params.LoadChainConfigFile(chainConfigFileName)
|
||||
params.LoadChainConfigFile(chainConfigFileName, nil)
|
||||
}
|
||||
|
||||
// Initializes any forks here.
|
||||
|
||||
Reference in New Issue
Block a user