Update justified point for batch sync (#6594)

* Update justified points
* Add the same check to on block init sync
* Add comments
* Add test
* Gaz
* Merge branch 'master' into fix-batch-sync
* Merge refs/heads/master into fix-batch-sync
This commit is contained in:
terence tsao
2020-07-14 09:20:25 -07:00
committed by GitHub
parent 8fda48409c
commit ea32af7bf7
4 changed files with 72 additions and 2 deletions

View File

@@ -98,6 +98,7 @@ go_test(
"//shared/event:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/assert:go_default_library",
"@com_github_ethereum_go_ethereum//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",

View File

@@ -166,6 +166,12 @@ func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed
s.clearInitSyncBlocks()
}
if postState.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
if err := s.updateJustifiedInitSync(ctx, postState.CurrentJustifiedCheckpoint()); err != nil {
return err
}
}
// Update finalized check point. Prune the block cache and helper caches on every new finalized epoch.
if postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch {
if err := s.updateFinalized(ctx, postState.FinalizedCheckpoint()); err != nil {
@@ -258,6 +264,12 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb
s.clearInitSyncBlocks()
}
if jCheckpoint.Epoch > s.justifiedCheckpt.Epoch {
if err := s.updateJustifiedInitSync(ctx, jCheckpoint); err != nil {
return err
}
}
// Update finalized check point. Prune the block cache and helper caches on every new finalized epoch.
if fCheckpoint.Epoch > s.finalizedCheckpt.Epoch {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {

View File

@@ -101,7 +101,6 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
return errors.New("nil finalized block")
}
finalizedBlk := finalizedBlkSigned.Block
bFinalizedRoot, err := s.ancestor(ctx, root[:], finalizedBlk.Slot)
if err != nil {
return errors.Wrap(err, "could not get finalized block root")
@@ -203,6 +202,19 @@ func (s *Service) updateJustified(ctx context.Context, state *stateTrie.BeaconSt
return s.beaconDB.SaveJustifiedCheckpoint(ctx, cpt)
}
// This caches input checkpoint as justified for the service struct. It rotates current justified to previous justified,
// caches justified checkpoint balances for fork choice and save justified checkpoint in DB.
// This method does not have defense against fork choice bouncing attack, which is why it's only recommend to be used during initial syncing.
func (s *Service) updateJustifiedInitSync(ctx context.Context, cp *ethpb.Checkpoint) error {
s.prevJustifiedCheckpt = s.justifiedCheckpt
s.justifiedCheckpt = cp
if err := s.cacheJustifiedStateBalances(ctx, bytesutil.ToBytes32(s.justifiedCheckpt.Root)); err != nil {
return err
}
return s.beaconDB.SaveJustifiedCheckpoint(ctx, cp)
}
func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) error {
// Blocks need to be saved so that we can retrieve finalized block from
// DB when migrating states.
@@ -256,7 +268,6 @@ func (s *Service) ancestor(ctx context.Context, root []byte, slot uint64) ([]byt
return nil, errors.New("nil block")
}
b := signed.Block
if b.Slot == slot || b.Slot < slot {
return root, nil
}

View File

@@ -24,6 +24,7 @@ import (
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
)
func TestStore_OnBlock(t *testing.T) {
@@ -864,3 +865,48 @@ func TestVerifyBlkDescendant(t *testing.T) {
}
}
}
func TestUpdateJustifiedInitSync(t *testing.T) {
db, _ := testDB.SetupDB(t)
ctx := context.Background()
cfg := &Config{BeaconDB: db}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
gBlk := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
gRoot, err := stateutil.BlockRoot(gBlk.Block)
if err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveBlock(ctx, gBlk); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveGenesisBlockRoot(ctx, gRoot); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: gRoot[:]}); err != nil {
t.Fatal(err)
}
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
if err := service.beaconDB.SaveState(ctx, beaconState, gRoot); err != nil {
t.Fatal(err)
}
service.genesisRoot = gRoot
currentCp := &ethpb.Checkpoint{Epoch: 1}
service.justifiedCheckpt = currentCp
newCp := &ethpb.Checkpoint{Epoch: 2, Root: gRoot[:]}
if err := service.updateJustifiedInitSync(ctx, newCp); err != nil {
t.Fatal(err)
}
assert.DeepEqual(t, currentCp, service.prevJustifiedCheckpt, "incorrect previous justified checkpoint")
assert.DeepEqual(t, newCp, service.CurrentJustifiedCheckpt(), "incorrect current justified checkpoint in cache")
cp, err := service.beaconDB.JustifiedCheckpoint(ctx)
if err != nil {
t.Fatal(err)
}
assert.DeepEqual(t, newCp, cp, "incorrect current justified checkpoint in db")
}