@@ -271,14 +271,6 @@ type addSweepsRequest struct {
271271	// Notifier is a notifier that is used to notify the requester of this 
272272	// sweep that the sweep was successful. 
273273	notifier  * SpendNotifier 
274- 
275- 	// completed is set if the sweep is spent and the spending transaction 
276- 	// is reorg-safely confirmed. 
277- 	completed  bool 
278- 
279- 	// parentBatch is the parent batch of this sweep. It is loaded ony if 
280- 	// completed is true. 
281- 	parentBatch  * dbBatch 
282274}
283275
284276// SpendDetail is a notification that is send to the user of sweepbatcher when 
@@ -687,10 +679,7 @@ func (b *Batcher) Run(ctx context.Context) error {
687679	for  {
688680		select  {
689681		case  req  :=  <- b .addSweepsChan :
690- 			err  =  b .handleSweeps (
691- 				runCtx , req .sweeps , req .notifier , req .completed ,
692- 				req .parentBatch ,
693- 			)
682+ 			err  =  b .handleSweeps (runCtx , req .sweeps , req .notifier )
694683			if  err  !=  nil  {
695684				warnf ("handleSweeps failed: %v." , err )
696685
@@ -803,15 +792,12 @@ func (b *Batcher) AddSweep(ctx context.Context, sweepReq *SweepRequest) error {
803792		return  fmt .Errorf ("failed to get the status of sweep %v: %w" ,
804793			sweep .outpoint , err )
805794	}
806- 	var  (
807- 		parentBatch     * dbBatch 
808- 		fullyConfirmed  bool 
809- 	)
795+ 	var  fullyConfirmed  bool 
810796	if  completed  {
811797		// Verify that the parent batch is confirmed. Note that a batch 
812798		// is only considered confirmed after it has received three 
813799		// on-chain confirmations to prevent issues caused by reorgs. 
814- 		parentBatch , err  =  b .store .GetParentBatch (ctx , sweep .outpoint )
800+ 		parentBatch , err  : =  b .store .GetParentBatch (ctx , sweep .outpoint )
815801		if  err  !=  nil  {
816802			return  fmt .Errorf ("unable to get parent batch for " + 
817803				"sweep %x: %w" , sweep .swapHash [:6 ], err )
@@ -847,10 +833,8 @@ func (b *Batcher) AddSweep(ctx context.Context, sweepReq *SweepRequest) error {
847833		sweep .swapHash [:6 ], sweep .presigned , completed )
848834
849835	req  :=  & addSweepsRequest {
850- 		sweeps :      sweeps ,
851- 		notifier :    sweepReq .Notifier ,
852- 		completed :   completed ,
853- 		parentBatch : parentBatch ,
836+ 		sweeps :   sweeps ,
837+ 		notifier : sweepReq .Notifier ,
854838	}
855839
856840	select  {
@@ -895,33 +879,17 @@ func (b *Batcher) testRunInEventLoop(ctx context.Context, handler func()) {
895879// handleSweeps handles a sweep request by either placing the group of sweeps in 
896880// an existing batch, or by spinning up a new batch for it. 
897881func  (b  * Batcher ) handleSweeps (ctx  context.Context , sweeps  []* sweep ,
898- 	notifier  * SpendNotifier ,  completed   bool ,  parentBatch   * dbBatch ) error  {
882+ 	notifier  * SpendNotifier ) error  {
899883
900884	// Since the whole group is added to the same batch and belongs to 
901885	// the same transaction, we use sweeps[0] below where we need any sweep. 
902886	sweep  :=  sweeps [0 ]
903887
904- 	// If the sweep has already been completed in a confirmed batch then we 
905- 	// can't attach its notifier to the batch as that is no longer running. 
906- 	// Instead we directly detect and return the spend here. 
907- 	if  completed  &&  parentBatch .Confirmed  {
908- 		return  b .monitorSpendAndNotify (
909- 			ctx , sweeps , parentBatch .ID , notifier ,
910- 		)
911- 	}
912- 
913888	sweep .notifier  =  notifier 
914889
915- 	// This is a check to see if a batch is completed. In that case we just 
916- 	// lazily delete it. 
917- 	for  _ , batch  :=  range  b .batches  {
918- 		if  batch .isComplete () {
919- 			delete (b .batches , batch .id )
920- 		}
921- 	}
922- 
923890	// Check if the sweep is already in a batch. If that is the case, we 
924891	// provide the sweep to that batch and return. 
892+ 	readded  :=  false 
925893	for  _ , batch  :=  range  b .batches  {
926894		if  batch .sweepExists (sweep .outpoint ) {
927895			accepted , err  :=  batch .addSweeps (ctx , sweeps )
@@ -936,12 +904,72 @@ func (b *Batcher) handleSweeps(ctx context.Context, sweeps []*sweep,
936904			}
937905
938906			// The sweep was updated in the batch, our job is done. 
939- 			return  nil 
907+ 			readded  =  true 
908+ 			break 
909+ 		}
910+ 	}
911+ 
912+ 	// Check whether any batch is already completed and lazily delete it. Do 
913+ 	// this after attempting the re-add so we do not remove the batch that 
914+ 	// would have accepted the sweep again; otherwise we could miss the 
915+ 	// re-addition and spin up a new batch for an already finished sweep. 
916+ 	for  _ , batch  :=  range  b .batches  {
917+ 		if  batch .isComplete () {
918+ 			delete (b .batches , batch .id )
919+ 		}
920+ 	}
921+ 
922+ 	// If the batch was re-added to an existing batch, our job is done. 
923+ 	if  readded  {
924+ 		return  nil 
925+ 	}
926+ 
927+ 	// If the sweep has already been completed in a confirmed batch then we 
928+ 	// can't attach its notifier to the batch as that is no longer running. 
929+ 	// Instead we directly detect and return the spend here. We cannot reuse 
930+ 	// the values gathered in AddSweep because the sweep status may change in 
931+ 	// the meantime. If the status flips while handleSweeps is running, the 
932+ 	// re-add path above will handle it. A batch is removed from b.batches 
933+ 	// only after the code below finds the sweep fully confirmed and switches 
934+ 	// to the monitorSpendAndNotify path. 
935+ 	completed , err  :=  b .store .GetSweepStatus (ctx , sweep .outpoint )
936+ 	if  err  !=  nil  {
937+ 		return  fmt .Errorf ("failed to get the status of sweep %v: %w" ,
938+ 			sweep .outpoint , err )
939+ 	}
940+ 	debugf ("Status of the sweep group of %d sweeps with primarySweep %x: " + 
941+ 		"presigned=%v, fully_confirmed=%v" , len (sweeps ),
942+ 		sweep .swapHash [:6 ], sweep .presigned , completed )
943+ 	if  completed  {
944+ 		// Verify that the parent batch is confirmed. Note that a batch 
945+ 		// is only considered confirmed after it has received three 
946+ 		// on-chain confirmations to prevent issues caused by reorgs. 
947+ 		parentBatch , err  :=  b .store .GetParentBatch (ctx , sweep .outpoint )
948+ 		if  err  !=  nil  {
949+ 			return  fmt .Errorf ("unable to get parent batch for " + 
950+ 				"sweep %x: %w" , sweep .swapHash [:6 ], err )
951+ 		}
952+ 
953+ 		debugf ("Status of the parent batch of the sweep group of %d " + 
954+ 			"sweeps with primarySweep %x: confirmed=%v" ,
955+ 			len (sweeps ), sweep .swapHash [:6 ], parentBatch .Confirmed )
956+ 
957+ 		// Note that sweeps are marked completed after the batch is 
958+ 		// marked confirmed because here we check the sweep status 
959+ 		// first and then check the batch status. 
960+ 		if  parentBatch .Confirmed  {
961+ 			debugf ("Sweep group of %d sweeps with primarySweep %x " + 
962+ 				"is fully confirmed, switching directly to " + 
963+ 				"monitoring" , len (sweeps ), sweep .swapHash [:6 ])
964+ 
965+ 			return  b .monitorSpendAndNotify (
966+ 				ctx , sweeps , parentBatch .ID , notifier ,
967+ 			)
940968		}
941969	}
942970
943971	// Try to run the greedy algorithm of batch selection to minimize costs. 
944- 	err  : =  b .greedyAddSweeps (ctx , sweeps )
972+ 	err  =  b .greedyAddSweeps (ctx , sweeps )
945973	if  err  ==  nil  {
946974		// The greedy algorithm succeeded. 
947975		return  nil 
0 commit comments