Skip to content

Commit 3c08109

Browse files
authored
Merge pull request #9335 from lightningnetwork/0-18-4-branch-rc2
release: create branch for v0.18.4-beta.rc2
2 parents c1129bb + 3447484 commit 3c08109

27 files changed

+931
-283
lines changed

build/version.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const (
4747

4848
// AppPreRelease MUST only contain characters from semanticAlphabet per
4949
// the semantic versioning spec.
50-
AppPreRelease = "beta.rc1"
50+
AppPreRelease = "beta.rc2"
5151
)
5252

5353
func init() {

config_builder.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/lightningnetwork/lnd/clock"
3636
"github.com/lightningnetwork/lnd/fn"
3737
"github.com/lightningnetwork/lnd/funding"
38+
"github.com/lightningnetwork/lnd/htlcswitch"
3839
"github.com/lightningnetwork/lnd/invoices"
3940
"github.com/lightningnetwork/lnd/keychain"
4041
"github.com/lightningnetwork/lnd/kvdb"
@@ -46,7 +47,6 @@ import (
4647
"github.com/lightningnetwork/lnd/lnwallet/rpcwallet"
4748
"github.com/lightningnetwork/lnd/macaroons"
4849
"github.com/lightningnetwork/lnd/msgmux"
49-
"github.com/lightningnetwork/lnd/routing"
5050
"github.com/lightningnetwork/lnd/rpcperms"
5151
"github.com/lightningnetwork/lnd/signal"
5252
"github.com/lightningnetwork/lnd/sqldb"
@@ -165,7 +165,7 @@ type AuxComponents struct {
165165

166166
// TrafficShaper is an optional traffic shaper that can be used to
167167
// control the outgoing channel of a payment.
168-
TrafficShaper fn.Option[routing.TlvTrafficShaper]
168+
TrafficShaper fn.Option[htlcswitch.AuxTrafficShaper]
169169

170170
// MsgRouter is an optional message router that if set will be used in
171171
// place of a new blank default message router.

contractcourt/channel_arbitrator.go

+32-5
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,20 @@ func (c *ChannelArbitrator) Start(state *chanArbStartState) error {
482482
return err
483483
}
484484

485+
c.wg.Add(1)
486+
go c.channelAttendant(bestHeight, state.commitSet)
487+
488+
return nil
489+
}
490+
491+
// progressStateMachineAfterRestart attempts to progress the state machine
492+
// after a restart. This makes sure that if the state transition failed, we
493+
// will try to progress the state machine again. Moreover it will relaunch
494+
// resolvers if the channel is still in the pending close state and has not
495+
// been fully resolved yet.
496+
func (c *ChannelArbitrator) progressStateMachineAfterRestart(bestHeight int32,
497+
commitSet *CommitSet) error {
498+
485499
// If the channel has been marked pending close in the database, and we
486500
// haven't transitioned the state machine to StateContractClosed (or a
487501
// succeeding state), then a state transition most likely failed. We'll
@@ -527,7 +541,7 @@ func (c *ChannelArbitrator) Start(state *chanArbStartState) error {
527541
// on-chain state, and our set of active contracts.
528542
startingState := c.state
529543
nextState, _, err := c.advanceState(
530-
triggerHeight, trigger, state.commitSet,
544+
triggerHeight, trigger, commitSet,
531545
)
532546
if err != nil {
533547
switch err {
@@ -564,14 +578,12 @@ func (c *ChannelArbitrator) Start(state *chanArbStartState) error {
564578
// receive a chain event from the chain watcher that the
565579
// commitment has been confirmed on chain, and before we
566580
// advance our state step, we call InsertConfirmedCommitSet.
567-
err := c.relaunchResolvers(state.commitSet, triggerHeight)
581+
err := c.relaunchResolvers(commitSet, triggerHeight)
568582
if err != nil {
569583
return err
570584
}
571585
}
572586

573-
c.wg.Add(1)
574-
go c.channelAttendant(bestHeight)
575587
return nil
576588
}
577589

@@ -2775,13 +2787,28 @@ func (c *ChannelArbitrator) updateActiveHTLCs() {
27752787
// Nursery for incubation, and ultimate sweeping.
27762788
//
27772789
// NOTE: This MUST be run as a goroutine.
2778-
func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
2790+
//
2791+
//nolint:funlen
2792+
func (c *ChannelArbitrator) channelAttendant(bestHeight int32,
2793+
commitSet *CommitSet) {
27792794

27802795
// TODO(roasbeef): tell top chain arb we're done
27812796
defer func() {
27822797
c.wg.Done()
27832798
}()
27842799

2800+
err := c.progressStateMachineAfterRestart(bestHeight, commitSet)
2801+
if err != nil {
2802+
// In case of an error, we return early but we do not shutdown
2803+
// LND, because there might be other channels that still can be
2804+
// resolved and we don't want to interfere with that.
2805+
// We continue to run the channel attendant in case the channel
2806+
// closes via other means for example the remote pary force
2807+
// closes the channel. So we log the error and continue.
2808+
log.Errorf("Unable to progress state machine after "+
2809+
"restart: %v", err)
2810+
}
2811+
27852812
for {
27862813
select {
27872814

contractcourt/channel_arbitrator_test.go

+20-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/lightningnetwork/lnd/input"
2222
"github.com/lightningnetwork/lnd/kvdb"
2323
"github.com/lightningnetwork/lnd/lntest/mock"
24+
"github.com/lightningnetwork/lnd/lntest/wait"
2425
"github.com/lightningnetwork/lnd/lntypes"
2526
"github.com/lightningnetwork/lnd/lnwallet"
2627
"github.com/lightningnetwork/lnd/lnwire"
@@ -1043,10 +1044,19 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
10431044

10441045
// Post restart, it should be the case that our resolver was properly
10451046
// supplemented, and we only have a single resolver in the final set.
1046-
if len(chanArb.activeResolvers) != 1 {
1047-
t.Fatalf("expected single resolver, instead got: %v",
1048-
len(chanArb.activeResolvers))
1049-
}
1047+
// The resolvers are added concurrently so we need to wait here.
1048+
err = wait.NoError(func() error {
1049+
chanArb.activeResolversLock.Lock()
1050+
defer chanArb.activeResolversLock.Unlock()
1051+
1052+
if len(chanArb.activeResolvers) != 1 {
1053+
return fmt.Errorf("expected single resolver, instead "+
1054+
"got: %v", len(chanArb.activeResolvers))
1055+
}
1056+
1057+
return nil
1058+
}, defaultTimeout)
1059+
require.NoError(t, err)
10501060

10511061
// We'll now examine the in-memory state of the active resolvers to
10521062
// ensure t hey were populated properly.
@@ -2884,9 +2894,12 @@ func TestChannelArbitratorStartForceCloseFail(t *testing.T) {
28842894
{
28852895
name: "Commitment is rejected with an " +
28862896
"unmatched error",
2887-
broadcastErr: fmt.Errorf("Reject Commitment Tx"),
2888-
expectedState: StateBroadcastCommit,
2889-
expectedStartup: false,
2897+
broadcastErr: fmt.Errorf("Reject Commitment Tx"),
2898+
expectedState: StateBroadcastCommit,
2899+
// We should still be able to start up since we other
2900+
// channels might be closing as well and we should
2901+
// resolve the contracts.
2902+
expectedStartup: true,
28902903
},
28912904

28922905
// We started after the DLP was triggered, and try to force

docs/release-notes/release-notes-0.18.4.md

+8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@
2626
* [Make the contract resolutions for the channel arbitrator optional](
2727
https://github.com/lightningnetwork/lnd/pull/9253).
2828

29+
* [Fixed a bug](https://github.com/lightningnetwork/lnd/pull/9324) to prevent
30+
potential deadlocks when LND depends on external components (e.g. aux
31+
components, hooks).
32+
33+
* [Make sure blinded payment failures are handled correctly in the mission
34+
controller](https://github.com/lightningnetwork/lnd/pull/9316).
35+
2936
# New Features
3037

3138
The main channel state machine and database now allow for processing and storing
@@ -121,4 +128,5 @@ types in a series of changes:
121128
* George Tsagkarelis
122129
* Olaoluwa Osuntokun
123130
* Oliver Gugger
131+
* Ziggie
124132

htlcswitch/interfaces.go

+58-10
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ const (
194194
Outgoing LinkDirection = true
195195
)
196196

197+
// OptionalBandwidth is a type alias for the result of a bandwidth query that
198+
// may return a bandwidth value or fn.None if the bandwidth is not available or
199+
// not applicable.
200+
type OptionalBandwidth = fn.Option[lnwire.MilliSatoshi]
201+
197202
// ChannelLink is an interface which represents the subsystem for managing the
198203
// incoming htlc requests, applying the changes to the channel, and also
199204
// propagating/forwarding it to htlc switch.
@@ -255,25 +260,26 @@ type ChannelLink interface {
255260
// in order to signal to the source of the HTLC, the policy consistency
256261
// issue.
257262
CheckHtlcForward(payHash [32]byte, incomingAmt lnwire.MilliSatoshi,
258-
amtToForward lnwire.MilliSatoshi,
259-
incomingTimeout, outgoingTimeout uint32,
260-
inboundFee models.InboundFee,
261-
heightNow uint32, scid lnwire.ShortChannelID) *LinkError
263+
amtToForward lnwire.MilliSatoshi, incomingTimeout,
264+
outgoingTimeout uint32, inboundFee models.InboundFee,
265+
heightNow uint32, scid lnwire.ShortChannelID,
266+
customRecords lnwire.CustomRecords) *LinkError
262267

263268
// CheckHtlcTransit should return a nil error if the passed HTLC details
264269
// satisfy the current channel policy. Otherwise, a LinkError with a
265270
// valid protocol failure message should be returned in order to signal
266271
// the violation. This call is intended to be used for locally initiated
267272
// payments for which there is no corresponding incoming htlc.
268273
CheckHtlcTransit(payHash [32]byte, amt lnwire.MilliSatoshi,
269-
timeout uint32, heightNow uint32) *LinkError
274+
timeout uint32, heightNow uint32,
275+
customRecords lnwire.CustomRecords) *LinkError
270276

271277
// Stats return the statistics of channel link. Number of updates,
272278
// total sent/received milli-satoshis.
273279
Stats() (uint64, lnwire.MilliSatoshi, lnwire.MilliSatoshi)
274280

275-
// Peer returns the serialized public key of remote peer with which we
276-
// have the channel link opened.
281+
// PeerPubKey returns the serialized public key of remote peer with
282+
// which we have the channel link opened.
277283
PeerPubKey() [33]byte
278284

279285
// AttachMailBox delivers an active MailBox to the link. The MailBox may
@@ -290,9 +296,18 @@ type ChannelLink interface {
290296
// commitment of the channel that this link is associated with.
291297
CommitmentCustomBlob() fn.Option[tlv.Blob]
292298

293-
// Start/Stop are used to initiate the start/stop of the channel link
294-
// functioning.
299+
// AuxBandwidth returns the bandwidth that can be used for a channel,
300+
// expressed in milli-satoshi. This might be different from the regular
301+
// BTC bandwidth for custom channels. This will always return fn.None()
302+
// for a regular (non-custom) channel.
303+
AuxBandwidth(amount lnwire.MilliSatoshi, cid lnwire.ShortChannelID,
304+
htlcBlob fn.Option[tlv.Blob],
305+
ts AuxTrafficShaper) fn.Result[OptionalBandwidth]
306+
307+
// Start starts the channel link.
295308
Start() error
309+
310+
// Stop requests the channel link to be shut down.
296311
Stop()
297312
}
298313

@@ -428,7 +443,7 @@ type htlcNotifier interface {
428443
NotifyForwardingEvent(key HtlcKey, info HtlcInfo,
429444
eventType HtlcEventType)
430445

431-
// NotifyIncomingLinkFailEvent notifies that a htlc has failed on our
446+
// NotifyLinkFailEvent notifies that a htlc has failed on our
432447
// incoming link. It takes an isReceive bool to differentiate between
433448
// our node's receives and forwards.
434449
NotifyLinkFailEvent(key HtlcKey, info HtlcInfo,
@@ -449,3 +464,36 @@ type htlcNotifier interface {
449464
NotifyFinalHtlcEvent(key models.CircuitKey,
450465
info channeldb.FinalHtlcInfo)
451466
}
467+
468+
// AuxHtlcModifier is an interface that allows the sender to modify the outgoing
469+
// HTLC of a payment by changing the amount or the wire message tlv records.
470+
type AuxHtlcModifier interface {
471+
// ProduceHtlcExtraData is a function that, based on the previous extra
472+
// data blob of an HTLC, may produce a different blob or modify the
473+
// amount of bitcoin this htlc should carry.
474+
ProduceHtlcExtraData(totalAmount lnwire.MilliSatoshi,
475+
htlcCustomRecords lnwire.CustomRecords) (lnwire.MilliSatoshi,
476+
lnwire.CustomRecords, error)
477+
}
478+
479+
// AuxTrafficShaper is an interface that allows the sender to determine if a
480+
// payment should be carried by a channel based on the TLV records that may be
481+
// present in the `update_add_htlc` message or the channel commitment itself.
482+
type AuxTrafficShaper interface {
483+
AuxHtlcModifier
484+
485+
// ShouldHandleTraffic is called in order to check if the channel
486+
// identified by the provided channel ID may have external mechanisms
487+
// that would allow it to carry out the payment.
488+
ShouldHandleTraffic(cid lnwire.ShortChannelID,
489+
fundingBlob fn.Option[tlv.Blob]) (bool, error)
490+
491+
// PaymentBandwidth returns the available bandwidth for a custom channel
492+
// decided by the given channel aux blob and HTLC blob. A return value
493+
// of 0 means there is no bandwidth available. To find out if a channel
494+
// is a custom channel that should be handled by the traffic shaper, the
495+
// ShouldHandleTraffic method should be called first.
496+
PaymentBandwidth(htlcBlob, commitmentBlob fn.Option[tlv.Blob],
497+
linkBandwidth,
498+
htlcAmt lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error)
499+
}

0 commit comments

Comments
 (0)