contractcourt: skip checkpoint timeout resolver upon mempool spend

Previously when a block spend is found for the outpoint, our htlc
timeout resolver will do a checkpoint, which implicitly creates a db
record if there isn't one. Now, if the spend is found in mempool,
the resolver will be deleted once the contract is resolved. Later on
when the spend is found in the block again, the resolver will be created
again, but never gets resolved this time.
This commit is contained in:
yyforyongyu 2023-04-28 20:23:57 +08:00
parent 56dcda0f7c
commit 186569c610
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868

View File

@ -822,6 +822,12 @@ func (h *htlcTimeoutResolver) consumeSpendEvents(resultChan chan *spendResult,
// Create a result chan to hold the results.
result := &spendResult{}
// hasMempoolSpend is a flag that indicates whether we have found a
// preimage spend from the mempool. This is used to determine whether
// to checkpoint the resolver or not when later we found the
// corresponding block spend.
hasMempoolSpent := false
// Wait for a spend event to arrive.
for {
select {
@ -846,8 +852,26 @@ func (h *htlcTimeoutResolver) consumeSpendEvents(resultChan chan *spendResult,
result.spend = spendDetail
// Once confirmed, persist the state on disk.
result.err = h.checkPointSecondLevelTx()
// Once confirmed, persist the state on disk if
// we haven't seen the output's spending tx in
// mempool before.
//
// NOTE: we don't checkpoint the resolver if
// it's spending tx has already been found in
// mempool - the resolver will take care of the
// checkpoint in its `claimCleanUp`. If we do
// checkpoint here, however, we'd create a new
// record in db for the same htlc resolver
// which won't be cleaned up later, resulting
// the channel to stay in unresolved state.
//
// TODO(yy): when fee bumper is implemented, we
// need to further check whether this is a
// preimage spend. Also need to refactor here
// to save us some indentation.
if !hasMempoolSpent {
result.err = h.checkPointSecondLevelTx()
}
}
// Send the result and exit the loop.
@ -894,6 +918,10 @@ func (h *htlcTimeoutResolver) consumeSpendEvents(resultChan chan *spendResult,
result.spend = spendDetail
resultChan <- result
// Set the hasMempoolSpent flag to true so we won't
// checkpoint the resolver again in db.
hasMempoolSpent = true
continue
// If the resolver exits, we exit the goroutine.