funding: add unit tests for reg+zero conf taproot chans
This commit is contained in:
1 file changed
+202
-22
+202
-22
@@ -33,6 +33,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lntest/mock"
|
"github.com/lightningnetwork/lnd/lntest/mock"
|
||||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||||
|
"github.com/lightningnetwork/lnd/lnutils"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
@@ -384,9 +385,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
|
|||||||
wc := &mock.WalletController{
|
wc := &mock.WalletController{
|
||||||
RootKey: alicePrivKey,
|
RootKey: alicePrivKey,
|
||||||
}
|
}
|
||||||
signer := &mock.SingleSigner{
|
signer := mock.NewSingleSigner(alicePrivKey)
|
||||||
Privkey: alicePrivKey,
|
|
||||||
}
|
|
||||||
bio := &mock.ChainIO{
|
bio := &mock.ChainIO{
|
||||||
BestHeight: fundingBroadcastHeight,
|
BestHeight: fundingBroadcastHeight,
|
||||||
}
|
}
|
||||||
@@ -720,12 +719,13 @@ func tearDownFundingManagers(t *testing.T, a, b *testNode) {
|
|||||||
// transaction is confirmed on-chain. Returns the funding out point.
|
// transaction is confirmed on-chain. Returns the funding out point.
|
||||||
func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
||||||
pushAmt btcutil.Amount, numConfs uint32,
|
pushAmt btcutil.Amount, numConfs uint32,
|
||||||
updateChan chan *lnrpc.OpenStatusUpdate, announceChan bool) (
|
updateChan chan *lnrpc.OpenStatusUpdate, announceChan bool,
|
||||||
|
chanType *lnwire.ChannelType) (
|
||||||
*wire.OutPoint, *wire.MsgTx) {
|
*wire.OutPoint, *wire.MsgTx) {
|
||||||
|
|
||||||
publ := fundChannel(
|
publ := fundChannel(
|
||||||
t, alice, bob, localFundingAmt, pushAmt, false, 0, 0, numConfs,
|
t, alice, bob, localFundingAmt, pushAmt, false, 0, 0, numConfs,
|
||||||
updateChan, announceChan, nil,
|
updateChan, announceChan, chanType,
|
||||||
)
|
)
|
||||||
fundingOutPoint := &wire.OutPoint{
|
fundingOutPoint := &wire.OutPoint{
|
||||||
Hash: publ.TxHash(),
|
Hash: publ.TxHash(),
|
||||||
@@ -734,6 +734,18 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
|||||||
return fundingOutPoint, publ
|
return fundingOutPoint, publ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isTaprootChanType(chanType *lnwire.ChannelType) bool {
|
||||||
|
if chanType == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
featVec := lnwire.RawFeatureVector(*chanType)
|
||||||
|
|
||||||
|
return featVec.IsSet(
|
||||||
|
lnwire.SimpleTaprootChannelsRequired,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// fundChannel takes the funding process to the point where the funding
|
// fundChannel takes the funding process to the point where the funding
|
||||||
// transaction is confirmed on-chain. Returns the funding tx.
|
// transaction is confirmed on-chain. Returns the funding tx.
|
||||||
func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
||||||
@@ -761,6 +773,12 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
|||||||
Err: errChan,
|
Err: errChan,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a taproot channel, then we want to force it to be a
|
||||||
|
// private channel, as that's the only channel type supported for now.
|
||||||
|
if isTaprootChanType(chanType) {
|
||||||
|
initReq.Private = true
|
||||||
|
}
|
||||||
|
|
||||||
alice.fundingMgr.InitFundingWorkflow(initReq)
|
alice.fundingMgr.InitFundingWorkflow(initReq)
|
||||||
|
|
||||||
// Alice should have sent the OpenChannel message to Bob.
|
// Alice should have sent the OpenChannel message to Bob.
|
||||||
@@ -785,6 +803,11 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
|||||||
"alice, instead got %T", aliceMsg)
|
"alice, instead got %T", aliceMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For taproot channel types, the nonce should be set.
|
||||||
|
if isTaprootChanType(chanType) {
|
||||||
|
require.NotNil(t, openChannelReq.LocalNonce)
|
||||||
|
}
|
||||||
|
|
||||||
// Let Bob handle the init message.
|
// Let Bob handle the init message.
|
||||||
bob.fundingMgr.ProcessFundingMsg(openChannelReq, alice)
|
bob.fundingMgr.ProcessFundingMsg(openChannelReq, alice)
|
||||||
|
|
||||||
@@ -793,6 +816,11 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
|||||||
t, bob.msgChan, "AcceptChannel",
|
t, bob.msgChan, "AcceptChannel",
|
||||||
).(*lnwire.AcceptChannel)
|
).(*lnwire.AcceptChannel)
|
||||||
|
|
||||||
|
// For taproot channel types, the nonce should be set.
|
||||||
|
if isTaprootChanType(chanType) {
|
||||||
|
require.NotNil(t, acceptChannelResponse.LocalNonce)
|
||||||
|
}
|
||||||
|
|
||||||
// They now should both have pending reservations for this channel
|
// They now should both have pending reservations for this channel
|
||||||
// active.
|
// active.
|
||||||
assertNumPendingReservations(t, alice, bobPubKey, 1)
|
assertNumPendingReservations(t, alice, bobPubKey, 1)
|
||||||
@@ -814,6 +842,11 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
|||||||
t, alice.msgChan, "FundingCreated",
|
t, alice.msgChan, "FundingCreated",
|
||||||
).(*lnwire.FundingCreated)
|
).(*lnwire.FundingCreated)
|
||||||
|
|
||||||
|
// For taproot channel types, the partial signature should be set.
|
||||||
|
if isTaprootChanType(chanType) {
|
||||||
|
require.NotNil(t, fundingCreated.PartialSig)
|
||||||
|
}
|
||||||
|
|
||||||
// Give the message to Bob.
|
// Give the message to Bob.
|
||||||
bob.fundingMgr.ProcessFundingMsg(fundingCreated, alice)
|
bob.fundingMgr.ProcessFundingMsg(fundingCreated, alice)
|
||||||
|
|
||||||
@@ -822,6 +855,11 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
|
|||||||
t, bob.msgChan, "FundingSigned",
|
t, bob.msgChan, "FundingSigned",
|
||||||
).(*lnwire.FundingSigned)
|
).(*lnwire.FundingSigned)
|
||||||
|
|
||||||
|
// For taproot channel types, the partial signature should be set.
|
||||||
|
if isTaprootChanType(chanType) {
|
||||||
|
require.NotNil(t, fundingSigned.PartialSig)
|
||||||
|
}
|
||||||
|
|
||||||
// Forward the signature to Alice.
|
// Forward the signature to Alice.
|
||||||
alice.fundingMgr.ProcessFundingMsg(fundingSigned, bob)
|
alice.fundingMgr.ProcessFundingMsg(fundingSigned, bob)
|
||||||
|
|
||||||
@@ -1244,6 +1282,25 @@ func assertAnnouncementSignatures(t *testing.T, alice, bob *testNode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertType[T any](t *testing.T, typ any) T {
|
||||||
|
value, ok := typ.(T)
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertNodeAnnSent(t *testing.T, alice, bob *testNode) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
for _, node := range []*testNode{alice, bob} {
|
||||||
|
nodeAnn, err := lnutils.RecvOrTimeout(
|
||||||
|
node.msgChan, time.Second*5,
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertType[*lnwire.NodeAnnouncement](t, *nodeAnn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func waitForOpenUpdate(t *testing.T, updateChan chan *lnrpc.OpenStatusUpdate) {
|
func waitForOpenUpdate(t *testing.T, updateChan chan *lnrpc.OpenStatusUpdate) {
|
||||||
var openUpdate *lnrpc.OpenStatusUpdate
|
var openUpdate *lnrpc.OpenStatusUpdate
|
||||||
select {
|
select {
|
||||||
@@ -1349,14 +1406,31 @@ func assertHandleChannelReady(t *testing.T, alice, bob *testNode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFundingManagerNormalWorkflow(t *testing.T) {
|
func testNormalWorkflow(t *testing.T, chanType *lnwire.ChannelType) {
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
alice, bob := setupFundingManagers(t)
|
alice, bob := setupFundingManagers(t)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
tearDownFundingManagers(t, alice, bob)
|
tearDownFundingManagers(t, alice, bob)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// If the channel type is set, then we need to make sure both parties
|
||||||
|
// support explicit channel type negotiation.
|
||||||
|
if chanType != nil {
|
||||||
|
// Alice and Bob will have the same set of feature bits in our
|
||||||
|
// test.
|
||||||
|
featureBits := []lnwire.FeatureBit{
|
||||||
|
lnwire.ZeroConfOptional,
|
||||||
|
lnwire.ScidAliasOptional,
|
||||||
|
lnwire.ExplicitChannelTypeOptional,
|
||||||
|
lnwire.StaticRemoteKeyOptional,
|
||||||
|
lnwire.AnchorsZeroFeeHtlcTxOptional,
|
||||||
|
lnwire.SimpleTaprootChannelsOptional,
|
||||||
|
}
|
||||||
|
alice.localFeatures = featureBits
|
||||||
|
alice.remoteFeatures = featureBits
|
||||||
|
bob.localFeatures = featureBits
|
||||||
|
bob.remoteFeatures = featureBits
|
||||||
|
}
|
||||||
|
|
||||||
// We will consume the channel updates as we go, so no buffering is
|
// We will consume the channel updates as we go, so no buffering is
|
||||||
// needed.
|
// needed.
|
||||||
updateChan := make(chan *lnrpc.OpenStatusUpdate)
|
updateChan := make(chan *lnrpc.OpenStatusUpdate)
|
||||||
@@ -1368,6 +1442,7 @@ func TestFundingManagerNormalWorkflow(t *testing.T) {
|
|||||||
capacity := localAmt + pushAmt
|
capacity := localAmt + pushAmt
|
||||||
fundingOutPoint, fundingTx := openChannel(
|
fundingOutPoint, fundingTx := openChannel(
|
||||||
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
||||||
|
chanType,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check that neither Alice nor Bob sent an error message.
|
// Check that neither Alice nor Bob sent an error message.
|
||||||
@@ -1400,6 +1475,13 @@ func TestFundingManagerNormalWorkflow(t *testing.T) {
|
|||||||
).(*lnwire.ChannelReady)
|
).(*lnwire.ChannelReady)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
|
|
||||||
|
// For taproot channels, the funding locked messages should have the
|
||||||
|
// next set of verification nonces.
|
||||||
|
if isTaprootChanType(chanType) {
|
||||||
|
require.NotNil(t, channelReadyAlice.NextLocalNonce)
|
||||||
|
require.NotNil(t, channelReadyBob.NextLocalNonce)
|
||||||
|
}
|
||||||
|
|
||||||
// Check that the state machine is updated accordingly
|
// Check that the state machine is updated accordingly
|
||||||
assertChannelReadySent(t, alice, bob, fundingOutPoint)
|
assertChannelReadySent(t, alice, bob, fundingOutPoint)
|
||||||
|
|
||||||
@@ -1431,8 +1513,20 @@ func TestFundingManagerNormalWorkflow(t *testing.T) {
|
|||||||
Tx: fundingTx,
|
Tx: fundingTx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the fundingManagers exchange announcement signatures.
|
switch {
|
||||||
|
// For taproot channels, we expect them to only send a node
|
||||||
|
// announcement message at this point. These channels aren't advertised
|
||||||
|
// so we don't expect the other messages.
|
||||||
|
case isTaprootChanType(chanType):
|
||||||
|
assertNodeAnnSent(t, alice, bob)
|
||||||
|
|
||||||
|
// For regular channels, we'll make sure the fundingManagers exchange
|
||||||
|
// announcement signatures.
|
||||||
|
case chanType == nil:
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
assertAnnouncementSignatures(t, alice, bob)
|
assertAnnouncementSignatures(t, alice, bob)
|
||||||
|
}
|
||||||
|
|
||||||
// The internal state-machine should now have deleted the channelStates
|
// The internal state-machine should now have deleted the channelStates
|
||||||
// from the database, as the channel is announced.
|
// from the database, as the channel is announced.
|
||||||
@@ -1443,6 +1537,37 @@ func TestFundingManagerNormalWorkflow(t *testing.T) {
|
|||||||
assertNoFwdingPolicy(t, alice, bob, channelReadyAlice.ChanID)
|
assertNoFwdingPolicy(t, alice, bob, channelReadyAlice.ChanID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestFundingManagerNormalWorkflow tests that the funding manager is able to
|
||||||
|
// do a routine channel funding flow back and forth.
|
||||||
|
func TestFundingManagerNormalWorkflow(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
taprootChanType := lnwire.ChannelType(*lnwire.NewRawFeatureVector(
|
||||||
|
lnwire.SimpleTaprootChannelsRequired,
|
||||||
|
))
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
typeName string
|
||||||
|
chanType *lnwire.ChannelType
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
typeName: "normal",
|
||||||
|
chanType: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
typeName: "taproot",
|
||||||
|
chanType: &taprootChanType,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:paralleltest
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.typeName, func(t *testing.T) {
|
||||||
|
testNormalWorkflow(t, testCase.chanType)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestFundingManagerRejectCSV tests checking of local CSV values against our
|
// TestFundingManagerRejectCSV tests checking of local CSV values against our
|
||||||
// local CSV limit for incoming and outgoing channels.
|
// local CSV limit for incoming and outgoing channels.
|
||||||
func TestFundingManagerRejectCSV(t *testing.T) {
|
func TestFundingManagerRejectCSV(t *testing.T) {
|
||||||
@@ -1617,6 +1742,7 @@ func TestFundingManagerRestartBehavior(t *testing.T) {
|
|||||||
updateChan := make(chan *lnrpc.OpenStatusUpdate)
|
updateChan := make(chan *lnrpc.OpenStatusUpdate)
|
||||||
fundingOutPoint, fundingTx := openChannel(
|
fundingOutPoint, fundingTx := openChannel(
|
||||||
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
||||||
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
// After the funding transaction gets mined, both nodes will send the
|
// After the funding transaction gets mined, both nodes will send the
|
||||||
@@ -1775,6 +1901,7 @@ func TestFundingManagerOfflinePeer(t *testing.T) {
|
|||||||
updateChan := make(chan *lnrpc.OpenStatusUpdate)
|
updateChan := make(chan *lnrpc.OpenStatusUpdate)
|
||||||
fundingOutPoint, fundingTx := openChannel(
|
fundingOutPoint, fundingTx := openChannel(
|
||||||
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
||||||
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
// After the funding transaction gets mined, both nodes will send the
|
// After the funding transaction gets mined, both nodes will send the
|
||||||
@@ -2160,7 +2287,7 @@ func TestFundingManagerFundingTimeout(t *testing.T) {
|
|||||||
|
|
||||||
// Run through the process of opening the channel, up until the funding
|
// Run through the process of opening the channel, up until the funding
|
||||||
// transaction is broadcasted.
|
// transaction is broadcasted.
|
||||||
_, _ = openChannel(t, alice, bob, 500000, 0, 1, updateChan, true)
|
_, _ = openChannel(t, alice, bob, 500000, 0, 1, updateChan, true, nil)
|
||||||
|
|
||||||
// Bob will at this point be waiting for the funding transaction to be
|
// Bob will at this point be waiting for the funding transaction to be
|
||||||
// confirmed, so the channel should be considered pending.
|
// confirmed, so the channel should be considered pending.
|
||||||
@@ -2208,7 +2335,7 @@ func TestFundingManagerFundingNotTimeoutInitiator(t *testing.T) {
|
|||||||
|
|
||||||
// Run through the process of opening the channel, up until the funding
|
// Run through the process of opening the channel, up until the funding
|
||||||
// transaction is broadcasted.
|
// transaction is broadcasted.
|
||||||
_, _ = openChannel(t, alice, bob, 500000, 0, 1, updateChan, true)
|
_, _ = openChannel(t, alice, bob, 500000, 0, 1, updateChan, true, nil)
|
||||||
|
|
||||||
// Alice will at this point be waiting for the funding transaction to be
|
// Alice will at this point be waiting for the funding transaction to be
|
||||||
// confirmed, so the channel should be considered pending.
|
// confirmed, so the channel should be considered pending.
|
||||||
@@ -2285,7 +2412,7 @@ func TestFundingManagerReceiveChannelReadyTwice(t *testing.T) {
|
|||||||
pushAmt := btcutil.Amount(0)
|
pushAmt := btcutil.Amount(0)
|
||||||
capacity := localAmt + pushAmt
|
capacity := localAmt + pushAmt
|
||||||
fundingOutPoint, fundingTx := openChannel(
|
fundingOutPoint, fundingTx := openChannel(
|
||||||
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
t, alice, bob, localAmt, pushAmt, 1, updateChan, true, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Notify that transaction was mined
|
// Notify that transaction was mined
|
||||||
@@ -2398,7 +2525,7 @@ func TestFundingManagerRestartAfterChanAnn(t *testing.T) {
|
|||||||
pushAmt := btcutil.Amount(0)
|
pushAmt := btcutil.Amount(0)
|
||||||
capacity := localAmt + pushAmt
|
capacity := localAmt + pushAmt
|
||||||
fundingOutPoint, fundingTx := openChannel(
|
fundingOutPoint, fundingTx := openChannel(
|
||||||
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
t, alice, bob, localAmt, pushAmt, 1, updateChan, true, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Notify that transaction was mined
|
// Notify that transaction was mined
|
||||||
@@ -2497,7 +2624,7 @@ func TestFundingManagerRestartAfterReceivingChannelReady(t *testing.T) {
|
|||||||
pushAmt := btcutil.Amount(0)
|
pushAmt := btcutil.Amount(0)
|
||||||
capacity := localAmt + pushAmt
|
capacity := localAmt + pushAmt
|
||||||
fundingOutPoint, fundingTx := openChannel(
|
fundingOutPoint, fundingTx := openChannel(
|
||||||
t, alice, bob, localAmt, pushAmt, 1, updateChan, true,
|
t, alice, bob, localAmt, pushAmt, 1, updateChan, true, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Notify that transaction was mined
|
// Notify that transaction was mined
|
||||||
@@ -2592,7 +2719,7 @@ func TestFundingManagerPrivateChannel(t *testing.T) {
|
|||||||
pushAmt := btcutil.Amount(0)
|
pushAmt := btcutil.Amount(0)
|
||||||
capacity := localAmt + pushAmt
|
capacity := localAmt + pushAmt
|
||||||
fundingOutPoint, fundingTx := openChannel(
|
fundingOutPoint, fundingTx := openChannel(
|
||||||
t, alice, bob, localAmt, pushAmt, 1, updateChan, false,
|
t, alice, bob, localAmt, pushAmt, 1, updateChan, false, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Notify that transaction was mined
|
// Notify that transaction was mined
|
||||||
@@ -2717,7 +2844,7 @@ func TestFundingManagerPrivateRestart(t *testing.T) {
|
|||||||
pushAmt := btcutil.Amount(0)
|
pushAmt := btcutil.Amount(0)
|
||||||
capacity := localAmt + pushAmt
|
capacity := localAmt + pushAmt
|
||||||
fundingOutPoint, fundingTx := openChannel(
|
fundingOutPoint, fundingTx := openChannel(
|
||||||
t, alice, bob, localAmt, pushAmt, 1, updateChan, false,
|
t, alice, bob, localAmt, pushAmt, 1, updateChan, false, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Notify that transaction was mined
|
// Notify that transaction was mined
|
||||||
@@ -4320,11 +4447,7 @@ func testUpfrontFailure(t *testing.T, pkscript []byte, expectErr bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestFundingManagerZeroConf tests that the fundingmanager properly handles
|
func testZeroConf(t *testing.T, chanType *lnwire.ChannelType) {
|
||||||
// the whole flow for zero-conf channels.
|
|
||||||
func TestFundingManagerZeroConf(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
alice, bob := setupFundingManagers(t)
|
alice, bob := setupFundingManagers(t)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
tearDownFundingManagers(t, alice, bob)
|
tearDownFundingManagers(t, alice, bob)
|
||||||
@@ -4337,6 +4460,7 @@ func TestFundingManagerZeroConf(t *testing.T) {
|
|||||||
lnwire.ExplicitChannelTypeOptional,
|
lnwire.ExplicitChannelTypeOptional,
|
||||||
lnwire.StaticRemoteKeyOptional,
|
lnwire.StaticRemoteKeyOptional,
|
||||||
lnwire.AnchorsZeroFeeHtlcTxOptional,
|
lnwire.AnchorsZeroFeeHtlcTxOptional,
|
||||||
|
lnwire.SimpleTaprootChannelsOptional,
|
||||||
}
|
}
|
||||||
alice.localFeatures = featureBits
|
alice.localFeatures = featureBits
|
||||||
alice.remoteFeatures = featureBits
|
alice.remoteFeatures = featureBits
|
||||||
@@ -4348,11 +4472,20 @@ func TestFundingManagerZeroConf(t *testing.T) {
|
|||||||
updateChan := make(chan *lnrpc.OpenStatusUpdate)
|
updateChan := make(chan *lnrpc.OpenStatusUpdate)
|
||||||
|
|
||||||
// Construct the zero-conf ChannelType for use in open_channel.
|
// Construct the zero-conf ChannelType for use in open_channel.
|
||||||
channelTypeBits := []lnwire.FeatureBit{
|
var channelTypeBits []lnwire.FeatureBit
|
||||||
|
if isTaprootChanType(chanType) {
|
||||||
|
channelTypeBits = []lnwire.FeatureBit{
|
||||||
|
lnwire.ZeroConfRequired,
|
||||||
|
lnwire.SimpleTaprootChannelsRequired,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channelTypeBits = []lnwire.FeatureBit{
|
||||||
lnwire.ZeroConfRequired,
|
lnwire.ZeroConfRequired,
|
||||||
lnwire.StaticRemoteKeyRequired,
|
lnwire.StaticRemoteKeyRequired,
|
||||||
lnwire.AnchorsZeroFeeHtlcTxRequired,
|
lnwire.AnchorsZeroFeeHtlcTxRequired,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
channelType := lnwire.ChannelType(
|
channelType := lnwire.ChannelType(
|
||||||
*lnwire.NewRawFeatureVector(channelTypeBits...),
|
*lnwire.NewRawFeatureVector(channelTypeBits...),
|
||||||
)
|
)
|
||||||
@@ -4425,9 +4558,12 @@ func TestFundingManagerZeroConf(t *testing.T) {
|
|||||||
Tx: fundingTx,
|
Tx: fundingTx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For taproot channels, we don't expect them to be announced atm.
|
||||||
|
if !isTaprootChanType(chanType) {
|
||||||
assertChannelAnnouncements(
|
assertChannelAnnouncements(
|
||||||
t, alice, bob, fundingAmt, nil, nil, nil, nil,
|
t, alice, bob, fundingAmt, nil, nil, nil, nil,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Both Alice and Bob should send on reportScidChan.
|
// Both Alice and Bob should send on reportScidChan.
|
||||||
select {
|
select {
|
||||||
@@ -4451,7 +4587,20 @@ func TestFundingManagerZeroConf(t *testing.T) {
|
|||||||
Tx: fundingTx,
|
Tx: fundingTx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
// For taproot channels, we expect them to only send a node
|
||||||
|
// announcement message at this point. These channels aren't advertised
|
||||||
|
// so we don't expect the other messages.
|
||||||
|
case isTaprootChanType(chanType):
|
||||||
|
assertNodeAnnSent(t, alice, bob)
|
||||||
|
|
||||||
|
// For regular channels, we'll make sure the fundingManagers exchange
|
||||||
|
// announcement signatures.
|
||||||
|
case chanType == nil:
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
assertAnnouncementSignatures(t, alice, bob)
|
assertAnnouncementSignatures(t, alice, bob)
|
||||||
|
}
|
||||||
|
|
||||||
// Assert that the channel state is deleted from the fundingmanager's
|
// Assert that the channel state is deleted from the fundingmanager's
|
||||||
// datastore.
|
// datastore.
|
||||||
@@ -4552,3 +4701,34 @@ func TestFundingManagerNoEchoChanType(t *testing.T) {
|
|||||||
alice.fundingMgr.ProcessFundingMsg(acceptChanMsg, bob)
|
alice.fundingMgr.ProcessFundingMsg(acceptChanMsg, bob)
|
||||||
assertFundingMsgSent(t, alice.msgChan, "Error")
|
assertFundingMsgSent(t, alice.msgChan, "Error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestFundingManagerZeroConf tests that the fundingmanager properly handles
|
||||||
|
// the whole flow for zero-conf channels.
|
||||||
|
func TestFundingManagerZeroConf(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
taprootChanType := lnwire.ChannelType(*lnwire.NewRawFeatureVector(
|
||||||
|
lnwire.SimpleTaprootChannelsRequired,
|
||||||
|
))
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
typeName string
|
||||||
|
chanType *lnwire.ChannelType
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
typeName: "normal",
|
||||||
|
chanType: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
typeName: "taproot",
|
||||||
|
chanType: &taprootChanType,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:paralleltest
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.typeName, func(t *testing.T) {
|
||||||
|
testZeroConf(t, testCase.chanType)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user