lnwallet: initialize the height of both commitment chains independently
This commit fixes a slight oversight in the current state machine which assumes that both commitment chains are always at the same height. In a future where we move back to allowing nodes to pipeline commitment updates, this will not always be the case.
This commit is contained in:
parent
a8671c485f
commit
d6c863e2d1
@ -268,13 +268,16 @@ func (c *commitment) toChannelDelta(ourCommit bool) (*channeldb.ChannelDelta, er
|
|||||||
// index of a particular HTLC within the current commitment
|
// index of a particular HTLC within the current commitment
|
||||||
// transaction.
|
// transaction.
|
||||||
locateOutputIndex := func(p *PaymentDescriptor) (uint16, error) {
|
locateOutputIndex := func(p *PaymentDescriptor) (uint16, error) {
|
||||||
var idx uint16
|
var (
|
||||||
var found bool
|
idx uint16
|
||||||
|
found bool
|
||||||
|
)
|
||||||
|
|
||||||
pkScript := p.theirPrevPkScript
|
pkScript := p.theirPrevPkScript
|
||||||
if ourCommit {
|
if ourCommit {
|
||||||
pkScript = p.ourPkScript
|
pkScript = p.ourPkScript
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, txOut := range c.txn.TxOut {
|
for i, txOut := range c.txn.TxOut {
|
||||||
if bytes.Equal(txOut.PkScript, pkScript) &&
|
if bytes.Equal(txOut.PkScript, pkScript) &&
|
||||||
txOut.Value == int64(p.Amount) {
|
txOut.Value == int64(p.Amount) {
|
||||||
@ -288,14 +291,17 @@ func (c *commitment) toChannelDelta(ourCommit bool) (*channeldb.ChannelDelta, er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
return 0, fmt.Errorf("could not find a matching output for the HTLC " +
|
return 0, fmt.Errorf("could not find a matching " +
|
||||||
"in the commitment transaction")
|
"output for the HTLC in the commitment transaction")
|
||||||
}
|
}
|
||||||
|
|
||||||
return idx, nil
|
return idx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var index uint16
|
var (
|
||||||
var err error
|
index uint16
|
||||||
|
err error
|
||||||
|
)
|
||||||
for _, htlc := range c.outgoingHTLCs {
|
for _, htlc := range c.outgoingHTLCs {
|
||||||
if (ourCommit && htlc.isDustLocal) ||
|
if (ourCommit && htlc.isDustLocal) ||
|
||||||
(!ourCommit && htlc.isDustRemote) {
|
(!ourCommit && htlc.isDustRemote) {
|
||||||
@ -314,6 +320,7 @@ func (c *commitment) toChannelDelta(ourCommit bool) (*channeldb.ChannelDelta, er
|
|||||||
}
|
}
|
||||||
delta.Htlcs = append(delta.Htlcs, h)
|
delta.Htlcs = append(delta.Htlcs, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, htlc := range c.incomingHTLCs {
|
for _, htlc := range c.incomingHTLCs {
|
||||||
if (ourCommit && htlc.isDustLocal) ||
|
if (ourCommit && htlc.isDustLocal) ||
|
||||||
(!ourCommit && htlc.isDustRemote) {
|
(!ourCommit && htlc.isDustRemote) {
|
||||||
@ -686,19 +693,46 @@ func NewLightningChannel(signer Signer, events chainntnfs.ChainNotifier,
|
|||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize both of our chains the current un-revoked commitment for
|
// Initialize both of our chains using current un-revoked commitment
|
||||||
// each side.
|
// for each side.
|
||||||
// TODO(roasbeef): add chnneldb.RevocationLogTail method, then init
|
lc.localCommitChain.addCommitment(&commitment{
|
||||||
// their commitment from that as we may be de-synced
|
|
||||||
initialCommitment := &commitment{
|
|
||||||
height: lc.currentHeight,
|
height: lc.currentHeight,
|
||||||
ourBalance: state.OurBalance,
|
ourBalance: state.OurBalance,
|
||||||
ourMessageIndex: 0,
|
ourMessageIndex: 0,
|
||||||
theirBalance: state.TheirBalance,
|
theirBalance: state.TheirBalance,
|
||||||
theirMessageIndex: 0,
|
theirMessageIndex: 0,
|
||||||
|
})
|
||||||
|
walletLog.Debugf("ChannelPoint(%v), starting local commitment: %v",
|
||||||
|
state.ChanID, newLogClosure(func() string {
|
||||||
|
return spew.Sdump(lc.localCommitChain.tail())
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
// To obtain the proper height for the remote node's commitment state,
|
||||||
|
// we'll need to fetch the tail end of their revocation log from the
|
||||||
|
// database.
|
||||||
|
logTail, err := state.RevocationLogTail()
|
||||||
|
if err != nil && err != channeldb.ErrNoActiveChannels &&
|
||||||
|
err != channeldb.ErrNoPastDeltas {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
lc.localCommitChain.addCommitment(initialCommitment)
|
remoteCommitment := &commitment{
|
||||||
lc.remoteCommitChain.addCommitment(initialCommitment)
|
ourBalance: state.OurBalance,
|
||||||
|
ourMessageIndex: 0,
|
||||||
|
theirBalance: state.TheirBalance,
|
||||||
|
theirMessageIndex: 0,
|
||||||
|
}
|
||||||
|
if logTail == nil {
|
||||||
|
remoteCommitment.height = 0
|
||||||
|
} else {
|
||||||
|
remoteCommitment.height = logTail.UpdateNum + 1
|
||||||
|
}
|
||||||
|
lc.remoteCommitChain.addCommitment(remoteCommitment)
|
||||||
|
walletLog.Debugf("ChannelPoint(%v), starting remote commitment: %v",
|
||||||
|
state.ChanID, newLogClosure(func() string {
|
||||||
|
return spew.Sdump(lc.remoteCommitChain.tail())
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
// If we're restarting from a channel with history, then restore the
|
// If we're restarting from a channel with history, then restore the
|
||||||
// update in-memory update logs to that of the prior state.
|
// update in-memory update logs to that of the prior state.
|
||||||
@ -949,6 +983,8 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven
|
|||||||
|
|
||||||
currentStateNum := lc.currentHeight
|
currentStateNum := lc.currentHeight
|
||||||
|
|
||||||
|
// TODO(roasbeef): track heights distinctly?
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
// If state number spending transaction matches the current latest
|
// If state number spending transaction matches the current latest
|
||||||
// state, then they've initiated a unilateral close. So we'll trigger
|
// state, then they've initiated a unilateral close. So we'll trigger
|
||||||
|
Loading…
Reference in New Issue
Block a user