lntemp+itest: refactor testRevokedCloseRetributionAltruistWatchtower

This commit is contained in:
yyforyongyu committed 2023-01-16 16:49:19 +08:00
1 parent 211aa4c6f2
commit 6792ca17b4
4 files changed
+150 -236

No files matched your search

+47
View File
@@ -1,5 +1,52 @@
package rpc package rpc
import (
"context"
"github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc"
"github.com/lightningnetwork/lnd/lnrpc/wtclientrpc"
)
// ===================== // =====================
// WatchtowerClient and WatchtowerClientClient related RPCs. // WatchtowerClient and WatchtowerClientClient related RPCs.
// ===================== // =====================
// GetInfoWatchtower makes a RPC call to the watchtower of the given node and
// asserts.
func (h *HarnessRPC) GetInfoWatchtower() *watchtowerrpc.GetInfoResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &watchtowerrpc.GetInfoRequest{}
info, err := h.Watchtower.GetInfo(ctxt, req)
h.NoError(err, "GetInfo from Watchtower")
return info
}
// AddTower makes a RPC call to the WatchtowerClient of the given node and
// asserts.
func (h *HarnessRPC) AddTower(
req *wtclientrpc.AddTowerRequest) *wtclientrpc.AddTowerResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.WatchtowerClient.AddTower(ctxt, req)
h.NoError(err, "AddTower")
return resp
}
// WatchtowerStats makes a RPC call to the WatchtowerClient of the given node
// and asserts.
func (h *HarnessRPC) WatchtowerStats() *wtclientrpc.StatsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &wtclientrpc.StatsRequest{}
resp, err := h.WatchtowerClient.Stats(ctxt, req)
h.NoError(err, "Stats from Watchtower")
return resp
}
+4
View File
@@ -304,4 +304,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
Name: "revoked uncooperative close retribution remote hodl", Name: "revoked uncooperative close retribution remote hodl",
TestFunc: testRevokedCloseRetributionRemoteHodl, TestFunc: testRevokedCloseRetributionRemoteHodl,
}, },
{
Name: "revoked uncooperative close retribution altruist watchtower",
TestFunc: testRevokedCloseRetributionAltruistWatchtower,
},
} }
+99 -232
View File
@@ -2,9 +2,7 @@ package itest
import ( import (
"bytes" "bytes"
"context"
"fmt" "fmt"
"strings"
"testing" "testing"
"time" "time"
@@ -13,7 +11,6 @@ import (
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc"
"github.com/lightningnetwork/lnd/lnrpc/wtclientrpc" "github.com/lightningnetwork/lnd/lnrpc/wtclientrpc"
"github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntemp"
"github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest"
@@ -581,9 +578,7 @@ func testRevokedCloseRetributionRemoteHodl(ht *lntemp.HarnessTest) {
// trigger a breach. Carol is kept offline throughout the process and the test // trigger a breach. Carol is kept offline throughout the process and the test
// asserts that Willy responds by broadcasting the justice transaction on // asserts that Willy responds by broadcasting the justice transaction on
// Carol's behalf sweeping her funds without a reward. // Carol's behalf sweeping her funds without a reward.
func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness, func testRevokedCloseRetributionAltruistWatchtower(ht *lntemp.HarnessTest) {
t *harnessTest) {
testCases := []struct { testCases := []struct {
name string name string
anchors bool anchors bool
@@ -597,23 +592,25 @@ func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,
for _, tc := range testCases { for _, tc := range testCases {
tc := tc tc := tc
testFunc := func(ht *lntemp.HarnessTest) {
testRevokedCloseRetributionAltruistWatchtowerCase(
ht, tc.anchors,
)
}
success := t.t.Run(tc.name, func(tt *testing.T) { success := ht.Run(tc.name, func(tt *testing.T) {
ht := newHarnessTest(tt, net) st := ht.Subtest(tt)
ht.RunTestCase(&testCase{
name: tc.name, st.RunTestCase(&lntemp.TestCase{
test: func(net1 *lntest.NetworkHarness, t1 *harnessTest) { Name: tc.name,
testRevokedCloseRetributionAltruistWatchtowerCase( TestFunc: testFunc,
net1, t1, tc.anchors,
)
},
}) })
}) })
if !success { if !success {
// Log failure time to help relate the lnd logs to the // Log failure time to help relate the lnd logs to the
// failure. // failure.
t.Logf("Failure time: %v", time.Now().Format( ht.Logf("Failure time: %v", time.Now().Format(
"2006-01-02 15:04:05.000", "2006-01-02 15:04:05.000",
)) ))
@@ -622,10 +619,9 @@ func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,
} }
} }
func testRevokedCloseRetributionAltruistWatchtowerCase( func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntemp.HarnessTest,
net *lntest.NetworkHarness, t *harnessTest, anchors bool) { anchors bool) {
ctxb := context.Background()
const ( const (
chanAmt = funding.MaxBtcFundingAmount chanAmt = funding.MaxBtcFundingAmount
paymentAmt = 10000 paymentAmt = 10000
@@ -639,49 +635,32 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(
if anchors { if anchors {
carolArgs = append(carolArgs, "--protocol.anchors") carolArgs = append(carolArgs, "--protocol.anchors")
} }
carol := net.NewNode(t.t, "Carol", carolArgs) carol := ht.NewNode("Carol", carolArgs)
defer shutdownAndAssert(net, t, carol)
// Willy the watchtower will protect Dave from Carol's breach. He will // Willy the watchtower will protect Dave from Carol's breach. He will
// remain online in order to punish Carol on Dave's behalf, since the // remain online in order to punish Carol on Dave's behalf, since the
// breach will happen while Dave is offline. // breach will happen while Dave is offline.
willy := net.NewNode(t.t, "Willy", []string{ willy := ht.NewNode(
"--watchtower.active", "Willy", []string{"--watchtower.active",
"--watchtower.externalip=" + externalIP, "--watchtower.externalip=" + externalIP},
})
defer shutdownAndAssert(net, t, willy)
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
willyInfo, err := willy.Watchtower.GetInfo(
ctxt, &watchtowerrpc.GetInfoRequest{},
) )
if err != nil {
t.Fatalf("unable to getinfo from willy: %v", err) willyInfo := willy.RPC.GetInfoWatchtower()
}
// Assert that Willy has one listener and it is 0.0.0.0:9911 or // Assert that Willy has one listener and it is 0.0.0.0:9911 or
// [::]:9911. Since no listener is explicitly specified, one of these // [::]:9911. Since no listener is explicitly specified, one of these
// should be the default depending on whether the host supports IPv6 or // should be the default depending on whether the host supports IPv6 or
// not. // not.
if len(willyInfo.Listeners) != 1 { require.Len(ht, willyInfo.Listeners, 1, "Willy should have 1 listener")
t.Fatalf("Willy should have 1 listener, has %d",
len(willyInfo.Listeners))
}
listener := willyInfo.Listeners[0] listener := willyInfo.Listeners[0]
if listener != "0.0.0.0:9911" && listener != "[::]:9911" { if listener != "0.0.0.0:9911" && listener != "[::]:9911" {
t.Fatalf("expected listener on 0.0.0.0:9911 or [::]:9911, "+ ht.Fatalf("expected listener on 0.0.0.0:9911 or [::]:9911, "+
"got %v", listener) "got %v", listener)
} }
// Assert the Willy's URIs properly display the chosen external IP. // Assert the Willy's URIs properly display the chosen external IP.
if len(willyInfo.Uris) != 1 { require.Len(ht, willyInfo.Uris, 1, "Willy should have 1 uri")
t.Fatalf("Willy should have 1 uri, has %d", require.Contains(ht, willyInfo.Uris[0], externalIP)
len(willyInfo.Uris))
}
if !strings.Contains(willyInfo.Uris[0], externalIP) {
t.Fatalf("expected uri with %v, got %v",
externalIP, willyInfo.Uris[0])
}
// Dave will be the breached party. We set --nolisten to ensure Carol // Dave will be the breached party. We set --nolisten to ensure Carol
// won't be able to connect to him and trigger the channel data // won't be able to connect to him and trigger the channel data
@@ -693,110 +672,67 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(
if anchors { if anchors {
daveArgs = append(daveArgs, "--protocol.anchors") daveArgs = append(daveArgs, "--protocol.anchors")
} }
dave := net.NewNode(t.t, "Dave", daveArgs) dave := ht.NewNode("Dave", daveArgs)
defer shutdownAndAssert(net, t, dave)
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
addTowerReq := &wtclientrpc.AddTowerRequest{ addTowerReq := &wtclientrpc.AddTowerRequest{
Pubkey: willyInfo.Pubkey, Pubkey: willyInfo.Pubkey,
Address: listener, Address: listener,
} }
if _, err := dave.WatchtowerClient.AddTower(ctxt, addTowerReq); err != nil { dave.RPC.AddTower(addTowerReq)
t.Fatalf("unable to add willy's watchtower: %v", err)
}
// We must let Dave have an open channel before she can send a node // We must let Dave have an open channel before she can send a node
// announcement, so we open a channel with Carol, // announcement, so we open a channel with Carol,
net.ConnectNodes(t.t, dave, carol) ht.ConnectNodes(dave, carol)
// Before we make a channel, we'll load up Dave with some coins sent // Before we make a channel, we'll load up Dave with some coins sent
// directly from the miner. // directly from the miner.
net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, dave) ht.FundCoins(btcutil.SatoshiPerBitcoin, dave)
// In order to test Dave's response to an uncooperative channel // In order to test Dave's response to an uncooperative channel
// closure by Carol, we'll first open up a channel between them with a // closure by Carol, we'll first open up a channel between them with a
// 0.5 BTC value. // 0.5 BTC value.
chanPoint := openChannelAndAssert( params := lntemp.OpenChannelParams{
t, net, dave, carol, Amt: 3 * (chanAmt / 4),
lntest.OpenChannelParams{ PushAmt: chanAmt / 4,
Amt: 3 * (chanAmt / 4), }
PushAmt: chanAmt / 4, chanPoint := ht.OpenChannel(dave, carol, params)
},
)
// With the channel open, we'll create a few invoices for Carol that // With the channel open, we'll create a few invoices for Carol that
// Dave will pay to in order to advance the state of the channel. // Dave will pay to in order to advance the state of the channel.
carolPayReqs, _, _, err := createPayReqs( carolPayReqs, _, _ := ht.CreatePayReqs(carol, paymentAmt, numInvoices)
carol, paymentAmt, numInvoices,
)
if err != nil {
t.Fatalf("unable to create pay reqs: %v", err)
}
// Wait for Dave to receive the channel edge from the funding manager.
err = dave.WaitForNetworkChannelOpen(chanPoint)
if err != nil {
t.Fatalf("dave didn't see the dave->carol channel before "+
"timeout: %v", err)
}
// Next query for Carol's channel state, as we sent 0 payments, Carol // Next query for Carol's channel state, as we sent 0 payments, Carol
// should still see her balance as the push amount, which is 1/4 of the // should still see her balance as the push amount, which is 1/4 of the
// capacity. // capacity.
carolChan, err := getChanInfo(carol) carolChan := ht.AssertChannelLocalBalance(
if err != nil { carol, chanPoint, int64(chanAmt/4),
t.Fatalf("unable to get carol's channel info: %v", err) )
}
if carolChan.LocalBalance != int64(chanAmt/4) {
t.Fatalf("carol's balance is incorrect, got %v, expected %v",
carolChan.LocalBalance, chanAmt/4)
}
// Grab Carol's current commitment height (update number), we'll later // Grab Carol's current commitment height (update number), we'll later
// revert her to this state after additional updates to force him to // revert her to this state after additional updates to force him to
// broadcast this soon to be revoked state. // broadcast this soon to be revoked state.
carolStateNumPreCopy := carolChan.NumUpdates carolStateNumPreCopy := int(carolChan.NumUpdates)
// With the temporary file created, copy Carol's current state into the // With the temporary file created, copy Carol's current state into the
// temporary file we created above. Later after more updates, we'll // temporary file we created above. Later after more updates, we'll
// restore this state. // restore this state.
if err := net.BackupDb(carol); err != nil { ht.BackupDB(carol)
t.Fatalf("unable to copy database files: %v", err)
}
// Reconnect the peers after the restart that was needed for the db // Reconnect the peers after the restart that was needed for the db
// backup. // backup.
net.EnsureConnected(t.t, dave, carol) ht.EnsureConnected(dave, carol)
// Finally, send payments from Dave to Carol, consuming Carol's remaining // Finally, send payments from Dave to Carol, consuming Carol's
// payment hashes. // remaining payment hashes.
err = completePaymentRequests( ht.CompletePaymentRequestsNoWait(dave, carolPayReqs, chanPoint)
dave, dave.RouterClient, carolPayReqs, false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
daveBalReq := &lnrpc.WalletBalanceRequest{}
daveBalResp, err := dave.WalletBalance(ctxt, daveBalReq)
if err != nil {
t.Fatalf("unable to get dave's balance: %v", err)
}
daveBalResp := dave.RPC.WalletBalance()
davePreSweepBalance := daveBalResp.ConfirmedBalance davePreSweepBalance := daveBalResp.ConfirmedBalance
// Wait until the backup has been accepted by the watchtower before // Wait until the backup has been accepted by the watchtower before
// shutting down Dave. // shutting down Dave.
err = wait.NoError(func() error { err := wait.NoError(func() error {
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) bkpStats := dave.RPC.WatchtowerStats()
defer cancel()
bkpStats, err := dave.WatchtowerClient.Stats(ctxt,
&wtclientrpc.StatsRequest{},
)
if err != nil {
return err
}
if bkpStats == nil { if bkpStats == nil {
return errors.New("no active backup sessions") return errors.New("no active backup sessions")
} }
@@ -806,197 +742,128 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(
return nil return nil
}, defaultTimeout) }, defaultTimeout)
if err != nil { require.NoError(ht, err, "unable to verify backup task completed")
t.Fatalf("unable to verify backup task completed: %v", err)
}
// Shutdown Dave to simulate going offline for an extended period of // Shutdown Dave to simulate going offline for an extended period of
// time. Once he's not watching, Carol will try to breach the channel. // time. Once he's not watching, Carol will try to breach the channel.
restart, err := net.SuspendNode(dave) restart := ht.SuspendNode(dave)
if err != nil {
t.Fatalf("unable to suspend Dave: %v", err)
}
// Now we shutdown Carol, copying over the his temporary database state // Now we shutdown Carol, copying over the his temporary database state
// which has the *prior* channel state over his current most up to date // which has the *prior* channel state over his current most up to date
// state. With this, we essentially force Carol to travel back in time // state. With this, we essentially force Carol to travel back in time
// within the channel's history. // within the channel's history.
if err = net.RestartNode(carol, func() error { ht.RestartNodeAndRestoreDB(carol)
return net.RestoreDb(carol)
}); err != nil {
t.Fatalf("unable to restart node: %v", err)
}
// Now query for Carol's channel state, it should show that he's at a // Now query for Carol's channel state, it should show that he's at a
// state number in the past, not the *latest* state. // state number in the past, not the *latest* state.
carolChan, err = getChanInfo(carol) ht.AssertChannelCommitHeight(carol, chanPoint, carolStateNumPreCopy)
if err != nil {
t.Fatalf("unable to get carol chan info: %v", err)
}
if carolChan.NumUpdates != carolStateNumPreCopy {
t.Fatalf("db copy failed: %v", carolChan.NumUpdates)
}
// Now force Carol to execute a *force* channel closure by unilaterally // Now force Carol to execute a *force* channel closure by unilaterally
// broadcasting his current channel state. This is actually the // broadcasting his current channel state. This is actually the
// commitment transaction of a prior *revoked* state, so he'll soon // commitment transaction of a prior *revoked* state, so he'll soon
// feel the wrath of Dave's retribution. // feel the wrath of Dave's retribution.
closeUpdates, closeTxID, err := net.CloseChannel(carol, chanPoint, true) closeUpdates, closeTxID := ht.CloseChannelAssertPending(
if err != nil { carol, chanPoint, true,
t.Fatalf("unable to close channel: %v", err) )
}
// Query the mempool for the breaching closing transaction, this should
// be broadcast by Carol when she force closes the channel above.
txid, err := waitForTxInMempool(net.Miner.Client, minerMempoolTimeout)
if err != nil {
t.Fatalf("unable to find Carol's force close tx in mempool: %v",
err)
}
if *txid != *closeTxID {
t.Fatalf("expected closeTx(%v) in mempool, instead found %v",
closeTxID, txid)
}
// Finally, generate a single block, wait for the final close status // Finally, generate a single block, wait for the final close status
// update, then ensure that the closing transaction was included in the // update, then ensure that the closing transaction was included in the
// block. // block.
block := mineBlocks(t, net, 1, 1)[0] block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
breachTXID, err := net.WaitForChannelClose(closeUpdates) breachTXID := ht.WaitForChannelCloseEvent(closeUpdates)
if err != nil { ht.Miner.AssertTxInBlock(block, breachTXID)
t.Fatalf("error while waiting for channel close: %v", err)
} // The breachTXID should match the above closeTxID.
assertTxInBlock(t, block, breachTXID) require.EqualValues(ht, breachTXID, closeTxID)
// Query the mempool for Dave's justice transaction, this should be // Query the mempool for Dave's justice transaction, this should be
// broadcast as Carol's contract breaching transaction gets confirmed // broadcast as Carol's contract breaching transaction gets confirmed
// above. // above.
justiceTXID, err := waitForTxInMempool(net.Miner.Client, minerMempoolTimeout) justiceTXID := ht.Miner.AssertNumTxsInMempool(1)[0]
if err != nil {
t.Fatalf("unable to find Dave's justice tx in mempool: %v",
err)
}
time.Sleep(100 * time.Millisecond)
// Query for the mempool transaction found above. Then assert that all // Query for the mempool transaction found above. Then assert that all
// the inputs of this transaction are spending outputs generated by // the inputs of this transaction are spending outputs generated by
// Carol's breach transaction above. // Carol's breach transaction above.
justiceTx, err := net.Miner.Client.GetRawTransaction(justiceTXID) justiceTx := ht.Miner.GetRawTransaction(justiceTXID)
if err != nil {
t.Fatalf("unable to query for justice tx: %v", err)
}
for _, txIn := range justiceTx.MsgTx().TxIn { for _, txIn := range justiceTx.MsgTx().TxIn {
if !bytes.Equal(txIn.PreviousOutPoint.Hash[:], breachTXID[:]) { require.Equal(ht, breachTXID[:], txIn.PreviousOutPoint.Hash[:],
t.Fatalf("justice tx not spending commitment utxo "+ "justice tx not spending commitment utxo")
"instead is: %v", txIn.PreviousOutPoint)
}
} }
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) willyBalResp := willy.RPC.WalletBalance()
willyBalReq := &lnrpc.WalletBalanceRequest{} require.Zero(ht, willyBalResp.ConfirmedBalance,
willyBalResp, err := willy.WalletBalance(ctxt, willyBalReq) "willy should have 0 balance before mining justice transaction")
if err != nil {
t.Fatalf("unable to get willy's balance: %v", err)
}
if willyBalResp.ConfirmedBalance != 0 {
t.Fatalf("willy should have 0 balance before mining "+
"justice transaction, instead has %d",
willyBalResp.ConfirmedBalance)
}
// Now mine a block, this transaction should include Dave's justice // Now mine a block, this transaction should include Dave's justice
// transaction which was just accepted into the mempool. // transaction which was just accepted into the mempool.
block = mineBlocks(t, net, 1, 1)[0] block = ht.MineBlocksAndAssertNumTxes(1, 1)[0]
// The block should have exactly *two* transactions, one of which is // The block should have exactly *two* transactions, one of which is
// the justice transaction. // the justice transaction.
if len(block.Transactions) != 2 { require.Len(ht, block.Transactions, 2, "transaction wasn't mined")
t.Fatalf("transaction wasn't mined")
}
justiceSha := block.Transactions[1].TxHash() justiceSha := block.Transactions[1].TxHash()
if !bytes.Equal(justiceTx.Hash()[:], justiceSha[:]) { require.Equal(ht, justiceTx.Hash()[:], justiceSha[:],
t.Fatalf("justice tx wasn't mined") "justice tx wasn't mined")
}
// Ensure that Willy doesn't get any funds, as he is acting as an // Ensure that Willy doesn't get any funds, as he is acting as an
// altruist watchtower. // altruist watchtower.
var predErr error err = wait.NoError(func() error {
err = wait.Invariant(func() bool { willyBalResp := willy.RPC.WalletBalance()
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
willyBalReq := &lnrpc.WalletBalanceRequest{}
willyBalResp, err := willy.WalletBalance(ctxt, willyBalReq)
if err != nil {
t.Fatalf("unable to get willy's balance: %v", err)
}
if willyBalResp.ConfirmedBalance != 0 { if willyBalResp.ConfirmedBalance != 0 {
predErr = fmt.Errorf("Expected Willy to have no funds "+ return fmt.Errorf("Expected Willy to have no funds "+
"after justice transaction was mined, found %v", "after justice transaction was mined, found %v",
willyBalResp) willyBalResp)
return false
} }
return true return nil
}, time.Second*5) }, time.Second*5)
if err != nil { require.NoError(ht, err, "timeout checking willy's balance")
t.Fatalf("%v", predErr)
} // Before restarting Dave, shutdown Carol so Dave won't sync with her.
// Otherwise, during the restart, Dave will realize Carol is falling
// behind and return `ErrCommitSyncRemoteDataLoss`, thus force closing
// the channel. Although this force close tx will be later replaced by
// the breach tx, it will create two anchor sweeping txes for neutrino
// backend, causing the confirmed wallet balance to be zero later on
// because the utxos are used in sweeping.
ht.Shutdown(carol)
// Restart Dave, who will still think his channel with Carol is open. // Restart Dave, who will still think his channel with Carol is open.
// We should him to detect the breach, but realize that the funds have // We should him to detect the breach, but realize that the funds have
// then been swept to his wallet by Willy. // then been swept to his wallet by Willy.
err = restart() require.NoError(ht, restart(), "unable to restart dave")
if err != nil {
t.Fatalf("unable to restart dave: %v", err)
}
err = wait.Predicate(func() bool {
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
daveBalReq := &lnrpc.ChannelBalanceRequest{}
daveBalResp, err := dave.ChannelBalance(ctxt, daveBalReq)
if err != nil {
t.Fatalf("unable to get dave's balance: %v", err)
}
err = wait.NoError(func() error {
daveBalResp := dave.RPC.ChannelBalance()
if daveBalResp.LocalBalance.Sat != 0 { if daveBalResp.LocalBalance.Sat != 0 {
predErr = fmt.Errorf("Dave should end up with zero "+ return fmt.Errorf("Dave should end up with zero "+
"channel balance, instead has %d", "channel balance, instead has %d",
daveBalResp.LocalBalance.Sat) daveBalResp.LocalBalance.Sat)
return false
} }
return true return nil
}, defaultTimeout) }, defaultTimeout)
if err != nil { require.NoError(ht, err, "timeout checking dave's channel balance")
t.Fatalf("%v", predErr)
}
assertNumPendingChannels(t, dave, 0, 0) ht.AssertNumPendingForceClose(dave, 0)
err = wait.Predicate(func() bool { // Check that Dave's wallet balance is increased.
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) err = wait.NoError(func() error {
daveBalReq := &lnrpc.WalletBalanceRequest{} daveBalResp := dave.RPC.WalletBalance()
daveBalResp, err := dave.WalletBalance(ctxt, daveBalReq)
if err != nil {
t.Fatalf("unable to get dave's balance: %v", err)
}
if daveBalResp.ConfirmedBalance <= davePreSweepBalance { if daveBalResp.ConfirmedBalance <= davePreSweepBalance {
predErr = fmt.Errorf("Dave should have more than %d "+ return fmt.Errorf("Dave should have more than %d "+
"after sweep, instead has %d", "after sweep, instead has %d",
davePreSweepBalance, davePreSweepBalance,
daveBalResp.ConfirmedBalance) daveBalResp.ConfirmedBalance)
return false
} }
return true return nil
}, defaultTimeout) }, defaultTimeout)
if err != nil { require.NoError(ht, err, "timeout checking dave's wallet balance")
t.Fatalf("%v", predErr)
}
// Dave should have no open channels. // Dave should have no open channels.
assertNodeNumChannels(t, dave, 0) ht.AssertNodeNumChannels(dave, 0)
} }
-4
View File
@@ -72,10 +72,6 @@ var allTestCases = []*testCase{
name: "switch offline delivery outgoing offline", name: "switch offline delivery outgoing offline",
test: testSwitchOfflineDeliveryOutgoingOffline, test: testSwitchOfflineDeliveryOutgoingOffline,
}, },
{
name: "revoked uncooperative close retribution altruist watchtower",
test: testRevokedCloseRetributionAltruistWatchtower,
},
{ {
name: "query routes", name: "query routes",
test: testQueryRoutes, test: testQueryRoutes,