Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release: create branch for v0.18.4-beta.rc2 #9335

Merged
merged 15 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const (

// AppPreRelease MUST only contain characters from semanticAlphabet per
// the semantic versioning spec.
AppPreRelease = "beta.rc1"
AppPreRelease = "beta.rc2"
)

func init() {
Expand Down
4 changes: 2 additions & 2 deletions config_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/kvdb"
Expand All @@ -46,7 +47,6 @@ import (
"github.com/lightningnetwork/lnd/lnwallet/rpcwallet"
"github.com/lightningnetwork/lnd/macaroons"
"github.com/lightningnetwork/lnd/msgmux"
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/rpcperms"
"github.com/lightningnetwork/lnd/signal"
"github.com/lightningnetwork/lnd/sqldb"
Expand Down Expand Up @@ -165,7 +165,7 @@ type AuxComponents struct {

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

// MsgRouter is an optional message router that if set will be used in
// place of a new blank default message router.
Expand Down
37 changes: 32 additions & 5 deletions contractcourt/channel_arbitrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,20 @@ func (c *ChannelArbitrator) Start(state *chanArbStartState) error {
return err
}

c.wg.Add(1)
go c.channelAttendant(bestHeight, state.commitSet)

return nil
}

// progressStateMachineAfterRestart attempts to progress the state machine
// after a restart. This makes sure that if the state transition failed, we
// will try to progress the state machine again. Moreover it will relaunch
// resolvers if the channel is still in the pending close state and has not
// been fully resolved yet.
func (c *ChannelArbitrator) progressStateMachineAfterRestart(bestHeight int32,
commitSet *CommitSet) error {

// If the channel has been marked pending close in the database, and we
// haven't transitioned the state machine to StateContractClosed (or a
// succeeding state), then a state transition most likely failed. We'll
Expand Down Expand Up @@ -527,7 +541,7 @@ func (c *ChannelArbitrator) Start(state *chanArbStartState) error {
// on-chain state, and our set of active contracts.
startingState := c.state
nextState, _, err := c.advanceState(
triggerHeight, trigger, state.commitSet,
triggerHeight, trigger, commitSet,
)
if err != nil {
switch err {
Expand Down Expand Up @@ -564,14 +578,12 @@ func (c *ChannelArbitrator) Start(state *chanArbStartState) error {
// receive a chain event from the chain watcher that the
// commitment has been confirmed on chain, and before we
// advance our state step, we call InsertConfirmedCommitSet.
err := c.relaunchResolvers(state.commitSet, triggerHeight)
err := c.relaunchResolvers(commitSet, triggerHeight)
if err != nil {
return err
}
}

c.wg.Add(1)
go c.channelAttendant(bestHeight)
return nil
}

Expand Down Expand Up @@ -2775,13 +2787,28 @@ func (c *ChannelArbitrator) updateActiveHTLCs() {
// Nursery for incubation, and ultimate sweeping.
//
// NOTE: This MUST be run as a goroutine.
func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
//
//nolint:funlen
func (c *ChannelArbitrator) channelAttendant(bestHeight int32,
commitSet *CommitSet) {

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

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

for {
select {

Expand Down
27 changes: 20 additions & 7 deletions contractcourt/channel_arbitrator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lntest/mock"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
Expand Down Expand Up @@ -1043,10 +1044,19 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {

// Post restart, it should be the case that our resolver was properly
// supplemented, and we only have a single resolver in the final set.
if len(chanArb.activeResolvers) != 1 {
t.Fatalf("expected single resolver, instead got: %v",
len(chanArb.activeResolvers))
}
// The resolvers are added concurrently so we need to wait here.
err = wait.NoError(func() error {
chanArb.activeResolversLock.Lock()
defer chanArb.activeResolversLock.Unlock()

if len(chanArb.activeResolvers) != 1 {
return fmt.Errorf("expected single resolver, instead "+
"got: %v", len(chanArb.activeResolvers))
}

return nil
}, defaultTimeout)
require.NoError(t, err)

// We'll now examine the in-memory state of the active resolvers to
// ensure t hey were populated properly.
Expand Down Expand Up @@ -2884,9 +2894,12 @@ func TestChannelArbitratorStartForceCloseFail(t *testing.T) {
{
name: "Commitment is rejected with an " +
"unmatched error",
broadcastErr: fmt.Errorf("Reject Commitment Tx"),
expectedState: StateBroadcastCommit,
expectedStartup: false,
broadcastErr: fmt.Errorf("Reject Commitment Tx"),
expectedState: StateBroadcastCommit,
// We should still be able to start up since we other
// channels might be closing as well and we should
// resolve the contracts.
expectedStartup: true,
},

// We started after the DLP was triggered, and try to force
Expand Down
8 changes: 8 additions & 0 deletions docs/release-notes/release-notes-0.18.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
* [Make the contract resolutions for the channel arbitrator optional](
https://github.com/lightningnetwork/lnd/pull/9253).

* [Fixed a bug](https://github.com/lightningnetwork/lnd/pull/9324) to prevent
potential deadlocks when LND depends on external components (e.g. aux
components, hooks).

* [Make sure blinded payment failures are handled correctly in the mission
controller](https://github.com/lightningnetwork/lnd/pull/9316).

# New Features

The main channel state machine and database now allow for processing and storing
Expand Down Expand Up @@ -121,4 +128,5 @@ types in a series of changes:
* George Tsagkarelis
* Olaoluwa Osuntokun
* Oliver Gugger
* Ziggie

68 changes: 58 additions & 10 deletions htlcswitch/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ const (
Outgoing LinkDirection = true
)

// OptionalBandwidth is a type alias for the result of a bandwidth query that
// may return a bandwidth value or fn.None if the bandwidth is not available or
// not applicable.
type OptionalBandwidth = fn.Option[lnwire.MilliSatoshi]

// ChannelLink is an interface which represents the subsystem for managing the
// incoming htlc requests, applying the changes to the channel, and also
// propagating/forwarding it to htlc switch.
Expand Down Expand Up @@ -255,25 +260,26 @@ type ChannelLink interface {
// in order to signal to the source of the HTLC, the policy consistency
// issue.
CheckHtlcForward(payHash [32]byte, incomingAmt lnwire.MilliSatoshi,
amtToForward lnwire.MilliSatoshi,
incomingTimeout, outgoingTimeout uint32,
inboundFee models.InboundFee,
heightNow uint32, scid lnwire.ShortChannelID) *LinkError
amtToForward lnwire.MilliSatoshi, incomingTimeout,
outgoingTimeout uint32, inboundFee models.InboundFee,
heightNow uint32, scid lnwire.ShortChannelID,
customRecords lnwire.CustomRecords) *LinkError

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

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

// Peer returns the serialized public key of remote peer with which we
// have the channel link opened.
// PeerPubKey returns the serialized public key of remote peer with
// which we have the channel link opened.
PeerPubKey() [33]byte

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

// Start/Stop are used to initiate the start/stop of the channel link
// functioning.
// AuxBandwidth returns the bandwidth that can be used for a channel,
// expressed in milli-satoshi. This might be different from the regular
// BTC bandwidth for custom channels. This will always return fn.None()
// for a regular (non-custom) channel.
AuxBandwidth(amount lnwire.MilliSatoshi, cid lnwire.ShortChannelID,
htlcBlob fn.Option[tlv.Blob],
ts AuxTrafficShaper) fn.Result[OptionalBandwidth]

// Start starts the channel link.
Start() error

// Stop requests the channel link to be shut down.
Stop()
}

Expand Down Expand Up @@ -428,7 +443,7 @@ type htlcNotifier interface {
NotifyForwardingEvent(key HtlcKey, info HtlcInfo,
eventType HtlcEventType)

// NotifyIncomingLinkFailEvent notifies that a htlc has failed on our
// NotifyLinkFailEvent notifies that a htlc has failed on our
// incoming link. It takes an isReceive bool to differentiate between
// our node's receives and forwards.
NotifyLinkFailEvent(key HtlcKey, info HtlcInfo,
Expand All @@ -449,3 +464,36 @@ type htlcNotifier interface {
NotifyFinalHtlcEvent(key models.CircuitKey,
info channeldb.FinalHtlcInfo)
}

// AuxHtlcModifier is an interface that allows the sender to modify the outgoing
// HTLC of a payment by changing the amount or the wire message tlv records.
type AuxHtlcModifier interface {
// ProduceHtlcExtraData is a function that, based on the previous extra
// data blob of an HTLC, may produce a different blob or modify the
// amount of bitcoin this htlc should carry.
ProduceHtlcExtraData(totalAmount lnwire.MilliSatoshi,
htlcCustomRecords lnwire.CustomRecords) (lnwire.MilliSatoshi,
lnwire.CustomRecords, error)
}

// AuxTrafficShaper is an interface that allows the sender to determine if a
// payment should be carried by a channel based on the TLV records that may be
// present in the `update_add_htlc` message or the channel commitment itself.
type AuxTrafficShaper interface {
AuxHtlcModifier

// ShouldHandleTraffic is called in order to check if the channel
// identified by the provided channel ID may have external mechanisms
// that would allow it to carry out the payment.
ShouldHandleTraffic(cid lnwire.ShortChannelID,
fundingBlob fn.Option[tlv.Blob]) (bool, error)

// PaymentBandwidth returns the available bandwidth for a custom channel
// decided by the given channel aux blob and HTLC blob. A return value
// of 0 means there is no bandwidth available. To find out if a channel
// is a custom channel that should be handled by the traffic shaper, the
// ShouldHandleTraffic method should be called first.
PaymentBandwidth(htlcBlob, commitmentBlob fn.Option[tlv.Blob],
linkBandwidth,
htlcAmt lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error)
}
Loading
Loading