Skip to content

Commit 7b25935

Browse files
committed
lnwallet: add noop HTLC below reserve test
1 parent 0808083 commit 7b25935

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

lnwallet/channel_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11396,3 +11396,92 @@ func TestNoopAddSettle(t *testing.T) {
1139611396
require.Equal(t, aliceBalance, aliceBalanceFinal)
1139711397
require.Equal(t, bobBalance, bobBalanceFinal)
1139811398
}
11399+
11400+
// TestNoopAddBelowReserve tests that the noop HTLCs behave as expected when
11401+
// added over a channel where a party is below their reserve.
11402+
func TestNoopAddBelowReserve(t *testing.T) {
11403+
t.Parallel()
11404+
11405+
// Create a test channel which will be used for the duration of this
11406+
// unittest. The channel will be funded evenly with Alice having 5 BTC,
11407+
// and Bob having 5 BTC.
11408+
chanType := channeldb.SimpleTaprootFeatureBit |
11409+
channeldb.AnchorOutputsBit | channeldb.ZeroHtlcTxFeeBit |
11410+
channeldb.SingleFunderTweaklessBit | channeldb.TapscriptRootBit
11411+
aliceChan, bobChan, err := CreateTestChannels(t, chanType)
11412+
require.NoError(t, err, "unable to create test channels")
11413+
11414+
aliceBalance := aliceChan.channelState.LocalCommitment.LocalBalance
11415+
bobBalance := bobChan.channelState.LocalCommitment.LocalBalance
11416+
11417+
const (
11418+
// htlcAmt is the default HTLC amount to be used, epxressed in
11419+
// milli-satoshis.
11420+
htlcAmt = lnwire.MilliSatoshi(500_000)
11421+
11422+
// numHtlc is the total number of HTLCs to be added/settled over
11423+
// the channel.
11424+
numHtlc = 20
11425+
)
11426+
11427+
// Let's create the noop add TLV record to be used in all added HTLCs
11428+
// over the channel.
11429+
noopRecord := tlv.NewPrimitiveRecord[NoopAddHtlcType, bool](true)
11430+
records, err := tlv.RecordsToMap([]tlv.Record{noopRecord.Record()})
11431+
require.NoError(t, err)
11432+
11433+
// Let's set Bob's reserve to whatever his local balance is, minus half
11434+
// of the total amount to be added by the total HTLCs. This way we can
11435+
// also verify that the noop-adds will start the nullification only once
11436+
// Bob is above reserve.
11437+
reserveTarget := (numHtlc / 2) * htlcAmt
11438+
bobReserve := bobBalance + reserveTarget
11439+
11440+
bobChan.channelState.LocalChanCfg.ChanReserve =
11441+
bobReserve.ToSatoshis()
11442+
11443+
aliceChan.channelState.RemoteChanCfg.ChanReserve =
11444+
bobReserve.ToSatoshis()
11445+
11446+
// Add and settle all the HTLCs over the channel.
11447+
for i := range numHtlc {
11448+
htlc, preimage := createHTLC(i, htlcAmt)
11449+
htlc.CustomRecords = records
11450+
11451+
aliceHtlcIndex, err := aliceChan.AddHTLC(htlc, nil)
11452+
require.NoError(t, err, "alice unable to add htlc")
11453+
bobHtlcIndex, err := bobChan.ReceiveHTLC(htlc)
11454+
require.NoError(t, err, "bob unable to receive htlc")
11455+
11456+
require.NoError(t, ForceStateTransition(aliceChan, bobChan))
11457+
11458+
// We'll have Bob settle the HTLC, then force another state
11459+
// transition.
11460+
err = bobChan.SettleHTLC(preimage, bobHtlcIndex, nil, nil, nil)
11461+
require.NoError(t, err, "bob unable to settle inbound htlc")
11462+
err = aliceChan.ReceiveHTLCSettle(preimage, aliceHtlcIndex)
11463+
if err != nil {
11464+
t.Fatalf("alice unable to accept settle of outbound "+
11465+
"htlc: %v", err)
11466+
}
11467+
require.NoError(t, ForceStateTransition(aliceChan, bobChan))
11468+
}
11469+
11470+
// We need to kick the state transition one last time for the balances
11471+
// to be updated on both commitments.
11472+
require.NoError(t, ForceStateTransition(aliceChan, bobChan))
11473+
11474+
aliceBalanceFinal := aliceChan.channelState.LocalCommitment.LocalBalance
11475+
bobBalanceFinal := bobChan.channelState.LocalCommitment.LocalBalance
11476+
11477+
// The balances of Alice and Bob must have changed exactly by half the
11478+
// total number of HTLCs we added over the channel, plus one to get Bob
11479+
// above the reserve. Bob's final balance should be as much as his
11480+
// reserve plus one extra default HTLC amount.
11481+
require.Equal(t, aliceBalance-htlcAmt*(numHtlc/2+1), aliceBalanceFinal)
11482+
require.Equal(t, bobBalance+htlcAmt*(numHtlc/2+1), bobBalanceFinal)
11483+
require.Equal(
11484+
t, bobBalanceFinal.ToSatoshis(),
11485+
bobChan.LocalChanReserve()+htlcAmt.ToSatoshis(),
11486+
)
11487+
}

0 commit comments

Comments
 (0)