itest: add taproot support for all variants of runMultiHopHtlcClaimTest

This commit is contained in:
Olaoluwa Osuntokun 2023-08-10 21:53:47 -07:00
parent 5739061f13
commit 7c5be4d056
No known key found for this signature in database
GPG key ID: 3BBD59E99B280306
3 changed files with 290 additions and 43 deletions

View file

@ -8,6 +8,7 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
@ -49,6 +50,67 @@ var commitWithZeroConf = []struct {
commitType: lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE,
zeroConf: true,
},
{
commitType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
zeroConf: false,
},
{
commitType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
zeroConf: true,
},
}
// makeRouteHints creates a route hints that will allow Carol to be reached
// using an unadvertised channel created by Bob (Bob -> Carol). If the zeroConf
// bool is set, then the scid alias of Bob will be used in place.
func makeRouteHints(bob, carol *node.HarnessNode,
zeroConf bool) []*lnrpc.RouteHint {
carolChans := carol.RPC.ListChannels(
&lnrpc.ListChannelsRequest{},
)
carolChan := carolChans.Channels[0]
hopHint := &lnrpc.HopHint{
NodeId: carolChan.RemotePubkey,
ChanId: carolChan.ChanId,
FeeBaseMsat: uint32(
chainreg.DefaultBitcoinBaseFeeMSat,
),
FeeProportionalMillionths: uint32(
chainreg.DefaultBitcoinFeeRate,
),
CltvExpiryDelta: chainreg.DefaultBitcoinTimeLockDelta,
}
if zeroConf {
bobChans := bob.RPC.ListChannels(
&lnrpc.ListChannelsRequest{},
)
// Now that we have Bob's channels, scan for the channel he has
// open to Carol so we can use the proper scid.
var found bool
for _, bobChan := range bobChans.Channels {
if bobChan.RemotePubkey == carol.PubKeyStr {
hopHint.ChanId = bobChan.AliasScids[0]
found = true
break
}
}
if !found {
bob.Fatalf("unable to create route hint")
}
}
return []*lnrpc.RouteHint{
{
HopHints: []*lnrpc.HopHint{hopHint},
},
}
}
// caseRunner defines a single test case runner.
@ -131,6 +193,13 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
dustPayHash := ht.Random32Bytes()
payHash := ht.Random32Bytes()
// If this is a taproot channel, then we'll need to make some manual
// route hints so Alice can actually find a route.
var routeHints []*lnrpc.RouteHint
if c == lnrpc.CommitmentType_SIMPLE_TAPROOT {
routeHints = makeRouteHints(bob, carol, zeroConf)
}
alice.RPC.SendPayment(&routerrpc.SendPaymentRequest{
Dest: carolPubKey,
Amt: int64(dustHtlcAmt),
@ -138,6 +207,7 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
FinalCltvDelta: finalCltvDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
RouteHints: routeHints,
})
alice.RPC.SendPayment(&routerrpc.SendPaymentRequest{
@ -147,6 +217,7 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
FinalCltvDelta: finalCltvDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
RouteHints: routeHints,
})
// Verify that all nodes in the path now have two HTLC's with the
@ -155,6 +226,18 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
ht.AssertActiveHtlcs(bob, dustPayHash, payHash)
ht.AssertActiveHtlcs(carol, dustPayHash, payHash)
// blocksMined records how many blocks have mined after the creation of
// the invoice so it can be used to calculate how many more blocks need
// to be mined to trigger a force close later on.
var blocksMined uint32
// If this is a private channel, and it was zero conf, then we'll need
// to mine one block to confirm the channels created above.
if zeroConf && routeHints != nil {
ht.MineBlocksAndAssertNumTxes(1, 2)
blocksMined++
}
// Increase the fee estimate so that the following force close tx will
// be cpfp'ed.
ht.SetFeeEstimate(30000)
@ -166,7 +249,7 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
numBlocks := padCLTV(
uint32(finalCltvDelta - lncfg.DefaultOutgoingBroadcastDelta),
)
ht.MineBlocks(numBlocks)
ht.MineBlocks(numBlocks - blocksMined)
// Bob's force close transaction should now be found in the mempool. If
// there are anchors, we also expect Bob's anchor sweep.
@ -286,6 +369,13 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
ht, alice, bob, false, c, zeroConf,
)
// If this is a taproot channel, then we'll need to make some manual
// route hints so Alice can actually find a route.
var routeHints []*lnrpc.RouteHint
if c == lnrpc.CommitmentType_SIMPLE_TAPROOT {
routeHints = makeRouteHints(bob, carol, zeroConf)
}
// With the network active, we'll now add a new hodl invoice at Carol's
// end. Make sure the cltv expiry delta is large enough, otherwise Bob
// won't send out the outgoing htlc.
@ -297,6 +387,7 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
Value: invoiceAmt,
CltvExpiry: finalCltvDelta,
Hash: payHash[:],
RouteHints: routeHints,
}
carolInvoice := carol.RPC.AddHoldInvoice(invoiceReq)
@ -319,6 +410,18 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
ht.AssertActiveHtlcs(bob, payHash[:])
ht.AssertActiveHtlcs(carol, payHash[:])
// blocksMined records how many blocks have mined after the creation of
// the invoice so it can be used to calculate how many more blocks need
// to be mined to trigger a force close later on.
var blocksMined uint32
// If this is a private channel, and it was zero conf, then we'll need
// to mine one block to confirm the channels created above.
if zeroConf && routeHints != nil {
ht.MineBlocksAndAssertNumTxes(1, 2)
blocksMined++
}
// Wait for carol to mark invoice as accepted. There is a small gap to
// bridge between adding the htlc to the channel and executing the exit
// hop logic.
@ -337,12 +440,16 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
// be cpfp'ed.
ht.SetFeeEstimate(30000)
// Now we'll mine enough blocks to prompt carol to actually go to the
// chain in order to sweep her HTLC since the value is high enough.
// We now advance the block height to the point where Carol will force
// close her channel with Bob, broadcast the closing tx but keep it
// unconfirmed.
numBlocks := padCLTV(uint32(
invoiceReq.CltvExpiry - lncfg.DefaultIncomingBroadcastDelta,
))
ht.MineBlocks(numBlocks)
// Now we'll mine enough blocks to prompt carol to actually go to the
// chain in order to sweep her HTLC since the value is high enough.
ht.MineBlocks(numBlocks - blocksMined)
// At this point, Carol should broadcast her active commitment
// transaction in order to go to the chain and sweep her HTLC. If there
@ -379,7 +486,7 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
// Carol should broadcast her second level HTLC transaction and Bob
// should broadcast a sweep tx to sweep his output in the channel with
// Carol, and another sweep tx to sweep his anchor output.
case lnrpc.CommitmentType_ANCHORS:
case lnrpc.CommitmentType_ANCHORS, lnrpc.CommitmentType_SIMPLE_TAPROOT:
expectedTxes = 3
// Carol should broadcast her second level HTLC transaction and Bob
@ -491,6 +598,13 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
// opens up the base for out tests.
const htlcAmt = btcutil.Amount(300_000)
// If this is a taproot channel, then we'll need to make some manual
// route hints so Alice can actually find a route.
var routeHints []*lnrpc.RouteHint
if c == lnrpc.CommitmentType_SIMPLE_TAPROOT {
routeHints = makeRouteHints(bob, carol, zeroConf)
}
// We'll now send a single HTLC across our multi-hop network.
carolPubKey := carol.PubKey[:]
payHash := ht.Random32Bytes()
@ -501,6 +615,7 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
FinalCltvDelta: finalCltvDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
RouteHints: routeHints,
}
alice.RPC.SendPayment(req)
@ -510,6 +625,18 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
ht.AssertActiveHtlcs(bob, payHash)
ht.AssertActiveHtlcs(carol, payHash)
// blocksMined records how many blocks have mined after the creation of
// the invoice so it can be used to calculate how many more blocks need
// to be mined to trigger a force close later on.
var blocksMined uint32
// If this is a private channel, and it was zero conf, then we'll need
// to mine one block to confirm the channels created above.
if zeroConf && routeHints != nil {
ht.MineBlocksAndAssertNumTxes(1, 2)
blocksMined++
}
// Increase the fee estimate so that the following force close tx will
// be cpfp'ed.
ht.SetFeeEstimate(30000)
@ -523,9 +650,9 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
bob, bobChanPoint, hasAnchors, stream,
)
// Record how many blocks have mined. At this step
// Increase the blocks mined. At this step
// AssertStreamChannelForceClosed mines one block.
blocksMined := uint32(1)
blocksMined++
// If the channel closed has anchors, we should expect to see a sweep
// transaction for Carol's anchor.
@ -546,7 +673,7 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
// CSV expires and the commitment was already mined inside
// AssertStreamChannelForceClosed(), so mine one block less
// than defaultCSV in order to perform mempool assertions.
ht.MineBlocks(defaultCSV - blocksMined)
ht.MineBlocks(defaultCSV - 1)
commitSweepTx := ht.Miner.AssertOutpointInMempool(
bobCommitOutpoint,
@ -555,12 +682,13 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
ht.Miner.AssertTxInBlock(block, &txid)
blocksMined = defaultCSV + 1
blocksMined += defaultCSV
}
// We'll now mine enough blocks for the HTLC to expire. After this, Bob
// should hand off the now expired HTLC output to the utxo nursery.
numBlocks := padCLTV(finalCltvDelta)
numBlocks := padCLTV(uint32(finalCltvDelta) -
lncfg.DefaultOutgoingBroadcastDelta)
ht.MineBlocks(numBlocks - blocksMined)
// Bob's pending channel report should show that he has a single HTLC
@ -647,6 +775,13 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
// opens up the base for out tests.
const htlcAmt = btcutil.Amount(30000)
// If this is a taproot channel, then we'll need to make some manual
// route hints so Alice can actually find a route.
var routeHints []*lnrpc.RouteHint
if c == lnrpc.CommitmentType_SIMPLE_TAPROOT {
routeHints = makeRouteHints(bob, carol, zeroConf)
}
// We'll now send a single HTLC across our multi-hop network.
var preimage lntypes.Preimage
copy(preimage[:], ht.Random32Bytes())
@ -655,6 +790,7 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
Value: int64(htlcAmt),
CltvExpiry: finalCltvDelta,
Hash: payHash[:],
RouteHints: routeHints,
}
carolInvoice := carol.RPC.AddHoldInvoice(invoiceReq)
@ -668,6 +804,18 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
}
alice.RPC.SendPayment(req)
// blocksMined records how many blocks have mined after the creation of
// the invoice so it can be used to calculate how many more blocks need
// to be mined to trigger a force close later on.
var blocksMined uint32
// If this is a private channel, and it was zero conf, then we'll need
// to mine one block to confirm the channels created above.
if zeroConf && routeHints != nil {
ht.MineBlocksAndAssertNumTxes(1, 2)
blocksMined++
}
// Once the HTLC has cleared, all the nodes in our mini network should
// show that the HTLC has been locked in.
ht.AssertActiveHtlcs(alice, payHash[:])
@ -690,6 +838,10 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
carol, bobChanPoint, hasAnchors, closeStream,
)
// Increase the blocks mined. At this step
// AssertStreamChannelForceClosed mines one block.
blocksMined++
// At this point, Bob should have a pending force close channel as
// Carol has gone directly to chain.
ht.AssertNumPendingForceClose(bob, 1)
@ -701,7 +853,7 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
expectedTxes = 1
// Bob can sweep his commit and anchor outputs immediately.
case lnrpc.CommitmentType_ANCHORS:
case lnrpc.CommitmentType_ANCHORS, lnrpc.CommitmentType_SIMPLE_TAPROOT:
expectedTxes = 2
// Bob can't sweep his commit output yet as he was the initiator of a
@ -719,12 +871,13 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
// Next, we'll mine enough blocks for the HTLC to expire. At this
// point, Bob should hand off the output to his internal utxo nursery,
// which will broadcast a sweep transaction.
numBlocks := padCLTV(finalCltvDelta - 1)
ht.MineBlocks(numBlocks)
numBlocks := padCLTV(uint32(finalCltvDelta) -
lncfg.DefaultOutgoingBroadcastDelta)
ht.MineBlocks(numBlocks - blocksMined)
// If we check Bob's pending channel report, it should show that he has
// a single HTLC that's now in the second stage, as skip the initial
// first stage since this is a direct HTLC.
// a single HTLC that's now in the second stage, as it skipped the
// initial first stage since this is a direct HTLC.
ht.AssertNumHTLCsAndStage(bob, bobChanPoint, 1, 2)
// We need to generate an additional block to trigger the sweep.
@ -796,6 +949,13 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
ht, alice, bob, false, c, zeroConf,
)
// If this is a taproot channel, then we'll need to make some manual
// route hints so Alice can actually find a route.
var routeHints []*lnrpc.RouteHint
if c == lnrpc.CommitmentType_SIMPLE_TAPROOT {
routeHints = makeRouteHints(bob, carol, zeroConf)
}
// With the network active, we'll now add a new hodl invoice at Carol's
// end. Make sure the cltv expiry delta is large enough, otherwise Bob
// won't send out the outgoing htlc.
@ -807,6 +967,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
Value: invoiceAmt,
CltvExpiry: finalCltvDelta,
Hash: payHash[:],
RouteHints: routeHints,
}
carolInvoice := carol.RPC.AddHoldInvoice(invoiceReq)
@ -834,6 +995,18 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
// hop logic.
ht.AssertInvoiceState(stream, lnrpc.Invoice_ACCEPTED)
// blocksMined records how many blocks have mined after the creation of
// the invoice so it can be used to calculate how many more blocks need
// to be mined to trigger a force close later on.
var blocksMined uint32
// If this is a private channel, and it was zero conf, then we'll need
// to mine one block to confirm the channels created above.
if zeroConf && routeHints != nil {
ht.MineBlocksAndAssertNumTxes(1, 2)
blocksMined++
}
// Increase the fee estimate so that the following force close tx will
// be cpfp'ed.
ht.SetFeeEstimate(30000)
@ -848,6 +1021,10 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
bob, aliceChanPoint, hasAnchors, closeStream,
)
// Increase the blocks mined. At this step
// AssertStreamChannelForceClosed mines one block.
blocksMined++
var expectedTxes int
switch c {
// Alice will sweep her commitment output immediately.
@ -855,7 +1032,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
expectedTxes = 1
// Alice will sweep her commitment and anchor output immediately.
case lnrpc.CommitmentType_ANCHORS:
case lnrpc.CommitmentType_ANCHORS, lnrpc.CommitmentType_SIMPLE_TAPROOT:
expectedTxes = 2
// Alice will sweep her anchor output immediately. Her commitment
@ -880,11 +1057,12 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
// channel arbitrator won't go to chain.
carol.RPC.SettleInvoice(preimage[:])
// We'll now mine enough blocks so Carol decides that she needs to go
// on-chain to claim the HTLC as Bob has been inactive.
numBlocks := padCLTV(uint32(invoiceReq.CltvExpiry-
lncfg.DefaultIncomingBroadcastDelta) - 1)
ht.MineBlocks(numBlocks)
// We now advance the block height to the point where Carol will force
// close her channel with Bob, broadcast the closing tx but keep it
// unconfirmed.
numBlocks := padCLTV(uint32(invoiceReq.CltvExpiry -
lncfg.DefaultIncomingBroadcastDelta))
ht.MineBlocks(numBlocks - blocksMined)
// Carol's commitment transaction should now be in the mempool. If
// there is an anchor, Carol will sweep that too.
@ -918,7 +1096,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
// Carol will broadcast her second level HTLC transaction and Bob will
// sweep his commitment and anchor output.
case lnrpc.CommitmentType_ANCHORS:
case lnrpc.CommitmentType_ANCHORS, lnrpc.CommitmentType_SIMPLE_TAPROOT:
expectedTxes = 3
// Carol will broadcast her second level HTLC transaction, and Bob will
@ -1090,6 +1268,13 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
ht, alice, bob, false, c, zeroConf,
)
// If this is a taproot channel, then we'll need to make some manual
// route hints so Alice can actually find a route.
var routeHints []*lnrpc.RouteHint
if c == lnrpc.CommitmentType_SIMPLE_TAPROOT {
routeHints = makeRouteHints(bob, carol, zeroConf)
}
// With the network active, we'll now add a new hodl invoice at Carol's
// end. Make sure the cltv expiry delta is large enough, otherwise Bob
// won't send out the outgoing htlc.
@ -1101,6 +1286,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
Value: invoiceAmt,
CltvExpiry: finalCltvDelta,
Hash: payHash[:],
RouteHints: routeHints,
}
carolInvoice := carol.RPC.AddHoldInvoice(invoiceReq)
@ -1128,6 +1314,18 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
// hop logic.
ht.AssertInvoiceState(stream, lnrpc.Invoice_ACCEPTED)
// blocksMined records how many blocks have mined after the creation of
// the invoice so it can be used to calculate how many more blocks need
// to be mined to trigger a force close later on.
var blocksMined uint32
// If this is a private channel, and it was zero conf, then we'll need
// to mine one block to confirm the channels created above.
if zeroConf && routeHints != nil {
ht.MineBlocksAndAssertNumTxes(1, 2)
blocksMined++
}
// Increase the fee estimate so that the following force close tx will
// be cpfp'ed.
ht.SetFeeEstimate(30000)
@ -1143,9 +1341,9 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
alice, aliceChanPoint, hasAnchors, closeStream,
)
// Record how many blocks have mined. At this step
// Increase the blocks mined. At this step
// AssertStreamChannelForceClosed mines one block.
blocksMined := uint32(1)
blocksMined++
// Wait for the channel to be marked pending force close.
ht.AssertChannelPendingForceClose(alice, aliceChanPoint)
@ -1164,8 +1362,8 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
// commit sweep tx will be broadcast immediately before it can
// be included in a block, so mine one less than defaultCSV in
// order to perform mempool assertions.
ht.MineBlocks(defaultCSV - blocksMined)
blocksMined = defaultCSV
ht.MineBlocks(defaultCSV - 1)
blocksMined += (defaultCSV - 1)
// Alice should now sweep her funds.
ht.Miner.AssertNumTxsInMempool(1)
@ -1224,7 +1422,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
// Carol should broadcast her second level HTLC transaction and Bob
// should broadcast a transaction to sweep his commitment output and
// another to sweep his anchor output.
case lnrpc.CommitmentType_ANCHORS:
case lnrpc.CommitmentType_ANCHORS, lnrpc.CommitmentType_SIMPLE_TAPROOT:
expectedTxes = 3
// Carol should broadcast her second level HTLC transaction and Bob
@ -1353,21 +1551,35 @@ func testMultiHopHtlcAggregation(ht *lntest.HarnessTest) {
func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) {
// First, we'll create a three hop network: Alice -> Bob -> Carol.
aliceChanPoint, bobChanPoint, carol := createThreeHopNetwork(
ht, alice, bob, false, c, zeroConf,
)
// For neutrino backend, we need one additional UTXO to create
// the sweeping tx for the second-level success txes.
if ht.IsNeutrinoBackend() {
ht.FundCoins(btcutil.SatoshiPerBitcoin, bob)
}
// First, we'll create a three hop network: Alice -> Bob -> Carol.
aliceChanPoint, bobChanPoint, carol := createThreeHopNetwork(
ht, alice, bob, false, c, zeroConf,
)
// If this is a taproot channel, then we'll need to make some manual
// route hints so Alice+Carol can actually find a route.
var (
carolRouteHints []*lnrpc.RouteHint
aliceRouteHints []*lnrpc.RouteHint
)
if c == lnrpc.CommitmentType_SIMPLE_TAPROOT {
carolRouteHints = makeRouteHints(bob, carol, zeroConf)
aliceRouteHints = makeRouteHints(bob, alice, zeroConf)
}
// To ensure we have capacity in both directions of the route, we'll
// make a fairly large payment Alice->Carol and settle it.
const reBalanceAmt = 500_000
invoice := &lnrpc.Invoice{Value: reBalanceAmt}
invoice := &lnrpc.Invoice{
Value: reBalanceAmt,
RouteHints: carolRouteHints,
}
resp := carol.RPC.AddInvoice(invoice)
ht.CompletePaymentRequests(alice, []string{resp.PaymentRequest})
@ -1398,6 +1610,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
Value: invoiceAmt,
CltvExpiry: finalCltvDelta,
Hash: payHash[:],
RouteHints: carolRouteHints,
}
carolInvoice := carol.RPC.AddHoldInvoice(invoiceReq)
@ -1419,6 +1632,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
Value: invoiceAmt,
CltvExpiry: thawHeightDelta - 4,
Hash: payHash[:],
RouteHints: aliceRouteHints,
}
aliceInvoice := alice.RPC.AddHoldInvoice(invoiceReq)
@ -1472,6 +1686,18 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
ht.AssertInvoiceState(stream, lnrpc.Invoice_ACCEPTED)
}
// blocksMined records how many blocks have mined after the creation of
// the invoice so it can be used to calculate how many more blocks need
// to be mined to trigger a force close later on.
var blocksMined uint32
// If this is a private channel, and it was zero conf, then we'll need
// to mine one block to confirm the channels created above.
if zeroConf && carolRouteHints != nil {
ht.MineBlocksAndAssertNumTxes(1, 2)
blocksMined++
}
// Increase the fee estimate so that the following force close tx will
// be cpfp'ed.
ht.SetFeeEstimate(30000)
@ -1488,7 +1714,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
numBlocks := padCLTV(
uint32(finalCltvDelta - lncfg.DefaultOutgoingBroadcastDelta),
)
ht.MineBlocks(numBlocks)
ht.MineBlocks(numBlocks - blocksMined)
// Bob's force close transaction should now be found in the mempool. If
// there are anchors, we also expect Bob's anchor sweep.
@ -1563,7 +1789,9 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
// Carol will also sweep her commitment and anchor output as separate
// txs (since it will be low fee).
case lnrpc.CommitmentType_ANCHORS,
lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE:
lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE,
lnrpc.CommitmentType_SIMPLE_TAPROOT:
expectedTxes = 4
default:
@ -1666,7 +1894,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
// Mining one additional block, Bob's second level tx is mature, and he
// can sweep the output. Before the blocks are mined, we should expect
// to see Bob's commit sweep in the mempool.
case lnrpc.CommitmentType_ANCHORS:
case lnrpc.CommitmentType_ANCHORS, lnrpc.CommitmentType_SIMPLE_TAPROOT:
ht.MineBlocksAndAssertNumTxes(1, 1)
// Since Bob is the initiator of the Bob-Carol script-enforced leased
@ -1782,8 +2010,13 @@ func createThreeHopNetwork(ht *lntest.HarnessTest,
)
}
// Prepare params for Alice.
var privateChan bool
if c == lnrpc.CommitmentType_SIMPLE_TAPROOT {
privateChan = true
}
aliceParams := lntest.OpenChannelParams{
Private: privateChan,
Amt: chanAmt,
CommitmentType: c,
FundingShim: aliceFundingShim,
@ -1802,6 +2035,7 @@ func createThreeHopNetwork(ht *lntest.HarnessTest,
// Prepare params for Bob.
bobParams := lntest.OpenChannelParams{
Amt: chanAmt,
Private: privateChan,
CommitmentType: c,
FundingShim: bobFundingShim,
ZeroConf: zeroConf,
@ -1840,8 +2074,18 @@ func createThreeHopNetwork(ht *lntest.HarnessTest,
}
// Make sure alice and carol know each other's channels.
ht.AssertTopologyChannelOpen(alice, bobChanPoint)
ht.AssertTopologyChannelOpen(carol, aliceChanPoint)
//
// We'll only do this though if it wasn't a private channel we opened
// earlier.
if !privateChan {
ht.AssertTopologyChannelOpen(alice, bobChanPoint)
ht.AssertTopologyChannelOpen(carol, aliceChanPoint)
} else {
// Otherwise, we want to wait for all the channels to be shown
// as active before we proceed.
ht.AssertChannelExists(alice, aliceChanPoint)
ht.AssertChannelExists(carol, bobChanPoint)
}
return aliceChanPoint, bobChanPoint, carol
}

View file

@ -1782,10 +1782,12 @@ func (h *HarnessTest) OpenMultiChannelsAsync(
// Wait for the channel open event from the stream.
cp := h.WaitForChannelOpenEvent(req.stream)
// Check that both alice and bob have seen the channel
// from their channel watch request.
h.AssertTopologyChannelOpen(req.Local, cp)
h.AssertTopologyChannelOpen(req.Remote, cp)
if !req.Param.Private {
// Check that both alice and bob have seen the channel
// from their channel watch request.
h.AssertTopologyChannelOpen(req.Local, cp)
h.AssertTopologyChannelOpen(req.Remote, cp)
}
// Finally, check that the channel can be seen in their
// ListChannels.

View file

@ -137,6 +137,7 @@ func CommitTypeHasTaproot(commitType lnrpc.CommitmentType) bool {
func CommitTypeHasAnchors(commitType lnrpc.CommitmentType) bool {
switch commitType {
case lnrpc.CommitmentType_ANCHORS,
lnrpc.CommitmentType_SIMPLE_TAPROOT,
lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE:
return true
default: