Expand Up
@@ -6,13 +6,15 @@ import (
"io/ioutil"
"testing"
sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/channeldb/kvdb"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
)
const (
Expand All
@@ -26,6 +28,7 @@ var (
testResCircuitKey = channeldb.CircuitKey {}
testOnionBlob = []byte {4 , 5 , 6 }
testAcceptHeight int32 = 1234
testHtlcAmount = 2300
)
// TestHtlcIncomingResolverFwdPreimageKnown tests resolution of a forwarded htlc
Expand All
@@ -34,11 +37,7 @@ func TestHtlcIncomingResolverFwdPreimageKnown(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx .registry .notifyResolution = invoices .NewFailResolution (
testResCircuitKey , testHtlcExpiry ,
invoices .ResultInvoiceNotFound ,
)
ctx := newIncomingResolverTestContext (t , false )
ctx .witnessBeacon .lookupPreimage [testResHash ] = testResPreimage
ctx .resolve ()
ctx .waitForResult (true )
Expand All
@@ -51,11 +50,7 @@ func TestHtlcIncomingResolverFwdContestedSuccess(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx .registry .notifyResolution = invoices .NewFailResolution (
testResCircuitKey , testHtlcExpiry ,
invoices .ResultInvoiceNotFound ,
)
ctx := newIncomingResolverTestContext (t , false )
ctx .resolve ()
// Simulate a new block coming in. HTLC is not yet expired.
Expand All
@@ -71,16 +66,36 @@ func TestHtlcIncomingResolverFwdContestedTimeout(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx .registry .notifyResolution = invoices .NewFailResolution (
testResCircuitKey , testHtlcExpiry ,
invoices .ResultInvoiceNotFound ,
)
ctx := newIncomingResolverTestContext (t , false )
// Replace our checkpoint with one which will push reports into a
// channel for us to consume. We replace this function on the resolver
// itself because it is created by the test context.
reportChan := make (chan * channeldb.ResolverReport )
ctx .resolver .Checkpoint = func (_ ContractResolver ,
reports ... * channeldb.ResolverReport ) error {
// Send all of our reports into the channel.
for _ , report := range reports {
reportChan <- report
}
return nil
}
ctx .resolve ()
// Simulate a new block coming in. HTLC expires.
ctx .notifyEpoch (testHtlcExpiry )
// Assert that we have a failure resolution because our invoice was
// cancelled.
assertResolverReport (t , reportChan , & channeldb.ResolverReport {
Amount : lnwire .MilliSatoshi (testHtlcAmount ).ToSatoshis (),
ResolverType : channeldb .ResolverTypeIncomingHtlc ,
ResolverOutcome : channeldb .ResolverOutcomeTimeout ,
})
ctx .waitForResult (false )
}
Expand All
@@ -90,11 +105,7 @@ func TestHtlcIncomingResolverFwdTimeout(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx .registry .notifyResolution = invoices .NewFailResolution (
testResCircuitKey , testHtlcExpiry ,
invoices .ResultInvoiceNotFound ,
)
ctx := newIncomingResolverTestContext (t , true )
ctx .witnessBeacon .lookupPreimage [testResHash ] = testResPreimage
ctx .resolver .htlcExpiry = 90
ctx .resolve ()
Expand All
@@ -107,7 +118,7 @@ func TestHtlcIncomingResolverExitSettle(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx := newIncomingResolverTestContext (t , true )
ctx .registry .notifyResolution = invoices .NewSettleResolution (
testResPreimage , testResCircuitKey , testAcceptHeight ,
invoices .ResultReplayToSettled ,
Expand Down
Expand Up
@@ -138,7 +149,7 @@ func TestHtlcIncomingResolverExitCancel(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx := newIncomingResolverTestContext (t , true )
ctx .registry .notifyResolution = invoices .NewFailResolution (
testResCircuitKey , testAcceptHeight ,
invoices .ResultInvoiceAlreadyCanceled ,
Expand All
@@ -154,7 +165,7 @@ func TestHtlcIncomingResolverExitSettleHodl(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx := newIncomingResolverTestContext (t , true )
ctx .resolve ()
notifyData := <- ctx .registry .notifyChan
Expand All
@@ -172,9 +183,34 @@ func TestHtlcIncomingResolverExitTimeoutHodl(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx := newIncomingResolverTestContext (t , true )
// Replace our checkpoint with one which will push reports into a
// channel for us to consume. We replace this function on the resolver
// itself because it is created by the test context.
reportChan := make (chan * channeldb.ResolverReport )
ctx .resolver .Checkpoint = func (_ ContractResolver ,
reports ... * channeldb.ResolverReport ) error {
// Send all of our reports into the channel.
for _ , report := range reports {
reportChan <- report
}
return nil
}
ctx .resolve ()
ctx .notifyEpoch (testHtlcExpiry )
// Assert that we have a failure resolution because our invoice was
// cancelled.
assertResolverReport (t , reportChan , & channeldb.ResolverReport {
Amount : lnwire .MilliSatoshi (testHtlcAmount ).ToSatoshis (),
ResolverType : channeldb .ResolverTypeIncomingHtlc ,
ResolverOutcome : channeldb .ResolverOutcomeTimeout ,
})
ctx .waitForResult (false )
}
Expand All
@@ -184,25 +220,62 @@ func TestHtlcIncomingResolverExitCancelHodl(t *testing.T) {
t .Parallel ()
defer timeout (t )()
ctx := newIncomingResolverTestContext (t )
ctx := newIncomingResolverTestContext (t , true )
// Replace our checkpoint with one which will push reports into a
// channel for us to consume. We replace this function on the resolver
// itself because it is created by the test context.
reportChan := make (chan * channeldb.ResolverReport )
ctx .resolver .Checkpoint = func (_ ContractResolver ,
reports ... * channeldb.ResolverReport ) error {
// Send all of our reports into the channel.
for _ , report := range reports {
reportChan <- report
}
return nil
}
ctx .resolve ()
notifyData := <- ctx .registry .notifyChan
notifyData .hodlChan <- invoices .NewFailResolution (
testResCircuitKey , testAcceptHeight , invoices .ResultCanceled ,
)
// Assert that we have a failure resolution because our invoice was
// cancelled.
assertResolverReport (t , reportChan , & channeldb.ResolverReport {
Amount : lnwire .MilliSatoshi (testHtlcAmount ).ToSatoshis (),
ResolverType : channeldb .ResolverTypeIncomingHtlc ,
ResolverOutcome : channeldb .ResolverOutcomeAbandoned ,
})
ctx .waitForResult (false )
}
type mockHopIterator struct {
isExit bool
hop.Iterator
}
func (h * mockHopIterator ) HopPayload () (* hop.Payload , error ) {
return nil , nil
var nextAddress [8 ]byte
if ! h .isExit {
nextAddress = [8 ]byte {0x01 }
}
return hop .NewLegacyPayload (& sphinx.HopData {
Realm : [1 ]byte {},
NextAddress : nextAddress ,
ForwardAmount : 100 ,
OutgoingCltv : 40 ,
ExtraBytes : [12 ]byte {},
}), nil
}
type mockOnionProcessor struct {
isExit bool
offeredOnionBlob []byte
}
Expand All
@@ -215,7 +288,7 @@ func (o *mockOnionProcessor) ReconstructHopIterator(r io.Reader, rHash []byte) (
}
o .offeredOnionBlob = data
return & mockHopIterator {}, nil
return & mockHopIterator {isExit : o . isExit }, nil
}
type incomingResolverTestContext struct {
Expand All
@@ -229,7 +302,7 @@ type incomingResolverTestContext struct {
t * testing.T
}
func newIncomingResolverTestContext (t * testing.T ) * incomingResolverTestContext {
func newIncomingResolverTestContext (t * testing.T , isExit bool ) * incomingResolverTestContext {
notifier := & mockNotifier {
epochChan : make (chan * chainntnfs.BlockEpoch ),
spendChan : make (chan * chainntnfs.SpendDetail ),
Expand All
@@ -240,7 +313,7 @@ func newIncomingResolverTestContext(t *testing.T) *incomingResolverTestContext {
notifyChan : make (chan notifyExitHopData , 1 ),
}
onionProcessor := & mockOnionProcessor {}
onionProcessor := & mockOnionProcessor {isExit : isExit }
checkPointChan := make (chan struct {}, 1 )
Expand Down
Expand Up
@@ -272,6 +345,7 @@ func newIncomingResolverTestContext(t *testing.T) *incomingResolverTestContext {
contractResolverKit : * newContractResolverKit (cfg ),
htlcResolution : lnwallet.IncomingHtlcResolution {},
htlc : channeldb.HTLC {
Amt : lnwire .MilliSatoshi (testHtlcAmount ),
RHash : testResHash ,
OnionBlob : testOnionBlob ,
},
Expand Down