From 1b8fd008c45fba5e78bd983b447beb5df1bbf1e9 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:02:25 -0700 Subject: [PATCH 01/10] lnwire: define feature bits for wumbo channels --- lnwire/features.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lnwire/features.go b/lnwire/features.go index 4e5899c2..9c871e4c 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -101,6 +101,14 @@ const ( // HTLC. MPPOptional FeatureBit = 17 + // WumboChannelsRequired is a required feature bit that signals that a + // node is willing to accept channels larger than 2^24 satoshis. + WumboChannelsRequired = 18 + + // WumboChannelsRequired is an optional feature bit that signals that a + // node is willing to accept channels larger than 2^24 satoshis. + WumboChannelsOptional = 19 + // AnchorsRequired is a required feature bit that signals that the node // requires channels to be made using commitments having anchor // outputs. @@ -150,6 +158,8 @@ var Features = map[FeatureBit]string{ MPPRequired: "multi-path-payments", AnchorsRequired: "anchor-commitments", AnchorsOptional: "anchor-commitments", + WumboChannelsRequired: "wumbo-channels", + WumboChannelsOptional: "wumbo-channels", } // RawFeatureVector represents a set of feature bits as defined in BOLT-09. A From 73cdb6a50f27ebf1fe40266560be4d4baef8d307 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:03:12 -0700 Subject: [PATCH 02/10] feature: add feature sets for the wumbo channel feature bit --- feature/default_sets.go | 4 ++++ feature/manager.go | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/feature/default_sets.go b/feature/default_sets.go index 8054894e..64e6f9bd 100644 --- a/feature/default_sets.go +++ b/feature/default_sets.go @@ -47,4 +47,8 @@ var defaultSetDesc = setDesc{ SetInit: {}, // I SetNodeAnn: {}, // N }, + lnwire.WumboChannelsOptional: { + SetInit: {}, // I + SetNodeAnn: {}, // N + }, } diff --git a/feature/manager.go b/feature/manager.go index 159540c2..7e20541e 100644 --- a/feature/manager.go +++ b/feature/manager.go @@ -20,6 +20,9 @@ type Config struct { // NoAnchors unsets any bits signaling support for anchor outputs. NoAnchors bool + + // NoWumbo unsets any bits signalling support for wumbo channels. + NoWumbo bool } // Manager is responsible for generating feature vectors for different requested @@ -36,7 +39,7 @@ func NewManager(cfg Config) (*Manager, error) { return newManager(cfg, defaultSetDesc) } -// newManager creates a new feeature Manager, applying any custom modifications +// newManager creates a new feature Manager, applying any custom modifications // to its feature sets before returning. This method accepts the setDesc as its // own parameter so that it can be unit tested. func newManager(cfg Config, desc setDesc) (*Manager, error) { @@ -83,6 +86,10 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) { raw.Unset(lnwire.AnchorsOptional) raw.Unset(lnwire.AnchorsRequired) } + if cfg.NoWumbo { + raw.Unset(lnwire.WumboChannelsOptional) + raw.Unset(lnwire.WumboChannelsRequired) + } // Ensure that all of our feature sets properly set any // dependent features. From 43a355321fe54610c8d5ffb876eb37c23e25d639 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 8 Jul 2020 14:26:05 -0700 Subject: [PATCH 03/10] lncfg: split off protocol options into normal and legacy, normal reqs no build tag In this commit, we split off the protocol options into a normal and legacy sub-config. The legacy sub-config protected by a built tag, and will only be populated if thet tag is set. Legacy options now have a `legacy` prefix. So `--protocol.legacyonion` is now `--protocol.onion`, and `--protocol.committweak`, is now `--protocol.legacy.committweak`. We also create a new experimental protocol feature sub-config for newer features that may not yet been fully complete, so they require a build tag. --- lncfg/protocol.go | 15 +++++++++++++++ lncfg/protocol_experimental_off.go | 14 ++++++++++++++ lncfg/protocol_experimental_on.go | 17 +++++++++++++++++ lncfg/protocol_legacy_off.go | 18 ++++++------------ lncfg/protocol_legacy_on.go | 24 +++++++----------------- lntest/itest/lnd_multi-hop-payments.go | 2 +- lntest/itest/lnd_test.go | 2 +- 7 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 lncfg/protocol.go create mode 100644 lncfg/protocol_experimental_off.go create mode 100644 lncfg/protocol_experimental_on.go diff --git a/lncfg/protocol.go b/lncfg/protocol.go new file mode 100644 index 00000000..ea4b1bfc --- /dev/null +++ b/lncfg/protocol.go @@ -0,0 +1,15 @@ +package lncfg + +// ProtocolOptions is a struct that we use to be able to test backwards +// compatibility of protocol additions, while defaulting to the latest within +// lnd, or to enable experimental protocol changes. +type ProtocolOptions struct { + // LegacyProtocol is a sub-config that houses all the legacy protocol + // options. These are mostly used for integration tests as most modern + // nodes shuld always run with them on by default. + LegacyProtocol `group:"legacy" namespace:"legacy"` + + // ExperimentalProtocol is a sub-config that houses any experimental + // protocol features that also require a build-tag to activate. + ExperimentalProtocol +} diff --git a/lncfg/protocol_experimental_off.go b/lncfg/protocol_experimental_off.go new file mode 100644 index 00000000..20d1ce48 --- /dev/null +++ b/lncfg/protocol_experimental_off.go @@ -0,0 +1,14 @@ +// +build !dev + +package lncfg + +// ExperimentalProtocol is a sub-config that houses any experimental protocol +// features that also require a build-tag to activate. +type ExperimentalProtocol struct { +} + +// AnchorCommitments returns true if support for the anchor commitment type +// should be signaled. +func (l *ExperimentalProtocol) AnchorCommitments() bool { + return false +} diff --git a/lncfg/protocol_experimental_on.go b/lncfg/protocol_experimental_on.go new file mode 100644 index 00000000..dac8cfea --- /dev/null +++ b/lncfg/protocol_experimental_on.go @@ -0,0 +1,17 @@ +// +build dev + +package lncfg + +// ExperimentalProtocol is a sub-config that houses any experimental protocol +// features that also require a build-tag to activate. +type ExperimentalProtocol struct { + // Anchors should be set if we want to support opening or accepting + // channels having the anchor commitment type. + Anchors bool `long:"anchors" description:"EXPERIMENTAL: enable experimental support for anchor commitments, won't work with watchtowers"` +} + +// AnchorCommitments returns true if support for the anchor commitment type +// should be signaled. +func (l *ExperimentalProtocol) AnchorCommitments() bool { + return l.Anchors +} diff --git a/lncfg/protocol_legacy_off.go b/lncfg/protocol_legacy_off.go index bd589c24..060569d8 100644 --- a/lncfg/protocol_legacy_off.go +++ b/lncfg/protocol_legacy_off.go @@ -2,27 +2,21 @@ package lncfg -// ProtocolOptions is a struct that we use to be able to test backwards -// compatibility of protocol additions, while defaulting to the latest within -// lnd, or to enable experimental protocol changes. -type ProtocolOptions struct { +// Legacy is a sub-config that houses all the legacy protocol options. These +// are mostly used for integration tests as most modern nodes shuld always run +// with them on by default. +type LegacyProtocol struct { } // LegacyOnion returns true if the old legacy onion format should be used when // we're an intermediate or final hop. This controls if we set the // TLVOnionPayloadOptional bit or not. -func (l *ProtocolOptions) LegacyOnion() bool { +func (l *LegacyProtocol) LegacyOnion() bool { return false } // NoStaticRemoteKey returns true if the old commitment format with a tweaked // remote key should be used for new funded channels. -func (l *ProtocolOptions) NoStaticRemoteKey() bool { - return false -} - -// AnchorCommitments returns true if support for the the anchor commitment type -// should be signaled. -func (l *ProtocolOptions) AnchorCommitments() bool { +func (l *LegacyProtocol) NoStaticRemoteKey() bool { return false } diff --git a/lncfg/protocol_legacy_on.go b/lncfg/protocol_legacy_on.go index ac388f02..712d5fed 100644 --- a/lncfg/protocol_legacy_on.go +++ b/lncfg/protocol_legacy_on.go @@ -2,41 +2,31 @@ package lncfg -// ProtocolOptions is a struct that we use to be able to test backwards -// compatibility of protocol additions, while defaulting to the latest within -// lnd, or to enable experimental protocol changes. -type ProtocolOptions struct { +// Legacy is a sub-config that houses all the legacy protocol options. These +// are mostly used for integration tests as most modern nodes shuld always run +// with them on by default. +type LegacyProtocol struct { // LegacyOnionFormat if set to true, then we won't signal // TLVOnionPayloadOptional. As a result, nodes that include us in the // route won't use the new modern onion framing. - LegacyOnionFormat bool `long:"legacyonion" description:"force node to not advertise the new modern TLV onion format"` + LegacyOnionFormat bool `long:"onion" description:"force node to not advertise the new modern TLV onion format"` // CommitmentTweak guards if we should use the old legacy commitment // protocol, or the newer variant that doesn't have a tweak for the // remote party's output in the commitment. If set to true, then we // won't signal StaticRemoteKeyOptional. CommitmentTweak bool `long:"committweak" description:"force node to not advertise the new commitment format"` - - // Anchors should be set if we want to support opening or accepting - // channels having the anchor commitment type. - Anchors bool `long:"anchors" description:"EXPERIMENTAL: enable experimental support for anchor commitments, won't work with watchtowers"` } // LegacyOnion returns true if the old legacy onion format should be used when // we're an intermediate or final hop. This controls if we set the // TLVOnionPayloadOptional bit or not. -func (l *ProtocolOptions) LegacyOnion() bool { +func (l *LegacyProtocol) LegacyOnion() bool { return l.LegacyOnionFormat } // NoStaticRemoteKey returns true if the old commitment format with a tweaked // remote key should be used for new funded channels. -func (l *ProtocolOptions) NoStaticRemoteKey() bool { +func (l *LegacyProtocol) NoStaticRemoteKey() bool { return l.CommitmentTweak } - -// AnchorCommitments returns true if support for the anchor commitment type -// should be signaled. -func (l *ProtocolOptions) AnchorCommitments() bool { - return l.Anchors -} diff --git a/lntest/itest/lnd_multi-hop-payments.go b/lntest/itest/lnd_multi-hop-payments.go index fb9e79cb..a7dfee5a 100644 --- a/lntest/itest/lnd_multi-hop-payments.go +++ b/lntest/itest/lnd_multi-hop-payments.go @@ -48,7 +48,7 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) { // // First, we'll create Dave and establish a channel to Alice. Dave will // be running an older node that requires the legacy onion payload. - daveArgs := []string{"--protocol.legacyonion"} + daveArgs := []string{"--protocol.legacy.onion"} dave, err := net.NewNode("Dave", daveArgs) if err != nil { t.Fatalf("unable to create new nodes: %v", err) diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index 0cf06fd1..90a93843 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -1178,7 +1178,7 @@ func (c commitType) String() string { func (c commitType) Args() []string { switch c { case commitTypeLegacy: - return []string{"--protocol.committweak"} + return []string{"--protocol.legacy.committweak"} case commitTypeTweakless: return []string{} case commitTypeAnchors: From 5345069b16fb3ff3ba8e88a78a807e959f6eeef6 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:04:25 -0700 Subject: [PATCH 04/10] server+lncfg: add new config flag to enable wumbo channels In this commit, we add a new config flag to enable wumbo channels, with the default being that nodes reject all wumbo channel attempts. --- lncfg/protocol.go | 11 +++++++++++ server.go | 1 + 2 files changed, 12 insertions(+) diff --git a/lncfg/protocol.go b/lncfg/protocol.go index ea4b1bfc..5e1be5e6 100644 --- a/lncfg/protocol.go +++ b/lncfg/protocol.go @@ -12,4 +12,15 @@ type ProtocolOptions struct { // ExperimentalProtocol is a sub-config that houses any experimental // protocol features that also require a build-tag to activate. ExperimentalProtocol + + // WumboChans should be set if we want to enable support for wumbo + // (channels larger than 0.16 BTC) channels, which is the opposite of + // mini. + WumboChans bool `long:"wumbo-channels" description:"if set, then lnd will create and accept requests for channels larger chan 0.16 BTC"` +} + +// Wumbo returns true if lnd should permit the creation and acceptance of wumbo +// channels. +func (l *ProtocolOptions) Wumbo() bool { + return l.WumboChans } diff --git a/server.go b/server.go index 69aea9e0..d00340b0 100644 --- a/server.go +++ b/server.go @@ -410,6 +410,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB, NoTLVOnion: cfg.ProtocolOptions.LegacyOnion(), NoStaticRemoteKey: cfg.ProtocolOptions.NoStaticRemoteKey(), NoAnchors: !cfg.ProtocolOptions.AnchorCommitments(), + NoWumbo: !cfg.ProtocolOptions.Wumbo(), }) if err != nil { return nil, err From 6243838444dc8379d3b40bd3f9fa2cd3d784818f Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:04:59 -0700 Subject: [PATCH 05/10] server: remove unused globalFeatures variable Everything is done through the feature manager now, so we don't need to set these feature bits manually anymore. --- server.go | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/server.go b/server.go index d00340b0..c1dd7b05 100644 --- a/server.go +++ b/server.go @@ -356,27 +356,6 @@ func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB, } } - globalFeatures := lnwire.NewRawFeatureVector() - - // Only if we're not being forced to use the legacy onion format, will - // we signal our knowledge of the new TLV onion format. - if !cfg.ProtocolOptions.LegacyOnion() { - globalFeatures.Set(lnwire.TLVOnionPayloadOptional) - } - - // Similarly, we default to supporting the new modern commitment format - // where the remote key is static unless the protocol config is set to - // keep using the older format. - if !cfg.ProtocolOptions.NoStaticRemoteKey() { - globalFeatures.Set(lnwire.StaticRemoteKeyOptional) - } - - // We only signal that we support the experimental anchor commitments - // if explicitly enabled in the config. - if cfg.ProtocolOptions.AnchorCommitments() { - globalFeatures.Set(lnwire.AnchorsOptional) - } - var serializedPubKey [33]byte copy(serializedPubKey[:], nodeKeyECDH.PubKey().SerializeCompressed()) From 8177fed3029199b6a821213d0a4ce3b2c8081141 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:05:26 -0700 Subject: [PATCH 06/10] funding: allow incoming wumbo channel requests if wumbo is enabled --- fundingmanager.go | 9 +++-- fundingmanager_test.go | 81 ++++++++++++++++++++++++++++++++++++++++++ server.go | 1 + 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/fundingmanager.go b/fundingmanager.go index ebad44b6..aa3887ed 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -227,6 +227,10 @@ func newSerializedKey(pubKey *btcec.PublicKey) serializedPubKey { // within the configuration MUST be non-nil for the FundingManager to carry out // its duties. type fundingConfig struct { + // NoWumboChans indicates if we're to reject all incoming wumbo channel + // requests, and also reject all outgoing wumbo channel requests. + NoWumboChans bool + // IDKey is the PublicKey that is used to identify this node within the // Lightning Network. IDKey *btcec.PublicKey @@ -1236,8 +1240,9 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { } // We'll reject any request to create a channel that's above the - // current soft-limit for channel size. - if msg.FundingAmount > MaxFundingAmount { + // current soft-limit for channel size, but only if we're rejecting all + // wumbo channel initiations. + if f.cfg.NoWumboChans && msg.FundingAmount > MaxFundingAmount { f.failFundingFlow( fmsg.peer, fmsg.msg.PendingChannelID, lnwire.ErrChanTooLarge, diff --git a/fundingmanager_test.go b/fundingmanager_test.go index 4ea95fa5..9896563d 100644 --- a/fundingmanager_test.go +++ b/fundingmanager_test.go @@ -3176,3 +3176,84 @@ func TestGetUpfrontShutdownScript(t *testing.T) { }) } } + +func expectOpenChannelMsg(t *testing.T, msgChan chan lnwire.Message) *lnwire.OpenChannel { + var msg lnwire.Message + select { + case msg = <-msgChan: + case <-time.After(time.Second * 5): + t.Fatalf("node did not send OpenChannel message") + } + + openChannelReq, ok := msg.(*lnwire.OpenChannel) + if !ok { + errorMsg, gotError := msg.(*lnwire.Error) + if gotError { + t.Fatalf("expected OpenChannel to be sent "+ + "from bob, instead got error: %v", + errorMsg.Error()) + } + t.Fatalf("expected OpenChannel to be sent, instead got %T", + msg) + } + + return openChannelReq +} + +// TestWumboChannelConfig tests that the funding manager will respect the wumbo +// channel config param when creating or accepting new channels. +func TestWumboChannelConfig(t *testing.T) { + t.Parallel() + + // First we'll create a set of funding managers that will reject wumbo + // channels. + alice, bob := setupFundingManagers(t, func(cfg *fundingConfig) { + cfg.NoWumboChans = true + }) + + // If we attempt to initiate a new funding open request to Alice, + // that's below the wumbo channel mark, we should be able to start the + // funding process w/o issue. + updateChan := make(chan *lnrpc.OpenStatusUpdate) + errChan := make(chan error, 1) + initReq := &openChanReq{ + targetPubkey: bob.privKey.PubKey(), + chainHash: *activeNetParams.GenesisHash, + localFundingAmt: MaxFundingAmount, + pushAmt: lnwire.NewMSatFromSatoshis(0), + private: false, + updates: updateChan, + err: errChan, + } + + // We expect Bob to respond with an Accept channel message. + alice.fundingMgr.initFundingWorkflow(bob, initReq) + openChanMsg := expectOpenChannelMsg(t, alice.msgChan) + bob.fundingMgr.processFundingOpen(openChanMsg, alice) + assertFundingMsgSent(t, bob.msgChan, "AcceptChannel") + + // We'll now attempt to create a channel above the wumbo mark, which + // should be rejected. + initReq.localFundingAmt = btcutil.SatoshiPerBitcoin + + // After processing the funding open message, bob should respond with + // an error rejecting the channel. + alice.fundingMgr.initFundingWorkflow(bob, initReq) + openChanMsg = expectOpenChannelMsg(t, alice.msgChan) + bob.fundingMgr.processFundingOpen(openChanMsg, alice) + assertErrorSent(t, bob.msgChan) + + // Next, we'll re-create the funding managers, but this time allowing + // wumbo channels explicitly. + tearDownFundingManagers(t, alice, bob) + alice, bob = setupFundingManagers(t, func(cfg *fundingConfig) { + cfg.NoWumboChans = false + }) + + // We should now be able to initiate a wumbo channel funding w/o any + // issues. + alice.fundingMgr.initFundingWorkflow(bob, initReq) + openChanMsg = expectOpenChannelMsg(t, alice.msgChan) + bob.fundingMgr.processFundingOpen(openChanMsg, alice) + assertFundingMsgSent(t, bob.msgChan, "AcceptChannel") +} diff --git a/server.go b/server.go index c1dd7b05..612f2970 100644 --- a/server.go +++ b/server.go @@ -967,6 +967,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB, } s.fundingMgr, err = newFundingManager(fundingConfig{ + NoWumboChans: !cfg.ProtocolOptions.Wumbo(), IDKey: nodeKeyECDH.PubKey(), Wallet: cc.wallet, PublishTransaction: cc.wallet.PublishTransaction, From 67b8bca5b23d3522c64ffb4ab98e5af334e0dca9 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:05:43 -0700 Subject: [PATCH 07/10] rpc: allow outgoing wumbo channel requests if wumbo is enabled --- rpcserver.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rpcserver.go b/rpcserver.go index 0130a407..2d6f525a 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1713,6 +1713,8 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest, remoteCsvDelay := uint16(in.RemoteCsvDelay) maxValue := lnwire.MilliSatoshi(in.RemoteMaxValueInFlightMsat) + globalFeatureSet := r.server.featureMgr.Get(feature.SetNodeAnn) + // Ensure that the initial balance of the remote party (if pushing // satoshis) does not exceed the amount the local party has requested // for funding. @@ -1726,7 +1728,10 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest, // Ensure that the user doesn't exceed the current soft-limit for // channel size. If the funding amount is above the soft-limit, then // we'll reject the request. - if localFundingAmt > MaxFundingAmount { + wumboEnabled := globalFeatureSet.HasFeature( + lnwire.WumboChannelsOptional, + ) + if !wumboEnabled && localFundingAmt > MaxFundingAmount { return nil, fmt.Errorf("funding amount is too large, the max "+ "channel size is: %v", MaxFundingAmount) } From 6f208bce40e9fd3731eb018e1f1bc169a095774e Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:06:05 -0700 Subject: [PATCH 08/10] server+funding: use max values for csv delay and confs for wumbo channels --- server.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/server.go b/server.go index 612f2970..fe711cec 100644 --- a/server.go +++ b/server.go @@ -1034,11 +1034,18 @@ func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB, return defaultConf } + minConf := uint64(3) + maxConf := uint64(6) + + // If this is a wumbo channel, then we'll require the + // max amount of confirmations. + if chanAmt > MaxFundingAmount { + return uint16(maxConf) + } + // If not we return a value scaled linearly // between 3 and 6, depending on channel size. // TODO(halseth): Use 1 as minimum? - minConf := uint64(3) - maxConf := uint64(6) maxChannelSize := uint64( lnwire.NewMSatFromSatoshis(MaxFundingAmount)) stake := lnwire.NewMSatFromSatoshis(chanAmt) + pushAmt @@ -1067,6 +1074,12 @@ func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB, return defaultDelay } + // If this is a wumbo channel, then we'll require the + // max value. + if chanAmt > MaxFundingAmount { + return maxRemoteDelay + } + // If not we scale according to channel size. delay := uint16(btcutil.Amount(maxRemoteDelay) * chanAmt / MaxFundingAmount) From 6c322c5eb2dea0870ebd9fa72ff245bc0a8a602d Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:06:31 -0700 Subject: [PATCH 09/10] lntest/itest: fix line wrapping in funding test case --- lntest/itest/lnd_test.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index 90a93843..b6aa1933 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -1457,9 +1457,14 @@ test: // Check that the signalled type matches what we // expect. switch { - case expType == commitTypeAnchors && chansCommitType == lnrpc.CommitmentType_ANCHORS: - case expType == commitTypeTweakless && chansCommitType == lnrpc.CommitmentType_STATIC_REMOTE_KEY: - case expType == commitTypeLegacy && chansCommitType == lnrpc.CommitmentType_LEGACY: + case expType == commitTypeAnchors && + chansCommitType == lnrpc.CommitmentType_ANCHORS: + + case expType == commitTypeTweakless && + chansCommitType == lnrpc.CommitmentType_STATIC_REMOTE_KEY: + + case expType == commitTypeLegacy && + chansCommitType == lnrpc.CommitmentType_LEGACY: default: t.Fatalf("expected nodes to signal "+ From f61e1ac568dac00583f2611affb7ff46dd2a0c66 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Jul 2020 21:06:44 -0700 Subject: [PATCH 10/10] lntest/itest: add new test for wumbo channels --- lntest/itest/lnd_test.go | 4 ++ lntest/itest/lnd_wumbo_channels_test.go | 92 +++++++++++++++++++++++++ lntest/itest/log_error_whitelist.txt | 5 +- 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 lntest/itest/lnd_wumbo_channels_test.go diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index b6aa1933..687483ab 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -15200,6 +15200,10 @@ var testsCases = []*testCase{ name: "intercept forwarded htlc packets", test: testForwardInterceptor, }, + { + name: "wumbo channels", + test: testWumboChannels, + }, } // TestLightningNetworkDaemon performs a series of integration tests amongst a diff --git a/lntest/itest/lnd_wumbo_channels_test.go b/lntest/itest/lnd_wumbo_channels_test.go new file mode 100644 index 00000000..31f379b8 --- /dev/null +++ b/lntest/itest/lnd_wumbo_channels_test.go @@ -0,0 +1,92 @@ +// +build rpctest + +package itest + +import ( + "context" + "strings" + + "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd" + "github.com/lightningnetwork/lnd/lntest" +) + +// testWumboChannels tests that only a node that signals wumbo channel +// acceptances will allow a wumbo channel to be created. Additionally, if a +// node is running with mini channels only enabled, then they should reject any +// inbound wumbo channel requests. +func testWumboChannels(net *lntest.NetworkHarness, t *harnessTest) { + // With all the channel types exercised, we'll now make sure the wumbo + // signalling support works properly. + // + // We'll make two new nodes, with one of them signalling support for + // wumbo channels while the other doesn't. + wumboNode, err := net.NewNode( + "wumbo", []string{"--protocol.wumbo-channels"}, + ) + if err != nil { + t.Fatalf("unable to create new node: %v", err) + } + defer shutdownAndAssert(net, t, wumboNode) + miniNode, err := net.NewNode("mini", nil) + if err != nil { + t.Fatalf("unable to create new node: %v", err) + } + defer shutdownAndAssert(net, t, miniNode) + + // We'll send coins to the wumbo node, as it'll be the one imitating + // the channel funding. + ctxb := context.Background() + err = net.SendCoins(ctxb, btcutil.SatoshiPerBitcoin, wumboNode) + if err != nil { + t.Fatalf("unable to send coins to carol: %v", err) + } + + // Next we'll connect both nodes, then attempt to make a wumbo channel + // funding request to the mini node we created above. The wumbo request + // should fail as the node isn't advertising wumbo channels. + err = net.EnsureConnected(ctxb, wumboNode, miniNode) + if err != nil { + t.Fatalf("unable to connect peers: %v", err) + } + + chanAmt := lnd.MaxBtcFundingAmount + 1 + _, err = net.OpenChannel( + ctxb, wumboNode, miniNode, lntest.OpenChannelParams{ + Amt: chanAmt, + }, + ) + if err == nil { + t.Fatalf("expected wumbo channel funding to fail") + } + + // The test should indicate a failure due to the channel being too + // large. + if !strings.Contains(err.Error(), "channel too large") { + t.Fatalf("channel should be rejected due to size, instead "+ + "error was: %v", err) + } + + // We'll now make another wumbo node to accept our wumbo channel + // funding. + wumboNode2, err := net.NewNode( + "wumbo2", []string{"--protocol.wumbo-channels"}, + ) + if err != nil { + t.Fatalf("unable to create new node: %v", err) + } + defer shutdownAndAssert(net, t, wumboNode2) + + // Creating a wumbo channel between these two nodes should succeed. + err = net.EnsureConnected(ctxb, wumboNode, wumboNode2) + if err != nil { + t.Fatalf("unable to connect peers: %v", err) + } + chanPoint := openChannelAndAssert( + ctxb, t, net, wumboNode, wumboNode2, + lntest.OpenChannelParams{ + Amt: chanAmt, + }, + ) + closeChannelAndAssert(ctxb, t, net, wumboNode, chanPoint, false) +} diff --git a/lntest/itest/log_error_whitelist.txt b/lntest/itest/log_error_whitelist.txt index 0185f6b4..59f1bdc3 100644 --- a/lntest/itest/log_error_whitelist.txt +++ b/lntest/itest/log_error_whitelist.txt @@ -191,4 +191,7 @@