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

multi: accept memo note when opening channel #7668

Merged
merged 9 commits into from
May 19, 2023
18 changes: 17 additions & 1 deletion channeldb/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ const (
// A tlv type definition used to serialize and deserialize the
// confirmed ShortChannelID for a zero-conf channel.
realScidType tlv.Type = 4

// A tlv type definition used to serialize and deserialize the
// Memo for the channel channel.
channelMemoType tlv.Type = 5
)

// indexStatus is an enum-like type that describes what state the
Expand Down Expand Up @@ -818,6 +822,10 @@ type OpenChannel struct {
// default ShortChannelID. This is only set for zero-conf channels.
confirmedScid lnwire.ShortChannelID

// Memo is any arbitrary information we wish to store locally about the
// channel that will be useful to our future selves.
Memo []byte

// TODO(roasbeef): eww
Db *ChannelStateDB

Expand Down Expand Up @@ -3642,6 +3650,7 @@ func putChanInfo(chanBucket kvdb.RwBucket, channel *OpenChannel) error {
initialRemoteBalanceType, &remoteBalance,
),
MakeScidRecord(realScidType, &channel.confirmedScid),
tlv.MakePrimitiveRecord(channelMemoType, &channel.Memo),
guggero marked this conversation as resolved.
Show resolved Hide resolved
)
if err != nil {
return err
Expand Down Expand Up @@ -3839,10 +3848,11 @@ func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
}
}

// Create balance fields in uint64.
// Create balance fields in uint64, and Memo field as byte slice.
var (
localBalance uint64
remoteBalance uint64
memo []byte
)

// Create the tlv stream.
Expand All @@ -3859,6 +3869,7 @@ func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
initialRemoteBalanceType, &remoteBalance,
),
MakeScidRecord(realScidType, &channel.confirmedScid),
tlv.MakePrimitiveRecord(channelMemoType, &memo),
)
if err != nil {
return err
Expand All @@ -3872,6 +3883,11 @@ func fetchChanInfo(chanBucket kvdb.RBucket, channel *OpenChannel) error {
channel.InitialLocalBalance = lnwire.MilliSatoshi(localBalance)
channel.InitialRemoteBalance = lnwire.MilliSatoshi(remoteBalance)

// Attach the memo field if non-empty.
if len(memo) > 0 {
channel.Memo = memo
}

channel.Packager = NewChannelPackager(channel.ShortChannelID)

// Finally, read the optional shutdown scripts.
Expand Down
16 changes: 15 additions & 1 deletion cmd/lncli/cmd_open_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,12 @@ var openChannelCommand = cli.Command{

One can manually set the fee to be used for the funding transaction via
either the --conf_target or --sat_per_vbyte arguments. This is
optional.`,
optional.

One can also specify a short string memo to record some useful
information about the channel using the --memo argument. This is stored
locally only, and is purely for reference. It has no bearing on the
channel's operation. Max allowed length is 500 characters.`,
ArgsUsage: "node-key local-amt push-amt",
Flags: []cli.Flag{
cli.StringFlag{
Expand Down Expand Up @@ -257,6 +262,14 @@ var openChannelCommand = cli.Command{
"payment. If not specified, a default of 1% " +
"of the channel capacity will be used.",
},
cli.StringFlag{
Name: "memo",
Usage: `(optional) a note-to-self containing some useful
information about the channel. This is stored
locally only, and is purely for reference. It
has no bearing on the channel's operation. Max
allowed length is 500 characters`,
},
},
Action: actionDecorator(openChannel),
}
Expand Down Expand Up @@ -300,6 +313,7 @@ func openChannel(ctx *cli.Context) error {
ScidAlias: ctx.Bool("scid_alias"),
RemoteChanReserveSat: ctx.Uint64("remote_reserve_sats"),
FundMax: ctx.Bool("fundmax"),
Memo: ctx.String("memo"),
guggero marked this conversation as resolved.
Show resolved Hide resolved
}

switch {
Expand Down
5 changes: 5 additions & 0 deletions docs/release-notes/release-notes-0.17.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ package](https://github.com/lightningnetwork/lnd/pull/7356)
and `--protocol.custom-invoice` flags to set feature bits for various feature
"sets", as defined in [BOLT 9](https://github.com/lightning/bolts/blob/master/09-features.md).

* `OpenChannel` now accepts an [optional `memo`
argument](https://github.com/lightningnetwork/lnd/pull/7668) for specifying
a helpful note-to-self containing arbitrary useful information about the
channel.

## Misc

* [Generate default macaroons
Expand Down
5 changes: 5 additions & 0 deletions funding/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,10 @@ type InitFundingMsg struct {
// support explicit channel type negotiation.
ChannelType *lnwire.ChannelType

// Memo is any arbitrary information we wish to store locally about the
// channel that will be useful to our future selves.
Memo []byte

// Updates is a channel which updates to the opening status of the
// channel are sent on.
Updates chan *lnrpc.OpenStatusUpdate
Expand Down Expand Up @@ -4137,6 +4141,7 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
ZeroConf: zeroConf,
OptionScidAlias: scid,
ScidAliasFeature: scidFeatureVal,
Memo: msg.Memo,
}

reservation, err := f.cfg.Wallet.InitChannelReservation(req)
Expand Down
35 changes: 31 additions & 4 deletions itest/lnd_open_channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package itest

import (
"fmt"
"strings"
"testing"

"github.com/btcsuite/btcd/btcjson"
Expand Down Expand Up @@ -373,16 +374,32 @@ func runBasicChannelCreationAndUpdates(ht *lntest.HarnessTest,
aliceChanSub := alice.RPC.SubscribeChannelEvents()

// Open the channels between Alice and Bob, asserting that the channels
// have been properly opened on-chain.
// have been properly opened on-chain. We also attach the optional Memo
// argument to one of the channels so we can test that it can be
// retrieved correctly when querying the created channel.
chanPoints := make([]*lnrpc.ChannelPoint, numChannels)
openChannelParams := []lntest.OpenChannelParams{
{Amt: amount, Memo: "bob is a good peer"},
{Amt: amount},
}
for i := 0; i < numChannels; i++ {
chanPoints[i] = ht.OpenChannel(
alice, bob, lntest.OpenChannelParams{
Amt: amount,
},
alice, bob, openChannelParams[i],
)
}

// Alice should see the memo when retrieving the first channel.
channel := ht.QueryChannelByChanPoint(alice, chanPoints[0])
require.Equal(ht, "bob is a good peer", channel.Memo)

// Bob shouldn't see the memo since it's for Alice only.
channel = ht.QueryChannelByChanPoint(bob, chanPoints[0])
require.Empty(ht, channel.Memo, "Memo is not empty")
Comment on lines +395 to +397
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


// The second channel doesn't have a memo.
channel = ht.QueryChannelByChanPoint(alice, chanPoints[1])
require.Empty(ht, channel.Memo, "Memo is not empty")

// Since each of the channels just became open, Bob and Alice should
// each receive an open and an active notification for each channel.
const numExpectedOpenUpdates = 3 * numChannels
Expand Down Expand Up @@ -445,6 +462,16 @@ func runBasicChannelCreationAndUpdates(ht *lntest.HarnessTest,
}
}

// If Bob now tries to open a channel with an invalid memo, reject it.
invalidMemo := strings.Repeat("a", 501)
params := lntest.OpenChannelParams{
Amt: funding.MaxBtcFundingAmount,
Memo: invalidMemo,
}
expErr := fmt.Errorf("provided memo (%s) is of length 501, exceeds 500",
invalidMemo)
ht.OpenChannelAssertErr(bob, alice, params, expErr)

// verifyCloseUpdatesReceived is used to verify that Alice and Bob
// receive the correct channel updates in order.
const numExpectedCloseUpdates = 3 * numChannels
Expand Down
Loading