itest+lntemp: refactor testMultiHopHtlcClaims

This commit is contained in:
yyforyongyu 2022-07-28 20:15:22 +08:00
parent e629a3b45a
commit 4a7f45b5d4
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
3 changed files with 211 additions and 104 deletions

View File

@ -15,6 +15,10 @@ var allTestCasesTemp = []*lntemp.TestCase{
Name: "basic funding flow",
TestFunc: testBasicChannelFunding,
},
{
Name: "test multi-hop htlc",
TestFunc: testMultiHopHtlcClaims,
},
{
Name: "external channel funding",
TestFunc: testExternalFundingChanPoint,

View File

@ -10,63 +10,68 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
"github.com/lightningnetwork/lnd/lntemp"
"github.com/lightningnetwork/lnd/lntemp/node"
"github.com/lightningnetwork/lnd/lntemp/rpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/stretchr/testify/require"
)
func testMultiHopHtlcClaims(net *lntest.NetworkHarness, t *harnessTest) {
func testMultiHopHtlcClaims(ht *lntemp.HarnessTest) {
type testCase struct {
name string
test func(net *lntest.NetworkHarness, t *harnessTest, alice,
bob *lntest.HarnessNode, c lnrpc.CommitmentType,
zeroConf bool)
test func(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode,
c lnrpc.CommitmentType, zeroConf bool)
commitType lnrpc.CommitmentType
}
subTests := []testCase{
{
// bob: outgoing our commit timeout
// carol: incoming their commit watch and see timeout
name: "local force close immediate expiry",
test: testMultiHopHtlcLocalTimeout,
},
{
// bob: outgoing watch and see, they sweep on chain
// carol: incoming our commit, know preimage
name: "receiver chain claim",
test: testMultiHopReceiverChainClaim,
},
{
// bob: outgoing our commit watch and see timeout
// carol: incoming their commit watch and see timeout
name: "local force close on-chain htlc timeout",
test: testMultiHopLocalForceCloseOnChainHtlcTimeout,
},
{
// bob: outgoing their commit watch and see timeout
// carol: incoming our commit watch and see timeout
name: "remote force close on-chain htlc timeout",
test: testMultiHopRemoteForceCloseOnChainHtlcTimeout,
},
{
// bob: outgoing our commit watch and see, they sweep on chain
// bob: incoming our commit watch and learn preimage
// carol: incoming their commit know preimage
name: "local chain claim",
test: testMultiHopHtlcLocalChainClaim,
},
{
// bob: outgoing their commit watch and see, they sweep on chain
// bob: incoming their commit watch and learn preimage
// carol: incoming our commit know preimage
name: "remote chain claim",
test: testMultiHopHtlcRemoteChainClaim,
},
{
// bob: outgoing and incoming, sweep all on chain
name: "local htlc aggregation",
test: testMultiHopHtlcAggregation,
},
// {
// // bob: outgoing our commit timeout
// // carol: incoming their commit watch and see timeout
// name: "local force close immediate expiry",
// test: testMultiHopHtlcLocalTimeout,
// },
// {
// // bob: outgoing watch and see, they sweep on chain
// // carol: incoming our commit, know preimage
// name: "receiver chain claim",
// test: testMultiHopReceiverChainClaim,
// },
// {
// // bob: outgoing our commit watch and see timeout
// // carol: incoming their commit watch and see timeout
// name: "local force close on-chain htlc timeout",
// test: testMultiHopLocalForceCloseOnChainHtlcTimeout,
// },
// {
// // bob: outgoing their commit watch and see timeout
// // carol: incoming our commit watch and see timeout
// name: "remote force close on-chain htlc timeout",
// test: testMultiHopRemoteForceCloseOnChainHtlcTimeout,
// },
// {
// // bob: outgoing our commit watch and see, they sweep
// // on chain
// // bob: incoming our commit watch and learn preimage
// // carol: incoming their commit know preimage
// name: "local chain claim",
// test: testMultiHopHtlcLocalChainClaim,
// },
// {
// // bob: outgoing their commit watch and see, they sweep
// // on chain
// // bob: incoming their commit watch and learn preimage
// // carol: incoming our commit know preimage
// name: "remote chain claim",
// test: testMultiHopHtlcRemoteChainClaim,
// },
// {
// // bob: outgoing and incoming, sweep all on chain
// name: "local htlc aggregation",
// test: testMultiHopHtlcAggregation,
// },
}
commitWithZeroConf := []struct {
@ -95,63 +100,56 @@ func testMultiHopHtlcClaims(net *lntest.NetworkHarness, t *harnessTest) {
},
}
for _, typeAndConf := range commitWithZeroConf {
typeAndConf := typeAndConf
testName := fmt.Sprintf(
"committype=%v zeroconf=%v",
typeAndConf.commitType.String(), typeAndConf.zeroConf,
)
runTestCase := func(st *lntemp.HarnessTest, name string, tc testCase,
zeroConf bool) {
success := t.t.Run(testName, func(t *testing.T) {
ht := newHarnessTest(t, net)
// Create the nodes here so that separate logs will be created
// for Alice and Bob.
args := nodeArgsForCommitType(tc.commitType)
if zeroConf {
args = append(
args, "--protocol.option-scid-alias",
"--protocol.zero-conf",
)
}
args := nodeArgsForCommitType(typeAndConf.commitType)
alice := st.NewNode("Alice", args)
bob := st.NewNode("Bob", args)
st.ConnectNodes(alice, bob)
if typeAndConf.zeroConf {
args = append(
args, "--protocol.option-scid-alias",
"--protocol.zero-conf",
// Start each test with the default static fee estimate.
st.SetFeeEstimate(12500)
// Add test name to the logs.
alice.AddToLogf("Running test case: %s", name)
bob.AddToLogf("Running test case: %s", name)
tc.test(st, alice, bob, tc.commitType, zeroConf)
}
for _, subTest := range subTests {
subTest := subTest
for _, typeAndConf := range commitWithZeroConf {
typeAndConf := typeAndConf
subTest.commitType = typeAndConf.commitType
name := fmt.Sprintf("%s/zeroconf=%v/committype=%v",
subTest.name, typeAndConf.zeroConf,
typeAndConf.commitType.String())
s := ht.Run(name, func(t1 *testing.T) {
st, cleanup := ht.Subtest(t1)
defer cleanup()
runTestCase(
st, name, subTest, typeAndConf.zeroConf,
)
})
if !s {
return
}
alice := net.NewNode(t, "Alice", args)
defer shutdownAndAssert(net, ht, alice)
bob := net.NewNode(t, "Bob", args)
defer shutdownAndAssert(net, ht, bob)
net.ConnectNodes(t, alice, bob)
for _, subTest := range subTests {
subTest := subTest
logLine := fmt.Sprintf(
"---- multi-hop htlc subtest "+
"%s/%s ----\n",
testName, subTest.name,
)
net.Alice.AddToLogf(logLine)
success := ht.t.Run(subTest.name, func(t *testing.T) {
ht := newHarnessTest(t, net)
// Start each test with the default
// static fee estimate.
net.SetFeeEstimate(12500)
subTest.test(
net, ht, alice, bob,
typeAndConf.commitType,
typeAndConf.zeroConf,
)
})
if !success {
return
}
}
})
if !success {
return
}
}
}
@ -239,7 +237,7 @@ func checkPaymentStatus(node *lntest.HarnessNode, preimage lntypes.Preimage,
return nil
}
// TODO(yy): delete
// TODO(yy): delete.
func createThreeHopNetworkOld(t *harnessTest, net *lntest.NetworkHarness,
alice, bob *lntest.HarnessNode, carolHodl bool, c lnrpc.CommitmentType,
zeroConf bool) (
@ -396,3 +394,112 @@ func assertAllTxesSpendFrom(t *harnessTest, txes []*wire.MsgTx,
}
}
}
// createThreeHopNetwork creates a topology of `Alice -> Bob -> Carol`.
func createThreeHopNetwork(ht *lntemp.HarnessTest,
alice, bob *node.HarnessNode, carolHodl bool, c lnrpc.CommitmentType,
zeroConf bool) (*lnrpc.ChannelPoint,
*lnrpc.ChannelPoint, *node.HarnessNode) {
ht.EnsureConnected(alice, bob)
// We'll create a new node "carol" and have Bob connect to her.
// If the carolHodl flag is set, we'll make carol always hold onto the
// HTLC, this way it'll force Bob to go to chain to resolve the HTLC.
carolFlags := nodeArgsForCommitType(c)
if carolHodl {
carolFlags = append(carolFlags, "--hodl.exit-settle")
}
if zeroConf {
carolFlags = append(
carolFlags, "--protocol.option-scid-alias",
"--protocol.zero-conf",
)
}
carol := ht.NewNode("Carol", carolFlags)
ht.ConnectNodes(bob, carol)
// Make sure there are enough utxos for anchoring. Because the anchor
// by itself often doesn't meet the dust limit, a utxo from the wallet
// needs to be attached as an additional input. This can still lead to
// a positively-yielding transaction.
for i := 0; i < 2; i++ {
ht.FundCoins(btcutil.SatoshiPerBitcoin, alice)
ht.FundCoins(btcutil.SatoshiPerBitcoin, bob)
ht.FundCoins(btcutil.SatoshiPerBitcoin, carol)
}
// We'll start the test by creating a channel between Alice and Bob,
// which will act as the first leg for out multi-hop HTLC.
const chanAmt = 1000000
var aliceFundingShim *lnrpc.FundingShim
var thawHeight uint32
if c == lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE {
_, minerHeight := ht.Miner.GetBestBlock()
thawHeight = uint32(minerHeight + 144)
aliceFundingShim, _, _ = deriveFundingShim(
ht, alice, bob, chanAmt, thawHeight, true,
)
}
var (
cancel context.CancelFunc
acceptStream rpc.AcceptorClient
)
// If a zero-conf channel is being opened, the nodes are signalling the
// zero-conf feature bit. Setup a ChannelAcceptor for the fundee.
if zeroConf {
acceptStream, cancel = bob.RPC.ChannelAcceptor()
go acceptChannel(ht.T, true, acceptStream)
}
aliceParams := lntemp.OpenChannelParams{
Amt: chanAmt,
CommitmentType: c,
FundingShim: aliceFundingShim,
ZeroConf: zeroConf,
}
aliceChanPoint := ht.OpenChannel(alice, bob, aliceParams)
// Remove the ChannelAcceptor for Bob.
if zeroConf {
cancel()
}
// We'll then create a channel from Bob to Carol. After this channel is
// open, our topology looks like: A -> B -> C.
var bobFundingShim *lnrpc.FundingShim
if c == lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE {
bobFundingShim, _, _ = deriveFundingShim(
ht, bob, carol, chanAmt, thawHeight, true,
)
}
// Setup a ChannelAcceptor for Carol if a zero-conf channel open is
// being attempted.
if zeroConf {
acceptStream, cancel = carol.RPC.ChannelAcceptor()
go acceptChannel(ht.T, true, acceptStream)
}
bobParams := lntemp.OpenChannelParams{
Amt: chanAmt,
CommitmentType: c,
FundingShim: bobFundingShim,
ZeroConf: zeroConf,
}
bobChanPoint := ht.OpenChannel(bob, carol, bobParams)
// Remove the ChannelAcceptor for Carol.
if zeroConf {
cancel()
}
// Make sure alice and carol know each other's channels.
ht.AssertTopologyChannelOpen(alice, bobChanPoint)
ht.AssertTopologyChannelOpen(carol, aliceChanPoint)
return aliceChanPoint, bobChanPoint, carol
}

View File

@ -4,10 +4,6 @@
package itest
var allTestCases = []*testCase{
{
name: "test multi-hop htlc",
test: testMultiHopHtlcClaims,
},
{
name: "sweep coins",
test: testSweepAllCoins,