• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 17189880600

24 Aug 2025 02:23PM UTC coverage: 66.762% (+9.4%) from 57.321%
17189880600

Pull #9432

github

web-flow
Merge a4a00e732 into 0c2f045f5
Pull Request #9432: multi: add upfront-shutdown-address to lnd.conf.

31 of 39 new or added lines in 4 files covered. (79.49%)

22 existing lines in 8 files now uncovered.

136012 of 203728 relevant lines covered (66.76%)

21523.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.95
/chanacceptor/chainedacceptor.go
1
package chanacceptor
2

3
import (
4
        "sync"
5
        "sync/atomic"
6

7
        "github.com/btcsuite/btcd/chaincfg"
8
        "github.com/lightningnetwork/lnd/lnwallet/chancloser"
9
)
10

11
// ChainedAcceptor represents a conjunction of ChannelAcceptor results.
12
type ChainedAcceptor struct {
13
        acceptorID uint64 // To be used atomically.
14

15
        // An address to enforce payout of our funds to on cooperative close.
16
        closeAddress string
17

18
        // params are our current chain params.
19
        params *chaincfg.Params
20

21
        // acceptors is a map of ChannelAcceptors that will be evaluated when
22
        // the ChainedAcceptor's Accept method is called.
23
        acceptors    map[uint64]ChannelAcceptor
24
        acceptorsMtx sync.RWMutex
25
}
26

27
// NewChainedAcceptor initializes a ChainedAcceptor.
28
func NewChainedAcceptor() *ChainedAcceptor {
108✔
29
        return &ChainedAcceptor{
108✔
30
                acceptors: make(map[uint64]ChannelAcceptor),
108✔
31
        }
108✔
32
}
108✔
33

34
// NewChainedAcceptorWithOpts initializes a ChainedAcceptor with the given
35
// closeAddress and params.
36
func NewChainedAcceptorWithOpts(
37
        closeAddress string, params *chaincfg.Params) *ChainedAcceptor {
6✔
38

6✔
39
        return &ChainedAcceptor{
6✔
40
                acceptors:    make(map[uint64]ChannelAcceptor),
6✔
41
                closeAddress: closeAddress,
6✔
42
                params:       params,
6✔
43
        }
6✔
44
}
6✔
45

46
// AddAcceptor adds a ChannelAcceptor to this ChainedAcceptor.
47
//
48
// NOTE: Part of the MultiplexAcceptor interface.
49
func (c *ChainedAcceptor) AddAcceptor(acceptor ChannelAcceptor) uint64 {
7✔
50
        id := atomic.AddUint64(&c.acceptorID, 1)
7✔
51

7✔
52
        c.acceptorsMtx.Lock()
7✔
53
        c.acceptors[id] = acceptor
7✔
54
        c.acceptorsMtx.Unlock()
7✔
55

7✔
56
        // Return the id so that a caller can call RemoveAcceptor.
7✔
57
        return id
7✔
58
}
7✔
59

60
// RemoveAcceptor removes a ChannelAcceptor from this ChainedAcceptor given
61
// an ID.
62
//
63
// NOTE: Part of the MultiplexAcceptor interface.
64
func (c *ChainedAcceptor) RemoveAcceptor(id uint64) {
7✔
65
        c.acceptorsMtx.Lock()
7✔
66
        delete(c.acceptors, id)
7✔
67
        c.acceptorsMtx.Unlock()
7✔
68
}
7✔
69

70
// numAcceptors returns the number of acceptors contained in the
71
// ChainedAcceptor.
72
func (c *ChainedAcceptor) numAcceptors() int {
9✔
73
        c.acceptorsMtx.RLock()
9✔
74
        defer c.acceptorsMtx.RUnlock()
9✔
75
        return len(c.acceptors)
9✔
76
}
9✔
77

78
// Accept evaluates the results of all ChannelAcceptors in the acceptors map
79
// and returns the conjunction of all these predicates.
80
//
81
// NOTE: Part of the ChannelAcceptor interface.
82
func (c *ChainedAcceptor) Accept(req *ChannelAcceptRequest) *ChannelAcceptResponse {
58✔
83
        c.acceptorsMtx.RLock()
58✔
84
        defer c.acceptorsMtx.RUnlock()
58✔
85

58✔
86
        var finalResp ChannelAcceptResponse
58✔
87

58✔
88
        for _, acceptor := range c.acceptors {
65✔
89
                // Call our acceptor to determine whether we want to accept this
7✔
90
                // channel.
7✔
91
                acceptorResponse := acceptor.Accept(req)
7✔
92

7✔
93
                // If we should reject the channel, we can just exit early. This
7✔
94
                // has the effect of returning the error belonging to our first
7✔
95
                // failed acceptor.
7✔
96
                if acceptorResponse.RejectChannel() {
10✔
97
                        return acceptorResponse
3✔
98
                }
3✔
99

100
                // If we have accepted the channel, we need to set the other
101
                // fields that were set in the response. However, since we are
102
                // dealing with multiple responses, we need to make sure that we
103
                // have not received inconsistent values (eg a csv delay of 1
104
                // from one acceptor, and a delay of 120 from another). We
105
                // set each value on our final response if it has not been set
106
                // yet, and allow duplicate sets if the value is the same. If
107
                // we cannot set a field, we return an error response.
108
                var err error
7✔
109
                finalResp, err = mergeResponse(finalResp, *acceptorResponse)
7✔
110
                if err != nil {
7✔
111
                        log.Errorf("response for: %x has inconsistent values: %v",
×
112
                                req.OpenChanMsg.PendingChannelID, err)
×
113

×
114
                        return NewChannelAcceptResponse(
×
115
                                false, errChannelRejected, nil, 0, 0,
×
116
                                0, 0, 0, 0, false,
×
117
                        )
×
118
                }
×
119
        }
120

121
        // Attempt to parse the upfront shutdown address provided.
122
        if len(finalResp.UpfrontShutdown) == 0 && len(c.closeAddress) != 0 {
68✔
123
                upfront, err := chancloser.ParseUpfrontShutdownAddress(
10✔
124
                        c.closeAddress, c.params,
10✔
125
                )
10✔
126
                if err != nil {
10✔
NEW
127
                        log.Errorf("Could not parse upfront shutdown for "+
×
NEW
128
                                "%x: %v", req.OpenChanMsg.PendingChannelID, err)
×
NEW
129

×
NEW
130
                        return NewChannelAcceptResponse(
×
NEW
131
                                false, errChannelRejected, nil, 0, 0,
×
NEW
132
                                0, 0, 0, 0, false,
×
NEW
133
                        )
×
NEW
134
                }
×
135
                finalResp.UpfrontShutdown = upfront
10✔
136
        }
137

138
        // If we have gone through all of our acceptors with no objections, we
139
        // can return an acceptor with a nil error.
140
        return &finalResp
58✔
141
}
142

143
// A compile-time constraint to ensure ChainedAcceptor implements the
144
// MultiplexAcceptor interface.
145
var _ MultiplexAcceptor = (*ChainedAcceptor)(nil)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc