lntemp+itest: refactor testChannelForceClosure

This commit is contained in:
yyforyongyu 2022-08-04 22:19:46 +08:00
parent 61364c0d9d
commit 008ef964fc
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
6 changed files with 338 additions and 573 deletions

View File

@ -16,6 +16,7 @@ import (
"github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
"github.com/lightningnetwork/lnd/lntemp/node"
"github.com/lightningnetwork/lnd/lntemp/rpc"
"github.com/lightningnetwork/lnd/lntest"
@ -1523,3 +1524,107 @@ func (h *HarnessTest) CalculateTxesFeeRate(txns []*wire.MsgTx) int64 {
return feeRate
}
type SweptOutput struct {
OutPoint wire.OutPoint
SweepTx *wire.MsgTx
}
// FindCommitAndAnchor looks for a commitment sweep and anchor sweep in the
// mempool. Our anchor output is identified by having multiple inputs in its
// sweep transition, because we have to bring another input to add fees to the
// anchor. Note that the anchor swept output may be nil if the channel did not
// have anchors.
func (h *HarnessTest) FindCommitAndAnchor(sweepTxns []*wire.MsgTx,
closeTx string) (*SweptOutput, *SweptOutput) {
var commitSweep, anchorSweep *SweptOutput
for _, tx := range sweepTxns {
txHash := tx.TxHash()
sweepTx := h.Miner.GetRawTransaction(&txHash)
// We expect our commitment sweep to have a single input, and,
// our anchor sweep to have more inputs (because the wallet
// needs to add balance to the anchor amount). We find their
// sweep txids here to setup appropriate resolutions. We also
// need to find the outpoint for our resolution, which we do by
// matching the inputs to the sweep to the close transaction.
inputs := sweepTx.MsgTx().TxIn
if len(inputs) == 1 {
commitSweep = &SweptOutput{
OutPoint: inputs[0].PreviousOutPoint,
SweepTx: tx,
}
} else {
// Since we have more than one input, we run through
// them to find the one whose previous outpoint matches
// the closing txid, which means this input is spending
// the close tx. This will be our anchor output.
for _, txin := range inputs {
op := txin.PreviousOutPoint.Hash.String()
if op == closeTx {
anchorSweep = &SweptOutput{
OutPoint: txin.PreviousOutPoint,
SweepTx: tx,
}
}
}
}
}
return commitSweep, anchorSweep
}
// AssertSweepFound looks up a sweep in a nodes list of broadcast sweeps and
// asserts it's found.
//
// NOTE: Does not account for node's internal state.
func (h *HarnessTest) AssertSweepFound(hn *node.HarnessNode,
sweep string, verbose bool) {
// List all sweeps that alice's node had broadcast.
sweepResp := hn.RPC.ListSweeps(verbose)
var found bool
if verbose {
found = findSweepInDetails(h, sweep, sweepResp)
} else {
found = findSweepInTxids(h, sweep, sweepResp)
}
require.Truef(h, found, "%s: sweep: %v not found", sweep, hn.Name())
}
func findSweepInTxids(ht *HarnessTest, sweepTxid string,
sweepResp *walletrpc.ListSweepsResponse) bool {
sweepTxIDs := sweepResp.GetTransactionIds()
require.NotNil(ht, sweepTxIDs, "expected transaction ids")
require.Nil(ht, sweepResp.GetTransactionDetails())
// Check that the sweep tx we have just produced is present.
for _, tx := range sweepTxIDs.TransactionIds {
if tx == sweepTxid {
return true
}
}
return false
}
func findSweepInDetails(ht *HarnessTest, sweepTxid string,
sweepResp *walletrpc.ListSweepsResponse) bool {
sweepDetails := sweepResp.GetTransactionDetails()
require.NotNil(ht, sweepDetails, "expected transaction details")
require.Nil(ht, sweepResp.GetTransactionIds())
for _, tx := range sweepDetails.Transactions {
if tx.TxHash == sweepTxid {
return true
}
}
return false
}

View File

@ -124,3 +124,28 @@ func (h *HarnessRPC) ListAddresses(
return key
}
// ListSweeps makes a ListSweeps RPC call to the node's WalletKit client.
func (h *HarnessRPC) ListSweeps(verbose bool) *walletrpc.ListSweepsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &walletrpc.ListSweepsRequest{Verbose: verbose}
resp, err := h.WalletKit.ListSweeps(ctxt, req)
h.NoError(err, "ListSweeps")
return resp
}
// PendingSweeps makes a RPC call to the node's WalletKitClient and asserts.
func (h *HarnessRPC) PendingSweeps() *walletrpc.PendingSweepsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &walletrpc.PendingSweepsRequest{}
resp, err := h.WalletKit.PendingSweeps(ctxt, req)
h.NoError(err, "PendingSweeps")
return resp
}

View File

@ -17,7 +17,6 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/stretchr/testify/require"
@ -815,100 +814,6 @@ func checkPendingHtlcStageAndMaturity(
return nil
}
// assertReports checks that the count of resolutions we have present per
// type matches a set of expected resolutions.
func assertReports(t *harnessTest, node *lntest.HarnessNode,
channelPoint wire.OutPoint, expected map[string]*lnrpc.Resolution) {
// Get our node's closed channels.
ctxb := context.Background()
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
closed, err := node.ClosedChannels(
ctxt, &lnrpc.ClosedChannelsRequest{},
)
require.NoError(t.t, err)
var resolutions []*lnrpc.Resolution
for _, close := range closed.Channels {
if close.ChannelPoint == channelPoint.String() {
resolutions = close.Resolutions
break
}
}
require.NotNil(t.t, resolutions)
require.Equal(t.t, len(expected), len(resolutions))
for _, res := range resolutions {
outPointStr := fmt.Sprintf("%v:%v", res.Outpoint.TxidStr,
res.Outpoint.OutputIndex)
expected, ok := expected[outPointStr]
require.True(t.t, ok)
require.Equal(t.t, expected, res)
}
}
// assertSweepFound looks up a sweep in a nodes list of broadcast sweeps.
func assertSweepFound(t *testing.T, node *lntest.HarnessNode,
sweep string, verbose bool) {
// List all sweeps that alice's node had broadcast.
ctxb := context.Background()
ctx, cancel := context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
sweepResp, err := node.WalletKitClient.ListSweeps(
ctx, &walletrpc.ListSweepsRequest{
Verbose: verbose,
},
)
require.NoError(t, err)
var found bool
if verbose {
found = findSweepInDetails(t, sweep, sweepResp)
} else {
found = findSweepInTxids(t, sweep, sweepResp)
}
require.True(t, found, "sweep: %v not found", sweep)
}
func findSweepInTxids(t *testing.T, sweepTxid string,
sweepResp *walletrpc.ListSweepsResponse) bool {
sweepTxIDs := sweepResp.GetTransactionIds()
require.NotNil(t, sweepTxIDs, "expected transaction ids")
require.Nil(t, sweepResp.GetTransactionDetails())
// Check that the sweep tx we have just produced is present.
for _, tx := range sweepTxIDs.TransactionIds {
if tx == sweepTxid {
return true
}
}
return false
}
func findSweepInDetails(t *testing.T, sweepTxid string,
sweepResp *walletrpc.ListSweepsResponse) bool {
sweepDetails := sweepResp.GetTransactionDetails()
require.NotNil(t, sweepDetails, "expected transaction details")
require.Nil(t, sweepResp.GetTransactionIds())
for _, tx := range sweepDetails.Transactions {
if tx.TxHash == sweepTxid {
return true
}
}
return false
}
// assertAmountSent generates a closure which queries listchannels for sndr and
// rcvr, and asserts that sndr sent amt satoshis, and that rcvr received amt
// satoshis.

View File

@ -211,4 +211,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
Name: "commitment deadline",
TestFunc: testCommitmentTransactionDeadline,
},
{
Name: "channel force closure",
TestFunc: testChannelForceClosure,
},
}

File diff suppressed because it is too large Load Diff

View File

@ -8,10 +8,6 @@ var allTestCases = []*testCase{
name: "open channel reorg test",
test: testOpenChannelAfterReorg,
},
{
name: "channel force closure",
test: testChannelForceClosure,
},
{
name: "single hop invoice",
test: testSingleHopInvoice,