mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 03:30:35 +00:00
Get genesis only once (#13796)
This commit is contained in:
parent
14d7416c16
commit
6de7df6b9d
@ -115,7 +115,7 @@ func NewNodeClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient i
|
||||
b := &beaconApiNodeClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
fallbackClient: fallbackClient,
|
||||
genesisProvider: beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler},
|
||||
genesisProvider: &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler},
|
||||
}
|
||||
b.healthTracker = beacon.NewNodeHealthTracker(b)
|
||||
return b
|
||||
|
@ -29,7 +29,7 @@ type beaconApiValidatorClient struct {
|
||||
|
||||
func NewBeaconApiValidatorClient(jsonRestHandler JsonRestHandler, opts ...ValidatorClientOpt) iface.ValidatorClient {
|
||||
c := &beaconApiValidatorClient{
|
||||
genesisProvider: beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler},
|
||||
genesisProvider: &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler},
|
||||
dutiesProvider: beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler},
|
||||
stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler},
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
@ -19,6 +20,8 @@ type GenesisProvider interface {
|
||||
|
||||
type beaconApiGenesisProvider struct {
|
||||
jsonRestHandler JsonRestHandler
|
||||
genesis *structs.Genesis
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
func (c beaconApiValidatorClient) waitForChainStart(ctx context.Context) (*ethpb.ChainStartResponse, error) {
|
||||
@ -64,15 +67,23 @@ func (c beaconApiValidatorClient) waitForChainStart(ctx context.Context) (*ethpb
|
||||
}
|
||||
|
||||
// GetGenesis gets the genesis information from the beacon node via the /eth/v1/beacon/genesis endpoint
|
||||
func (c beaconApiGenesisProvider) GetGenesis(ctx context.Context) (*structs.Genesis, error) {
|
||||
func (c *beaconApiGenesisProvider) GetGenesis(ctx context.Context) (*structs.Genesis, error) {
|
||||
genesisJson := &structs.GetGenesisResponse{}
|
||||
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/genesis", genesisJson); err != nil {
|
||||
return nil, err
|
||||
var doErr error
|
||||
c.once.Do(func() {
|
||||
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/genesis", genesisJson); err != nil {
|
||||
doErr = err
|
||||
return
|
||||
}
|
||||
if genesisJson.Data == nil {
|
||||
doErr = errors.New("genesis data is nil")
|
||||
return
|
||||
}
|
||||
c.genesis = genesisJson.Data
|
||||
})
|
||||
if doErr != nil {
|
||||
// Allow another call because the current one returned an error
|
||||
c.once = sync.Once{}
|
||||
}
|
||||
|
||||
if genesisJson.Data == nil {
|
||||
return nil, errors.New("genesis data is nil")
|
||||
}
|
||||
|
||||
return genesisJson.Data, nil
|
||||
return c.genesis, doErr
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
@ -66,3 +67,78 @@ func TestGetGenesis_NilData(t *testing.T) {
|
||||
_, err := genesisProvider.GetGenesis(ctx)
|
||||
assert.ErrorContains(t, "genesis data is nil", err)
|
||||
}
|
||||
|
||||
func TestGetGenesis_EndpointCalledOnlyOnce(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
genesisResponseJson := structs.GetGenesisResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
"/eth/v1/beacon/genesis",
|
||||
&genesisResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetGenesisResponse{
|
||||
Data: &structs.Genesis{
|
||||
GenesisTime: "1234",
|
||||
GenesisValidatorsRoot: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := genesisProvider.GetGenesis(ctx)
|
||||
assert.NoError(t, err)
|
||||
resp, err := genesisProvider.GetGenesis(ctx)
|
||||
assert.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
assert.Equal(t, "1234", resp.GenesisTime)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", resp.GenesisValidatorsRoot)
|
||||
}
|
||||
|
||||
func TestGetGenesis_EndpointCanBeCalledAgainAfterError(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
genesisResponseJson := structs.GetGenesisResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
"/eth/v1/beacon/genesis",
|
||||
&genesisResponseJson,
|
||||
).Return(
|
||||
errors.New("foo"),
|
||||
).Times(1)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
"/eth/v1/beacon/genesis",
|
||||
&genesisResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetGenesisResponse{
|
||||
Data: &structs.Genesis{
|
||||
GenesisTime: "1234",
|
||||
GenesisValidatorsRoot: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := genesisProvider.GetGenesis(ctx)
|
||||
require.ErrorContains(t, "foo", err)
|
||||
resp, err := genesisProvider.GetGenesis(ctx)
|
||||
assert.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
assert.Equal(t, "1234", resp.GenesisTime)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", resp.GenesisValidatorsRoot)
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func TestWaitForChainStart_ValidGenesis(t *testing.T) {
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
validatorClient := beaconApiValidatorClient{genesisProvider: genesisProvider}
|
||||
validatorClient := beaconApiValidatorClient{genesisProvider: &genesisProvider}
|
||||
resp, err := validatorClient.WaitForChainStart(ctx, &emptypb.Empty{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
@ -104,7 +104,7 @@ func TestWaitForChainStart_BadGenesis(t *testing.T) {
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
validatorClient := beaconApiValidatorClient{genesisProvider: genesisProvider}
|
||||
validatorClient := beaconApiValidatorClient{genesisProvider: &genesisProvider}
|
||||
_, err := validatorClient.WaitForChainStart(ctx, &emptypb.Empty{})
|
||||
assert.ErrorContains(t, testCase.errorMessage, err)
|
||||
})
|
||||
@ -127,7 +127,7 @@ func TestWaitForChainStart_JsonResponseError(t *testing.T) {
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
validatorClient := beaconApiValidatorClient{genesisProvider: genesisProvider}
|
||||
validatorClient := beaconApiValidatorClient{genesisProvider: &genesisProvider}
|
||||
_, err := validatorClient.WaitForChainStart(ctx, &emptypb.Empty{})
|
||||
assert.ErrorContains(t, "failed to get genesis data", err)
|
||||
assert.ErrorContains(t, "some specific json error", err)
|
||||
@ -172,7 +172,7 @@ func TestWaitForChainStart_JsonResponseError404(t *testing.T) {
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
validatorClient := beaconApiValidatorClient{genesisProvider: genesisProvider}
|
||||
validatorClient := beaconApiValidatorClient{genesisProvider: &genesisProvider}
|
||||
resp, err := validatorClient.WaitForChainStart(ctx, &emptypb.Empty{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user