itest+lntemp: refactor testMultiHopHtlcClaims
This commit is contained in:
3 files changed
+211
-104
No files matched your search
@@ -15,6 +15,10 @@ var allTestCasesTemp = []*lntemp.TestCase{
|
|||||||
Name: "basic funding flow",
|
Name: "basic funding flow",
|
||||||
TestFunc: testBasicChannelFunding,
|
TestFunc: testBasicChannelFunding,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "test multi-hop htlc",
|
||||||
|
TestFunc: testMultiHopHtlcClaims,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "external channel funding",
|
Name: "external channel funding",
|
||||||
TestFunc: testExternalFundingChanPoint,
|
TestFunc: testExternalFundingChanPoint,
|
||||||
|
|||||||
+207
-100
@@ -10,63 +10,68 @@ import (
|
|||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
"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/lntest"
|
||||||
"github.com/lightningnetwork/lnd/lntypes"
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testMultiHopHtlcClaims(net *lntest.NetworkHarness, t *harnessTest) {
|
func testMultiHopHtlcClaims(ht *lntemp.HarnessTest) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
name string
|
name string
|
||||||
test func(net *lntest.NetworkHarness, t *harnessTest, alice,
|
test func(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode,
|
||||||
bob *lntest.HarnessNode, c lnrpc.CommitmentType,
|
c lnrpc.CommitmentType, zeroConf bool)
|
||||||
zeroConf bool)
|
commitType lnrpc.CommitmentType
|
||||||
}
|
}
|
||||||
|
|
||||||
subTests := []testCase{
|
subTests := []testCase{
|
||||||
{
|
// {
|
||||||
// bob: outgoing our commit timeout
|
// // bob: outgoing our commit timeout
|
||||||
// carol: incoming their commit watch and see timeout
|
// // carol: incoming their commit watch and see timeout
|
||||||
name: "local force close immediate expiry",
|
// name: "local force close immediate expiry",
|
||||||
test: testMultiHopHtlcLocalTimeout,
|
// test: testMultiHopHtlcLocalTimeout,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
// bob: outgoing watch and see, they sweep on chain
|
// // bob: outgoing watch and see, they sweep on chain
|
||||||
// carol: incoming our commit, know preimage
|
// // carol: incoming our commit, know preimage
|
||||||
name: "receiver chain claim",
|
// name: "receiver chain claim",
|
||||||
test: testMultiHopReceiverChainClaim,
|
// test: testMultiHopReceiverChainClaim,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
// bob: outgoing our commit watch and see timeout
|
// // bob: outgoing our commit watch and see timeout
|
||||||
// carol: incoming their commit watch and see timeout
|
// // carol: incoming their commit watch and see timeout
|
||||||
name: "local force close on-chain htlc timeout",
|
// name: "local force close on-chain htlc timeout",
|
||||||
test: testMultiHopLocalForceCloseOnChainHtlcTimeout,
|
// test: testMultiHopLocalForceCloseOnChainHtlcTimeout,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
// bob: outgoing their commit watch and see timeout
|
// // bob: outgoing their commit watch and see timeout
|
||||||
// carol: incoming our commit watch and see timeout
|
// // carol: incoming our commit watch and see timeout
|
||||||
name: "remote force close on-chain htlc timeout",
|
// name: "remote force close on-chain htlc timeout",
|
||||||
test: testMultiHopRemoteForceCloseOnChainHtlcTimeout,
|
// test: testMultiHopRemoteForceCloseOnChainHtlcTimeout,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
// bob: outgoing our commit watch and see, they sweep on chain
|
// // bob: outgoing our commit watch and see, they sweep
|
||||||
// bob: incoming our commit watch and learn preimage
|
// // on chain
|
||||||
// carol: incoming their commit know preimage
|
// // bob: incoming our commit watch and learn preimage
|
||||||
name: "local chain claim",
|
// // carol: incoming their commit know preimage
|
||||||
test: testMultiHopHtlcLocalChainClaim,
|
// 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
|
// // bob: outgoing their commit watch and see, they sweep
|
||||||
// carol: incoming our commit know preimage
|
// // on chain
|
||||||
name: "remote chain claim",
|
// // bob: incoming their commit watch and learn preimage
|
||||||
test: testMultiHopHtlcRemoteChainClaim,
|
// // 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 and incoming, sweep all on chain
|
||||||
},
|
// name: "local htlc aggregation",
|
||||||
|
// test: testMultiHopHtlcAggregation,
|
||||||
|
// },
|
||||||
}
|
}
|
||||||
|
|
||||||
commitWithZeroConf := []struct {
|
commitWithZeroConf := []struct {
|
||||||
@@ -95,63 +100,56 @@ func testMultiHopHtlcClaims(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, typeAndConf := range commitWithZeroConf {
|
runTestCase := func(st *lntemp.HarnessTest, name string, tc testCase,
|
||||||
typeAndConf := typeAndConf
|
zeroConf bool) {
|
||||||
testName := fmt.Sprintf(
|
|
||||||
"committype=%v zeroconf=%v",
|
|
||||||
typeAndConf.commitType.String(), typeAndConf.zeroConf,
|
|
||||||
)
|
|
||||||
|
|
||||||
success := t.t.Run(testName, func(t *testing.T) {
|
// Create the nodes here so that separate logs will be created
|
||||||
ht := newHarnessTest(t, net)
|
// 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 {
|
// Start each test with the default static fee estimate.
|
||||||
args = append(
|
st.SetFeeEstimate(12500)
|
||||||
args, "--protocol.option-scid-alias",
|
|
||||||
"--protocol.zero-conf",
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(yy): delete
|
// TODO(yy): delete.
|
||||||
func createThreeHopNetworkOld(t *harnessTest, net *lntest.NetworkHarness,
|
func createThreeHopNetworkOld(t *harnessTest, net *lntest.NetworkHarness,
|
||||||
alice, bob *lntest.HarnessNode, carolHodl bool, c lnrpc.CommitmentType,
|
alice, bob *lntest.HarnessNode, carolHodl bool, c lnrpc.CommitmentType,
|
||||||
zeroConf bool) (
|
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
|
||||||
|
}
|
||||||
@@ -4,10 +4,6 @@
|
|||||||
package itest
|
package itest
|
||||||
|
|
||||||
var allTestCases = []*testCase{
|
var allTestCases = []*testCase{
|
||||||
{
|
|
||||||
name: "test multi-hop htlc",
|
|
||||||
test: testMultiHopHtlcClaims,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "sweep coins",
|
name: "sweep coins",
|
||||||
test: testSweepAllCoins,
|
test: testSweepAllCoins,
|
||||||
|
|||||||
Reference in new issue
Block a user