itest+sweep: fix current itest re anchor deadline

This commit is contained in:
yyforyongyu 2024-05-16 23:22:19 +08:00
parent e68c0235c6
commit 4079f61d7e
No known key found for this signature in database
GPG key ID: 9BCD95C4FF296868
4 changed files with 59 additions and 80 deletions

View file

@ -216,34 +216,17 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
// We expect to see Alice's force close tx in the mempool.
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
// broadcast as a result of the force closure. Once mined, we also
// expect Alice's anchor sweeping tx being published.
ht.MineBlocksAndAssertNumTxes(1, 1)
// Assert Alice's anchor sweeping tx is found in the mempool.
aliceSweepTxid := ht.Miner.AssertNumTxsInMempool(1)[0]
// 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: aliceSweepTxid.String(),
Outpoint: aliceAnchor.Outpoint,
AmountSat: uint64(anchorSize),
}
// Assert Alice's has one pending anchor output - because she doesn't
// have incoming HTLCs, her outgoing HTLC won't have a deadline, thus
// she won't use the anchor to perform CPFP.
aliceAnchor := ht.AssertNumPendingSweeps(alice, 1)[0]
require.Equal(ht, aliceAnchor.Outpoint.TxidStr,
waitingClose.Commitments.LocalTxid)
// Now that the commitment has been confirmed, the channel should be
// 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
// anchor sweeping. This block will also confirm Alice's anchor
// sweeping tx as her anchor is used for CPFP due to there are
// time-sensitive HTLCs.
ht.MineBlocksAndAssertNumTxes(1, 1)
// anchor sweeping.
ht.MineEmptyBlocks(1)
// Carol's sweep tx should be in the mempool already, as her output is
// not timelocked.
@ -307,7 +288,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
totalFeeCarol := ht.CalculateTxFee(carolTx)
// 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)
carolReports[op] = &lnrpc.Resolution{
ResolutionType: lnrpc.ResolutionType_ANCHOR,
@ -336,27 +317,8 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
// commit and anchor outputs.
ht.MineBlocksAndAssertNumTxes(1, 1)
// Once Alice's anchor sweeping is mined, she should have no pending
// sweep requests atm.
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)
// Alice should still have the anchor sweeping request.
ht.AssertNumPendingSweeps(alice, 1)
// The following restart checks to ensure that outputs in the
// 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 " +
"limbo")
}
if !anchorRecovered {
return nil
}
if forceClose.RecoveredBalance != anchorSize {
return fmt.Errorf("expected %v to be recovered",
anchorSize)
if forceClose.RecoveredBalance != 0 {
return errors.New("no funds should be recovered")
}
return nil
@ -417,7 +375,11 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
// At this point, the CSV will expire in the next block, meaning that
// 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
// commitment sweep txid.
@ -438,16 +400,27 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
}
// We expect a resolution which spends our commit output.
op = fmt.Sprintf("%v:%v", aliceCommit.Outpoint.TxidStr,
aliceCommit.Outpoint.OutputIndex)
op = fmt.Sprintf("%v:%v", commitSweep.Outpoint.TxidStr,
commitSweep.Outpoint.OutputIndex)
aliceReports[op] = &lnrpc.Resolution{
ResolutionType: lnrpc.ResolutionType_COMMIT,
Outcome: lnrpc.ResolutionOutcome_CLAIMED,
SweepTxid: sweepingTXID.String(),
Outpoint: aliceCommit.Outpoint,
Outpoint: commitSweep.Outpoint,
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
// sweeps, using the simple transaction id ListSweeps output.
ht.AssertSweepFound(alice, sweepingTXID.String(), false, 0)

View file

@ -713,9 +713,11 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
// to be mined to trigger a force close later on.
var blocksMined uint32
// Increase the fee estimate so that the following force close tx will
// be cpfp'ed.
ht.SetFeeEstimate(30000)
// We need to mine a block otherwise `FindOutgoingHTLCDeadline` cannot
// find the incoming HTLC on Bob's ChainArbitrator.
//
// TODO(yy): Investigate and fix it!
ht.MineEmptyBlocks(1)
// Now that all parties have the HTLC locked in, we'll immediately
// force close the Bob -> Carol channel. This should trigger contract
@ -755,7 +757,7 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
ht.MineEmptyBlocks(int(defaultCSV - blocksMined))
blocksMined = defaultCSV
// Assert Bob has the sweep and trigger it..
// Assert Bob has the sweep and trigger it.
ht.AssertNumPendingSweeps(bob, 1)
ht.MineEmptyBlocks(1)
blocksMined++
@ -1523,10 +1525,6 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
ht.AssertNumPendingSweeps(bob, 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
// closed channel. AssertStreamChannelForceClosed() already mined a
// block containing the commitment tx and the commit sweep tx will be
@ -1537,7 +1535,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
blocksMined = defaultCSV
// Alice should now sweep her funds.
ht.AssertNumPendingSweeps(alice, 1)
ht.AssertNumPendingSweeps(alice, 2)
// Mine a block to trigger the sweep.
ht.MineEmptyBlocks(1)
@ -1690,7 +1688,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
ht.MineEmptyBlocks(numBlocks)
// Both Alice and Bob should offer their commit sweeps.
ht.AssertNumPendingSweeps(alice, 1)
ht.AssertNumPendingSweeps(alice, 2)
ht.AssertNumPendingSweeps(bob, 1)
// Mine a block to trigger the sweeps.
@ -2472,7 +2470,6 @@ func runExtraPreimageFromRemoteCommit(ht *lntest.HarnessTest,
if ht.IsNeutrinoBackend() {
// Mine a block to confirm Carol's 2nd level success tx.
ht.MineBlocksAndAssertNumTxes(1, 1)
numTxesMempool--
numBlocks--
}
@ -2503,6 +2500,15 @@ func runExtraPreimageFromRemoteCommit(ht *lntest.HarnessTest,
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.
ht.MineBlocksAndAssertNumTxes(1, numTxesMempool)

View file

@ -874,9 +874,6 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
))
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
// aware that Bob's incoming HTLC will expire before his outgoing HTLC
// 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
// delta.
outgoingFeeRateDelta := (outgoingEndFeeRate - outgoingStartFeeRate) /
chainfee.SatPerKWeight(outgoingHTLCDeadline)
chainfee.SatPerKWeight(outgoingHTLCDeadline-1)
// outgoingFuncPosition records the position of Bob's fee function used
// 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
// delta.
incomingFeeRateDelta := (incomingEndFeeRate - incomingStartFeeRate) /
chainfee.SatPerKWeight(incomingHTLCDeadline)
chainfee.SatPerKWeight(incomingHTLCDeadline-1)
// incomingFuncPosition records the position of Bob's fee function used
// 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
// HTLC's deadline. Along the way, we check the expected fee rates are
// 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++ {
// Mine an empty block.
ht.MineEmptyBlocks(1)
@ -1418,7 +1418,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
bobTxWeight := uint64(ht.CalculateTxWeight(bobSweepTx))
bobEndingFeeRate := chainfee.NewSatPerKWeight(bobBudget, bobTxWeight)
bobFeeRateDelta := (bobEndingFeeRate - bobStartFeeRate) /
chainfee.SatPerKWeight(deadlineB)
chainfee.SatPerKWeight(deadlineB-1)
// Mine an empty block, which should trigger Alice's contractcourt to
// offer her commit output to the sweeper.
@ -1550,7 +1550,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
aliceTxWeight := uint64(ht.CalculateTxWeight(aliceSweepTx))
aliceEndingFeeRate := sweep.DefaultMaxFeeRate.FeePerKWeight()
aliceFeeRateDelta := (aliceEndingFeeRate - aliceStartingFeeRate) /
chainfee.SatPerKWeight(deadlineA)
chainfee.SatPerKWeight(deadlineA-1)
aliceFeeRate := ht.CalculateTxFeeRate(aliceSweepTx)
expectedFeeRateAlice := aliceStartingFeeRate +

View file

@ -1216,8 +1216,8 @@ func (t *TxPublisher) createSweepTx(inputs []input.Input, changePkScript []byte,
}
}
log.Debugf("Created sweep tx %v for %v inputs", sweepTx.TxHash(),
len(inputs))
log.Debugf("Created sweep tx %v for inputs:\n%v", sweepTx.TxHash(),
inputTypeSummary(inputs))
return sweepTx, txFee, nil
}