mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-23 07:11:11 +02:00
itest+sweep: fix current itest re anchor deadline
This commit is contained in:
parent
e68c0235c6
commit
4079f61d7e
@ -216,34 +216,17 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||||||
// We expect to see Alice's force close tx in the mempool.
|
// We expect to see Alice's force close tx in the mempool.
|
||||||
ht.Miner.GetNumTxsFromMempool(1)
|
ht.Miner.GetNumTxsFromMempool(1)
|
||||||
|
|
||||||
// Assert Alice's has the pending anchor outputs - one for local and
|
|
||||||
// the other for remote (invalid).
|
|
||||||
sweeps := ht.AssertNumPendingSweeps(alice, 2)
|
|
||||||
aliceAnchor := sweeps[0]
|
|
||||||
if aliceAnchor.Outpoint.TxidStr != waitingClose.Commitments.LocalTxid {
|
|
||||||
aliceAnchor = sweeps[1]
|
|
||||||
}
|
|
||||||
require.Equal(ht, aliceAnchor.Outpoint.TxidStr,
|
|
||||||
waitingClose.Commitments.LocalTxid)
|
|
||||||
|
|
||||||
// Mine a block which should confirm the commitment transaction
|
// Mine a block which should confirm the commitment transaction
|
||||||
// broadcast as a result of the force closure. Once mined, we also
|
// broadcast as a result of the force closure. Once mined, we also
|
||||||
// expect Alice's anchor sweeping tx being published.
|
// expect Alice's anchor sweeping tx being published.
|
||||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||||
|
|
||||||
// Assert Alice's anchor sweeping tx is found in the mempool.
|
// Assert Alice's has one pending anchor output - because she doesn't
|
||||||
aliceSweepTxid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
// have incoming HTLCs, her outgoing HTLC won't have a deadline, thus
|
||||||
|
// she won't use the anchor to perform CPFP.
|
||||||
// Add alice's anchor to our expected set of reports.
|
aliceAnchor := ht.AssertNumPendingSweeps(alice, 1)[0]
|
||||||
op := fmt.Sprintf("%v:%v", aliceAnchor.Outpoint.TxidStr,
|
require.Equal(ht, aliceAnchor.Outpoint.TxidStr,
|
||||||
aliceAnchor.Outpoint.OutputIndex)
|
waitingClose.Commitments.LocalTxid)
|
||||||
aliceReports[op] = &lnrpc.Resolution{
|
|
||||||
ResolutionType: lnrpc.ResolutionType_ANCHOR,
|
|
||||||
Outcome: lnrpc.ResolutionOutcome_CLAIMED,
|
|
||||||
SweepTxid: aliceSweepTxid.String(),
|
|
||||||
Outpoint: aliceAnchor.Outpoint,
|
|
||||||
AmountSat: uint64(anchorSize),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now that the commitment has been confirmed, the channel should be
|
// Now that the commitment has been confirmed, the channel should be
|
||||||
// marked as force closed.
|
// marked as force closed.
|
||||||
@ -290,10 +273,8 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mine a block to trigger Carol's sweeper to make decisions on the
|
// Mine a block to trigger Carol's sweeper to make decisions on the
|
||||||
// anchor sweeping. This block will also confirm Alice's anchor
|
// anchor sweeping.
|
||||||
// sweeping tx as her anchor is used for CPFP due to there are
|
ht.MineEmptyBlocks(1)
|
||||||
// time-sensitive HTLCs.
|
|
||||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
|
||||||
|
|
||||||
// Carol's sweep tx should be in the mempool already, as her output is
|
// Carol's sweep tx should be in the mempool already, as her output is
|
||||||
// not timelocked.
|
// not timelocked.
|
||||||
@ -307,7 +288,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||||||
totalFeeCarol := ht.CalculateTxFee(carolTx)
|
totalFeeCarol := ht.CalculateTxFee(carolTx)
|
||||||
|
|
||||||
// If we have anchors, add an anchor resolution for carol.
|
// If we have anchors, add an anchor resolution for carol.
|
||||||
op = fmt.Sprintf("%v:%v", carolAnchor.Outpoint.TxidStr,
|
op := fmt.Sprintf("%v:%v", carolAnchor.Outpoint.TxidStr,
|
||||||
carolAnchor.Outpoint.OutputIndex)
|
carolAnchor.Outpoint.OutputIndex)
|
||||||
carolReports[op] = &lnrpc.Resolution{
|
carolReports[op] = &lnrpc.Resolution{
|
||||||
ResolutionType: lnrpc.ResolutionType_ANCHOR,
|
ResolutionType: lnrpc.ResolutionType_ANCHOR,
|
||||||
@ -336,27 +317,8 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||||||
// commit and anchor outputs.
|
// commit and anchor outputs.
|
||||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||||
|
|
||||||
// Once Alice's anchor sweeping is mined, she should have no pending
|
// Alice should still have the anchor sweeping request.
|
||||||
// sweep requests atm.
|
ht.AssertNumPendingSweeps(alice, 1)
|
||||||
ht.AssertNumPendingSweeps(alice, 0)
|
|
||||||
|
|
||||||
// TODO(yy): fix the case in 0.18.1 - the CPFP anchor sweeping may be
|
|
||||||
// replaced with a following request after the above restart - the
|
|
||||||
// anchor will be offered to the sweeper again with updated params,
|
|
||||||
// which cannot be swept due to it being uneconomical.
|
|
||||||
var anchorRecovered bool
|
|
||||||
err = wait.NoError(func() error {
|
|
||||||
sweepResp := alice.RPC.ListSweeps(false, 0)
|
|
||||||
txns := sweepResp.GetTransactionIds().TransactionIds
|
|
||||||
|
|
||||||
if len(txns) >= 1 {
|
|
||||||
anchorRecovered = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("expected 1 sweep tx, got %d", len(txns))
|
|
||||||
}, wait.DefaultTimeout)
|
|
||||||
ht.Logf("waiting for Alice's anchor sweep to be broadcast: %v", err)
|
|
||||||
|
|
||||||
// The following restart checks to ensure that outputs in the
|
// The following restart checks to ensure that outputs in the
|
||||||
// kindergarten bucket are persisted while waiting for the required
|
// kindergarten bucket are persisted while waiting for the required
|
||||||
@ -399,12 +361,8 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||||||
return errors.New("all funds should still be in " +
|
return errors.New("all funds should still be in " +
|
||||||
"limbo")
|
"limbo")
|
||||||
}
|
}
|
||||||
if !anchorRecovered {
|
if forceClose.RecoveredBalance != 0 {
|
||||||
return nil
|
return errors.New("no funds should be recovered")
|
||||||
}
|
|
||||||
if forceClose.RecoveredBalance != anchorSize {
|
|
||||||
return fmt.Errorf("expected %v to be recovered",
|
|
||||||
anchorSize)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -417,7 +375,11 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||||||
|
|
||||||
// At this point, the CSV will expire in the next block, meaning that
|
// At this point, the CSV will expire in the next block, meaning that
|
||||||
// the output should be offered to the sweeper.
|
// the output should be offered to the sweeper.
|
||||||
aliceCommit := ht.AssertNumPendingSweeps(alice, 1)[0]
|
sweeps := ht.AssertNumPendingSweeps(alice, 2)
|
||||||
|
commitSweep, anchorSweep := sweeps[0], sweeps[1]
|
||||||
|
if commitSweep.AmountSat < anchorSweep.AmountSat {
|
||||||
|
commitSweep, anchorSweep = anchorSweep, commitSweep
|
||||||
|
}
|
||||||
|
|
||||||
// Restart Alice to ensure that she resumes watching the finalized
|
// Restart Alice to ensure that she resumes watching the finalized
|
||||||
// commitment sweep txid.
|
// commitment sweep txid.
|
||||||
@ -438,16 +400,27 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We expect a resolution which spends our commit output.
|
// We expect a resolution which spends our commit output.
|
||||||
op = fmt.Sprintf("%v:%v", aliceCommit.Outpoint.TxidStr,
|
op = fmt.Sprintf("%v:%v", commitSweep.Outpoint.TxidStr,
|
||||||
aliceCommit.Outpoint.OutputIndex)
|
commitSweep.Outpoint.OutputIndex)
|
||||||
aliceReports[op] = &lnrpc.Resolution{
|
aliceReports[op] = &lnrpc.Resolution{
|
||||||
ResolutionType: lnrpc.ResolutionType_COMMIT,
|
ResolutionType: lnrpc.ResolutionType_COMMIT,
|
||||||
Outcome: lnrpc.ResolutionOutcome_CLAIMED,
|
Outcome: lnrpc.ResolutionOutcome_CLAIMED,
|
||||||
SweepTxid: sweepingTXID.String(),
|
SweepTxid: sweepingTXID.String(),
|
||||||
Outpoint: aliceCommit.Outpoint,
|
Outpoint: commitSweep.Outpoint,
|
||||||
AmountSat: uint64(aliceBalance),
|
AmountSat: uint64(aliceBalance),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add alice's anchor to our expected set of reports.
|
||||||
|
op = fmt.Sprintf("%v:%v", aliceAnchor.Outpoint.TxidStr,
|
||||||
|
aliceAnchor.Outpoint.OutputIndex)
|
||||||
|
aliceReports[op] = &lnrpc.Resolution{
|
||||||
|
ResolutionType: lnrpc.ResolutionType_ANCHOR,
|
||||||
|
Outcome: lnrpc.ResolutionOutcome_CLAIMED,
|
||||||
|
SweepTxid: sweepingTXID.String(),
|
||||||
|
Outpoint: aliceAnchor.Outpoint,
|
||||||
|
AmountSat: uint64(anchorSize),
|
||||||
|
}
|
||||||
|
|
||||||
// Check that we can find the commitment sweep in our set of known
|
// Check that we can find the commitment sweep in our set of known
|
||||||
// sweeps, using the simple transaction id ListSweeps output.
|
// sweeps, using the simple transaction id ListSweeps output.
|
||||||
ht.AssertSweepFound(alice, sweepingTXID.String(), false, 0)
|
ht.AssertSweepFound(alice, sweepingTXID.String(), false, 0)
|
||||||
|
@ -713,9 +713,11 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
|
|||||||
// to be mined to trigger a force close later on.
|
// to be mined to trigger a force close later on.
|
||||||
var blocksMined uint32
|
var blocksMined uint32
|
||||||
|
|
||||||
// Increase the fee estimate so that the following force close tx will
|
// We need to mine a block otherwise `FindOutgoingHTLCDeadline` cannot
|
||||||
// be cpfp'ed.
|
// find the incoming HTLC on Bob's ChainArbitrator.
|
||||||
ht.SetFeeEstimate(30000)
|
//
|
||||||
|
// TODO(yy): Investigate and fix it!
|
||||||
|
ht.MineEmptyBlocks(1)
|
||||||
|
|
||||||
// Now that all parties have the HTLC locked in, we'll immediately
|
// Now that all parties have the HTLC locked in, we'll immediately
|
||||||
// force close the Bob -> Carol channel. This should trigger contract
|
// force close the Bob -> Carol channel. This should trigger contract
|
||||||
@ -755,7 +757,7 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
|
|||||||
ht.MineEmptyBlocks(int(defaultCSV - blocksMined))
|
ht.MineEmptyBlocks(int(defaultCSV - blocksMined))
|
||||||
blocksMined = defaultCSV
|
blocksMined = defaultCSV
|
||||||
|
|
||||||
// Assert Bob has the sweep and trigger it..
|
// Assert Bob has the sweep and trigger it.
|
||||||
ht.AssertNumPendingSweeps(bob, 1)
|
ht.AssertNumPendingSweeps(bob, 1)
|
||||||
ht.MineEmptyBlocks(1)
|
ht.MineEmptyBlocks(1)
|
||||||
blocksMined++
|
blocksMined++
|
||||||
@ -1523,10 +1525,6 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||||||
ht.AssertNumPendingSweeps(bob, 1)
|
ht.AssertNumPendingSweeps(bob, 1)
|
||||||
ht.AssertNumPendingSweeps(alice, 1)
|
ht.AssertNumPendingSweeps(alice, 1)
|
||||||
|
|
||||||
// Mine a block to confirm Alice's CPFP anchor sweeping.
|
|
||||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
|
||||||
blocksMined++
|
|
||||||
|
|
||||||
// Mine enough blocks for Alice to sweep her funds from the force
|
// Mine enough blocks for Alice to sweep her funds from the force
|
||||||
// closed channel. AssertStreamChannelForceClosed() already mined a
|
// closed channel. AssertStreamChannelForceClosed() already mined a
|
||||||
// block containing the commitment tx and the commit sweep tx will be
|
// block containing the commitment tx and the commit sweep tx will be
|
||||||
@ -1537,7 +1535,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||||||
blocksMined = defaultCSV
|
blocksMined = defaultCSV
|
||||||
|
|
||||||
// Alice should now sweep her funds.
|
// Alice should now sweep her funds.
|
||||||
ht.AssertNumPendingSweeps(alice, 1)
|
ht.AssertNumPendingSweeps(alice, 2)
|
||||||
|
|
||||||
// Mine a block to trigger the sweep.
|
// Mine a block to trigger the sweep.
|
||||||
ht.MineEmptyBlocks(1)
|
ht.MineEmptyBlocks(1)
|
||||||
@ -1690,7 +1688,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||||||
ht.MineEmptyBlocks(numBlocks)
|
ht.MineEmptyBlocks(numBlocks)
|
||||||
|
|
||||||
// Both Alice and Bob should offer their commit sweeps.
|
// Both Alice and Bob should offer their commit sweeps.
|
||||||
ht.AssertNumPendingSweeps(alice, 1)
|
ht.AssertNumPendingSweeps(alice, 2)
|
||||||
ht.AssertNumPendingSweeps(bob, 1)
|
ht.AssertNumPendingSweeps(bob, 1)
|
||||||
|
|
||||||
// Mine a block to trigger the sweeps.
|
// Mine a block to trigger the sweeps.
|
||||||
@ -2472,7 +2470,6 @@ func runExtraPreimageFromRemoteCommit(ht *lntest.HarnessTest,
|
|||||||
if ht.IsNeutrinoBackend() {
|
if ht.IsNeutrinoBackend() {
|
||||||
// Mine a block to confirm Carol's 2nd level success tx.
|
// Mine a block to confirm Carol's 2nd level success tx.
|
||||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||||
numTxesMempool--
|
|
||||||
numBlocks--
|
numBlocks--
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2503,6 +2500,15 @@ func runExtraPreimageFromRemoteCommit(ht *lntest.HarnessTest,
|
|||||||
case lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE:
|
case lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For neutrino backend, Carol's second-stage sweep should be offered
|
||||||
|
// to her sweeper.
|
||||||
|
if ht.IsNeutrinoBackend() {
|
||||||
|
ht.AssertNumPendingSweeps(carol, 1)
|
||||||
|
|
||||||
|
// Mine a block to trigger the sweep.
|
||||||
|
ht.MineEmptyBlocks(1)
|
||||||
|
}
|
||||||
|
|
||||||
// Mine a block to clean the mempool.
|
// Mine a block to clean the mempool.
|
||||||
ht.MineBlocksAndAssertNumTxes(1, numTxesMempool)
|
ht.MineBlocksAndAssertNumTxes(1, numTxesMempool)
|
||||||
|
|
||||||
|
@ -874,9 +874,6 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||||||
))
|
))
|
||||||
ht.MineBlocks(numBlocks)
|
ht.MineBlocks(numBlocks)
|
||||||
|
|
||||||
// Bob force closes the channel.
|
|
||||||
// ht.CloseChannelAssertPending(bob, bcChanPoint, true)
|
|
||||||
|
|
||||||
// Before we mine empty blocks to check the RBF behavior, we need to be
|
// Before we mine empty blocks to check the RBF behavior, we need to be
|
||||||
// aware that Bob's incoming HTLC will expire before his outgoing HTLC
|
// aware that Bob's incoming HTLC will expire before his outgoing HTLC
|
||||||
// deadline is reached. This happens because the incoming HTLC is sent
|
// deadline is reached. This happens because the incoming HTLC is sent
|
||||||
@ -944,7 +941,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||||||
// Now the start fee rate is checked, we can calculate the fee rate
|
// Now the start fee rate is checked, we can calculate the fee rate
|
||||||
// delta.
|
// delta.
|
||||||
outgoingFeeRateDelta := (outgoingEndFeeRate - outgoingStartFeeRate) /
|
outgoingFeeRateDelta := (outgoingEndFeeRate - outgoingStartFeeRate) /
|
||||||
chainfee.SatPerKWeight(outgoingHTLCDeadline)
|
chainfee.SatPerKWeight(outgoingHTLCDeadline-1)
|
||||||
|
|
||||||
// outgoingFuncPosition records the position of Bob's fee function used
|
// outgoingFuncPosition records the position of Bob's fee function used
|
||||||
// for his outgoing HTLC sweeping tx.
|
// for his outgoing HTLC sweeping tx.
|
||||||
@ -1083,7 +1080,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||||||
// Now the start fee rate is checked, we can calculate the fee rate
|
// Now the start fee rate is checked, we can calculate the fee rate
|
||||||
// delta.
|
// delta.
|
||||||
incomingFeeRateDelta := (incomingEndFeeRate - incomingStartFeeRate) /
|
incomingFeeRateDelta := (incomingEndFeeRate - incomingStartFeeRate) /
|
||||||
chainfee.SatPerKWeight(incomingHTLCDeadline)
|
chainfee.SatPerKWeight(incomingHTLCDeadline-1)
|
||||||
|
|
||||||
// incomingFuncPosition records the position of Bob's fee function used
|
// incomingFuncPosition records the position of Bob's fee function used
|
||||||
// for his incoming HTLC sweeping tx.
|
// for his incoming HTLC sweeping tx.
|
||||||
@ -1143,7 +1140,10 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||||||
// We now mine enough blocks till we reach the end of the outgoing
|
// We now mine enough blocks till we reach the end of the outgoing
|
||||||
// HTLC's deadline. Along the way, we check the expected fee rates are
|
// HTLC's deadline. Along the way, we check the expected fee rates are
|
||||||
// used for both incoming and outgoing HTLC sweeping txns.
|
// used for both incoming and outgoing HTLC sweeping txns.
|
||||||
blocksLeft := outgoingHTLCDeadline - outgoingFuncPosition
|
//
|
||||||
|
// NOTE: We need to subtract 1 from the deadline as the budget must be
|
||||||
|
// used up before the deadline.
|
||||||
|
blocksLeft := outgoingHTLCDeadline - outgoingFuncPosition - 1
|
||||||
for i := int32(0); i < blocksLeft; i++ {
|
for i := int32(0); i < blocksLeft; i++ {
|
||||||
// Mine an empty block.
|
// Mine an empty block.
|
||||||
ht.MineEmptyBlocks(1)
|
ht.MineEmptyBlocks(1)
|
||||||
@ -1418,7 +1418,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||||||
bobTxWeight := uint64(ht.CalculateTxWeight(bobSweepTx))
|
bobTxWeight := uint64(ht.CalculateTxWeight(bobSweepTx))
|
||||||
bobEndingFeeRate := chainfee.NewSatPerKWeight(bobBudget, bobTxWeight)
|
bobEndingFeeRate := chainfee.NewSatPerKWeight(bobBudget, bobTxWeight)
|
||||||
bobFeeRateDelta := (bobEndingFeeRate - bobStartFeeRate) /
|
bobFeeRateDelta := (bobEndingFeeRate - bobStartFeeRate) /
|
||||||
chainfee.SatPerKWeight(deadlineB)
|
chainfee.SatPerKWeight(deadlineB-1)
|
||||||
|
|
||||||
// Mine an empty block, which should trigger Alice's contractcourt to
|
// Mine an empty block, which should trigger Alice's contractcourt to
|
||||||
// offer her commit output to the sweeper.
|
// offer her commit output to the sweeper.
|
||||||
@ -1550,7 +1550,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||||||
aliceTxWeight := uint64(ht.CalculateTxWeight(aliceSweepTx))
|
aliceTxWeight := uint64(ht.CalculateTxWeight(aliceSweepTx))
|
||||||
aliceEndingFeeRate := sweep.DefaultMaxFeeRate.FeePerKWeight()
|
aliceEndingFeeRate := sweep.DefaultMaxFeeRate.FeePerKWeight()
|
||||||
aliceFeeRateDelta := (aliceEndingFeeRate - aliceStartingFeeRate) /
|
aliceFeeRateDelta := (aliceEndingFeeRate - aliceStartingFeeRate) /
|
||||||
chainfee.SatPerKWeight(deadlineA)
|
chainfee.SatPerKWeight(deadlineA-1)
|
||||||
|
|
||||||
aliceFeeRate := ht.CalculateTxFeeRate(aliceSweepTx)
|
aliceFeeRate := ht.CalculateTxFeeRate(aliceSweepTx)
|
||||||
expectedFeeRateAlice := aliceStartingFeeRate +
|
expectedFeeRateAlice := aliceStartingFeeRate +
|
||||||
|
@ -1216,8 +1216,8 @@ func (t *TxPublisher) createSweepTx(inputs []input.Input, changePkScript []byte,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Created sweep tx %v for %v inputs", sweepTx.TxHash(),
|
log.Debugf("Created sweep tx %v for inputs:\n%v", sweepTx.TxHash(),
|
||||||
len(inputs))
|
inputTypeSummary(inputs))
|
||||||
|
|
||||||
return sweepTx, txFee, nil
|
return sweepTx, txFee, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user