Beacon Node Determines Slot From Genesis Block if ChainState Detected (#606)

This commit is contained in:
Raul Jordan 2018-10-02 15:07:33 -05:00 committed by GitHub
parent d5bf733948
commit 593e3dcdf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 13 deletions

View File

@ -61,7 +61,6 @@ func NewChainService(ctx context.Context, cfg *Config) (*ChainService, error) {
ctx, cancel := context.WithCancel(ctx)
return &ChainService{
ctx: ctx,
genesisTimestamp: params.GetConfig().GenesisTime,
chain: cfg.Chain,
cancel: cancel,
beaconDB: cfg.BeaconDB,
@ -85,6 +84,15 @@ func (c *ChainService) Start() {
// to truly continue across sessions.
log.Info("Starting service")
genesis, err := c.GenesisBlock()
if err != nil {
log.Fatalf("Could not get genesis block: %v", err)
}
c.genesisTimestamp, err = genesis.Timestamp()
if err != nil {
log.Fatalf("Could not get genesis timestamp: %v", err)
}
// If the genesis time was at 12:00:00PM and the current time is 12:00:03PM,
// the next slot should tick at 12:00:08PM. We can accomplish this
// using utils.BlockingWait and passing in the desired
@ -373,7 +381,14 @@ func (c *ChainService) blockProcessing() {
aState := c.chain.ActiveState()
cState := c.chain.CrystallizedState()
if valid := block.IsValid(c, aState, cState, parent.SlotNumber(), c.enableAttestationValidity); !valid {
if valid := block.IsValid(
c,
aState,
cState,
parent.SlotNumber(),
c.enableAttestationValidity,
c.genesisTimestamp,
); !valid {
log.Debugf("Block failed validity conditions: %v", err)
continue
}

View File

@ -13,7 +13,6 @@ go_library(
"//proto/beacon/rpc/v1:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//event:go_default_library",
"@com_github_golang_protobuf//ptypes:go_default_library_gen",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_bazel_rules_go//proto/wkt:empty_go_proto",
"@org_golang_google_grpc//:go_default_library",

View File

@ -11,7 +11,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/event"
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/empty"
"github.com/prysmaticlabs/prysm/beacon-chain/casper"
"github.com/prysmaticlabs/prysm/beacon-chain/params"
@ -46,6 +45,7 @@ type canonicalFetcher interface {
type chainService interface {
IncomingBlockFeed() *event.Feed
CurrentCrystallizedState() *types.CrystallizedState
GenesisBlock() (*types.Block, error)
}
type attestationService interface {
@ -178,8 +178,12 @@ func (s *Service) CurrentAssignmentsAndGenesisTime(ctx context.Context, req *pb.
// This error is safe to ignore as we are initializing a proto timestamp
// from a constant value (genesis time is constant in the protocol
// and defined in the params.GetConfig().package).
// #nosec G104
protoGenesis, _ := ptypes.TimestampProto(params.GetConfig().GenesisTime)
// Get the genesis timestamp from persistent storage.
genesis, err := s.chainService.GenesisBlock()
if err != nil {
return nil, fmt.Errorf("could not get genesis block: %v", err)
}
cState := s.chainService.CurrentCrystallizedState()
var keys []*pb.PublicKey
if req.AllValidators {
@ -198,7 +202,7 @@ func (s *Service) CurrentAssignmentsAndGenesisTime(ctx context.Context, req *pb.
}
return &pb.CurrentAssignmentsResponse{
GenesisTimestamp: protoGenesis,
GenesisTimestamp: genesis.Proto().GetTimestamp(),
Assignments: assignments,
}, nil
}

View File

@ -50,6 +50,10 @@ func (f *faultyChainService) CanonicalCrystallizedStateFeed() *event.Feed {
return nil
}
func (f *faultyChainService) GenesisBlock() (*types.Block, error) {
return nil, errors.New("failed")
}
type mockChainService struct {
blockFeed *event.Feed
stateFeed *event.Feed
@ -96,6 +100,10 @@ func (m *mockChainService) CanonicalCrystallizedState() *types.CrystallizedState
return types.NewCrystallizedState(data)
}
func (m *mockChainService) GenesisBlock() (*types.Block, error) {
return types.NewGenesisBlock([32]byte{}, [32]byte{}), nil
}
func newMockChainService() *mockChainService {
return &mockChainService{
blockFeed: new(event.Feed),

View File

@ -138,9 +138,9 @@ func (b *Block) Timestamp() (time.Time, error) {
}
// isSlotValid compares the slot to the system clock to determine if the block is valid.
func (b *Block) isSlotValid() bool {
func (b *Block) isSlotValid(genesisTimestamp time.Time) bool {
slotDuration := time.Duration(b.SlotNumber()*params.GetConfig().SlotDuration) * time.Second
validTimeThreshold := params.GetConfig().GenesisTime.Add(slotDuration)
validTimeThreshold := genesisTimestamp.Add(slotDuration)
return clock.Now().After(validTimeThreshold)
}
@ -152,7 +152,8 @@ func (b *Block) IsValid(
aState *ActiveState,
cState *CrystallizedState,
parentSlot uint64,
enableAttestationValidity bool) bool {
enableAttestationValidity bool,
genesisTimestamp time.Time) bool {
_, err := b.Hash()
if err != nil {
log.Errorf("Could not hash incoming block: %v", err)
@ -164,7 +165,7 @@ func (b *Block) IsValid(
return false
}
if !b.isSlotValid() {
if !b.isSlotValid(genesisTimestamp) {
log.Errorf("Slot of block is too high: %d", b.SlotNumber())
return false
}

View File

@ -107,10 +107,11 @@ func TestBlockValidity(t *testing.T) {
t.Fatalf("failed attestation validation")
}
if !b.IsValid(chainService, aState, cState, parentSlot, false) {
genesisTime := params.GetConfig().GenesisTime
if !b.IsValid(chainService, aState, cState, parentSlot, false, genesisTime) {
t.Fatalf("failed block validation")
}
if !b.IsValid(chainService, aState, cState, parentSlot, true) {
if !b.IsValid(chainService, aState, cState, parentSlot, true, genesisTime) {
t.Fatalf("failed block validation")
}
}