lnd: add support for channel state snapshots in peer

This commit is contained in:
Olaoluwa Osuntokun 2016-06-22 22:22:06 -07:00
parent 2e706f39b9
commit e61a03a372
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2

36
peer.go

@ -40,6 +40,12 @@ type outgoinMsg struct {
sentChan chan struct{} // MUST be buffered. sentChan chan struct{} // MUST be buffered.
} }
// chanSnapshotReq is a message sent by outside sub-systems to a peer in order
// to gain a snapshot of the peer's currently active channels.
type chanSnapshotReq struct {
resp chan []*channeldb.ChannelSnapshot
}
// peer is an active peer on the Lightning Network. This struct is responsible // peer is an active peer on the Lightning Network. This struct is responsible
// for managing any channel state related to this peer. To do so, it has several // for managing any channel state related to this peer. To do so, it has several
// helper goroutines to handle events such as HTLC timeouts, new funding // helper goroutines to handle events such as HTLC timeouts, new funding
@ -55,9 +61,8 @@ type peer struct {
lightningAddr *lndc.LNAdr lightningAddr *lndc.LNAdr
lightningID wire.ShaHash lightningID wire.ShaHash
inbound bool inbound bool
protocolVersion uint32 id int32
id int32
// For purposes of detecting retransmits, etc. // For purposes of detecting retransmits, etc.
lastNMessages map[lnwire.Message]struct{} lastNMessages map[lnwire.Message]struct{}
@ -92,7 +97,8 @@ type peer struct {
// activeChannels is a map which stores the state machines of all // activeChannels is a map which stores the state machines of all
// active channels. Channels are indexed into the map by the txid of // active channels. Channels are indexed into the map by the txid of
// the funding transaction which opened the channel. // the funding transaction which opened the channel.
activeChannels map[wire.OutPoint]*lnwallet.LightningChannel activeChannels map[wire.OutPoint]*lnwallet.LightningChannel
chanSnapshotReqs chan *chanSnapshotReq
// newChanBarriers is a map from a channel point to a 'barrier' which // newChanBarriers is a map from a channel point to a 'barrier' which
// will be signalled once the channel is fully open. This barrier acts // will be signalled once the channel is fully open. This barrier acts
@ -152,9 +158,10 @@ func newPeer(conn net.Conn, server *server, net wire.BitcoinNet, inbound bool) (
sendQueue: make(chan outgoinMsg, 1), sendQueue: make(chan outgoinMsg, 1),
outgoingQueue: make(chan outgoinMsg, outgoingQueueLen), outgoingQueue: make(chan outgoinMsg, outgoingQueueLen),
newChanBarriers: make(map[wire.OutPoint]chan struct{}), newChanBarriers: make(map[wire.OutPoint]chan struct{}),
activeChannels: make(map[wire.OutPoint]*lnwallet.LightningChannel), activeChannels: make(map[wire.OutPoint]*lnwallet.LightningChannel),
newChannels: make(chan *lnwallet.LightningChannel, 1), chanSnapshotReqs: make(chan *chanSnapshotReq),
newChannels: make(chan *lnwallet.LightningChannel, 1),
localCloseChanReqs: make(chan *closeChanReq), localCloseChanReqs: make(chan *closeChanReq),
remoteCloseChanReqs: make(chan *lnwire.CloseRequest), remoteCloseChanReqs: make(chan *lnwire.CloseRequest),
@ -433,6 +440,14 @@ func (p *peer) queueMsg(msg lnwire.Message, doneChan chan struct{}) {
p.outgoingQueue <- outgoinMsg{msg, doneChan} p.outgoingQueue <- outgoinMsg{msg, doneChan}
} }
// ChannelSnapshots returns a slice of channel snapshots detaling all currently
// active channels maintained with the remote peer.
func (p *peer) ChannelSnapshots() []*channeldb.ChannelSnapshot {
resp := make(chan []*channeldb.ChannelSnapshot, 1)
p.chanSnapshotReqs <- &chanSnapshotReq{resp}
return <-resp
}
// channelManager is goroutine dedicated to handling all requests/signals // channelManager is goroutine dedicated to handling all requests/signals
// pertaining to the opening, cooperative closing, and force closing of all // pertaining to the opening, cooperative closing, and force closing of all
// channels maintained with the remote peer. // channels maintained with the remote peer.
@ -442,6 +457,13 @@ func (p *peer) channelManager() {
out: out:
for { for {
select { select {
case req := <-p.chanSnapshotReqs:
snapshots := make([]*channeldb.ChannelSnapshot, 0, len(p.activeChannels))
for _, activeChan := range p.activeChannels {
snapshot := activeChan.StateSnapshot()
snapshots = append(snapshots, snapshot)
}
req.resp <- snapshots
case newChan := <-p.newChannels: case newChan := <-p.newChannels:
chanPoint := *newChan.ChannelPoint() chanPoint := *newChan.ChannelPoint()
p.activeChannels[chanPoint] = newChan p.activeChannels[chanPoint] = newChan