Merge pull request #8981 from ProofOfKeags/refactor/payment-descriptor-quarantine
[KILO]: Quarantine paymentDescriptor to the lnwallet package
This commit is contained in:
14 files changed
+552
-718
No files matched your search
@@ -286,6 +286,27 @@ func NewFwdPkg(source lnwire.ShortChannelID, height uint64,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SourceRef is a convenience method that returns an AddRef to this forwarding
|
||||||
|
// package for the index in the argument. It is the caller's responsibility
|
||||||
|
// to ensure that the index is in bounds.
|
||||||
|
func (f *FwdPkg) SourceRef(i uint16) AddRef {
|
||||||
|
return AddRef{
|
||||||
|
Height: f.Height,
|
||||||
|
Index: i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DestRef is a convenience method that returns a SettleFailRef to this
|
||||||
|
// forwarding package for the index in the argument. It is the caller's
|
||||||
|
// responsibility to ensure that the index is in bounds.
|
||||||
|
func (f *FwdPkg) DestRef(i uint16) SettleFailRef {
|
||||||
|
return SettleFailRef{
|
||||||
|
Source: f.Source,
|
||||||
|
Height: f.Height,
|
||||||
|
Index: i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ID returns an unique identifier for this package, used to ensure that sphinx
|
// ID returns an unique identifier for this package, used to ensure that sphinx
|
||||||
// replay processing of this batch is idempotent.
|
// replay processing of this batch is idempotent.
|
||||||
func (f *FwdPkg) ID() []byte {
|
func (f *FwdPkg) ID() []byte {
|
||||||
|
|||||||
+120
-128
@@ -442,7 +442,8 @@ func (m *hookMap) invoke() {
|
|||||||
|
|
||||||
// hodlHtlc contains htlc data that is required for resolution.
|
// hodlHtlc contains htlc data that is required for resolution.
|
||||||
type hodlHtlc struct {
|
type hodlHtlc struct {
|
||||||
pd *lnwallet.PaymentDescriptor
|
add lnwire.UpdateAddHTLC
|
||||||
|
sourceRef channeldb.AddRef
|
||||||
obfuscator hop.ErrorEncrypter
|
obfuscator hop.ErrorEncrypter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -992,15 +993,7 @@ func (l *channelLink) resolveFwdPkg(fwdPkg *channeldb.FwdPkg) 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, err := lnwallet.PayDescsFromRemoteLogUpdates(
|
l.processRemoteSettleFails(fwdPkg)
|
||||||
fwdPkg.Source, fwdPkg.Height, fwdPkg.SettleFails,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
l.log.Errorf("unable to process remote log updates: %v",
|
|
||||||
err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
l.processRemoteSettleFails(fwdPkg, settleFails)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, replay *ALL ADDS* in this forwarding package. The
|
// Finally, replay *ALL ADDS* in this forwarding package. The
|
||||||
@@ -1008,15 +1001,7 @@ func (l *channelLink) resolveFwdPkg(fwdPkg *channeldb.FwdPkg) error {
|
|||||||
// shove the entire, original set of adds down the pipeline so that the
|
// shove the entire, original set of adds down the pipeline so that the
|
||||||
// batch of adds presented to the sphinx router does not ever change.
|
// batch of adds presented to the sphinx router does not ever change.
|
||||||
if !fwdPkg.AckFilter.IsFull() {
|
if !fwdPkg.AckFilter.IsFull() {
|
||||||
adds, err := lnwallet.PayDescsFromRemoteLogUpdates(
|
l.processRemoteAdds(fwdPkg)
|
||||||
fwdPkg.Source, fwdPkg.Height, fwdPkg.Adds,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
l.log.Errorf("unable to process remote log updates: %v",
|
|
||||||
err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
l.processRemoteAdds(fwdPkg, adds)
|
|
||||||
|
|
||||||
// If the link failed during processing the adds, we must
|
// If the link failed during processing the adds, we must
|
||||||
// return to ensure we won't attempted to update the state
|
// return to ensure we won't attempted to update the state
|
||||||
@@ -1520,7 +1505,9 @@ func (l *channelLink) processHtlcResolution(resolution invoices.HtlcResolution,
|
|||||||
l.log.Debugf("received settle resolution for %v "+
|
l.log.Debugf("received settle resolution for %v "+
|
||||||
"with outcome: %v", circuitKey, res.Outcome)
|
"with outcome: %v", circuitKey, res.Outcome)
|
||||||
|
|
||||||
return l.settleHTLC(res.Preimage, htlc.pd)
|
return l.settleHTLC(
|
||||||
|
res.Preimage, htlc.add.ID, htlc.sourceRef,
|
||||||
|
)
|
||||||
|
|
||||||
// For htlc failures, we get the relevant failure message based
|
// For htlc failures, we get the relevant failure message based
|
||||||
// on the failure resolution and then fail the htlc.
|
// on the failure resolution and then fail the htlc.
|
||||||
@@ -1530,10 +1517,11 @@ func (l *channelLink) processHtlcResolution(resolution invoices.HtlcResolution,
|
|||||||
|
|
||||||
// Get the lnwire failure message based on the resolution
|
// Get the lnwire failure message based on the resolution
|
||||||
// result.
|
// result.
|
||||||
failure := getResolutionFailure(res, htlc.pd.Amount)
|
failure := getResolutionFailure(res, htlc.add.Amount)
|
||||||
|
|
||||||
l.sendHTLCError(
|
l.sendHTLCError(
|
||||||
htlc.pd, failure, htlc.obfuscator, true,
|
htlc.add, htlc.sourceRef, failure, htlc.obfuscator,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
@@ -2333,8 +2321,7 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
|
|||||||
|
|
||||||
// We now process the message and advance our remote commit
|
// We now process the message and advance our remote commit
|
||||||
// chain.
|
// chain.
|
||||||
fwdPkg, adds, settleFails, remoteHTLCs, err := l.channel.
|
fwdPkg, remoteHTLCs, err := l.channel.ReceiveRevocation(msg)
|
||||||
ReceiveRevocation(msg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(halseth): force close?
|
// TODO(halseth): force close?
|
||||||
l.failf(
|
l.failf(
|
||||||
@@ -2384,8 +2371,8 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
l.processRemoteSettleFails(fwdPkg, settleFails)
|
l.processRemoteSettleFails(fwdPkg)
|
||||||
l.processRemoteAdds(fwdPkg, adds)
|
l.processRemoteAdds(fwdPkg)
|
||||||
|
|
||||||
// If the link failed during processing the adds, we must
|
// If the link failed during processing the adds, we must
|
||||||
// return to ensure we won't attempted to update the state
|
// return to ensure we won't attempted to update the state
|
||||||
@@ -3291,17 +3278,17 @@ func (l *channelLink) updateChannelFee(feePerKw chainfee.SatPerKWeight) error {
|
|||||||
// the context of the provided forwarding package. Any settles or fails that
|
// the context of the provided forwarding package. Any settles or fails that
|
||||||
// have already been acknowledged in the forwarding package will not be sent to
|
// have already been acknowledged in the forwarding package will not be sent to
|
||||||
// the switch.
|
// the switch.
|
||||||
func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg,
|
func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg) {
|
||||||
settleFails []*lnwallet.PaymentDescriptor) {
|
if len(fwdPkg.SettleFails) == 0 {
|
||||||
|
|
||||||
if len(settleFails) == 0 {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
l.log.Debugf("settle-fail-filter: %v", fwdPkg.SettleFailFilter)
|
l.log.Debugf("settle-fail-filter: %v", fwdPkg.SettleFailFilter)
|
||||||
|
|
||||||
var switchPackets []*htlcPacket
|
var switchPackets []*htlcPacket
|
||||||
for i, pd := range settleFails {
|
for i, update := range fwdPkg.SettleFails {
|
||||||
|
destRef := fwdPkg.DestRef(uint16(i))
|
||||||
|
|
||||||
// Skip any settles or fails that have already been
|
// Skip any settles or fails that have already been
|
||||||
// acknowledged by the incoming link that originated the
|
// acknowledged by the incoming link that originated the
|
||||||
// forwarded Add.
|
// forwarded Add.
|
||||||
@@ -3312,12 +3299,11 @@ func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg,
|
|||||||
// TODO(roasbeef): rework log entries to a shared
|
// TODO(roasbeef): rework log entries to a shared
|
||||||
// interface.
|
// interface.
|
||||||
|
|
||||||
switch pd.EntryType {
|
switch msg := update.UpdateMsg.(type) {
|
||||||
|
|
||||||
// A settle for an HTLC we previously forwarded HTLC has been
|
// A settle for an HTLC we previously forwarded HTLC has been
|
||||||
// received. So we'll forward the HTLC to the switch which will
|
// received. So we'll forward the HTLC to the switch which will
|
||||||
// handle propagating the settle to the prior hop.
|
// handle propagating the settle to the prior hop.
|
||||||
case lnwallet.Settle:
|
case *lnwire.UpdateFulfillHTLC:
|
||||||
// If hodl.SettleIncoming is requested, we will not
|
// If hodl.SettleIncoming is requested, we will not
|
||||||
// forward the SETTLE to the switch and will not signal
|
// forward the SETTLE to the switch and will not signal
|
||||||
// a free slot on the commitment transaction.
|
// a free slot on the commitment transaction.
|
||||||
@@ -3328,11 +3314,9 @@ func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg,
|
|||||||
|
|
||||||
settlePacket := &htlcPacket{
|
settlePacket := &htlcPacket{
|
||||||
outgoingChanID: l.ShortChanID(),
|
outgoingChanID: l.ShortChanID(),
|
||||||
outgoingHTLCID: pd.ParentIndex,
|
outgoingHTLCID: msg.ID,
|
||||||
destRef: pd.DestRef,
|
destRef: &destRef,
|
||||||
htlc: &lnwire.UpdateFulfillHTLC{
|
htlc: msg,
|
||||||
PaymentPreimage: pd.RPreimage,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the packet to the batch to be forwarded, and
|
// Add the packet to the batch to be forwarded, and
|
||||||
@@ -3344,7 +3328,7 @@ func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg,
|
|||||||
// been received. As a result a new slot will be freed up in
|
// been received. As a result a new slot will be freed up in
|
||||||
// our commitment state, so we'll forward this to the switch so
|
// our commitment state, so we'll forward this to the switch so
|
||||||
// the backwards undo can continue.
|
// the backwards undo can continue.
|
||||||
case lnwallet.Fail:
|
case *lnwire.UpdateFailHTLC:
|
||||||
// If hodl.SettleIncoming is requested, we will not
|
// If hodl.SettleIncoming is requested, we will not
|
||||||
// forward the FAIL to the switch and will not signal a
|
// forward the FAIL to the switch and will not signal a
|
||||||
// free slot on the commitment transaction.
|
// free slot on the commitment transaction.
|
||||||
@@ -3359,16 +3343,12 @@ func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg,
|
|||||||
// set on the packet.
|
// set on the packet.
|
||||||
failPacket := &htlcPacket{
|
failPacket := &htlcPacket{
|
||||||
outgoingChanID: l.ShortChanID(),
|
outgoingChanID: l.ShortChanID(),
|
||||||
outgoingHTLCID: pd.ParentIndex,
|
outgoingHTLCID: msg.ID,
|
||||||
destRef: pd.DestRef,
|
destRef: &destRef,
|
||||||
htlc: &lnwire.UpdateFailHTLC{
|
htlc: msg,
|
||||||
Reason: lnwire.OpaqueReason(
|
|
||||||
pd.FailReason,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l.log.Debugf("Failed to send %s", pd.Amount)
|
l.log.Debugf("Failed to send HTLC with ID=%d", msg.ID)
|
||||||
|
|
||||||
// If the failure message lacks an HMAC (but includes
|
// If the failure message lacks an HMAC (but includes
|
||||||
// the 4 bytes for encoding the message and padding
|
// the 4 bytes for encoding the message and padding
|
||||||
@@ -3378,7 +3358,7 @@ func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg,
|
|||||||
// to an actual error, by encrypting it as if we were
|
// to an actual error, by encrypting it as if we were
|
||||||
// the originating hop.
|
// the originating hop.
|
||||||
convertedErrorSize := lnwire.FailureMessageLength + 4
|
convertedErrorSize := lnwire.FailureMessageLength + 4
|
||||||
if len(pd.FailReason) == convertedErrorSize {
|
if len(msg.Reason) == convertedErrorSize {
|
||||||
failPacket.convertedError = true
|
failPacket.convertedError = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3401,32 +3381,29 @@ func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg,
|
|||||||
// indicating whether this is the first time these Adds are being processed, or
|
// indicating whether this is the first time these Adds are being processed, or
|
||||||
// whether we are reprocessing as a result of a failure or restart. Adds that
|
// whether we are reprocessing as a result of a failure or restart. Adds that
|
||||||
// have already been acknowledged in the forwarding package will be ignored.
|
// have already been acknowledged in the forwarding package will be ignored.
|
||||||
func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
//
|
||||||
lockedInHtlcs []*lnwallet.PaymentDescriptor) {
|
//nolint:funlen
|
||||||
|
func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
|
||||||
l.log.Tracef("processing %d remote adds for height %d",
|
l.log.Tracef("processing %d remote adds for height %d",
|
||||||
len(lockedInHtlcs), fwdPkg.Height)
|
len(fwdPkg.Adds), fwdPkg.Height)
|
||||||
|
|
||||||
decodeReqs := make(
|
decodeReqs := make(
|
||||||
[]hop.DecodeHopIteratorRequest, 0, len(lockedInHtlcs),
|
[]hop.DecodeHopIteratorRequest, 0, len(fwdPkg.Adds),
|
||||||
)
|
)
|
||||||
for _, pd := range lockedInHtlcs {
|
for _, update := range fwdPkg.Adds {
|
||||||
switch pd.EntryType {
|
if msg, ok := update.UpdateMsg.(*lnwire.UpdateAddHTLC); ok {
|
||||||
|
|
||||||
// TODO(conner): remove type switch?
|
|
||||||
case lnwallet.Add:
|
|
||||||
// Before adding the new htlc to the state machine,
|
// Before adding the new htlc to the state machine,
|
||||||
// parse the onion object in order to obtain the
|
// parse the onion object in order to obtain the
|
||||||
// routing information with DecodeHopIterator function
|
// routing information with DecodeHopIterator function
|
||||||
// which process the Sphinx packet.
|
// which process the Sphinx packet.
|
||||||
onionReader := bytes.NewReader(pd.OnionBlob)
|
onionReader := bytes.NewReader(msg.OnionBlob[:])
|
||||||
|
|
||||||
req := hop.DecodeHopIteratorRequest{
|
req := hop.DecodeHopIteratorRequest{
|
||||||
OnionReader: onionReader,
|
OnionReader: onionReader,
|
||||||
RHash: pd.RHash[:],
|
RHash: msg.PaymentHash[:],
|
||||||
IncomingCltv: pd.Timeout,
|
IncomingCltv: msg.Expiry,
|
||||||
IncomingAmount: pd.Amount,
|
IncomingAmount: msg.Amount,
|
||||||
BlindingPoint: pd.BlindingPoint,
|
BlindingPoint: msg.BlindingPoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
decodeReqs = append(decodeReqs, req)
|
decodeReqs = append(decodeReqs, req)
|
||||||
@@ -3448,9 +3425,13 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
|
|
||||||
var switchPackets []*htlcPacket
|
var switchPackets []*htlcPacket
|
||||||
|
|
||||||
for i, pd := range lockedInHtlcs {
|
for i, update := range fwdPkg.Adds {
|
||||||
idx := uint16(i)
|
idx := uint16(i)
|
||||||
|
|
||||||
|
//nolint:forcetypeassert
|
||||||
|
add := *update.UpdateMsg.(*lnwire.UpdateAddHTLC)
|
||||||
|
sourceRef := fwdPkg.SourceRef(idx)
|
||||||
|
|
||||||
if fwdPkg.State == channeldb.FwdStateProcessed &&
|
if fwdPkg.State == channeldb.FwdStateProcessed &&
|
||||||
fwdPkg.AckFilter.Contains(idx) {
|
fwdPkg.AckFilter.Contains(idx) {
|
||||||
|
|
||||||
@@ -3468,11 +3449,6 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
// or are able to settle it (and it adheres to our fee related
|
// or are able to settle it (and it adheres to our fee related
|
||||||
// constraints).
|
// constraints).
|
||||||
|
|
||||||
// Fetch the onion blob that was included within this processed
|
|
||||||
// payment descriptor.
|
|
||||||
var onionBlob [lnwire.OnionPacketSize]byte
|
|
||||||
copy(onionBlob[:], pd.OnionBlob)
|
|
||||||
|
|
||||||
// Before adding the new htlc to the state machine, parse the
|
// Before adding the new htlc to the state machine, parse the
|
||||||
// onion object in order to obtain the routing information with
|
// onion object in order to obtain the routing information with
|
||||||
// DecodeHopIterator function which process the Sphinx packet.
|
// DecodeHopIterator function which process the Sphinx packet.
|
||||||
@@ -3481,8 +3457,9 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
// If we're unable to process the onion blob then we
|
// If we're unable to process the onion blob then we
|
||||||
// should send the malformed htlc error to payment
|
// should send the malformed htlc error to payment
|
||||||
// sender.
|
// sender.
|
||||||
l.sendMalformedHTLCError(pd.HtlcIndex, failureCode,
|
l.sendMalformedHTLCError(
|
||||||
onionBlob[:], pd.SourceRef)
|
add.ID, failureCode, add.OnionBlob, &sourceRef,
|
||||||
|
)
|
||||||
|
|
||||||
l.log.Errorf("unable to decode onion hop "+
|
l.log.Errorf("unable to decode onion hop "+
|
||||||
"iterator: %v", failureCode)
|
"iterator: %v", failureCode)
|
||||||
@@ -3526,8 +3503,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
// We can't process this htlc, send back
|
// We can't process this htlc, send back
|
||||||
// malformed.
|
// malformed.
|
||||||
l.sendMalformedHTLCError(
|
l.sendMalformedHTLCError(
|
||||||
pd.HtlcIndex, failureCode,
|
add.ID, failureCode, add.OnionBlob,
|
||||||
onionBlob[:], pd.SourceRef,
|
&sourceRef,
|
||||||
)
|
)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
@@ -3540,8 +3517,10 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
// payloads. Deferring this non-trival effort till a
|
// payloads. Deferring this non-trival effort till a
|
||||||
// later date
|
// later date
|
||||||
failure := lnwire.NewInvalidOnionPayload(failedType, 0)
|
failure := lnwire.NewInvalidOnionPayload(failedType, 0)
|
||||||
|
|
||||||
l.sendHTLCError(
|
l.sendHTLCError(
|
||||||
pd, NewLinkError(failure), obfuscator, false,
|
add, sourceRef, NewLinkError(failure),
|
||||||
|
obfuscator, false,
|
||||||
)
|
)
|
||||||
|
|
||||||
l.log.Errorf("unable to decode forwarding "+
|
l.log.Errorf("unable to decode forwarding "+
|
||||||
@@ -3561,8 +3540,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
// should send the malformed htlc error to payment
|
// should send the malformed htlc error to payment
|
||||||
// sender.
|
// sender.
|
||||||
l.sendMalformedHTLCError(
|
l.sendMalformedHTLCError(
|
||||||
pd.HtlcIndex, failureCode, onionBlob[:],
|
add.ID, failureCode, add.OnionBlob,
|
||||||
pd.SourceRef,
|
&sourceRef,
|
||||||
)
|
)
|
||||||
|
|
||||||
l.log.Errorf("unable to decode onion "+
|
l.log.Errorf("unable to decode onion "+
|
||||||
@@ -3581,10 +3560,12 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
l.cfg.DisallowRouteBlinding {
|
l.cfg.DisallowRouteBlinding {
|
||||||
|
|
||||||
failure := lnwire.NewInvalidBlinding(
|
failure := lnwire.NewInvalidBlinding(
|
||||||
onionBlob[:],
|
fn.Some(add.OnionBlob),
|
||||||
)
|
)
|
||||||
|
|
||||||
l.sendHTLCError(
|
l.sendHTLCError(
|
||||||
pd, NewLinkError(failure), obfuscator, false,
|
add, sourceRef, NewLinkError(failure),
|
||||||
|
obfuscator, false,
|
||||||
)
|
)
|
||||||
|
|
||||||
l.log.Error("rejected htlc that uses use as an " +
|
l.log.Error("rejected htlc that uses use as an " +
|
||||||
@@ -3597,7 +3578,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
switch fwdInfo.NextHop {
|
switch fwdInfo.NextHop {
|
||||||
case hop.Exit:
|
case hop.Exit:
|
||||||
err := l.processExitHop(
|
err := l.processExitHop(
|
||||||
pd, obfuscator, fwdInfo, heightNow, pld,
|
add, sourceRef, obfuscator, fwdInfo,
|
||||||
|
heightNow, pld,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.failf(LinkFailureError{
|
l.failf(LinkFailureError{
|
||||||
@@ -3631,18 +3613,20 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, it was already processed, we can
|
// Otherwise, it was already processed, we can
|
||||||
// collect it and continue.
|
// can collect it and continue.
|
||||||
addMsg := &lnwire.UpdateAddHTLC{
|
outgoingAdd := &lnwire.UpdateAddHTLC{
|
||||||
Expiry: fwdInfo.OutgoingCTLV,
|
Expiry: fwdInfo.OutgoingCTLV,
|
||||||
Amount: fwdInfo.AmountToForward,
|
Amount: fwdInfo.AmountToForward,
|
||||||
PaymentHash: pd.RHash,
|
PaymentHash: add.PaymentHash,
|
||||||
BlindingPoint: fwdInfo.NextBlinding,
|
BlindingPoint: fwdInfo.NextBlinding,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, we'll encode the onion packet for
|
// Finally, we'll encode the onion packet for
|
||||||
// the _next_ hop using the hop iterator
|
// the _next_ hop using the hop iterator
|
||||||
// decoded for the current hop.
|
// decoded for the current hop.
|
||||||
buf := bytes.NewBuffer(addMsg.OnionBlob[0:0])
|
buf := bytes.NewBuffer(
|
||||||
|
outgoingAdd.OnionBlob[0:0],
|
||||||
|
)
|
||||||
|
|
||||||
// We know this cannot fail, as this ADD
|
// We know this cannot fail, as this ADD
|
||||||
// was marked forwarded in a previous
|
// was marked forwarded in a previous
|
||||||
@@ -3654,18 +3638,18 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
//nolint:lll
|
//nolint:lll
|
||||||
updatePacket := &htlcPacket{
|
updatePacket := &htlcPacket{
|
||||||
incomingChanID: l.ShortChanID(),
|
incomingChanID: l.ShortChanID(),
|
||||||
incomingHTLCID: pd.HtlcIndex,
|
incomingHTLCID: add.ID,
|
||||||
outgoingChanID: fwdInfo.NextHop,
|
outgoingChanID: fwdInfo.NextHop,
|
||||||
sourceRef: pd.SourceRef,
|
sourceRef: &sourceRef,
|
||||||
incomingAmount: pd.Amount,
|
incomingAmount: add.Amount,
|
||||||
amount: addMsg.Amount,
|
amount: outgoingAdd.Amount,
|
||||||
htlc: addMsg,
|
htlc: outgoingAdd,
|
||||||
obfuscator: obfuscator,
|
obfuscator: obfuscator,
|
||||||
incomingTimeout: pd.Timeout,
|
incomingTimeout: add.Expiry,
|
||||||
outgoingTimeout: fwdInfo.OutgoingCTLV,
|
outgoingTimeout: fwdInfo.OutgoingCTLV,
|
||||||
inOnionCustomRecords: pld.CustomRecords(),
|
inOnionCustomRecords: pld.CustomRecords(),
|
||||||
inboundFee: inboundFee,
|
inboundFee: inboundFee,
|
||||||
inWireCustomRecords: pd.CustomRecords.Copy(),
|
inWireCustomRecords: add.CustomRecords.Copy(),
|
||||||
}
|
}
|
||||||
switchPackets = append(
|
switchPackets = append(
|
||||||
switchPackets, updatePacket,
|
switchPackets, updatePacket,
|
||||||
@@ -3683,7 +3667,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
addMsg := &lnwire.UpdateAddHTLC{
|
addMsg := &lnwire.UpdateAddHTLC{
|
||||||
Expiry: fwdInfo.OutgoingCTLV,
|
Expiry: fwdInfo.OutgoingCTLV,
|
||||||
Amount: fwdInfo.AmountToForward,
|
Amount: fwdInfo.AmountToForward,
|
||||||
PaymentHash: pd.RHash,
|
PaymentHash: add.PaymentHash,
|
||||||
BlindingPoint: fwdInfo.NextBlinding,
|
BlindingPoint: fwdInfo.NextBlinding,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3705,7 +3689,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
)
|
)
|
||||||
|
|
||||||
l.sendHTLCError(
|
l.sendHTLCError(
|
||||||
pd, NewLinkError(failure), obfuscator, false,
|
add, sourceRef, NewLinkError(failure),
|
||||||
|
obfuscator, false,
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -3724,18 +3709,18 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
//nolint:lll
|
//nolint:lll
|
||||||
updatePacket := &htlcPacket{
|
updatePacket := &htlcPacket{
|
||||||
incomingChanID: l.ShortChanID(),
|
incomingChanID: l.ShortChanID(),
|
||||||
incomingHTLCID: pd.HtlcIndex,
|
incomingHTLCID: add.ID,
|
||||||
outgoingChanID: fwdInfo.NextHop,
|
outgoingChanID: fwdInfo.NextHop,
|
||||||
sourceRef: pd.SourceRef,
|
sourceRef: &sourceRef,
|
||||||
incomingAmount: pd.Amount,
|
incomingAmount: add.Amount,
|
||||||
amount: addMsg.Amount,
|
amount: addMsg.Amount,
|
||||||
htlc: addMsg,
|
htlc: addMsg,
|
||||||
obfuscator: obfuscator,
|
obfuscator: obfuscator,
|
||||||
incomingTimeout: pd.Timeout,
|
incomingTimeout: add.Expiry,
|
||||||
outgoingTimeout: fwdInfo.OutgoingCTLV,
|
outgoingTimeout: fwdInfo.OutgoingCTLV,
|
||||||
inOnionCustomRecords: pld.CustomRecords(),
|
inOnionCustomRecords: pld.CustomRecords(),
|
||||||
inboundFee: inboundFee,
|
inboundFee: inboundFee,
|
||||||
inWireCustomRecords: pd.CustomRecords.Copy(),
|
inWireCustomRecords: add.CustomRecords.Copy(),
|
||||||
}
|
}
|
||||||
|
|
||||||
fwdPkg.FwdFilter.Set(idx)
|
fwdPkg.FwdFilter.Set(idx)
|
||||||
@@ -3775,9 +3760,10 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
|
|||||||
|
|
||||||
// processExitHop handles an htlc for which this link is the exit hop. It
|
// processExitHop handles an htlc for which this link is the exit hop. It
|
||||||
// returns a boolean indicating whether the commitment tx needs an update.
|
// returns a boolean indicating whether the commitment tx needs an update.
|
||||||
func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
|
func (l *channelLink) processExitHop(add lnwire.UpdateAddHTLC,
|
||||||
obfuscator hop.ErrorEncrypter, fwdInfo hop.ForwardingInfo,
|
sourceRef channeldb.AddRef, obfuscator hop.ErrorEncrypter,
|
||||||
heightNow uint32, payload invoices.Payload) error {
|
fwdInfo hop.ForwardingInfo, heightNow uint32,
|
||||||
|
payload invoices.Payload) error {
|
||||||
|
|
||||||
// If hodl.ExitSettle is requested, we will not validate the final hop's
|
// If hodl.ExitSettle is requested, we will not validate the final hop's
|
||||||
// ADD, nor will we settle the corresponding invoice or respond with the
|
// ADD, nor will we settle the corresponding invoice or respond with the
|
||||||
@@ -3791,30 +3777,31 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
|
|||||||
// As we're the exit hop, we'll double check the hop-payload included in
|
// As we're the exit hop, we'll double check the hop-payload included in
|
||||||
// the HTLC to ensure that it was crafted correctly by the sender and
|
// the HTLC to ensure that it was crafted correctly by the sender and
|
||||||
// is compatible with the HTLC we were extended.
|
// is compatible with the HTLC we were extended.
|
||||||
if pd.Amount < fwdInfo.AmountToForward {
|
if add.Amount < fwdInfo.AmountToForward {
|
||||||
l.log.Errorf("onion payload of incoming htlc(%x) has "+
|
l.log.Errorf("onion payload of incoming htlc(%x) has "+
|
||||||
"incompatible value: expected <=%v, got %v", pd.RHash,
|
"incompatible value: expected <=%v, got %v",
|
||||||
pd.Amount, fwdInfo.AmountToForward)
|
add.PaymentHash, add.Amount, fwdInfo.AmountToForward)
|
||||||
|
|
||||||
failure := NewLinkError(
|
failure := NewLinkError(
|
||||||
lnwire.NewFinalIncorrectHtlcAmount(pd.Amount),
|
lnwire.NewFinalIncorrectHtlcAmount(add.Amount),
|
||||||
)
|
)
|
||||||
l.sendHTLCError(pd, failure, obfuscator, true)
|
l.sendHTLCError(add, sourceRef, failure, obfuscator, true)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll also ensure that our time-lock value has been computed
|
// We'll also ensure that our time-lock value has been computed
|
||||||
// correctly.
|
// correctly.
|
||||||
if pd.Timeout < fwdInfo.OutgoingCTLV {
|
if add.Expiry < fwdInfo.OutgoingCTLV {
|
||||||
l.log.Errorf("onion payload of incoming htlc(%x) has "+
|
l.log.Errorf("onion payload of incoming htlc(%x) has "+
|
||||||
"incompatible time-lock: expected <=%v, got %v",
|
"incompatible time-lock: expected <=%v, got %v",
|
||||||
pd.RHash[:], pd.Timeout, fwdInfo.OutgoingCTLV)
|
add.PaymentHash, add.Expiry, fwdInfo.OutgoingCTLV)
|
||||||
|
|
||||||
failure := NewLinkError(
|
failure := NewLinkError(
|
||||||
lnwire.NewFinalIncorrectCltvExpiry(pd.Timeout),
|
lnwire.NewFinalIncorrectCltvExpiry(add.Expiry),
|
||||||
)
|
)
|
||||||
l.sendHTLCError(pd, failure, obfuscator, true)
|
|
||||||
|
l.sendHTLCError(add, sourceRef, failure, obfuscator, true)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -3822,15 +3809,15 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
|
|||||||
// Notify the invoiceRegistry of the exit hop htlc. If we crash right
|
// Notify the invoiceRegistry of the exit hop htlc. If we crash right
|
||||||
// after this, this code will be re-executed after restart. We will
|
// after this, this code will be re-executed after restart. We will
|
||||||
// receive back a resolution event.
|
// receive back a resolution event.
|
||||||
invoiceHash := lntypes.Hash(pd.RHash)
|
invoiceHash := lntypes.Hash(add.PaymentHash)
|
||||||
|
|
||||||
circuitKey := models.CircuitKey{
|
circuitKey := models.CircuitKey{
|
||||||
ChanID: l.ShortChanID(),
|
ChanID: l.ShortChanID(),
|
||||||
HtlcID: pd.HtlcIndex,
|
HtlcID: add.ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
event, err := l.cfg.Registry.NotifyExitHopHtlc(
|
event, err := l.cfg.Registry.NotifyExitHopHtlc(
|
||||||
invoiceHash, pd.Amount, pd.Timeout, int32(heightNow),
|
invoiceHash, add.Amount, add.Expiry, int32(heightNow),
|
||||||
circuitKey, l.hodlQueue.ChanIn(), payload,
|
circuitKey, l.hodlQueue.ChanIn(), payload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -3839,7 +3826,8 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
|
|||||||
|
|
||||||
// Create a hodlHtlc struct and decide either resolved now or later.
|
// Create a hodlHtlc struct and decide either resolved now or later.
|
||||||
htlc := hodlHtlc{
|
htlc := hodlHtlc{
|
||||||
pd: pd,
|
add: add,
|
||||||
|
sourceRef: sourceRef,
|
||||||
obfuscator: obfuscator,
|
obfuscator: obfuscator,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3856,14 +3844,14 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
|
|||||||
|
|
||||||
// settleHTLC settles the HTLC on the channel.
|
// settleHTLC settles the HTLC on the channel.
|
||||||
func (l *channelLink) settleHTLC(preimage lntypes.Preimage,
|
func (l *channelLink) settleHTLC(preimage lntypes.Preimage,
|
||||||
pd *lnwallet.PaymentDescriptor) error {
|
htlcIndex uint64, sourceRef channeldb.AddRef) error {
|
||||||
|
|
||||||
hash := preimage.Hash()
|
hash := preimage.Hash()
|
||||||
|
|
||||||
l.log.Infof("settling htlc %v as exit hop", hash)
|
l.log.Infof("settling htlc %v as exit hop", hash)
|
||||||
|
|
||||||
err := l.channel.SettleHTLC(
|
err := l.channel.SettleHTLC(
|
||||||
preimage, pd.HtlcIndex, pd.SourceRef, nil, nil,
|
preimage, htlcIndex, &sourceRef, nil, nil,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to settle htlc: %w", err)
|
return fmt.Errorf("unable to settle htlc: %w", err)
|
||||||
@@ -3881,7 +3869,7 @@ func (l *channelLink) settleHTLC(preimage lntypes.Preimage,
|
|||||||
// remote peer.
|
// remote peer.
|
||||||
l.cfg.Peer.SendMessage(false, &lnwire.UpdateFulfillHTLC{
|
l.cfg.Peer.SendMessage(false, &lnwire.UpdateFulfillHTLC{
|
||||||
ChanID: l.ChanID(),
|
ChanID: l.ChanID(),
|
||||||
ID: pd.HtlcIndex,
|
ID: htlcIndex,
|
||||||
PaymentPreimage: preimage,
|
PaymentPreimage: preimage,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -3890,7 +3878,7 @@ func (l *channelLink) settleHTLC(preimage lntypes.Preimage,
|
|||||||
HtlcKey{
|
HtlcKey{
|
||||||
IncomingCircuit: models.CircuitKey{
|
IncomingCircuit: models.CircuitKey{
|
||||||
ChanID: l.ShortChanID(),
|
ChanID: l.ShortChanID(),
|
||||||
HtlcID: pd.HtlcIndex,
|
HtlcID: htlcIndex,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
preimage,
|
preimage,
|
||||||
@@ -3925,8 +3913,9 @@ func (l *channelLink) forwardBatch(replay bool, packets ...*htlcPacket) {
|
|||||||
|
|
||||||
// sendHTLCError functions cancels HTLC and send cancel message back to the
|
// sendHTLCError functions cancels HTLC and send cancel message back to the
|
||||||
// peer from which HTLC was received.
|
// peer from which HTLC was received.
|
||||||
func (l *channelLink) sendHTLCError(pd *lnwallet.PaymentDescriptor,
|
func (l *channelLink) sendHTLCError(add lnwire.UpdateAddHTLC,
|
||||||
failure *LinkError, e hop.ErrorEncrypter, isReceive bool) {
|
sourceRef channeldb.AddRef, failure *LinkError,
|
||||||
|
e hop.ErrorEncrypter, isReceive bool) {
|
||||||
|
|
||||||
reason, err := e.EncryptFirstHop(failure.WireMessage())
|
reason, err := e.EncryptFirstHop(failure.WireMessage())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -3934,7 +3923,7 @@ func (l *channelLink) sendHTLCError(pd *lnwallet.PaymentDescriptor,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.channel.FailHTLC(pd.HtlcIndex, reason, pd.SourceRef, nil, nil)
|
err = l.channel.FailHTLC(add.ID, reason, &sourceRef, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.log.Errorf("unable cancel htlc: %v", err)
|
l.log.Errorf("unable cancel htlc: %v", err)
|
||||||
return
|
return
|
||||||
@@ -3943,7 +3932,7 @@ func (l *channelLink) sendHTLCError(pd *lnwallet.PaymentDescriptor,
|
|||||||
// Send the appropriate failure message depending on whether we're
|
// Send the appropriate failure message depending on whether we're
|
||||||
// in a blinded route or not.
|
// in a blinded route or not.
|
||||||
if err := l.sendIncomingHTLCFailureMsg(
|
if err := l.sendIncomingHTLCFailureMsg(
|
||||||
pd.HtlcIndex, e, reason,
|
add.ID, e, reason,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
l.log.Errorf("unable to send HTLC failure: %v", err)
|
l.log.Errorf("unable to send HTLC failure: %v", err)
|
||||||
return
|
return
|
||||||
@@ -3963,12 +3952,12 @@ func (l *channelLink) sendHTLCError(pd *lnwallet.PaymentDescriptor,
|
|||||||
HtlcKey{
|
HtlcKey{
|
||||||
IncomingCircuit: models.CircuitKey{
|
IncomingCircuit: models.CircuitKey{
|
||||||
ChanID: l.ShortChanID(),
|
ChanID: l.ShortChanID(),
|
||||||
HtlcID: pd.HtlcIndex,
|
HtlcID: add.ID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
HtlcInfo{
|
HtlcInfo{
|
||||||
IncomingTimeLock: pd.Timeout,
|
IncomingTimeLock: add.Expiry,
|
||||||
IncomingAmt: pd.Amount,
|
IncomingAmt: add.Amount,
|
||||||
},
|
},
|
||||||
eventType,
|
eventType,
|
||||||
failure,
|
failure,
|
||||||
@@ -4027,7 +4016,9 @@ func (l *channelLink) sendIncomingHTLCFailureMsg(htlcIndex uint64,
|
|||||||
|
|
||||||
// The specification does not require that we set the onion
|
// The specification does not require that we set the onion
|
||||||
// blob.
|
// blob.
|
||||||
failureMsg := lnwire.NewInvalidBlinding(nil)
|
failureMsg := lnwire.NewInvalidBlinding(
|
||||||
|
fn.None[[lnwire.OnionPacketSize]byte](),
|
||||||
|
)
|
||||||
reason, err := e.EncryptFirstHop(failureMsg)
|
reason, err := e.EncryptFirstHop(failureMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -4065,9 +4056,10 @@ func (l *channelLink) sendIncomingHTLCFailureMsg(htlcIndex uint64,
|
|||||||
// sendMalformedHTLCError helper function which sends the malformed HTLC update
|
// sendMalformedHTLCError helper function which sends the malformed HTLC update
|
||||||
// to the payment sender.
|
// to the payment sender.
|
||||||
func (l *channelLink) sendMalformedHTLCError(htlcIndex uint64,
|
func (l *channelLink) sendMalformedHTLCError(htlcIndex uint64,
|
||||||
code lnwire.FailCode, onionBlob []byte, sourceRef *channeldb.AddRef) {
|
code lnwire.FailCode, onionBlob [lnwire.OnionPacketSize]byte,
|
||||||
|
sourceRef *channeldb.AddRef) {
|
||||||
|
|
||||||
shaOnionBlob := sha256.Sum256(onionBlob)
|
shaOnionBlob := sha256.Sum256(onionBlob[:])
|
||||||
err := l.channel.MalformedFailHTLC(htlcIndex, code, shaOnionBlob, sourceRef)
|
err := l.channel.MalformedFailHTLC(htlcIndex, code, shaOnionBlob, sourceRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.log.Errorf("unable cancel htlc: %v", err)
|
l.log.Errorf("unable cancel htlc: %v", err)
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ func (l *linkTestContext) receiveRevAndAckAliceToBob() {
|
|||||||
l.t.Fatalf("expected RevokeAndAck, got %T", msg)
|
l.t.Fatalf("expected RevokeAndAck, got %T", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, _, err := l.bobChannel.ReceiveRevocation(rev)
|
_, _, err := l.bobChannel.ReceiveRevocation(rev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.t.Fatalf("bob failed receiving revocation: %v", err)
|
l.t.Fatalf("bob failed receiving revocation: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2335,7 +2335,7 @@ func handleStateUpdate(link *channelLink,
|
|||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("expected RevokeAndAck got %T", msg)
|
return fmt.Errorf("expected RevokeAndAck got %T", msg)
|
||||||
}
|
}
|
||||||
_, _, _, _, err = remoteChannel.ReceiveRevocation(revoke)
|
_, _, err = remoteChannel.ReceiveRevocation(revoke)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to receive "+
|
return fmt.Errorf("unable to receive "+
|
||||||
"revocation: %v", err)
|
"revocation: %v", err)
|
||||||
@@ -2389,7 +2389,7 @@ func updateState(batchTick chan time.Time, link *channelLink,
|
|||||||
return fmt.Errorf("expected RevokeAndAck got %T",
|
return fmt.Errorf("expected RevokeAndAck got %T",
|
||||||
msg)
|
msg)
|
||||||
}
|
}
|
||||||
_, _, _, _, err = remoteChannel.ReceiveRevocation(revoke)
|
_, _, err = remoteChannel.ReceiveRevocation(revoke)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to receive "+
|
return fmt.Errorf("unable to receive "+
|
||||||
"revocation: %v", err)
|
"revocation: %v", err)
|
||||||
@@ -3643,7 +3643,7 @@ func TestChannelLinkTrimCircuitsRemoteCommit(t *testing.T) {
|
|||||||
rev, _, _, err := harness.bobChannel.RevokeCurrentCommitment()
|
rev, _, _, err := harness.bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "unable to revoke current commitment")
|
require.NoError(t, err, "unable to revoke current commitment")
|
||||||
|
|
||||||
_, _, _, _, err = alice.channel.ReceiveRevocation(rev)
|
_, _, err = alice.channel.ReceiveRevocation(rev)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
// Restart Alice's link, which simulates a disconnection with the remote
|
// Restart Alice's link, which simulates a disconnection with the remote
|
||||||
|
|||||||
+15
-25
@@ -1911,18 +1911,8 @@ 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, err := lnwallet.PayDescsFromRemoteLogUpdates(
|
switchPackets := make([]*htlcPacket, 0, len(fwdPkg.SettleFails))
|
||||||
fwdPkg.Source, fwdPkg.Height, fwdPkg.SettleFails,
|
for i, update := range fwdPkg.SettleFails {
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Unable to process remote log updates: %v",
|
|
||||||
err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switchPackets := make([]*htlcPacket, 0, len(settleFails))
|
|
||||||
for i, pd := range settleFails {
|
|
||||||
|
|
||||||
// Skip any settles or fails that have already been
|
// Skip any settles or fails that have already been
|
||||||
// acknowledged by the incoming link that originated the
|
// acknowledged by the incoming link that originated the
|
||||||
// forwarded Add.
|
// forwarded Add.
|
||||||
@@ -1930,20 +1920,18 @@ func (s *Switch) reforwardSettleFails(fwdPkgs []*channeldb.FwdPkg) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch pd.EntryType {
|
switch msg := update.UpdateMsg.(type) {
|
||||||
|
|
||||||
// A settle for an HTLC we previously forwarded HTLC has
|
// A settle for an HTLC we previously forwarded HTLC has
|
||||||
// been received. So we'll forward the HTLC to the
|
// been received. So we'll forward the HTLC to the
|
||||||
// switch which will handle propagating the settle to
|
// switch which will handle propagating the settle to
|
||||||
// the prior hop.
|
// the prior hop.
|
||||||
case lnwallet.Settle:
|
case *lnwire.UpdateFulfillHTLC:
|
||||||
|
destRef := fwdPkg.DestRef(uint16(i))
|
||||||
settlePacket := &htlcPacket{
|
settlePacket := &htlcPacket{
|
||||||
outgoingChanID: fwdPkg.Source,
|
outgoingChanID: fwdPkg.Source,
|
||||||
outgoingHTLCID: pd.ParentIndex,
|
outgoingHTLCID: msg.ID,
|
||||||
destRef: pd.DestRef,
|
destRef: &destRef,
|
||||||
htlc: &lnwire.UpdateFulfillHTLC{
|
htlc: msg,
|
||||||
PaymentPreimage: pd.RPreimage,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the packet to the batch to be forwarded, and
|
// Add the packet to the batch to be forwarded, and
|
||||||
@@ -1955,7 +1943,7 @@ func (s *Switch) reforwardSettleFails(fwdPkgs []*channeldb.FwdPkg) {
|
|||||||
// received. As a result a new slot will be freed up in our
|
// received. As a result a new slot will be freed up in our
|
||||||
// commitment state, so we'll forward this to the switch so the
|
// commitment state, so we'll forward this to the switch so the
|
||||||
// backwards undo can continue.
|
// backwards undo can continue.
|
||||||
case lnwallet.Fail:
|
case *lnwire.UpdateFailHTLC:
|
||||||
// Fetch the reason the HTLC was canceled so
|
// Fetch the reason the HTLC was canceled so
|
||||||
// we can continue to propagate it. This
|
// we can continue to propagate it. This
|
||||||
// failure originated from another node, so
|
// failure originated from another node, so
|
||||||
@@ -1964,11 +1952,13 @@ func (s *Switch) reforwardSettleFails(fwdPkgs []*channeldb.FwdPkg) {
|
|||||||
// additional circuit information for us.
|
// additional circuit information for us.
|
||||||
failPacket := &htlcPacket{
|
failPacket := &htlcPacket{
|
||||||
outgoingChanID: fwdPkg.Source,
|
outgoingChanID: fwdPkg.Source,
|
||||||
outgoingHTLCID: pd.ParentIndex,
|
outgoingHTLCID: msg.ID,
|
||||||
destRef: pd.DestRef,
|
destRef: &channeldb.SettleFailRef{
|
||||||
htlc: &lnwire.UpdateFailHTLC{
|
Source: fwdPkg.Source,
|
||||||
Reason: lnwire.OpaqueReason(pd.FailReason),
|
Height: fwdPkg.Height,
|
||||||
|
Index: uint16(i),
|
||||||
},
|
},
|
||||||
|
htlc: msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the packet to the batch to be forwarded, and
|
// Add the packet to the batch to be forwarded, and
|
||||||
|
|||||||
+173
-425
File diff suppressed because it is too large.
Load diff
+121
-103
@@ -132,7 +132,7 @@ func testAddSettleWorkflow(t *testing.T, tweakless bool,
|
|||||||
// Alice then processes this revocation, sending her own revocation for
|
// Alice then processes this revocation, sending her own revocation for
|
||||||
// her prior commitment transaction. Alice shouldn't have any HTLCs to
|
// her prior commitment transaction. Alice shouldn't have any HTLCs to
|
||||||
// forward since she's sending an outgoing HTLC.
|
// forward since she's sending an outgoing HTLC.
|
||||||
fwdPkg, _, _, _, err := aliceChannel.ReceiveRevocation(bobRevocation)
|
fwdPkg, _, err := aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to process bob's revocation")
|
require.NoError(t, err, "alice unable to process bob's revocation")
|
||||||
if len(fwdPkg.Adds) != 0 {
|
if len(fwdPkg.Adds) != 0 {
|
||||||
t.Fatalf("alice forwards %v add htlcs, should forward none",
|
t.Fatalf("alice forwards %v add htlcs, should forward none",
|
||||||
@@ -157,7 +157,7 @@ func testAddSettleWorkflow(t *testing.T, tweakless bool,
|
|||||||
// is fully locked in within both commitment transactions. Bob should
|
// is fully locked in within both commitment transactions. Bob should
|
||||||
// also be able to forward an HTLC now that the HTLC has been locked
|
// also be able to forward an HTLC now that the HTLC has been locked
|
||||||
// into both commitment transactions.
|
// into both commitment transactions.
|
||||||
fwdPkg, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
fwdPkg, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to process alice's revocation")
|
require.NoError(t, err, "bob unable to process alice's revocation")
|
||||||
if len(fwdPkg.Adds) != 1 {
|
if len(fwdPkg.Adds) != 1 {
|
||||||
t.Fatalf("bob forwards %v add htlcs, should only forward one",
|
t.Fatalf("bob forwards %v add htlcs, should only forward one",
|
||||||
@@ -249,7 +249,7 @@ func testAddSettleWorkflow(t *testing.T, tweakless bool,
|
|||||||
aliceNewCommit, err = aliceChannel.SignNextCommitment()
|
aliceNewCommit, err = aliceChannel.SignNextCommitment()
|
||||||
require.NoError(t, err, "alice unable to sign new commitment")
|
require.NoError(t, err, "alice unable to sign new commitment")
|
||||||
|
|
||||||
fwdPkg, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation2)
|
fwdPkg, _, err = bobChannel.ReceiveRevocation(aliceRevocation2)
|
||||||
require.NoError(t, err, "bob unable to process alice's revocation")
|
require.NoError(t, err, "bob unable to process alice's revocation")
|
||||||
if len(fwdPkg.Adds) != 0 {
|
if len(fwdPkg.Adds) != 0 {
|
||||||
t.Fatalf("bob forwards %v add htlcs, should forward none",
|
t.Fatalf("bob forwards %v add htlcs, should forward none",
|
||||||
@@ -286,7 +286,7 @@ func testAddSettleWorkflow(t *testing.T, tweakless bool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fwdPkg, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation2)
|
fwdPkg, _, err = aliceChannel.ReceiveRevocation(bobRevocation2)
|
||||||
require.NoError(t, err, "alice unable to process bob's revocation")
|
require.NoError(t, err, "alice unable to process bob's revocation")
|
||||||
if len(fwdPkg.Adds) != 0 {
|
if len(fwdPkg.Adds) != 0 {
|
||||||
// Alice should now be able to forward the settlement HTLC to
|
// Alice should now be able to forward the settlement HTLC to
|
||||||
@@ -468,7 +468,7 @@ func TestChannelZeroAddLocalHeight(t *testing.T) {
|
|||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// We now restore Alice's channel as this was the point at which
|
// We now restore Alice's channel as this was the point at which
|
||||||
@@ -644,7 +644,7 @@ func testCommitHTLCSigTieBreak(t *testing.T, restart bool) {
|
|||||||
|
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "unable to revoke bob's commitment")
|
require.NoError(t, err, "unable to revoke bob's commitment")
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "unable to receive bob's revocation")
|
require.NoError(t, err, "unable to receive bob's revocation")
|
||||||
|
|
||||||
// Now have Bob initiate the second half of the commitment dance. Here
|
// Now have Bob initiate the second half of the commitment dance. Here
|
||||||
@@ -2556,7 +2556,7 @@ func TestUpdateFeeSenderCommits(t *testing.T) {
|
|||||||
// Alice receives the revocation of the old one, and can now assume
|
// Alice receives the revocation of the old one, and can now assume
|
||||||
// that Bob's received everything up to the signature she sent,
|
// that Bob's received everything up to the signature she sent,
|
||||||
// including the HTLC and fee update.
|
// including the HTLC and fee update.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to process bob's revocation")
|
require.NoError(t, err, "alice unable to process bob's revocation")
|
||||||
|
|
||||||
// Alice receives new signature from Bob, and assumes this covers the
|
// Alice receives new signature from Bob, and assumes this covers the
|
||||||
@@ -2584,7 +2584,7 @@ func TestUpdateFeeSenderCommits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bob receives revocation from Alice.
|
// Bob receives revocation from Alice.
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to process alice's revocation")
|
require.NoError(t, err, "bob unable to process alice's revocation")
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2644,7 +2644,7 @@ func TestUpdateFeeReceiverCommits(t *testing.T) {
|
|||||||
require.NoError(t, err, "unable to generate bob revocation")
|
require.NoError(t, err, "unable to generate bob revocation")
|
||||||
|
|
||||||
// Bob receives the revocation of the old commitment
|
// Bob receives the revocation of the old commitment
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "alice unable to process bob's revocation")
|
require.NoError(t, err, "alice unable to process bob's revocation")
|
||||||
|
|
||||||
// Alice will sign next commitment. Since she sent the revocation, she
|
// Alice will sign next commitment. Since she sent the revocation, she
|
||||||
@@ -2685,7 +2685,7 @@ func TestUpdateFeeReceiverCommits(t *testing.T) {
|
|||||||
|
|
||||||
// Alice receives revocation from Bob, and can now be sure that Bob
|
// Alice receives revocation from Bob, and can now be sure that Bob
|
||||||
// received the two updates, and they are considered locked in.
|
// received the two updates, and they are considered locked in.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "bob unable to process alice's revocation")
|
require.NoError(t, err, "bob unable to process alice's revocation")
|
||||||
|
|
||||||
// Alice will receive the signature from Bob, which will cover what was
|
// Alice will receive the signature from Bob, which will cover what was
|
||||||
@@ -2713,7 +2713,7 @@ func TestUpdateFeeReceiverCommits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bob receives revocation from Alice.
|
// Bob receives revocation from Alice.
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to process alice's revocation")
|
require.NoError(t, err, "bob unable to process alice's revocation")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2822,7 +2822,7 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) {
|
|||||||
// Alice receives the revocation of the old one, and can now assume that
|
// Alice receives the revocation of the old one, and can now assume that
|
||||||
// Bob's received everything up to the signature she sent, including the
|
// Bob's received everything up to the signature she sent, including the
|
||||||
// HTLC and fee update.
|
// HTLC and fee update.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to process bob's revocation")
|
require.NoError(t, err, "alice unable to process bob's revocation")
|
||||||
|
|
||||||
// Alice receives new signature from Bob, and assumes this covers the
|
// Alice receives new signature from Bob, and assumes this covers the
|
||||||
@@ -2852,7 +2852,7 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bob receives revocation from Alice.
|
// Bob receives revocation from Alice.
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to process alice's revocation")
|
require.NoError(t, err, "bob unable to process alice's revocation")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3267,13 +3267,13 @@ func testChanSyncOweCommitment(t *testing.T, chanType channeldb.ChannelType) {
|
|||||||
require.NoError(t, err, "unable to revoke bob commitment")
|
require.NoError(t, err, "unable to revoke bob commitment")
|
||||||
bobNewCommit, err := bobChannel.SignNextCommitment()
|
bobNewCommit, err := bobChannel.SignNextCommitment()
|
||||||
require.NoError(t, err, "bob unable to sign commitment")
|
require.NoError(t, err, "bob unable to sign commitment")
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to recv revocation")
|
require.NoError(t, err, "alice unable to recv revocation")
|
||||||
err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs)
|
err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs)
|
||||||
require.NoError(t, err, "alice unable to rev bob's commitment")
|
require.NoError(t, err, "alice unable to rev bob's commitment")
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "alice unable to revoke commitment")
|
require.NoError(t, err, "alice unable to revoke commitment")
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to recv revocation")
|
require.NoError(t, err, "bob unable to recv revocation")
|
||||||
|
|
||||||
// At this point, we'll now assert that their log states are what we
|
// At this point, we'll now assert that their log states are what we
|
||||||
@@ -3466,7 +3466,7 @@ func testChanSyncOweCommitmentPendingRemote(t *testing.T,
|
|||||||
t.Fatalf("unable to revoke commitment: %v", err)
|
t.Fatalf("unable to revoke commitment: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevoke)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevoke)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to revoke commitment: %v", err)
|
t.Fatalf("unable to revoke commitment: %v", err)
|
||||||
}
|
}
|
||||||
@@ -3502,7 +3502,7 @@ func testChanSyncOweCommitmentPendingRemote(t *testing.T,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevoke)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevoke)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -3603,7 +3603,7 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) {
|
|||||||
bobNewCommit, err := bobChannel.SignNextCommitment()
|
bobNewCommit, err := bobChannel.SignNextCommitment()
|
||||||
require.NoError(t, err, "bob unable to sign commitment")
|
require.NoError(t, err, "bob unable to sign commitment")
|
||||||
|
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to recv revocation")
|
require.NoError(t, err, "alice unable to recv revocation")
|
||||||
err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs)
|
err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs)
|
||||||
require.NoError(t, err, "alice unable to rev bob's commitment")
|
require.NoError(t, err, "alice unable to rev bob's commitment")
|
||||||
@@ -3698,7 +3698,7 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) {
|
|||||||
|
|
||||||
// We'll continue by then allowing bob to process Alice's revocation
|
// We'll continue by then allowing bob to process Alice's revocation
|
||||||
// message.
|
// message.
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to recv revocation")
|
require.NoError(t, err, "bob unable to recv revocation")
|
||||||
|
|
||||||
// Finally, Alice will add an HTLC over her own such that we assert the
|
// Finally, Alice will add an HTLC over her own such that we assert the
|
||||||
@@ -3916,13 +3916,13 @@ func testChanSyncOweRevocationAndCommit(t *testing.T,
|
|||||||
|
|
||||||
// We'll now finish the state transition by having Alice process both
|
// We'll now finish the state transition by having Alice process both
|
||||||
// messages, and send her final revocation.
|
// messages, and send her final revocation.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to recv revocation")
|
require.NoError(t, err, "alice unable to recv revocation")
|
||||||
err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs)
|
err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs)
|
||||||
require.NoError(t, err, "alice unable to recv bob's commitment")
|
require.NoError(t, err, "alice unable to recv bob's commitment")
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "alice unable to revoke commitment")
|
require.NoError(t, err, "alice unable to revoke commitment")
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to recv revocation")
|
require.NoError(t, err, "bob unable to recv revocation")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4016,7 +4016,7 @@ func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T,
|
|||||||
// local commit chain getting height > remote commit chain.
|
// local commit chain getting height > remote commit chain.
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "alice unable to revoke commitment")
|
require.NoError(t, err, "alice unable to revoke commitment")
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to recv revocation")
|
require.NoError(t, err, "bob unable to recv revocation")
|
||||||
|
|
||||||
// Next, Alice will settle that incoming HTLC, then we'll start the
|
// Next, Alice will settle that incoming HTLC, then we'll start the
|
||||||
@@ -4148,7 +4148,7 @@ func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T,
|
|||||||
// Now, we'll continue the exchange, sending Bob's revocation and
|
// Now, we'll continue the exchange, sending Bob's revocation and
|
||||||
// signature message to Alice, ending with Alice sending her revocation
|
// signature message to Alice, ending with Alice sending her revocation
|
||||||
// message to Bob.
|
// message to Bob.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to recv revocation")
|
require.NoError(t, err, "alice unable to recv revocation")
|
||||||
err = aliceChannel.ReceiveNewCommitment(&CommitSigs{
|
err = aliceChannel.ReceiveNewCommitment(&CommitSigs{
|
||||||
CommitSig: bobSigMsg.CommitSig,
|
CommitSig: bobSigMsg.CommitSig,
|
||||||
@@ -4158,7 +4158,7 @@ func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T,
|
|||||||
require.NoError(t, err, "alice unable to rev bob's commitment")
|
require.NoError(t, err, "alice unable to rev bob's commitment")
|
||||||
aliceRevocation, _, _, err = aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err = aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "alice unable to revoke commitment")
|
require.NoError(t, err, "alice unable to revoke commitment")
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to recv revocation")
|
require.NoError(t, err, "bob unable to recv revocation")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4584,13 +4584,13 @@ func TestChannelRetransmissionFeeUpdate(t *testing.T) {
|
|||||||
require.NoError(t, err, "unable to revoke bob commitment")
|
require.NoError(t, err, "unable to revoke bob commitment")
|
||||||
bobNewCommit, err := bobChannel.SignNextCommitment()
|
bobNewCommit, err := bobChannel.SignNextCommitment()
|
||||||
require.NoError(t, err, "bob unable to sign commitment")
|
require.NoError(t, err, "bob unable to sign commitment")
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to recv revocation")
|
require.NoError(t, err, "alice unable to recv revocation")
|
||||||
err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs)
|
err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs)
|
||||||
require.NoError(t, err, "alice unable to rev bob's commitment")
|
require.NoError(t, err, "alice unable to rev bob's commitment")
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "alice unable to revoke commitment")
|
require.NoError(t, err, "alice unable to revoke commitment")
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to recv revocation")
|
require.NoError(t, err, "bob unable to recv revocation")
|
||||||
|
|
||||||
// Both parties should now have the latest fee rate locked-in.
|
// Both parties should now have the latest fee rate locked-in.
|
||||||
@@ -4782,13 +4782,13 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) {
|
|||||||
require.NoError(t, err, "unable to revoke bob commitment")
|
require.NoError(t, err, "unable to revoke bob commitment")
|
||||||
bobNewCommitSigs, err := bobChannel.SignNextCommitment()
|
bobNewCommitSigs, err := bobChannel.SignNextCommitment()
|
||||||
require.NoError(t, err, "bob unable to sign commitment")
|
require.NoError(t, err, "bob unable to sign commitment")
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "alice unable to recv revocation")
|
require.NoError(t, err, "alice unable to recv revocation")
|
||||||
err = aliceChannel.ReceiveNewCommitment(bobNewCommitSigs.CommitSigs)
|
err = aliceChannel.ReceiveNewCommitment(bobNewCommitSigs.CommitSigs)
|
||||||
require.NoError(t, err, "alice unable to rev bob's commitment")
|
require.NoError(t, err, "alice unable to rev bob's commitment")
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "alice unable to revoke commitment")
|
require.NoError(t, err, "alice unable to revoke commitment")
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to recv revocation")
|
require.NoError(t, err, "bob unable to recv revocation")
|
||||||
|
|
||||||
// Both parties should now have the latest fee rate locked-in.
|
// Both parties should now have the latest fee rate locked-in.
|
||||||
@@ -5497,7 +5497,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Alice should detect that she doesn't need to forward any HTLC's.
|
// Alice should detect that she doesn't need to forward any HTLC's.
|
||||||
fwdPkg, _, _, _, err := aliceChannel.ReceiveRevocation(bobRevocation)
|
fwdPkg, _, err := aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -5528,7 +5528,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) {
|
|||||||
|
|
||||||
// Bob should now detect that he now has 2 incoming HTLC's that he can
|
// Bob should now detect that he now has 2 incoming HTLC's that he can
|
||||||
// forward along.
|
// forward along.
|
||||||
fwdPkg, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
fwdPkg, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -5573,7 +5573,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) {
|
|||||||
// At this point, Bob receives the revocation from Alice, which is now
|
// At this point, Bob receives the revocation from Alice, which is now
|
||||||
// his signal to examine all the HTLC's that have been locked in to
|
// his signal to examine all the HTLC's that have been locked in to
|
||||||
// process.
|
// process.
|
||||||
fwdPkg, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
fwdPkg, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -5622,22 +5622,31 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) {
|
|||||||
|
|
||||||
// Alice should detect that she doesn't need to forward any Adds's, but
|
// Alice should detect that she doesn't need to forward any Adds's, but
|
||||||
// that the Fail has been locked in an can be forwarded.
|
// that the Fail has been locked in an can be forwarded.
|
||||||
_, adds, settleFails, _, err := aliceChannel.ReceiveRevocation(bobRevocation)
|
fwdPkg, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adds := fwdPkg.Adds
|
||||||
|
settleFails := fwdPkg.SettleFails
|
||||||
if len(adds) != 0 {
|
if len(adds) != 0 {
|
||||||
t.Fatalf("alice shouldn't forward any HTLC's, instead wants to "+
|
t.Fatalf("alice shouldn't forward any HTLC's, instead wants to "+
|
||||||
"forward %v htlcs", len(adds))
|
"forward %v htlcs", len(fwdPkg.Adds))
|
||||||
}
|
}
|
||||||
if len(settleFails) != 1 {
|
if len(settleFails) != 1 {
|
||||||
t.Fatalf("alice should only forward %d HTLC's, instead wants to "+
|
t.Fatalf("alice should only forward %d HTLC's, instead wants to "+
|
||||||
"forward %v htlcs", 1, len(settleFails))
|
"forward %v htlcs", 1, len(fwdPkg.SettleFails))
|
||||||
}
|
}
|
||||||
if settleFails[0].ParentIndex != htlc.ID {
|
|
||||||
|
fail, ok := settleFails[0].UpdateMsg.(*lnwire.UpdateFailHTLC)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected UpdateFailHTLC, got %T",
|
||||||
|
settleFails[0].UpdateMsg)
|
||||||
|
}
|
||||||
|
if fail.ID != htlc.ID {
|
||||||
t.Fatalf("alice should forward fail for htlcid=%d, instead "+
|
t.Fatalf("alice should forward fail for htlcid=%d, instead "+
|
||||||
"forwarding id=%d", htlc.ID,
|
"forwarding id=%d", htlc.ID,
|
||||||
settleFails[0].ParentIndex)
|
fail.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll now restart both Alice and Bob. This emulates a reconnection
|
// We'll now restart both Alice and Bob. This emulates a reconnection
|
||||||
@@ -5671,7 +5680,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) {
|
|||||||
|
|
||||||
// Alice should detect that she doesn't need to forward any HTLC's, as
|
// Alice should detect that she doesn't need to forward any HTLC's, as
|
||||||
// the updates haven't been committed by Bob yet.
|
// the updates haven't been committed by Bob yet.
|
||||||
fwdPkg, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
fwdPkg, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -5702,7 +5711,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) {
|
|||||||
|
|
||||||
// Bob should detect that he has nothing to forward, as he hasn't
|
// Bob should detect that he has nothing to forward, as he hasn't
|
||||||
// received any HTLCs.
|
// received any HTLCs.
|
||||||
fwdPkg, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
fwdPkg, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -5732,10 +5741,13 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) {
|
|||||||
|
|
||||||
// When Alice receives the revocation, she should detect that she
|
// When Alice receives the revocation, she should detect that she
|
||||||
// can now forward the freshly locked-in Fail.
|
// can now forward the freshly locked-in Fail.
|
||||||
_, adds, settleFails, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
fwdPkg, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adds = fwdPkg.Adds
|
||||||
|
settleFails = fwdPkg.SettleFails
|
||||||
if len(adds) != 0 {
|
if len(adds) != 0 {
|
||||||
t.Fatalf("alice shouldn't forward any HTLC's, instead wants to "+
|
t.Fatalf("alice shouldn't forward any HTLC's, instead wants to "+
|
||||||
"forward %v htlcs", len(adds))
|
"forward %v htlcs", len(adds))
|
||||||
@@ -5744,10 +5756,16 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) {
|
|||||||
t.Fatalf("alice should only forward one HTLC, instead wants to "+
|
t.Fatalf("alice should only forward one HTLC, instead wants to "+
|
||||||
"forward %v htlcs", len(settleFails))
|
"forward %v htlcs", len(settleFails))
|
||||||
}
|
}
|
||||||
if settleFails[0].ParentIndex != htlc2.ID {
|
|
||||||
|
fail, ok = settleFails[0].UpdateMsg.(*lnwire.UpdateFailHTLC)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected UpdateFailHTLC, got %T",
|
||||||
|
settleFails[0].UpdateMsg)
|
||||||
|
}
|
||||||
|
if fail.ID != htlc2.ID {
|
||||||
t.Fatalf("alice should forward fail for htlcid=%d, instead "+
|
t.Fatalf("alice should forward fail for htlcid=%d, instead "+
|
||||||
"forwarding id=%d", htlc2.ID,
|
"forwarding id=%d", htlc2.ID,
|
||||||
settleFails[0].ParentIndex)
|
fail.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6347,13 +6365,13 @@ func TestMaxAsynchronousHtlcs(t *testing.T) {
|
|||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "unable to revoke revocation")
|
require.NoError(t, err, "unable to revoke revocation")
|
||||||
|
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "unable to revoke revocation")
|
require.NoError(t, err, "unable to revoke revocation")
|
||||||
|
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
// Send the final Add which should succeed as in step 6.
|
// Send the final Add which should succeed as in step 6.
|
||||||
@@ -6916,8 +6934,8 @@ func TestNewBreachRetributionSkipsDustHtlcs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// compareHtlcs compares two PaymentDescriptors.
|
// compareHtlcs compares two paymentDescriptors.
|
||||||
func compareHtlcs(htlc1, htlc2 *PaymentDescriptor) error {
|
func compareHtlcs(htlc1, htlc2 *paymentDescriptor) error {
|
||||||
if htlc1.LogIndex != htlc2.LogIndex {
|
if htlc1.LogIndex != htlc2.LogIndex {
|
||||||
return fmt.Errorf("htlc log index did not match")
|
return fmt.Errorf("htlc log index did not match")
|
||||||
}
|
}
|
||||||
@@ -6935,7 +6953,7 @@ func compareHtlcs(htlc1, htlc2 *PaymentDescriptor) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compareIndexes is a helper method to compare two index maps.
|
// compareIndexes is a helper method to compare two index maps.
|
||||||
func compareIndexes(a, b map[uint64]*fn.Node[*PaymentDescriptor]) error {
|
func compareIndexes(a, b map[uint64]*fn.Node[*paymentDescriptor]) error {
|
||||||
for k1, e1 := range a {
|
for k1, e1 := range a {
|
||||||
e2, ok := b[k1]
|
e2, ok := b[k1]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -7035,7 +7053,7 @@ func TestChannelRestoreUpdateLogs(t *testing.T) {
|
|||||||
// sent. However her local commitment chain still won't include the
|
// sent. However her local commitment chain still won't include the
|
||||||
// state with the HTLC, since she hasn't received a new commitment
|
// state with the HTLC, since she hasn't received a new commitment
|
||||||
// signature from Bob yet.
|
// signature from Bob yet.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
// Now make Alice send and sign an additional HTLC. We don't let Bob
|
// Now make Alice send and sign an additional HTLC. We don't let Bob
|
||||||
@@ -7211,7 +7229,7 @@ func TestChannelRestoreUpdateLogsFailedHTLC(t *testing.T) {
|
|||||||
|
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "unable to revoke commitment")
|
require.NoError(t, err, "unable to revoke commitment")
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to process alice's revocation")
|
require.NoError(t, err, "bob unable to process alice's revocation")
|
||||||
|
|
||||||
// At this point Alice has advanced her local commitment chain to a
|
// At this point Alice has advanced her local commitment chain to a
|
||||||
@@ -7241,7 +7259,7 @@ func TestChannelRestoreUpdateLogsFailedHTLC(t *testing.T) {
|
|||||||
// the corresponding Fail from the local update log.
|
// the corresponding Fail from the local update log.
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "unable to revoke commitment")
|
require.NoError(t, err, "unable to revoke commitment")
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
assertInLogs(t, aliceChannel, 0, 0, 0, 0)
|
assertInLogs(t, aliceChannel, 0, 0, 0, 0)
|
||||||
@@ -7404,7 +7422,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) {
|
|||||||
t.Fatalf("unable to create new channel: %v", err)
|
t.Fatalf("unable to create new channel: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var pd *PaymentDescriptor
|
var pd *paymentDescriptor
|
||||||
if remoteLog {
|
if remoteLog {
|
||||||
h := newChannel.updateLogs.Local.lookupHtlc(htlcIndex)
|
h := newChannel.updateLogs.Local.lookupHtlc(htlcIndex)
|
||||||
if h != nil {
|
if h != nil {
|
||||||
@@ -7466,7 +7484,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) {
|
|||||||
bobChannel = restoreAndAssertCommitHeights(t, bobChannel, true, 0, 1, 0)
|
bobChannel = restoreAndAssertCommitHeights(t, bobChannel, true, 0, 1, 0)
|
||||||
|
|
||||||
// Alice receives the revocation, ACKing her pending commitment.
|
// Alice receives the revocation, ACKing her pending commitment.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
// However, the HTLC is still not locked into her local commitment, so
|
// However, the HTLC is still not locked into her local commitment, so
|
||||||
@@ -7495,7 +7513,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) {
|
|||||||
t, aliceChannel, false, 0, 1, 1,
|
t, aliceChannel, false, 0, 1, 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
// Alice ACKing Bob's pending commitment shouldn't change the heights
|
// Alice ACKing Bob's pending commitment shouldn't change the heights
|
||||||
@@ -7540,7 +7558,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) {
|
|||||||
bobChannel = restoreAndAssertCommitHeights(t, bobChannel, true, 1, 2, 0)
|
bobChannel = restoreAndAssertCommitHeights(t, bobChannel, true, 1, 2, 0)
|
||||||
|
|
||||||
// Alice receives the revocation, ACKing her pending commitment for Bob.
|
// Alice receives the revocation, ACKing her pending commitment for Bob.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
// Alice receiving Bob's revocation should bump both addCommitHeightRemote
|
// Alice receiving Bob's revocation should bump both addCommitHeightRemote
|
||||||
@@ -7578,7 +7596,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) {
|
|||||||
|
|
||||||
// Bob receives the revocation, which should set both addCommitHeightRemote
|
// Bob receives the revocation, which should set both addCommitHeightRemote
|
||||||
// fields to 2.
|
// fields to 2.
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "unable to receive revocation")
|
require.NoError(t, err, "unable to receive revocation")
|
||||||
|
|
||||||
bobChannel = restoreAndAssertCommitHeights(t, bobChannel, true, 0, 2, 2)
|
bobChannel = restoreAndAssertCommitHeights(t, bobChannel, true, 0, 2, 2)
|
||||||
@@ -7681,7 +7699,7 @@ func TestForceCloseBorkedState(t *testing.T) {
|
|||||||
|
|
||||||
// At this point, all channel mutating methods should now fail as they
|
// At this point, all channel mutating methods should now fail as they
|
||||||
// shouldn't be able to proceed if the channel is borked.
|
// shouldn't be able to proceed if the channel is borked.
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(revokeMsg)
|
_, _, err = aliceChannel.ReceiveRevocation(revokeMsg)
|
||||||
if err != channeldb.ErrChanBorked {
|
if err != channeldb.ErrChanBorked {
|
||||||
t.Fatalf("advance commitment tail should have failed")
|
t.Fatalf("advance commitment tail should have failed")
|
||||||
}
|
}
|
||||||
@@ -8173,8 +8191,8 @@ func TestFetchParent(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
whoseCommitChain lntypes.ChannelParty
|
whoseCommitChain lntypes.ChannelParty
|
||||||
whoseUpdateLog lntypes.ChannelParty
|
whoseUpdateLog lntypes.ChannelParty
|
||||||
localEntries []*PaymentDescriptor
|
localEntries []*paymentDescriptor
|
||||||
remoteEntries []*PaymentDescriptor
|
remoteEntries []*paymentDescriptor
|
||||||
|
|
||||||
// parentIndex is the parent index of the entry that we will
|
// parentIndex is the parent index of the entry that we will
|
||||||
// lookup with fetch parent.
|
// lookup with fetch parent.
|
||||||
@@ -8208,7 +8226,7 @@ func TestFetchParent(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "remote log + chain, remote add height 0",
|
name: "remote log + chain, remote add height 0",
|
||||||
localEntries: nil,
|
localEntries: nil,
|
||||||
remoteEntries: []*PaymentDescriptor{
|
remoteEntries: []*paymentDescriptor{
|
||||||
// This entry will be added at log index =0.
|
// This entry will be added at log index =0.
|
||||||
{
|
{
|
||||||
HtlcIndex: 1,
|
HtlcIndex: 1,
|
||||||
@@ -8230,7 +8248,7 @@ func TestFetchParent(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "remote log, local chain, local add height 0",
|
name: "remote log, local chain, local add height 0",
|
||||||
remoteEntries: []*PaymentDescriptor{
|
remoteEntries: []*paymentDescriptor{
|
||||||
// This entry will be added at log index =0.
|
// This entry will be added at log index =0.
|
||||||
{
|
{
|
||||||
HtlcIndex: 1,
|
HtlcIndex: 1,
|
||||||
@@ -8253,7 +8271,7 @@ func TestFetchParent(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "local log + chain, local add height 0",
|
name: "local log + chain, local add height 0",
|
||||||
localEntries: []*PaymentDescriptor{
|
localEntries: []*paymentDescriptor{
|
||||||
// This entry will be added at log index =0.
|
// This entry will be added at log index =0.
|
||||||
{
|
{
|
||||||
HtlcIndex: 1,
|
HtlcIndex: 1,
|
||||||
@@ -8277,7 +8295,7 @@ func TestFetchParent(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
name: "local log + remote chain, remote add height 0",
|
name: "local log + remote chain, remote add height 0",
|
||||||
localEntries: []*PaymentDescriptor{
|
localEntries: []*paymentDescriptor{
|
||||||
// This entry will be added at log index =0.
|
// This entry will be added at log index =0.
|
||||||
{
|
{
|
||||||
HtlcIndex: 1,
|
HtlcIndex: 1,
|
||||||
@@ -8301,7 +8319,7 @@ func TestFetchParent(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "remote log found",
|
name: "remote log found",
|
||||||
localEntries: nil,
|
localEntries: nil,
|
||||||
remoteEntries: []*PaymentDescriptor{
|
remoteEntries: []*paymentDescriptor{
|
||||||
// This entry will be added at log index =0.
|
// This entry will be added at log index =0.
|
||||||
{
|
{
|
||||||
HtlcIndex: 1,
|
HtlcIndex: 1,
|
||||||
@@ -8324,7 +8342,7 @@ func TestFetchParent(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "local log found",
|
name: "local log found",
|
||||||
localEntries: []*PaymentDescriptor{
|
localEntries: []*paymentDescriptor{
|
||||||
// This entry will be added at log index =0.
|
// This entry will be added at log index =0.
|
||||||
{
|
{
|
||||||
HtlcIndex: 1,
|
HtlcIndex: 1,
|
||||||
@@ -8370,7 +8388,7 @@ func TestFetchParent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parent, err := lc.fetchParent(
|
parent, err := lc.fetchParent(
|
||||||
&PaymentDescriptor{
|
&paymentDescriptor{
|
||||||
ParentIndex: test.parentIndex,
|
ParentIndex: test.parentIndex,
|
||||||
},
|
},
|
||||||
test.whoseCommitChain,
|
test.whoseCommitChain,
|
||||||
@@ -8433,8 +8451,8 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
ourHtlcs []*PaymentDescriptor
|
ourHtlcs []*paymentDescriptor
|
||||||
theirHtlcs []*PaymentDescriptor
|
theirHtlcs []*paymentDescriptor
|
||||||
whoseCommitChain lntypes.ChannelParty
|
whoseCommitChain lntypes.ChannelParty
|
||||||
mutateState bool
|
mutateState bool
|
||||||
|
|
||||||
@@ -8466,7 +8484,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
name: "our fee update is applied",
|
name: "our fee update is applied",
|
||||||
whoseCommitChain: lntypes.Local,
|
whoseCommitChain: lntypes.Local,
|
||||||
mutateState: false,
|
mutateState: false,
|
||||||
ourHtlcs: []*PaymentDescriptor{
|
ourHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
Amount: ourFeeUpdateAmt,
|
Amount: ourFeeUpdateAmt,
|
||||||
EntryType: FeeUpdate,
|
EntryType: FeeUpdate,
|
||||||
@@ -8483,8 +8501,8 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
name: "their fee update is applied",
|
name: "their fee update is applied",
|
||||||
whoseCommitChain: lntypes.Local,
|
whoseCommitChain: lntypes.Local,
|
||||||
mutateState: false,
|
mutateState: false,
|
||||||
ourHtlcs: []*PaymentDescriptor{},
|
ourHtlcs: []*paymentDescriptor{},
|
||||||
theirHtlcs: []*PaymentDescriptor{
|
theirHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
Amount: theirFeeUpdateAmt,
|
Amount: theirFeeUpdateAmt,
|
||||||
EntryType: FeeUpdate,
|
EntryType: FeeUpdate,
|
||||||
@@ -8501,14 +8519,14 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
name: "htlcs adds without settles",
|
name: "htlcs adds without settles",
|
||||||
whoseCommitChain: lntypes.Local,
|
whoseCommitChain: lntypes.Local,
|
||||||
mutateState: false,
|
mutateState: false,
|
||||||
ourHtlcs: []*PaymentDescriptor{
|
ourHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
EntryType: Add,
|
EntryType: Add,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
theirHtlcs: []*PaymentDescriptor{
|
theirHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8535,7 +8553,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
name: "our htlc settled, state mutated",
|
name: "our htlc settled, state mutated",
|
||||||
whoseCommitChain: lntypes.Local,
|
whoseCommitChain: lntypes.Local,
|
||||||
mutateState: true,
|
mutateState: true,
|
||||||
ourHtlcs: []*PaymentDescriptor{
|
ourHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8543,7 +8561,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
addCommitHeightLocal: addHeight,
|
addCommitHeightLocal: addHeight,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
theirHtlcs: []*PaymentDescriptor{
|
theirHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8570,7 +8588,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
name: "our htlc settled, state not mutated",
|
name: "our htlc settled, state not mutated",
|
||||||
whoseCommitChain: lntypes.Local,
|
whoseCommitChain: lntypes.Local,
|
||||||
mutateState: false,
|
mutateState: false,
|
||||||
ourHtlcs: []*PaymentDescriptor{
|
ourHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8578,7 +8596,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
addCommitHeightLocal: addHeight,
|
addCommitHeightLocal: addHeight,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
theirHtlcs: []*PaymentDescriptor{
|
theirHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8605,7 +8623,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
name: "their htlc settled, state mutated",
|
name: "their htlc settled, state mutated",
|
||||||
whoseCommitChain: lntypes.Local,
|
whoseCommitChain: lntypes.Local,
|
||||||
mutateState: true,
|
mutateState: true,
|
||||||
ourHtlcs: []*PaymentDescriptor{
|
ourHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8620,7 +8638,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
ParentIndex: 1,
|
ParentIndex: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
theirHtlcs: []*PaymentDescriptor{
|
theirHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8649,7 +8667,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
|
|
||||||
whoseCommitChain: lntypes.Local,
|
whoseCommitChain: lntypes.Local,
|
||||||
mutateState: false,
|
mutateState: false,
|
||||||
ourHtlcs: []*PaymentDescriptor{
|
ourHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8664,7 +8682,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
ParentIndex: 0,
|
ParentIndex: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
theirHtlcs: []*PaymentDescriptor{
|
theirHtlcs: []*paymentDescriptor{
|
||||||
{
|
{
|
||||||
HtlcIndex: 0,
|
HtlcIndex: 0,
|
||||||
Amount: htlcAddAmount,
|
Amount: htlcAddAmount,
|
||||||
@@ -8771,7 +8789,7 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
|
|
||||||
// checkExpectedHtlcs checks that a set of htlcs that we have contains all the
|
// checkExpectedHtlcs checks that a set of htlcs that we have contains all the
|
||||||
// htlcs we expect.
|
// htlcs we expect.
|
||||||
func checkExpectedHtlcs(t *testing.T, actual []*PaymentDescriptor,
|
func checkExpectedHtlcs(t *testing.T, actual []*paymentDescriptor,
|
||||||
expected map[uint64]bool) {
|
expected map[uint64]bool) {
|
||||||
|
|
||||||
if len(expected) != len(actual) {
|
if len(expected) != len(actual) {
|
||||||
@@ -8963,7 +8981,7 @@ func TestProcessFeeUpdate(t *testing.T) {
|
|||||||
// Create a fee update with add and remove heights as
|
// Create a fee update with add and remove heights as
|
||||||
// set in the test.
|
// set in the test.
|
||||||
heights := test.startHeights
|
heights := test.startHeights
|
||||||
update := &PaymentDescriptor{
|
update := &paymentDescriptor{
|
||||||
Amount: ourFeeUpdateAmt,
|
Amount: ourFeeUpdateAmt,
|
||||||
addCommitHeightRemote: heights.remoteAdd,
|
addCommitHeightRemote: heights.remoteAdd,
|
||||||
addCommitHeightLocal: heights.localAdd,
|
addCommitHeightLocal: heights.localAdd,
|
||||||
@@ -8990,7 +9008,7 @@ func TestProcessFeeUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkHeights(t *testing.T, update *PaymentDescriptor, expected heights) {
|
func checkHeights(t *testing.T, update *paymentDescriptor, expected heights) {
|
||||||
updateHeights := heights{
|
updateHeights := heights{
|
||||||
localAdd: update.addCommitHeightLocal,
|
localAdd: update.addCommitHeightLocal,
|
||||||
localRemove: update.removeCommitHeightLocal,
|
localRemove: update.removeCommitHeightLocal,
|
||||||
@@ -9359,7 +9377,7 @@ func TestProcessAddRemoveEntry(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
heights := test.startHeights
|
heights := test.startHeights
|
||||||
update := &PaymentDescriptor{
|
update := &paymentDescriptor{
|
||||||
Amount: updateAmount,
|
Amount: updateAmount,
|
||||||
addCommitHeightLocal: heights.localAdd,
|
addCommitHeightLocal: heights.localAdd,
|
||||||
addCommitHeightRemote: heights.remoteAdd,
|
addCommitHeightRemote: heights.remoteAdd,
|
||||||
@@ -9477,7 +9495,7 @@ func TestChannelUnsignedAckedFailure(t *testing.T) {
|
|||||||
// -----rev----->
|
// -----rev----->
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Alice should sign the next commitment and go down before
|
// Alice should sign the next commitment and go down before
|
||||||
@@ -9502,7 +9520,7 @@ func TestChannelUnsignedAckedFailure(t *testing.T) {
|
|||||||
// <----rev------
|
// <----rev------
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = newAliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = newAliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Now Bob sends an HTLC to Alice.
|
// Now Bob sends an HTLC to Alice.
|
||||||
@@ -9588,7 +9606,7 @@ func TestChannelLocalUnsignedUpdatesFailure(t *testing.T) {
|
|||||||
// <----rev-----
|
// <----rev-----
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Restart Alice and assert that she can receive Bob's next commitment
|
// Restart Alice and assert that she can receive Bob's next commitment
|
||||||
@@ -9672,7 +9690,7 @@ func TestChannelSignedAckRegression(t *testing.T) {
|
|||||||
// <----rev-----
|
// <----rev-----
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// <----sig-----
|
// <----sig-----
|
||||||
@@ -9699,7 +9717,7 @@ func TestChannelSignedAckRegression(t *testing.T) {
|
|||||||
// <----rev-----
|
// <----rev-----
|
||||||
bobRevocation, _, _, err = bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err = bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Restart Bob's channel state here.
|
// Restart Bob's channel state here.
|
||||||
@@ -9712,7 +9730,7 @@ func TestChannelSignedAckRegression(t *testing.T) {
|
|||||||
// -----rev---->
|
// -----rev---->
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fwdPkg, _, _, _, err := newBobChannel.ReceiveRevocation(aliceRevocation)
|
fwdPkg, _, err := newBobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Assert that the fwdpkg is not empty.
|
// Assert that the fwdpkg is not empty.
|
||||||
@@ -9804,7 +9822,7 @@ func TestIsChannelClean(t *testing.T) {
|
|||||||
// <---rev---
|
// <---rev---
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertCleanOrDirty(false, aliceChannel, bobChannel, t)
|
assertCleanOrDirty(false, aliceChannel, bobChannel, t)
|
||||||
|
|
||||||
@@ -9818,7 +9836,7 @@ func TestIsChannelClean(t *testing.T) {
|
|||||||
// ---rev--->
|
// ---rev--->
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertCleanOrDirty(false, aliceChannel, bobChannel, t)
|
assertCleanOrDirty(false, aliceChannel, bobChannel, t)
|
||||||
|
|
||||||
@@ -9839,7 +9857,7 @@ func TestIsChannelClean(t *testing.T) {
|
|||||||
// ---rev--->
|
// ---rev--->
|
||||||
aliceRevocation, _, _, err = aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err = aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertCleanOrDirty(false, aliceChannel, bobChannel, t)
|
assertCleanOrDirty(false, aliceChannel, bobChannel, t)
|
||||||
|
|
||||||
@@ -9853,7 +9871,7 @@ func TestIsChannelClean(t *testing.T) {
|
|||||||
// <---rev---
|
// <---rev---
|
||||||
bobRevocation, _, _, err = bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err = bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertCleanOrDirty(true, aliceChannel, bobChannel, t)
|
assertCleanOrDirty(true, aliceChannel, bobChannel, t)
|
||||||
|
|
||||||
@@ -9877,7 +9895,7 @@ func TestIsChannelClean(t *testing.T) {
|
|||||||
// <---rev---
|
// <---rev---
|
||||||
bobRevocation, _, _, err = bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err = bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertCleanOrDirty(false, aliceChannel, bobChannel, t)
|
assertCleanOrDirty(false, aliceChannel, bobChannel, t)
|
||||||
|
|
||||||
@@ -9892,7 +9910,7 @@ func TestIsChannelClean(t *testing.T) {
|
|||||||
// ---rev--->
|
// ---rev--->
|
||||||
aliceRevocation, _, _, err = aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err = aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertCleanOrDirty(true, aliceChannel, bobChannel, t)
|
assertCleanOrDirty(true, aliceChannel, bobChannel, t)
|
||||||
}
|
}
|
||||||
@@ -10035,7 +10053,7 @@ func testGetDustSum(t *testing.T, chantype channeldb.ChannelType) {
|
|||||||
// dust.
|
// dust.
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
checkDust(aliceChannel, htlc2Amt, htlc2Amt)
|
checkDust(aliceChannel, htlc2Amt, htlc2Amt)
|
||||||
checkDust(bobChannel, htlc2Amt, htlc2Amt)
|
checkDust(bobChannel, htlc2Amt, htlc2Amt)
|
||||||
@@ -10048,7 +10066,7 @@ func testGetDustSum(t *testing.T, chantype channeldb.ChannelType) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
aliceRevocation, _, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
checkDust(aliceChannel, htlc2Amt, htlc2Amt)
|
checkDust(aliceChannel, htlc2Amt, htlc2Amt)
|
||||||
checkDust(bobChannel, htlc2Amt, htlc2Amt)
|
checkDust(bobChannel, htlc2Amt, htlc2Amt)
|
||||||
@@ -10554,7 +10572,7 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TestExtractPayDescs asserts that `extractPayDescs` can correctly turn a
|
// TestExtractPayDescs asserts that `extractPayDescs` can correctly turn a
|
||||||
// slice of htlcs into two slices of PaymentDescriptors.
|
// slice of htlcs into two slices of paymentDescriptors.
|
||||||
func TestExtractPayDescs(t *testing.T) {
|
func TestExtractPayDescs(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -10591,22 +10609,22 @@ func TestExtractPayDescs(t *testing.T) {
|
|||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Assert the incoming PaymentDescriptors are matched.
|
// Assert the incoming paymentDescriptors are matched.
|
||||||
for i, pd := range incomingPDs {
|
for i, pd := range incomingPDs {
|
||||||
htlc := incomings[i]
|
htlc := incomings[i]
|
||||||
assertPayDescMatchHTLC(t, pd, htlc)
|
assertPayDescMatchHTLC(t, pd, htlc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert the outgoing PaymentDescriptors are matched.
|
// Assert the outgoing paymentDescriptors are matched.
|
||||||
for i, pd := range outgoingPDs {
|
for i, pd := range outgoingPDs {
|
||||||
htlc := outgoings[i]
|
htlc := outgoings[i]
|
||||||
assertPayDescMatchHTLC(t, pd, htlc)
|
assertPayDescMatchHTLC(t, pd, htlc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// assertPayDescMatchHTLC compares a PaymentDescriptor to a channeldb.HTLC and
|
// assertPayDescMatchHTLC compares a paymentDescriptor to a channeldb.HTLC and
|
||||||
// asserts that the fields are matched.
|
// asserts that the fields are matched.
|
||||||
func assertPayDescMatchHTLC(t *testing.T, pd PaymentDescriptor,
|
func assertPayDescMatchHTLC(t *testing.T, pd paymentDescriptor,
|
||||||
htlc channeldb.HTLC) {
|
htlc channeldb.HTLC) {
|
||||||
|
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
@@ -11008,7 +11026,7 @@ func TestAsynchronousSendingWithFeeBuffer(t *testing.T) {
|
|||||||
|
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
_, _, err = aliceChannel.ReceiveRevocation(bobRevocation)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Before testing the behavior of the fee buffer, we are going to fail
|
// Before testing the behavior of the fee buffer, we are going to fail
|
||||||
|
|||||||
@@ -1229,10 +1229,10 @@ func genHtlcScript(chanType channeldb.ChannelType, isIncoming bool,
|
|||||||
// is incoming and if it's being applied to our commitment transaction or that
|
// is incoming and if it's being applied to our commitment transaction or that
|
||||||
// of the remote node's. Additionally, in order to be able to efficiently
|
// of the remote node's. Additionally, in order to be able to efficiently
|
||||||
// locate the added HTLC on the commitment transaction from the
|
// locate the added HTLC on the commitment transaction from the
|
||||||
// PaymentDescriptor that generated it, the generated script is stored within
|
// paymentDescriptor that generated it, the generated script is stored within
|
||||||
// the descriptor itself.
|
// the descriptor itself.
|
||||||
func addHTLC(commitTx *wire.MsgTx, whoseCommit lntypes.ChannelParty,
|
func addHTLC(commitTx *wire.MsgTx, whoseCommit lntypes.ChannelParty,
|
||||||
isIncoming bool, paymentDesc *PaymentDescriptor,
|
isIncoming bool, paymentDesc *paymentDescriptor,
|
||||||
keyRing *CommitmentKeyRing, chanType channeldb.ChannelType,
|
keyRing *CommitmentKeyRing, chanType channeldb.ChannelType,
|
||||||
auxLeaf input.AuxTapLeaf) error {
|
auxLeaf input.AuxTapLeaf) error {
|
||||||
|
|
||||||
@@ -1253,7 +1253,7 @@ func addHTLC(commitTx *wire.MsgTx, whoseCommit lntypes.ChannelParty,
|
|||||||
amountPending := int64(paymentDesc.Amount.ToSatoshis())
|
amountPending := int64(paymentDesc.Amount.ToSatoshis())
|
||||||
commitTx.AddTxOut(wire.NewTxOut(amountPending, pkScript))
|
commitTx.AddTxOut(wire.NewTxOut(amountPending, pkScript))
|
||||||
|
|
||||||
// Store the pkScript of this particular PaymentDescriptor so we can
|
// Store the pkScript of this particular paymentDescriptor so we can
|
||||||
// quickly locate it within the commitment transaction later.
|
// quickly locate it within the commitment transaction later.
|
||||||
if whoseCommit.IsLocal() {
|
if whoseCommit.IsLocal() {
|
||||||
paymentDesc.ourPkScript = pkScript
|
paymentDesc.ourPkScript = pkScript
|
||||||
|
|||||||
@@ -62,14 +62,19 @@ func (u updateType) String() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaymentDescriptor represents a commitment state update which either adds,
|
// paymentDescriptor represents a commitment state update which either adds,
|
||||||
// settles, or removes an HTLC. PaymentDescriptors encapsulate all necessary
|
// settles, or removes an HTLC. paymentDescriptors encapsulate all necessary
|
||||||
// metadata w.r.t to an HTLC, and additional data pairing a settle message to
|
// metadata w.r.t to an HTLC, and additional data pairing a settle message to
|
||||||
// the original added HTLC.
|
// the original added HTLC.
|
||||||
//
|
//
|
||||||
// TODO(roasbeef): LogEntry interface??
|
// TODO(roasbeef): LogEntry interface??
|
||||||
// - need to separate attrs for cancel/add/settle/feeupdate
|
// - need to separate attrs for cancel/add/settle/feeupdate
|
||||||
type PaymentDescriptor struct {
|
type paymentDescriptor struct {
|
||||||
|
// ChanID is the ChannelID of the LightningChannel that this
|
||||||
|
// paymentDescriptor belongs to. We track this here so we can
|
||||||
|
// reconstruct the Messages that this paymentDescriptor is built from.
|
||||||
|
ChanID lnwire.ChannelID
|
||||||
|
|
||||||
// RHash is the payment hash for this HTLC. The HTLC can be settled iff
|
// RHash is the payment hash for this HTLC. The HTLC can be settled iff
|
||||||
// the preimage to this hash is presented.
|
// the preimage to this hash is presented.
|
||||||
RHash PaymentHash
|
RHash PaymentHash
|
||||||
@@ -165,7 +170,7 @@ type PaymentDescriptor struct {
|
|||||||
|
|
||||||
// removeCommitHeight[Remote|Local] encodes the height of the
|
// removeCommitHeight[Remote|Local] encodes the height of the
|
||||||
// commitment which removed the parent pointer of this
|
// commitment which removed the parent pointer of this
|
||||||
// PaymentDescriptor either due to a timeout or a settle. Once both
|
// paymentDescriptor either due to a timeout or a settle. Once both
|
||||||
// these heights are below the tail of both chains, the log entries can
|
// these heights are below the tail of both chains, the log entries can
|
||||||
// safely be removed.
|
// safely be removed.
|
||||||
removeCommitHeightRemote uint64
|
removeCommitHeightRemote uint64
|
||||||
@@ -175,7 +180,7 @@ type PaymentDescriptor struct {
|
|||||||
// routing.
|
// routing.
|
||||||
//
|
//
|
||||||
// NOTE: Populated only on add payment descriptor entry types.
|
// NOTE: Populated only on add payment descriptor entry types.
|
||||||
OnionBlob []byte
|
OnionBlob [lnwire.OnionPacketSize]byte
|
||||||
|
|
||||||
// ShaOnionBlob is a sha of the onion blob.
|
// ShaOnionBlob is a sha of the onion blob.
|
||||||
//
|
//
|
||||||
@@ -194,7 +199,7 @@ type PaymentDescriptor struct {
|
|||||||
|
|
||||||
// [our|their|]PkScript are the raw public key scripts that encodes the
|
// [our|their|]PkScript are the raw public key scripts that encodes the
|
||||||
// redemption rules for this particular HTLC. These fields will only be
|
// redemption rules for this particular HTLC. These fields will only be
|
||||||
// populated iff the EntryType of this PaymentDescriptor is Add.
|
// populated iff the EntryType of this paymentDescriptor is Add.
|
||||||
// ourPkScript is the ourPkScript from the context of our local
|
// ourPkScript is the ourPkScript from the context of our local
|
||||||
// commitment chain. theirPkScript is the latest pkScript from the
|
// commitment chain. theirPkScript is the latest pkScript from the
|
||||||
// context of the remote commitment chain.
|
// context of the remote commitment chain.
|
||||||
@@ -207,7 +212,7 @@ type PaymentDescriptor struct {
|
|||||||
theirPkScript []byte
|
theirPkScript []byte
|
||||||
theirWitnessScript []byte
|
theirWitnessScript []byte
|
||||||
|
|
||||||
// EntryType denotes the exact type of the PaymentDescriptor. In the
|
// EntryType denotes the exact type of the paymentDescriptor. In the
|
||||||
// case of a Timeout, or Settle type, then the Parent field will point
|
// case of a Timeout, or Settle type, then the Parent field will point
|
||||||
// into the log to the HTLC being modified.
|
// into the log to the HTLC being modified.
|
||||||
EntryType updateType
|
EntryType updateType
|
||||||
@@ -226,3 +231,56 @@ type PaymentDescriptor struct {
|
|||||||
// may have been attached to a sent HTLC.
|
// may have been attached to a sent HTLC.
|
||||||
CustomRecords lnwire.CustomRecords
|
CustomRecords lnwire.CustomRecords
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// toLogUpdate recovers the underlying LogUpdate from the paymentDescriptor.
|
||||||
|
// This operation is lossy and will forget some extra information tracked by the
|
||||||
|
// paymentDescriptor but the function is total in that all paymentDescriptors
|
||||||
|
// can be converted back to LogUpdates.
|
||||||
|
func (pd *paymentDescriptor) toLogUpdate() channeldb.LogUpdate {
|
||||||
|
var msg lnwire.Message
|
||||||
|
switch pd.EntryType {
|
||||||
|
case Add:
|
||||||
|
msg = &lnwire.UpdateAddHTLC{
|
||||||
|
ChanID: pd.ChanID,
|
||||||
|
ID: pd.HtlcIndex,
|
||||||
|
Amount: pd.Amount,
|
||||||
|
PaymentHash: pd.RHash,
|
||||||
|
Expiry: pd.Timeout,
|
||||||
|
OnionBlob: pd.OnionBlob,
|
||||||
|
BlindingPoint: pd.BlindingPoint,
|
||||||
|
CustomRecords: pd.CustomRecords.Copy(),
|
||||||
|
}
|
||||||
|
case Settle:
|
||||||
|
msg = &lnwire.UpdateFulfillHTLC{
|
||||||
|
ChanID: pd.ChanID,
|
||||||
|
ID: pd.ParentIndex,
|
||||||
|
PaymentPreimage: pd.RPreimage,
|
||||||
|
}
|
||||||
|
case Fail:
|
||||||
|
msg = &lnwire.UpdateFailHTLC{
|
||||||
|
ChanID: pd.ChanID,
|
||||||
|
ID: pd.ParentIndex,
|
||||||
|
Reason: pd.FailReason,
|
||||||
|
}
|
||||||
|
case MalformedFail:
|
||||||
|
msg = &lnwire.UpdateFailMalformedHTLC{
|
||||||
|
ChanID: pd.ChanID,
|
||||||
|
ID: pd.ParentIndex,
|
||||||
|
ShaOnionBlob: pd.ShaOnionBlob,
|
||||||
|
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.
|
||||||
|
msg = &lnwire.UpdateFee{
|
||||||
|
ChanID: pd.ChanID,
|
||||||
|
FeePerKw: uint32(pd.Amount.ToSatoshis()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return channeldb.LogUpdate{
|
||||||
|
LogIndex: pd.LogIndex,
|
||||||
|
UpdateMsg: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -566,7 +566,7 @@ func ForceStateTransition(chanA, chanB *LightningChannel) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, _, err = chanA.ReceiveRevocation(bobRevocation)
|
_, _, err = chanA.ReceiveRevocation(bobRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -579,7 +579,7 @@ func ForceStateTransition(chanA, chanB *LightningChannel) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, _, _, _, err = chanB.ReceiveRevocation(aliceRevocation)
|
_, _, err = chanB.ReceiveRevocation(aliceRevocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ func testVectors(t *testing.T, chanType channeldb.ChannelType, test testCase) {
|
|||||||
revMsg, _, _, err := remoteChannel.RevokeCurrentCommitment()
|
revMsg, _, _, err := remoteChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, _, _, _, err = localChannel.ReceiveRevocation(revMsg)
|
_, _, err = localChannel.ReceiveRevocation(revMsg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
remoteNewCommit, err := remoteChannel.SignNextCommitment()
|
remoteNewCommit, err := remoteChannel.SignNextCommitment()
|
||||||
|
|||||||
+12
-12
@@ -29,16 +29,16 @@ type updateLog struct {
|
|||||||
|
|
||||||
// List is the updatelog itself, we embed this value so updateLog has
|
// List is the updatelog itself, we embed this value so updateLog has
|
||||||
// access to all the method of a list.List.
|
// access to all the method of a list.List.
|
||||||
*fn.List[*PaymentDescriptor]
|
*fn.List[*paymentDescriptor]
|
||||||
|
|
||||||
// updateIndex maps a `logIndex` to a particular update entry. It
|
// updateIndex maps a `logIndex` to a particular update entry. It
|
||||||
// deals with the four update types:
|
// deals with the four update types:
|
||||||
// `Fail|MalformedFail|Settle|FeeUpdate`
|
// `Fail|MalformedFail|Settle|FeeUpdate`
|
||||||
updateIndex map[uint64]*fn.Node[*PaymentDescriptor]
|
updateIndex map[uint64]*fn.Node[*paymentDescriptor]
|
||||||
|
|
||||||
// htlcIndex maps a `htlcCounter` to an offered HTLC entry, hence the
|
// htlcIndex maps a `htlcCounter` to an offered HTLC entry, hence the
|
||||||
// `Add` update.
|
// `Add` update.
|
||||||
htlcIndex map[uint64]*fn.Node[*PaymentDescriptor]
|
htlcIndex map[uint64]*fn.Node[*paymentDescriptor]
|
||||||
|
|
||||||
// modifiedHtlcs is a set that keeps track of all the current modified
|
// modifiedHtlcs is a set that keeps track of all the current modified
|
||||||
// htlcs, hence update types `Fail|MalformedFail|Settle`. A modified
|
// htlcs, hence update types `Fail|MalformedFail|Settle`. A modified
|
||||||
@@ -50,9 +50,9 @@ type updateLog struct {
|
|||||||
// newUpdateLog creates a new updateLog instance.
|
// newUpdateLog creates a new updateLog instance.
|
||||||
func newUpdateLog(logIndex, htlcCounter uint64) *updateLog {
|
func newUpdateLog(logIndex, htlcCounter uint64) *updateLog {
|
||||||
return &updateLog{
|
return &updateLog{
|
||||||
List: fn.NewList[*PaymentDescriptor](),
|
List: fn.NewList[*paymentDescriptor](),
|
||||||
updateIndex: make(map[uint64]*fn.Node[*PaymentDescriptor]),
|
updateIndex: make(map[uint64]*fn.Node[*paymentDescriptor]),
|
||||||
htlcIndex: make(map[uint64]*fn.Node[*PaymentDescriptor]),
|
htlcIndex: make(map[uint64]*fn.Node[*paymentDescriptor]),
|
||||||
logIndex: logIndex,
|
logIndex: logIndex,
|
||||||
htlcCounter: htlcCounter,
|
htlcCounter: htlcCounter,
|
||||||
modifiedHtlcs: fn.NewSet[uint64](),
|
modifiedHtlcs: fn.NewSet[uint64](),
|
||||||
@@ -64,7 +64,7 @@ func newUpdateLog(logIndex, htlcCounter uint64) *updateLog {
|
|||||||
// state. This function differs from appendHtlc in that it won't increment
|
// state. This function differs from appendHtlc in that it won't increment
|
||||||
// either of log's counters. If the HTLC is already present, then it is
|
// either of log's counters. If the HTLC is already present, then it is
|
||||||
// ignored.
|
// ignored.
|
||||||
func (u *updateLog) restoreHtlc(pd *PaymentDescriptor) {
|
func (u *updateLog) restoreHtlc(pd *paymentDescriptor) {
|
||||||
if _, ok := u.htlcIndex[pd.HtlcIndex]; ok {
|
if _, ok := u.htlcIndex[pd.HtlcIndex]; ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ func (u *updateLog) restoreHtlc(pd *PaymentDescriptor) {
|
|||||||
|
|
||||||
// appendUpdate appends a new update to the tip of the updateLog. The entry is
|
// appendUpdate appends a new update to the tip of the updateLog. The entry is
|
||||||
// also added to index accordingly.
|
// also added to index accordingly.
|
||||||
func (u *updateLog) appendUpdate(pd *PaymentDescriptor) {
|
func (u *updateLog) appendUpdate(pd *paymentDescriptor) {
|
||||||
u.updateIndex[u.logIndex] = u.PushBack(pd)
|
u.updateIndex[u.logIndex] = u.PushBack(pd)
|
||||||
u.logIndex++
|
u.logIndex++
|
||||||
}
|
}
|
||||||
@@ -82,13 +82,13 @@ func (u *updateLog) appendUpdate(pd *PaymentDescriptor) {
|
|||||||
// restoreUpdate appends a new update to the tip of the updateLog. The entry is
|
// restoreUpdate appends a new update to the tip of the updateLog. The entry is
|
||||||
// also added to index accordingly. This function differs from appendUpdate in
|
// also added to index accordingly. This function differs from appendUpdate in
|
||||||
// that it won't increment the log index counter.
|
// that it won't increment the log index counter.
|
||||||
func (u *updateLog) restoreUpdate(pd *PaymentDescriptor) {
|
func (u *updateLog) restoreUpdate(pd *paymentDescriptor) {
|
||||||
u.updateIndex[pd.LogIndex] = u.PushBack(pd)
|
u.updateIndex[pd.LogIndex] = u.PushBack(pd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendHtlc appends a new HTLC offer to the tip of the update log. The entry
|
// appendHtlc appends a new HTLC offer to the tip of the update log. The entry
|
||||||
// is also added to the offer index accordingly.
|
// is also added to the offer index accordingly.
|
||||||
func (u *updateLog) appendHtlc(pd *PaymentDescriptor) {
|
func (u *updateLog) appendHtlc(pd *paymentDescriptor) {
|
||||||
u.htlcIndex[u.htlcCounter] = u.PushBack(pd)
|
u.htlcIndex[u.htlcCounter] = u.PushBack(pd)
|
||||||
u.htlcCounter++
|
u.htlcCounter++
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ func (u *updateLog) appendHtlc(pd *PaymentDescriptor) {
|
|||||||
|
|
||||||
// lookupHtlc attempts to look up an offered HTLC according to its offer
|
// lookupHtlc attempts to look up an offered HTLC according to its offer
|
||||||
// index. If the entry isn't found, then a nil pointer is returned.
|
// index. If the entry isn't found, then a nil pointer is returned.
|
||||||
func (u *updateLog) lookupHtlc(i uint64) *PaymentDescriptor {
|
func (u *updateLog) lookupHtlc(i uint64) *paymentDescriptor {
|
||||||
htlc, ok := u.htlcIndex[i]
|
htlc, ok := u.htlcIndex[i]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
@@ -145,7 +145,7 @@ func compactLogs(ourLog, theirLog *updateLog,
|
|||||||
localChainTail, remoteChainTail uint64) {
|
localChainTail, remoteChainTail uint64) {
|
||||||
|
|
||||||
compactLog := func(logA, logB *updateLog) {
|
compactLog := func(logA, logB *updateLog) {
|
||||||
var nextA *fn.Node[*PaymentDescriptor]
|
var nextA *fn.Node[*paymentDescriptor]
|
||||||
for e := logA.Front(); e != nil; e = nextA {
|
for e := logA.Front(); e != nil; e = nextA {
|
||||||
// Assign next iteration element at top of loop because
|
// Assign next iteration element at top of loop because
|
||||||
// we may remove the current element from the list,
|
// we may remove the current element from the list,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
|
"github.com/lightningnetwork/lnd/fn"
|
||||||
"github.com/lightningnetwork/lnd/tlv"
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1271,14 +1272,19 @@ func (f *FailInvalidBlinding) Encode(w *bytes.Buffer, _ uint32) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewInvalidBlinding creates new instance of FailInvalidBlinding.
|
// NewInvalidBlinding creates new instance of FailInvalidBlinding.
|
||||||
func NewInvalidBlinding(onion []byte) *FailInvalidBlinding {
|
func NewInvalidBlinding(
|
||||||
|
onion fn.Option[[OnionPacketSize]byte]) *FailInvalidBlinding {
|
||||||
// The spec allows empty onion hashes for invalid blinding, so we only
|
// The spec allows empty onion hashes for invalid blinding, so we only
|
||||||
// include our onion hash if it's provided.
|
// include our onion hash if it's provided.
|
||||||
if onion == nil {
|
if onion.IsNone() {
|
||||||
return &FailInvalidBlinding{}
|
return &FailInvalidBlinding{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &FailInvalidBlinding{OnionSHA256: sha256.Sum256(onion)}
|
shaSum := fn.MapOptionZ(onion, func(o [OnionPacketSize]byte) [32]byte {
|
||||||
|
return sha256.Sum256(o[:])
|
||||||
|
})
|
||||||
|
|
||||||
|
return &FailInvalidBlinding{OnionSHA256: shaSum}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeFailure decodes, validates, and parses the lnwire onion failure, for
|
// DecodeFailure decodes, validates, and parses the lnwire onion failure, for
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/lightningnetwork/lnd/fn"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testOnionHash = []byte{}
|
testOnionHash = [OnionPacketSize]byte{}
|
||||||
testAmount = MilliSatoshi(1)
|
testAmount = MilliSatoshi(1)
|
||||||
testCtlvExpiry = uint32(2)
|
testCtlvExpiry = uint32(2)
|
||||||
testFlags = uint16(2)
|
testFlags = uint16(2)
|
||||||
@@ -43,9 +44,9 @@ var onionFailures = []FailureMessage{
|
|||||||
&FailMPPTimeout{},
|
&FailMPPTimeout{},
|
||||||
|
|
||||||
NewFailIncorrectDetails(99, 100),
|
NewFailIncorrectDetails(99, 100),
|
||||||
NewInvalidOnionVersion(testOnionHash),
|
NewInvalidOnionVersion(testOnionHash[:]),
|
||||||
NewInvalidOnionHmac(testOnionHash),
|
NewInvalidOnionHmac(testOnionHash[:]),
|
||||||
NewInvalidOnionKey(testOnionHash),
|
NewInvalidOnionKey(testOnionHash[:]),
|
||||||
NewTemporaryChannelFailure(&testChannelUpdate),
|
NewTemporaryChannelFailure(&testChannelUpdate),
|
||||||
NewTemporaryChannelFailure(nil),
|
NewTemporaryChannelFailure(nil),
|
||||||
NewAmountBelowMinimum(testAmount, testChannelUpdate),
|
NewAmountBelowMinimum(testAmount, testChannelUpdate),
|
||||||
@@ -56,7 +57,7 @@ var onionFailures = []FailureMessage{
|
|||||||
NewFinalIncorrectCltvExpiry(testCtlvExpiry),
|
NewFinalIncorrectCltvExpiry(testCtlvExpiry),
|
||||||
NewFinalIncorrectHtlcAmount(testAmount),
|
NewFinalIncorrectHtlcAmount(testAmount),
|
||||||
NewInvalidOnionPayload(testType, testOffset),
|
NewInvalidOnionPayload(testType, testOffset),
|
||||||
NewInvalidBlinding(testOnionHash),
|
NewInvalidBlinding(fn.Some(testOnionHash)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestEncodeDecodeCode tests the ability of onion errors to be properly encoded
|
// TestEncodeDecodeCode tests the ability of onion errors to be properly encoded
|
||||||
|
|||||||
Reference in new issue
Block a user