Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement GetBeaconState Endpoint #5668

Merged
merged 25 commits into from
May 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d83bbfb
implement get beacon state
rauljordan Apr 28, 2020
763fac2
gaz
rauljordan Apr 28, 2020
d7a62c1
Merge branch 'master' into implement-debug-state
rauljordan Apr 28, 2020
39cbb9b
passing tests
rauljordan Apr 28, 2020
95916a6
enable with featureconfig
rauljordan Apr 28, 2020
99a0ad2
struct oder
rauljordan Apr 28, 2020
b4d0122
Update beacon-chain/rpc/beacon/state.go
rauljordan Apr 28, 2020
b3417f1
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 29, 2020
6e18a28
lint resolve
rauljordan Apr 29, 2020
f5c4706
Merge branch 'implement-debug-state' of github.com:prysmaticlabs/prys…
rauljordan Apr 29, 2020
9f60d17
tested at runtime
rauljordan Apr 29, 2020
5e2932b
fix build
rauljordan Apr 29, 2020
7b2bda5
Merge branch 'master' into implement-debug-state
rauljordan Apr 29, 2020
3171842
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 29, 2020
39e47d1
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 29, 2020
4f256ae
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 29, 2020
0bbf1ed
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 29, 2020
1a84ae0
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 29, 2020
6e0ec7e
build and fmt
rauljordan Apr 30, 2020
1cbb61a
conf
rauljordan Apr 30, 2020
2293439
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 30, 2020
f3f527b
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 30, 2020
09ee03d
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 30, 2020
3d5fc25
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 30, 2020
ca048dc
Merge refs/heads/master into implement-debug-state
prylabs-bulldozer[bot] Apr 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions beacon-chain/flags/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,9 @@ var (
Usage: "The amount of blocks the local peer is bounded to request and respond to in a batch.",
Value: 64,
}
// EnableDebugRPCEndpoints as /v1/beacon/state.
EnableDebugRPCEndpoints = &cli.BoolFlag{
Name: "enable-debug-rpc-endpoints",
Usage: "Enables the debug rpc service, containing utility endpoints such as /eth/v1alpha1/beacon/state. Requires --new-state-mgmt",
}
)
1 change: 1 addition & 0 deletions beacon-chain/gateway/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ go_library(
],
deps = [
"//shared:go_default_library",
"//proto/beacon/rpc/v1:go_grpc_gateway_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_grpc_gateway_library",
"@com_github_rs_cors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
Expand Down
56 changes: 37 additions & 19 deletions beacon-chain/gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1_gateway"
pbrpc "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1_gateway"
"github.com/prysmaticlabs/prysm/shared"
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
Expand All @@ -21,16 +22,16 @@ var _ = shared.Service(&Gateway{})
// Gateway is the gRPC gateway to serve HTTP JSON traffic as a proxy and forward
// it to the beacon-chain gRPC server.
type Gateway struct {
conn *grpc.ClientConn
ctx context.Context
cancel context.CancelFunc
gatewayAddr string
remoteAddr string
server *http.Server
mux *http.ServeMux
allowedOrigins []string

startFailure error
conn *grpc.ClientConn
ctx context.Context
cancel context.CancelFunc
gatewayAddr string
remoteAddr string
server *http.Server
mux *http.ServeMux
allowedOrigins []string
startFailure error
enableDebugRPCEndpoints bool
}

// Start the gateway service. This serves the HTTP JSON traffic on the specified
Expand All @@ -50,12 +51,21 @@ func (g *Gateway) Start() {

g.conn = conn

gwmux := gwruntime.NewServeMux(gwruntime.WithMarshalerOption(gwruntime.MIMEWildcard, &gwruntime.JSONPb{OrigName: false, EmitDefaults: true}))
for _, f := range []func(context.Context, *gwruntime.ServeMux, *grpc.ClientConn) error{
gwmux := gwruntime.NewServeMux(
gwruntime.WithMarshalerOption(
gwruntime.MIMEWildcard,
&gwruntime.JSONPb{OrigName: false, EmitDefaults: true},
),
)
handlers := []func(context.Context, *gwruntime.ServeMux, *grpc.ClientConn) error{
ethpb.RegisterNodeHandler,
ethpb.RegisterBeaconChainHandler,
ethpb.RegisterBeaconNodeValidatorHandler,
} {
}
if g.enableDebugRPCEndpoints {
handlers = append(handlers, pbrpc.RegisterDebugHandler)
}
for _, f := range handlers {
if err := f(ctx, gwmux, conn); err != nil {
log.WithError(err).Error("Failed to start gateway")
g.startFailure = err
Expand Down Expand Up @@ -108,17 +118,25 @@ func (g *Gateway) Stop() error {

// New returns a new gateway server which translates HTTP into gRPC.
// Accepts a context and optional http.ServeMux.
func New(ctx context.Context, remoteAddress, gatewayAddress string, mux *http.ServeMux, allowedOrigins []string) *Gateway {
func New(
ctx context.Context,
remoteAddress,
gatewayAddress string,
mux *http.ServeMux,
allowedOrigins []string,
enableDebugRPCEndpoints bool,
) *Gateway {
if mux == nil {
mux = http.NewServeMux()
}

return &Gateway{
remoteAddr: remoteAddress,
gatewayAddr: gatewayAddress,
ctx: ctx,
mux: mux,
allowedOrigins: allowedOrigins,
remoteAddr: remoteAddress,
gatewayAddr: gatewayAddress,
ctx: ctx,
mux: mux,
allowedOrigins: allowedOrigins,
enableDebugRPCEndpoints: enableDebugRPCEndpoints,
}
}

Expand Down
18 changes: 13 additions & 5 deletions beacon-chain/gateway/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import (
)

var (
beaconRPC = flag.String("beacon-rpc", "localhost:4000", "Beacon chain gRPC endpoint")
port = flag.Int("port", 8000, "Port to serve on")
debug = flag.Bool("debug", false, "Enable debug logging")
allowedOrigins = flag.String("corsdomain", "", "A comma separated list of CORS domains to allow")
beaconRPC = flag.String("beacon-rpc", "localhost:4000", "Beacon chain gRPC endpoint")
port = flag.Int("port", 8000, "Port to serve on")
debug = flag.Bool("debug", false, "Enable debug logging")
allowedOrigins = flag.String("corsdomain", "", "A comma separated list of CORS domains to allow")
enableDebugRPCEndpoints = flag.Bool("enable-debug-rpc-endpoints", false, "Enable debug rpc endpoints such as /eth/v1alpha1/beacon/state")
)

func init() {
Expand All @@ -35,7 +36,14 @@ func main() {
}

mux := http.NewServeMux()
gw := gateway.New(context.Background(), *beaconRPC, fmt.Sprintf("0.0.0.0:%d", *port), mux, strings.Split(*allowedOrigins, ","))
gw := gateway.New(
context.Background(),
*beaconRPC,
fmt.Sprintf("0.0.0.0:%d", *port),
mux,
strings.Split(*allowedOrigins, ","),
*enableDebugRPCEndpoints,
)
mux.HandleFunc("/swagger/", gateway.SwaggerServer())
mux.HandleFunc("/healthz", healthzServer(gw))
gw.Start()
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var appFlags = []cli.Flag{
flags.ArchiveBlocksFlag,
flags.ArchiveAttestationsFlag,
flags.SlotsPerArchivedPoint,
flags.EnableDebugRPCEndpoints,
cmd.BootstrapNode,
cmd.NoDiscovery,
cmd.StaticPeers,
Expand Down
64 changes: 34 additions & 30 deletions beacon-chain/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,38 +538,40 @@ func (b *BeaconNode) registerRPCService() error {
slasherCert := b.cliCtx.String(flags.SlasherCertFlag.Name)
slasherProvider := b.cliCtx.String(flags.SlasherProviderFlag.Name)
mockEth1DataVotes := b.cliCtx.Bool(flags.InteropMockEth1DataVotesFlag.Name)
enableDebugRPCEndpoints := b.cliCtx.Bool(flags.EnableDebugRPCEndpoints.Name)
p2pService := b.fetchP2P()
rpcService := rpc.NewService(b.ctx, &rpc.Config{
Host: host,
Port: port,
CertFlag: cert,
KeyFlag: key,
BeaconDB: b.db,
Broadcaster: p2pService,
PeersFetcher: p2pService,
HeadFetcher: chainService,
ForkFetcher: chainService,
FinalizationFetcher: chainService,
ParticipationFetcher: chainService,
BlockReceiver: chainService,
AttestationReceiver: chainService,
GenesisTimeFetcher: chainService,
GenesisFetcher: chainService,
AttestationsPool: b.attestationPool,
ExitPool: b.exitPool,
SlashingsPool: b.slashingsPool,
POWChainService: web3Service,
ChainStartFetcher: chainStartFetcher,
MockEth1Votes: mockEth1DataVotes,
SyncService: syncService,
DepositFetcher: depositFetcher,
PendingDepositFetcher: b.depositCache,
BlockNotifier: b,
StateNotifier: b,
OperationNotifier: b,
SlasherCert: slasherCert,
SlasherProvider: slasherProvider,
StateGen: b.stateGen,
Host: host,
Port: port,
CertFlag: cert,
KeyFlag: key,
BeaconDB: b.db,
Broadcaster: p2pService,
PeersFetcher: p2pService,
HeadFetcher: chainService,
ForkFetcher: chainService,
FinalizationFetcher: chainService,
ParticipationFetcher: chainService,
BlockReceiver: chainService,
AttestationReceiver: chainService,
GenesisTimeFetcher: chainService,
GenesisFetcher: chainService,
AttestationsPool: b.attestationPool,
ExitPool: b.exitPool,
SlashingsPool: b.slashingsPool,
POWChainService: web3Service,
ChainStartFetcher: chainStartFetcher,
MockEth1Votes: mockEth1DataVotes,
SyncService: syncService,
DepositFetcher: depositFetcher,
PendingDepositFetcher: b.depositCache,
BlockNotifier: b,
StateNotifier: b,
OperationNotifier: b,
SlasherCert: slasherCert,
SlasherProvider: slasherProvider,
StateGen: b.stateGen,
EnableDebugRPCEndpoints: enableDebugRPCEndpoints,
})

return b.services.RegisterService(rpcService)
Expand Down Expand Up @@ -610,13 +612,15 @@ func (b *BeaconNode) registerGRPCGateway() error {
selfAddress := fmt.Sprintf("127.0.0.1:%d", b.cliCtx.Int(flags.RPCPort.Name))
gatewayAddress := fmt.Sprintf("0.0.0.0:%d", gatewayPort)
allowedOrigins := strings.Split(b.cliCtx.String(flags.GPRCGatewayCorsDomain.Name), ",")
enableDebugRPCEndpoints := b.cliCtx.Bool(flags.EnableDebugRPCEndpoints.Name)
return b.services.RegisterService(
gateway.New(
b.ctx,
selfAddress,
gatewayAddress,
nil, /*optional mux*/
allowedOrigins,
enableDebugRPCEndpoints,
),
)
}
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/rpc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ go_library(
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/sync:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/beacon/rpc/v1:go_default_library",
"//proto/slashing:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/params:go_default_library",
Expand Down
4 changes: 4 additions & 0 deletions beacon-chain/rpc/beacon/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ go_library(
"config.go",
"server.go",
"slashings.go",
"state.go",
"validators.go",
"validators_stream.go",
],
Expand Down Expand Up @@ -37,6 +38,7 @@ go_library(
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/beacon/rpc/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/event:go_default_library",
Expand Down Expand Up @@ -67,6 +69,7 @@ go_test(
"committees_test.go",
"config_test.go",
"slashings_test.go",
"state_test.go",
"validators_stream_test.go",
"validators_test.go",
],
Expand All @@ -92,6 +95,7 @@ go_test(
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/beacon/rpc/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
Expand Down
39 changes: 39 additions & 0 deletions beacon-chain/rpc/beacon/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package beacon

import (
"context"

pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
pbrpc "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// GetBeaconState retrieves a beacon state
// from the beacon node by either a slot or block root.
func (bs *Server) GetBeaconState(
ctx context.Context,
req *pbrpc.BeaconStateRequest,
) (*pbp2p.BeaconState, error) {
if !featureconfig.Get().NewStateMgmt {
return nil, status.Error(codes.FailedPrecondition, "requires --enable-new-state-mgmt to function")
}
switch q := req.QueryFilter.(type) {
case *pbrpc.BeaconStateRequest_Slot:
st, err := bs.StateGen.StateBySlot(ctx, q.Slot)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not compute state by slot: %v", err)
}
return st.CloneInnerState(), nil
case *pbrpc.BeaconStateRequest_BlockRoot:
st, err := bs.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(q.BlockRoot))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not compute state by block root: %v", err)
}
return st.CloneInnerState(), nil
default:
return nil, status.Error(codes.InvalidArgument, "need to specify either a block root or slot to request state")
}
}
80 changes: 80 additions & 0 deletions beacon-chain/rpc/beacon/state_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package beacon

import (
"context"
"testing"

"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
pbrpc "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/testutil"
)

func TestServer_GetBeaconState(t *testing.T) {
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{NewStateMgmt: true})
defer resetCfg()

db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)

ctx := context.Background()
st := testutil.NewBeaconState()
slot := uint64(100)
if err := st.SetSlot(slot); err != nil {
t.Fatal(err)
}
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{
Slot: slot,
}}
if err := db.SaveBlock(ctx, b); err != nil {
t.Fatal(err)
}
gRoot, err := ssz.HashTreeRoot(b.Block)
if err != nil {
t.Fatal(err)
}
gen := stategen.New(db, cache.NewStateSummaryCache())
if err := gen.SaveState(ctx, gRoot, st); err != nil {
t.Fatal(err)
}
if err := db.SaveState(ctx, st, gRoot); err != nil {
t.Fatal(err)
}
bs := &Server{
BeaconDB: db,
StateGen: gen,
}
if _, err := bs.GetBeaconState(ctx, &pbrpc.BeaconStateRequest{}); err == nil {
t.Errorf("Expected error without a query filter, received nil")
}
req := &pbrpc.BeaconStateRequest{
QueryFilter: &pbrpc.BeaconStateRequest_BlockRoot{
BlockRoot: gRoot[:],
},
}
res, err := bs.GetBeaconState(ctx, req)
if err != nil {
t.Fatal(err)
}
wanted := st.CloneInnerState()
if !proto.Equal(wanted, res) {
t.Errorf("Wanted %v, received %v", wanted, res)
}
req = &pbrpc.BeaconStateRequest{
QueryFilter: &pbrpc.BeaconStateRequest_Slot{
Slot: slot,
},
}
res, err = bs.GetBeaconState(ctx, req)
if err != nil {
t.Fatal(err)
}
if !proto.Equal(wanted, res) {
t.Errorf("Wanted %v, received %v", wanted, res)
}
}
Loading