lntest+itest: extend CloseChannelAssertPending
In this commit, we extend `CloseChannelAssertPending` with new args that returns the raw close status update (as we have more things we'd like to assert), and also allows us to pass in a custom fee rate.
This commit is contained in:
1 parent
2899a757c4
commit
fbc67f7610
4 files changed
+60
-21
No files matched your search
@@ -109,7 +109,11 @@ func breachRetributionTestCase(ht *lntest.HarnessTest,
|
|||||||
// broadcasting his current channel state. This is actually the
|
// broadcasting his current channel state. This is actually the
|
||||||
// commitment transaction of a prior *revoked* state, so he'll soon
|
// commitment transaction of a prior *revoked* state, so he'll soon
|
||||||
// feel the wrath of Carol's retribution.
|
// feel the wrath of Carol's retribution.
|
||||||
_, breachTXID := ht.CloseChannelAssertPending(bob, chanPoint, true)
|
_, breachCloseUpd := ht.CloseChannelAssertPending(bob, chanPoint, true)
|
||||||
|
closeUpd := breachCloseUpd.GetClosePending()
|
||||||
|
require.NotNil(ht, closeUpd)
|
||||||
|
breachTXID, err := chainhash.NewHash(closeUpd.Txid)
|
||||||
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Here, Carol sees Bob's breach transaction in the mempool, but is
|
// Here, Carol sees Bob's breach transaction in the mempool, but is
|
||||||
// waiting for it to confirm before continuing her retribution. We
|
// waiting for it to confirm before continuing her retribution. We
|
||||||
@@ -122,13 +126,13 @@ func breachRetributionTestCase(ht *lntest.HarnessTest,
|
|||||||
// update, then ensure that the closing transaction was included in the
|
// update, then ensure that the closing transaction was included in the
|
||||||
// block.
|
// block.
|
||||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||||
ht.AssertTxInBlock(block, breachTXID)
|
ht.AssertTxInBlock(block, *breachTXID)
|
||||||
|
|
||||||
// Construct to_remote output which pays to Bob. Based on the output
|
// Construct to_remote output which pays to Bob. Based on the output
|
||||||
// ordering, the first output in this breach tx is the to_remote
|
// ordering, the first output in this breach tx is the to_remote
|
||||||
// output.
|
// output.
|
||||||
toRemoteOp := wire.OutPoint{
|
toRemoteOp := wire.OutPoint{
|
||||||
Hash: breachTXID,
|
Hash: *breachTXID,
|
||||||
Index: 0,
|
Index: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +155,7 @@ func breachRetributionTestCase(ht *lntest.HarnessTest,
|
|||||||
// Assert that all the inputs of this transaction are spending outputs
|
// Assert that all the inputs of this transaction are spending outputs
|
||||||
// generated by Bob's breach transaction above.
|
// generated by Bob's breach transaction above.
|
||||||
for _, txIn := range justiceTx.TxIn {
|
for _, txIn := range justiceTx.TxIn {
|
||||||
require.Equal(ht, breachTXID, txIn.PreviousOutPoint.Hash,
|
require.Equal(ht, *breachTXID, txIn.PreviousOutPoint.Hash,
|
||||||
"justice tx not spending commitment utxo")
|
"justice tx not spending commitment utxo")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +300,7 @@ func revokedCloseRetributionZeroValueRemoteOutputCase(ht *lntest.HarnessTest,
|
|||||||
// broadcasting her current channel state. This is actually the
|
// broadcasting her current channel state. This is actually the
|
||||||
// commitment transaction of a prior *revoked* state, so she'll soon
|
// commitment transaction of a prior *revoked* state, so she'll soon
|
||||||
// feel the wrath of Dave's retribution.
|
// feel the wrath of Dave's retribution.
|
||||||
stream, closeTxID := ht.CloseChannelAssertPending(
|
stream, closeUpdate := ht.CloseChannelAssertPending(
|
||||||
carol, chanPoint, true,
|
carol, chanPoint, true,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -310,9 +314,11 @@ func revokedCloseRetributionZeroValueRemoteOutputCase(ht *lntest.HarnessTest,
|
|||||||
// state and continues exacting justice after his node restarts.
|
// state and continues exacting justice after his node restarts.
|
||||||
ht.RestartNode(dave)
|
ht.RestartNode(dave)
|
||||||
|
|
||||||
|
closeTxID := closeUpdate.GetClosePending().Txid
|
||||||
|
|
||||||
// The breachTXID should match the above closeTxID.
|
// The breachTXID should match the above closeTxID.
|
||||||
breachTXID := ht.WaitForChannelCloseEvent(stream)
|
breachTXID := ht.WaitForChannelCloseEvent(stream)
|
||||||
require.EqualValues(ht, breachTXID, closeTxID)
|
require.EqualValues(ht, breachTXID[:], closeTxID)
|
||||||
|
|
||||||
// Construct to_local output which pays to Dave. Based on the output
|
// Construct to_local output which pays to Dave. Based on the output
|
||||||
// ordering, the first output in this breach tx is the to_local
|
// ordering, the first output in this breach tx is the to_local
|
||||||
@@ -543,9 +549,13 @@ func revokedCloseRetributionRemoteHodlCase(ht *lntest.HarnessTest,
|
|||||||
// broadcasting her current channel state. This is actually the
|
// broadcasting her current channel state. This is actually the
|
||||||
// commitment transaction of a prior *revoked* state, so she'll soon
|
// commitment transaction of a prior *revoked* state, so she'll soon
|
||||||
// feel the wrath of Dave's retribution.
|
// feel the wrath of Dave's retribution.
|
||||||
closeUpdates, closeTxID := ht.CloseChannelAssertPending(
|
closeUpdates, closeUpd := ht.CloseChannelAssertPending(
|
||||||
carol, chanPoint, true,
|
carol, chanPoint, true,
|
||||||
)
|
)
|
||||||
|
pendingCloseUpd := closeUpd.GetClosePending()
|
||||||
|
require.NotNil(ht, pendingCloseUpd)
|
||||||
|
closeTxID, err := chainhash.NewHash(pendingCloseUpd.Txid)
|
||||||
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Generate a single block to mine the breach transaction.
|
// Generate a single block to mine the breach transaction.
|
||||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||||
@@ -593,7 +603,7 @@ func revokedCloseRetributionRemoteHodlCase(ht *lntest.HarnessTest,
|
|||||||
return nil, errNotFound
|
return nil, errNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
err := wait.NoError(func() error {
|
err = wait.NoError(func() error {
|
||||||
txid, err := findJusticeTx()
|
txid, err := findJusticeTx()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/contractcourt"
|
"github.com/lightningnetwork/lnd/contractcourt"
|
||||||
"github.com/lightningnetwork/lnd/fn/v2"
|
"github.com/lightningnetwork/lnd/fn/v2"
|
||||||
@@ -1963,8 +1964,8 @@ func testBumpForceCloseFee(ht *lntest.HarnessTest) {
|
|||||||
ht.FundCoinsP2TR(btcutil.SatoshiPerBitcoin, alice)
|
ht.FundCoinsP2TR(btcutil.SatoshiPerBitcoin, alice)
|
||||||
|
|
||||||
// Alice force closes the channel which has no HTLCs at stake.
|
// Alice force closes the channel which has no HTLCs at stake.
|
||||||
_, closingTxID := ht.CloseChannelAssertPending(alice, chanPoint, true)
|
_, closeUpdates := ht.CloseChannelAssertPending(alice, chanPoint, true)
|
||||||
require.NotNil(ht, closingTxID)
|
require.NotNil(ht, closeUpdates)
|
||||||
|
|
||||||
// Alice should see one waiting close channel.
|
// Alice should see one waiting close channel.
|
||||||
ht.AssertNumWaitingClose(alice, 1)
|
ht.AssertNumWaitingClose(alice, 1)
|
||||||
@@ -1974,8 +1975,10 @@ func testBumpForceCloseFee(ht *lntest.HarnessTest) {
|
|||||||
ht.AssertNumPendingSweeps(alice, 2)
|
ht.AssertNumPendingSweeps(alice, 2)
|
||||||
|
|
||||||
// Calculate the commitment tx fee rate.
|
// Calculate the commitment tx fee rate.
|
||||||
closingTx := ht.AssertTxInMempool(closingTxID)
|
pendingClose := closeUpdates.GetClosePending()
|
||||||
require.NotNil(ht, closingTx)
|
closeTxid, err := chainhash.NewHash(pendingClose.Txid)
|
||||||
|
require.NoError(ht, err)
|
||||||
|
closingTx := ht.AssertTxInMempool(*closeTxid)
|
||||||
|
|
||||||
// The default commitment fee for anchor channels is capped at 2500
|
// The default commitment fee for anchor channels is capped at 2500
|
||||||
// sat/kw but there might be some inaccuracies because of the witness
|
// sat/kw but there might be some inaccuracies because of the witness
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntest.HarnessTest,
|
|||||||
// broadcasting his current channel state. This is actually the
|
// broadcasting his current channel state. This is actually the
|
||||||
// commitment transaction of a prior *revoked* state, so he'll soon
|
// commitment transaction of a prior *revoked* state, so he'll soon
|
||||||
// feel the wrath of Dave's retribution.
|
// feel the wrath of Dave's retribution.
|
||||||
closeUpdates, closeTxID := ht.CloseChannelAssertPending(
|
closeUpdates, pendingClose := ht.CloseChannelAssertPending(
|
||||||
carol, chanPoint, true,
|
carol, chanPoint, true,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -504,7 +504,8 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntest.HarnessTest,
|
|||||||
ht.AssertTxInBlock(block, breachTXID)
|
ht.AssertTxInBlock(block, breachTXID)
|
||||||
|
|
||||||
// The breachTXID should match the above closeTxID.
|
// The breachTXID should match the above closeTxID.
|
||||||
require.EqualValues(ht, breachTXID, closeTxID)
|
closeTxID := pendingClose.GetClosePending().Txid
|
||||||
|
require.EqualValues(ht, breachTXID[:], closeTxID)
|
||||||
|
|
||||||
// Query the mempool for Dave's justice transaction, this should be
|
// Query the mempool for Dave's justice transaction, this should be
|
||||||
// broadcast as Carol's contract breaching transaction gets confirmed
|
// broadcast as Carol's contract breaching transaction gets confirmed
|
||||||
|
|||||||
+32
-7
@@ -1208,14 +1208,40 @@ func (h *HarnessTest) OpenChannelAssertErr(srcNode, destNode *node.HarnessNode,
|
|||||||
"error returned, want %v, got %v", expectedErr, err)
|
"error returned, want %v, got %v", expectedErr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// closeChannelOpts holds the options for closing a channel.
|
||||||
|
type closeChannelOpts struct {
|
||||||
|
feeRate fn.Option[chainfee.SatPerVByte]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseChanOpt is a functional option to modify the way we close a channel.
|
||||||
|
type CloseChanOpt func(*closeChannelOpts)
|
||||||
|
|
||||||
|
// WithCoopCloseFeeRate is a functional option to set the fee rate for a coop
|
||||||
|
// close attempt.
|
||||||
|
func WithCoopCloseFeeRate(rate chainfee.SatPerVByte) CloseChanOpt {
|
||||||
|
return func(o *closeChannelOpts) {
|
||||||
|
o.feeRate = fn.Some(rate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaultCloseOpts returns the set of default close options.
|
||||||
|
func defaultCloseOpts() *closeChannelOpts {
|
||||||
|
return &closeChannelOpts{}
|
||||||
|
}
|
||||||
|
|
||||||
// CloseChannelAssertPending attempts to close the channel indicated by the
|
// CloseChannelAssertPending attempts to close the channel indicated by the
|
||||||
// passed channel point, initiated by the passed node. Once the CloseChannel
|
// passed channel point, initiated by the passed node. Once the CloseChannel
|
||||||
// rpc is called, it will consume one event and assert it's a close pending
|
// rpc is called, it will consume one event and assert it's a close pending
|
||||||
// event. In addition, it will check that the closing tx can be found in the
|
// event. In addition, it will check that the closing tx can be found in the
|
||||||
// mempool.
|
// mempool.
|
||||||
func (h *HarnessTest) CloseChannelAssertPending(hn *node.HarnessNode,
|
func (h *HarnessTest) CloseChannelAssertPending(hn *node.HarnessNode,
|
||||||
cp *lnrpc.ChannelPoint,
|
cp *lnrpc.ChannelPoint, force bool,
|
||||||
force bool) (rpc.CloseChanClient, chainhash.Hash) {
|
opts ...CloseChanOpt) (rpc.CloseChanClient, *lnrpc.CloseStatusUpdate) {
|
||||||
|
|
||||||
|
closeOpts := defaultCloseOpts()
|
||||||
|
for _, optFunc := range opts {
|
||||||
|
optFunc(closeOpts)
|
||||||
|
}
|
||||||
|
|
||||||
// Calls the rpc to close the channel.
|
// Calls the rpc to close the channel.
|
||||||
closeReq := &lnrpc.CloseChannelRequest{
|
closeReq := &lnrpc.CloseChannelRequest{
|
||||||
@@ -1224,10 +1250,9 @@ func (h *HarnessTest) CloseChannelAssertPending(hn *node.HarnessNode,
|
|||||||
NoWait: true,
|
NoWait: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// For coop close, we use a default confg target of 6.
|
closeOpts.feeRate.WhenSome(func(feeRate chainfee.SatPerVByte) {
|
||||||
if !force {
|
closeReq.SatPerVbyte = uint64(feeRate)
|
||||||
closeReq.TargetConf = 6
|
})
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
stream rpc.CloseChanClient
|
stream rpc.CloseChanClient
|
||||||
@@ -1260,7 +1285,7 @@ func (h *HarnessTest) CloseChannelAssertPending(hn *node.HarnessNode,
|
|||||||
// Assert the closing tx is in the mempool.
|
// Assert the closing tx is in the mempool.
|
||||||
h.miner.AssertTxInMempool(*closeTxid)
|
h.miner.AssertTxInMempool(*closeTxid)
|
||||||
|
|
||||||
return stream, *closeTxid
|
return stream, event
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloseChannel attempts to coop close a non-anchored channel identified by the
|
// CloseChannel attempts to coop close a non-anchored channel identified by the
|
||||||
|
|||||||
Reference in new issue
Block a user