lnwallet/channel: add lnwire<->PaymentDescriptor FeeUpdate conversion

This commit adds conversion between the lnwire.UpdateFee message and the
new FeeUpdate PaymentDescriptor. We re-purpose the existing Amount field
in the PaymentDescriptor stuct to hold the feerate.
This commit is contained in:
Johan T. Halseth 2019-01-10 12:23:56 +01:00
parent 36857a1042
commit 480f43f1dc
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
3 changed files with 57 additions and 5 deletions

@ -681,9 +681,14 @@ func (l *channelLink) resolveFwdPkg(fwdPkg *channeldb.FwdPkg) (bool, error) {
// If the package is fully acked but not completed, it must still have // If the package is fully acked but not completed, it must still have
// settles and fails to propagate. // settles and fails to propagate.
if !fwdPkg.SettleFailFilter.IsFull() { if !fwdPkg.SettleFailFilter.IsFull() {
settleFails := lnwallet.PayDescsFromRemoteLogUpdates( settleFails, err := lnwallet.PayDescsFromRemoteLogUpdates(
fwdPkg.Source, fwdPkg.Height, fwdPkg.SettleFails, fwdPkg.Source, fwdPkg.Height, fwdPkg.SettleFails,
) )
if err != nil {
l.errorf("Unable to process remote log updates: %v",
err)
return false, err
}
l.processRemoteSettleFails(fwdPkg, settleFails) l.processRemoteSettleFails(fwdPkg, settleFails)
} }
@ -693,9 +698,14 @@ func (l *channelLink) resolveFwdPkg(fwdPkg *channeldb.FwdPkg) (bool, error) {
// batch of adds presented to the sphinx router does not ever change. // batch of adds presented to the sphinx router does not ever change.
var needUpdate bool var needUpdate bool
if !fwdPkg.AckFilter.IsFull() { if !fwdPkg.AckFilter.IsFull() {
adds := lnwallet.PayDescsFromRemoteLogUpdates( adds, err := lnwallet.PayDescsFromRemoteLogUpdates(
fwdPkg.Source, fwdPkg.Height, fwdPkg.Adds, fwdPkg.Source, fwdPkg.Height, fwdPkg.Adds,
) )
if err != nil {
l.errorf("Unable to process remote log updates: %v",
err)
return false, err
}
needUpdate = l.processRemoteAdds(fwdPkg, adds) needUpdate = l.processRemoteAdds(fwdPkg, adds)
// If the link failed during processing the adds, we must // If the link failed during processing the adds, we must

@ -1781,9 +1781,14 @@ func (s *Switch) loadChannelFwdPkgs(source lnwire.ShortChannelID) ([]*channeldb.
// NOTE: This should mimic the behavior processRemoteSettleFails. // NOTE: This should mimic the behavior processRemoteSettleFails.
func (s *Switch) reforwardSettleFails(fwdPkgs []*channeldb.FwdPkg) { func (s *Switch) reforwardSettleFails(fwdPkgs []*channeldb.FwdPkg) {
for _, fwdPkg := range fwdPkgs { for _, fwdPkg := range fwdPkgs {
settleFails := lnwallet.PayDescsFromRemoteLogUpdates( settleFails, err := lnwallet.PayDescsFromRemoteLogUpdates(
fwdPkg.Source, fwdPkg.Height, fwdPkg.SettleFails, fwdPkg.Source, fwdPkg.Height, fwdPkg.SettleFails,
) )
if err != nil {
log.Errorf("Unable to process remote log updates: %v",
err)
continue
}
switchPackets := make([]*htlcPacket, 0, len(settleFails)) switchPackets := make([]*htlcPacket, 0, len(settleFails))
for i, pd := range settleFails { for i, pd := range settleFails {

@ -351,7 +351,7 @@ type PaymentDescriptor struct {
// NOTE: The provided `logUpdates` MUST corresponding exactly to either the Adds // NOTE: The provided `logUpdates` MUST corresponding exactly to either the Adds
// or SettleFails in this channel's forwarding package at `height`. // or SettleFails in this channel's forwarding package at `height`.
func PayDescsFromRemoteLogUpdates(chanID lnwire.ShortChannelID, height uint64, func PayDescsFromRemoteLogUpdates(chanID lnwire.ShortChannelID, height uint64,
logUpdates []channeldb.LogUpdate) []*PaymentDescriptor { logUpdates []channeldb.LogUpdate) ([]*PaymentDescriptor, error) {
// Allocate enough space to hold all of the payment descriptors we will // Allocate enough space to hold all of the payment descriptors we will
// reconstruct, and also the list of pointers that will be returned to // reconstruct, and also the list of pointers that will be returned to
@ -423,13 +423,18 @@ func PayDescsFromRemoteLogUpdates(chanID lnwire.ShortChannelID, height uint64,
Index: uint16(i), Index: uint16(i),
}, },
} }
// NOTE: UpdateFee is not expected since they are not forwarded.
case *lnwire.UpdateFee:
return nil, fmt.Errorf("unexpected update fee")
} }
payDescs = append(payDescs, pd) payDescs = append(payDescs, pd)
payDescPtrs = append(payDescPtrs, &payDescs[i]) payDescPtrs = append(payDescPtrs, &payDescs[i])
} }
return payDescPtrs return payDescPtrs, nil
} }
// commitment represents a commitment to a new state within an active channel. // commitment represents a commitment to a new state within an active channel.
@ -1568,6 +1573,23 @@ func (lc *LightningChannel) logUpdateToPayDesc(logUpdate *channeldb.LogUpdate,
ShaOnionBlob: wireMsg.ShaOnionBlob, ShaOnionBlob: wireMsg.ShaOnionBlob,
removeCommitHeightRemote: commitHeight, removeCommitHeightRemote: commitHeight,
} }
// For fee updates we'll create a FeeUpdate type to add to the log. We
// reuse the amount field to hold the fee rate. Since the amount field
// is denominated in msat we won't lose precision when storing the
// sat/kw denominated feerate. Note that we set both the add and remove
// height to the same value, as we consider the fee update locked in by
// adding and removing it at the same height.
case *lnwire.UpdateFee:
pd = &PaymentDescriptor{
LogIndex: logUpdate.LogIndex,
Amount: lnwire.NewMSatFromSatoshis(
btcutil.Amount(wireMsg.FeePerKw),
),
EntryType: FeeUpdate,
addCommitHeightRemote: commitHeight,
removeCommitHeightRemote: commitHeight,
}
} }
return pd, nil return pd, nil
@ -2883,6 +2905,15 @@ func (lc *LightningChannel) createCommitDiff(
ShaOnionBlob: pd.ShaOnionBlob, ShaOnionBlob: pd.ShaOnionBlob,
FailureCode: pd.FailCode, FailureCode: pd.FailCode,
} }
case FeeUpdate:
// The Amount field holds the feerate denominated in
// msat. Since feerates are only denominated in sat/kw,
// we can convert it without loss of precision.
logUpdate.UpdateMsg = &lnwire.UpdateFee{
ChanID: chanID,
FeePerKw: uint32(pd.Amount.ToSatoshis()),
}
} }
// Gather the fwd pkg references from any settle or fail // Gather the fwd pkg references from any settle or fail
@ -4254,6 +4285,12 @@ func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.RevokeAndAck) (
for e := lc.remoteUpdateLog.Front(); e != nil; e = e.Next() { for e := lc.remoteUpdateLog.Front(); e != nil; e = e.Next() {
pd := e.Value.(*PaymentDescriptor) pd := e.Value.(*PaymentDescriptor)
// Fee updates are local to this particular channel, and should
// never be forwarded.
if pd.EntryType == FeeUpdate {
continue
}
if pd.isForwarded { if pd.isForwarded {
continue continue
} }