diff --git a/lntest/harness.go b/lntest/harness.go index 43423c6b..d680f9be 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -855,6 +855,11 @@ type OpenChannelParams struct { // MinHtlc is the htlc_minimum_msat value set when opening the channel. MinHtlc lnwire.MilliSatoshi + // RemoteMaxHtlcs is the remote_max_htlcs value set when opening the + // channel, restricting the number of concurrent HTLCs the remote party + // can add to a commitment. + RemoteMaxHtlcs uint16 + // FundingShim is an optional funding shim that the caller can specify // in order to modify the channel funding workflow. FundingShim *lnrpc.FundingShim @@ -893,6 +898,7 @@ func (n *NetworkHarness) OpenChannel(ctx context.Context, MinConfs: minConfs, SpendUnconfirmed: p.SpendUnconfirmed, MinHtlcMsat: int64(p.MinHtlc), + RemoteMaxHtlcs: uint32(p.RemoteMaxHtlcs), FundingShim: p.FundingShim, } diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index 864e3345..09e3d15c 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -4848,9 +4848,7 @@ func testListChannels(net *lntest.NetworkHarness, t *harnessTest) { const bobRemoteMaxHtlcs = 100 // Create two fresh nodes and open a channel between them. - alice, err := net.NewNode("Alice", []string{ - fmt.Sprintf("--default-remote-max-htlcs=%v", aliceRemoteMaxHtlcs), - }) + alice, err := net.NewNode("Alice", nil) if err != nil { t.Fatalf("unable to create new node: %v", err) } @@ -4887,8 +4885,9 @@ func testListChannels(net *lntest.NetworkHarness, t *harnessTest) { chanPoint := openChannelAndAssert( ctxt, t, net, alice, bob, lntest.OpenChannelParams{ - Amt: chanAmt, - MinHtlc: customizedMinHtlc, + Amt: chanAmt, + MinHtlc: customizedMinHtlc, + RemoteMaxHtlcs: aliceRemoteMaxHtlcs, }, ) diff --git a/rpcserver.go b/rpcserver.go index e9f1271a..78b34da1 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1742,6 +1742,7 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest, minHtlcIn := lnwire.MilliSatoshi(in.MinHtlcMsat) remoteCsvDelay := uint16(in.RemoteCsvDelay) maxValue := lnwire.MilliSatoshi(in.RemoteMaxValueInFlightMsat) + maxHtlcs := uint16(in.RemoteMaxHtlcs) globalFeatureSet := r.server.featureMgr.Get(feature.SetNodeAnn) @@ -1774,6 +1775,13 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest, "channel size is: %v SAT", int64(minChanFundingSize)) } + // Prevent users from submitting a max-htlc value that would exceed the + // protocol maximum. + if maxHtlcs > input.MaxHTLCNumber/2 { + return nil, fmt.Errorf("remote-max-htlcs (%v) cannot be "+ + "greater than %v", maxHtlcs, input.MaxHTLCNumber/2) + } + // Then, we'll extract the minimum number of confirmations that each // output we use to fund the channel's funding transaction should // satisfy. @@ -1862,6 +1870,7 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest, minConfs: minConfs, shutdownScript: script, maxValueInFlight: maxValue, + maxHtlcs: maxHtlcs, }, nil }