Merge pull request #7647 from yyforyongyu/skip-checkpoint-resolver

contractcourt: skip checkpoint htlc outgoing resolver if it's resolved
This commit is contained in:
Olaoluwa Osuntokun 2023-04-28 14:01:14 -05:00 committed by GitHub
commit 33047e69d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 8 deletions

View File

@ -1132,19 +1132,27 @@ func (c *ChannelArbitrator) stateStep(
log.Infof("ChannelArbitrator(%v): still awaiting contract "+
"resolution", c.cfg.ChanPoint)
numUnresolved, err := c.log.FetchUnresolvedContracts()
unresolved, err := c.log.FetchUnresolvedContracts()
if err != nil {
return StateError, closeTx, err
}
// If we still have unresolved contracts, then we'll stay alive
// to oversee their resolution.
if len(numUnresolved) != 0 {
nextState = StateWaitingFullResolution
// If we have no unresolved contracts, then we can move to the
// final state.
if len(unresolved) == 0 {
nextState = StateFullyResolved
break
}
nextState = StateFullyResolved
// Otherwise we still have unresolved contracts, then we'll
// stay alive to oversee their resolution.
nextState = StateWaitingFullResolution
// Add debug logs.
for _, r := range unresolved {
log.Debugf("ChannelArbitrator(%v): still have "+
"unresolved contract: %T", c.cfg.ChanPoint, r)
}
// If we start as fully resolved, then we'll end as fully resolved.
case StateFullyResolved:

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.