itest: break down basic funding flow tests
This commit is contained in:
2 files changed
+215
-150
No files matched your search
@@ -11,10 +11,6 @@ var allTestCases = []*lntest.TestCase{
|
|||||||
Name: "update channel status",
|
Name: "update channel status",
|
||||||
TestFunc: testUpdateChanStatus,
|
TestFunc: testUpdateChanStatus,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Name: "basic funding flow",
|
|
||||||
TestFunc: testBasicChannelFunding,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Name: "external channel funding",
|
Name: "external channel funding",
|
||||||
TestFunc: testExternalFundingChanPoint,
|
TestFunc: testExternalFundingChanPoint,
|
||||||
@@ -681,4 +677,5 @@ func init() {
|
|||||||
allTestCases = append(allTestCases, zeroConfPolicyTestCases...)
|
allTestCases = append(allTestCases, zeroConfPolicyTestCases...)
|
||||||
allTestCases = append(allTestCases, channelFeePolicyTestCases...)
|
allTestCases = append(allTestCases, channelFeePolicyTestCases...)
|
||||||
allTestCases = append(allTestCases, walletImportAccountTestCases...)
|
allTestCases = append(allTestCases, walletImportAccountTestCases...)
|
||||||
|
allTestCases = append(allTestCases, basicFundingTestCases...)
|
||||||
}
|
}
|
||||||
+214
-146
@@ -20,165 +20,233 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// testBasicChannelFunding performs a test exercising expected behavior from a
|
// basicFundingTestCases defines the test cases for the basic funding test.
|
||||||
// basic funding workflow. The test creates a new channel between Alice and
|
var basicFundingTestCases = []*lntest.TestCase{
|
||||||
// Bob, then immediately closes the channel after asserting some expected post
|
{
|
||||||
// conditions. Finally, the chain itself is checked to ensure the closing
|
Name: "basic funding flow static key remote",
|
||||||
// transaction was mined.
|
TestFunc: testBasicChannelFundingStaticRemote,
|
||||||
func testBasicChannelFunding(ht *lntest.HarnessTest) {
|
},
|
||||||
// Run through the test with combinations of all the different
|
{
|
||||||
// commitment types.
|
Name: "basic funding flow anchor",
|
||||||
allTypes := []lnrpc.CommitmentType{
|
TestFunc: testBasicChannelFundingAnchor,
|
||||||
lnrpc.CommitmentType_STATIC_REMOTE_KEY,
|
},
|
||||||
lnrpc.CommitmentType_ANCHORS,
|
{
|
||||||
lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
Name: "basic funding flow simple taproot",
|
||||||
}
|
TestFunc: testBasicChannelFundingSimpleTaproot,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// testFunding is a function closure that takes Carol and Dave's
|
// allFundingTypes defines the channel types to test for the basic funding
|
||||||
// commitment types and test the funding flow.
|
// test.
|
||||||
testFunding := func(ht *lntest.HarnessTest, carolCommitType,
|
var allFundingTypes = []lnrpc.CommitmentType{
|
||||||
daveCommitType lnrpc.CommitmentType) {
|
lnrpc.CommitmentType_STATIC_REMOTE_KEY,
|
||||||
|
lnrpc.CommitmentType_ANCHORS,
|
||||||
|
lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||||
|
}
|
||||||
|
|
||||||
// Based on the current tweak variable for Carol, we'll
|
// testBasicChannelFundingStaticRemote performs a test exercising expected
|
||||||
// preferentially signal the legacy commitment format. We do
|
// behavior from a basic funding workflow. The test creates a new channel
|
||||||
// the same for Dave shortly below.
|
// between Carol and Dave, with Carol using the static remote key commitment
|
||||||
carolArgs := lntest.NodeArgsForCommitType(carolCommitType)
|
// type, and Dave using allFundingTypes.
|
||||||
carol := ht.NewNode("Carol", carolArgs)
|
func testBasicChannelFundingStaticRemote(ht *lntest.HarnessTest) {
|
||||||
|
carolCommitType := lnrpc.CommitmentType_STATIC_REMOTE_KEY
|
||||||
|
|
||||||
// Each time, we'll send Carol a new set of coins in order to
|
|
||||||
// fund the channel.
|
|
||||||
ht.FundCoins(btcutil.SatoshiPerBitcoin, carol)
|
|
||||||
|
|
||||||
daveArgs := lntest.NodeArgsForCommitType(daveCommitType)
|
|
||||||
dave := ht.NewNode("Dave", daveArgs)
|
|
||||||
|
|
||||||
// Before we start the test, we'll ensure both sides are
|
|
||||||
// connected to the funding flow can properly be executed.
|
|
||||||
ht.EnsureConnected(carol, dave)
|
|
||||||
|
|
||||||
var privateChan bool
|
|
||||||
|
|
||||||
// If this is to be a taproot channel type, then it needs to be
|
|
||||||
// private, otherwise it'll be rejected by Dave.
|
|
||||||
//
|
|
||||||
// TODO(roasbeef): lift after gossip 1.75
|
|
||||||
if carolCommitType == lnrpc.CommitmentType_SIMPLE_TAPROOT {
|
|
||||||
privateChan = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If carol wants taproot, but dave wants something
|
|
||||||
// else, then we'll assert that the channel negotiation
|
|
||||||
// attempt fails.
|
|
||||||
if carolCommitType == lnrpc.CommitmentType_SIMPLE_TAPROOT &&
|
|
||||||
daveCommitType != lnrpc.CommitmentType_SIMPLE_TAPROOT {
|
|
||||||
|
|
||||||
expectedErr := fmt.Errorf("requested channel type " +
|
|
||||||
"not supported")
|
|
||||||
amt := funding.MaxBtcFundingAmount
|
|
||||||
ht.OpenChannelAssertErr(
|
|
||||||
carol, dave, lntest.OpenChannelParams{
|
|
||||||
Private: privateChan,
|
|
||||||
Amt: amt,
|
|
||||||
CommitmentType: carolCommitType,
|
|
||||||
}, expectedErr,
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
carolChan, daveChan := basicChannelFundingTest(
|
|
||||||
ht, carol, dave, nil, privateChan, &carolCommitType,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Both nodes should report the same commitment
|
|
||||||
// type.
|
|
||||||
chansCommitType := carolChan.CommitmentType
|
|
||||||
require.Equal(ht, chansCommitType, daveChan.CommitmentType,
|
|
||||||
"commit types don't match")
|
|
||||||
|
|
||||||
// Now check that the commitment type reported by both nodes is
|
|
||||||
// what we expect. It will be the minimum of the two nodes'
|
|
||||||
// preference, in the order Legacy, Tweakless, Anchors.
|
|
||||||
expType := carolCommitType
|
|
||||||
|
|
||||||
switch daveCommitType {
|
|
||||||
// Dave supports taproot, type will be what Carol supports.
|
|
||||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
|
||||||
|
|
||||||
// Dave supports anchors, type will be what Carol supports.
|
|
||||||
case lnrpc.CommitmentType_ANCHORS:
|
|
||||||
// However if Alice wants taproot chans, then we
|
|
||||||
// downgrade to anchors as this is still using implicit
|
|
||||||
// negotiation.
|
|
||||||
if expType == lnrpc.CommitmentType_SIMPLE_TAPROOT {
|
|
||||||
expType = lnrpc.CommitmentType_ANCHORS
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dave only supports tweakless, channel will be downgraded to
|
|
||||||
// this type if Carol supports anchors.
|
|
||||||
case lnrpc.CommitmentType_STATIC_REMOTE_KEY:
|
|
||||||
switch expType {
|
|
||||||
case lnrpc.CommitmentType_ANCHORS:
|
|
||||||
expType = lnrpc.CommitmentType_STATIC_REMOTE_KEY
|
|
||||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
|
||||||
expType = lnrpc.CommitmentType_STATIC_REMOTE_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dave only supports legacy type, channel will be downgraded
|
|
||||||
// to this type.
|
|
||||||
case lnrpc.CommitmentType_LEGACY:
|
|
||||||
expType = lnrpc.CommitmentType_LEGACY
|
|
||||||
|
|
||||||
default:
|
|
||||||
ht.Fatalf("invalid commit type %v", daveCommitType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the signalled type matches what we expect.
|
|
||||||
switch {
|
|
||||||
case expType == lnrpc.CommitmentType_ANCHORS &&
|
|
||||||
chansCommitType == lnrpc.CommitmentType_ANCHORS:
|
|
||||||
|
|
||||||
case expType == lnrpc.CommitmentType_STATIC_REMOTE_KEY &&
|
|
||||||
chansCommitType == lnrpc.CommitmentType_STATIC_REMOTE_KEY: //nolint:ll
|
|
||||||
|
|
||||||
case expType == lnrpc.CommitmentType_LEGACY &&
|
|
||||||
chansCommitType == lnrpc.CommitmentType_LEGACY:
|
|
||||||
|
|
||||||
case expType == lnrpc.CommitmentType_SIMPLE_TAPROOT &&
|
|
||||||
chansCommitType == lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
|
||||||
|
|
||||||
default:
|
|
||||||
ht.Fatalf("expected nodes to signal "+
|
|
||||||
"commit type %v, instead got "+
|
|
||||||
"%v", expType, chansCommitType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test:
|
|
||||||
// We'll test all possible combinations of the feature bit presence
|
// We'll test all possible combinations of the feature bit presence
|
||||||
// that both nodes can signal for this new channel type. We'll make a
|
// that both nodes can signal for this new channel type. We'll make a
|
||||||
// new Carol+Dave for each test instance as well.
|
// new Carol+Dave for each test instance as well.
|
||||||
for _, carolCommitType := range allTypes {
|
for _, daveCommitType := range allFundingTypes {
|
||||||
for _, daveCommitType := range allTypes {
|
cc := carolCommitType
|
||||||
cc := carolCommitType
|
dc := daveCommitType
|
||||||
dc := daveCommitType
|
|
||||||
|
|
||||||
testName := fmt.Sprintf(
|
testName := fmt.Sprintf(
|
||||||
"carol_commit=%v,dave_commit=%v", cc, dc,
|
"carol_commit=%v,dave_commit=%v", cc, dc,
|
||||||
)
|
)
|
||||||
|
|
||||||
success := ht.Run(testName, func(t *testing.T) {
|
success := ht.Run(testName, func(t *testing.T) {
|
||||||
st := ht.Subtest(t)
|
st := ht.Subtest(t)
|
||||||
testFunding(st, cc, dc)
|
runBasicFundingTest(st, cc, dc)
|
||||||
})
|
})
|
||||||
|
|
||||||
if !success {
|
if !success {
|
||||||
break test
|
break
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testBasicChannelFundingAnchor performs a test exercising expected behavior
|
||||||
|
// from a basic funding workflow. The test creates a new channel between Carol
|
||||||
|
// and Dave, with Carol using the anchor commitment type, and Dave using
|
||||||
|
// allFundingTypes.
|
||||||
|
func testBasicChannelFundingAnchor(ht *lntest.HarnessTest) {
|
||||||
|
carolCommitType := lnrpc.CommitmentType_ANCHORS
|
||||||
|
|
||||||
|
// We'll test all possible combinations of the feature bit presence
|
||||||
|
// that both nodes can signal for this new channel type. We'll make a
|
||||||
|
// new Carol+Dave for each test instance as well.
|
||||||
|
for _, daveCommitType := range allFundingTypes {
|
||||||
|
cc := carolCommitType
|
||||||
|
dc := daveCommitType
|
||||||
|
|
||||||
|
testName := fmt.Sprintf(
|
||||||
|
"carol_commit=%v,dave_commit=%v", cc, dc,
|
||||||
|
)
|
||||||
|
|
||||||
|
success := ht.Run(testName, func(t *testing.T) {
|
||||||
|
st := ht.Subtest(t)
|
||||||
|
runBasicFundingTest(st, cc, dc)
|
||||||
|
})
|
||||||
|
|
||||||
|
if !success {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// testBasicChannelFundingSimpleTaproot performs a test exercising expected
|
||||||
|
// behavior from a basic funding workflow. The test creates a new channel
|
||||||
|
// between Carol and Dave, with Carol using the simple taproot commitment type,
|
||||||
|
// and Dave using allFundingTypes.
|
||||||
|
func testBasicChannelFundingSimpleTaproot(ht *lntest.HarnessTest) {
|
||||||
|
carolCommitType := lnrpc.CommitmentType_SIMPLE_TAPROOT
|
||||||
|
|
||||||
|
// We'll test all possible combinations of the feature bit presence
|
||||||
|
// that both nodes can signal for this new channel type. We'll make a
|
||||||
|
// new Carol+Dave for each test instance as well.
|
||||||
|
for _, daveCommitType := range allFundingTypes {
|
||||||
|
cc := carolCommitType
|
||||||
|
dc := daveCommitType
|
||||||
|
|
||||||
|
testName := fmt.Sprintf(
|
||||||
|
"carol_commit=%v,dave_commit=%v", cc, dc,
|
||||||
|
)
|
||||||
|
|
||||||
|
success := ht.Run(testName, func(t *testing.T) {
|
||||||
|
st := ht.Subtest(t)
|
||||||
|
runBasicFundingTest(st, cc, dc)
|
||||||
|
})
|
||||||
|
|
||||||
|
if !success {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// runBasicFundingTest is a helper function that takes Carol and Dave's
|
||||||
|
// commitment types and test the funding flow.
|
||||||
|
func runBasicFundingTest(ht *lntest.HarnessTest, carolCommitType,
|
||||||
|
daveCommitType lnrpc.CommitmentType) {
|
||||||
|
|
||||||
|
// Based on the current tweak variable for Carol, we'll preferentially
|
||||||
|
// signal the legacy commitment format. We do the same for Dave
|
||||||
|
// shortly below.
|
||||||
|
carolArgs := lntest.NodeArgsForCommitType(carolCommitType)
|
||||||
|
carol := ht.NewNode("Carol", carolArgs)
|
||||||
|
|
||||||
|
// Each time, we'll send Carol a new set of coins in order to fund the
|
||||||
|
// channel.
|
||||||
|
ht.FundCoins(btcutil.SatoshiPerBitcoin, carol)
|
||||||
|
|
||||||
|
daveArgs := lntest.NodeArgsForCommitType(daveCommitType)
|
||||||
|
dave := ht.NewNode("Dave", daveArgs)
|
||||||
|
|
||||||
|
// Before we start the test, we'll ensure both sides are connected to
|
||||||
|
// the funding flow can properly be executed.
|
||||||
|
ht.EnsureConnected(carol, dave)
|
||||||
|
|
||||||
|
var privateChan bool
|
||||||
|
|
||||||
|
// If this is to be a taproot channel type, then it needs to be
|
||||||
|
// private, otherwise it'll be rejected by Dave.
|
||||||
|
//
|
||||||
|
// TODO(roasbeef): lift after gossip 1.75
|
||||||
|
if carolCommitType == lnrpc.CommitmentType_SIMPLE_TAPROOT {
|
||||||
|
privateChan = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// If carol wants taproot, but dave wants something else, then we'll
|
||||||
|
// assert that the channel negotiation attempt fails.
|
||||||
|
if carolCommitType == lnrpc.CommitmentType_SIMPLE_TAPROOT &&
|
||||||
|
daveCommitType != lnrpc.CommitmentType_SIMPLE_TAPROOT {
|
||||||
|
|
||||||
|
expectedErr := fmt.Errorf("requested channel type " +
|
||||||
|
"not supported")
|
||||||
|
amt := funding.MaxBtcFundingAmount
|
||||||
|
ht.OpenChannelAssertErr(
|
||||||
|
carol, dave, lntest.OpenChannelParams{
|
||||||
|
Private: privateChan,
|
||||||
|
Amt: amt,
|
||||||
|
CommitmentType: carolCommitType,
|
||||||
|
}, expectedErr,
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
carolChan, daveChan := basicChannelFundingTest(
|
||||||
|
ht, carol, dave, nil, privateChan, &carolCommitType,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Both nodes should report the same commitment type.
|
||||||
|
chansCommitType := carolChan.CommitmentType
|
||||||
|
require.Equal(ht, chansCommitType, daveChan.CommitmentType,
|
||||||
|
"commit types don't match")
|
||||||
|
|
||||||
|
// Now check that the commitment type reported by both nodes is what we
|
||||||
|
// expect. It will be the minimum of the two nodes' preference, in the
|
||||||
|
// order Legacy, Tweakless, Anchors.
|
||||||
|
expType := carolCommitType
|
||||||
|
|
||||||
|
switch daveCommitType {
|
||||||
|
// Dave supports taproot, type will be what Carol supports.
|
||||||
|
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||||
|
|
||||||
|
// Dave supports anchors, type will be what Carol supports.
|
||||||
|
case lnrpc.CommitmentType_ANCHORS:
|
||||||
|
// However if Alice wants taproot chans, then we downgrade to
|
||||||
|
// anchors as this is still using implicit negotiation.
|
||||||
|
if expType == lnrpc.CommitmentType_SIMPLE_TAPROOT {
|
||||||
|
expType = lnrpc.CommitmentType_ANCHORS
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dave only supports tweakless, channel will be downgraded to this
|
||||||
|
// type if Carol supports anchors.
|
||||||
|
case lnrpc.CommitmentType_STATIC_REMOTE_KEY:
|
||||||
|
switch expType {
|
||||||
|
case lnrpc.CommitmentType_ANCHORS:
|
||||||
|
expType = lnrpc.CommitmentType_STATIC_REMOTE_KEY
|
||||||
|
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||||
|
expType = lnrpc.CommitmentType_STATIC_REMOTE_KEY
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dave only supports legacy type, channel will be downgraded to this
|
||||||
|
// type.
|
||||||
|
case lnrpc.CommitmentType_LEGACY:
|
||||||
|
expType = lnrpc.CommitmentType_LEGACY
|
||||||
|
|
||||||
|
default:
|
||||||
|
ht.Fatalf("invalid commit type %v", daveCommitType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the signalled type matches what we expect.
|
||||||
|
switch {
|
||||||
|
case expType == lnrpc.CommitmentType_ANCHORS &&
|
||||||
|
chansCommitType == lnrpc.CommitmentType_ANCHORS:
|
||||||
|
|
||||||
|
case expType == lnrpc.CommitmentType_STATIC_REMOTE_KEY &&
|
||||||
|
chansCommitType == lnrpc.CommitmentType_STATIC_REMOTE_KEY:
|
||||||
|
|
||||||
|
case expType == lnrpc.CommitmentType_LEGACY &&
|
||||||
|
chansCommitType == lnrpc.CommitmentType_LEGACY:
|
||||||
|
|
||||||
|
case expType == lnrpc.CommitmentType_SIMPLE_TAPROOT &&
|
||||||
|
chansCommitType == lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||||
|
|
||||||
|
default:
|
||||||
|
ht.Fatalf("expected nodes to signal commit type %v, instead "+
|
||||||
|
"got %v", expType, chansCommitType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// basicChannelFundingTest is a sub-test of the main testBasicChannelFunding
|
// basicChannelFundingTest is a sub-test of the main testBasicChannelFunding
|
||||||
// test. Given two nodes: Alice and Bob, it'll assert proper channel creation,
|
// test. Given two nodes: Alice and Bob, it'll assert proper channel creation,
|
||||||
// then return a function closure that should be called to assert proper
|
// then return a function closure that should be called to assert proper
|
||||||
|
|||||||
Reference in new issue
Block a user