diff --git a/beacon-chain/blockchain/process_block_helpers.go b/beacon-chain/blockchain/process_block_helpers.go index 6623c5e0a9..47c4dfe88e 100644 --- a/beacon-chain/blockchain/process_block_helpers.go +++ b/beacon-chain/blockchain/process_block_helpers.go @@ -234,15 +234,19 @@ func (s *Service) insertFinalizedDeposits(ctx context.Context, fRoot [32]byte) { // The deposit index in the state is always the index of the next deposit // to be included(rather than the last one to be processed). This was most likely // done as the state cannot represent signed integers. - eth1DepositIndex -= 1 - if err = s.cfg.DepositCache.InsertFinalizedDeposits(ctx, int64(eth1DepositIndex)); err != nil { + finalizedEth1DepIdx := eth1DepositIndex - 1 + if err = s.cfg.DepositCache.InsertFinalizedDeposits(ctx, int64(finalizedEth1DepIdx)); err != nil { log.WithError(err).Error("could not insert finalized deposits") return } // Deposit proofs are only used during state transition and can be safely removed to save space. - if err = s.cfg.DepositCache.PruneProofs(ctx, int64(eth1DepositIndex)); err != nil { + if err = s.cfg.DepositCache.PruneProofs(ctx, int64(finalizedEth1DepIdx)); err != nil { log.WithError(err).Error("could not prune deposit proofs") } + // Prune deposits which have already been finalized, the below method prunes all pending deposits (non-inclusive) up + // to the provided eth1 deposit index. + s.cfg.DepositCache.PrunePendingDeposits(ctx, int64(eth1DepositIndex)) // lint:ignore uintcast -- Deposit index should not exceed int64 in your lifetime. + log.WithField("duration", time.Since(startTime).String()).Debug("Finalized deposit insertion completed") } diff --git a/beacon-chain/blockchain/process_block_test.go b/beacon-chain/blockchain/process_block_test.go index 1cc3d1aacd..a4c7a1f8bd 100644 --- a/beacon-chain/blockchain/process_block_test.go +++ b/beacon-chain/blockchain/process_block_test.go @@ -726,6 +726,45 @@ func TestInsertFinalizedDeposits(t *testing.T) { } } +func TestInsertFinalizedDeposits_PrunePendingDeposits(t *testing.T) { + service, tr := minimalTestService(t) + ctx, depositCache := tr.ctx, tr.dc + + gs, _ := util.DeterministicGenesisState(t, 32) + require.NoError(t, service.saveGenesisData(ctx, gs)) + gs = gs.Copy() + assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 10})) + assert.NoError(t, gs.SetEth1DepositIndex(8)) + assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs)) + var zeroSig [96]byte + for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ { + root := []byte(strconv.Itoa(int(i))) + assert.NoError(t, depositCache.InsertDeposit(ctx, ðpb.Deposit{Data: ðpb.Deposit_Data{ + PublicKey: bytesutil.FromBytes48([fieldparams.BLSPubkeyLength]byte{}), + WithdrawalCredentials: params.BeaconConfig().ZeroHash[:], + Amount: 0, + Signature: zeroSig[:], + }, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root))) + depositCache.InsertPendingDeposit(ctx, ðpb.Deposit{Data: ðpb.Deposit_Data{ + PublicKey: bytesutil.FromBytes48([fieldparams.BLSPubkeyLength]byte{}), + WithdrawalCredentials: params.BeaconConfig().ZeroHash[:], + Amount: 0, + Signature: zeroSig[:], + }, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root)) + } + service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}) + fDeposits := depositCache.FinalizedDeposits(ctx) + assert.Equal(t, 7, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly") + deps := depositCache.AllDeposits(ctx, big.NewInt(107)) + for _, d := range deps { + assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty") + } + pendingDeps := depositCache.PendingContainers(ctx, nil) + for _, d := range pendingDeps { + assert.DeepEqual(t, true, d.Index >= 8, "Pending deposits were not pruned") + } +} + func TestInsertFinalizedDeposits_MultipleFinalizedRoutines(t *testing.T) { service, tr := minimalTestService(t) ctx, depositCache := tr.ctx, tr.dc