Skip to content

Commit

Permalink
Merge pull request #8241 from Roasbeef/v0-17-3-branch
Browse files Browse the repository at this point in the history
release: create v0.17.3-beta.rc1 release branch
  • Loading branch information
Roasbeef committed Dec 1, 2023
2 parents 6744c64 + 937fe6f commit d5b05d6
Show file tree
Hide file tree
Showing 12 changed files with 251 additions and 24 deletions.
4 changes: 2 additions & 2 deletions build/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ const (
AppMinor uint = 17

// AppPatch defines the application patch for this binary.
AppPatch uint = 2
AppPatch uint = 3

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

func init() {
Expand Down
36 changes: 36 additions & 0 deletions channeldb/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,30 @@ type OpenChannel struct {
sync.RWMutex
}

// String returns a string representation of the channel.
func (c *OpenChannel) String() string {
indexStr := "height=%v, local_htlc_index=%v, local_log_index=%v, " +
"remote_htlc_index=%v, remote_log_index=%v"

commit := c.LocalCommitment
local := fmt.Sprintf(indexStr, commit.CommitHeight,
commit.LocalHtlcIndex, commit.LocalLogIndex,
commit.RemoteHtlcIndex, commit.RemoteLogIndex,
)

commit = c.RemoteCommitment
remote := fmt.Sprintf(indexStr, commit.CommitHeight,
commit.LocalHtlcIndex, commit.LocalLogIndex,
commit.RemoteHtlcIndex, commit.RemoteLogIndex,
)

return fmt.Sprintf("SCID=%v, status=%v, initiator=%v, pending=%v, "+
"local commitment has %s, remote commitment has %s",
c.ShortChannelID, c.chanStatus, c.IsInitiator, c.IsPending,
local, remote,
)
}

// ShortChanID returns the current ShortChannelID of this channel.
func (c *OpenChannel) ShortChanID() lnwire.ShortChannelID {
c.RLock()
Expand Down Expand Up @@ -2100,6 +2124,10 @@ func (c *OpenChannel) ActiveHtlcs() []HTLC {
// which ones are present on their commitment.
remoteHtlcs := make(map[[32]byte]struct{})
for _, htlc := range c.RemoteCommitment.Htlcs {
log.Tracef("RemoteCommitment has htlc: id=%v, update=%v "+
"incoming=%v", htlc.HtlcIndex, htlc.LogIndex,
htlc.Incoming)

onionHash := sha256.Sum256(htlc.OnionBlob[:])
remoteHtlcs[onionHash] = struct{}{}
}
Expand All @@ -2108,8 +2136,16 @@ func (c *OpenChannel) ActiveHtlcs() []HTLC {
// as active if *we* know them as well.
activeHtlcs := make([]HTLC, 0, len(remoteHtlcs))
for _, htlc := range c.LocalCommitment.Htlcs {
log.Tracef("LocalCommitment has htlc: id=%v, update=%v "+
"incoming=%v", htlc.HtlcIndex, htlc.LogIndex,
htlc.Incoming)

onionHash := sha256.Sum256(htlc.OnionBlob[:])
if _, ok := remoteHtlcs[onionHash]; !ok {
log.Tracef("Skipped htlc due to onion mismatched: "+
"id=%v, update=%v incoming=%v",
htlc.HtlcIndex, htlc.LogIndex, htlc.Incoming)

continue
}

Expand Down
57 changes: 57 additions & 0 deletions docs/release-notes/release-notes-0.17.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Release Notes
- [Bug Fixes](#bug-fixes)
- [New Features](#new-features)
- [Functional Enhancements](#functional-enhancements)
- [RPC Additions](#rpc-additions)
- [lncli Additions](#lncli-additions)
- [Improvements](#improvements)
- [Functional Updates](#functional-updates)
- [RPC Updates](#rpc-updates)
- [lncli Updates](#lncli-updates)
- [Breaking Changes](#breaking-changes)
- [Performance Improvements](#performance-improvements)
- [Technical and Architectural Updates](#technical-and-architectural-updates)
- [BOLT Spec Updates](#bolt-spec-updates)
- [Testing](#testing)
- [Database](#database)
- [Code Health](#code-health)
- [Tooling and Documentation](#tooling-and-documentation)

# Bug Fixes

* [Replaced](https://github.com/lightningnetwork/lnd/pull/8224)
`musig2Sessions` with a `SyncMap` used in `input` package to avoid concurrent
write to this map.

* [Fixed](https://github.com/lightningnetwork/lnd/pull/8220) a loop variable
issue which may affect programs built using go `v1.20` and below.

* [An issue where LND would hang on shutdown has been fixed.](https://github.com/lightningnetwork/lnd/pull/8151)

# New Features
## Functional Enhancements
## RPC Additions
## lncli Additions

# Improvements
## Functional Updates
## RPC Updates
## lncli Updates
## Code Health
## Breaking Changes
## Performance Improvements

* [Optimized](https://github.com/lightningnetwork/lnd/pull/8232) the memoray
usage of `btcwallet`'s mempool. Users would need to use `bitcoind v25.0.0`
and above to take the advantage of this optimization.

# Technical and Architectural Updates
## BOLT Spec Updates
## Testing
## Database
## Code Health
## Tooling and Documentation

# Contributors (Alphabetical Order)
* Eugene Siegel
* Yong Yu
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/btcsuite/btcd/btcutil/psbt v1.1.8
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
github.com/btcsuite/btcwallet v0.16.10-0.20231017144732-e3ff37491e9c
github.com/btcsuite/btcwallet v0.16.10-0.20231129183218-5df09dd43358
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0
github.com/btcsuite/btcwallet/walletdb v1.4.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtyd
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcwallet v0.16.10-0.20231017144732-e3ff37491e9c h1:+7tbYEUj0TYYIvuvE9YP+x5dU3FT/8J6Qh8d5YvQwrE=
github.com/btcsuite/btcwallet v0.16.10-0.20231017144732-e3ff37491e9c/go.mod h1:WSKhOJWUmUOHKCKEzdt+jWAHFAE/t4RqVbCwL2pEdiU=
github.com/btcsuite/btcwallet v0.16.10-0.20231129183218-5df09dd43358 h1:lZUSo6TISHUJQxpn/AniW5gqaN1iRNS87SDWvV3AHfg=
github.com/btcsuite/btcwallet v0.16.10-0.20231129183218-5df09dd43358/go.mod h1:WSKhOJWUmUOHKCKEzdt+jWAHFAE/t4RqVbCwL2pEdiU=
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2 h1:etuLgGEojecsDOYTII8rYiGHjGyV5xTqsXi+ZQ715UU=
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2/go.mod h1:Zpk/LOb2sKqwP2lmHjaZT9AdaKsHPSbNLm2Uql5IQ/0=
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0 h1:BtEN5Empw62/RVnZ0VcJaVtVlBijnLlJY+dwjAye2Bg=
Expand Down
5 changes: 3 additions & 2 deletions htlcswitch/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,12 +649,13 @@ func (l *channelLink) createFailureWithUpdate(incoming bool,
// flow. We'll compare out commitment chains with the remote party, and re-send
// either a danging commit signature, a revocation, or both.
func (l *channelLink) syncChanStates() error {
l.log.Info("attempting to re-synchronize")
chanState := l.channel.State()

l.log.Infof("Attempting to re-synchronize channel: %v", chanState)

// First, we'll generate our ChanSync message to send to the other
// side. Based on this message, the remote party will decide if they
// need to retransmit any data or not.
chanState := l.channel.State()
localChanSyncMsg, err := chanState.ChanSyncMsg()
if err != nil {
return fmt.Errorf("unable to generate chan sync message for "+
Expand Down
29 changes: 15 additions & 14 deletions input/musig2_session_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnutils"
"github.com/lightningnetwork/lnd/multimutex"
)

Expand Down Expand Up @@ -38,16 +39,18 @@ type MusigSessionManager struct {

sessionMtx *multimutex.Mutex[MuSig2SessionID]

musig2Sessions map[MuSig2SessionID]*MuSig2State
musig2Sessions *lnutils.SyncMap[MuSig2SessionID, *MuSig2State]
}

// NewMusigSessionManager creates a new musig manager given an abstract key
// fetcher.
func NewMusigSessionManager(keyFetcher PrivKeyFetcher) *MusigSessionManager {
return &MusigSessionManager{
keyFetcher: keyFetcher,
musig2Sessions: make(map[MuSig2SessionID]*MuSig2State),
sessionMtx: multimutex.NewMutex[MuSig2SessionID](),
keyFetcher: keyFetcher,
musig2Sessions: &lnutils.SyncMap[
MuSig2SessionID, *MuSig2State,
]{},
sessionMtx: multimutex.NewMutex[MuSig2SessionID](),
}
}

Expand Down Expand Up @@ -134,9 +137,7 @@ func (m *MusigSessionManager) MuSig2CreateSession(bipVersion MuSig2Version,
//
// We'll use just all zeroes as the session ID for the mutex, as this
// is a "global" action.
m.sessionMtx.Lock(MuSig2SessionID{})
m.musig2Sessions[session.SessionID] = session
m.sessionMtx.Unlock(MuSig2SessionID{})
m.musig2Sessions.Store(session.SessionID, session)

return &session.MuSig2SessionInfo, nil
}
Expand All @@ -157,7 +158,7 @@ func (m *MusigSessionManager) MuSig2Sign(sessionID MuSig2SessionID,
m.sessionMtx.Lock(sessionID)
defer m.sessionMtx.Unlock(sessionID)

session, ok := m.musig2Sessions[sessionID]
session, ok := m.musig2Sessions.Load(sessionID)
if !ok {
return nil, fmt.Errorf("session with ID %x not found",
sessionID[:])
Expand All @@ -178,7 +179,7 @@ func (m *MusigSessionManager) MuSig2Sign(sessionID MuSig2SessionID,

// Clean up our local state if requested.
if cleanUp {
delete(m.musig2Sessions, sessionID)
m.musig2Sessions.Delete(sessionID)
}

return partialSig, nil
Expand All @@ -198,7 +199,7 @@ func (m *MusigSessionManager) MuSig2CombineSig(sessionID MuSig2SessionID,
m.sessionMtx.Lock(sessionID)
defer m.sessionMtx.Unlock(sessionID)

session, ok := m.musig2Sessions[sessionID]
session, ok := m.musig2Sessions.Load(sessionID)
if !ok {
return nil, false, fmt.Errorf("session with ID %x not found",
sessionID[:])
Expand Down Expand Up @@ -231,7 +232,7 @@ func (m *MusigSessionManager) MuSig2CombineSig(sessionID MuSig2SessionID,
// there is nothing more left to do.
if session.HaveAllSigs {
finalSig = session.session.FinalSig()
delete(m.musig2Sessions, sessionID)
m.musig2Sessions.Delete(sessionID)
}

return finalSig, session.HaveAllSigs, nil
Expand All @@ -245,12 +246,12 @@ func (m *MusigSessionManager) MuSig2Cleanup(sessionID MuSig2SessionID) error {
m.sessionMtx.Lock(sessionID)
defer m.sessionMtx.Unlock(sessionID)

_, ok := m.musig2Sessions[sessionID]
_, ok := m.musig2Sessions.Load(sessionID)
if !ok {
return fmt.Errorf("session with ID %x not found", sessionID[:])
}

delete(m.musig2Sessions, sessionID)
m.musig2Sessions.Delete(sessionID)

return nil
}
Expand All @@ -267,7 +268,7 @@ func (m *MusigSessionManager) MuSig2RegisterNonces(sessionID MuSig2SessionID,
m.sessionMtx.Lock(sessionID)
defer m.sessionMtx.Unlock(sessionID)

session, ok := m.musig2Sessions[sessionID]
session, ok := m.musig2Sessions.Load(sessionID)
if !ok {
return false, fmt.Errorf("session with ID %x not found",
sessionID[:])
Expand Down
3 changes: 2 additions & 1 deletion lntest/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,8 @@ func (h *HarnessTest) Shutdown(node *node.HarnessNode) {
return h.manager.shutdownNode(node)
}, DefaultTimeout)

require.NoErrorf(h, err, "unable to shutdown %v", node.Name())
require.NoErrorf(h, err, "unable to shutdown %v in %v", node.Name(),
h.manager.currentTestCase)
}

// SuspendNode stops the given node and returns a callback that can be used to
Expand Down
2 changes: 2 additions & 0 deletions lnwallet/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,8 @@ func (lc *LightningChannel) extractPayDescs(commitHeight uint64,
// persist state w.r.t to if forwarded or not, or can
// inadvertently trigger replays

htlc := htlc

payDesc, err := lc.diskHtlcToPayDesc(
feeRate, commitHeight, &htlc,
localCommitKeys, remoteCommitKeys,
Expand Down
98 changes: 98 additions & 0 deletions lnwallet/channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10112,3 +10112,101 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
)
require.ErrorIs(t, err, channeldb.ErrLogEntryNotFound)
}

// TestExtractPayDescs asserts that `extractPayDescs` can correctly turn a
// slice of htlcs into two slices of PaymentDescriptors.
func TestExtractPayDescs(t *testing.T) {
t.Parallel()

// Create a testing LightningChannel.
lnChan, _, err := CreateTestChannels(
t, channeldb.SingleFunderTweaklessBit,
)
require.NoError(t, err)

// Create two incoming HTLCs.
incomings := []channeldb.HTLC{
createRandomHTLC(t, true),
createRandomHTLC(t, true),
}

// Create two outgoing HTLCs.
outgoings := []channeldb.HTLC{
createRandomHTLC(t, false),
createRandomHTLC(t, false),
}

// Concatenate incomings and outgoings into a single slice.
htlcs := []channeldb.HTLC{}
htlcs = append(htlcs, incomings...)
htlcs = append(htlcs, outgoings...)

// Run the method under test.
//
// NOTE: we use nil commitment key rings to avoid checking the htlc
// scripts(`genHtlcScript`) as it should be tested independently.
incomingPDs, outgoingPDs, err := lnChan.extractPayDescs(
0, 0, htlcs, nil, nil, true,
)
require.NoError(t, err)

// Assert the incoming PaymentDescriptors are matched.
for i, pd := range incomingPDs {
htlc := incomings[i]
assertPayDescMatchHTLC(t, pd, htlc)
}

// Assert the outgoing PaymentDescriptors are matched.
for i, pd := range outgoingPDs {
htlc := outgoings[i]
assertPayDescMatchHTLC(t, pd, htlc)
}
}

// assertPayDescMatchHTLC compares a PaymentDescriptor to a channeldb.HTLC and
// asserts that the fields are matched.
func assertPayDescMatchHTLC(t *testing.T, pd PaymentDescriptor,
htlc channeldb.HTLC) {

require := require.New(t)

require.EqualValues(htlc.RHash, pd.RHash, "RHash")
require.Equal(htlc.RefundTimeout, pd.Timeout, "Timeout")
require.Equal(htlc.Amt, pd.Amount, "Amount")
require.Equal(htlc.HtlcIndex, pd.HtlcIndex, "HtlcIndex")
require.Equal(htlc.LogIndex, pd.LogIndex, "LogIndex")
require.EqualValues(htlc.OnionBlob[:], pd.OnionBlob, "OnionBlob")
}

// createRandomHTLC creates an HTLC that has random value in every field except
// the `Incoming`.
func createRandomHTLC(t *testing.T, incoming bool) channeldb.HTLC {
var onionBlob [lnwire.OnionPacketSize]byte
_, err := rand.Read(onionBlob[:])
require.NoError(t, err)

var rHash [lntypes.HashSize]byte
_, err = rand.Read(rHash[:])
require.NoError(t, err)

sig := make([]byte, 64)
_, err = rand.Read(sig)
require.NoError(t, err)

extra := make([]byte, 1000)
_, err = rand.Read(extra)
require.NoError(t, err)

return channeldb.HTLC{
Signature: sig,
RHash: rHash,
Amt: lnwire.MilliSatoshi(rand.Uint64()),
RefundTimeout: rand.Uint32(),
OutputIndex: rand.Int31n(1000),
Incoming: incoming,
OnionBlob: onionBlob,
HtlcIndex: rand.Uint64(),
LogIndex: rand.Uint64(),
ExtraData: extra,
}
}
3 changes: 2 additions & 1 deletion peer/brontide.go
Original file line number Diff line number Diff line change
Expand Up @@ -1941,7 +1941,8 @@ func messageSummary(msg lnwire.Message) string {
msg.ChanID, int64(msg.FeePerKw))

case *lnwire.ChannelReestablish:
return fmt.Sprintf("next_local_height=%v, remote_tail_height=%v",
return fmt.Sprintf("chan_id=%v, next_local_height=%v, "+
"remote_tail_height=%v", msg.ChanID,
msg.NextLocalCommitHeight, msg.RemoteCommitTailHeight)

case *lnwire.ReplyShortChanIDsEnd:
Expand Down

0 comments on commit d5b05d6

Please sign in to comment.