mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-13 11:09:23 +01:00
Merge pull request #8892 from lightningnetwork/yy-itest-miner
Beat [0/4]: improve itest miner
This commit is contained in:
commit
f27f9f2799
43 changed files with 1274 additions and 1018 deletions
|
@ -750,8 +750,8 @@ func (d *AuthenticatedGossiper) Stop() error {
|
|||
}
|
||||
|
||||
func (d *AuthenticatedGossiper) stop() {
|
||||
log.Info("Authenticated Gossiper is stopping")
|
||||
defer log.Info("Authenticated Gossiper stopped")
|
||||
log.Debug("Authenticated Gossiper is stopping")
|
||||
defer log.Debug("Authenticated Gossiper stopped")
|
||||
|
||||
d.blockEpochs.Cancel()
|
||||
|
||||
|
|
|
@ -116,6 +116,11 @@
|
|||
|
||||
## Tooling and Documentation
|
||||
|
||||
* [`lntest.HarnessTest` no longer exposes `Miner`
|
||||
instance](https://github.com/lightningnetwork/lnd/pull/8892). Instead, it's
|
||||
changed into a private `miner` instance and all mining related assertions are
|
||||
now only accessible via the harness.
|
||||
|
||||
# Contributors (Alphabetical Order)
|
||||
|
||||
* Andras Banki-Horvath
|
||||
|
|
|
@ -149,6 +149,9 @@ func (d *DecayedLog) initBuckets() error {
|
|||
|
||||
// Stop halts the garbage collector and closes boltdb.
|
||||
func (d *DecayedLog) Stop() error {
|
||||
log.Debugf("DecayedLog shutting down...")
|
||||
defer log.Debugf("DecayedLog shutdown complete")
|
||||
|
||||
if !atomic.CompareAndSwapInt32(&d.stopped, 0, 1) {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ func newChanRestoreScenario(ht *lntest.HarnessTest, ct lnrpc.CommitmentType,
|
|||
ht.FundCoinsUnconfirmed(btcutil.SatoshiPerBitcoin, dave)
|
||||
|
||||
// Mine a block to confirm the funds.
|
||||
ht.MineBlocks(1)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 2)
|
||||
|
||||
// For the anchor output case we need two UTXOs for Carol so she can
|
||||
// sweep both the local and remote anchor.
|
||||
|
@ -267,7 +267,7 @@ func testChannelBackupRestoreBasic(ht *lntest.HarnessTest) {
|
|||
// the node from seed, then manually recover
|
||||
// the channel backup.
|
||||
return chanRestoreViaRPC(
|
||||
st, password, mnemonic, multi, oldNode,
|
||||
st, password, mnemonic, multi,
|
||||
)
|
||||
},
|
||||
},
|
||||
|
@ -291,7 +291,7 @@ func testChannelBackupRestoreBasic(ht *lntest.HarnessTest) {
|
|||
// create a new nodeRestorer that will restore
|
||||
// using the on-disk channel.backup.
|
||||
return chanRestoreViaRPC(
|
||||
st, password, mnemonic, multi, oldNode,
|
||||
st, password, mnemonic, multi,
|
||||
)
|
||||
},
|
||||
},
|
||||
|
@ -523,7 +523,7 @@ func runChanRestoreScenarioUnConfirmed(ht *lntest.HarnessTest, useFile bool) {
|
|||
// In our nodeRestorer function, we'll restore the node from seed, then
|
||||
// manually recover the channel backup.
|
||||
restoredNodeFunc := chanRestoreViaRPC(
|
||||
ht, crs.password, crs.mnemonic, multi, dave,
|
||||
ht, crs.password, crs.mnemonic, multi,
|
||||
)
|
||||
|
||||
// Test the scenario.
|
||||
|
@ -624,8 +624,8 @@ func runChanRestoreScenarioCommitTypes(ht *lntest.HarnessTest,
|
|||
|
||||
var fundingShim *lnrpc.FundingShim
|
||||
if ct == lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE {
|
||||
_, minerHeight := ht.Miner.GetBestBlock()
|
||||
thawHeight := uint32(minerHeight + thawHeightDelta)
|
||||
minerHeight := ht.CurrentHeight()
|
||||
thawHeight := minerHeight + thawHeightDelta
|
||||
|
||||
fundingShim, _ = deriveFundingShim(
|
||||
ht, dave, carol, crs.params.Amt, thawHeight, true, ct,
|
||||
|
@ -658,7 +658,7 @@ func runChanRestoreScenarioCommitTypes(ht *lntest.HarnessTest,
|
|||
// Now that we have Dave's backup file, we'll create a new nodeRestorer
|
||||
// that we'll restore using the on-disk channels.backup.
|
||||
restoredNodeFunc := chanRestoreViaRPC(
|
||||
ht, crs.password, crs.mnemonic, multi, dave,
|
||||
ht, crs.password, crs.mnemonic, multi,
|
||||
)
|
||||
|
||||
// Test the scenario.
|
||||
|
@ -687,7 +687,7 @@ func testChannelBackupRestoreLegacy(ht *lntest.HarnessTest) {
|
|||
// In our nodeRestorer function, we'll restore the node from seed, then
|
||||
// manually recover the channel backup.
|
||||
restoredNodeFunc := chanRestoreViaRPC(
|
||||
ht, crs.password, crs.mnemonic, multi, dave,
|
||||
ht, crs.password, crs.mnemonic, multi,
|
||||
)
|
||||
|
||||
// Test the scenario.
|
||||
|
@ -779,11 +779,11 @@ func runChanRestoreScenarioForceClose(ht *lntest.HarnessTest, zeroConf bool) {
|
|||
// Now that we have Dave's backup file, we'll create a new nodeRestorer
|
||||
// that will restore using the on-disk channel.backup.
|
||||
restoredNodeFunc := chanRestoreViaRPC(
|
||||
ht, crs.password, crs.mnemonic, multi, dave,
|
||||
ht, crs.password, crs.mnemonic, multi,
|
||||
)
|
||||
|
||||
// We now wait until both Dave's closing tx.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Now that we're able to make our restored now, we'll shutdown the old
|
||||
// Dave node as we'll be storing it shortly below.
|
||||
|
@ -1272,7 +1272,7 @@ func testDataLossProtection(ht *lntest.HarnessTest) {
|
|||
ht.MineBlocks(1)
|
||||
|
||||
// Dave should sweep his funds.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Mine a block to confirm the sweep, and make sure Dave got his
|
||||
// balance back.
|
||||
|
@ -1388,8 +1388,7 @@ func createLegacyRevocationChannel(ht *lntest.HarnessTest,
|
|||
// instance which will restore the target node from a password+seed, then
|
||||
// trigger a SCB restore using the RPC interface.
|
||||
func chanRestoreViaRPC(ht *lntest.HarnessTest, password []byte,
|
||||
mnemonic []string, multi []byte,
|
||||
oldNode *node.HarnessNode) nodeRestorer {
|
||||
mnemonic []string, multi []byte) nodeRestorer {
|
||||
|
||||
backup := &lnrpc.RestoreChanBackupRequest_MultiChanBackup{
|
||||
MultiChanBackup: multi,
|
||||
|
@ -1428,7 +1427,7 @@ func assertTimeLockSwept(ht *lntest.HarnessTest, carol, dave *node.HarnessNode,
|
|||
|
||||
// Mine a block to trigger the sweeps.
|
||||
ht.MineBlocks(1)
|
||||
ht.Miner.AssertNumTxsInMempool(expectedTxes)
|
||||
ht.AssertNumTxsInMempool(expectedTxes)
|
||||
|
||||
// Carol should consider the channel pending force close (since she is
|
||||
// waiting for her sweep to confirm).
|
||||
|
@ -1462,9 +1461,9 @@ func assertTimeLockSwept(ht *lntest.HarnessTest, carol, dave *node.HarnessNode,
|
|||
|
||||
// Mine a block to trigger the sweeps.
|
||||
ht.MineEmptyBlocks(1)
|
||||
daveSweep := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
daveSweep := ht.AssertNumTxsInMempool(1)[0]
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, daveSweep)
|
||||
ht.AssertTxInBlock(block, daveSweep)
|
||||
|
||||
// Now the channel should be fully closed also from Dave's POV.
|
||||
ht.AssertNumPendingForceClose(dave, 0)
|
||||
|
@ -1510,7 +1509,7 @@ func assertDLPExecuted(ht *lntest.HarnessTest,
|
|||
|
||||
// Upon reconnection, the nodes should detect that Dave is out of sync.
|
||||
// Carol should force close the channel using her latest commitment.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Channel should be in the state "waiting close" for Carol since she
|
||||
// broadcasted the force close tx.
|
||||
|
|
|
@ -160,7 +160,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
|
||||
// Fetch starting height of this test so we can compute the block
|
||||
// heights we expect certain events to take place.
|
||||
_, curHeight := ht.Miner.GetBestBlock()
|
||||
curHeight := int32(ht.CurrentHeight())
|
||||
|
||||
// Using the current height of the chain, derive the relevant heights
|
||||
// for incubating two-stage htlcs.
|
||||
|
@ -214,7 +214,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
ht.AssertNumUTXOs(alice, expectedUtxos)
|
||||
|
||||
// We expect to see Alice's force close tx in the mempool.
|
||||
ht.Miner.GetNumTxsFromMempool(1)
|
||||
ht.GetNumTxsFromMempool(1)
|
||||
|
||||
// Mine a block which should confirm the commitment transaction
|
||||
// broadcast as a result of the force closure. Once mined, we also
|
||||
|
@ -278,7 +278,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
|
||||
// Carol's sweep tx should be in the mempool already, as her output is
|
||||
// not timelocked.
|
||||
carolTx := ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
carolTx := ht.GetNumTxsFromMempool(1)[0]
|
||||
|
||||
// Carol's sweeping tx should have 2-input-1-output shape.
|
||||
require.Len(ht, carolTx.TxIn, 2)
|
||||
|
@ -389,11 +389,11 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
// So we fetch the node's mempool to ensure it has been properly
|
||||
// broadcast.
|
||||
ht.MineEmptyBlocks(1)
|
||||
sweepingTXID := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
sweepingTXID := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Fetch the sweep transaction, all input it's spending should be from
|
||||
// the commitment transaction which was broadcast on-chain.
|
||||
sweepTx := ht.Miner.GetRawTransaction(sweepingTXID)
|
||||
sweepTx := ht.GetRawTransaction(sweepingTXID)
|
||||
for _, txIn := range sweepTx.MsgTx().TxIn {
|
||||
require.Equal(ht, &txIn.PreviousOutPoint.Hash, closingTxID,
|
||||
"sweep transaction not spending from commit")
|
||||
|
@ -431,7 +431,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Update current height
|
||||
_, curHeight = ht.Miner.GetBestBlock()
|
||||
curHeight = int32(ht.CurrentHeight())
|
||||
|
||||
// checkForceClosedChannelNumHtlcs verifies that a force closed channel
|
||||
// has the proper number of htlcs.
|
||||
|
@ -485,7 +485,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
// number of blocks we have generated since adding it to the nursery,
|
||||
// and take an additional block off so that we end up one block shy of
|
||||
// the expiry height, and add the block padding.
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
currentHeight := int32(ht.CurrentHeight())
|
||||
cltvHeightDelta := int(htlcExpiryHeight - uint32(currentHeight) - 1)
|
||||
|
||||
// Advance the blockchain until just before the CLTV expires, nothing
|
||||
|
@ -547,7 +547,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
// NOTE: after restart, all the htlc timeout txns will be offered to
|
||||
// the sweeper with `Immediate` set to true, so they won't be
|
||||
// aggregated.
|
||||
htlcTxIDs := ht.Miner.AssertNumTxsInMempool(numInvoices)
|
||||
htlcTxIDs := ht.AssertNumTxsInMempool(numInvoices)
|
||||
|
||||
// Retrieve each htlc timeout txn from the mempool, and ensure it is
|
||||
// well-formed. This entails verifying that each only spends from
|
||||
|
@ -567,7 +567,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
// on-chain. In case of an anchor type channel, we expect one
|
||||
// extra input that is not spending from the commitment, that
|
||||
// is added for fees.
|
||||
htlcTx := ht.Miner.GetRawTransaction(htlcTxID)
|
||||
htlcTx := ht.GetRawTransaction(htlcTxID)
|
||||
|
||||
// Ensure the htlc transaction has the expected number of
|
||||
// inputs.
|
||||
|
@ -662,7 +662,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
|
||||
// Advance the chain until just before the 2nd-layer CSV delays expire.
|
||||
// For anchor channels this is one block earlier.
|
||||
_, currentHeight = ht.Miner.GetBestBlock()
|
||||
currentHeight = int32(ht.CurrentHeight())
|
||||
ht.Logf("current height: %v, htlcCsvMaturityHeight=%v", currentHeight,
|
||||
htlcCsvMaturityHeight)
|
||||
numBlocks := int(htlcCsvMaturityHeight - uint32(currentHeight) - 2)
|
||||
|
@ -709,7 +709,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
// NOTE: we don't check `len(mempool) == 1` because it will
|
||||
// give us false positive.
|
||||
err := wait.NoError(func() error {
|
||||
mempool := ht.Miner.GetRawMempool()
|
||||
mempool := ht.Miner().GetRawMempool()
|
||||
if len(mempool) == 2 {
|
||||
return nil
|
||||
}
|
||||
|
@ -733,10 +733,10 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
}
|
||||
|
||||
// Wait for the single sweep txn to appear in the mempool.
|
||||
htlcSweepTxID := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
htlcSweepTxID := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Fetch the htlc sweep transaction from the mempool.
|
||||
htlcSweepTx := ht.Miner.GetRawTransaction(htlcSweepTxID)
|
||||
htlcSweepTx := ht.GetRawTransaction(htlcSweepTxID)
|
||||
|
||||
// Ensure the htlc sweep transaction only has one input for each htlc
|
||||
// Alice extended before force closing.
|
||||
|
@ -818,7 +818,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest,
|
|||
// Generate the final block that sweeps all htlc funds into the user's
|
||||
// wallet, and make sure the sweep is in this block.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, htlcSweepTxID)
|
||||
ht.AssertTxInBlock(block, htlcSweepTxID)
|
||||
|
||||
// Now that the channel has been fully swept, it should no longer show
|
||||
// up within the pending channels RPC.
|
||||
|
@ -935,7 +935,7 @@ func testFailingChannel(ht *lntest.HarnessTest) {
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// Carol should have broadcast her sweeping tx.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Mine two blocks to confirm Carol's sweeping tx, which will by now
|
||||
// Alice's commit output should be offered to her sweeper.
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type chanFundMaxTestCase struct {
|
||||
|
@ -317,8 +316,7 @@ func fundingFee(numInput int, change bool) btcutil.Amount {
|
|||
// sweepNodeWalletAndAssert sweeps funds from a node wallet.
|
||||
func sweepNodeWalletAndAssert(ht *lntest.HarnessTest, node *node.HarnessNode) {
|
||||
// New miner address we will sweep all funds to.
|
||||
minerAddr, err := ht.Miner.NewAddress()
|
||||
require.NoError(ht, err)
|
||||
minerAddr := ht.NewMinerAddress()
|
||||
|
||||
// Send all funds back to the miner node.
|
||||
node.RPC.SendCoins(&lnrpc.SendCoinsRequest{
|
||||
|
|
|
@ -316,7 +316,7 @@ func testGraphTopologyNtfns(ht *lntest.HarnessTest, pinned bool) {
|
|||
ht.AssertNumNodeAnns(alice, alice.PubKeyStr, 1)
|
||||
ht.AssertNumNodeAnns(alice, bob.PubKeyStr, 1)
|
||||
|
||||
_, blockHeight := ht.Miner.GetBestBlock()
|
||||
blockHeight := ht.CurrentHeight()
|
||||
|
||||
// Now we'll test that updates are properly sent after channels are
|
||||
// closed within the network.
|
||||
|
@ -326,7 +326,7 @@ func testGraphTopologyNtfns(ht *lntest.HarnessTest, pinned bool) {
|
|||
// notification indicating so.
|
||||
closedChan := ht.AssertTopologyChannelClosed(alice, chanPoint)
|
||||
|
||||
require.Equal(ht, uint32(blockHeight+1), closedChan.ClosedHeight,
|
||||
require.Equal(ht, blockHeight+1, closedChan.ClosedHeight,
|
||||
"close heights of channel mismatch")
|
||||
|
||||
fundingTxid := ht.OutPointFromChannelPoint(chanPoint)
|
||||
|
|
|
@ -117,7 +117,7 @@ func coopCloseWithHTLCs(ht *lntest.HarnessTest) {
|
|||
)
|
||||
|
||||
// Wait for the close tx to be in the Mempool.
|
||||
ht.Miner.AssertTxInMempool(&closeTxid)
|
||||
ht.AssertTxInMempool(&closeTxid)
|
||||
|
||||
// Wait for it to get mined and finish tearing down.
|
||||
ht.AssertStreamChannelCoopClosed(alice, chanPoint, false, closeClient)
|
||||
|
|
|
@ -359,6 +359,8 @@ func testEstimateRouteFee(ht *lntest.HarnessTest) {
|
|||
|
||||
mts.ht.CloseChannelAssertPending(mts.bob, channelPointBobPaula, false)
|
||||
mts.ht.CloseChannelAssertPending(mts.eve, channelPointEvePaula, false)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 2)
|
||||
|
||||
mts.closeChannels()
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/chainreg"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/funding"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
|
@ -292,6 +291,24 @@ func testUnconfirmedChannelFunding(ht *lntest.HarnessTest) {
|
|||
// We'll send her some unconfirmed funds.
|
||||
ht.FundCoinsUnconfirmed(2*chanAmt, carol)
|
||||
|
||||
// For neutrino backend, we will confirm the coins sent above and let
|
||||
// Carol send all her funds to herself to create unconfirmed output.
|
||||
if ht.IsNeutrinoBackend() {
|
||||
// Confirm the above coins.
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Create a new address and send to herself.
|
||||
resp := carol.RPC.NewAddress(&lnrpc.NewAddressRequest{
|
||||
Type: lnrpc.AddressType_TAPROOT_PUBKEY,
|
||||
})
|
||||
|
||||
// Once sent, Carol would have one unconfirmed UTXO.
|
||||
carol.RPC.SendCoins(&lnrpc.SendCoinsRequest{
|
||||
Addr: resp.Address,
|
||||
SendAll: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Now, we'll connect her to Alice so that they can open a channel
|
||||
// together. The funding flow should select Carol's unconfirmed output
|
||||
// as she doesn't have any other funds since it's a new node.
|
||||
|
@ -362,11 +379,7 @@ func testUnconfirmedChannelFunding(ht *lntest.HarnessTest) {
|
|||
// parties. For neutrino backend, the funding transaction should be
|
||||
// mined. Otherwise, two transactions should be mined, the unconfirmed
|
||||
// spend and the funding tx.
|
||||
if ht.IsNeutrinoBackend() {
|
||||
ht.MineBlocksAndAssertNumTxes(6, 1)
|
||||
} else {
|
||||
ht.MineBlocksAndAssertNumTxes(6, 2)
|
||||
}
|
||||
ht.MineBlocksAndAssertNumTxes(6, 2)
|
||||
|
||||
chanPoint := ht.WaitForChannelOpenEvent(chanOpenUpdate)
|
||||
|
||||
|
@ -859,10 +872,10 @@ func testChannelFundingPersistence(ht *lntest.HarnessTest) {
|
|||
// channel has been opened. The funding transaction should be found
|
||||
// within the newly mined block.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, fundingTxID)
|
||||
ht.AssertTxInBlock(block, fundingTxID)
|
||||
|
||||
// Get the height that our transaction confirmed at.
|
||||
_, height := ht.Miner.GetBestBlock()
|
||||
height := int32(ht.CurrentHeight())
|
||||
|
||||
// Restart both nodes to test that the appropriate state has been
|
||||
// persisted and that both nodes recover gracefully.
|
||||
|
@ -1047,13 +1060,13 @@ func testBatchChanFunding(ht *lntest.HarnessTest) {
|
|||
|
||||
// Mine the batch transaction and check the network topology.
|
||||
block := ht.MineBlocksAndAssertNumTxes(6, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, txHash)
|
||||
ht.AssertTxInBlock(block, txHash)
|
||||
ht.AssertTopologyChannelOpen(alice, chanPoint1)
|
||||
ht.AssertTopologyChannelOpen(alice, chanPoint2)
|
||||
ht.AssertTopologyChannelOpen(alice, chanPoint3)
|
||||
|
||||
// Check if the change type from the batch_open_channel funding is P2TR.
|
||||
rawTx := ht.Miner.GetRawTransaction(txHash)
|
||||
rawTx := ht.GetRawTransaction(txHash)
|
||||
require.Len(ht, rawTx.MsgTx().TxOut, 5)
|
||||
|
||||
// For calculating the change output index we use the formula for the
|
||||
|
@ -1182,9 +1195,9 @@ func deriveFundingShim(ht *lntest.HarnessTest, carol, dave *node.HarnessNode,
|
|||
var txid *chainhash.Hash
|
||||
targetOutputs := []*wire.TxOut{fundingOutput}
|
||||
if publish {
|
||||
txid = ht.Miner.SendOutputsWithoutChange(targetOutputs, 5)
|
||||
txid = ht.SendOutputsWithoutChange(targetOutputs, 5)
|
||||
} else {
|
||||
tx := ht.Miner.CreateTransaction(targetOutputs, 5)
|
||||
tx := ht.CreateTransaction(targetOutputs, 5)
|
||||
|
||||
txHash := tx.TxHash()
|
||||
txid = &txHash
|
||||
|
@ -1341,22 +1354,22 @@ func testChannelFundingWithUnstableUtxos(ht *lntest.HarnessTest) {
|
|||
// that by dave force-closing the channel. Which let's carol sweep its
|
||||
// to_remote output which is not encumbered by any relative locktime.
|
||||
ht.CloseChannelAssertPending(dave, chanPoint2, true)
|
||||
|
||||
// Mine the force close commitment transaction.
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Make sure Carol sees her to_remote output from the force close tx.
|
||||
ht.AssertNumPendingSweeps(carol, 1)
|
||||
|
||||
// Mine one block to trigger the sweep transaction.
|
||||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// We need to wait for carol initiating the sweep of the to_remote
|
||||
// output of chanPoint2.
|
||||
utxos := ht.AssertNumUTXOsUnconfirmed(carol, 1)
|
||||
utxo := ht.AssertNumUTXOsUnconfirmed(carol, 1)[0]
|
||||
|
||||
// We filter for the unconfirmed utxo and try to open a channel with
|
||||
// that utxo.
|
||||
utxoOpt := fn.Find(func(u *lnrpc.Utxo) bool {
|
||||
return u.Confirmations == 0
|
||||
}, utxos)
|
||||
fundingUtxo := utxoOpt.UnwrapOrFail(ht.T)
|
||||
// We now try to open channel using the unconfirmed utxo.
|
||||
fundingUtxo := utxo
|
||||
|
||||
// Now try to open the channel with this utxo and expect an error.
|
||||
expectedErr := fmt.Errorf("outpoint already spent or "+
|
||||
|
@ -1405,6 +1418,9 @@ func testChannelFundingWithUnstableUtxos(ht *lntest.HarnessTest) {
|
|||
ht.CloseChannelAssertPending(dave, chanPoint3, true)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Make sure Carol sees her to_remote output from the force close tx.
|
||||
ht.AssertNumPendingSweeps(carol, 1)
|
||||
|
||||
// Mine one block to trigger the sweep transaction.
|
||||
ht.MineEmptyBlocks(1)
|
||||
|
||||
|
|
|
@ -59,14 +59,14 @@ func testHoldInvoiceForceClose(ht *lntest.HarnessTest) {
|
|||
require.Len(ht, channel.PendingHtlcs, 1)
|
||||
activeHtlc := channel.PendingHtlcs[0]
|
||||
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
currentHeight := ht.CurrentHeight()
|
||||
|
||||
// Now we will mine blocks until the htlc expires, and wait for each
|
||||
// node to sync to our latest height. Sanity check that we won't
|
||||
// underflow.
|
||||
require.Greater(ht, activeHtlc.ExpirationHeight, uint32(currentHeight),
|
||||
require.Greater(ht, activeHtlc.ExpirationHeight, currentHeight,
|
||||
"expected expiry after current height")
|
||||
blocksTillExpiry := activeHtlc.ExpirationHeight - uint32(currentHeight)
|
||||
blocksTillExpiry := activeHtlc.ExpirationHeight - currentHeight
|
||||
|
||||
// Alice will go to chain with some delta, sanity check that we won't
|
||||
// underflow and subtract this from our mined blocks.
|
||||
|
@ -93,7 +93,7 @@ func testHoldInvoiceForceClose(ht *lntest.HarnessTest) {
|
|||
// TODO(yy): fix block height asymmetry among all the subsystems.
|
||||
//
|
||||
// We first mine enough blocks to trigger an invoice cancelation.
|
||||
ht.MineBlocks(blocksTillCancel)
|
||||
ht.MineBlocks(int(blocksTillCancel))
|
||||
|
||||
// Wait for the nodes to be synced.
|
||||
ht.WaitForBlockchainSync(alice)
|
||||
|
@ -133,7 +133,7 @@ func testHoldInvoiceForceClose(ht *lntest.HarnessTest) {
|
|||
// happen in bitcoind backend, as Alice's CNCT was syncing way faster
|
||||
// than Bob's INVC, causing the channel being force closed before the
|
||||
// invoice cancelation message was received by Alice.
|
||||
ht.MineBlocks(blocksTillForce - blocksTillCancel)
|
||||
ht.MineBlocks(int(blocksTillForce - blocksTillCancel))
|
||||
|
||||
// Wait for the nodes to be synced.
|
||||
ht.WaitForBlockchainSync(alice)
|
||||
|
|
|
@ -416,7 +416,7 @@ func testMaxPendingChannels(ht *lntest.HarnessTest) {
|
|||
|
||||
// Ensure that the funding transaction enters a block, and is
|
||||
// properly advertised by Alice.
|
||||
ht.Miner.AssertTxInBlock(block, fundingTxID)
|
||||
ht.AssertTxInBlock(block, fundingTxID)
|
||||
ht.AssertTopologyChannelOpen(alice, fundingChanPoint)
|
||||
|
||||
// The channel should be listed in the peer information
|
||||
|
@ -823,14 +823,14 @@ func testSweepAllCoins(ht *lntest.HarnessTest) {
|
|||
// Send coins to a compatible address without specifying fee rate or
|
||||
// conf target.
|
||||
// ainz.RPC.SendCoinsAssertErr(&lnrpc.SendCoinsRequest{
|
||||
// Addr: ht.Miner.NewMinerAddress().String(),
|
||||
// Addr: ht.NewMinerAddress().String(),
|
||||
// SendAll: true,
|
||||
// Label: sendCoinsLabel,
|
||||
// })
|
||||
|
||||
// Send coins to a compatible address.
|
||||
ainz.RPC.SendCoins(&lnrpc.SendCoinsRequest{
|
||||
Addr: ht.Miner.NewMinerAddress().String(),
|
||||
Addr: ht.NewMinerAddress().String(),
|
||||
SendAll: true,
|
||||
Label: sendCoinsLabel,
|
||||
TargetConf: 6,
|
||||
|
@ -930,7 +930,7 @@ func testSweepAllCoins(ht *lntest.HarnessTest) {
|
|||
// If we try again, but this time specifying an amount, then the call
|
||||
// should fail.
|
||||
ainz.RPC.SendCoinsAssertErr(&lnrpc.SendCoinsRequest{
|
||||
Addr: ht.Miner.NewMinerAddress().String(),
|
||||
Addr: ht.NewMinerAddress().String(),
|
||||
Amount: 10000,
|
||||
SendAll: true,
|
||||
Label: sendCoinsLabel,
|
||||
|
|
|
@ -208,7 +208,8 @@ func newMppTestScenario(ht *lntest.HarnessTest) *mppTestScenario {
|
|||
ht.FundCoinsUnconfirmed(btcutil.SatoshiPerBitcoin, carol)
|
||||
ht.FundCoinsUnconfirmed(btcutil.SatoshiPerBitcoin, dave)
|
||||
ht.FundCoinsUnconfirmed(btcutil.SatoshiPerBitcoin, eve)
|
||||
ht.MineBlocks(1)
|
||||
|
||||
ht.MineBlocksAndAssertNumTxes(1, 3)
|
||||
}
|
||||
|
||||
mts := &mppTestScenario{
|
||||
|
@ -318,7 +319,7 @@ func (m *mppTestScenario) closeChannels() {
|
|||
m.ht.CloseChannelAssertPending(m.eve, m.channelPoints[5], false)
|
||||
|
||||
// Now mine a block to include all the closing transactions.
|
||||
m.ht.MineBlocks(1)
|
||||
m.ht.MineBlocksAndAssertNumTxes(1, 6)
|
||||
|
||||
// Assert that the channels are closed.
|
||||
for _, hn := range m.nodes {
|
||||
|
|
|
@ -243,12 +243,12 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
|
|||
numBlocks := padCLTV(
|
||||
uint32(finalCltvDelta - lncfg.DefaultOutgoingBroadcastDelta),
|
||||
)
|
||||
ht.MineBlocks(numBlocks)
|
||||
ht.MineBlocks(int(numBlocks))
|
||||
|
||||
// Bob's force close transaction should now be found in the mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
op := ht.OutPointFromChannelPoint(bobChanPoint)
|
||||
closeTx := ht.Miner.AssertOutpointInMempool(op)
|
||||
closeTx := ht.AssertOutpointInMempool(op)
|
||||
|
||||
// Bob's anchor output should be offered to his sweep since Bob has
|
||||
// time-sensitive HTLCs - we expect both anchors are offered.
|
||||
|
@ -276,11 +276,11 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
|
|||
// 1. Bob's sweeping tx anchor sweep should now be found in the mempool.
|
||||
// 2. Bob's HTLC timeout tx sweep should now be found in the mempool.
|
||||
// Carol's anchor sweep should be failed due to output being dust.
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
htlcOutpoint := wire.OutPoint{Hash: closeTx.TxHash(), Index: 2}
|
||||
commitOutpoint := wire.OutPoint{Hash: closeTx.TxHash(), Index: 3}
|
||||
htlcTimeoutTxid := ht.Miner.AssertOutpointInMempool(
|
||||
htlcTimeoutTxid := ht.AssertOutpointInMempool(
|
||||
htlcOutpoint,
|
||||
).TxHash()
|
||||
|
||||
|
@ -330,7 +330,7 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
|
|||
ht.AssertNumPendingSweeps(bob, 2)
|
||||
|
||||
// Assert that the HTLC timeout tx is now in the mempool.
|
||||
ht.Miner.AssertOutpointInMempool(htlcTimeoutOutpoint)
|
||||
ht.AssertOutpointInMempool(htlcTimeoutOutpoint)
|
||||
|
||||
// We now wait for 30 seconds to overcome the flake - there's a
|
||||
// block race between contractcourt and sweeper, causing the
|
||||
|
@ -339,7 +339,7 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
|
|||
// TODO(yy): remove this once `blockbeat` is in place.
|
||||
numExpected := 1
|
||||
err := wait.NoError(func() error {
|
||||
mem := ht.Miner.GetRawMempool()
|
||||
mem := ht.GetRawMempool()
|
||||
if len(mem) == 2 {
|
||||
numExpected = 2
|
||||
return nil
|
||||
|
@ -363,7 +363,7 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
|
|||
pendingChanResp := bob.RPC.PendingChannels()
|
||||
if len(pendingChanResp.PendingForceClosingChannels) != 0 {
|
||||
// Check that the sweep spends the expected inputs.
|
||||
ht.Miner.AssertOutpointInMempool(commitOutpoint)
|
||||
ht.AssertOutpointInMempool(commitOutpoint)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
}
|
||||
} else {
|
||||
|
@ -381,14 +381,14 @@ func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// Check that the sweep spends from the mined commitment.
|
||||
ht.Miner.AssertOutpointInMempool(commitOutpoint)
|
||||
ht.AssertOutpointInMempool(commitOutpoint)
|
||||
|
||||
// Mine one more block to trigger the timeout path.
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Bob's sweeper should now broadcast his second layer sweep
|
||||
// due to the CSV on the HTLC timeout output.
|
||||
ht.Miner.AssertOutpointInMempool(htlcTimeoutOutpoint)
|
||||
ht.AssertOutpointInMempool(htlcTimeoutOutpoint)
|
||||
|
||||
// Next, we'll mine a final block that should confirm the
|
||||
// sweeping transactions left.
|
||||
|
@ -501,9 +501,9 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
|
|||
|
||||
// At this point, Carol should broadcast her active commitment
|
||||
// transaction in order to go to the chain and sweep her HTLC.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
closingTx := ht.Miner.AssertOutpointInMempool(
|
||||
closingTx := ht.AssertOutpointInMempool(
|
||||
ht.OutPointFromChannelPoint(bobChanPoint),
|
||||
)
|
||||
closingTxid := closingTx.TxHash()
|
||||
|
@ -526,7 +526,7 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
|
|||
// scenarios, as we are using a wallet utxo, which means any txns using
|
||||
// that wallet utxo must pay more fees. On the other hand, there's no
|
||||
// way to remove that anchor-CPFP tx from the mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// After the force close transaction is mined, Carol should offer her
|
||||
// second level HTLC tx to the sweeper, which means we should see two
|
||||
|
@ -572,7 +572,7 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// All transactions should be spending from the commitment transaction.
|
||||
txes := ht.Miner.GetNumTxsFromMempool(expectedTxes)
|
||||
txes := ht.GetNumTxsFromMempool(expectedTxes)
|
||||
ht.AssertAllTxesSpendFrom(txes, closingTxid)
|
||||
|
||||
// We'll now mine an additional block which should confirm both the
|
||||
|
@ -600,7 +600,7 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// We should have a new transaction in the mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Finally, if we mine an additional block to confirm Carol's second
|
||||
// level success transaction. Carol should not show a pending channel
|
||||
|
@ -644,7 +644,7 @@ func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
commitOutpoint := wire.OutPoint{Hash: closingTxid, Index: 3}
|
||||
ht.Miner.AssertOutpointInMempool(commitOutpoint)
|
||||
ht.AssertOutpointInMempool(commitOutpoint)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
}
|
||||
|
||||
|
@ -756,12 +756,12 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(1)
|
||||
blocksMined++
|
||||
|
||||
commitSweepTx := ht.Miner.AssertOutpointInMempool(
|
||||
commitSweepTx := ht.AssertOutpointInMempool(
|
||||
bobCommitOutpoint,
|
||||
)
|
||||
txid := commitSweepTx.TxHash()
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &txid)
|
||||
ht.AssertTxInBlock(block, &txid)
|
||||
|
||||
blocksMined++
|
||||
}
|
||||
|
@ -784,12 +784,12 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
|
|||
|
||||
// We should also now find a transaction in the mempool, as Bob should
|
||||
// have broadcast his second layer timeout transaction.
|
||||
timeoutTx := ht.Miner.AssertOutpointInMempool(htlcOutpoint).TxHash()
|
||||
timeoutTx := ht.AssertOutpointInMempool(htlcOutpoint).TxHash()
|
||||
|
||||
// Next, we'll mine an additional block. This should serve to confirm
|
||||
// the second layer timeout transaction.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &timeoutTx)
|
||||
ht.AssertTxInBlock(block, &timeoutTx)
|
||||
|
||||
// With the second layer timeout transaction confirmed, Bob should have
|
||||
// canceled backwards the HTLC that carol sent.
|
||||
|
@ -837,7 +837,7 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
|
|||
|
||||
// Assert the sweeping tx is found in the mempool.
|
||||
htlcTimeoutOutpoint := wire.OutPoint{Hash: timeoutTx, Index: 0}
|
||||
ht.Miner.AssertOutpointInMempool(htlcTimeoutOutpoint)
|
||||
ht.AssertOutpointInMempool(htlcTimeoutOutpoint)
|
||||
|
||||
// Mine a block to confirm the sweep.
|
||||
ht.MineBlocksAndAssertNumTxes(1, numExpected)
|
||||
|
@ -1007,12 +1007,12 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
|
|||
|
||||
// Bob's sweeping transaction should now be found in the mempool at
|
||||
// this point.
|
||||
sweepTx := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
sweepTx := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// If we mine an additional block, then this should confirm Bob's
|
||||
// transaction which sweeps the direct HTLC output.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, sweepTx)
|
||||
ht.AssertTxInBlock(block, sweepTx)
|
||||
|
||||
// Now that the sweeping transaction has been confirmed, Bob should
|
||||
// cancel back that HTLC. As a result, Alice should not know of any
|
||||
|
@ -1042,12 +1042,12 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
bobCommitOutpoint := wire.OutPoint{Hash: *closeTx, Index: 3}
|
||||
bobCommitSweep := ht.Miner.AssertOutpointInMempool(
|
||||
bobCommitSweep := ht.AssertOutpointInMempool(
|
||||
bobCommitOutpoint,
|
||||
)
|
||||
bobCommitSweepTxid := bobCommitSweep.TxHash()
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &bobCommitSweepTxid)
|
||||
ht.AssertTxInBlock(block, &bobCommitSweepTxid)
|
||||
}
|
||||
ht.AssertNumPendingForceClose(bob, 0)
|
||||
|
||||
|
@ -1191,7 +1191,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
|
|||
blocksMined++
|
||||
|
||||
// Assert the expected num of txns are found in the mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(expectedTxes)
|
||||
ht.AssertNumTxsInMempool(expectedTxes)
|
||||
|
||||
// Mine a block to clean up the mempool for the rest of the test.
|
||||
ht.MineBlocksAndAssertNumTxes(1, expectedTxes)
|
||||
|
@ -1215,18 +1215,18 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(int(numBlocks - blocksMined))
|
||||
|
||||
// Carol's commitment transaction should now be in the mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Look up the closing transaction. It should be spending from the
|
||||
// funding transaction,
|
||||
closingTx := ht.Miner.AssertOutpointInMempool(
|
||||
closingTx := ht.AssertOutpointInMempool(
|
||||
ht.OutPointFromChannelPoint(bobChanPoint),
|
||||
)
|
||||
closingTxid := closingTx.TxHash()
|
||||
|
||||
// Mine a block that should confirm the commit tx.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &closingTxid)
|
||||
ht.AssertTxInBlock(block, &closingTxid)
|
||||
|
||||
// After the force close transaction is mined, Carol should offer her
|
||||
// second-level success HTLC tx and anchor to the sweeper.
|
||||
|
@ -1273,7 +1273,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// Assert transactions can be found in the mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(expectedTxes)
|
||||
ht.AssertNumTxsInMempool(expectedTxes)
|
||||
|
||||
// At this point we suspend Alice to make sure she'll handle the
|
||||
// on-chain settle after a restart.
|
||||
|
@ -1300,7 +1300,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
|
|||
carolSecondLevelCSV--
|
||||
|
||||
// Check Bob's second level tx.
|
||||
bobSecondLvlTx := ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
bobSecondLvlTx := ht.GetNumTxsFromMempool(1)[0]
|
||||
|
||||
// It should spend from the commitment in the channel with Alice.
|
||||
ht.AssertTxSpendFrom(bobSecondLvlTx, *bobForceClose)
|
||||
|
@ -1345,7 +1345,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
|
|||
bobSecondLevelCSV--
|
||||
|
||||
// Carol's sweep tx should be broadcast.
|
||||
carolSweep := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
carolSweep := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Bob should offer his second level tx to his sweeper.
|
||||
ht.AssertNumPendingSweeps(bob, 1)
|
||||
|
@ -1353,16 +1353,16 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
|
|||
// Mining one additional block, Bob's second level tx is mature, and he
|
||||
// can sweep the output.
|
||||
block = ht.MineBlocksAndAssertNumTxes(bobSecondLevelCSV, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, carolSweep)
|
||||
ht.AssertTxInBlock(block, carolSweep)
|
||||
|
||||
bobSweep := ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
bobSweep := ht.GetNumTxsFromMempool(1)[0]
|
||||
bobSweepTxid := bobSweep.TxHash()
|
||||
|
||||
// When we mine one additional block, that will confirm Bob's sweep.
|
||||
// Now Bob should have no pending channels anymore, as this just
|
||||
// resolved it by the confirmation of the sweep transaction.
|
||||
block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &bobSweepTxid)
|
||||
ht.AssertTxInBlock(block, &bobSweepTxid)
|
||||
|
||||
// With the script-enforced lease commitment type, Alice and Bob still
|
||||
// haven't been able to sweep their respective commit outputs due to the
|
||||
|
@ -1399,11 +1399,11 @@ func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest,
|
|||
aliceCommitOutpoint := wire.OutPoint{
|
||||
Hash: *bobForceClose, Index: 3,
|
||||
}
|
||||
ht.Miner.AssertOutpointInMempool(
|
||||
ht.AssertOutpointInMempool(
|
||||
aliceCommitOutpoint,
|
||||
).TxHash()
|
||||
bobCommitOutpoint := wire.OutPoint{Hash: closingTxid, Index: 3}
|
||||
ht.Miner.AssertOutpointInMempool(
|
||||
ht.AssertOutpointInMempool(
|
||||
bobCommitOutpoint,
|
||||
).TxHash()
|
||||
|
||||
|
@ -1558,11 +1558,11 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(int(numBlocks) - blocksMined)
|
||||
|
||||
// Carol's commitment transaction should now be in the mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// The closing transaction should be spending from the funding
|
||||
// transaction.
|
||||
closingTx := ht.Miner.AssertOutpointInMempool(
|
||||
closingTx := ht.AssertOutpointInMempool(
|
||||
ht.OutPointFromChannelPoint(bobChanPoint),
|
||||
)
|
||||
closingTxid := closingTx.TxHash()
|
||||
|
@ -1574,7 +1574,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||
|
||||
// Mine a block, which should contain: the commitment.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &closingTxid)
|
||||
ht.AssertTxInBlock(block, &closingTxid)
|
||||
|
||||
// After the force close transaction is mined, Carol should offer her
|
||||
// second level HTLC tx to the sweeper, along with her anchor output.
|
||||
|
@ -1612,7 +1612,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||
// anchor sweeping.
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
carolSecondLevelCSV--
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
// Mine a block to confirm the expected transactions.
|
||||
ht.MineBlocksAndAssertNumTxes(1, 2)
|
||||
|
@ -1624,7 +1624,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||
// NOTE: after Bob is restarted, the sweeping of the direct preimage
|
||||
// spent will happen immediately so we don't need to mine a block to
|
||||
// trigger Bob's sweeper to sweep it.
|
||||
bobHtlcSweep := ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
bobHtlcSweep := ht.GetNumTxsFromMempool(1)[0]
|
||||
bobHtlcSweepTxid := bobHtlcSweep.TxHash()
|
||||
|
||||
// It should spend from the commitment in the channel with Alice.
|
||||
|
@ -1633,7 +1633,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||
// We'll now mine a block which should confirm Bob's HTLC sweep
|
||||
// transaction.
|
||||
block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &bobHtlcSweepTxid)
|
||||
ht.AssertTxInBlock(block, &bobHtlcSweepTxid)
|
||||
carolSecondLevelCSV--
|
||||
|
||||
// Now that the sweeping transaction has been confirmed, Bob should now
|
||||
|
@ -1656,12 +1656,12 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||
|
||||
// Mine a block to trigger the sweep of the second level tx.
|
||||
ht.MineEmptyBlocks(1)
|
||||
carolSweep := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
carolSweep := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// When Carol's sweep gets confirmed, she should have no more pending
|
||||
// channels.
|
||||
block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, carolSweep)
|
||||
ht.AssertTxInBlock(block, carolSweep)
|
||||
ht.AssertNumPendingForceClose(carol, 0)
|
||||
|
||||
// With the script-enforced lease commitment type, Alice and Bob still
|
||||
|
@ -1692,9 +1692,9 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest,
|
|||
aliceCommitOutpoint := wire.OutPoint{
|
||||
Hash: *aliceForceClose, Index: 3,
|
||||
}
|
||||
ht.Miner.AssertOutpointInMempool(aliceCommitOutpoint)
|
||||
ht.AssertOutpointInMempool(aliceCommitOutpoint)
|
||||
bobCommitOutpoint := wire.OutPoint{Hash: closingTxid, Index: 3}
|
||||
ht.Miner.AssertOutpointInMempool(bobCommitOutpoint)
|
||||
ht.AssertOutpointInMempool(bobCommitOutpoint)
|
||||
|
||||
// Confirm their sweeps.
|
||||
ht.MineBlocksAndAssertNumTxes(1, 2)
|
||||
|
@ -1881,13 +1881,13 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
|
|||
|
||||
// Bob's force close transaction should now be found in the mempool. If
|
||||
// there are anchors, we expect it to be offered to Bob's sweeper.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Bob has two anchor sweep requests, one for remote (invalid) and the
|
||||
// other for local.
|
||||
ht.AssertNumPendingSweeps(bob, 2)
|
||||
|
||||
closeTx := ht.Miner.AssertOutpointInMempool(
|
||||
closeTx := ht.AssertOutpointInMempool(
|
||||
ht.OutPointFromChannelPoint(bobChanPoint),
|
||||
)
|
||||
closeTxid := closeTx.TxHash()
|
||||
|
@ -1925,7 +1925,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
|
|||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// The above mined block will trigger Bob to sweep his anchor output.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Let Alice settle her invoices. When Bob now gets the preimages, he
|
||||
// has no other option than to broadcast his second-level transactions
|
||||
|
@ -1977,7 +1977,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
|
|||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Assert the sweeping txns are found in the mempool.
|
||||
txes := ht.Miner.GetNumTxsFromMempool(expectedTxes)
|
||||
txes := ht.GetNumTxsFromMempool(expectedTxes)
|
||||
|
||||
// Since Bob can aggregate the transactions, we expect a single
|
||||
// transaction, that have multiple spends from the commitment.
|
||||
|
@ -2048,7 +2048,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// Find the commitment sweep.
|
||||
bobCommitSweep := ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
bobCommitSweep := ht.GetNumTxsFromMempool(1)[0]
|
||||
ht.AssertTxSpendFrom(bobCommitSweep, closeTxid)
|
||||
|
||||
// Also ensure it is not spending from any of the HTLC output.
|
||||
|
@ -2092,7 +2092,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
|
|||
numBlocks := uint32(forceCloseChan.BlocksTilMaturity)
|
||||
|
||||
// Add debug log.
|
||||
_, height := ht.Miner.GetBestBlock()
|
||||
height := ht.CurrentHeight()
|
||||
bob.AddToLogf("itest: now mine %d blocks at height %d",
|
||||
numBlocks, height)
|
||||
ht.MineEmptyBlocks(int(numBlocks) - 1)
|
||||
|
@ -2120,7 +2120,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
|
|||
// TODO(yy): remove this once `blockbeat` is in place.
|
||||
numExpected := 1
|
||||
err := wait.NoError(func() error {
|
||||
mem := ht.Miner.GetRawMempool()
|
||||
mem := ht.GetRawMempool()
|
||||
if len(mem) == numExpected {
|
||||
return nil
|
||||
}
|
||||
|
@ -2135,7 +2135,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
|
|||
ht.Logf("Checking mempool got: %v", err)
|
||||
|
||||
// Make sure it spends from the second level tx.
|
||||
secondLevelSweep := ht.Miner.GetNumTxsFromMempool(numExpected)[0]
|
||||
secondLevelSweep := ht.GetNumTxsFromMempool(numExpected)[0]
|
||||
bobSweep := secondLevelSweep.TxHash()
|
||||
|
||||
// It should be sweeping all the second-level outputs.
|
||||
|
@ -2162,7 +2162,7 @@ func runMultiHopHtlcAggregation(ht *lntest.HarnessTest,
|
|||
// level sweep. Now Bob should have no pending channels anymore, as
|
||||
// this just resolved it by the confirmation of the sweep transaction.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, numExpected)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &bobSweep)
|
||||
ht.AssertTxInBlock(block, &bobSweep)
|
||||
|
||||
// For leased channels, we need to mine one more block to confirm Bob's
|
||||
// commit output sweep.
|
||||
|
@ -2223,7 +2223,7 @@ func createThreeHopNetwork(ht *lntest.HarnessTest,
|
|||
ht.FundCoinsUnconfirmed(btcutil.SatoshiPerBitcoin, carol)
|
||||
|
||||
// Mine 1 block to get the above coins confirmed.
|
||||
ht.MineBlocks(1)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 3)
|
||||
}
|
||||
|
||||
// We'll start the test by creating a channel between Alice and Bob,
|
||||
|
@ -2232,8 +2232,8 @@ func createThreeHopNetwork(ht *lntest.HarnessTest,
|
|||
var aliceFundingShim *lnrpc.FundingShim
|
||||
var thawHeight uint32
|
||||
if c == lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE {
|
||||
_, minerHeight := ht.Miner.GetBestBlock()
|
||||
thawHeight = uint32(minerHeight + thawHeightDelta)
|
||||
minerHeight := ht.CurrentHeight()
|
||||
thawHeight = minerHeight + thawHeightDelta
|
||||
aliceFundingShim, _ = deriveFundingShim(
|
||||
ht, alice, bob, chanAmt, thawHeight, true, c,
|
||||
)
|
||||
|
@ -2441,7 +2441,7 @@ func runExtraPreimageFromRemoteCommit(ht *lntest.HarnessTest,
|
|||
// Mine a block to trigger the sweep, and clean up the anchor sweeping
|
||||
// tx.
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Restart Bob. Once he finishes syncing the channel state, he should
|
||||
// notice the force close from Carol.
|
||||
|
@ -2449,15 +2449,15 @@ func runExtraPreimageFromRemoteCommit(ht *lntest.HarnessTest,
|
|||
|
||||
// Get the current height to compute number of blocks to mine to
|
||||
// trigger the htlc timeout resolver from Bob.
|
||||
_, height := ht.Miner.GetBestBlock()
|
||||
height := ht.CurrentHeight()
|
||||
|
||||
// We'll now mine enough blocks to trigger Bob's timeout resolver.
|
||||
numBlocks = htlc.ExpirationHeight - uint32(height) -
|
||||
numBlocks = htlc.ExpirationHeight - height -
|
||||
lncfg.DefaultOutgoingBroadcastDelta
|
||||
|
||||
// We should now have Carol's htlc success tx in the mempool.
|
||||
numTxesMempool := 1
|
||||
ht.Miner.AssertNumTxsInMempool(numTxesMempool)
|
||||
ht.AssertNumTxsInMempool(numTxesMempool)
|
||||
|
||||
// For neutrino backend, the timeout resolver needs to extract the
|
||||
// preimage from the blocks.
|
||||
|
@ -2667,25 +2667,25 @@ func runExtraPreimageFromLocalCommit(ht *lntest.HarnessTest,
|
|||
switch c {
|
||||
case lnrpc.CommitmentType_LEGACY:
|
||||
htlcOutpoint.Index = 0
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
case lnrpc.CommitmentType_ANCHORS, lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||
htlcOutpoint.Index = 2
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
case lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE:
|
||||
htlcOutpoint.Index = 2
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
}
|
||||
|
||||
// Get the current height to compute number of blocks to mine to
|
||||
// trigger the timeout resolver from Bob.
|
||||
_, height := ht.Miner.GetBestBlock()
|
||||
height := ht.CurrentHeight()
|
||||
|
||||
// We'll now mine enough blocks to trigger Bob's htlc timeout resolver
|
||||
// to act. Once his timeout resolver starts, it will extract the
|
||||
// preimage from Carol's direct spend tx found in the mempool.
|
||||
numBlocks = htlc.ExpirationHeight - uint32(height) -
|
||||
numBlocks = htlc.ExpirationHeight - height -
|
||||
lncfg.DefaultOutgoingBroadcastDelta
|
||||
|
||||
// Decrease the fee rate used by the sweeper so Bob's timeout tx will
|
||||
|
@ -2701,10 +2701,16 @@ func runExtraPreimageFromLocalCommit(ht *lntest.HarnessTest,
|
|||
// preimage from the blocks.
|
||||
if ht.IsNeutrinoBackend() {
|
||||
// Make sure the direct spend tx is still in the mempool.
|
||||
ht.Miner.AssertOutpointInMempool(htlcOutpoint)
|
||||
ht.AssertOutpointInMempool(htlcOutpoint)
|
||||
|
||||
// Mine a block to confirm Carol's direct spend tx.
|
||||
ht.MineBlocks(1)
|
||||
// Mine a block to confirm two txns,
|
||||
// - Carol's direct spend tx.
|
||||
// - Bob's to_local output sweep tx.
|
||||
if c != lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE {
|
||||
ht.MineBlocksAndAssertNumTxes(1, 2)
|
||||
} else {
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, check that the Alice's payment is marked as succeeded as
|
||||
|
|
|
@ -96,8 +96,8 @@ func testNonStdSweepInner(ht *lntest.HarnessTest, address string) {
|
|||
carol.RPC.SendCoins(sendReq)
|
||||
|
||||
// Fetch the txid so we can grab the raw transaction.
|
||||
txid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
tx := ht.Miner.GetRawTransaction(txid)
|
||||
txid := ht.AssertNumTxsInMempool(1)[0]
|
||||
tx := ht.GetRawTransaction(txid)
|
||||
|
||||
msgTx := tx.MsgTx()
|
||||
|
||||
|
@ -111,7 +111,7 @@ func testNonStdSweepInner(ht *lntest.HarnessTest, address string) {
|
|||
for _, inp := range msgTx.TxIn {
|
||||
// Fetch the previous outpoint's value.
|
||||
prevOut := inp.PreviousOutPoint
|
||||
ptx := ht.Miner.GetRawTransaction(&prevOut.Hash)
|
||||
ptx := ht.GetRawTransaction(&prevOut.Hash)
|
||||
|
||||
pout := ptx.MsgTx().TxOut[prevOut.Index]
|
||||
inputVal += int(pout.Value)
|
||||
|
@ -125,7 +125,7 @@ func testNonStdSweepInner(ht *lntest.HarnessTest, address string) {
|
|||
|
||||
// Fetch the vsize of the transaction so we can determine if the
|
||||
// transaction pays >= 1 sat/vbyte.
|
||||
rawTx := ht.Miner.GetRawTransactionVerbose(txid)
|
||||
rawTx := ht.Miner().GetRawTransactionVerbose(txid)
|
||||
|
||||
// Require fee >= vbytes.
|
||||
require.True(ht, fee >= int(rawTx.Vsize))
|
||||
|
|
|
@ -321,7 +321,7 @@ func testAnchorReservedValue(ht *lntest.HarnessTest) {
|
|||
|
||||
// Alice tries to send all funds to an external address, the reserved
|
||||
// value must stay in her wallet.
|
||||
minerAddr := ht.Miner.NewMinerAddress()
|
||||
minerAddr := ht.NewMinerAddress()
|
||||
|
||||
sweepReq = &lnrpc.SendCoinsRequest{
|
||||
Addr: minerAddr.String(),
|
||||
|
@ -486,7 +486,7 @@ func testAnchorThirdPartySpend(ht *lntest.HarnessTest) {
|
|||
|
||||
// We now update the anchor sweep's deadline to be different than the
|
||||
// commit sweep so they can won't grouped together.
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
currentHeight := int32(ht.CurrentHeight())
|
||||
deadline := int32(commit.DeadlineHeight) - currentHeight
|
||||
require.Positive(ht, deadline)
|
||||
ht.Logf("Found commit deadline %d, anchor deadline %d",
|
||||
|
@ -520,7 +520,7 @@ func testAnchorThirdPartySpend(ht *lntest.HarnessTest) {
|
|||
// Mine one block to trigger Alice's sweeper to reconsider the anchor
|
||||
// sweeping - it will be swept with her commit output together in one
|
||||
// tx.
|
||||
txns := ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns := ht.GetNumTxsFromMempool(2)
|
||||
aliceSweep := txns[0]
|
||||
if aliceSweep.TxOut[0].Value > txns[1].TxOut[0].Value {
|
||||
aliceSweep = txns[1]
|
||||
|
@ -544,7 +544,7 @@ func testAnchorThirdPartySpend(ht *lntest.HarnessTest) {
|
|||
// With the anchor output located, and the main commitment mined we'll
|
||||
// instruct the wallet to send all coins in the wallet to a new address
|
||||
// (to the miner), including unconfirmed change.
|
||||
minerAddr := ht.Miner.NewMinerAddress()
|
||||
minerAddr := ht.NewMinerAddress()
|
||||
sweepReq := &lnrpc.SendCoinsRequest{
|
||||
Addr: minerAddr.String(),
|
||||
SendAll: true,
|
||||
|
@ -574,7 +574,7 @@ func testAnchorThirdPartySpend(ht *lntest.HarnessTest) {
|
|||
// mine a transaction that double spends the output.
|
||||
thirdPartyAnchorSweep := genAnchorSweep(ht, aliceSweep, anchor.Outpoint)
|
||||
ht.Logf("Third party tx=%v", thirdPartyAnchorSweep.TxHash())
|
||||
ht.Miner.MineBlockWithTx(thirdPartyAnchorSweep)
|
||||
ht.MineBlockWithTx(thirdPartyAnchorSweep)
|
||||
|
||||
// At this point, we should no longer find Alice's transaction that
|
||||
// tried to sweep the anchor in her wallet.
|
||||
|
@ -600,8 +600,8 @@ func testAnchorThirdPartySpend(ht *lntest.HarnessTest) {
|
|||
Hash: *forceCloseTxID,
|
||||
Index: 1,
|
||||
}
|
||||
ht.Miner.AssertOutpointInMempool(commitSweepOp)
|
||||
ht.MineBlocks(1)
|
||||
ht.AssertOutpointInMempool(commitSweepOp)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
ht.AssertNumWaitingClose(alice, 0)
|
||||
}
|
||||
|
@ -673,7 +673,7 @@ func genAnchorSweep(ht *lntest.HarnessTest, aliceSweep *wire.MsgTx,
|
|||
aliceAnchorTxIn.Witness[0] = nil
|
||||
aliceAnchorTxIn.Sequence = 16
|
||||
|
||||
minerAddr := ht.Miner.NewMinerAddress()
|
||||
minerAddr := ht.NewMinerAddress()
|
||||
addrScript, err := txscript.PayToAddrScript(minerAddr)
|
||||
require.NoError(ht, err, "unable to gen addr script")
|
||||
|
||||
|
@ -717,7 +717,7 @@ func testRemoveTx(ht *lntest.HarnessTest) {
|
|||
TargetConf: 6,
|
||||
}
|
||||
alice.RPC.SendCoins(sendReq)
|
||||
txID := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
txID := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Make sure the unspent number of utxos is 2 and the unconfirmed
|
||||
// balances add up.
|
||||
|
@ -727,7 +727,7 @@ func testRemoveTx(ht *lntest.HarnessTest) {
|
|||
require.Lenf(ht, unconfirmed, 2, "number of unconfirmed tx")
|
||||
|
||||
// Get the raw transaction to calculate the exact fee.
|
||||
tx := ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
tx := ht.GetNumTxsFromMempool(1)[0]
|
||||
|
||||
// Calculate the tx fee so we can compare the end amounts. We are
|
||||
// sending from the internal wallet to the internal wallet so only
|
||||
|
@ -766,8 +766,8 @@ func testRemoveTx(ht *lntest.HarnessTest) {
|
|||
// Mine a block and make sure the transaction previously broadcasted
|
||||
// shows up in alice's wallet although we removed the transaction from
|
||||
// the wallet when it was unconfirmed.
|
||||
block := ht.Miner.MineBlocks(1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, txID)
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.AssertTxInBlock(block, txID)
|
||||
|
||||
// Verify that alice has 2 confirmed unspent utxos in her default
|
||||
// wallet.
|
||||
|
@ -836,7 +836,7 @@ func testListSweeps(ht *lntest.HarnessTest) {
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// Get the current block height.
|
||||
_, blockHeight := ht.Miner.GetBestBlock()
|
||||
blockHeight := int32(ht.CurrentHeight())
|
||||
|
||||
// Close the second channel and also sweep the funds.
|
||||
ht.ForceCloseChannel(alice, chanPoints[1])
|
||||
|
@ -861,7 +861,7 @@ func testListSweeps(ht *lntest.HarnessTest) {
|
|||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// Now we can expect that the sweep has been broadcast.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// List all unconfirmed sweeps that alice's node had broadcast.
|
||||
sweepResp := alice.RPC.ListSweeps(false, -1)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
|
@ -30,9 +31,9 @@ func testOpenChannelAfterReorg(ht *lntest.HarnessTest) {
|
|||
}
|
||||
|
||||
// Create a temp miner.
|
||||
tempMiner := ht.Miner.SpawnTempMiner()
|
||||
tempMiner := ht.SpawnTempMiner()
|
||||
|
||||
miner := ht.Miner
|
||||
miner := ht.Miner()
|
||||
alice, bob := ht.Alice, ht.Bob
|
||||
|
||||
// Create a new channel that requires 1 confs before it's considered
|
||||
|
@ -45,7 +46,7 @@ func testOpenChannelAfterReorg(ht *lntest.HarnessTest) {
|
|||
|
||||
// Wait for miner to have seen the funding tx. The temporary miner is
|
||||
// disconnected, and won't see the transaction.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// At this point, the channel's funding transaction will have been
|
||||
// broadcast, but not confirmed, and the channel should be pending.
|
||||
|
@ -58,8 +59,8 @@ func testOpenChannelAfterReorg(ht *lntest.HarnessTest) {
|
|||
// and our new miner mine 15. This will also confirm our pending
|
||||
// channel on the original miner's chain, which should be considered
|
||||
// open.
|
||||
block := ht.MineBlocks(10)[0]
|
||||
ht.Miner.AssertTxInBlock(block, fundingTxID)
|
||||
block := ht.MineBlocksAndAssertNumTxes(10, 1)[0]
|
||||
ht.AssertTxInBlock(block, fundingTxID)
|
||||
_, err = tempMiner.Client.Generate(15)
|
||||
require.NoError(ht, err, "unable to generate blocks")
|
||||
|
||||
|
@ -115,7 +116,7 @@ func testOpenChannelAfterReorg(ht *lntest.HarnessTest) {
|
|||
|
||||
// Cleanup by mining the funding tx again, then closing the channel.
|
||||
block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, fundingTxID)
|
||||
ht.AssertTxInBlock(block, fundingTxID)
|
||||
|
||||
ht.CloseChannel(alice, chanPoint)
|
||||
}
|
||||
|
@ -767,6 +768,18 @@ func testFundingExpiryBlocksOnPending(ht *lntest.HarnessTest) {
|
|||
// channel.
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
chanPoint := lntest.ChanPointFromPendingUpdate(update)
|
||||
|
||||
// TODO(yy): remove the sleep once the following bug is fixed.
|
||||
//
|
||||
// We may get the error `unable to gracefully close channel
|
||||
// while peer is offline (try force closing it instead):
|
||||
// channel link not found`. This happens because the channel
|
||||
// link hasn't been added yet but we now proceed to closing the
|
||||
// channel. We may need to revisit how the channel open event
|
||||
// is created and make sure the event is only sent after all
|
||||
// relevant states have been updated.
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
ht.CloseChannel(alice, chanPoint)
|
||||
}
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ func runPsbtChanFunding(ht *lntest.HarnessTest, carol, dave *node.HarnessNode,
|
|||
}
|
||||
|
||||
// No transaction should have been published yet.
|
||||
ht.Miner.AssertNumTxsInMempool(0)
|
||||
ht.AssertNumTxsInMempool(0)
|
||||
|
||||
// Let's progress the second channel now. This time we'll use the raw
|
||||
// wire format transaction directly.
|
||||
|
@ -295,7 +295,7 @@ func runPsbtChanFunding(ht *lntest.HarnessTest, carol, dave *node.HarnessNode,
|
|||
|
||||
txHash := finalTx.TxHash()
|
||||
block := ht.MineBlocksAndAssertNumTxes(6, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &txHash)
|
||||
ht.AssertTxInBlock(block, &txHash)
|
||||
ht.AssertTopologyChannelOpen(carol, chanPoint)
|
||||
ht.AssertTopologyChannelOpen(carol, chanPoint2)
|
||||
|
||||
|
@ -456,7 +456,7 @@ func runPsbtChanFundingExternal(ht *lntest.HarnessTest, carol,
|
|||
finalizeRes := alice.RPC.FinalizePsbt(finalizeReq)
|
||||
|
||||
// No transaction should have been published yet.
|
||||
ht.Miner.AssertNumTxsInMempool(0)
|
||||
ht.AssertNumTxsInMempool(0)
|
||||
|
||||
// Great, now let's publish the final raw transaction.
|
||||
var finalTx wire.MsgTx
|
||||
|
@ -464,13 +464,13 @@ func runPsbtChanFundingExternal(ht *lntest.HarnessTest, carol,
|
|||
require.NoError(ht, err)
|
||||
|
||||
txHash := finalTx.TxHash()
|
||||
_, err = ht.Miner.Client.SendRawTransaction(&finalTx, false)
|
||||
_, err = ht.SendRawTransaction(&finalTx, false)
|
||||
require.NoError(ht, err)
|
||||
|
||||
// Now we can mine a block to get the transaction confirmed, then wait
|
||||
// for the new channel to be propagated through the network.
|
||||
block := ht.MineBlocksAndAssertNumTxes(6, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &txHash)
|
||||
ht.AssertTxInBlock(block, &txHash)
|
||||
ht.AssertTopologyChannelOpen(carol, chanPoint)
|
||||
ht.AssertTopologyChannelOpen(carol, chanPoint2)
|
||||
|
||||
|
@ -627,7 +627,7 @@ func runPsbtChanFundingSingleStep(ht *lntest.HarnessTest, carol,
|
|||
|
||||
txHash := finalTx.TxHash()
|
||||
block := ht.MineBlocksAndAssertNumTxes(6, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &txHash)
|
||||
ht.AssertTxInBlock(block, &txHash)
|
||||
ht.AssertTopologyChannelOpen(carol, chanPoint)
|
||||
|
||||
// Next, to make sure the channel functions as normal, we'll make some
|
||||
|
@ -1326,7 +1326,7 @@ func extractPublishAndMine(ht *lntest.HarnessTest, node *node.HarnessNode,
|
|||
// Mine one block which should contain two transactions.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
txHash := finalTx.TxHash()
|
||||
ht.Miner.AssertTxInBlock(block, &txHash)
|
||||
ht.AssertTxInBlock(block, &txHash)
|
||||
|
||||
return finalTx
|
||||
}
|
||||
|
@ -1432,8 +1432,8 @@ func assertPsbtSpend(ht *lntest.HarnessTest, alice *node.HarnessNode,
|
|||
block := ht.MineBlocksAndAssertNumTxes(1, 2)[0]
|
||||
firstTxHash := prevTx.TxHash()
|
||||
secondTxHash := finalTx.TxHash()
|
||||
ht.Miner.AssertTxInBlock(block, &firstTxHash)
|
||||
ht.Miner.AssertTxInBlock(block, &secondTxHash)
|
||||
ht.AssertTxInBlock(block, &firstTxHash)
|
||||
ht.AssertTxInBlock(block, &secondTxHash)
|
||||
}
|
||||
|
||||
// assertPsbtFundSignSpend funds a PSBT from the internal wallet and then
|
||||
|
@ -1683,6 +1683,9 @@ func testPsbtChanFundingWithUnstableUtxos(ht *lntest.HarnessTest) {
|
|||
ht.CloseChannelAssertPending(dave, channelPoint, true)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Make sure Carol sees her to_remote output from the force close tx.
|
||||
ht.AssertNumPendingSweeps(carol, 1)
|
||||
|
||||
// Mine one block to trigger the sweep transaction.
|
||||
ht.MineEmptyBlocks(1)
|
||||
|
||||
|
@ -1794,7 +1797,7 @@ func testPsbtChanFundingWithUnstableUtxos(ht *lntest.HarnessTest) {
|
|||
|
||||
txHash := finalTx.TxHash()
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &txHash)
|
||||
ht.AssertTxInBlock(block, &txHash)
|
||||
|
||||
// Now we do the same but instead use preselected utxos to verify that
|
||||
// these utxos respects the utxo restrictions on sweeper unconfirmed
|
||||
|
@ -1805,6 +1808,9 @@ func testPsbtChanFundingWithUnstableUtxos(ht *lntest.HarnessTest) {
|
|||
ht.CloseChannelAssertPending(dave, channelPoint2, true)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Make sure Carol sees her to_remote output from the force close tx.
|
||||
ht.AssertNumPendingSweeps(carol, 1)
|
||||
|
||||
// Mine one block to trigger the sweep transaction.
|
||||
ht.MineEmptyBlocks(1)
|
||||
|
||||
|
@ -1929,19 +1935,11 @@ func testPsbtChanFundingWithUnstableUtxos(ht *lntest.HarnessTest) {
|
|||
updateResp = ht.ReceiveOpenChannelUpdate(chanUpdates)
|
||||
upd, ok = updateResp.Update.(*lnrpc.OpenStatusUpdate_ChanPending)
|
||||
require.True(ht, ok)
|
||||
channelPoint3 := &lnrpc.ChannelPoint{
|
||||
FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
|
||||
FundingTxidBytes: upd.ChanPending.Txid,
|
||||
},
|
||||
OutputIndex: upd.ChanPending.OutputIndex,
|
||||
}
|
||||
|
||||
err = finalTx.Deserialize(bytes.NewReader(finalizeRes.RawFinalTx))
|
||||
require.NoError(ht, err)
|
||||
|
||||
txHash = finalTx.TxHash()
|
||||
block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, &txHash)
|
||||
|
||||
ht.CloseChannel(carol, channelPoint3)
|
||||
ht.AssertTxInBlock(block, &txHash)
|
||||
}
|
||||
|
|
|
@ -252,7 +252,7 @@ func testOnchainFundRecovery(ht *lntest.HarnessTest) {
|
|||
promptChangeAddr := func(node *node.HarnessNode) {
|
||||
ht.Helper()
|
||||
|
||||
minerAddr := ht.Miner.NewMinerAddress()
|
||||
minerAddr := ht.NewMinerAddress()
|
||||
req := &lnrpc.SendCoinsRequest{
|
||||
Addr: minerAddr.String(),
|
||||
Amount: minerAmt,
|
||||
|
@ -260,11 +260,11 @@ func testOnchainFundRecovery(ht *lntest.HarnessTest) {
|
|||
}
|
||||
resp := node.RPC.SendCoins(req)
|
||||
|
||||
txid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
txid := ht.AssertNumTxsInMempool(1)[0]
|
||||
require.Equal(ht, txid.String(), resp.Txid)
|
||||
|
||||
block := ht.MineBlocks(1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, txid)
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.AssertTxInBlock(block, txid)
|
||||
}
|
||||
restoreCheckBalance(finalBalance, 9, 20, promptChangeAddr)
|
||||
|
||||
|
@ -428,8 +428,7 @@ func testRescanAddressDetection(ht *lntest.HarnessTest) {
|
|||
})
|
||||
|
||||
// Wait until the spending tx is found and mine a block to confirm it.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.MineBlocks(1)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// The wallet should still just see a single UTXO of the change output
|
||||
// created earlier.
|
||||
|
|
|
@ -66,7 +66,7 @@ func testResHandoff(ht *lntest.HarnessTest) {
|
|||
ht.AssertNumWaitingClose(bob, 1)
|
||||
|
||||
// Mine a block to confirm the closing tx.
|
||||
ht.MineBlocks(1)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// We sleep here so we can be sure that the hand-off has occurred from
|
||||
// Bob's contractcourt to Bob's htlcswitch. This sleep could be removed
|
||||
|
|
|
@ -238,7 +238,7 @@ func testRestAPI(ht *lntest.HarnessTest) {
|
|||
|
||||
func wsTestCaseSubscription(ht *lntest.HarnessTest) {
|
||||
// Find out the current best block so we can subscribe to the next one.
|
||||
hash, height := ht.Miner.GetBestBlock()
|
||||
hash, height := ht.GetBestBlock()
|
||||
|
||||
// Create a new subscription to get block epoch events.
|
||||
req := &chainrpc.BlockEpoch{
|
||||
|
@ -296,7 +296,7 @@ func wsTestCaseSubscription(ht *lntest.HarnessTest) {
|
|||
}()
|
||||
|
||||
// Mine a block and make sure we get a message for it.
|
||||
blockHashes := ht.Miner.GenerateBlocks(1)
|
||||
blockHashes := ht.Miner().GenerateBlocks(1)
|
||||
select {
|
||||
case msg := <-msgChan:
|
||||
require.Equal(
|
||||
|
@ -314,7 +314,7 @@ func wsTestCaseSubscription(ht *lntest.HarnessTest) {
|
|||
|
||||
func wsTestCaseSubscriptionMacaroon(ht *lntest.HarnessTest) {
|
||||
// Find out the current best block so we can subscribe to the next one.
|
||||
hash, height := ht.Miner.GetBestBlock()
|
||||
hash, height := ht.GetBestBlock()
|
||||
|
||||
// Create a new subscription to get block epoch events.
|
||||
req := &chainrpc.BlockEpoch{
|
||||
|
@ -388,7 +388,7 @@ func wsTestCaseSubscriptionMacaroon(ht *lntest.HarnessTest) {
|
|||
}()
|
||||
|
||||
// Mine a block and make sure we get a message for it.
|
||||
blockHashes := ht.Miner.GenerateBlocks(1)
|
||||
blockHashes := ht.Miner().GenerateBlocks(1)
|
||||
select {
|
||||
case msg := <-msgChan:
|
||||
require.Equal(
|
||||
|
|
|
@ -122,7 +122,7 @@ func breachRetributionTestCase(ht *lntest.HarnessTest,
|
|||
// update, then ensure that the closing transaction was included in the
|
||||
// block.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, breachTXID)
|
||||
ht.AssertTxInBlock(block, breachTXID)
|
||||
|
||||
// Construct to_remote output which pays to Bob. Based on the output
|
||||
// ordering, the first output in this breach tx is the to_remote
|
||||
|
@ -146,7 +146,7 @@ func breachRetributionTestCase(ht *lntest.HarnessTest,
|
|||
// sweeping transactions in the mempool. Thus we directly assert that
|
||||
// the breach transaction's outpoint is seen in the mempool instead of
|
||||
// checking the number of transactions.
|
||||
justiceTx := ht.Miner.AssertOutpointInMempool(toRemoteOp)
|
||||
justiceTx := ht.AssertOutpointInMempool(toRemoteOp)
|
||||
|
||||
// Assert that all the inputs of this transaction are spending outputs
|
||||
// generated by Bob's breach transaction above.
|
||||
|
@ -174,7 +174,7 @@ func breachRetributionTestCase(ht *lntest.HarnessTest,
|
|||
// transaction which was just accepted into the mempool.
|
||||
block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
justiceTxid := justiceTx.TxHash()
|
||||
ht.Miner.AssertTxInBlock(block, &justiceTxid)
|
||||
ht.AssertTxInBlock(block, &justiceTxid)
|
||||
|
||||
ht.AssertNodeNumChannels(carol, 0)
|
||||
|
||||
|
@ -338,7 +338,7 @@ func revokedCloseRetributionZeroValueRemoteOutputCase(ht *lntest.HarnessTest,
|
|||
// sweeping transactions in the mempool. Thus we directly assert that
|
||||
// the breach transaction's outpoint is seen in the mempool instead of
|
||||
// checking the number of transactions.
|
||||
justiceTx := ht.Miner.AssertOutpointInMempool(toLocalOp)
|
||||
justiceTx := ht.AssertOutpointInMempool(toLocalOp)
|
||||
|
||||
// Assert that all the inputs of this transaction are spending outputs
|
||||
// generated by Carol's breach transaction above.
|
||||
|
@ -363,7 +363,7 @@ func revokedCloseRetributionZeroValueRemoteOutputCase(ht *lntest.HarnessTest,
|
|||
// transaction which was just accepted into the mempool.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
justiceTxid := justiceTx.TxHash()
|
||||
ht.Miner.AssertTxInBlock(block, &justiceTxid)
|
||||
ht.AssertTxInBlock(block, &justiceTxid)
|
||||
|
||||
// At this point, Dave should have no pending channels.
|
||||
ht.AssertNodeNumChannels(dave, 0)
|
||||
|
@ -559,7 +559,7 @@ func revokedCloseRetributionRemoteHodlCase(ht *lntest.HarnessTest,
|
|||
breachTXID := ht.WaitForChannelCloseEvent(closeUpdates)
|
||||
require.Equal(ht, closeTxID[:], breachTXID[:],
|
||||
"expected breach ID to be equal to close ID")
|
||||
ht.Miner.AssertTxInBlock(block, breachTXID)
|
||||
ht.AssertTxInBlock(block, breachTXID)
|
||||
|
||||
// Query the mempool for Dave's justice transaction, this should be
|
||||
// broadcast as Carol's contract breaching transaction gets confirmed
|
||||
|
@ -570,16 +570,16 @@ func revokedCloseRetributionRemoteHodlCase(ht *lntest.HarnessTest,
|
|||
var justiceTxid *chainhash.Hash
|
||||
errNotFound := errors.New("justice tx not found")
|
||||
findJusticeTx := func() (*chainhash.Hash, error) {
|
||||
mempool := ht.Miner.GetRawMempool()
|
||||
mempool := ht.GetRawMempool()
|
||||
|
||||
for _, txid := range mempool {
|
||||
// Check that the justice tx has the appropriate number
|
||||
// of inputs.
|
||||
//
|
||||
// NOTE: We don't use `ht.Miner.GetRawTransaction`
|
||||
// NOTE: We don't use `ht.GetRawTransaction`
|
||||
// which asserts a txid must be found as the HTLC
|
||||
// spending txes might be aggregated.
|
||||
tx, err := ht.Miner.Client.GetRawTransaction(txid)
|
||||
tx, err := ht.Miner().Client.GetRawTransaction(txid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -626,14 +626,14 @@ func revokedCloseRetributionRemoteHodlCase(ht *lntest.HarnessTest,
|
|||
}
|
||||
require.NoError(ht, err, "timeout finding justice tx")
|
||||
|
||||
justiceTx := ht.Miner.GetRawTransaction(justiceTxid)
|
||||
justiceTx := ht.GetRawTransaction(justiceTxid)
|
||||
|
||||
// isSecondLevelSpend checks that the passed secondLevelTxid is a
|
||||
// potentitial second level spend spending from the commit tx.
|
||||
isSecondLevelSpend := func(commitTxid,
|
||||
secondLevelTxid *chainhash.Hash) bool {
|
||||
|
||||
secondLevel := ht.Miner.GetRawTransaction(secondLevelTxid)
|
||||
secondLevel := ht.GetRawTransaction(secondLevelTxid)
|
||||
|
||||
// A second level spend should have only one input, and one
|
||||
// output.
|
||||
|
|
|
@ -1010,7 +1010,7 @@ func testErrorHandlingOnChainFailure(ht *lntest.HarnessTest) {
|
|||
ht.MineBlocks(node.DefaultCSV - 1)
|
||||
ht.AssertNumPendingSweeps(ht.Bob, 1)
|
||||
ht.MineEmptyBlocks(1)
|
||||
ht.Miner.MineBlocksAndAssertNumTxes(1, 1)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Restart bob so that we can test that he's able to recover everything
|
||||
// he needs to claim a blinded HTLC.
|
||||
|
@ -1021,13 +1021,13 @@ func testErrorHandlingOnChainFailure(ht *lntest.HarnessTest) {
|
|||
// value.
|
||||
info := ht.Bob.RPC.GetInfo()
|
||||
target := carolHTLC.IncomingExpiry - info.BlockHeight
|
||||
ht.MineBlocks(target)
|
||||
ht.MineBlocks(int(target))
|
||||
|
||||
// Wait for Bob's timeout transaction in the mempool, since we've
|
||||
// suspended Carol we don't need to account for her commitment output
|
||||
// claim.
|
||||
ht.Miner.MineBlocksAndAssertNumTxes(1, 1)
|
||||
ht.AssertNumPendingSweeps(ht.Bob, 0)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Assert that the HTLC has cleared.
|
||||
ht.WaitForBlockchainSync(ht.Bob)
|
||||
|
@ -1049,7 +1049,7 @@ func testErrorHandlingOnChainFailure(ht *lntest.HarnessTest) {
|
|||
// Clean up the rest of our force close: mine blocks so that Bob's CSV
|
||||
// expires plus one block to trigger his sweep and then mine it.
|
||||
ht.MineBlocks(node.DefaultCSV + 1)
|
||||
ht.Miner.MineBlocksAndAssertNumTxes(1, 1)
|
||||
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
// Bring carol back up so that we can close out the rest of our
|
||||
// channels cooperatively. She requires an interceptor to start up
|
||||
|
|
|
@ -117,7 +117,7 @@ func testSingleHopSendToRouteCase(ht *lntest.HarnessTest,
|
|||
// Assert Carol and Dave are synced to the chain before proceeding, to
|
||||
// ensure the queried route will have a valid final CLTV once the HTLC
|
||||
// reaches Dave.
|
||||
_, minerHeight := ht.Miner.GetBestBlock()
|
||||
minerHeight := int32(ht.CurrentHeight())
|
||||
ht.WaitForNodeBlockHeight(carol, minerHeight)
|
||||
ht.WaitForNodeBlockHeight(dave, minerHeight)
|
||||
|
||||
|
|
|
@ -296,7 +296,7 @@ func assertSignOutputRaw(ht *lntest.HarnessTest,
|
|||
alice.RPC.SendCoins(req)
|
||||
|
||||
// Wait until the TX is found in the mempool.
|
||||
txid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
txid := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
targetOutputIndex := ht.GetOutputIndex(txid, targetAddr.String())
|
||||
|
||||
|
@ -359,7 +359,7 @@ func assertSignOutputRaw(ht *lntest.HarnessTest,
|
|||
})
|
||||
|
||||
// Wait until the spending tx is found.
|
||||
txid = ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
txid = ht.AssertNumTxsInMempool(1)[0]
|
||||
p2wkhOutputIndex := ht.GetOutputIndex(txid, p2wkhAdrr.String())
|
||||
|
||||
op := &lnrpc.OutPoint{
|
||||
|
|
|
@ -168,11 +168,11 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
|
|||
ht.MineEmptyBlocks(int(numBlocks))
|
||||
|
||||
// Assert Bob's force closing tx has been broadcast.
|
||||
closeTxid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
closeTxid := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Remember the force close height so we can calculate the deadline
|
||||
// height.
|
||||
_, forceCloseHeight := ht.Miner.GetBestBlock()
|
||||
forceCloseHeight := ht.CurrentHeight()
|
||||
|
||||
// Bob should have two pending sweeps,
|
||||
// - anchor sweeping from his local commitment.
|
||||
|
@ -188,7 +188,7 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
|
|||
sweeps := ht.AssertNumPendingSweeps(bob, 2)
|
||||
|
||||
// The two anchor sweeping should have the same deadline height.
|
||||
deadlineHeight := uint32(forceCloseHeight) + deadlineDeltaAnchor
|
||||
deadlineHeight := forceCloseHeight + deadlineDeltaAnchor
|
||||
require.Equal(ht, deadlineHeight, sweeps[0].DeadlineHeight)
|
||||
require.Equal(ht, deadlineHeight, sweeps[1].DeadlineHeight)
|
||||
|
||||
|
@ -209,7 +209,7 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
|
|||
//
|
||||
// We should see Bob's anchor sweeping tx triggered by the above
|
||||
// block, along with his force close tx.
|
||||
txns := ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns := ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx.
|
||||
sweepTx := ht.FindSweepingTxns(txns, 1, *closeTxid)[0]
|
||||
|
@ -261,12 +261,12 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
|
|||
|
||||
// Make sure Bob's old sweeping tx has been removed from the
|
||||
// mempool.
|
||||
ht.Miner.AssertTxNotInMempool(sweepTx.TxHash())
|
||||
ht.AssertTxNotInMempool(sweepTx.TxHash())
|
||||
|
||||
// We expect to see two txns in the mempool,
|
||||
// - Bob's force close tx.
|
||||
// - Bob's anchor sweep tx.
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
// We expect the fees to increase by i*delta.
|
||||
expectedFee := startFeeAnchor + feeDelta.MulF64(float64(i))
|
||||
|
@ -276,7 +276,7 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
|
|||
|
||||
// We should see Bob's anchor sweeping tx being fee bumped
|
||||
// since it's not confirmed, along with his force close tx.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns = ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx.
|
||||
sweepTx = ht.FindSweepingTxns(txns, 1, *closeTxid)[0]
|
||||
|
@ -304,18 +304,18 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
|
|||
//
|
||||
// Once out of the above loop, we expect to be 2 blocks before the CPFP
|
||||
// deadline.
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
currentHeight := ht.CurrentHeight()
|
||||
require.Equal(ht, int(anchorDeadline-2), int(currentHeight))
|
||||
|
||||
// Mine one more block, we'd use up all the CPFP budget.
|
||||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// Make sure Bob's old sweeping tx has been removed from the mempool.
|
||||
ht.Miner.AssertTxNotInMempool(sweepTx.TxHash())
|
||||
ht.AssertTxNotInMempool(sweepTx.TxHash())
|
||||
|
||||
// Get the last sweeping tx - we should see two txns here, Bob's anchor
|
||||
// sweeping tx and his force close tx.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns = ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx.
|
||||
sweepTx = ht.FindSweepingTxns(txns, 1, *closeTxid)[0]
|
||||
|
@ -336,7 +336,7 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
|
|||
//
|
||||
// We expect two txns here, one for the anchor sweeping, the other for
|
||||
// the force close tx.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns = ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx.
|
||||
currentSweepTx := ht.FindSweepingTxns(txns, 1, *closeTxid)[0]
|
||||
|
@ -512,12 +512,12 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
|
|||
forceCloseHeight := htlc.ExpirationHeight - goToChainDelta
|
||||
|
||||
// Mine till the goToChainHeight is reached.
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
numBlocks := forceCloseHeight - uint32(currentHeight)
|
||||
currentHeight := ht.CurrentHeight()
|
||||
numBlocks := forceCloseHeight - currentHeight
|
||||
ht.MineEmptyBlocks(int(numBlocks))
|
||||
|
||||
// Assert Bob's force closing tx has been broadcast.
|
||||
closeTxid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
closeTxid := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Bob should have two pending sweeps,
|
||||
// - anchor sweeping from his local commitment.
|
||||
|
@ -546,7 +546,7 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
|
|||
//
|
||||
// We should see Bob's anchor sweeping tx triggered by the above
|
||||
// block, along with his force close tx.
|
||||
txns := ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns := ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx.
|
||||
sweepTx := ht.FindSweepingTxns(txns, 1, *closeTxid)[0]
|
||||
|
@ -598,12 +598,12 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
|
|||
|
||||
// Make sure Bob's old sweeping tx has been removed from the
|
||||
// mempool.
|
||||
ht.Miner.AssertTxNotInMempool(sweepTx.TxHash())
|
||||
ht.AssertTxNotInMempool(sweepTx.TxHash())
|
||||
|
||||
// We expect to see two txns in the mempool,
|
||||
// - Bob's force close tx.
|
||||
// - Bob's anchor sweep tx.
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
// We expect the fees to increase by i*delta.
|
||||
expectedFee := startFeeAnchor + feeDelta.MulF64(float64(i))
|
||||
|
@ -613,7 +613,7 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
|
|||
|
||||
// We should see Bob's anchor sweeping tx being fee bumped
|
||||
// since it's not confirmed, along with his force close tx.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns = ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx.
|
||||
sweepTx = ht.FindSweepingTxns(txns, 1, *closeTxid)[0]
|
||||
|
@ -641,18 +641,18 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
|
|||
//
|
||||
// Once out of the above loop, we expect to be 2 blocks before the CPFP
|
||||
// deadline.
|
||||
_, currentHeight = ht.Miner.GetBestBlock()
|
||||
currentHeight = ht.CurrentHeight()
|
||||
require.Equal(ht, int(anchorDeadline-2), int(currentHeight))
|
||||
|
||||
// Mine one more block, we'd use up all the CPFP budget.
|
||||
ht.MineEmptyBlocks(1)
|
||||
|
||||
// Make sure Bob's old sweeping tx has been removed from the mempool.
|
||||
ht.Miner.AssertTxNotInMempool(sweepTx.TxHash())
|
||||
ht.AssertTxNotInMempool(sweepTx.TxHash())
|
||||
|
||||
// Get the last sweeping tx - we should see two txns here, Bob's anchor
|
||||
// sweeping tx and his force close tx.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns = ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx.
|
||||
sweepTx = ht.FindSweepingTxns(txns, 1, *closeTxid)[0]
|
||||
|
@ -673,7 +673,7 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
|
|||
//
|
||||
// We expect two txns here, one for the anchor sweeping, the other for
|
||||
// the force close tx.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns = ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx.
|
||||
currentSweepTx := ht.FindSweepingTxns(txns, 1, *closeTxid)[0]
|
||||
|
@ -872,7 +872,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
numBlocks := padCLTV(uint32(
|
||||
invoiceReqHold.CltvExpiry - lncfg.DefaultOutgoingBroadcastDelta,
|
||||
))
|
||||
ht.MineBlocks(numBlocks)
|
||||
ht.MineBlocks(int(numBlocks))
|
||||
|
||||
// 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
|
||||
|
@ -887,7 +887,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
ht.AssertNumPendingSweeps(bob, 2)
|
||||
|
||||
// Assert Bob's force closing tx has been broadcast.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Mine the force close tx, which triggers Bob's contractcourt to offer
|
||||
// his outgoing HTLC to his sweeper.
|
||||
|
@ -912,7 +912,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
|
||||
// Bob should now have one sweep and one sweeping tx in the mempool.
|
||||
ht.AssertNumPendingSweeps(bob, 1)
|
||||
outgoingSweep := ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
outgoingSweep := ht.GetNumTxsFromMempool(1)[0]
|
||||
|
||||
// Check the shape of the sweeping tx - we expect it to be
|
||||
// 2-input-2-output as a wallet utxo is used and a required output is
|
||||
|
@ -982,17 +982,17 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
outgoingFuncPosition++
|
||||
|
||||
// We should see Bob's sweeping tx in the mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(1)
|
||||
ht.AssertNumTxsInMempool(1)
|
||||
|
||||
// Make sure Bob's old sweeping tx has been removed from the
|
||||
// mempool.
|
||||
ht.Miner.AssertTxNotInMempool(outgoingSweep.TxHash())
|
||||
ht.AssertTxNotInMempool(outgoingSweep.TxHash())
|
||||
|
||||
// Bob should still have the outgoing HTLC sweep.
|
||||
ht.AssertNumPendingSweeps(bob, 1)
|
||||
|
||||
// We should see Bob's replacement tx in the mempool.
|
||||
outgoingSweep = ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
outgoingSweep = ht.GetNumTxsFromMempool(1)[0]
|
||||
|
||||
// Bob's outgoing HTLC sweeping tx should be fee bumped.
|
||||
assertSweepFeeRate(
|
||||
|
@ -1018,7 +1018,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
// We should see two txns in the mempool:
|
||||
// 1. Bob's outgoing HTLC sweeping tx.
|
||||
// 2. Bob's force close tx for Alice->Bob.
|
||||
txns := ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns := ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the force close tx - we expect it to have a single input.
|
||||
closeTx := txns[0]
|
||||
|
@ -1029,7 +1029,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
// We don't care the behavior of the anchor sweep in this test, so we
|
||||
// mine the force close tx to trigger Bob's contractcourt to offer his
|
||||
// incoming HTLC to his sweeper.
|
||||
ht.Miner.MineBlockWithTx(closeTx)
|
||||
ht.MineBlockWithTx(closeTx)
|
||||
|
||||
// Update Bob's fee function position.
|
||||
outgoingFuncPosition++
|
||||
|
@ -1051,7 +1051,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
// 1. the outgoing HTLC sweeping tx.
|
||||
// 2. the incoming HTLC sweeping tx.
|
||||
// 3. the anchor sweeping tx.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(3)
|
||||
txns = ht.GetNumTxsFromMempool(3)
|
||||
|
||||
abCloseTxid := closeTx.TxHash()
|
||||
|
||||
|
@ -1088,7 +1088,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
incomingFuncPosition := int32(0)
|
||||
|
||||
// Mine the anchor sweeping tx to reduce noise in this test.
|
||||
ht.Miner.MineBlockWithTxes([]*btcutil.Tx{btcutil.NewTx(anchorSweep)})
|
||||
ht.MineBlockWithTx(anchorSweep)
|
||||
|
||||
// Update the fee function's positions.
|
||||
outgoingFuncPosition++
|
||||
|
@ -1102,7 +1102,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
// We should see two txns in the mempool:
|
||||
// 1. the outgoing HTLC sweeping tx.
|
||||
// 2. the incoming HTLC sweeping tx.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns = ht.GetNumTxsFromMempool(2)
|
||||
|
||||
var incoming, outgoing *wire.MsgTx
|
||||
|
||||
|
@ -1156,12 +1156,12 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
|
|||
// We should see two txns in the mempool,
|
||||
// - the incoming HTLC sweeping tx.
|
||||
// - the outgoing HTLC sweeping tx.
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
// Make sure Bob's old sweeping txns have been removed from the
|
||||
// mempool.
|
||||
ht.Miner.AssertTxNotInMempool(outgoingSweep.TxHash())
|
||||
ht.Miner.AssertTxNotInMempool(incomingSweep.TxHash())
|
||||
ht.AssertTxNotInMempool(outgoingSweep.TxHash())
|
||||
ht.AssertTxNotInMempool(incomingSweep.TxHash())
|
||||
|
||||
// Bob should have two pending sweeps:
|
||||
// 1. the outgoing HTLC output on Bob->Carol.
|
||||
|
@ -1370,7 +1370,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
// - Alice's anchor sweeping tx must have been failed due to the fee
|
||||
// rate chosen in this test - the anchor sweep tx has no output.
|
||||
// - Bob's sweeping tx, which sweeps both his anchor and commit outputs.
|
||||
bobSweepTx := ht.Miner.GetNumTxsFromMempool(1)[0]
|
||||
bobSweepTx := ht.GetNumTxsFromMempool(1)[0]
|
||||
|
||||
// We expect two pending sweeps for Bob - anchor and commit outputs.
|
||||
pendingSweepBob := ht.AssertNumPendingSweeps(bob, 2)[0]
|
||||
|
@ -1380,7 +1380,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
//
|
||||
// TODO(yy): assert they are equal once blocks are synced via
|
||||
// `blockbeat`.
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
currentHeight := int32(ht.CurrentHeight())
|
||||
actualDeadline := int32(pendingSweepBob.DeadlineHeight) - currentHeight
|
||||
if actualDeadline != int32(deadlineB) {
|
||||
ht.Logf("!!! Found unsynced block between sweeper and "+
|
||||
|
@ -1438,7 +1438,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
//
|
||||
// TODO(yy): assert they are equal once blocks are synced via
|
||||
// `blockbeat`.
|
||||
_, currentHeight = ht.Miner.GetBestBlock()
|
||||
currentHeight = int32(ht.CurrentHeight())
|
||||
actualDeadline = int32(aliceCommit.DeadlineHeight) - currentHeight
|
||||
if actualDeadline != int32(deadlineA) {
|
||||
ht.Logf("!!! Found unsynced block between Alice's sweeper and "+
|
||||
|
@ -1456,7 +1456,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
aliceStartPosition := 0
|
||||
var aliceFirstSweepTx *wire.MsgTx
|
||||
err := wait.NoError(func() error {
|
||||
mem := ht.Miner.GetRawMempool()
|
||||
mem := ht.GetRawMempool()
|
||||
if len(mem) != 2 {
|
||||
return fmt.Errorf("want 2, got %v in mempool: %v",
|
||||
len(mem), mem)
|
||||
|
@ -1466,7 +1466,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
// created and published.
|
||||
aliceStartPosition = 1
|
||||
|
||||
txns := ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns := ht.GetNumTxsFromMempool(2)
|
||||
aliceFirstSweepTx = txns[0]
|
||||
|
||||
// Reassign if the second tx is larger.
|
||||
|
@ -1486,7 +1486,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
// block would trigger an RBF. We now need to assert the mempool has
|
||||
// removed the replaced tx.
|
||||
if aliceFirstSweepTx != nil {
|
||||
ht.Miner.AssertTxNotInMempool(aliceFirstSweepTx.TxHash())
|
||||
ht.AssertTxNotInMempool(aliceFirstSweepTx.TxHash())
|
||||
}
|
||||
|
||||
// We also remember the positions of fee functions used by Alice and
|
||||
|
@ -1503,7 +1503,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
// commit output together because they have different deadlines.
|
||||
// - Bob's previous sweeping tx, which sweeps both his anchor and
|
||||
// commit outputs, at the starting fee rate.
|
||||
txns := ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns := ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Assume the first tx is Alice's sweeping tx, if the second tx has a
|
||||
// larger output value, then that's Alice's as her to_local value is
|
||||
|
@ -1600,18 +1600,18 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
|
||||
// We expect to see both Alice's and Bob's sweeping txns in the
|
||||
// mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
// Make sure Alice's old sweeping tx has been removed from the
|
||||
// mempool.
|
||||
ht.Miner.AssertTxNotInMempool(aliceSweepTx.TxHash())
|
||||
ht.AssertTxNotInMempool(aliceSweepTx.TxHash())
|
||||
|
||||
// We should see two txns in the mempool:
|
||||
// - Alice's sweeping tx, which sweeps both her anchor and
|
||||
// commit outputs, using the increased fee rate.
|
||||
// - Bob's previous sweeping tx, which sweeps both his anchor
|
||||
// and commit outputs, at the possible increased fee rate.
|
||||
txns = ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns = ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Assume the first tx is Alice's sweeping tx, if the second tx
|
||||
// has a larger output value, then that's Alice's as her
|
||||
|
@ -1687,18 +1687,18 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
|
||||
// We expect to see both Alice's and Bob's sweeping txns in the
|
||||
// mempool.
|
||||
ht.Miner.AssertNumTxsInMempool(2)
|
||||
ht.AssertNumTxsInMempool(2)
|
||||
|
||||
// Make sure Alice's old sweeping tx has been removed from the
|
||||
// mempool.
|
||||
ht.Miner.AssertTxNotInMempool(aliceSweepTx.TxHash())
|
||||
ht.AssertTxNotInMempool(aliceSweepTx.TxHash())
|
||||
|
||||
// Make sure Bob's old sweeping tx has been removed from the
|
||||
// mempool. Since Bob's sweeping tx will only be successfully
|
||||
// RBFed every 4 blocks, his old sweeping tx only will be
|
||||
// removed when there are 4 blocks increased.
|
||||
if bobPosition%4 == 0 {
|
||||
ht.Miner.AssertTxNotInMempool(bobSweepTx.TxHash())
|
||||
ht.AssertTxNotInMempool(bobSweepTx.TxHash())
|
||||
}
|
||||
|
||||
// We should see two txns in the mempool:
|
||||
|
@ -1706,7 +1706,7 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
|
|||
// commit outputs, using the increased fee rate.
|
||||
// - Bob's previous sweeping tx, which sweeps both his anchor
|
||||
// and commit outputs, at the possible increased fee rate.
|
||||
txns := ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns := ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Assume the first tx is Alice's sweeping tx, if the second tx
|
||||
// has a larger output value, then that's Alice's as her
|
||||
|
@ -1804,7 +1804,7 @@ func createSimpleNetwork(ht *lntest.HarnessTest, nodeCfg []string,
|
|||
}
|
||||
|
||||
// Mine 1 block to get the above coins confirmed.
|
||||
ht.MineBlocks(1)
|
||||
ht.MineBlocksAndAssertNumTxes(1, numNodes-1)
|
||||
|
||||
// Open channels in batch to save blocks mined.
|
||||
reqs := make([]*lntest.OpenChannelRequest, 0, len(nodes)-1)
|
||||
|
@ -1911,7 +1911,7 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
|
|||
|
||||
// We expect to see Alice's original tx and her CPFP tx in the
|
||||
// mempool.
|
||||
txns := ht.Miner.GetNumTxsFromMempool(2)
|
||||
txns := ht.GetNumTxsFromMempool(2)
|
||||
|
||||
// Find the sweeping tx - assume it's the first item, if it has
|
||||
// the same txid as the parent tx, use the second item.
|
||||
|
@ -1972,7 +1972,7 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
|
|||
|
||||
// Since the request doesn't specify a deadline, we expect the default
|
||||
// deadline to be used.
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
currentHeight := int32(ht.CurrentHeight())
|
||||
deadline := uint32(currentHeight + sweep.DefaultDeadlineDelta)
|
||||
|
||||
// Assert the pending sweep is created with the expected values:
|
||||
|
@ -2003,7 +2003,7 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
|
|||
alice.RPC.BumpFee(bumpFeeReq)
|
||||
|
||||
// Alice's old sweeping tx should be replaced.
|
||||
ht.Miner.AssertTxNotInMempool(sweepTx1.TxHash())
|
||||
ht.AssertTxNotInMempool(sweepTx1.TxHash())
|
||||
|
||||
// Assert the pending sweep is created with the expected values:
|
||||
// - broadcast attempts: 2.
|
||||
|
@ -2035,7 +2035,7 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
|
|||
alice.RPC.BumpFee(bumpFeeReq)
|
||||
|
||||
// Alice's old sweeping tx should be replaced.
|
||||
ht.Miner.AssertTxNotInMempool(sweepTx2.TxHash())
|
||||
ht.AssertTxNotInMempool(sweepTx2.TxHash())
|
||||
|
||||
// Assert the pending sweep is created with the expected values:
|
||||
// - broadcast attempts: 3.
|
||||
|
@ -2066,7 +2066,7 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
|
|||
alice.RPC.BumpFee(bumpFeeReq)
|
||||
|
||||
// Alice's old sweeping tx should be replaced.
|
||||
ht.Miner.AssertTxNotInMempool(sweepTx3.TxHash())
|
||||
ht.AssertTxNotInMempool(sweepTx3.TxHash())
|
||||
|
||||
// Assert the pending sweep is created with the expected values:
|
||||
// - broadcast attempts: 4.
|
||||
|
@ -2093,7 +2093,7 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
|
|||
alice.RPC.BumpFee(bumpFeeReq)
|
||||
|
||||
// Alice's old sweeping tx should be replaced.
|
||||
ht.Miner.AssertTxNotInMempool(sweepTx4.TxHash())
|
||||
ht.AssertTxNotInMempool(sweepTx4.TxHash())
|
||||
|
||||
// Assert the pending sweep is created with the expected values:
|
||||
// - broadcast attempts: 5.
|
||||
|
|
|
@ -96,7 +96,7 @@ func testTaprootSendCoinsKeySpendBip86(ht *lntest.HarnessTest,
|
|||
|
||||
// Assert this is a segwit v1 address that starts with bcrt1p.
|
||||
require.Contains(
|
||||
ht, p2trResp.Address, ht.Miner.ActiveNet.Bech32HRPSegwit+"1p",
|
||||
ht, p2trResp.Address, ht.Miner().ActiveNet.Bech32HRPSegwit+"1p",
|
||||
)
|
||||
|
||||
// Send the coins from Alice's wallet to her own, but to the new p2tr
|
||||
|
@ -107,7 +107,7 @@ func testTaprootSendCoinsKeySpendBip86(ht *lntest.HarnessTest,
|
|||
TargetConf: 6,
|
||||
})
|
||||
|
||||
txid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
txid := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Wait until bob has seen the tx and considers it as owned.
|
||||
p2trOutputIndex := ht.GetOutputIndex(txid, p2trResp.Address)
|
||||
|
@ -162,7 +162,7 @@ func testTaprootComputeInputScriptKeySpendBip86(ht *lntest.HarnessTest,
|
|||
alice.RPC.SendCoins(req)
|
||||
|
||||
// Wait until bob has seen the tx and considers it as owned.
|
||||
txid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
txid := ht.AssertNumTxsInMempool(1)[0]
|
||||
p2trOutputIndex := ht.GetOutputIndex(txid, p2trAddr.String())
|
||||
op := &lnrpc.OutPoint{
|
||||
TxidBytes: txid[:],
|
||||
|
@ -1413,7 +1413,7 @@ func clearWalletImportedTapscriptBalance(ht *lntest.HarnessTest,
|
|||
// Mine one block which should contain the sweep transaction.
|
||||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
sweepTxHash := sweepTx.TxHash()
|
||||
ht.Miner.AssertTxInBlock(block, &sweepTxHash)
|
||||
ht.AssertTxInBlock(block, &sweepTxHash)
|
||||
}
|
||||
|
||||
// testScriptHashLock returns a simple bitcoin script that locks the funds to
|
||||
|
@ -1481,7 +1481,7 @@ func sendToTaprootOutput(ht *lntest.HarnessTest, hn *node.HarnessNode,
|
|||
hn.RPC.SendCoins(req)
|
||||
|
||||
// Wait until the TX is found in the mempool.
|
||||
txid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
txid := ht.AssertNumTxsInMempool(1)[0]
|
||||
p2trOutputIndex := ht.GetOutputIndex(txid, tapScriptAddr.String())
|
||||
p2trOutpoint := wire.OutPoint{
|
||||
Hash: *txid,
|
||||
|
@ -1535,13 +1535,13 @@ func publishTxAndConfirmSweep(ht *lntest.HarnessTest, node *node.HarnessNode,
|
|||
// Before we publish the tx that spends the p2tr transaction, we want to
|
||||
// register a spend listener that we expect to fire after mining the
|
||||
// block.
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
currentHeight := ht.CurrentHeight()
|
||||
|
||||
// For a Taproot output we cannot leave the outpoint empty. Let's make
|
||||
// sure the API returns the correct error here.
|
||||
req := &chainrpc.SpendRequest{
|
||||
Script: spendRequest.Script,
|
||||
HeightHint: uint32(currentHeight),
|
||||
HeightHint: currentHeight,
|
||||
}
|
||||
spendClient := node.RPC.RegisterSpendNtfn(req)
|
||||
|
||||
|
@ -1556,7 +1556,7 @@ func publishTxAndConfirmSweep(ht *lntest.HarnessTest, node *node.HarnessNode,
|
|||
req = &chainrpc.SpendRequest{
|
||||
Outpoint: spendRequest.Outpoint,
|
||||
Script: spendRequest.Script,
|
||||
HeightHint: uint32(currentHeight),
|
||||
HeightHint: currentHeight,
|
||||
}
|
||||
spendClient = node.RPC.RegisterSpendNtfn(req)
|
||||
|
||||
|
@ -1582,7 +1582,7 @@ func publishTxAndConfirmSweep(ht *lntest.HarnessTest, node *node.HarnessNode,
|
|||
require.NoError(ht, err)
|
||||
spend := spendMsg.GetSpend()
|
||||
require.NotNil(ht, spend)
|
||||
require.Equal(ht, spend.SpendingHeight, uint32(currentHeight+1))
|
||||
require.Equal(ht, spend.SpendingHeight, currentHeight+1)
|
||||
}
|
||||
|
||||
// confirmAddress makes sure that a transaction in the mempool spends funds to
|
||||
|
@ -1592,7 +1592,7 @@ func confirmAddress(ht *lntest.HarnessTest, hn *node.HarnessNode,
|
|||
addrString string) {
|
||||
|
||||
// Wait until the tx that sends to the address is found.
|
||||
txid := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
txid := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Wait until bob has seen the tx and considers it as owned.
|
||||
addrOutputIndex := ht.GetOutputIndex(txid, addrString)
|
||||
|
@ -1609,11 +1609,11 @@ func confirmAddress(ht *lntest.HarnessTest, hn *node.HarnessNode,
|
|||
addrPkScript, err := txscript.PayToAddrScript(parsedAddr)
|
||||
require.NoError(ht, err)
|
||||
|
||||
_, currentHeight := ht.Miner.GetBestBlock()
|
||||
currentHeight := ht.CurrentHeight()
|
||||
req := &chainrpc.ConfRequest{
|
||||
Script: addrPkScript,
|
||||
Txid: txid[:],
|
||||
HeightHint: uint32(currentHeight),
|
||||
HeightHint: currentHeight,
|
||||
NumConfs: 1,
|
||||
IncludeBlock: true,
|
||||
}
|
||||
|
@ -1628,7 +1628,7 @@ func confirmAddress(ht *lntest.HarnessTest, hn *node.HarnessNode,
|
|||
require.NoError(ht, err)
|
||||
conf := confMsg.GetConf()
|
||||
require.NotNil(ht, conf)
|
||||
require.Equal(ht, conf.BlockHeight, uint32(currentHeight+1))
|
||||
require.Equal(ht, conf.BlockHeight, currentHeight+1)
|
||||
require.NotNil(ht, conf.RawBlock)
|
||||
|
||||
// We should also be able to decode the raw block.
|
||||
|
@ -1850,7 +1850,7 @@ func testTaprootCoopClose(ht *lntest.HarnessTest) {
|
|||
// assertTaprootDeliveryUsed returns true if a Taproot addr was used in
|
||||
// the co-op close transaction.
|
||||
assertTaprootDeliveryUsed := func(closingTxid *chainhash.Hash) bool {
|
||||
tx := ht.Miner.GetRawTransaction(closingTxid)
|
||||
tx := ht.GetRawTransaction(closingTxid)
|
||||
for _, txOut := range tx.MsgTx().TxOut {
|
||||
if !txscript.IsPayToTaproot(txOut.PkScript) {
|
||||
return false
|
||||
|
|
|
@ -151,7 +151,7 @@ func TestLightningNetworkDaemon(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
_, height := harnessTest.Miner.GetBestBlock()
|
||||
height := harnessTest.CurrentHeight()
|
||||
t.Logf("=========> tests finished for tranche: %v, tested %d "+
|
||||
"cases, end height: %d\n", trancheIndex, len(testCases), height)
|
||||
}
|
||||
|
|
|
@ -372,7 +372,7 @@ func fundChanAndCloseFromImportedAccount(ht *lntest.HarnessTest, srcNode,
|
|||
)
|
||||
|
||||
block := ht.MineBlocksAndAssertNumTxes(6, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, txHash)
|
||||
ht.AssertTxInBlock(block, txHash)
|
||||
|
||||
confBalanceAfterChan += chanChangeUtxoAmt
|
||||
ht.AssertWalletAccountBalance(srcNode, account, 0, 0)
|
||||
|
@ -389,7 +389,7 @@ func fundChanAndCloseFromImportedAccount(ht *lntest.HarnessTest, srcNode,
|
|||
)
|
||||
|
||||
block := ht.MineBlocksAndAssertNumTxes(6, 1)[0]
|
||||
ht.Miner.AssertTxInBlock(block, txHash)
|
||||
ht.AssertTxInBlock(block, txHash)
|
||||
|
||||
confBalanceAfterChan += chanChangeUtxoAmt
|
||||
ht.AssertWalletAccountBalance(
|
||||
|
|
|
@ -86,7 +86,7 @@ func testTowerClientTowerAndSessionManagement(ht *lntest.HarnessTest) {
|
|||
}
|
||||
|
||||
if mineOnFail {
|
||||
ht.Miner.MineBlocksSlow(1)
|
||||
ht.MineBlocks(1)
|
||||
}
|
||||
|
||||
return fmt.Errorf("expected %d sessions, got %d",
|
||||
|
@ -502,7 +502,7 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntest.HarnessTest,
|
|||
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||
|
||||
breachTXID := ht.WaitForChannelCloseEvent(closeUpdates)
|
||||
ht.Miner.AssertTxInBlock(block, breachTXID)
|
||||
ht.AssertTxInBlock(block, breachTXID)
|
||||
|
||||
// The breachTXID should match the above closeTxID.
|
||||
require.EqualValues(ht, breachTXID, closeTxID)
|
||||
|
@ -510,12 +510,12 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntest.HarnessTest,
|
|||
// Query the mempool for Dave's justice transaction, this should be
|
||||
// broadcast as Carol's contract breaching transaction gets confirmed
|
||||
// above.
|
||||
justiceTXID := ht.Miner.AssertNumTxsInMempool(1)[0]
|
||||
justiceTXID := ht.AssertNumTxsInMempool(1)[0]
|
||||
|
||||
// Query for the mempool transaction found above. Then assert that all
|
||||
// the inputs of this transaction are spending outputs generated by
|
||||
// Carol's breach transaction above.
|
||||
justiceTx := ht.Miner.GetRawTransaction(justiceTXID)
|
||||
justiceTx := ht.GetRawTransaction(justiceTXID)
|
||||
for _, txIn := range justiceTx.MsgTx().TxIn {
|
||||
require.Equal(ht, breachTXID[:], txIn.PreviousOutPoint.Hash[:],
|
||||
"justice tx not spending commitment utxo")
|
||||
|
@ -702,7 +702,7 @@ func assertNumBackups(ht *lntest.HarnessTest, node *rpc.HarnessRPC,
|
|||
}
|
||||
|
||||
if mineOnFail {
|
||||
ht.Miner.MineBlocksSlow(1)
|
||||
ht.MineBlocks(1)
|
||||
}
|
||||
|
||||
return fmt.Errorf("expected %d backups, got %d",
|
||||
|
|
|
@ -110,7 +110,7 @@ func testZeroConfChannelOpen(ht *lntest.HarnessTest) {
|
|||
|
||||
fundingTxID := ht.GetChanPointFundingTxid(fundingPoint2)
|
||||
|
||||
ht.Miner.AssertTxInBlock(block, fundingTxID)
|
||||
ht.AssertTxInBlock(block, fundingTxID)
|
||||
|
||||
daveInvoiceResp3 := dave.RPC.AddInvoice(daveInvoiceParams)
|
||||
ht.CompletePaymentRequests(
|
||||
|
@ -159,7 +159,7 @@ func testZeroConfChannelOpen(ht *lntest.HarnessTest) {
|
|||
block = ht.MineBlocksAndAssertNumTxes(6, 1)[0]
|
||||
|
||||
fundingTxID = ht.GetChanPointFundingTxid(fundingPoint3)
|
||||
ht.Miner.AssertTxInBlock(block, fundingTxID)
|
||||
ht.AssertTxInBlock(block, fundingTxID)
|
||||
|
||||
// Wait until Eve's ZeroConf channel is replaced by the confirmed SCID
|
||||
// in her graph.
|
||||
|
@ -950,7 +950,7 @@ func testZeroConfReorg(ht *lntest.HarnessTest) {
|
|||
// exists in the graph.
|
||||
//
|
||||
// First, we'll setup a new miner that we can use to cause a reorg.
|
||||
tempMiner := ht.Miner.SpawnTempMiner()
|
||||
tempMiner := ht.SpawnTempMiner()
|
||||
|
||||
// We now cause a fork, by letting our original miner mine 1 block and
|
||||
// our new miner will mine 2. We also expect the funding transition to
|
||||
|
@ -959,10 +959,10 @@ func testZeroConfReorg(ht *lntest.HarnessTest) {
|
|||
tempMiner.MineEmptyBlocks(2)
|
||||
|
||||
// Ensure the temp miner is one block ahead.
|
||||
ht.Miner.AssertMinerBlockHeightDelta(tempMiner, 1)
|
||||
ht.AssertMinerBlockHeightDelta(tempMiner, 1)
|
||||
|
||||
// Wait for Carol to sync to the original miner's chain.
|
||||
_, minerHeight := ht.Miner.GetBestBlock()
|
||||
minerHeight := int32(ht.CurrentHeight())
|
||||
ht.WaitForNodeBlockHeight(carol, minerHeight)
|
||||
|
||||
// Now we'll disconnect Carol's chain backend from the original miner
|
||||
|
@ -972,14 +972,14 @@ func testZeroConfReorg(ht *lntest.HarnessTest) {
|
|||
|
||||
// Connecting to the temporary miner should cause the original miner to
|
||||
// reorg to the longer chain.
|
||||
ht.Miner.ConnectMiner(tempMiner)
|
||||
ht.ConnectToMiner(tempMiner)
|
||||
|
||||
// They should now be on the same chain.
|
||||
ht.Miner.AssertMinerBlockHeightDelta(tempMiner, 0)
|
||||
ht.AssertMinerBlockHeightDelta(tempMiner, 0)
|
||||
|
||||
// Now we disconnect the two miners and reconnect our original chain
|
||||
// backend.
|
||||
ht.Miner.DisconnectMiner(tempMiner)
|
||||
ht.DisconnectFromMiner(tempMiner)
|
||||
|
||||
ht.ConnectMiner()
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/integration/rpctest"
|
||||
"github.com/btcsuite/btcd/rpcclient"
|
||||
"github.com/lightningnetwork/lnd/lntest/miner"
|
||||
"github.com/lightningnetwork/lnd/lntest/node"
|
||||
)
|
||||
|
||||
|
@ -53,12 +54,14 @@ func (b BtcdBackendConfig) GenArgs() []string {
|
|||
|
||||
// ConnectMiner is called to establish a connection to the test miner.
|
||||
func (b BtcdBackendConfig) ConnectMiner() error {
|
||||
return b.harness.Client.Node(btcjson.NConnect, b.minerAddr, &temp)
|
||||
return b.harness.Client.Node(btcjson.NConnect, b.minerAddr, &miner.Temp)
|
||||
}
|
||||
|
||||
// DisconnectMiner is called to disconnect the miner.
|
||||
func (b BtcdBackendConfig) DisconnectMiner() error {
|
||||
return b.harness.Client.Node(btcjson.NDisconnect, b.minerAddr, &temp)
|
||||
return b.harness.Client.Node(
|
||||
btcjson.NDisconnect, b.minerAddr, &miner.Temp,
|
||||
)
|
||||
}
|
||||
|
||||
// Credentials returns the rpc username, password and host for the backend.
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
|
||||
"github.com/lightningnetwork/lnd/lntest/miner"
|
||||
"github.com/lightningnetwork/lnd/lntest/node"
|
||||
"github.com/lightningnetwork/lnd/lntest/rpc"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
|
@ -76,9 +77,9 @@ type HarnessTest struct {
|
|||
// Embed the standbyNodes so we can easily access them via `ht.Alice`.
|
||||
standbyNodes
|
||||
|
||||
// Miner is a reference to a running full node that can be used to
|
||||
// miner is a reference to a running full node that can be used to
|
||||
// create new blocks on the network.
|
||||
Miner *HarnessMiner
|
||||
miner *miner.HarnessMiner
|
||||
|
||||
// manager handles the start and stop of a given node.
|
||||
manager *nodeManager
|
||||
|
@ -104,6 +105,9 @@ type HarnessTest struct {
|
|||
// cleaned specifies whether the cleanup has been applied for the
|
||||
// current HarnessTest.
|
||||
cleaned bool
|
||||
|
||||
// currentHeight is the current height of the chain backend.
|
||||
currentHeight uint32
|
||||
}
|
||||
|
||||
// harnessOpts contains functional option to modify the behavior of the various
|
||||
|
@ -158,7 +162,9 @@ func NewHarnessTest(t *testing.T, lndBinary string, feeService WebFeeService,
|
|||
|
||||
// Start will assemble the chain backend and the miner for the HarnessTest. It
|
||||
// also starts the fee service and watches lnd process error.
|
||||
func (h *HarnessTest) Start(chain node.BackendConfig, miner *HarnessMiner) {
|
||||
func (h *HarnessTest) Start(chain node.BackendConfig,
|
||||
miner *miner.HarnessMiner) {
|
||||
|
||||
// Spawn a new goroutine to watch for any fatal errors that any of the
|
||||
// running lnd processes encounter. If an error occurs, then the test
|
||||
// case should naturally as a result and we log the server error here
|
||||
|
@ -185,7 +191,7 @@ func (h *HarnessTest) Start(chain node.BackendConfig, miner *HarnessMiner) {
|
|||
h.manager.feeServiceURL = h.feeService.URL()
|
||||
|
||||
// Assemble the miner.
|
||||
h.Miner = miner
|
||||
h.miner = miner
|
||||
}
|
||||
|
||||
// ChainBackendName returns the chain backend name used in the test.
|
||||
|
@ -251,7 +257,7 @@ func (h *HarnessTest) createAndSendOutput(target *node.HarnessNode,
|
|||
PkScript: addrScript,
|
||||
Value: int64(amt),
|
||||
}
|
||||
h.Miner.SendOutput(output, defaultMinerFeeRate)
|
||||
h.miner.SendOutput(output, defaultMinerFeeRate)
|
||||
}
|
||||
|
||||
// SetupRemoteSigningStandbyNodes starts the initial seeder nodes within the
|
||||
|
@ -353,11 +359,6 @@ func (h *HarnessTest) Stop() {
|
|||
return
|
||||
}
|
||||
|
||||
// Stop all running nodes.
|
||||
for _, node := range h.manager.activeNodes {
|
||||
h.Shutdown(node)
|
||||
}
|
||||
|
||||
close(h.lndErrorChan)
|
||||
|
||||
// Stop the fee service.
|
||||
|
@ -368,7 +369,7 @@ func (h *HarnessTest) Stop() {
|
|||
h.stopChainBackend()
|
||||
|
||||
// Stop the miner.
|
||||
h.Miner.Stop()
|
||||
h.miner.Stop()
|
||||
}
|
||||
|
||||
// RunTestCase executes a harness test case. Any errors or panics will be
|
||||
|
@ -411,7 +412,7 @@ func (h *HarnessTest) Subtest(t *testing.T) *HarnessTest {
|
|||
st := &HarnessTest{
|
||||
T: t,
|
||||
manager: h.manager,
|
||||
Miner: h.Miner,
|
||||
miner: h.miner,
|
||||
standbyNodes: h.standbyNodes,
|
||||
feeService: h.feeService,
|
||||
lndErrorChan: make(chan error, lndErrorChanSize),
|
||||
|
@ -421,7 +422,7 @@ func (h *HarnessTest) Subtest(t *testing.T) *HarnessTest {
|
|||
st.runCtx, st.cancel = context.WithCancel(h.runCtx)
|
||||
|
||||
// Inherit the subtest for the miner.
|
||||
st.Miner.T = st.T
|
||||
st.miner.T = st.T
|
||||
|
||||
// Reset the standby nodes.
|
||||
st.resetStandbyNodes(t)
|
||||
|
@ -430,10 +431,11 @@ func (h *HarnessTest) Subtest(t *testing.T) *HarnessTest {
|
|||
st.feeService.Reset()
|
||||
|
||||
// Record block height.
|
||||
_, startHeight := h.Miner.GetBestBlock()
|
||||
h.updateCurrentHeight()
|
||||
startHeight := int32(h.CurrentHeight())
|
||||
|
||||
st.Cleanup(func() {
|
||||
_, endHeight := h.Miner.GetBestBlock()
|
||||
_, endHeight := h.GetBestBlock()
|
||||
|
||||
st.Logf("finished test: %s, start height=%d, end height=%d, "+
|
||||
"mined blocks=%d", st.manager.currentTestCase,
|
||||
|
@ -464,7 +466,7 @@ func (h *HarnessTest) Subtest(t *testing.T) *HarnessTest {
|
|||
st.shutdownNonStandbyNodes()
|
||||
|
||||
// We require the mempool to be cleaned from the test.
|
||||
require.Empty(st, st.Miner.GetRawMempool(), "mempool not "+
|
||||
require.Empty(st, st.miner.GetRawMempool(), "mempool not "+
|
||||
"cleaned, please mine blocks to clean them all.")
|
||||
|
||||
// Finally, cancel the run context. We have to do it here
|
||||
|
@ -1190,7 +1192,7 @@ func (h *HarnessTest) openChannel(alice, bob *node.HarnessNode,
|
|||
|
||||
// Check that the funding tx is found in the first block.
|
||||
fundingTxID := h.GetChanPointFundingTxid(fundingChanPoint)
|
||||
h.Miner.AssertTxInBlock(block, fundingTxID)
|
||||
h.AssertTxInBlock(block, fundingTxID)
|
||||
|
||||
// Check that both alice and bob have seen the channel from their
|
||||
// network topology.
|
||||
|
@ -1295,7 +1297,7 @@ func (h *HarnessTest) CloseChannelAssertPending(hn *node.HarnessNode,
|
|||
pendingClose.ClosePending.Txid)
|
||||
|
||||
// Assert the closing tx is in the mempool.
|
||||
h.Miner.AssertTxInMempool(closeTxid)
|
||||
h.miner.AssertTxInMempool(closeTxid)
|
||||
|
||||
return stream, closeTxid
|
||||
}
|
||||
|
@ -1393,7 +1395,7 @@ func (h *HarnessTest) fundCoins(amt btcutil.Amount, target *node.HarnessNode,
|
|||
PkScript: addrScript,
|
||||
Value: int64(amt),
|
||||
}
|
||||
h.Miner.SendOutput(output, defaultMinerFeeRate)
|
||||
h.miner.SendOutput(output, defaultMinerFeeRate)
|
||||
|
||||
// Encode the pkScript in hex as this the format that it will be
|
||||
// returned via rpc.
|
||||
|
@ -1411,24 +1413,24 @@ func (h *HarnessTest) fundCoins(amt btcutil.Amount, target *node.HarnessNode,
|
|||
pkScriptStr := utxos[0].PkScript
|
||||
require.Equal(h, pkScriptStr, expPkScriptStr,
|
||||
"pkscript mismatch")
|
||||
|
||||
expectedBalance := btcutil.Amount(
|
||||
initialBalance.UnconfirmedBalance,
|
||||
) + amt
|
||||
h.WaitForBalanceUnconfirmed(target, expectedBalance)
|
||||
}
|
||||
|
||||
// If the transaction should remain unconfirmed, then we'll wait until
|
||||
// the target node's unconfirmed balance reflects the expected balance
|
||||
// and exit.
|
||||
if !confirmed && !h.IsNeutrinoBackend() {
|
||||
expectedBalance := btcutil.Amount(
|
||||
initialBalance.UnconfirmedBalance,
|
||||
) + amt
|
||||
h.WaitForBalanceUnconfirmed(target, expectedBalance)
|
||||
|
||||
if !confirmed {
|
||||
return
|
||||
}
|
||||
|
||||
// Otherwise, we'll generate 1 new blocks to ensure the output gains a
|
||||
// sufficient number of confirmations and wait for the balance to
|
||||
// reflect what's expected.
|
||||
h.MineBlocks(1)
|
||||
h.MineBlocksAndAssertNumTxes(1, 1)
|
||||
|
||||
expectedBalance := btcutil.Amount(initialBalance.ConfirmedBalance) + amt
|
||||
h.WaitForBalanceConfirmed(target, expectedBalance)
|
||||
|
@ -1599,7 +1601,7 @@ func (h *HarnessTest) OpenChannelPsbt(srcNode, destNode *node.HarnessNode,
|
|||
// Make sure the channel funding address has the correct type for the
|
||||
// given commitment type.
|
||||
fundingAddr, err := btcutil.DecodeAddress(
|
||||
upd.PsbtFund.FundingAddress, harnessNetParams,
|
||||
upd.PsbtFund.FundingAddress, miner.HarnessNetParams,
|
||||
)
|
||||
require.NoError(h, err)
|
||||
|
||||
|
@ -1646,40 +1648,6 @@ func (h *HarnessTest) CleanupForceClose(hn *node.HarnessNode) {
|
|||
h.mineTillForceCloseResolved(hn)
|
||||
}
|
||||
|
||||
// mineTillForceCloseResolved asserts that the number of pending close channels
|
||||
// are zero. Each time it checks, a new block is mined using MineBlocksSlow to
|
||||
// give the node some time to catch up the chain.
|
||||
//
|
||||
// NOTE: this method is a workaround to make sure we have a clean mempool at
|
||||
// the end of a channel force closure. We cannot directly mine blocks and
|
||||
// assert channels being fully closed because the subsystems in lnd don't share
|
||||
// the same block height. This is especially the case when blocks are produced
|
||||
// too fast.
|
||||
// TODO(yy): remove this workaround when syncing blocks are unified in all the
|
||||
// subsystems.
|
||||
func (h *HarnessTest) mineTillForceCloseResolved(hn *node.HarnessNode) {
|
||||
_, startHeight := h.Miner.GetBestBlock()
|
||||
|
||||
err := wait.NoError(func() error {
|
||||
resp := hn.RPC.PendingChannels()
|
||||
total := len(resp.PendingForceClosingChannels)
|
||||
if total != 0 {
|
||||
h.MineBlocks(1)
|
||||
|
||||
return fmt.Errorf("expected num of pending force " +
|
||||
"close channel to be zero")
|
||||
}
|
||||
|
||||
_, height := h.Miner.GetBestBlock()
|
||||
h.Logf("Mined %d blocks while waiting for force closed "+
|
||||
"channel to be resolved", height-startHeight)
|
||||
|
||||
return nil
|
||||
}, DefaultTimeout)
|
||||
|
||||
require.NoErrorf(h, err, "assert force close resolved timeout")
|
||||
}
|
||||
|
||||
// CreatePayReqs is a helper method that will create a slice of payment
|
||||
// requests for the given node.
|
||||
func (h *HarnessTest) CreatePayReqs(hn *node.HarnessNode,
|
||||
|
@ -1739,92 +1707,6 @@ func (h *HarnessTest) RestartNodeAndRestoreDB(hn *node.HarnessNode) {
|
|||
h.WaitForBlockchainSync(hn)
|
||||
}
|
||||
|
||||
// MineBlocks mines blocks and asserts all active nodes have synced to the
|
||||
// chain.
|
||||
//
|
||||
// NOTE: this differs from miner's `MineBlocks` as it requires the nodes to be
|
||||
// synced.
|
||||
func (h *HarnessTest) MineBlocks(num uint32) []*wire.MsgBlock {
|
||||
require.Less(h, num, uint32(maxBlocksAllowed),
|
||||
"too many blocks to mine")
|
||||
|
||||
// Mining the blocks slow to give `lnd` more time to sync.
|
||||
blocks := h.Miner.MineBlocksSlow(num)
|
||||
|
||||
// Make sure all the active nodes are synced.
|
||||
bestBlock := blocks[len(blocks)-1]
|
||||
h.AssertActiveNodesSyncedTo(bestBlock)
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// MineBlocksAndAssertNumTxes mines blocks and asserts the number of
|
||||
// transactions are found in the first block. It also asserts all active nodes
|
||||
// have synced to the chain.
|
||||
//
|
||||
// NOTE: this differs from miner's `MineBlocks` as it requires the nodes to be
|
||||
// synced.
|
||||
//
|
||||
// TODO(yy): change the APIs to force callers to think about blocks and txns:
|
||||
// - MineBlocksAndAssertNumTxes -> MineBlocks
|
||||
// - add more APIs to mine a single tx.
|
||||
func (h *HarnessTest) MineBlocksAndAssertNumTxes(num uint32,
|
||||
numTxs int) []*wire.MsgBlock {
|
||||
|
||||
// If we expect transactions to be included in the blocks we'll mine,
|
||||
// we wait here until they are seen in the miner's mempool.
|
||||
txids := h.Miner.AssertNumTxsInMempool(numTxs)
|
||||
|
||||
// Mine blocks.
|
||||
blocks := h.Miner.MineBlocksSlow(num)
|
||||
|
||||
// Assert that all the transactions were included in the first block.
|
||||
for _, txid := range txids {
|
||||
h.Miner.AssertTxInBlock(blocks[0], txid)
|
||||
}
|
||||
|
||||
// Make sure the mempool has been updated.
|
||||
for _, txid := range txids {
|
||||
h.Miner.AssertTxNotInMempool(*txid)
|
||||
}
|
||||
|
||||
// Finally, make sure all the active nodes are synced.
|
||||
bestBlock := blocks[len(blocks)-1]
|
||||
h.AssertActiveNodesSyncedTo(bestBlock)
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// cleanMempool mines blocks till the mempool is empty and asserts all active
|
||||
// nodes have synced to the chain.
|
||||
func (h *HarnessTest) cleanMempool() {
|
||||
_, startHeight := h.Miner.GetBestBlock()
|
||||
|
||||
// Mining the blocks slow to give `lnd` more time to sync.
|
||||
var bestBlock *wire.MsgBlock
|
||||
err := wait.NoError(func() error {
|
||||
// If mempool is empty, exit.
|
||||
mem := h.Miner.GetRawMempool()
|
||||
if len(mem) == 0 {
|
||||
_, height := h.Miner.GetBestBlock()
|
||||
h.Logf("Mined %d blocks when cleanup the mempool",
|
||||
height-startHeight)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise mine a block.
|
||||
blocks := h.Miner.MineBlocksSlow(1)
|
||||
bestBlock = blocks[len(blocks)-1]
|
||||
|
||||
// Make sure all the active nodes are synced.
|
||||
h.AssertActiveNodesSyncedTo(bestBlock)
|
||||
|
||||
return fmt.Errorf("still have %d txes in mempool", len(mem))
|
||||
}, wait.MinerMempoolTimeout)
|
||||
require.NoError(h, err, "timeout cleaning up mempool")
|
||||
}
|
||||
|
||||
// CleanShutDown is used to quickly end a test by shutting down all non-standby
|
||||
// nodes and mining blocks to empty the mempool.
|
||||
//
|
||||
|
@ -1840,21 +1722,6 @@ func (h *HarnessTest) CleanShutDown() {
|
|||
h.cleanMempool()
|
||||
}
|
||||
|
||||
// MineEmptyBlocks mines a given number of empty blocks.
|
||||
//
|
||||
// NOTE: this differs from miner's `MineEmptyBlocks` as it requires the nodes
|
||||
// to be synced.
|
||||
func (h *HarnessTest) MineEmptyBlocks(num int) []*wire.MsgBlock {
|
||||
require.Less(h, num, maxBlocksAllowed, "too many blocks to mine")
|
||||
|
||||
blocks := h.Miner.MineEmptyBlocks(num)
|
||||
|
||||
// Finally, make sure all the active nodes are synced.
|
||||
h.AssertActiveNodesSynced()
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// QueryChannelByChanPoint tries to find a channel matching the channel point
|
||||
// and asserts. It returns the channel found.
|
||||
func (h *HarnessTest) QueryChannelByChanPoint(hn *node.HarnessNode,
|
||||
|
@ -2035,7 +1902,7 @@ func (h *HarnessTest) CalculateTxFee(tx *wire.MsgTx) btcutil.Amount {
|
|||
var balance btcutil.Amount
|
||||
for _, in := range tx.TxIn {
|
||||
parentHash := in.PreviousOutPoint.Hash
|
||||
rawTx := h.Miner.GetRawTransaction(&parentHash)
|
||||
rawTx := h.miner.GetRawTransaction(&parentHash)
|
||||
parent := rawTx.MsgTx()
|
||||
value := parent.TxOut[in.PreviousOutPoint.Index].Value
|
||||
|
||||
|
@ -2147,19 +2014,6 @@ func findSweepInDetails(ht *HarnessTest, sweepTxid string,
|
|||
return false
|
||||
}
|
||||
|
||||
// ConnectMiner connects the miner with the chain backend in the network.
|
||||
func (h *HarnessTest) ConnectMiner() {
|
||||
err := h.manager.chainBackend.ConnectMiner()
|
||||
require.NoError(h, err, "failed to connect miner")
|
||||
}
|
||||
|
||||
// DisconnectMiner removes the connection between the miner and the chain
|
||||
// backend in the network.
|
||||
func (h *HarnessTest) DisconnectMiner() {
|
||||
err := h.manager.chainBackend.DisconnectMiner()
|
||||
require.NoError(h, err, "failed to disconnect miner")
|
||||
}
|
||||
|
||||
// QueryRoutesAndRetry attempts to keep querying a route until timeout is
|
||||
// reached.
|
||||
//
|
||||
|
@ -2266,12 +2120,12 @@ func (h *HarnessTest) ReceiveChannelEvent(
|
|||
func (h *HarnessTest) GetOutputIndex(txid *chainhash.Hash, addr string) int {
|
||||
// We'll then extract the raw transaction from the mempool in order to
|
||||
// determine the index of the p2tr output.
|
||||
tx := h.Miner.GetRawTransaction(txid)
|
||||
tx := h.miner.GetRawTransaction(txid)
|
||||
|
||||
p2trOutputIndex := -1
|
||||
for i, txOut := range tx.MsgTx().TxOut {
|
||||
_, addrs, _, err := txscript.ExtractPkScriptAddrs(
|
||||
txOut.PkScript, h.Miner.ActiveNet,
|
||||
txOut.PkScript, h.miner.ActiveNet,
|
||||
)
|
||||
require.NoError(h, err)
|
||||
|
||||
|
@ -2303,7 +2157,7 @@ func (h *HarnessTest) SendCoins(a, b *node.HarnessNode,
|
|||
TargetConf: 6,
|
||||
}
|
||||
a.RPC.SendCoins(sendReq)
|
||||
tx := h.Miner.GetNumTxsFromMempool(1)[0]
|
||||
tx := h.GetNumTxsFromMempool(1)[0]
|
||||
|
||||
return tx
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
|
||||
"github.com/lightningnetwork/lnd/lntest/miner"
|
||||
"github.com/lightningnetwork/lnd/lntest/node"
|
||||
"github.com/lightningnetwork/lnd/lntest/rpc"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
|
@ -655,7 +656,7 @@ func (h *HarnessTest) AssertStreamChannelCoopClosed(hn *node.HarnessNode,
|
|||
// Consume one close event and assert the closing txid can be found in
|
||||
// the block.
|
||||
closingTxid := h.WaitForChannelCloseEvent(stream)
|
||||
h.Miner.AssertTxInBlock(block, closingTxid)
|
||||
h.AssertTxInBlock(block, closingTxid)
|
||||
|
||||
// We should see zero waiting close channels now.
|
||||
h.AssertNumWaitingClose(hn, 0)
|
||||
|
@ -699,7 +700,7 @@ func (h *HarnessTest) AssertStreamChannelForceClosed(hn *node.HarnessNode,
|
|||
// Consume one close event and assert the closing txid can be found in
|
||||
// the block.
|
||||
closingTxid := h.WaitForChannelCloseEvent(stream)
|
||||
h.Miner.AssertTxInBlock(block, closingTxid)
|
||||
h.AssertTxInBlock(block, closingTxid)
|
||||
|
||||
// We should see zero waiting close channels and 1 pending force close
|
||||
// channels now.
|
||||
|
@ -784,8 +785,13 @@ func (h *HarnessTest) AssertNumUTXOsWithConf(hn *node.HarnessNode,
|
|||
return nil
|
||||
}
|
||||
|
||||
desc := "has UTXOs:\n"
|
||||
for _, utxo := range resp.Utxos {
|
||||
desc += fmt.Sprintf("%v\n", utxo)
|
||||
}
|
||||
|
||||
return errNumNotMatched(hn.Name(), "num of UTXOs",
|
||||
expectedUtxos, total-old, total, old)
|
||||
expectedUtxos, total-old, total, old, desc)
|
||||
}, DefaultTimeout)
|
||||
require.NoError(h, err, "timeout waiting for UTXOs")
|
||||
|
||||
|
@ -937,7 +943,7 @@ func (h *HarnessTest) RandomPreimage() lntypes.Preimage {
|
|||
|
||||
// DecodeAddress decodes a given address and asserts there's no error.
|
||||
func (h *HarnessTest) DecodeAddress(addr string) btcutil.Address {
|
||||
resp, err := btcutil.DecodeAddress(addr, harnessNetParams)
|
||||
resp, err := btcutil.DecodeAddress(addr, miner.HarnessNetParams)
|
||||
require.NoError(h, err, "DecodeAddress failed")
|
||||
|
||||
return resp
|
||||
|
@ -2015,6 +2021,7 @@ func (h *HarnessTest) CreateBurnAddr(addrType lnrpc.AddressType) ([]byte,
|
|||
require.NoError(h, err)
|
||||
|
||||
randomKeyBytes := randomPrivKey.PubKey().SerializeCompressed()
|
||||
harnessNetParams := miner.HarnessNetParams
|
||||
|
||||
var addr btcutil.Address
|
||||
switch addrType {
|
||||
|
@ -2562,11 +2569,11 @@ func (h *HarnessTest) AssertClosingTxInMempool(cp *lnrpc.ChannelPoint,
|
|||
}
|
||||
|
||||
// Wait for the expected txes to be found in the mempool.
|
||||
h.Miner.AssertNumTxsInMempool(expectedTxes)
|
||||
h.AssertNumTxsInMempool(expectedTxes)
|
||||
|
||||
// Get the closing tx from the mempool.
|
||||
op := h.OutPointFromChannelPoint(cp)
|
||||
closeTx := h.Miner.AssertOutpointInMempool(op)
|
||||
closeTx := h.AssertOutpointInMempool(op)
|
||||
|
||||
return closeTx
|
||||
}
|
||||
|
@ -2576,11 +2583,11 @@ func (h *HarnessTest) AssertClosingTxInMempool(cp *lnrpc.ChannelPoint,
|
|||
// will assert the anchor sweep tx is also in the mempool.
|
||||
func (h *HarnessTest) MineClosingTx(cp *lnrpc.ChannelPoint) *wire.MsgTx {
|
||||
// Wait for the expected txes to be found in the mempool.
|
||||
h.Miner.AssertNumTxsInMempool(1)
|
||||
h.AssertNumTxsInMempool(1)
|
||||
|
||||
// Get the closing tx from the mempool.
|
||||
op := h.OutPointFromChannelPoint(cp)
|
||||
closeTx := h.Miner.AssertOutpointInMempool(op)
|
||||
closeTx := h.AssertOutpointInMempool(op)
|
||||
|
||||
// Mine a block to confirm the closing transaction and potential anchor
|
||||
// sweep.
|
||||
|
|
|
@ -1,311 +1,208 @@
|
|||
package lntest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcjson"
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/integration/rpctest"
|
||||
"github.com/btcsuite/btcd/rpcclient"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/lntest/miner"
|
||||
"github.com/lightningnetwork/lnd/lntest/node"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
// minerLogFilename is the default log filename for the miner node.
|
||||
minerLogFilename = "output_btcd_miner.log"
|
||||
|
||||
// minerLogDir is the default log dir for the miner node.
|
||||
minerLogDir = ".minerlogs"
|
||||
|
||||
// slowMineDelay defines a wait period between mining new blocks.
|
||||
slowMineDelay = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
var (
|
||||
harnessNetParams = &chaincfg.RegressionNetParams
|
||||
|
||||
// temp is used to signal we want to establish a temporary connection
|
||||
// using the btcd Node API.
|
||||
//
|
||||
// NOTE: Cannot be const, since the node API expects a reference.
|
||||
temp = "temp"
|
||||
)
|
||||
|
||||
type HarnessMiner struct {
|
||||
*testing.T
|
||||
*rpctest.Harness
|
||||
|
||||
// runCtx is a context with cancel method. It's used to signal when the
|
||||
// node needs to quit, and used as the parent context when spawning
|
||||
// children contexts for RPC requests.
|
||||
runCtx context.Context //nolint:containedctx
|
||||
cancel context.CancelFunc
|
||||
|
||||
// logPath is the directory path of the miner's logs.
|
||||
logPath string
|
||||
|
||||
// logFilename is the saved log filename of the miner node.
|
||||
logFilename string
|
||||
// Miner returns the miner instance.
|
||||
//
|
||||
// NOTE: Caller should keep in mind that when using this private instance,
|
||||
// certain states won't be managed by the HarnessTest anymore. For instance,
|
||||
// when mining directly, the nodes managed by the HarnessTest can be out of
|
||||
// sync, and the `HarnessTest.CurrentHeight()` won't be accurate.
|
||||
func (h *HarnessTest) Miner() *miner.HarnessMiner {
|
||||
return h.miner
|
||||
}
|
||||
|
||||
// NewMiner creates a new miner using btcd backend with the default log file
|
||||
// dir and name.
|
||||
func NewMiner(ctxt context.Context, t *testing.T) *HarnessMiner {
|
||||
t.Helper()
|
||||
return newMiner(ctxt, t, minerLogDir, minerLogFilename)
|
||||
}
|
||||
// MineBlocks mines blocks and asserts all active nodes have synced to the
|
||||
// chain. It assumes no txns are expected in the blocks.
|
||||
//
|
||||
// NOTE: Use `MineBlocksAndAssertNumTxes` if you expect txns in the blocks. Use
|
||||
// `MineEmptyBlocks` if you want to make sure that txns stay unconfirmed.
|
||||
func (h *HarnessTest) MineBlocks(num int) {
|
||||
require.Less(h, num, maxBlocksAllowed, "too many blocks to mine")
|
||||
|
||||
// NewTempMiner creates a new miner using btcd backend with the specified log
|
||||
// file dir and name.
|
||||
func NewTempMiner(ctxt context.Context, t *testing.T,
|
||||
tempDir, tempLogFilename string) *HarnessMiner {
|
||||
// Update the harness's current height.
|
||||
defer h.updateCurrentHeight()
|
||||
|
||||
t.Helper()
|
||||
// Mine num of blocks.
|
||||
for i := 0; i < num; i++ {
|
||||
block := h.miner.MineBlocks(1)[0]
|
||||
|
||||
return newMiner(ctxt, t, tempDir, tempLogFilename)
|
||||
}
|
||||
// Check the block doesn't have any txns except the coinbase.
|
||||
if len(block.Transactions) <= 1 {
|
||||
// Make sure all the active nodes are synced.
|
||||
h.AssertActiveNodesSyncedTo(block)
|
||||
|
||||
// newMiner creates a new miner using btcd's rpctest.
|
||||
func newMiner(ctxb context.Context, t *testing.T, minerDirName,
|
||||
logFilename string) *HarnessMiner {
|
||||
// Mine the next block.
|
||||
continue
|
||||
}
|
||||
|
||||
t.Helper()
|
||||
// Create a detailed description.
|
||||
desc := fmt.Sprintf("block %v has %d txns:\n",
|
||||
block.BlockHash(), len(block.Transactions)-1)
|
||||
|
||||
handler := &rpcclient.NotificationHandlers{}
|
||||
btcdBinary := node.GetBtcdBinary()
|
||||
baseLogPath := fmt.Sprintf("%s/%s", node.GetLogDir(), minerDirName)
|
||||
// Print all the txns except the coinbase.
|
||||
for _, tx := range block.Transactions {
|
||||
if blockchain.IsCoinBaseTx(tx) {
|
||||
continue
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"--rejectnonstd",
|
||||
"--txindex",
|
||||
"--nowinservice",
|
||||
"--nobanning",
|
||||
"--debuglevel=debug",
|
||||
"--logdir=" + baseLogPath,
|
||||
"--trickleinterval=100ms",
|
||||
// Don't disconnect if a reply takes too long.
|
||||
"--nostalldetect",
|
||||
}
|
||||
desc += fmt.Sprintf("%v\n", tx.TxHash())
|
||||
}
|
||||
|
||||
miner, err := rpctest.New(harnessNetParams, handler, args, btcdBinary)
|
||||
require.NoError(t, err, "unable to create mining node")
|
||||
desc += "Consider using `MineBlocksAndAssertNumTxes` if you " +
|
||||
"expect txns, or `MineEmptyBlocks` if you want to " +
|
||||
"keep the txns unconfirmed."
|
||||
|
||||
ctxt, cancel := context.WithCancel(ctxb)
|
||||
|
||||
return &HarnessMiner{
|
||||
T: t,
|
||||
Harness: miner,
|
||||
runCtx: ctxt,
|
||||
cancel: cancel,
|
||||
logPath: baseLogPath,
|
||||
logFilename: logFilename,
|
||||
// Raise an error if the block has txns.
|
||||
require.Fail(h, "MineBlocks", desc)
|
||||
}
|
||||
}
|
||||
|
||||
// saveLogs copies the node logs and save it to the file specified by
|
||||
// h.logFilename.
|
||||
func (h *HarnessMiner) saveLogs() {
|
||||
// After shutting down the miner, we'll make a copy of the log files
|
||||
// before deleting the temporary log dir.
|
||||
path := fmt.Sprintf("%s/%s", h.logPath, harnessNetParams.Name)
|
||||
files, err := os.ReadDir(path)
|
||||
require.NoError(h, err, "unable to read log directory")
|
||||
// MineEmptyBlocks mines a given number of empty blocks.
|
||||
//
|
||||
// NOTE: this differs from miner's `MineEmptyBlocks` as it requires the nodes
|
||||
// to be synced.
|
||||
func (h *HarnessTest) MineEmptyBlocks(num int) []*wire.MsgBlock {
|
||||
require.Less(h, num, maxBlocksAllowed, "too many blocks to mine")
|
||||
|
||||
for _, file := range files {
|
||||
newFilename := strings.Replace(
|
||||
file.Name(), "btcd.log", h.logFilename, 1,
|
||||
)
|
||||
copyPath := fmt.Sprintf("%s/../%s", h.logPath, newFilename)
|
||||
// Update the harness's current height.
|
||||
defer h.updateCurrentHeight()
|
||||
|
||||
logFile := fmt.Sprintf("%s/%s", path, file.Name())
|
||||
err := CopyFile(filepath.Clean(copyPath), logFile)
|
||||
require.NoError(h, err, "unable to copy file")
|
||||
}
|
||||
blocks := h.miner.MineEmptyBlocks(num)
|
||||
|
||||
err = os.RemoveAll(h.logPath)
|
||||
require.NoErrorf(h, err, "cannot remove dir %s", h.logPath)
|
||||
}
|
||||
|
||||
// Stop shuts down the miner and saves its logs.
|
||||
func (h *HarnessMiner) Stop() {
|
||||
h.cancel()
|
||||
require.NoError(h, h.TearDown(), "tear down miner got error")
|
||||
h.saveLogs()
|
||||
}
|
||||
|
||||
// GetBestBlock makes a RPC request to miner and asserts.
|
||||
func (h *HarnessMiner) GetBestBlock() (*chainhash.Hash, int32) {
|
||||
blockHash, height, err := h.Client.GetBestBlock()
|
||||
require.NoError(h, err, "failed to GetBestBlock")
|
||||
|
||||
return blockHash, height
|
||||
}
|
||||
|
||||
// GetRawMempool makes a RPC call to the miner's GetRawMempool and
|
||||
// asserts.
|
||||
func (h *HarnessMiner) GetRawMempool() []*chainhash.Hash {
|
||||
mempool, err := h.Client.GetRawMempool()
|
||||
require.NoError(h, err, "unable to get mempool")
|
||||
|
||||
return mempool
|
||||
}
|
||||
|
||||
// GenerateBlocks mine 'num' of blocks and returns them.
|
||||
func (h *HarnessMiner) GenerateBlocks(num uint32) []*chainhash.Hash {
|
||||
blockHashes, err := h.Client.Generate(num)
|
||||
require.NoError(h, err, "unable to generate blocks")
|
||||
require.Len(h, blockHashes, int(num), "wrong num of blocks generated")
|
||||
|
||||
return blockHashes
|
||||
}
|
||||
|
||||
// GetBlock gets a block using its block hash.
|
||||
func (h *HarnessMiner) GetBlock(blockHash *chainhash.Hash) *wire.MsgBlock {
|
||||
block, err := h.Client.GetBlock(blockHash)
|
||||
require.NoError(h, err, "unable to get block")
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
// MineBlocks mine 'num' of blocks and check that blocks are present in
|
||||
// node blockchain.
|
||||
func (h *HarnessMiner) MineBlocks(num uint32) []*wire.MsgBlock {
|
||||
blocks := make([]*wire.MsgBlock, num)
|
||||
|
||||
blockHashes := h.GenerateBlocks(num)
|
||||
|
||||
for i, blockHash := range blockHashes {
|
||||
block := h.GetBlock(blockHash)
|
||||
blocks[i] = block
|
||||
}
|
||||
// Finally, make sure all the active nodes are synced.
|
||||
h.AssertActiveNodesSynced()
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// AssertNumTxsInMempool polls until finding the desired number of transactions
|
||||
// in the provided miner's mempool. It will asserrt if this number is not met
|
||||
// after the given timeout.
|
||||
func (h *HarnessMiner) AssertNumTxsInMempool(n int) []*chainhash.Hash {
|
||||
var (
|
||||
mem []*chainhash.Hash
|
||||
err error
|
||||
)
|
||||
|
||||
err = wait.NoError(func() error {
|
||||
// We require the RPC call to be succeeded and won't wait for
|
||||
// it as it's an unexpected behavior.
|
||||
mem = h.GetRawMempool()
|
||||
if len(mem) == n {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("want %v, got %v in mempool: %v",
|
||||
n, len(mem), mem)
|
||||
}, wait.MinerMempoolTimeout)
|
||||
require.NoError(h, err, "assert tx in mempool timeout")
|
||||
|
||||
return mem
|
||||
}
|
||||
|
||||
// AssertTxInBlock asserts that a given txid can be found in the passed block.
|
||||
func (h *HarnessMiner) AssertTxInBlock(block *wire.MsgBlock,
|
||||
txid *chainhash.Hash) {
|
||||
|
||||
blockTxes := make([]chainhash.Hash, 0)
|
||||
|
||||
for _, tx := range block.Transactions {
|
||||
sha := tx.TxHash()
|
||||
blockTxes = append(blockTxes, sha)
|
||||
|
||||
if bytes.Equal(txid[:], sha[:]) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
require.Failf(h, "tx was not included in block", "tx:%v, block has:%v",
|
||||
txid, blockTxes)
|
||||
}
|
||||
|
||||
// MineBlocksAndAssertNumTxes mine 'num' of blocks and check that blocks are
|
||||
// present in node blockchain. numTxs should be set to the number of
|
||||
// transactions (excluding the coinbase) we expect to be included in the first
|
||||
// mined block.
|
||||
func (h *HarnessMiner) MineBlocksAndAssertNumTxes(num uint32,
|
||||
// MineBlocksAndAssertNumTxes mines blocks and asserts the number of
|
||||
// transactions are found in the first block. It also asserts all active nodes
|
||||
// have synced to the chain.
|
||||
//
|
||||
// NOTE: this differs from miner's `MineBlocks` as it requires the nodes to be
|
||||
// synced.
|
||||
func (h *HarnessTest) MineBlocksAndAssertNumTxes(num uint32,
|
||||
numTxs int) []*wire.MsgBlock {
|
||||
|
||||
// Update the harness's current height.
|
||||
defer h.updateCurrentHeight()
|
||||
|
||||
// If we expect transactions to be included in the blocks we'll mine,
|
||||
// we wait here until they are seen in the miner's mempool.
|
||||
txids := h.AssertNumTxsInMempool(numTxs)
|
||||
|
||||
// Mine blocks.
|
||||
blocks := h.MineBlocks(num)
|
||||
blocks := h.miner.MineBlocks(num)
|
||||
|
||||
// Finally, assert that all the transactions were included in the first
|
||||
// block.
|
||||
// Assert that all the transactions were included in the first block.
|
||||
for _, txid := range txids {
|
||||
h.AssertTxInBlock(blocks[0], txid)
|
||||
h.miner.AssertTxInBlock(blocks[0], txid)
|
||||
}
|
||||
|
||||
// Make sure the mempool has been updated.
|
||||
for _, txid := range txids {
|
||||
h.miner.AssertTxNotInMempool(*txid)
|
||||
}
|
||||
|
||||
// Finally, make sure all the active nodes are synced.
|
||||
bestBlock := blocks[len(blocks)-1]
|
||||
h.AssertActiveNodesSyncedTo(bestBlock)
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// GetRawTransaction makes a RPC call to the miner's GetRawTransaction and
|
||||
// asserts.
|
||||
func (h *HarnessMiner) GetRawTransaction(txid *chainhash.Hash) *btcutil.Tx {
|
||||
tx, err := h.Client.GetRawTransaction(txid)
|
||||
require.NoErrorf(h, err, "failed to get raw tx: %v", txid)
|
||||
return tx
|
||||
// ConnectMiner connects the miner with the chain backend in the network.
|
||||
func (h *HarnessTest) ConnectMiner() {
|
||||
err := h.manager.chainBackend.ConnectMiner()
|
||||
require.NoError(h, err, "failed to connect miner")
|
||||
}
|
||||
|
||||
// GetRawTransactionVerbose makes a RPC call to the miner's
|
||||
// GetRawTransactionVerbose and asserts.
|
||||
func (h *HarnessMiner) GetRawTransactionVerbose(
|
||||
txid *chainhash.Hash) *btcjson.TxRawResult {
|
||||
// DisconnectMiner removes the connection between the miner and the chain
|
||||
// backend in the network.
|
||||
func (h *HarnessTest) DisconnectMiner() {
|
||||
err := h.manager.chainBackend.DisconnectMiner()
|
||||
require.NoError(h, err, "failed to disconnect miner")
|
||||
}
|
||||
|
||||
tx, err := h.Client.GetRawTransactionVerbose(txid)
|
||||
require.NoErrorf(h, err, "failed to get raw tx verbose: %v", txid)
|
||||
return tx
|
||||
// cleanMempool mines blocks till the mempool is empty and asserts all active
|
||||
// nodes have synced to the chain.
|
||||
func (h *HarnessTest) cleanMempool() {
|
||||
_, startHeight := h.GetBestBlock()
|
||||
|
||||
// Mining the blocks slow to give `lnd` more time to sync.
|
||||
var bestBlock *wire.MsgBlock
|
||||
err := wait.NoError(func() error {
|
||||
// If mempool is empty, exit.
|
||||
mem := h.miner.GetRawMempool()
|
||||
if len(mem) == 0 {
|
||||
_, height := h.GetBestBlock()
|
||||
h.Logf("Mined %d blocks when cleanup the mempool",
|
||||
height-startHeight)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise mine a block.
|
||||
blocks := h.miner.MineBlocksSlow(1)
|
||||
bestBlock = blocks[len(blocks)-1]
|
||||
|
||||
// Make sure all the active nodes are synced.
|
||||
h.AssertActiveNodesSyncedTo(bestBlock)
|
||||
|
||||
return fmt.Errorf("still have %d txes in mempool", len(mem))
|
||||
}, wait.MinerMempoolTimeout)
|
||||
require.NoError(h, err, "timeout cleaning up mempool")
|
||||
}
|
||||
|
||||
// mineTillForceCloseResolved asserts that the number of pending close channels
|
||||
// are zero. Each time it checks, a new block is mined using MineBlocksSlow to
|
||||
// give the node some time to catch up the chain.
|
||||
//
|
||||
// NOTE: this method is a workaround to make sure we have a clean mempool at
|
||||
// the end of a channel force closure. We cannot directly mine blocks and
|
||||
// assert channels being fully closed because the subsystems in lnd don't share
|
||||
// the same block height. This is especially the case when blocks are produced
|
||||
// too fast.
|
||||
// TODO(yy): remove this workaround when syncing blocks are unified in all the
|
||||
// subsystems.
|
||||
func (h *HarnessTest) mineTillForceCloseResolved(hn *node.HarnessNode) {
|
||||
_, startHeight := h.GetBestBlock()
|
||||
|
||||
err := wait.NoError(func() error {
|
||||
resp := hn.RPC.PendingChannels()
|
||||
total := len(resp.PendingForceClosingChannels)
|
||||
if total != 0 {
|
||||
h.MineBlocks(1)
|
||||
|
||||
return fmt.Errorf("expected num of pending force " +
|
||||
"close channel to be zero")
|
||||
}
|
||||
|
||||
_, height := h.GetBestBlock()
|
||||
h.Logf("Mined %d blocks while waiting for force closed "+
|
||||
"channel to be resolved", height-startHeight)
|
||||
|
||||
return nil
|
||||
}, DefaultTimeout)
|
||||
|
||||
require.NoErrorf(h, err, "assert force close resolved timeout")
|
||||
}
|
||||
|
||||
// AssertTxInMempool asserts a given transaction can be found in the mempool.
|
||||
func (h *HarnessMiner) AssertTxInMempool(txid *chainhash.Hash) *wire.MsgTx {
|
||||
var msgTx *wire.MsgTx
|
||||
|
||||
err := wait.NoError(func() error {
|
||||
// We require the RPC call to be succeeded and won't wait for
|
||||
// it as it's an unexpected behavior.
|
||||
mempool := h.GetRawMempool()
|
||||
|
||||
if len(mempool) == 0 {
|
||||
return fmt.Errorf("empty mempool")
|
||||
}
|
||||
|
||||
for _, memTx := range mempool {
|
||||
// Check the values are equal.
|
||||
if *memTx == *txid {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("txid %v not found in mempool: %v", txid,
|
||||
mempool)
|
||||
}, wait.MinerMempoolTimeout)
|
||||
|
||||
require.NoError(h, err, "timeout checking mempool")
|
||||
|
||||
return msgTx
|
||||
func (h *HarnessTest) AssertTxInMempool(txid *chainhash.Hash) *wire.MsgTx {
|
||||
return h.miner.AssertTxInMempool(txid)
|
||||
}
|
||||
|
||||
// AssertTxNotInMempool asserts a given transaction cannot be found in the
|
||||
|
@ -314,289 +211,122 @@ func (h *HarnessMiner) AssertTxInMempool(txid *chainhash.Hash) *wire.MsgTx {
|
|||
// NOTE: this should be used after `AssertTxInMempool` to ensure the tx has
|
||||
// entered the mempool before. Otherwise it might give false positive and the
|
||||
// tx may enter the mempool after the check.
|
||||
func (h *HarnessMiner) AssertTxNotInMempool(txid chainhash.Hash) *wire.MsgTx {
|
||||
var msgTx *wire.MsgTx
|
||||
|
||||
err := wait.NoError(func() error {
|
||||
// We require the RPC call to be succeeded and won't wait for
|
||||
// it as it's an unexpected behavior.
|
||||
mempool := h.GetRawMempool()
|
||||
|
||||
for _, memTx := range mempool {
|
||||
// Check the values are equal.
|
||||
if txid.IsEqual(memTx) {
|
||||
return fmt.Errorf("expect txid %v to be NOT "+
|
||||
"found in mempool", txid)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, wait.MinerMempoolTimeout)
|
||||
|
||||
require.NoError(h, err, "timeout checking tx not in mempool")
|
||||
|
||||
return msgTx
|
||||
func (h *HarnessTest) AssertTxNotInMempool(txid chainhash.Hash) *wire.MsgTx {
|
||||
return h.miner.AssertTxNotInMempool(txid)
|
||||
}
|
||||
|
||||
// SendOutputsWithoutChange uses the miner to send the given outputs using the
|
||||
// specified fee rate and returns the txid.
|
||||
func (h *HarnessMiner) SendOutputsWithoutChange(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) *chainhash.Hash {
|
||||
|
||||
txid, err := h.Harness.SendOutputsWithoutChange(
|
||||
outputs, feeRate,
|
||||
)
|
||||
require.NoErrorf(h, err, "failed to send output")
|
||||
|
||||
return txid
|
||||
}
|
||||
|
||||
// CreateTransaction uses the miner to create a transaction using the given
|
||||
// outputs using the specified fee rate and returns the transaction.
|
||||
func (h *HarnessMiner) CreateTransaction(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) *wire.MsgTx {
|
||||
|
||||
tx, err := h.Harness.CreateTransaction(outputs, feeRate, false)
|
||||
require.NoErrorf(h, err, "failed to create transaction")
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
// SendOutput creates, signs, and finally broadcasts a transaction spending
|
||||
// the harness' available mature coinbase outputs to create the new output.
|
||||
func (h *HarnessMiner) SendOutput(newOutput *wire.TxOut,
|
||||
feeRate btcutil.Amount) *chainhash.Hash {
|
||||
|
||||
hash, err := h.Harness.SendOutputs([]*wire.TxOut{newOutput}, feeRate)
|
||||
require.NoErrorf(h, err, "failed to send outputs")
|
||||
|
||||
return hash
|
||||
}
|
||||
|
||||
// MineBlocksSlow mines 'num' of blocks. Between each mined block an artificial
|
||||
// delay is introduced to give all network participants time to catch up.
|
||||
func (h *HarnessMiner) MineBlocksSlow(num uint32) []*wire.MsgBlock {
|
||||
blocks := make([]*wire.MsgBlock, num)
|
||||
blockHashes := make([]*chainhash.Hash, 0, num)
|
||||
|
||||
for i := uint32(0); i < num; i++ {
|
||||
generatedHashes := h.GenerateBlocks(1)
|
||||
blockHashes = append(blockHashes, generatedHashes...)
|
||||
|
||||
time.Sleep(slowMineDelay)
|
||||
}
|
||||
|
||||
for i, blockHash := range blockHashes {
|
||||
block, err := h.Client.GetBlock(blockHash)
|
||||
require.NoError(h, err, "get blocks")
|
||||
|
||||
blocks[i] = block
|
||||
}
|
||||
|
||||
return blocks
|
||||
// AssertNumTxsInMempool polls until finding the desired number of transactions
|
||||
// in the provided miner's mempool. It will asserrt if this number is not met
|
||||
// after the given timeout.
|
||||
func (h *HarnessTest) AssertNumTxsInMempool(n int) []*chainhash.Hash {
|
||||
return h.miner.AssertNumTxsInMempool(n)
|
||||
}
|
||||
|
||||
// AssertOutpointInMempool asserts a given outpoint can be found in the mempool.
|
||||
func (h *HarnessMiner) AssertOutpointInMempool(op wire.OutPoint) *wire.MsgTx {
|
||||
var msgTx *wire.MsgTx
|
||||
func (h *HarnessTest) AssertOutpointInMempool(op wire.OutPoint) *wire.MsgTx {
|
||||
return h.miner.AssertOutpointInMempool(op)
|
||||
}
|
||||
|
||||
err := wait.NoError(func() error {
|
||||
// We require the RPC call to be succeeded and won't wait for
|
||||
// it as it's an unexpected behavior.
|
||||
mempool := h.GetRawMempool()
|
||||
// AssertTxInBlock asserts that a given txid can be found in the passed block.
|
||||
func (h *HarnessTest) AssertTxInBlock(block *wire.MsgBlock,
|
||||
txid *chainhash.Hash) {
|
||||
|
||||
if len(mempool) == 0 {
|
||||
return fmt.Errorf("empty mempool")
|
||||
}
|
||||
|
||||
for _, txid := range mempool {
|
||||
// We don't use `ht.Miner.GetRawTransaction` which
|
||||
// asserts a txid must be found. While iterating here,
|
||||
// the actual mempool state might have been changed,
|
||||
// causing a given txid being removed and cannot be
|
||||
// found. For instance, the aggregation logic used in
|
||||
// sweeping HTLC outputs will update the mempool by
|
||||
// replacing the HTLC spending txes with a single one.
|
||||
tx, err := h.Client.GetRawTransaction(txid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgTx = tx.MsgTx()
|
||||
for _, txIn := range msgTx.TxIn {
|
||||
if txIn.PreviousOutPoint == op {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("outpoint %v not found in mempool", op)
|
||||
}, wait.MinerMempoolTimeout)
|
||||
|
||||
require.NoError(h, err, "timeout checking mempool")
|
||||
|
||||
return msgTx
|
||||
h.miner.AssertTxInBlock(block, txid)
|
||||
}
|
||||
|
||||
// GetNumTxsFromMempool polls until finding the desired number of transactions
|
||||
// in the miner's mempool and returns the full transactions to the caller.
|
||||
func (h *HarnessMiner) GetNumTxsFromMempool(n int) []*wire.MsgTx {
|
||||
txids := h.AssertNumTxsInMempool(n)
|
||||
func (h *HarnessTest) GetNumTxsFromMempool(n int) []*wire.MsgTx {
|
||||
return h.miner.GetNumTxsFromMempool(n)
|
||||
}
|
||||
|
||||
var txes []*wire.MsgTx
|
||||
for _, txid := range txids {
|
||||
tx := h.GetRawTransaction(txid)
|
||||
txes = append(txes, tx.MsgTx())
|
||||
}
|
||||
// GetBestBlock makes a RPC request to miner and asserts.
|
||||
func (h *HarnessTest) GetBestBlock() (*chainhash.Hash, int32) {
|
||||
return h.miner.GetBestBlock()
|
||||
}
|
||||
|
||||
return txes
|
||||
// MineBlockWithTx mines a single block to include the specifies tx only.
|
||||
func (h *HarnessTest) MineBlockWithTx(tx *wire.MsgTx) *wire.MsgBlock {
|
||||
return h.miner.MineBlockWithTx(tx)
|
||||
}
|
||||
|
||||
// ConnectToMiner connects the miner to a temp miner.
|
||||
func (h *HarnessTest) ConnectToMiner(tempMiner *miner.HarnessMiner) {
|
||||
h.miner.ConnectMiner(tempMiner)
|
||||
}
|
||||
|
||||
// DisconnectFromMiner disconnects the miner from the temp miner.
|
||||
func (h *HarnessTest) DisconnectFromMiner(tempMiner *miner.HarnessMiner) {
|
||||
h.miner.DisconnectMiner(tempMiner)
|
||||
}
|
||||
|
||||
// GetRawMempool makes a RPC call to the miner's GetRawMempool and
|
||||
// asserts.
|
||||
func (h *HarnessTest) GetRawMempool() []*chainhash.Hash {
|
||||
return h.miner.GetRawMempool()
|
||||
}
|
||||
|
||||
// GetRawTransaction makes a RPC call to the miner's GetRawTransaction and
|
||||
// asserts.
|
||||
func (h *HarnessTest) GetRawTransaction(txid *chainhash.Hash) *btcutil.Tx {
|
||||
return h.miner.GetRawTransaction(txid)
|
||||
}
|
||||
|
||||
// NewMinerAddress creates a new address for the miner and asserts.
|
||||
func (h *HarnessMiner) NewMinerAddress() btcutil.Address {
|
||||
addr, err := h.NewAddress()
|
||||
require.NoError(h, err, "failed to create new miner address")
|
||||
return addr
|
||||
}
|
||||
|
||||
// MineBlocksWithTxes mines a single block to include the specifies
|
||||
// transactions only.
|
||||
func (h *HarnessMiner) MineBlockWithTxes(txes []*btcutil.Tx) *wire.MsgBlock {
|
||||
var emptyTime time.Time
|
||||
|
||||
// Generate a block.
|
||||
b, err := h.GenerateAndSubmitBlock(txes, -1, emptyTime)
|
||||
require.NoError(h, err, "unable to mine block")
|
||||
|
||||
block, err := h.Client.GetBlock(b.Hash())
|
||||
require.NoError(h, err, "unable to get block")
|
||||
|
||||
// Make sure the mempool has been updated.
|
||||
for _, tx := range txes {
|
||||
h.AssertTxNotInMempool(*tx.Hash())
|
||||
}
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
// MineBlocksWithTx mines a single block to include the specifies tx only.
|
||||
func (h *HarnessMiner) MineBlockWithTx(tx *wire.MsgTx) *wire.MsgBlock {
|
||||
var emptyTime time.Time
|
||||
|
||||
txes := []*btcutil.Tx{btcutil.NewTx(tx)}
|
||||
|
||||
// Generate a block.
|
||||
b, err := h.GenerateAndSubmitBlock(txes, -1, emptyTime)
|
||||
require.NoError(h, err, "unable to mine block")
|
||||
|
||||
block, err := h.Client.GetBlock(b.Hash())
|
||||
require.NoError(h, err, "unable to get block")
|
||||
|
||||
// Make sure the mempool has been updated.
|
||||
h.AssertTxNotInMempool(tx.TxHash())
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
// MineEmptyBlocks mines a given number of empty blocks.
|
||||
func (h *HarnessMiner) MineEmptyBlocks(num int) []*wire.MsgBlock {
|
||||
var emptyTime time.Time
|
||||
|
||||
blocks := make([]*wire.MsgBlock, num)
|
||||
for i := 0; i < num; i++ {
|
||||
// Generate an empty block.
|
||||
b, err := h.GenerateAndSubmitBlock(nil, -1, emptyTime)
|
||||
require.NoError(h, err, "unable to mine empty block")
|
||||
|
||||
block := h.GetBlock(b.Hash())
|
||||
blocks[i] = block
|
||||
}
|
||||
|
||||
return blocks
|
||||
func (h *HarnessTest) NewMinerAddress() btcutil.Address {
|
||||
return h.miner.NewMinerAddress()
|
||||
}
|
||||
|
||||
// SpawnTempMiner creates a temp miner and syncs it with the current miner.
|
||||
// Once miners are synced, the temp miner is disconnected from the original
|
||||
// miner and returned.
|
||||
func (h *HarnessMiner) SpawnTempMiner() *HarnessMiner {
|
||||
require := require.New(h.T)
|
||||
|
||||
// Setup a temp miner.
|
||||
tempLogDir := ".tempminerlogs"
|
||||
logFilename := "output-temp_miner.log"
|
||||
tempMiner := NewTempMiner(h.runCtx, h.T, tempLogDir, logFilename)
|
||||
|
||||
// Make sure to clean the miner when the test ends.
|
||||
h.T.Cleanup(tempMiner.Stop)
|
||||
|
||||
// Setup the miner.
|
||||
require.NoError(tempMiner.SetUp(false, 0), "unable to setup miner")
|
||||
|
||||
// Connect the temp miner to the original miner.
|
||||
err := h.Client.Node(btcjson.NConnect, tempMiner.P2PAddress(), &temp)
|
||||
require.NoError(err, "unable to connect node")
|
||||
|
||||
// Sync the blocks.
|
||||
nodeSlice := []*rpctest.Harness{h.Harness, tempMiner.Harness}
|
||||
err = rpctest.JoinNodes(nodeSlice, rpctest.Blocks)
|
||||
require.NoError(err, "unable to join node on blocks")
|
||||
|
||||
// The two miners should be on the same block height.
|
||||
h.AssertMinerBlockHeightDelta(tempMiner, 0)
|
||||
|
||||
// Once synced, we now disconnect the temp miner so it'll be
|
||||
// independent from the original miner.
|
||||
err = h.Client.Node(btcjson.NDisconnect, tempMiner.P2PAddress(), &temp)
|
||||
require.NoError(err, "unable to disconnect miners")
|
||||
|
||||
return tempMiner
|
||||
func (h *HarnessTest) SpawnTempMiner() *miner.HarnessMiner {
|
||||
return h.miner.SpawnTempMiner()
|
||||
}
|
||||
|
||||
// ConnectMiner connects the miner to a temp miner.
|
||||
func (h *HarnessMiner) ConnectMiner(tempMiner *HarnessMiner) {
|
||||
require := require.New(h.T)
|
||||
// CreateTransaction uses the miner to create a transaction using the given
|
||||
// outputs using the specified fee rate and returns the transaction.
|
||||
func (h *HarnessTest) CreateTransaction(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) *wire.MsgTx {
|
||||
|
||||
// Connect the current miner to the temporary miner.
|
||||
err := h.Client.Node(btcjson.NConnect, tempMiner.P2PAddress(), &temp)
|
||||
require.NoError(err, "unable to connect temp miner")
|
||||
|
||||
nodes := []*rpctest.Harness{tempMiner.Harness, h.Harness}
|
||||
err = rpctest.JoinNodes(nodes, rpctest.Blocks)
|
||||
require.NoError(err, "unable to join node on blocks")
|
||||
return h.miner.CreateTransaction(outputs, feeRate)
|
||||
}
|
||||
|
||||
// DisconnectMiner disconnects the miner from the temp miner.
|
||||
func (h *HarnessMiner) DisconnectMiner(tempMiner *HarnessMiner) {
|
||||
err := h.Client.Node(btcjson.NDisconnect, tempMiner.P2PAddress(), &temp)
|
||||
require.NoError(h.T, err, "unable to disconnect temp miner")
|
||||
// SendOutputsWithoutChange uses the miner to send the given outputs using the
|
||||
// specified fee rate and returns the txid.
|
||||
func (h *HarnessTest) SendOutputsWithoutChange(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) *chainhash.Hash {
|
||||
|
||||
return h.miner.SendOutputsWithoutChange(outputs, feeRate)
|
||||
}
|
||||
|
||||
// AssertMinerBlockHeightDelta ensures that tempMiner is 'delta' blocks ahead
|
||||
// of miner.
|
||||
func (h *HarnessMiner) AssertMinerBlockHeightDelta(tempMiner *HarnessMiner,
|
||||
delta int32) {
|
||||
func (h *HarnessTest) AssertMinerBlockHeightDelta(
|
||||
tempMiner *miner.HarnessMiner, delta int32) {
|
||||
|
||||
// Ensure the chain lengths are what we expect.
|
||||
err := wait.NoError(func() error {
|
||||
_, tempMinerHeight, err := tempMiner.Client.GetBestBlock()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get current "+
|
||||
"blockheight %v", err)
|
||||
}
|
||||
|
||||
_, minerHeight, err := h.Client.GetBestBlock()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get current "+
|
||||
"blockheight %v", err)
|
||||
}
|
||||
|
||||
if tempMinerHeight != minerHeight+delta {
|
||||
return fmt.Errorf("expected new miner(%d) to be %d "+
|
||||
"blocks ahead of original miner(%d)",
|
||||
tempMinerHeight, delta, minerHeight)
|
||||
}
|
||||
|
||||
return nil
|
||||
}, DefaultTimeout)
|
||||
require.NoError(h.T, err, "failed to assert block height delta")
|
||||
h.miner.AssertMinerBlockHeightDelta(tempMiner, delta)
|
||||
}
|
||||
|
||||
// SendRawTransaction submits the encoded transaction to the server which will
|
||||
// then relay it to the network.
|
||||
func (h *HarnessTest) SendRawTransaction(tx *wire.MsgTx,
|
||||
allowHighFees bool) (chainhash.Hash, error) {
|
||||
|
||||
txid, err := h.miner.Client.SendRawTransaction(tx, allowHighFees)
|
||||
require.NoError(h, err)
|
||||
|
||||
return *txid, nil
|
||||
}
|
||||
|
||||
// CurrentHeight returns the current block height.
|
||||
func (h *HarnessTest) CurrentHeight() uint32 {
|
||||
return h.currentHeight
|
||||
}
|
||||
|
||||
// updateCurrentHeight set the harness's current height to the best known
|
||||
// height.
|
||||
func (h *HarnessTest) updateCurrentHeight() {
|
||||
_, height := h.GetBestBlock()
|
||||
h.currentHeight = uint32(height)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lntest/miner"
|
||||
"github.com/lightningnetwork/lnd/lntest/node"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
)
|
||||
|
@ -88,7 +89,7 @@ func (nm *nodeManager) newNode(t *testing.T, name string, extraArgs []string,
|
|||
NativeSQL: nm.nativeSQL,
|
||||
NodeID: nm.nextNodeID(),
|
||||
LndBinary: nm.lndBinary,
|
||||
NetParams: harnessNetParams,
|
||||
NetParams: miner.HarnessNetParams,
|
||||
SkipUnlock: noAuth,
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/integration/rpctest"
|
||||
"github.com/lightningnetwork/lnd/lntest/miner"
|
||||
"github.com/lightningnetwork/lnd/lntest/node"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -65,27 +66,27 @@ func SetupHarness(t *testing.T, binaryPath, dbBackendName string,
|
|||
// transactions on simnet to reject them. Transactions on the lightning network
|
||||
// should always be standard to get better guarantees of getting included in to
|
||||
// blocks.
|
||||
func prepareMiner(ctxt context.Context, t *testing.T) *HarnessMiner {
|
||||
miner := NewMiner(ctxt, t)
|
||||
func prepareMiner(ctxt context.Context, t *testing.T) *miner.HarnessMiner {
|
||||
m := miner.NewMiner(ctxt, t)
|
||||
|
||||
// Before we start anything, we want to overwrite some of the
|
||||
// connection settings to make the tests more robust. We might need to
|
||||
// restart the miner while there are already blocks present, which will
|
||||
// take a bit longer than the 1 second the default settings amount to.
|
||||
// Doubling both values will give us retries up to 4 seconds.
|
||||
miner.MaxConnRetries = rpctest.DefaultMaxConnectionRetries * 2
|
||||
miner.ConnectionRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2
|
||||
m.MaxConnRetries = rpctest.DefaultMaxConnectionRetries * 2
|
||||
m.ConnectionRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2
|
||||
|
||||
// Set up miner and connect chain backend to it.
|
||||
require.NoError(t, miner.SetUp(true, 50))
|
||||
require.NoError(t, miner.Client.NotifyNewTransactions(false))
|
||||
require.NoError(t, m.SetUp(true, 50))
|
||||
require.NoError(t, m.Client.NotifyNewTransactions(false))
|
||||
|
||||
// Next mine enough blocks in order for segwit and the CSV package
|
||||
// soft-fork to activate on SimNet.
|
||||
numBlocks := harnessNetParams.MinerConfirmationWindow * 2
|
||||
miner.GenerateBlocks(numBlocks)
|
||||
numBlocks := miner.HarnessNetParams.MinerConfirmationWindow * 2
|
||||
m.GenerateBlocks(numBlocks)
|
||||
|
||||
return miner
|
||||
return m
|
||||
}
|
||||
|
||||
// prepareChainBackend creates a new chain backend.
|
||||
|
@ -93,7 +94,7 @@ func prepareChainBackend(t *testing.T,
|
|||
minerAddr string) (node.BackendConfig, func()) {
|
||||
|
||||
chainBackend, cleanUp, err := NewBackend(
|
||||
minerAddr, harnessNetParams,
|
||||
minerAddr, miner.HarnessNetParams,
|
||||
)
|
||||
require.NoError(t, err, "new backend")
|
||||
|
||||
|
|
602
lntest/miner/miner.go
Normal file
602
lntest/miner/miner.go
Normal file
|
@ -0,0 +1,602 @@
|
|||
package miner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcjson"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/integration/rpctest"
|
||||
"github.com/btcsuite/btcd/rpcclient"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/lntest/node"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
// minerLogFilename is the default log filename for the miner node.
|
||||
minerLogFilename = "output_btcd_miner.log"
|
||||
|
||||
// minerLogDir is the default log dir for the miner node.
|
||||
minerLogDir = ".minerlogs"
|
||||
|
||||
// slowMineDelay defines a wait period between mining new blocks.
|
||||
slowMineDelay = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
var (
|
||||
HarnessNetParams = &chaincfg.RegressionNetParams
|
||||
|
||||
// temp is used to signal we want to establish a temporary connection
|
||||
// using the btcd Node API.
|
||||
//
|
||||
// NOTE: Cannot be const, since the node API expects a reference.
|
||||
Temp = "temp"
|
||||
)
|
||||
|
||||
type HarnessMiner struct {
|
||||
*testing.T
|
||||
*rpctest.Harness
|
||||
|
||||
// runCtx is a context with cancel method. It's used to signal when the
|
||||
// node needs to quit, and used as the parent context when spawning
|
||||
// children contexts for RPC requests.
|
||||
runCtx context.Context //nolint:containedctx
|
||||
cancel context.CancelFunc
|
||||
|
||||
// logPath is the directory path of the miner's logs.
|
||||
logPath string
|
||||
|
||||
// logFilename is the saved log filename of the miner node.
|
||||
logFilename string
|
||||
}
|
||||
|
||||
// NewMiner creates a new miner using btcd backend with the default log file
|
||||
// dir and name.
|
||||
func NewMiner(ctxt context.Context, t *testing.T) *HarnessMiner {
|
||||
t.Helper()
|
||||
return newMiner(ctxt, t, minerLogDir, minerLogFilename)
|
||||
}
|
||||
|
||||
// NewTempMiner creates a new miner using btcd backend with the specified log
|
||||
// file dir and name.
|
||||
func NewTempMiner(ctxt context.Context, t *testing.T,
|
||||
tempDir, tempLogFilename string) *HarnessMiner {
|
||||
|
||||
t.Helper()
|
||||
|
||||
return newMiner(ctxt, t, tempDir, tempLogFilename)
|
||||
}
|
||||
|
||||
// newMiner creates a new miner using btcd's rpctest.
|
||||
func newMiner(ctxb context.Context, t *testing.T, minerDirName,
|
||||
logFilename string) *HarnessMiner {
|
||||
|
||||
t.Helper()
|
||||
|
||||
handler := &rpcclient.NotificationHandlers{}
|
||||
btcdBinary := node.GetBtcdBinary()
|
||||
baseLogPath := fmt.Sprintf("%s/%s", node.GetLogDir(), minerDirName)
|
||||
|
||||
args := []string{
|
||||
"--rejectnonstd",
|
||||
"--txindex",
|
||||
"--nowinservice",
|
||||
"--nobanning",
|
||||
"--debuglevel=debug",
|
||||
"--logdir=" + baseLogPath,
|
||||
"--trickleinterval=100ms",
|
||||
// Don't disconnect if a reply takes too long.
|
||||
"--nostalldetect",
|
||||
}
|
||||
|
||||
miner, err := rpctest.New(HarnessNetParams, handler, args, btcdBinary)
|
||||
require.NoError(t, err, "unable to create mining node")
|
||||
|
||||
ctxt, cancel := context.WithCancel(ctxb)
|
||||
|
||||
return &HarnessMiner{
|
||||
T: t,
|
||||
Harness: miner,
|
||||
runCtx: ctxt,
|
||||
cancel: cancel,
|
||||
logPath: baseLogPath,
|
||||
logFilename: logFilename,
|
||||
}
|
||||
}
|
||||
|
||||
// saveLogs copies the node logs and save it to the file specified by
|
||||
// h.logFilename.
|
||||
func (h *HarnessMiner) saveLogs() {
|
||||
// After shutting down the miner, we'll make a copy of the log files
|
||||
// before deleting the temporary log dir.
|
||||
path := fmt.Sprintf("%s/%s", h.logPath, HarnessNetParams.Name)
|
||||
files, err := os.ReadDir(path)
|
||||
require.NoError(h, err, "unable to read log directory")
|
||||
|
||||
for _, file := range files {
|
||||
newFilename := strings.Replace(
|
||||
file.Name(), "btcd.log", h.logFilename, 1,
|
||||
)
|
||||
copyPath := fmt.Sprintf("%s/../%s", h.logPath, newFilename)
|
||||
|
||||
logFile := fmt.Sprintf("%s/%s", path, file.Name())
|
||||
err := node.CopyFile(filepath.Clean(copyPath), logFile)
|
||||
require.NoError(h, err, "unable to copy file")
|
||||
}
|
||||
|
||||
err = os.RemoveAll(h.logPath)
|
||||
require.NoErrorf(h, err, "cannot remove dir %s", h.logPath)
|
||||
}
|
||||
|
||||
// Stop shuts down the miner and saves its logs.
|
||||
func (h *HarnessMiner) Stop() {
|
||||
h.cancel()
|
||||
require.NoError(h, h.TearDown(), "tear down miner got error")
|
||||
h.saveLogs()
|
||||
}
|
||||
|
||||
// GetBestBlock makes a RPC request to miner and asserts.
|
||||
func (h *HarnessMiner) GetBestBlock() (*chainhash.Hash, int32) {
|
||||
blockHash, height, err := h.Client.GetBestBlock()
|
||||
require.NoError(h, err, "failed to GetBestBlock")
|
||||
|
||||
return blockHash, height
|
||||
}
|
||||
|
||||
// GetRawMempool makes a RPC call to the miner's GetRawMempool and
|
||||
// asserts.
|
||||
func (h *HarnessMiner) GetRawMempool() []*chainhash.Hash {
|
||||
mempool, err := h.Client.GetRawMempool()
|
||||
require.NoError(h, err, "unable to get mempool")
|
||||
|
||||
return mempool
|
||||
}
|
||||
|
||||
// GenerateBlocks mine 'num' of blocks and returns them.
|
||||
func (h *HarnessMiner) GenerateBlocks(num uint32) []*chainhash.Hash {
|
||||
blockHashes, err := h.Client.Generate(num)
|
||||
require.NoError(h, err, "unable to generate blocks")
|
||||
require.Len(h, blockHashes, int(num), "wrong num of blocks generated")
|
||||
|
||||
return blockHashes
|
||||
}
|
||||
|
||||
// GetBlock gets a block using its block hash.
|
||||
func (h *HarnessMiner) GetBlock(blockHash *chainhash.Hash) *wire.MsgBlock {
|
||||
block, err := h.Client.GetBlock(blockHash)
|
||||
require.NoError(h, err, "unable to get block")
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
// MineBlocks mine 'num' of blocks and check that blocks are present in
|
||||
// node blockchain.
|
||||
func (h *HarnessMiner) MineBlocks(num uint32) []*wire.MsgBlock {
|
||||
blocks := make([]*wire.MsgBlock, num)
|
||||
|
||||
blockHashes := h.GenerateBlocks(num)
|
||||
|
||||
for i, blockHash := range blockHashes {
|
||||
block := h.GetBlock(blockHash)
|
||||
blocks[i] = block
|
||||
}
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// AssertNumTxsInMempool polls until finding the desired number of transactions
|
||||
// in the provided miner's mempool. It will asserrt if this number is not met
|
||||
// after the given timeout.
|
||||
func (h *HarnessMiner) AssertNumTxsInMempool(n int) []*chainhash.Hash {
|
||||
var (
|
||||
mem []*chainhash.Hash
|
||||
err error
|
||||
)
|
||||
|
||||
err = wait.NoError(func() error {
|
||||
// We require the RPC call to be succeeded and won't wait for
|
||||
// it as it's an unexpected behavior.
|
||||
mem = h.GetRawMempool()
|
||||
if len(mem) == n {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("want %v, got %v in mempool: %v",
|
||||
n, len(mem), mem)
|
||||
}, wait.MinerMempoolTimeout)
|
||||
require.NoError(h, err, "assert tx in mempool timeout")
|
||||
|
||||
return mem
|
||||
}
|
||||
|
||||
// AssertTxInBlock asserts that a given txid can be found in the passed block.
|
||||
func (h *HarnessMiner) AssertTxInBlock(block *wire.MsgBlock,
|
||||
txid *chainhash.Hash) {
|
||||
|
||||
blockTxes := make([]chainhash.Hash, 0)
|
||||
|
||||
for _, tx := range block.Transactions {
|
||||
sha := tx.TxHash()
|
||||
blockTxes = append(blockTxes, sha)
|
||||
|
||||
if bytes.Equal(txid[:], sha[:]) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
require.Failf(h, "tx was not included in block", "tx:%v, block has:%v",
|
||||
txid, blockTxes)
|
||||
}
|
||||
|
||||
// MineBlocksAndAssertNumTxes mine 'num' of blocks and check that blocks are
|
||||
// present in node blockchain. numTxs should be set to the number of
|
||||
// transactions (excluding the coinbase) we expect to be included in the first
|
||||
// mined block.
|
||||
func (h *HarnessMiner) MineBlocksAndAssertNumTxes(num uint32,
|
||||
numTxs int) []*wire.MsgBlock {
|
||||
|
||||
// If we expect transactions to be included in the blocks we'll mine,
|
||||
// we wait here until they are seen in the miner's mempool.
|
||||
txids := h.AssertNumTxsInMempool(numTxs)
|
||||
|
||||
// Mine blocks.
|
||||
blocks := h.MineBlocks(num)
|
||||
|
||||
// Finally, assert that all the transactions were included in the first
|
||||
// block.
|
||||
for _, txid := range txids {
|
||||
h.AssertTxInBlock(blocks[0], txid)
|
||||
}
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// GetRawTransaction makes a RPC call to the miner's GetRawTransaction and
|
||||
// asserts.
|
||||
func (h *HarnessMiner) GetRawTransaction(txid *chainhash.Hash) *btcutil.Tx {
|
||||
tx, err := h.Client.GetRawTransaction(txid)
|
||||
require.NoErrorf(h, err, "failed to get raw tx: %v", txid)
|
||||
return tx
|
||||
}
|
||||
|
||||
// GetRawTransactionVerbose makes a RPC call to the miner's
|
||||
// GetRawTransactionVerbose and asserts.
|
||||
func (h *HarnessMiner) GetRawTransactionVerbose(
|
||||
txid *chainhash.Hash) *btcjson.TxRawResult {
|
||||
|
||||
tx, err := h.Client.GetRawTransactionVerbose(txid)
|
||||
require.NoErrorf(h, err, "failed to get raw tx verbose: %v", txid)
|
||||
return tx
|
||||
}
|
||||
|
||||
// AssertTxInMempool asserts a given transaction can be found in the mempool.
|
||||
func (h *HarnessMiner) AssertTxInMempool(txid *chainhash.Hash) *wire.MsgTx {
|
||||
var msgTx *wire.MsgTx
|
||||
|
||||
err := wait.NoError(func() error {
|
||||
// We require the RPC call to be succeeded and won't wait for
|
||||
// it as it's an unexpected behavior.
|
||||
mempool := h.GetRawMempool()
|
||||
|
||||
if len(mempool) == 0 {
|
||||
return fmt.Errorf("empty mempool")
|
||||
}
|
||||
|
||||
for _, memTx := range mempool {
|
||||
// Check the values are equal.
|
||||
if *memTx == *txid {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("txid %v not found in mempool: %v", txid,
|
||||
mempool)
|
||||
}, wait.MinerMempoolTimeout)
|
||||
|
||||
require.NoError(h, err, "timeout checking mempool")
|
||||
|
||||
return msgTx
|
||||
}
|
||||
|
||||
// AssertTxNotInMempool asserts a given transaction cannot be found in the
|
||||
// mempool. It assumes the mempool is not empty.
|
||||
//
|
||||
// NOTE: this should be used after `AssertTxInMempool` to ensure the tx has
|
||||
// entered the mempool before. Otherwise it might give false positive and the
|
||||
// tx may enter the mempool after the check.
|
||||
func (h *HarnessMiner) AssertTxNotInMempool(txid chainhash.Hash) *wire.MsgTx {
|
||||
var msgTx *wire.MsgTx
|
||||
|
||||
err := wait.NoError(func() error {
|
||||
// We require the RPC call to be succeeded and won't wait for
|
||||
// it as it's an unexpected behavior.
|
||||
mempool := h.GetRawMempool()
|
||||
|
||||
for _, memTx := range mempool {
|
||||
// Check the values are equal.
|
||||
if txid.IsEqual(memTx) {
|
||||
return fmt.Errorf("expect txid %v to be NOT "+
|
||||
"found in mempool", txid)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, wait.MinerMempoolTimeout)
|
||||
|
||||
require.NoError(h, err, "timeout checking tx not in mempool")
|
||||
|
||||
return msgTx
|
||||
}
|
||||
|
||||
// SendOutputsWithoutChange uses the miner to send the given outputs using the
|
||||
// specified fee rate and returns the txid.
|
||||
func (h *HarnessMiner) SendOutputsWithoutChange(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) *chainhash.Hash {
|
||||
|
||||
txid, err := h.Harness.SendOutputsWithoutChange(
|
||||
outputs, feeRate,
|
||||
)
|
||||
require.NoErrorf(h, err, "failed to send output")
|
||||
|
||||
return txid
|
||||
}
|
||||
|
||||
// CreateTransaction uses the miner to create a transaction using the given
|
||||
// outputs using the specified fee rate and returns the transaction.
|
||||
func (h *HarnessMiner) CreateTransaction(outputs []*wire.TxOut,
|
||||
feeRate btcutil.Amount) *wire.MsgTx {
|
||||
|
||||
tx, err := h.Harness.CreateTransaction(outputs, feeRate, false)
|
||||
require.NoErrorf(h, err, "failed to create transaction")
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
// SendOutput creates, signs, and finally broadcasts a transaction spending
|
||||
// the harness' available mature coinbase outputs to create the new output.
|
||||
func (h *HarnessMiner) SendOutput(newOutput *wire.TxOut,
|
||||
feeRate btcutil.Amount) *chainhash.Hash {
|
||||
|
||||
hash, err := h.Harness.SendOutputs([]*wire.TxOut{newOutput}, feeRate)
|
||||
require.NoErrorf(h, err, "failed to send outputs")
|
||||
|
||||
return hash
|
||||
}
|
||||
|
||||
// MineBlocksSlow mines 'num' of blocks. Between each mined block an artificial
|
||||
// delay is introduced to give all network participants time to catch up.
|
||||
func (h *HarnessMiner) MineBlocksSlow(num uint32) []*wire.MsgBlock {
|
||||
blocks := make([]*wire.MsgBlock, num)
|
||||
blockHashes := make([]*chainhash.Hash, 0, num)
|
||||
|
||||
for i := uint32(0); i < num; i++ {
|
||||
generatedHashes := h.GenerateBlocks(1)
|
||||
blockHashes = append(blockHashes, generatedHashes...)
|
||||
|
||||
time.Sleep(slowMineDelay)
|
||||
}
|
||||
|
||||
for i, blockHash := range blockHashes {
|
||||
block, err := h.Client.GetBlock(blockHash)
|
||||
require.NoError(h, err, "get blocks")
|
||||
|
||||
blocks[i] = block
|
||||
}
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// AssertOutpointInMempool asserts a given outpoint can be found in the mempool.
|
||||
func (h *HarnessMiner) AssertOutpointInMempool(op wire.OutPoint) *wire.MsgTx {
|
||||
var msgTx *wire.MsgTx
|
||||
|
||||
err := wait.NoError(func() error {
|
||||
// We require the RPC call to be succeeded and won't wait for
|
||||
// it as it's an unexpected behavior.
|
||||
mempool := h.GetRawMempool()
|
||||
|
||||
if len(mempool) == 0 {
|
||||
return fmt.Errorf("empty mempool")
|
||||
}
|
||||
|
||||
for _, txid := range mempool {
|
||||
// We don't use `ht.GetRawTransaction` which
|
||||
// asserts a txid must be found. While iterating here,
|
||||
// the actual mempool state might have been changed,
|
||||
// causing a given txid being removed and cannot be
|
||||
// found. For instance, the aggregation logic used in
|
||||
// sweeping HTLC outputs will update the mempool by
|
||||
// replacing the HTLC spending txes with a single one.
|
||||
tx, err := h.Client.GetRawTransaction(txid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgTx = tx.MsgTx()
|
||||
for _, txIn := range msgTx.TxIn {
|
||||
if txIn.PreviousOutPoint == op {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("outpoint %v not found in mempool", op)
|
||||
}, wait.MinerMempoolTimeout)
|
||||
|
||||
require.NoError(h, err, "timeout checking mempool")
|
||||
|
||||
return msgTx
|
||||
}
|
||||
|
||||
// GetNumTxsFromMempool polls until finding the desired number of transactions
|
||||
// in the miner's mempool and returns the full transactions to the caller.
|
||||
func (h *HarnessMiner) GetNumTxsFromMempool(n int) []*wire.MsgTx {
|
||||
txids := h.AssertNumTxsInMempool(n)
|
||||
|
||||
var txes []*wire.MsgTx
|
||||
for _, txid := range txids {
|
||||
tx := h.GetRawTransaction(txid)
|
||||
txes = append(txes, tx.MsgTx())
|
||||
}
|
||||
|
||||
return txes
|
||||
}
|
||||
|
||||
// NewMinerAddress creates a new address for the miner and asserts.
|
||||
func (h *HarnessMiner) NewMinerAddress() btcutil.Address {
|
||||
addr, err := h.NewAddress()
|
||||
require.NoError(h, err, "failed to create new miner address")
|
||||
return addr
|
||||
}
|
||||
|
||||
// MineBlocksWithTxes mines a single block to include the specifies
|
||||
// transactions only.
|
||||
func (h *HarnessMiner) MineBlockWithTxes(txes []*btcutil.Tx) *wire.MsgBlock {
|
||||
var emptyTime time.Time
|
||||
|
||||
// Generate a block.
|
||||
b, err := h.GenerateAndSubmitBlock(txes, -1, emptyTime)
|
||||
require.NoError(h, err, "unable to mine block")
|
||||
|
||||
block, err := h.Client.GetBlock(b.Hash())
|
||||
require.NoError(h, err, "unable to get block")
|
||||
|
||||
// Make sure the mempool has been updated.
|
||||
for _, tx := range txes {
|
||||
h.AssertTxNotInMempool(*tx.Hash())
|
||||
}
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
// MineBlocksWithTx mines a single block to include the specifies tx only.
|
||||
func (h *HarnessMiner) MineBlockWithTx(tx *wire.MsgTx) *wire.MsgBlock {
|
||||
var emptyTime time.Time
|
||||
|
||||
txes := []*btcutil.Tx{btcutil.NewTx(tx)}
|
||||
|
||||
// Generate a block.
|
||||
b, err := h.GenerateAndSubmitBlock(txes, -1, emptyTime)
|
||||
require.NoError(h, err, "unable to mine block")
|
||||
|
||||
block, err := h.Client.GetBlock(b.Hash())
|
||||
require.NoError(h, err, "unable to get block")
|
||||
|
||||
// Make sure the mempool has been updated.
|
||||
h.AssertTxNotInMempool(tx.TxHash())
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
// MineEmptyBlocks mines a given number of empty blocks.
|
||||
func (h *HarnessMiner) MineEmptyBlocks(num int) []*wire.MsgBlock {
|
||||
var emptyTime time.Time
|
||||
|
||||
blocks := make([]*wire.MsgBlock, num)
|
||||
for i := 0; i < num; i++ {
|
||||
// Generate an empty block.
|
||||
b, err := h.GenerateAndSubmitBlock(nil, -1, emptyTime)
|
||||
require.NoError(h, err, "unable to mine empty block")
|
||||
|
||||
block := h.GetBlock(b.Hash())
|
||||
blocks[i] = block
|
||||
}
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
// SpawnTempMiner creates a temp miner and syncs it with the current miner.
|
||||
// Once miners are synced, the temp miner is disconnected from the original
|
||||
// miner and returned.
|
||||
func (h *HarnessMiner) SpawnTempMiner() *HarnessMiner {
|
||||
require := require.New(h.T)
|
||||
|
||||
// Setup a temp miner.
|
||||
tempLogDir := ".tempminerlogs"
|
||||
logFilename := "output-temp_miner.log"
|
||||
tempMiner := NewTempMiner(h.runCtx, h.T, tempLogDir, logFilename)
|
||||
|
||||
// Make sure to clean the miner when the test ends.
|
||||
h.T.Cleanup(tempMiner.Stop)
|
||||
|
||||
// Setup the miner.
|
||||
require.NoError(tempMiner.SetUp(false, 0), "unable to setup miner")
|
||||
|
||||
// Connect the temp miner to the original miner.
|
||||
err := h.Client.Node(btcjson.NConnect, tempMiner.P2PAddress(), &Temp)
|
||||
require.NoError(err, "unable to connect node")
|
||||
|
||||
// Sync the blocks.
|
||||
nodeSlice := []*rpctest.Harness{h.Harness, tempMiner.Harness}
|
||||
err = rpctest.JoinNodes(nodeSlice, rpctest.Blocks)
|
||||
require.NoError(err, "unable to join node on blocks")
|
||||
|
||||
// The two miners should be on the same block height.
|
||||
h.AssertMinerBlockHeightDelta(tempMiner, 0)
|
||||
|
||||
// Once synced, we now disconnect the temp miner so it'll be
|
||||
// independent from the original miner.
|
||||
err = h.Client.Node(btcjson.NDisconnect, tempMiner.P2PAddress(), &Temp)
|
||||
require.NoError(err, "unable to disconnect miners")
|
||||
|
||||
return tempMiner
|
||||
}
|
||||
|
||||
// ConnectMiner connects the miner to a temp miner.
|
||||
func (h *HarnessMiner) ConnectMiner(tempMiner *HarnessMiner) {
|
||||
require := require.New(h.T)
|
||||
|
||||
// Connect the current miner to the temporary miner.
|
||||
err := h.Client.Node(btcjson.NConnect, tempMiner.P2PAddress(), &Temp)
|
||||
require.NoError(err, "unable to connect temp miner")
|
||||
|
||||
nodes := []*rpctest.Harness{tempMiner.Harness, h.Harness}
|
||||
err = rpctest.JoinNodes(nodes, rpctest.Blocks)
|
||||
require.NoError(err, "unable to join node on blocks")
|
||||
}
|
||||
|
||||
// DisconnectMiner disconnects the miner from the temp miner.
|
||||
func (h *HarnessMiner) DisconnectMiner(tempMiner *HarnessMiner) {
|
||||
err := h.Client.Node(btcjson.NDisconnect, tempMiner.P2PAddress(), &Temp)
|
||||
require.NoError(h.T, err, "unable to disconnect temp miner")
|
||||
}
|
||||
|
||||
// AssertMinerBlockHeightDelta ensures that tempMiner is 'delta' blocks ahead
|
||||
// of miner.
|
||||
func (h *HarnessMiner) AssertMinerBlockHeightDelta(tempMiner *HarnessMiner,
|
||||
delta int32) {
|
||||
|
||||
// Ensure the chain lengths are what we expect.
|
||||
err := wait.NoError(func() error {
|
||||
_, tempMinerHeight, err := tempMiner.Client.GetBestBlock()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get current "+
|
||||
"blockheight %v", err)
|
||||
}
|
||||
|
||||
_, minerHeight, err := h.Client.GetBestBlock()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get current "+
|
||||
"blockheight %v", err)
|
||||
}
|
||||
|
||||
if tempMinerHeight != minerHeight+delta {
|
||||
return fmt.Errorf("expected new miner(%d) to be %d "+
|
||||
"blocks ahead of original miner(%d)",
|
||||
tempMinerHeight, delta, minerHeight)
|
||||
}
|
||||
|
||||
return nil
|
||||
}, wait.DefaultTimeout)
|
||||
require.NoError(h.T, err, "failed to assert block height delta")
|
||||
}
|
|
@ -53,10 +53,16 @@ func CopyFile(dest, src string) error {
|
|||
|
||||
// errNumNotMatched is a helper method to return a nicely formatted error.
|
||||
func errNumNotMatched(name string, subject string,
|
||||
want, got, total, old int) error {
|
||||
want, got, total, old int, desc ...any) error {
|
||||
|
||||
return fmt.Errorf("%s: assert %s failed: want %d, got: %d, total: "+
|
||||
err := fmt.Errorf("%s: assert %s failed: want %d, got: %d, total: "+
|
||||
"%d, previously had: %d", name, subject, want, got, total, old)
|
||||
|
||||
if len(desc) > 0 {
|
||||
err = fmt.Errorf("%w, desc: %v", err, desc)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// parseDerivationPath parses a path in the form of m/x'/y'/z'/a/b into a slice
|
||||
|
|
|
@ -125,6 +125,9 @@ func (b *BitcoindFilteredChainView) Start() error {
|
|||
//
|
||||
// NOTE: This is part of the FilteredChainView interface.
|
||||
func (b *BitcoindFilteredChainView) Stop() error {
|
||||
log.Debug("BitcoindFilteredChainView stopping")
|
||||
defer log.Debug("BitcoindFilteredChainView stopped")
|
||||
|
||||
// Already shutting down?
|
||||
if atomic.AddInt32(&b.stopped, 1) != 1 {
|
||||
return nil
|
||||
|
@ -136,8 +139,6 @@ func (b *BitcoindFilteredChainView) Stop() error {
|
|||
|
||||
b.blockQueue.Stop()
|
||||
|
||||
log.Infof("FilteredChainView stopping")
|
||||
|
||||
close(b.quit)
|
||||
b.wg.Wait()
|
||||
|
||||
|
|
|
@ -135,6 +135,9 @@ func (b *BtcdFilteredChainView) Start() error {
|
|||
//
|
||||
// NOTE: This is part of the FilteredChainView interface.
|
||||
func (b *BtcdFilteredChainView) Stop() error {
|
||||
log.Debug("BtcdFilteredChainView stopping")
|
||||
defer log.Debug("BtcdFilteredChainView stopped")
|
||||
|
||||
// Already shutting down?
|
||||
if atomic.AddInt32(&b.stopped, 1) != 1 {
|
||||
return nil
|
||||
|
@ -146,8 +149,6 @@ func (b *BtcdFilteredChainView) Stop() error {
|
|||
|
||||
b.blockQueue.Stop()
|
||||
|
||||
log.Infof("FilteredChainView stopping")
|
||||
|
||||
close(b.quit)
|
||||
b.wg.Wait()
|
||||
|
||||
|
|
|
@ -135,13 +135,14 @@ func (c *CfFilteredChainView) Start() error {
|
|||
//
|
||||
// NOTE: This is part of the FilteredChainView interface.
|
||||
func (c *CfFilteredChainView) Stop() error {
|
||||
log.Debug("CfFilteredChainView stopping")
|
||||
defer log.Debug("CfFilteredChainView stopped")
|
||||
|
||||
// Already shutting down?
|
||||
if atomic.AddInt32(&c.stopped, 1) != 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Infof("FilteredChainView stopping")
|
||||
|
||||
close(c.quit)
|
||||
c.blockQueue.Stop()
|
||||
c.wg.Wait()
|
||||
|
|
|
@ -303,7 +303,11 @@ func (b *missionControlStore) run() {
|
|||
// channel needs to be drained appropriately. This could happen
|
||||
// if the flushInterval is very small (e.g. 1 nanosecond).
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
select {
|
||||
case <-timer.C:
|
||||
case <-b.done:
|
||||
log.Debugf("Stopping mission control store")
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
|
@ -335,7 +339,12 @@ func (b *missionControlStore) run() {
|
|||
case <-b.done:
|
||||
// Release the timer's resources.
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
select {
|
||||
case <-timer.C:
|
||||
case <-b.done:
|
||||
log.Debugf("Mission control " +
|
||||
"store stopped")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue