mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-19 05:45:21 +01:00
itest: test backup restore of script enforced lease channel type
This commit is contained in:
parent
0b0dd65c93
commit
e891dd0fd3
@ -1109,7 +1109,7 @@ func assertNumPendingChannels(t *harnessTest, node *lntest.HarnessNode,
|
||||
func assertDLPExecuted(net *lntest.NetworkHarness, t *harnessTest,
|
||||
carol *lntest.HarnessNode, carolStartingBalance int64,
|
||||
dave *lntest.HarnessNode, daveStartingBalance int64,
|
||||
anchors bool) {
|
||||
commitType lnrpc.CommitmentType) {
|
||||
|
||||
// Increase the fee estimate so that the following force close tx will
|
||||
// be cpfp'ed.
|
||||
@ -1124,7 +1124,7 @@ func assertDLPExecuted(net *lntest.NetworkHarness, t *harnessTest,
|
||||
// Upon reconnection, the nodes should detect that Dave is out of sync.
|
||||
// Carol should force close the channel using her latest commitment.
|
||||
expectedTxes := 1
|
||||
if anchors {
|
||||
if commitTypeHasAnchors(commitType) {
|
||||
expectedTxes = 2
|
||||
}
|
||||
_, err := waitForNTxsInMempool(
|
||||
@ -1151,13 +1151,6 @@ func assertDLPExecuted(net *lntest.NetworkHarness, t *harnessTest,
|
||||
// Generate a single block, which should confirm the closing tx.
|
||||
_ = mineBlocks(t, net, 1, expectedTxes)[0]
|
||||
|
||||
// Dave should sweep his funds immediately, as they are not timelocked.
|
||||
// We also expect Dave to sweep his anchor, if present.
|
||||
_, err = waitForNTxsInMempool(
|
||||
net.Miner.Client, expectedTxes, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err, "unable to find Dave's sweep tx in mempool")
|
||||
|
||||
// Dave should consider the channel pending force close (since he is
|
||||
// waiting for his sweep to confirm).
|
||||
assertNumPendingChannels(t, dave, 0, 1)
|
||||
@ -1166,11 +1159,93 @@ func assertDLPExecuted(net *lntest.NetworkHarness, t *harnessTest,
|
||||
// before she can sweep her outputs.
|
||||
assertNumPendingChannels(t, carol, 0, 1)
|
||||
|
||||
// Mine the sweep tx.
|
||||
_ = mineBlocks(t, net, 1, expectedTxes)[0]
|
||||
if commitType == lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE {
|
||||
// Dave should sweep his anchor only, since he still has the
|
||||
// lease CLTV constraint on his commitment output.
|
||||
_, err = waitForNTxsInMempool(
|
||||
net.Miner.Client, 1, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err, "unable to find Dave's anchor sweep "+
|
||||
"tx in mempool")
|
||||
|
||||
// Now Dave should consider the channel fully closed.
|
||||
assertNumPendingChannels(t, dave, 0, 0)
|
||||
// Mine Dave's anchor sweep tx.
|
||||
_ = mineBlocks(t, net, 1, 1)[0]
|
||||
|
||||
// After Carol's output matures, she should also reclaim her
|
||||
// funds.
|
||||
//
|
||||
// The commit sweep resolver publishes the sweep tx at
|
||||
// defaultCSV-1 and we already mined one block after the
|
||||
// commitmment was published, so take that into account.
|
||||
mineBlocks(t, net, defaultCSV-1-1, 0)
|
||||
carolSweep, err := waitForTxInMempool(
|
||||
net.Miner.Client, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err, "unable to find Carol's sweep tx in "+
|
||||
"mempool")
|
||||
block := mineBlocks(t, net, 1, 1)[0]
|
||||
assertTxInBlock(t, block, carolSweep)
|
||||
|
||||
// Now the channel should be fully closed also from Carol's POV.
|
||||
assertNumPendingChannels(t, carol, 0, 0)
|
||||
|
||||
// We'll now mine the remaining blocks to prompt Dave to sweep
|
||||
// his CLTV-constrained output.
|
||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||
defer cancel()
|
||||
resp, err := dave.PendingChannels(
|
||||
ctxt, &lnrpc.PendingChannelsRequest{},
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
blocksTilMaturity :=
|
||||
resp.PendingForceClosingChannels[0].BlocksTilMaturity
|
||||
require.Positive(t.t, blocksTilMaturity)
|
||||
|
||||
mineBlocks(t, net, uint32(blocksTilMaturity), 0)
|
||||
daveSweep, err := waitForTxInMempool(
|
||||
net.Miner.Client, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err, "unable to find Dave's sweep tx in "+
|
||||
"mempool")
|
||||
block = mineBlocks(t, net, 1, 1)[0]
|
||||
assertTxInBlock(t, block, daveSweep)
|
||||
|
||||
// Now Dave should consider the channel fully closed.
|
||||
assertNumPendingChannels(t, dave, 0, 0)
|
||||
} else {
|
||||
// Dave should sweep his funds immediately, as they are not
|
||||
// timelocked. We also expect Dave to sweep his anchor, if
|
||||
// present.
|
||||
_, err = waitForNTxsInMempool(
|
||||
net.Miner.Client, expectedTxes, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err, "unable to find Dave's sweep tx in "+
|
||||
"mempool")
|
||||
|
||||
// Mine the sweep tx.
|
||||
_ = mineBlocks(t, net, 1, expectedTxes)[0]
|
||||
|
||||
// Now Dave should consider the channel fully closed.
|
||||
assertNumPendingChannels(t, dave, 0, 0)
|
||||
|
||||
// After Carol's output matures, she should also reclaim her
|
||||
// funds.
|
||||
//
|
||||
// The commit sweep resolver publishes the sweep tx at
|
||||
// defaultCSV-1 and we already mined one block after the
|
||||
// commitmment was published, so take that into account.
|
||||
mineBlocks(t, net, defaultCSV-1-1, 0)
|
||||
carolSweep, err := waitForTxInMempool(
|
||||
net.Miner.Client, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err, "unable to find Carol's sweep tx in "+
|
||||
"mempool")
|
||||
block := mineBlocks(t, net, 1, 1)[0]
|
||||
assertTxInBlock(t, block, carolSweep)
|
||||
|
||||
// Now the channel should be fully closed also from Carol's POV.
|
||||
assertNumPendingChannels(t, carol, 0, 0)
|
||||
}
|
||||
|
||||
// We query Dave's balance to make sure it increased after the channel
|
||||
// closed. This checks that he was able to sweep the funds he had in
|
||||
@ -1185,22 +1260,6 @@ func assertDLPExecuted(net *lntest.NetworkHarness, t *harnessTest,
|
||||
t.t, daveBalance, daveStartingBalance, "balance not increased",
|
||||
)
|
||||
|
||||
// After the Carol's output matures, she should also reclaim her funds.
|
||||
//
|
||||
// The commit sweep resolver publishes the sweep tx at defaultCSV-1 and
|
||||
// we already mined one block after the commitment was published, so
|
||||
// take that into account.
|
||||
mineBlocks(t, net, defaultCSV-1-1, 0)
|
||||
carolSweep, err := waitForTxInMempool(
|
||||
net.Miner.Client, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err, "unable to find Carol's sweep tx in mempool")
|
||||
block := mineBlocks(t, net, 1, 1)[0]
|
||||
assertTxInBlock(t, block, carolSweep)
|
||||
|
||||
// Now the channel should be fully closed also from Carol's POV.
|
||||
assertNumPendingChannels(t, carol, 0, 0)
|
||||
|
||||
// Make sure Carol got her balance back.
|
||||
err = wait.NoError(func() error {
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
|
@ -337,10 +337,37 @@ func testChannelBackupRestore(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
// Restore the backup from the on-disk file, using the RPC
|
||||
// interface, for anchor commitment channels.
|
||||
{
|
||||
name: "restore from backup file anchors",
|
||||
initiator: true,
|
||||
private: false,
|
||||
anchorCommit: true,
|
||||
name: "restore from backup file anchors",
|
||||
initiator: true,
|
||||
private: false,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
restoreMethod: func(oldNode *lntest.HarnessNode,
|
||||
backupFilePath string,
|
||||
mnemonic []string) (nodeRestorer, error) {
|
||||
|
||||
// Read the entire Multi backup stored within
|
||||
// this node's channels.backup file.
|
||||
multi, err := ioutil.ReadFile(backupFilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now that we have Dave's backup file, we'll
|
||||
// create a new nodeRestorer that will restore
|
||||
// using the on-disk channels.backup.
|
||||
return chanRestoreViaRPC(
|
||||
net, password, mnemonic, multi, oldNode,
|
||||
)
|
||||
},
|
||||
},
|
||||
|
||||
// Restore the backup from the on-disk file, using the RPC
|
||||
// interface, for script-enforced leased channels.
|
||||
{
|
||||
name: "restore from backup file script enforced lease",
|
||||
initiator: true,
|
||||
private: false,
|
||||
commitmentType: lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE,
|
||||
restoreMethod: func(oldNode *lntest.HarnessNode,
|
||||
backupFilePath string,
|
||||
mnemonic []string) (nodeRestorer, error) {
|
||||
@ -399,7 +426,7 @@ func testChannelBackupRestore(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
"anchors",
|
||||
initiator: true,
|
||||
private: false,
|
||||
anchorCommit: true,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
localForceClose: true,
|
||||
restoreMethod: func(oldNode *lntest.HarnessNode,
|
||||
backupFilePath string,
|
||||
@ -814,9 +841,9 @@ type chanRestoreTestCase struct {
|
||||
// confirmed or not.
|
||||
unconfirmed bool
|
||||
|
||||
// anchorCommit is true, then the new anchor commitment type will be
|
||||
// used for the channels created in the test.
|
||||
anchorCommit bool
|
||||
// commitmentType specifies the commitment type that should be used for
|
||||
// the channel from Dave to Carol.
|
||||
commitmentType lnrpc.CommitmentType
|
||||
|
||||
// legacyRevocation signals if a channel with the legacy revocation
|
||||
// producer format should also be created before restoring.
|
||||
@ -854,11 +881,9 @@ func testChanRestoreScenario(t *harnessTest, net *lntest.NetworkHarness,
|
||||
"--minbackoff=50ms",
|
||||
"--maxbackoff=1s",
|
||||
}
|
||||
if testCase.anchorCommit {
|
||||
anchorNodeArgs := nodeArgsForCommitType(
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
nodeArgs = append(nodeArgs, anchorNodeArgs...)
|
||||
if testCase.commitmentType != lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE {
|
||||
args := nodeArgsForCommitType(testCase.commitmentType)
|
||||
nodeArgs = append(nodeArgs, args...)
|
||||
}
|
||||
|
||||
// First, we'll create a brand new node we'll use within the test. If
|
||||
@ -884,7 +909,7 @@ func testChanRestoreScenario(t *harnessTest, net *lntest.NetworkHarness,
|
||||
|
||||
// For the anchor output case we need two UTXOs for Carol so she can
|
||||
// sweep both the local and remote anchor.
|
||||
if testCase.anchorCommit {
|
||||
if commitTypeHasAnchors(testCase.commitmentType) {
|
||||
net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, carol)
|
||||
}
|
||||
|
||||
@ -936,12 +961,23 @@ func testChanRestoreScenario(t *harnessTest, net *lntest.NetworkHarness,
|
||||
)
|
||||
|
||||
default:
|
||||
var fundingShim *lnrpc.FundingShim
|
||||
if testCase.commitmentType == lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE {
|
||||
_, minerHeight, err := net.Miner.Client.GetBestBlock()
|
||||
require.NoError(t.t, err)
|
||||
thawHeight := uint32(minerHeight + 144)
|
||||
|
||||
fundingShim, _, _ = deriveFundingShim(
|
||||
net, t, from, to, chanAmt, thawHeight, true,
|
||||
)
|
||||
}
|
||||
chanPoint = openChannelAndAssert(
|
||||
t, net, from, to,
|
||||
lntest.OpenChannelParams{
|
||||
Amt: chanAmt,
|
||||
PushAmt: pushAmt,
|
||||
Private: testCase.private,
|
||||
t, net, from, to, lntest.OpenChannelParams{
|
||||
Amt: chanAmt,
|
||||
PushAmt: pushAmt,
|
||||
Private: testCase.private,
|
||||
FundingShim: fundingShim,
|
||||
CommitmentType: testCase.commitmentType,
|
||||
},
|
||||
)
|
||||
|
||||
@ -1086,7 +1122,8 @@ func testChanRestoreScenario(t *harnessTest, net *lntest.NetworkHarness,
|
||||
|
||||
assertTimeLockSwept(
|
||||
net, t, carol, carolStartingBalance, dave,
|
||||
daveStartingBalance, testCase.anchorCommit,
|
||||
daveStartingBalance,
|
||||
commitTypeHasAnchors(testCase.commitmentType),
|
||||
)
|
||||
|
||||
return
|
||||
@ -1167,7 +1204,7 @@ func testChanRestoreScenario(t *harnessTest, net *lntest.NetworkHarness,
|
||||
require.NoError(t.t, err)
|
||||
|
||||
numUTXOs := 1
|
||||
if testCase.anchorCommit {
|
||||
if commitTypeHasAnchors(testCase.commitmentType) {
|
||||
numUTXOs = 2
|
||||
}
|
||||
assertNumUTXOs(t.t, carol, numUTXOs)
|
||||
@ -1183,7 +1220,7 @@ func testChanRestoreScenario(t *harnessTest, net *lntest.NetworkHarness,
|
||||
// end of the protocol.
|
||||
assertDLPExecuted(
|
||||
net, t, carol, carolStartingBalance, dave, daveStartingBalance,
|
||||
testCase.anchorCommit,
|
||||
testCase.commitmentType,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1014,7 @@ func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
// on chain, and both of them properly carry out the DLP protocol.
|
||||
assertDLPExecuted(
|
||||
net, t, carol, carolStartingBalance, dave, daveStartingBalance,
|
||||
false,
|
||||
lnrpc.CommitmentType_STATIC_REMOTE_KEY,
|
||||
)
|
||||
|
||||
// As a second part of this test, we will test the scenario where a
|
||||
|
Loading…
Reference in New Issue
Block a user