From 6ac809059983fd6b1cdf747184e9e1557f270250 Mon Sep 17 00:00:00 2001 From: Potuz Date: Fri, 18 Oct 2024 12:51:58 -0300 Subject: [PATCH] rollback on SaveState error (#14555) * rollback on SaveState error * add test --- CHANGELOG.md | 2 ++ beacon-chain/blockchain/process_block.go | 4 ++++ beacon-chain/blockchain/receive_block.go | 3 +++ beacon-chain/blockchain/receive_block_test.go | 2 ++ 4 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a01a870a659d..aa7c18cb6b35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Fix `engine_exchangeCapabilities` implementation. - Updated the default `scrape-interval` in `Client-stats` to 2 minutes to accommodate Beaconcha.in API rate limits. - Switch to compounding when consolidating with source==target. +- Revert block db save when saving state fails. +- Return false from HasBlock if the block is being synced. ### Deprecated diff --git a/beacon-chain/blockchain/process_block.go b/beacon-chain/blockchain/process_block.go index 425da163ecd0..d7dd6e8057e5 100644 --- a/beacon-chain/blockchain/process_block.go +++ b/beacon-chain/blockchain/process_block.go @@ -404,6 +404,10 @@ func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interface return errors.Wrapf(err, "could not save block from slot %d", b.Block().Slot()) } if err := s.cfg.StateGen.SaveState(ctx, r, st); err != nil { + log.Warnf("Rolling back insertion of block with root %#x", r) + if err := s.cfg.BeaconDB.DeleteBlock(ctx, r); err != nil { + log.WithError(err).Errorf("Could not delete block with block root %#x", r) + } return errors.Wrap(err, "could not save state") } return nil diff --git a/beacon-chain/blockchain/receive_block.go b/beacon-chain/blockchain/receive_block.go index 241c0ca9ced9..45543f9cee86 100644 --- a/beacon-chain/blockchain/receive_block.go +++ b/beacon-chain/blockchain/receive_block.go @@ -349,6 +349,9 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []blocks.ROBlock // HasBlock returns true if the block of the input root exists in initial sync blocks cache or DB. func (s *Service) HasBlock(ctx context.Context, root [32]byte) bool { + if s.BlockBeingSynced(root) { + return false + } return s.hasBlockInInitSyncOrDB(ctx, root) } diff --git a/beacon-chain/blockchain/receive_block_test.go b/beacon-chain/blockchain/receive_block_test.go index 1fdcb196e450..d8d36051a013 100644 --- a/beacon-chain/blockchain/receive_block_test.go +++ b/beacon-chain/blockchain/receive_block_test.go @@ -278,6 +278,8 @@ func TestService_HasBlock(t *testing.T) { r, err = b.Block.HashTreeRoot() require.NoError(t, err) require.Equal(t, true, s.HasBlock(context.Background(), r)) + s.blockBeingSynced.set(r) + require.Equal(t, false, s.HasBlock(context.Background(), r)) } func TestCheckSaveHotStateDB_Enabling(t *testing.T) {