@@ -265,8 +265,15 @@ func (db *Database) Close() error {
265265 p .Lock ()
266266 defer p .Unlock ()
267267
268- // All remaining proposals must be dereferenced.
269- p .possible = nil
268+ if p .tree == nil {
269+ return nil // already closed
270+ }
271+
272+ // All remaining proposals can explicitly be dropped.
273+ p .cleanupPossible (nil )
274+ for _ , child := range p .tree .children {
275+ p .removeProposalAndChildren (child )
276+ }
270277 p .byStateRoot = nil
271278 p .tree = nil
272279
@@ -297,6 +304,7 @@ func (db *Database) Update(root, parent common.Hash, height uint64, _ *trienode.
297304 }
298305
299306 p , ok := db .proposals .findUnverified (height , parentBlockHash )
307+ defer db .proposals .cleanupPossible (p )
300308 if ! ok {
301309 return fmt .Errorf ("firewood: no unverified proposal found for block %d, root %s, hash %s" , height , root .Hex (), blockHash .Hex ())
302310 }
@@ -350,26 +358,46 @@ func (ps *proposals) exists(root, block, parentBlock common.Hash) bool {
350358}
351359
352360func (ps * proposals ) findUnverified (height uint64 , parentBlock common.Hash ) (* proposal , bool ) {
361+ // First, try to find a proposal with the correct parent block hash.
353362 p , ok := find (ps .possible , func (p * proposal ) bool {
354363 _ , ok := p .parent .blockHashes [parentBlock ]
355364 return ok
356365 })
357- if ok { // note positive boolean
366+ // The exact proposal was found.
367+ if ok {
358368 return p , true
359369 }
360370
371+ // Otherwise, this may be the first block after startup, and the parent hash wasn't recorded.
361372 p , ok = find (ps .possible , func (p * proposal ) bool {
362373 _ , ok := p .parent .blockHashes [common.Hash {}]
363374 return ok
364375 })
365- if ! ok { // note negative boolean
376+ if ! ok {
377+ // No suitable proposal found.
366378 return nil , false
367379 }
380+
381+ // For clarity, while using this proposal, we should update the meta.
368382 p .proposalMeta .height = height
369383 p .proposalMeta .parent .blockHashes [parentBlock ] = struct {}{}
370384 return p , true
371385}
372386
387+ // cleanupPossible drops all possible proposals except the given one.
388+ // If nil, all possible proposals are dropped.
389+ func (ps * proposals ) cleanupPossible (p * proposal ) {
390+ for _ , candidate := range ps .possible {
391+ if candidate == p {
392+ continue
393+ }
394+ if err := candidate .handle .Drop (); err != nil {
395+ log .Error ("error dropping proposal" , "root" , candidate .root , "height" , candidate .height , "err" , err )
396+ }
397+ }
398+ ps .possible = nil
399+ }
400+
373401// find is equivalent to [slices.IndexFunc], returning the element instead of
374402// the index. The returned boolean indicates whether a suitable element was
375403// found.
@@ -490,7 +518,7 @@ func (ps *proposals) cleanupCommittedProposal(p *proposal) {
490518 ps .tree .parent = nil
491519 ps .tree .handle = nil
492520
493- ps .removeProposalFromMap (p .proposalMeta )
521+ ps .removeProposalFromMap (p .proposalMeta , false )
494522
495523 for _ , child := range oldChildren {
496524 if child != p .proposalMeta {
@@ -509,18 +537,24 @@ func (ps *proposals) removeProposalAndChildren(p *proposalMeta) {
509537 }
510538
511539 // Remove the proposal from the map.
512- ps .removeProposalFromMap (p )
540+ ps .removeProposalFromMap (p , true )
513541}
514542
515543// removeProposalFromMap removes the proposal from the proposal map.
516544// The proposal lock must be held when calling this function.
517- func (ps * proposals ) removeProposalFromMap (meta * proposalMeta ) {
545+ func (ps * proposals ) removeProposalFromMap (meta * proposalMeta , drop bool ) {
518546 rootList := ps .byStateRoot [meta .root ]
519547 for i , p := range rootList {
520548 if p .proposalMeta == meta { // pointer comparison - guaranteed to be unique
521549 rootList [i ] = rootList [len (rootList )- 1 ]
522550 rootList [len (rootList )- 1 ] = nil
523551 rootList = rootList [:len (rootList )- 1 ]
552+
553+ if drop {
554+ if err := p .handle .Drop (); err != nil {
555+ log .Error ("error dropping proposal" , "root" , meta .root , "height" , meta .height , "err" , err )
556+ }
557+ }
524558 break
525559 }
526560 }
0 commit comments