Merge pull request #3480 from Roasbeef/proper-resolution-supplements

contractcourt: supplement resolvers with confirmed commit set HTLCs
This commit is contained in:
Olaoluwa Osuntokun 2019-09-25 17:08:35 -07:00 committed by GitHub
commit c57bb9d86b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 369 additions and 225 deletions

View File

@ -45,6 +45,16 @@ linters:
# trigger funlen problems that we may not want to solve at that time.
- funlen
# Disable for now as we haven't yet tuned the sensitivity to our codebase
# yet. Enabling by default for example, would also force new contributors to
# potentially extensively refactor code, when they want to smaller change to
# land.
- gocyclo
# Instances of table driven tests that don't pre-allocate shouldn't trigger
# the linter.
- prealloc
issues:
# Only show newly introduced problems.
new-from-rev: 01f696afce2f9c0d4ed854edefa3846891d01d8a

View File

@ -415,7 +415,19 @@ func (c *ChannelArbitrator) Start() error {
if startingState == StateWaitingFullResolution &&
nextState == StateWaitingFullResolution {
if err := c.relaunchResolvers(); err != nil {
// In order to relaunch the resolvers, we'll need to fetch the
// set of HTLCs that were present in the commitment transaction
// at the time it was confirmed. commitSet.ConfCommitKey can't
// be nil at this point since we're in
// StateWaitingFullResolution. We can only be in
// StateWaitingFullResolution after we've transitioned from
// StateContractClosed which can only be triggered by the local
// or remote close trigger. This trigger is only fired when we
// receive a chain event from the chain watcher than the
// commitment has been confirmed on chain, and before we
// advance our state step, we call InsertConfirmedCommitSet.
confCommitSet := commitSet.HtlcSets[*commitSet.ConfCommitKey]
if err := c.relaunchResolvers(confCommitSet); err != nil {
c.cfg.BlockEpochs.Cancel()
return err
}
@ -431,7 +443,7 @@ func (c *ChannelArbitrator) Start() error {
// starting the ChannelArbitrator. This information should ideally be stored in
// the database, so this only serves as a intermediate work-around to prevent a
// migration.
func (c *ChannelArbitrator) relaunchResolvers() error {
func (c *ChannelArbitrator) relaunchResolvers(confirmedHTLCs []channeldb.HTLC) error {
// We'll now query our log to see if there are any active
// unresolved contracts. If this is the case, then we'll
// relaunch all contract resolvers.
@ -456,31 +468,22 @@ func (c *ChannelArbitrator) relaunchResolvers() error {
// to prevent a db migration. We use all available htlc sets here in
// order to ensure we have complete coverage.
htlcMap := make(map[wire.OutPoint]*channeldb.HTLC)
for _, htlcs := range c.activeHTLCs {
for _, htlc := range htlcs.incomingHTLCs {
htlc := htlc
outpoint := wire.OutPoint{
Hash: commitHash,
Index: uint32(htlc.OutputIndex),
}
htlcMap[outpoint] = &htlc
}
for _, htlc := range htlcs.outgoingHTLCs {
htlc := htlc
outpoint := wire.OutPoint{
Hash: commitHash,
Index: uint32(htlc.OutputIndex),
}
htlcMap[outpoint] = &htlc
for _, htlc := range confirmedHTLCs {
htlc := htlc
outpoint := wire.OutPoint{
Hash: commitHash,
Index: uint32(htlc.OutputIndex),
}
htlcMap[outpoint] = &htlc
}
log.Infof("ChannelArbitrator(%v): relaunching %v contract "+
"resolvers", c.cfg.ChanPoint, len(unresolvedContracts))
for _, resolver := range unresolvedContracts {
c.supplementResolver(resolver, htlcMap)
if err := c.supplementResolver(resolver, htlcMap); err != nil {
return err
}
}
c.launchResolvers(unresolvedContracts)

File diff suppressed because it is too large Load Diff