Skip to content

Commit

Permalink
contractcourt: fix race access to c.activeResolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
yyforyongyu committed Nov 18, 2024
1 parent 3b959b0 commit 2bdbe76
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions contractcourt/channel_arbitrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,11 +811,8 @@ func (c *ChannelArbitrator) relaunchResolvers(commitSet *CommitSet,

// Report returns htlc reports for the active resolvers.
func (c *ChannelArbitrator) Report() []*ContractReport {
c.activeResolversLock.RLock()
defer c.activeResolversLock.RUnlock()

var reports []*ContractReport
for _, resolver := range c.activeResolvers {
for _, resolver := range c.resolvers() {
r, ok := resolver.(reportingContractResolver)
if !ok {
continue
Expand Down Expand Up @@ -1569,26 +1566,23 @@ func (c *ChannelArbitrator) findCommitmentDeadlineAndValue(heightHint uint32,
// resolveContracts updates the activeResolvers list and starts to resolve each
// contract concurrently, and launches them.
func (c *ChannelArbitrator) resolveContracts(resolvers []ContractResolver) {
// Update the active contract resolvers.
c.activeResolversLock.Lock()
c.activeResolvers = resolvers
c.activeResolversLock.Unlock()

// Launch all resolvers.
c.launchResolvers()

for _, contract := range resolvers {
for _, contract := range c.resolvers() {
c.wg.Add(1)
go c.resolveContract(contract)
}
}

// launchResolvers launches all the active resolvers.
func (c *ChannelArbitrator) launchResolvers() {
c.activeResolversLock.Lock()
resolvers := c.activeResolvers
c.activeResolversLock.Unlock()

for _, contract := range resolvers {
for _, contract := range c.resolvers() {
// If the contract is already resolved, there's no need to
// launch it again.
if contract.IsResolved() {
Expand Down Expand Up @@ -3426,3 +3420,14 @@ func (c *ChannelArbitrator) abandonForwards(htlcs fn.Set[uint64]) error {

return nil
}

// resolvers returns a copy of the active resolvers.
func (c *ChannelArbitrator) resolvers() []ContractResolver {
c.activeResolversLock.Lock()
defer c.activeResolversLock.Unlock()

resolvers := make([]ContractResolver, 0, len(c.activeResolvers))
resolvers = append(resolvers, c.activeResolvers...)

return resolvers
}

0 comments on commit 2bdbe76

Please sign in to comment.