From 988d01de0df2994d278faa81306322bb6c8da459 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 3 Mar 2021 19:32:14 -0800 Subject: [PATCH 01/11] lnwire: introduce new explicit ChannelType TLV record In this commit, we add a new TLV record that's intended to be used as an explicit channel commitment type for a new form of funding negotiation, and later on a dynamic commitment upgrade protocol. As defined, we have 3 channel types: base (the OG), tweakless, and anchors w/ zero fee HTLCs. We omit the original variant of anchors as it was never truly deployed from the PoV of lnd. --- lnwire/channel_type.go | 58 +++++++++++++++++++++++++++++++++++++ lnwire/channel_type_test.go | 28 ++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 lnwire/channel_type.go create mode 100644 lnwire/channel_type_test.go diff --git a/lnwire/channel_type.go b/lnwire/channel_type.go new file mode 100644 index 000000000..a0696048b --- /dev/null +++ b/lnwire/channel_type.go @@ -0,0 +1,58 @@ +package lnwire + +import ( + "io" + + "github.com/lightningnetwork/lnd/tlv" +) + +const ( + // ChannelTypeRecordType is the type of the experimental record used + // to denote which channel type is being negotiated. + ChannelTypeRecordType tlv.Type = 1 +) + +// ChannelType represents a specific channel type as a set of feature bits that +// comprise it. +type ChannelType RawFeatureVector + +// featureBitLen returns the length in bytes of the encoded feature bits. +func (c ChannelType) featureBitLen() uint64 { + fv := RawFeatureVector(c) + return uint64(fv.SerializeSize()) +} + +// Record returns a TLV record that can be used to encode/decode the channel +// type from a given TLV stream. +func (c *ChannelType) Record() tlv.Record { + return tlv.MakeDynamicRecord( + ChannelTypeRecordType, c, c.featureBitLen, channelTypeEncoder, + channelTypeDecoder, + ) +} + +// channelTypeEncoder is a custom TLV encoder for the ChannelType record. +func channelTypeEncoder(w io.Writer, val interface{}, buf *[8]byte) error { + if v, ok := val.(*ChannelType); ok { + // Encode the feature bits as a byte slice without its length + // prepended, as that's already taken care of by the TLV record. + fv := RawFeatureVector(*v) + return fv.encode(w, fv.SerializeSize(), 8) + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.ChannelType") +} + +// channelTypeDecoder is a custom TLV decoder for the ChannelType record. +func channelTypeDecoder(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { + if v, ok := val.(*ChannelType); ok { + fv := NewRawFeatureVector() + if err := fv.decode(r, int(l), 8); err != nil { + return err + } + *v = ChannelType(*fv) + return nil + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.ChannelType") +} diff --git a/lnwire/channel_type_test.go b/lnwire/channel_type_test.go new file mode 100644 index 000000000..0edef0779 --- /dev/null +++ b/lnwire/channel_type_test.go @@ -0,0 +1,28 @@ +package lnwire + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// TestChannelTypeEncodeDecode tests that we're able to properly encode and +// decode channel types within TLV streams. +func TestChannelTypeEncodeDecode(t *testing.T) { + t.Parallel() + + chanType := ChannelType(*NewRawFeatureVector( + StaticRemoteKeyRequired, + AnchorsZeroFeeHtlcTxRequired, + )) + + var extraData ExtraOpaqueData + require.NoError(t, extraData.PackRecords(chanType.Record())) + + var chanType2 ChannelType + tlvs, err := extraData.ExtractRecords(chanType2.Record()) + require.NoError(t, err) + + require.Contains(t, tlvs, ChannelTypeRecordType) + require.Equal(t, chanType, chanType2) +} From 57b7a668c00ad3ebc049fd3517517118389238e0 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 3 Mar 2021 19:37:00 -0800 Subject: [PATCH 02/11] lnwire: add new ChannelType field as TLV record to Open/AcceptChannel In this commit, we add a new ChannelType field as a new TLV record to the OpenChannel message. During this change, we make a few tweaks to the generic TLV encode/decode methods for the ExtraOpaqueData struct to have it work on the level of tlv.RecordProducer instead of tlv.Record, as this reduces line noise a bit. We also partially undo existing logic that would attempt to "prepend" any new TLV records to the end of the ExtraOpaqueData if one was already present within the struct. This is based on the assumption that if we've read a message from disk to order to re-send/transmit it, then the ExtraOpaqueData is fully populated so we'll write that as is. Otherwise, a message is being encoded for the first time, and we expect all fields that are known TLV fields to be specified within the struct itself. This change required the unit tests to be modified slightly, as we'll always encode a fresh set of TLV records if none was already specified within the struct. --- lnwire/accept_channel.go | 90 ++++++++---------------------- lnwire/channel_type_test.go | 4 +- lnwire/extra_bytes.go | 37 +++++++++++- lnwire/extra_bytes_test.go | 22 +++++--- lnwire/lnwire_test.go | 29 +++++----- lnwire/open_channel.go | 32 ++++++++--- lnwire/typed_delivery_addr.go | 6 +- lnwire/typed_delivery_addr_test.go | 4 +- 8 files changed, 116 insertions(+), 108 deletions(-) diff --git a/lnwire/accept_channel.go b/lnwire/accept_channel.go index f5786b918..2f7957ff6 100644 --- a/lnwire/accept_channel.go +++ b/lnwire/accept_channel.go @@ -2,11 +2,11 @@ package lnwire import ( "bytes" - "fmt" "io" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/tlv" ) // AcceptChannel is the message Bob sends to Alice after she initiates the @@ -95,6 +95,10 @@ type AcceptChannel struct { // and its length followed by the script will be written if it is set. UpfrontShutdownScript DeliveryAddress + // ChannelType is the explicit channel type the initiator wishes to + // open. + ChannelType *ChannelType + // ExtraData is the set of data that was appended to this message to // fill out the full maximum transport message size. These fields can // be used to specify optional data such as custom TLV fields. @@ -117,11 +121,11 @@ var _ Message = (*AcceptChannel)(nil) // // This is part of the lnwire.Message interface. func (a *AcceptChannel) Encode(w *bytes.Buffer, pver uint32) error { - // Since the upfront script is encoded as a TLV record, concatenate it - // with the ExtraData, and write them as one. - tlvRecords, err := packShutdownScript( - a.UpfrontShutdownScript, a.ExtraData, - ) + recordProducers := []tlv.RecordProducer{&a.UpfrontShutdownScript} + if a.ChannelType != nil { + recordProducers = append(recordProducers, a.ChannelType) + } + err := EncodeMessageExtraData(&a.ExtraData, recordProducers...) if err != nil { return err } @@ -182,7 +186,7 @@ func (a *AcceptChannel) Encode(w *bytes.Buffer, pver uint32) error { return err } - return WriteBytes(w, tlvRecords) + return WriteBytes(w, a.ExtraData) } // Decode deserializes the serialized AcceptChannel stored in the passed @@ -220,74 +224,26 @@ func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error { return err } - a.UpfrontShutdownScript, a.ExtraData, err = parseShutdownScript( - tlvRecords, + // Next we'll parse out the set of known records, keeping the raw tlv + // bytes untouched to ensure we don't drop any bytes erroneously. + var chanType ChannelType + typeMap, err := tlvRecords.ExtractRecords( + &a.UpfrontShutdownScript, &chanType, ) if err != nil { return err } + // Set the corresponding TLV types if they were included in the stream. + if val, ok := typeMap[ChannelTypeRecordType]; ok && val == nil { + a.ChannelType = &chanType + } + + a.ExtraData = tlvRecords + return nil } -// packShutdownScript takes an upfront shutdown script and an opaque data blob -// and concatenates them. -func packShutdownScript(addr DeliveryAddress, extraData ExtraOpaqueData) ( - ExtraOpaqueData, error) { - - // We'll always write the upfront shutdown script record, regardless of - // the script being empty. - var tlvRecords ExtraOpaqueData - - // Pack it into a data blob as a TLV record. - err := tlvRecords.PackRecords(addr.NewRecord()) - if err != nil { - return nil, fmt.Errorf("unable to pack upfront shutdown "+ - "script as TLV record: %v", err) - } - - // Concatenate the remaining blob with the shutdown script record. - tlvRecords = append(tlvRecords, extraData...) - return tlvRecords, nil -} - -// parseShutdownScript reads and extract the upfront shutdown script from the -// passe data blob. It returns the script, if any, and the remainder of the -// data blob. -// -// This can be used to parse extra data for the OpenChannel and AcceptChannel -// messages, where the shutdown script is mandatory if extra TLV data is -// present. -func parseShutdownScript(tlvRecords ExtraOpaqueData) (DeliveryAddress, - ExtraOpaqueData, error) { - - // If no TLV data is present there can't be any script available. - if len(tlvRecords) == 0 { - return nil, tlvRecords, nil - } - - // Otherwise the shutdown script MUST be present. - var addr DeliveryAddress - tlvs, err := tlvRecords.ExtractRecords(addr.NewRecord()) - if err != nil { - return nil, nil, err - } - - // Not among TLV records, this means the data was invalid. - if _, ok := tlvs[DeliveryAddrType]; !ok { - return nil, nil, fmt.Errorf("no shutdown script in non-empty " + - "data blob") - } - - // Now that we have retrieved the address (which can be zero-length), - // we'll remove the bytes encoding it from the TLV data before - // returning it. - addrLen := len(addr) - tlvRecords = tlvRecords[addrLen+2:] - - return addr, tlvRecords, nil -} - // MsgType returns the MessageType code which uniquely identifies this message // as an AcceptChannel on the wire. // diff --git a/lnwire/channel_type_test.go b/lnwire/channel_type_test.go index 0edef0779..dd8e02439 100644 --- a/lnwire/channel_type_test.go +++ b/lnwire/channel_type_test.go @@ -17,10 +17,10 @@ func TestChannelTypeEncodeDecode(t *testing.T) { )) var extraData ExtraOpaqueData - require.NoError(t, extraData.PackRecords(chanType.Record())) + require.NoError(t, extraData.PackRecords(&chanType)) var chanType2 ChannelType - tlvs, err := extraData.ExtractRecords(chanType2.Record()) + tlvs, err := extraData.ExtractRecords(&chanType2) require.NoError(t, err) require.Contains(t, tlvs, ChannelTypeRecordType) diff --git a/lnwire/extra_bytes.go b/lnwire/extra_bytes.go index 70554f4f5..88b914c38 100644 --- a/lnwire/extra_bytes.go +++ b/lnwire/extra_bytes.go @@ -2,6 +2,7 @@ package lnwire import ( "bytes" + "fmt" "io" "io/ioutil" @@ -50,7 +51,17 @@ func (e *ExtraOpaqueData) Decode(r io.Reader) error { // PackRecords attempts to encode the set of tlv records into the target // ExtraOpaqueData instance. The records will be encoded as a raw TLV stream // and stored within the backing slice pointer. -func (e *ExtraOpaqueData) PackRecords(records ...tlv.Record) error { +func (e *ExtraOpaqueData) PackRecords(recordProducers ...tlv.RecordProducer) error { + // First, assemble all the records passed in in series. + records := make([]tlv.Record, 0, len(recordProducers)) + for _, producer := range recordProducers { + records = append(records, producer.Record()) + } + + // Ensure that the set of records are sorted before we encode them into + // the stream, to ensure they're canonical. + tlv.SortRecords(records) + tlvStream, err := tlv.NewStream(records...) if err != nil { return err @@ -70,9 +81,15 @@ func (e *ExtraOpaqueData) PackRecords(records ...tlv.Record) error { // it were a tlv stream. The set of raw parsed types is returned, and any // passed records (if found in the stream) will be parsed into the proper // tlv.Record. -func (e *ExtraOpaqueData) ExtractRecords(records ...tlv.Record) ( +func (e *ExtraOpaqueData) ExtractRecords(recordProducers ...tlv.RecordProducer) ( tlv.TypeMap, error) { + // First, assemble all the records passed in in series. + records := make([]tlv.Record, 0, len(recordProducers)) + for _, producer := range recordProducers { + records = append(records, producer.Record()) + } + extraBytesReader := bytes.NewReader(*e) tlvStream, err := tlv.NewStream(records...) @@ -82,3 +99,19 @@ func (e *ExtraOpaqueData) ExtractRecords(records ...tlv.Record) ( return tlvStream.DecodeWithParsedTypes(extraBytesReader) } + +// EncodeMessageExtraData encodes the given recordProducers into the given +// extraData. +func EncodeMessageExtraData(extraData *ExtraOpaqueData, + recordProducers ...tlv.RecordProducer) error { + + // Treat extraData as a mutable reference. + if extraData == nil { + return fmt.Errorf("extra data cannot be nil") + } + + // Pack in the series of TLV records into this message. The order we + // pass them in doesn't matter, as the method will ensure that things + // are all properly sorted. + return extraData.PackRecords(recordProducers...) +} diff --git a/lnwire/extra_bytes_test.go b/lnwire/extra_bytes_test.go index 39271d6aa..88ffcc307 100644 --- a/lnwire/extra_bytes_test.go +++ b/lnwire/extra_bytes_test.go @@ -86,6 +86,14 @@ func TestExtraOpaqueDataEncodeDecode(t *testing.T) { } } +type recordProducer struct { + record tlv.Record +} + +func (r *recordProducer) Record() tlv.Record { + return r.record +} + // TestExtraOpaqueDataPackUnpackRecords tests that we're able to pack a set of // tlv.Records into a stream, and unpack them on the other side to obtain the // same set of records. @@ -102,23 +110,23 @@ func TestExtraOpaqueDataPackUnpackRecords(t *testing.T) { hop1 uint32 = 99 hop2 uint32 ) - testRecords := []tlv.Record{ - tlv.MakePrimitiveRecord(type1, &channelType1), - tlv.MakePrimitiveRecord(type2, &hop1), + testRecordsProducers := []tlv.RecordProducer{ + &recordProducer{tlv.MakePrimitiveRecord(type1, &channelType1)}, + &recordProducer{tlv.MakePrimitiveRecord(type2, &hop1)}, } // Now that we have our set of sample records and types, we'll encode // them into the passed ExtraOpaqueData instance. var extraBytes ExtraOpaqueData - if err := extraBytes.PackRecords(testRecords...); err != nil { + if err := extraBytes.PackRecords(testRecordsProducers...); err != nil { t.Fatalf("unable to pack records: %v", err) } // We'll now simulate decoding these types _back_ into records on the // other side. - newRecords := []tlv.Record{ - tlv.MakePrimitiveRecord(type1, &channelType2), - tlv.MakePrimitiveRecord(type2, &hop2), + newRecords := []tlv.RecordProducer{ + &recordProducer{tlv.MakePrimitiveRecord(type1, &channelType2)}, + &recordProducer{tlv.MakePrimitiveRecord(type2, &hop2)}, } typeMap, err := extraBytes.ExtractRecords(newRecords...) if err != nil { diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 4475b3382..5143d74bd 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -18,8 +18,8 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" - "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/tor" + "github.com/stretchr/testify/assert" ) var ( @@ -284,9 +284,7 @@ func TestLightningWireProtocol(t *testing.T) { t.Fatalf("unable to read msg: %v", err) return false } - if !reflect.DeepEqual(msg, newMsg) { - t.Fatalf("messages don't match after re-encoding: %v "+ - "vs %v", spew.Sdump(msg), spew.Sdump(newMsg)) + if !assert.Equalf(t, msg, newMsg, "message mismatch") { return false } @@ -369,17 +367,16 @@ func TestLightningWireProtocol(t *testing.T) { t.Fatalf("unable to generate delivery address: %v", err) return } + + req.ChannelType = new(ChannelType) + *req.ChannelType = ChannelType(*randRawFeatureVector(r)) } else { req.UpfrontShutdownScript = []byte{} } - // 1/2 chance how having more TLV data after the - // shutdown script. + // 1/2 chance additional TLV data. if r.Intn(2) == 0 { - // TLV type 1 of length 2. - req.ExtraData = []byte{1, 2, 0xff, 0xff} - } else { - req.ExtraData = []byte{} + req.ExtraData = []byte{0xfd, 0x00, 0xff, 0x00} } v[0] = reflect.ValueOf(req) @@ -439,16 +436,16 @@ func TestLightningWireProtocol(t *testing.T) { t.Fatalf("unable to generate delivery address: %v", err) return } + + req.ChannelType = new(ChannelType) + *req.ChannelType = ChannelType(*randRawFeatureVector(r)) } else { req.UpfrontShutdownScript = []byte{} } - // 1/2 chance how having more TLV data after the - // shutdown script. + + // 1/2 chance additional TLV data. if r.Intn(2) == 0 { - // TLV type 1 of length 2. - req.ExtraData = []byte{1, 2, 0xff, 0xff} - } else { - req.ExtraData = []byte{} + req.ExtraData = []byte{0xfd, 0x00, 0xff, 0x00} } v[0] = reflect.ValueOf(req) diff --git a/lnwire/open_channel.go b/lnwire/open_channel.go index 035297ba2..534f17ee9 100644 --- a/lnwire/open_channel.go +++ b/lnwire/open_channel.go @@ -7,6 +7,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/tlv" ) // FundingFlag represents the possible bit mask values for the ChannelFlags @@ -130,6 +131,10 @@ type OpenChannel struct { // and its length followed by the script will be written if it is set. UpfrontShutdownScript DeliveryAddress + // ChannelType is the explicit channel type the initiator wishes to + // open. + ChannelType *ChannelType + // ExtraData is the set of data that was appended to this message to // fill out the full maximum transport message size. These fields can // be used to specify optional data such as custom TLV fields. @@ -150,13 +155,12 @@ var _ Message = (*OpenChannel)(nil) // implementation. Serialization will observe the rules defined by the passed // protocol version. // -// This is part of the lnwire.Message interface. func (o *OpenChannel) Encode(w *bytes.Buffer, pver uint32) error { - // Since the upfront script is encoded as a TLV record, concatenate it - // with the ExtraData, and write them as one. - tlvRecords, err := packShutdownScript( - o.UpfrontShutdownScript, o.ExtraData, - ) + recordProducers := []tlv.RecordProducer{&o.UpfrontShutdownScript} + if o.ChannelType != nil { + recordProducers = append(recordProducers, o.ChannelType) + } + err := EncodeMessageExtraData(&o.ExtraData, recordProducers...) if err != nil { return err } @@ -234,7 +238,7 @@ func (o *OpenChannel) Encode(w *bytes.Buffer, pver uint32) error { return err } - return WriteBytes(w, tlvRecords) + return WriteBytes(w, o.ExtraData) } // Decode deserializes the serialized OpenChannel stored in the passed @@ -276,13 +280,23 @@ func (o *OpenChannel) Decode(r io.Reader, pver uint32) error { return err } - o.UpfrontShutdownScript, o.ExtraData, err = parseShutdownScript( - tlvRecords, + // Next we'll parse out the set of known records, keeping the raw tlv + // bytes untouched to ensure we don't drop any bytes erroneously. + var chanType ChannelType + typeMap, err := tlvRecords.ExtractRecords( + &o.UpfrontShutdownScript, &chanType, ) if err != nil { return err } + // Set the corresponding TLV types if they were included in the stream. + if val, ok := typeMap[ChannelTypeRecordType]; ok && val == nil { + o.ChannelType = &chanType + } + + o.ExtraData = tlvRecords + return nil } diff --git a/lnwire/typed_delivery_addr.go b/lnwire/typed_delivery_addr.go index 9ad53b1ae..90a101b34 100644 --- a/lnwire/typed_delivery_addr.go +++ b/lnwire/typed_delivery_addr.go @@ -24,11 +24,11 @@ const ( // p2wpkh. type DeliveryAddress []byte -// NewRecord returns a TLV record that can be used to encode the delivery -// address within the ExtraData TLV stream. This was intorudced in order to +// Record returns a TLV record that can be used to encode the delivery +// address within the ExtraData TLV stream. This was introduced in order to // allow the OpenChannel/AcceptChannel messages to properly be extended with // TLV types. -func (d *DeliveryAddress) NewRecord() tlv.Record { +func (d *DeliveryAddress) Record() tlv.Record { addrBytes := (*[]byte)(d) return tlv.MakeDynamicRecord( diff --git a/lnwire/typed_delivery_addr_test.go b/lnwire/typed_delivery_addr_test.go index d5d9c703a..9d00bc8bd 100644 --- a/lnwire/typed_delivery_addr_test.go +++ b/lnwire/typed_delivery_addr_test.go @@ -15,13 +15,13 @@ func TestDeliveryAddressEncodeDecode(t *testing.T) { ) var extraData ExtraOpaqueData - err := extraData.PackRecords(addr.NewRecord()) + err := extraData.PackRecords(&addr) if err != nil { t.Fatal(err) } var addr2 DeliveryAddress - tlvs, err := extraData.ExtractRecords(addr2.NewRecord()) + tlvs, err := extraData.ExtractRecords(&addr2) if err != nil { t.Fatal(err) } From d0779e2ec2d51fd22ef3d463abaf990f322586f9 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 3 Mar 2021 19:39:12 -0800 Subject: [PATCH 03/11] lnwire: add new feature bits for explicit channel type negotiation If these bits are present, then both sides can examine the new CommitmentType TLV field that's present and use this in place of the existing implicit commiment type negotiation. With this change, it's now possible to actually deprecate old unsupported commitment types properly. --- feature/default_sets.go | 4 ++++ feature/deps.go | 4 ++++ lnwire/features.go | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/feature/default_sets.go b/feature/default_sets.go index 9103f903c..5ee98792a 100644 --- a/feature/default_sets.go +++ b/feature/default_sets.go @@ -60,4 +60,8 @@ var defaultSetDesc = setDesc{ lnwire.AMPRequired: { SetInvoiceAmp: {}, // 9A }, + lnwire.ExplicitChannelTypeOptional: { + SetInit: {}, // I + SetNodeAnn: {}, // N + }, } diff --git a/feature/deps.go b/feature/deps.go index 51ee37e9b..d6f57cb90 100644 --- a/feature/deps.go +++ b/feature/deps.go @@ -58,9 +58,13 @@ var deps = depDesc{ lnwire.AnchorsOptional: { lnwire.StaticRemoteKeyOptional: {}, }, + lnwire.AnchorsZeroFeeHtlcTxOptional: { + lnwire.StaticRemoteKeyOptional: {}, + }, lnwire.AMPOptional: { lnwire.PaymentAddrOptional: {}, }, + lnwire.ExplicitChannelTypeOptional: {}, } // ValidateDeps asserts that a feature vector sets all features and their diff --git a/lnwire/features.go b/lnwire/features.go index 675ba0f50..70aa23154 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -139,6 +139,26 @@ const ( // sender-generated preimages according to BOLT XX. AMPOptional FeatureBit = 31 + // ExplicitChannelTypeRequired is a required bit that denotes that a + // connection established with this node is to use explicit channel + // commitment types for negotiation instead of the existing implicit + // negotiation methods. With this bit, there is no longer a "default" + // implicit channel commitment type, allowing a connection to + // open/maintain types of several channels over its lifetime. + // + // TODO: Decide on actual feature bit value. + ExplicitChannelTypeRequired = 2020 + + // ExplicitChannelTypeOptional is an optional bit that denotes that a + // connection established with this node is to use explicit channel + // commitment types for negotiation instead of the existing implicit + // negotiation methods. With this bit, there is no longer a "default" + // implicit channel commitment type, allowing a connection to + // open/maintain types of several channels over its lifetime. + // + // TODO: Decide on actual feature bit value. + ExplicitChannelTypeOptional = 2021 + // maxAllowedSize is a maximum allowed size of feature vector. // // NOTE: Within the protocol, the maximum allowed message size is 65535 @@ -184,6 +204,8 @@ var Features = map[FeatureBit]string{ WumboChannelsOptional: "wumbo-channels", AMPRequired: "amp", AMPOptional: "amp", + ExplicitChannelTypeOptional: "explicit-commitment-type", + ExplicitChannelTypeRequired: "explicit-commitment-type", } // RawFeatureVector represents a set of feature bits as defined in BOLT-09. A From 5a9f499dd59a49d93d1779c6dd284090d9651831 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 3 Mar 2021 19:39:53 -0800 Subject: [PATCH 04/11] rpc: add new commitment_type field to OpenChannelRequest This field will be examined later down the stack along with the set of feature bits to determine if explicit channel commitment type negotiation is possible or not. --- funding/manager.go | 5 + lnrpc/lightning.pb.go | 1216 +++++++++++++++++----------------- lnrpc/lightning.proto | 22 +- lnrpc/lightning.swagger.json | 12 +- rpcserver.go | 28 + 5 files changed, 671 insertions(+), 612 deletions(-) diff --git a/funding/manager.go b/funding/manager.go index 63269ccb6..2a0473b33 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -240,6 +240,11 @@ type InitFundingMsg struct { // protocol. PendingChanID [32]byte + // ChannelType allows the caller to use an explicit channel type for the + // funding negotiation. This type will only be observed if BOTH sides + // support explicit channel type negotiation. + ChannelType *lnwire.ChannelType + // Updates is a channel which updates to the opening status of the channel // are sent on. Updates chan *lnrpc.OpenStatusUpdate diff --git a/lnrpc/lightning.pb.go b/lnrpc/lightning.pb.go index 1f2d3bc18..b2c97b349 100644 --- a/lnrpc/lightning.pb.go +++ b/lnrpc/lightning.pb.go @@ -80,39 +80,39 @@ func (AddressType) EnumDescriptor() ([]byte, []int) { type CommitmentType int32 const ( + // + //Returned when the commitment type isn't known or unavailable. + CommitmentType_UNKNOWN_COMMITMENT_TYPE CommitmentType = 0 // //A channel using the legacy commitment format having tweaked to_remote //keys. - CommitmentType_LEGACY CommitmentType = 0 + CommitmentType_LEGACY CommitmentType = 1 // //A channel that uses the modern commitment format where the key in the //output of the remote party does not change each state. This makes back //up and recovery easier as when the channel is closed, the funds go //directly to that key. - CommitmentType_STATIC_REMOTE_KEY CommitmentType = 1 + CommitmentType_STATIC_REMOTE_KEY CommitmentType = 2 // //A channel that uses a commitment format that has anchor outputs on the //commitments, allowing fee bumping after a force close transaction has //been broadcast. - CommitmentType_ANCHORS CommitmentType = 2 - // - //Returned when the commitment type isn't known or unavailable. - CommitmentType_UNKNOWN_COMMITMENT_TYPE CommitmentType = 999 + CommitmentType_ANCHORS CommitmentType = 3 ) // Enum value maps for CommitmentType. var ( CommitmentType_name = map[int32]string{ - 0: "LEGACY", - 1: "STATIC_REMOTE_KEY", - 2: "ANCHORS", - 999: "UNKNOWN_COMMITMENT_TYPE", + 0: "UNKNOWN_COMMITMENT_TYPE", + 1: "LEGACY", + 2: "STATIC_REMOTE_KEY", + 3: "ANCHORS", } CommitmentType_value = map[string]int32{ - "LEGACY": 0, - "STATIC_REMOTE_KEY": 1, - "ANCHORS": 2, - "UNKNOWN_COMMITMENT_TYPE": 999, + "UNKNOWN_COMMITMENT_TYPE": 0, + "LEGACY": 1, + "STATIC_REMOTE_KEY": 2, + "ANCHORS": 3, } ) @@ -4149,7 +4149,7 @@ func (x *Channel) GetCommitmentType() CommitmentType { if x != nil { return x.CommitmentType } - return CommitmentType_LEGACY + return CommitmentType_UNKNOWN_COMMITMENT_TYPE } func (x *Channel) GetLifetime() int64 { @@ -6105,6 +6105,10 @@ type OpenChannelRequest struct { //Max local csv is the maximum csv delay we will allow for our own commitment //transaction. MaxLocalCsv uint32 `protobuf:"varint,17,opt,name=max_local_csv,json=maxLocalCsv,proto3" json:"max_local_csv,omitempty"` + // + //The explicit commitment type to use. Note this field will only be used if + //the remote peer supports explicit channel negotiation. + CommitmentType CommitmentType `protobuf:"varint,18,opt,name=commitment_type,json=commitmentType,proto3,enum=lnrpc.CommitmentType" json:"commitment_type,omitempty"` } func (x *OpenChannelRequest) Reset() { @@ -6260,6 +6264,13 @@ func (x *OpenChannelRequest) GetMaxLocalCsv() uint32 { return 0 } +func (x *OpenChannelRequest) GetCommitmentType() CommitmentType { + if x != nil { + return x.CommitmentType + } + return CommitmentType_UNKNOWN_COMMITMENT_TYPE +} + type OpenStatusUpdate struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -14388,7 +14399,7 @@ func (x *PendingChannelsResponse_PendingChannel) GetCommitmentType() CommitmentT if x != nil { return x.CommitmentType } - return CommitmentType_LEGACY + return CommitmentType_UNKNOWN_COMMITMENT_TYPE } type PendingChannelsResponse_PendingOpenChannel struct { @@ -15525,7 +15536,7 @@ var file_lightning_proto_rawDesc = []byte{ 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x66, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x73, 0x62, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x70, 0x73, 0x62, 0x74, 0x22, 0xc0, 0x05, 0x0a, 0x12, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, + 0x04, 0x70, 0x73, 0x62, 0x74, 0x22, 0x80, 0x06, 0x0a, 0x12, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x61, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x76, 0x62, 0x79, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x61, 0x74, 0x50, 0x65, 0x72, 0x56, 0x62, 0x79, 0x74, 0x65, @@ -15569,7 +15580,11 @@ var file_lightning_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4d, 0x61, 0x78, 0x48, 0x74, 0x6c, 0x63, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x73, 0x76, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x61, 0x78, - 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x73, 0x76, 0x22, 0xf3, 0x01, 0x0a, 0x10, 0x4f, 0x70, 0x65, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x73, 0x76, 0x12, 0x3e, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0xf3, 0x01, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, 0x64, @@ -16884,363 +16899,363 @@ var file_lightning_proto_rawDesc = []byte{ 0x45, 0x44, 0x5f, 0x57, 0x49, 0x54, 0x4e, 0x45, 0x53, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4b, 0x45, 0x59, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x5f, 0x4e, 0x45, 0x53, 0x54, 0x45, 0x44, 0x5f, 0x50, 0x55, 0x42, 0x4b, 0x45, 0x59, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x03, 0x2a, 0x5e, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x45, 0x47, - 0x41, 0x43, 0x59, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, - 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, - 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x53, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x17, 0x55, 0x4e, 0x4b, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x03, 0x2a, 0x5d, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x4d, 0x45, 0x4e, 0x54, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x10, 0xe7, 0x07, 0x2a, 0x61, 0x0a, 0x09, 0x49, 0x6e, 0x69, 0x74, 0x69, - 0x61, 0x74, 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x4f, - 0x52, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x49, - 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x01, - 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x52, 0x45, - 0x4d, 0x4f, 0x54, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, - 0x54, 0x4f, 0x52, 0x5f, 0x42, 0x4f, 0x54, 0x48, 0x10, 0x03, 0x2a, 0x60, 0x0a, 0x0e, 0x52, 0x65, - 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, - 0x0a, 0x06, 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e, - 0x43, 0x4f, 0x4d, 0x49, 0x4e, 0x47, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x10, 0x02, 0x12, 0x11, 0x0a, - 0x0d, 0x4f, 0x55, 0x54, 0x47, 0x4f, 0x49, 0x4e, 0x47, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x10, 0x03, - 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x04, 0x2a, 0x71, 0x0a, 0x11, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, - 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x45, - 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x45, 0x44, - 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x42, 0x41, 0x4e, 0x44, 0x4f, 0x4e, 0x45, 0x44, 0x10, - 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, - 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x05, 0x2a, - 0x39, 0x0a, 0x0e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1a, - 0x0a, 0x16, 0x42, 0x45, 0x54, 0x57, 0x45, 0x45, 0x4e, 0x4e, 0x45, 0x53, 0x53, 0x5f, 0x43, 0x45, - 0x4e, 0x54, 0x52, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x01, 0x2a, 0x3b, 0x0a, 0x10, 0x49, 0x6e, - 0x76, 0x6f, 0x69, 0x63, 0x65, 0x48, 0x54, 0x4c, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0c, - 0x0a, 0x08, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, - 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x41, 0x4e, - 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x2a, 0xd9, 0x01, 0x0a, 0x14, 0x50, 0x61, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x12, 0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, - 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, - 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, - 0x4f, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, - 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, - 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, - 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x2c, 0x0a, 0x28, - 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, - 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, - 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x10, 0x04, 0x12, 0x27, 0x0a, 0x23, 0x46, 0x41, - 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, - 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, - 0x45, 0x10, 0x05, 0x2a, 0xcf, 0x04, 0x0a, 0x0a, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, - 0x69, 0x74, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x53, 0x53, 0x5f, 0x50, - 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, - 0x44, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x53, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, - 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, - 0x4c, 0x5f, 0x52, 0x4f, 0x55, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x03, 0x12, + 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x45, 0x47, 0x41, 0x43, 0x59, + 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x4d, + 0x4f, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4e, 0x43, + 0x48, 0x4f, 0x52, 0x53, 0x10, 0x03, 0x2a, 0x61, 0x0a, 0x09, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, + 0x74, 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x4f, 0x52, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, + 0x49, 0x54, 0x49, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, + 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x4d, + 0x4f, 0x54, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, + 0x4f, 0x52, 0x5f, 0x42, 0x4f, 0x54, 0x48, 0x10, 0x03, 0x2a, 0x60, 0x0a, 0x0e, 0x52, 0x65, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, + 0x06, 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e, 0x43, + 0x4f, 0x4d, 0x49, 0x4e, 0x47, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, + 0x4f, 0x55, 0x54, 0x47, 0x4f, 0x49, 0x4e, 0x47, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x10, 0x03, 0x12, + 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x04, 0x2a, 0x71, 0x0a, 0x11, 0x52, + 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, + 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x45, 0x44, 0x10, + 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x42, 0x41, 0x4e, 0x44, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x03, + 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x10, + 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x05, 0x2a, 0x39, + 0x0a, 0x0e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1a, 0x0a, + 0x16, 0x42, 0x45, 0x54, 0x57, 0x45, 0x45, 0x4e, 0x4e, 0x45, 0x53, 0x53, 0x5f, 0x43, 0x45, 0x4e, + 0x54, 0x52, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x01, 0x2a, 0x3b, 0x0a, 0x10, 0x49, 0x6e, 0x76, + 0x6f, 0x69, 0x63, 0x65, 0x48, 0x54, 0x4c, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0c, 0x0a, + 0x08, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, + 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x41, 0x4e, 0x43, + 0x45, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x2a, 0xd9, 0x01, 0x0a, 0x14, 0x50, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, + 0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, + 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, 0x4c, + 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, + 0x55, 0x54, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, + 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10, + 0x02, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, + 0x53, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x2c, 0x0a, 0x28, 0x46, + 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, + 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, + 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x10, 0x04, 0x12, 0x27, 0x0a, 0x23, 0x46, 0x41, 0x49, + 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, + 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, + 0x10, 0x05, 0x2a, 0xcf, 0x04, 0x0a, 0x0a, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x69, + 0x74, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x53, 0x53, 0x5f, 0x50, 0x52, + 0x4f, 0x54, 0x45, 0x43, 0x54, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x44, + 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x53, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, 0x5f, + 0x4f, 0x50, 0x54, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, + 0x5f, 0x52, 0x4f, 0x55, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x03, 0x12, 0x1f, + 0x0a, 0x1b, 0x55, 0x50, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, + 0x57, 0x4e, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x04, 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x50, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x53, 0x48, 0x55, 0x54, 0x44, - 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x04, - 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x50, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x53, 0x48, 0x55, 0x54, - 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4f, 0x50, 0x54, 0x10, - 0x05, 0x12, 0x16, 0x0a, 0x12, 0x47, 0x4f, 0x53, 0x53, 0x49, 0x50, 0x5f, 0x51, 0x55, 0x45, 0x52, - 0x49, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x47, 0x4f, 0x53, - 0x53, 0x49, 0x50, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x49, 0x45, 0x53, 0x5f, 0x4f, 0x50, 0x54, 0x10, - 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x4c, 0x56, 0x5f, 0x4f, 0x4e, 0x49, 0x4f, 0x4e, 0x5f, 0x52, - 0x45, 0x51, 0x10, 0x08, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x4c, 0x56, 0x5f, 0x4f, 0x4e, 0x49, 0x4f, - 0x4e, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x09, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x54, 0x5f, 0x47, - 0x4f, 0x53, 0x53, 0x49, 0x50, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x49, 0x45, 0x53, 0x5f, 0x52, 0x45, - 0x51, 0x10, 0x0a, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x54, 0x5f, 0x47, 0x4f, 0x53, 0x53, 0x49, - 0x50, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x49, 0x45, 0x53, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x0b, 0x12, - 0x19, 0x0a, 0x15, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, - 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x0c, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x54, - 0x41, 0x54, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x5f, - 0x4f, 0x50, 0x54, 0x10, 0x0d, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, - 0x5f, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x0e, 0x12, 0x14, 0x0a, 0x10, 0x50, - 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x4f, 0x50, 0x54, 0x10, - 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x4d, 0x50, 0x50, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x10, 0x12, 0x0b, - 0x0a, 0x07, 0x4d, 0x50, 0x50, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x11, 0x12, 0x16, 0x0a, 0x12, 0x57, - 0x55, 0x4d, 0x42, 0x4f, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x53, 0x5f, 0x52, 0x45, - 0x51, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x57, 0x55, 0x4d, 0x42, 0x4f, 0x5f, 0x43, 0x48, 0x41, - 0x4e, 0x4e, 0x45, 0x4c, 0x53, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x13, 0x12, 0x0f, 0x0a, 0x0b, 0x41, - 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x14, 0x12, 0x0f, 0x0a, 0x0b, - 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x53, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x15, 0x12, 0x1d, 0x0a, - 0x19, 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x53, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x5f, 0x46, 0x45, - 0x45, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x16, 0x12, 0x1d, 0x0a, 0x19, + 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x05, + 0x12, 0x16, 0x0a, 0x12, 0x47, 0x4f, 0x53, 0x53, 0x49, 0x50, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x49, + 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x47, 0x4f, 0x53, 0x53, + 0x49, 0x50, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x49, 0x45, 0x53, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x07, + 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x4c, 0x56, 0x5f, 0x4f, 0x4e, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, + 0x51, 0x10, 0x08, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x4c, 0x56, 0x5f, 0x4f, 0x4e, 0x49, 0x4f, 0x4e, + 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x09, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x54, 0x5f, 0x47, 0x4f, + 0x53, 0x53, 0x49, 0x50, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x49, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, + 0x10, 0x0a, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x54, 0x5f, 0x47, 0x4f, 0x53, 0x53, 0x49, 0x50, + 0x5f, 0x51, 0x55, 0x45, 0x52, 0x49, 0x45, 0x53, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x0b, 0x12, 0x19, + 0x0a, 0x15, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x5f, + 0x4b, 0x45, 0x59, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x0c, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x54, 0x41, + 0x54, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4f, + 0x50, 0x54, 0x10, 0x0d, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, + 0x41, 0x44, 0x44, 0x52, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x0e, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41, + 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x0f, + 0x12, 0x0b, 0x0a, 0x07, 0x4d, 0x50, 0x50, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x10, 0x12, 0x0b, 0x0a, + 0x07, 0x4d, 0x50, 0x50, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x11, 0x12, 0x16, 0x0a, 0x12, 0x57, 0x55, + 0x4d, 0x42, 0x4f, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x53, 0x5f, 0x52, 0x45, 0x51, + 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x57, 0x55, 0x4d, 0x42, 0x4f, 0x5f, 0x43, 0x48, 0x41, 0x4e, + 0x4e, 0x45, 0x4c, 0x53, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x13, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x4e, + 0x43, 0x48, 0x4f, 0x52, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x14, 0x12, 0x0f, 0x0a, 0x0b, 0x41, + 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x53, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x15, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x53, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x5f, 0x46, 0x45, 0x45, - 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x17, 0x12, 0x0b, 0x0a, 0x07, 0x41, - 0x4d, 0x50, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x1e, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4d, 0x50, 0x5f, - 0x4f, 0x50, 0x54, 0x10, 0x1f, 0x32, 0xc9, 0x21, 0x0a, 0x09, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x6e, - 0x69, 0x6e, 0x67, 0x12, 0x4a, 0x0a, 0x0d, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, - 0x6c, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4d, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, - 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, - 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x44, 0x0a, 0x0b, 0x45, - 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, - 0x70, 0x63, 0x2e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x73, - 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x12, 0x17, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, - 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, - 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, - 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x62, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x16, 0x12, 0x1d, 0x0a, 0x19, 0x41, + 0x4e, 0x43, 0x48, 0x4f, 0x52, 0x53, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x5f, 0x46, 0x45, 0x45, 0x5f, + 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x17, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4d, + 0x50, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x1e, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4d, 0x50, 0x5f, 0x4f, + 0x50, 0x54, 0x10, 0x1f, 0x32, 0xc9, 0x21, 0x0a, 0x09, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, + 0x6e, 0x67, 0x12, 0x4a, 0x0a, 0x0d, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x42, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, + 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, + 0x0f, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, - 0x79, 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, - 0x6e, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, - 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, - 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0d, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x2e, 0x6c, - 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, - 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, - 0x0e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, - 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, - 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, - 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, - 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x13, - 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x1a, 0x10, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x15, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, - 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x50, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, - 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, - 0x65, 0x6c, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, - 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x16, - 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, - 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, - 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, - 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, - 0x73, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0f, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, - 0x65, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, - 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, - 0x6c, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x43, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, + 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x44, 0x0a, 0x0b, 0x45, 0x73, + 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, + 0x63, 0x2e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x73, 0x74, + 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3e, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x12, 0x17, 0x2e, + 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x44, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x12, + 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, + 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x79, + 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, + 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0d, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x2e, 0x6c, 0x6e, + 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, + 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0e, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1c, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, + 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, + 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x13, 0x53, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x1a, 0x10, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x30, 0x01, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x15, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, + 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x50, 0x0a, 0x0f, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x16, 0x53, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, + 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0f, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x4c, 0x0a, 0x10, 0x46, - 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, - 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x67, 0x1a, 0x1b, 0x2e, 0x6c, - 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x12, 0x50, 0x0a, 0x0f, 0x43, 0x68, 0x61, - 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x2e, 0x6c, - 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, - 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, 0x12, 0x46, 0x0a, 0x0c, 0x43, - 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, - 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, - 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x43, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, - 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, - 0x64, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, - 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x28, - 0x01, 0x30, 0x01, 0x12, 0x3a, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, - 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x46, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x19, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, - 0x88, 0x02, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x54, - 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, - 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x41, 0x64, - 0x64, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, - 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x6f, 0x69, - 0x63, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x6f, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0d, 0x4c, 0x6f, - 0x6f, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x12, 0x2e, 0x6c, 0x6e, - 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x1a, - 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, - 0x41, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x49, 0x6e, 0x76, 0x6f, - 0x69, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, - 0x6f, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x1a, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, - 0x30, 0x01, 0x12, 0x32, 0x0a, 0x0c, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x79, 0x52, - 0x65, 0x71, 0x12, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x52, 0x65, - 0x71, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x1a, 0x0d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, - 0x50, 0x61, 0x79, 0x52, 0x65, 0x71, 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x56, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, + 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x43, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, + 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x4c, 0x0a, 0x10, 0x46, 0x75, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x1b, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x67, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, + 0x72, 0x70, 0x63, 0x2e, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x12, 0x50, 0x0a, 0x0f, 0x43, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, + 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, + 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, 0x12, 0x46, 0x0a, 0x0c, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, + 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, + 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x43, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, + 0x6e, 0x64, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, + 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3f, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x28, 0x01, + 0x30, 0x01, 0x12, 0x3a, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, + 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, + 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x19, 0x2e, + 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, + 0x02, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x41, 0x64, 0x64, + 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, + 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, + 0x41, 0x64, 0x64, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, + 0x65, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, + 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, + 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0d, 0x4c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, + 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x0e, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x41, + 0x0a, 0x11, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x49, 0x6e, 0x76, 0x6f, 0x69, + 0x63, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, + 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, + 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x30, + 0x01, 0x12, 0x32, 0x0a, 0x0c, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x79, 0x52, 0x65, + 0x71, 0x12, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x52, 0x65, 0x71, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x1a, 0x0d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, + 0x61, 0x79, 0x52, 0x65, 0x71, 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, + 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x62, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, - 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, - 0x6e, 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x47, 0x0a, 0x0e, 0x47, 0x65, 0x74, - 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, - 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, - 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, - 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x12, 0x36, 0x0a, - 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x6c, - 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x47, - 0x65, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, - 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, + 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x47, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, + 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, + 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, - 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x35, 0x0a, 0x0a, - 0x53, 0x74, 0x6f, 0x70, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, - 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x20, 0x2e, 0x6c, - 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, - 0x67, 0x79, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1a, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x54, 0x6f, 0x70, 0x6f, - 0x6c, 0x6f, 0x67, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, - 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x18, 0x2e, 0x6c, 0x6e, 0x72, - 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, - 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x3e, 0x0a, 0x09, 0x46, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x6c, - 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, - 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4e, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x56, 0x0a, 0x11, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, + 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x0b, + 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x6c, 0x6e, + 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x47, 0x65, + 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x6c, + 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x35, 0x0a, 0x0a, 0x53, + 0x74, 0x6f, 0x70, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, + 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x57, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x20, 0x2e, 0x6c, 0x6e, + 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1a, 0x2e, + 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x54, 0x6f, 0x70, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, + 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, + 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, + 0x0a, 0x09, 0x46, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x6e, + 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x65, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, + 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, + 0x0a, 0x11, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x77, + 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, - 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x21, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x61, - 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, - 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x54, 0x0a, 0x17, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x4e, 0x0a, - 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, - 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, - 0x15, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, - 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x62, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, - 0x12, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x30, 0x01, 0x12, - 0x47, 0x0a, 0x0c, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x12, - 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, - 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, - 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, - 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, - 0x49, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x21, 0x2e, + 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x14, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x54, 0x0a, 0x17, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x41, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x4e, 0x0a, 0x10, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6e, + 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x15, + 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, + 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x30, 0x01, 0x12, 0x47, + 0x0a, 0x0c, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x12, 0x1a, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, + 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, + 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, - 0x44, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x10, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1e, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, - 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, - 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x50, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x10, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1e, 0x2e, + 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, + 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, + 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, + 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -17502,241 +17517,242 @@ var file_lightning_proto_depIdxs = []int32{ 74, // 35: lnrpc.CloseStatusUpdate.close_pending:type_name -> lnrpc.PendingUpdate 71, // 36: lnrpc.CloseStatusUpdate.chan_close:type_name -> lnrpc.ChannelCloseUpdate 82, // 37: lnrpc.OpenChannelRequest.funding_shim:type_name -> lnrpc.FundingShim - 74, // 38: lnrpc.OpenStatusUpdate.chan_pending:type_name -> lnrpc.PendingUpdate - 70, // 39: lnrpc.OpenStatusUpdate.chan_open:type_name -> lnrpc.ChannelOpenUpdate - 75, // 40: lnrpc.OpenStatusUpdate.psbt_fund:type_name -> lnrpc.ReadyForPsbtFunding - 78, // 41: lnrpc.KeyDescriptor.key_loc:type_name -> lnrpc.KeyLocator - 28, // 42: lnrpc.ChanPointShim.chan_point:type_name -> lnrpc.ChannelPoint - 79, // 43: lnrpc.ChanPointShim.local_key:type_name -> lnrpc.KeyDescriptor - 80, // 44: lnrpc.FundingShim.chan_point_shim:type_name -> lnrpc.ChanPointShim - 81, // 45: lnrpc.FundingShim.psbt_shim:type_name -> lnrpc.PsbtShim - 82, // 46: lnrpc.FundingTransitionMsg.shim_register:type_name -> lnrpc.FundingShim - 83, // 47: lnrpc.FundingTransitionMsg.shim_cancel:type_name -> lnrpc.FundingShimCancel - 84, // 48: lnrpc.FundingTransitionMsg.psbt_verify:type_name -> lnrpc.FundingPsbtVerify - 85, // 49: lnrpc.FundingTransitionMsg.psbt_finalize:type_name -> lnrpc.FundingPsbtFinalize - 189, // 50: lnrpc.PendingChannelsResponse.pending_open_channels:type_name -> lnrpc.PendingChannelsResponse.PendingOpenChannel - 192, // 51: lnrpc.PendingChannelsResponse.pending_closing_channels:type_name -> lnrpc.PendingChannelsResponse.ClosedChannel - 193, // 52: lnrpc.PendingChannelsResponse.pending_force_closing_channels:type_name -> lnrpc.PendingChannelsResponse.ForceClosedChannel - 190, // 53: lnrpc.PendingChannelsResponse.waiting_close_channels:type_name -> lnrpc.PendingChannelsResponse.WaitingCloseChannel - 51, // 54: lnrpc.ChannelEventUpdate.open_channel:type_name -> lnrpc.Channel - 54, // 55: lnrpc.ChannelEventUpdate.closed_channel:type_name -> lnrpc.ChannelCloseSummary - 28, // 56: lnrpc.ChannelEventUpdate.active_channel:type_name -> lnrpc.ChannelPoint - 28, // 57: lnrpc.ChannelEventUpdate.inactive_channel:type_name -> lnrpc.ChannelPoint - 74, // 58: lnrpc.ChannelEventUpdate.pending_open_channel:type_name -> lnrpc.PendingUpdate - 28, // 59: lnrpc.ChannelEventUpdate.fully_resolved_channel:type_name -> lnrpc.ChannelPoint - 13, // 60: lnrpc.ChannelEventUpdate.type:type_name -> lnrpc.ChannelEventUpdate.UpdateType - 194, // 61: lnrpc.WalletBalanceResponse.account_balance:type_name -> lnrpc.WalletBalanceResponse.AccountBalanceEntry - 96, // 62: lnrpc.ChannelBalanceResponse.local_balance:type_name -> lnrpc.Amount - 96, // 63: lnrpc.ChannelBalanceResponse.remote_balance:type_name -> lnrpc.Amount - 96, // 64: lnrpc.ChannelBalanceResponse.unsettled_local_balance:type_name -> lnrpc.Amount - 96, // 65: lnrpc.ChannelBalanceResponse.unsettled_remote_balance:type_name -> lnrpc.Amount - 96, // 66: lnrpc.ChannelBalanceResponse.pending_open_local_balance:type_name -> lnrpc.Amount - 96, // 67: lnrpc.ChannelBalanceResponse.pending_open_remote_balance:type_name -> lnrpc.Amount - 22, // 68: lnrpc.QueryRoutesRequest.fee_limit:type_name -> lnrpc.FeeLimit - 101, // 69: lnrpc.QueryRoutesRequest.ignored_edges:type_name -> lnrpc.EdgeLocator - 100, // 70: lnrpc.QueryRoutesRequest.ignored_pairs:type_name -> lnrpc.NodePair - 195, // 71: lnrpc.QueryRoutesRequest.dest_custom_records:type_name -> lnrpc.QueryRoutesRequest.DestCustomRecordsEntry - 129, // 72: lnrpc.QueryRoutesRequest.route_hints:type_name -> lnrpc.RouteHint - 8, // 73: lnrpc.QueryRoutesRequest.dest_features:type_name -> lnrpc.FeatureBit - 106, // 74: lnrpc.QueryRoutesResponse.routes:type_name -> lnrpc.Route - 104, // 75: lnrpc.Hop.mpp_record:type_name -> lnrpc.MPPRecord - 105, // 76: lnrpc.Hop.amp_record:type_name -> lnrpc.AMPRecord - 196, // 77: lnrpc.Hop.custom_records:type_name -> lnrpc.Hop.CustomRecordsEntry - 103, // 78: lnrpc.Route.hops:type_name -> lnrpc.Hop - 109, // 79: lnrpc.NodeInfo.node:type_name -> lnrpc.LightningNode - 112, // 80: lnrpc.NodeInfo.channels:type_name -> lnrpc.ChannelEdge - 110, // 81: lnrpc.LightningNode.addresses:type_name -> lnrpc.NodeAddress - 197, // 82: lnrpc.LightningNode.features:type_name -> lnrpc.LightningNode.FeaturesEntry - 111, // 83: lnrpc.ChannelEdge.node1_policy:type_name -> lnrpc.RoutingPolicy - 111, // 84: lnrpc.ChannelEdge.node2_policy:type_name -> lnrpc.RoutingPolicy - 109, // 85: lnrpc.ChannelGraph.nodes:type_name -> lnrpc.LightningNode - 112, // 86: lnrpc.ChannelGraph.edges:type_name -> lnrpc.ChannelEdge - 5, // 87: lnrpc.NodeMetricsRequest.types:type_name -> lnrpc.NodeMetricType - 198, // 88: lnrpc.NodeMetricsResponse.betweenness_centrality:type_name -> lnrpc.NodeMetricsResponse.BetweennessCentralityEntry - 125, // 89: lnrpc.GraphTopologyUpdate.node_updates:type_name -> lnrpc.NodeUpdate - 126, // 90: lnrpc.GraphTopologyUpdate.channel_updates:type_name -> lnrpc.ChannelEdgeUpdate - 127, // 91: lnrpc.GraphTopologyUpdate.closed_chans:type_name -> lnrpc.ClosedChannelUpdate - 110, // 92: lnrpc.NodeUpdate.node_addresses:type_name -> lnrpc.NodeAddress - 199, // 93: lnrpc.NodeUpdate.features:type_name -> lnrpc.NodeUpdate.FeaturesEntry - 28, // 94: lnrpc.ChannelEdgeUpdate.chan_point:type_name -> lnrpc.ChannelPoint - 111, // 95: lnrpc.ChannelEdgeUpdate.routing_policy:type_name -> lnrpc.RoutingPolicy - 28, // 96: lnrpc.ClosedChannelUpdate.chan_point:type_name -> lnrpc.ChannelPoint - 128, // 97: lnrpc.RouteHint.hop_hints:type_name -> lnrpc.HopHint - 129, // 98: lnrpc.Invoice.route_hints:type_name -> lnrpc.RouteHint - 14, // 99: lnrpc.Invoice.state:type_name -> lnrpc.Invoice.InvoiceState - 131, // 100: lnrpc.Invoice.htlcs:type_name -> lnrpc.InvoiceHTLC - 200, // 101: lnrpc.Invoice.features:type_name -> lnrpc.Invoice.FeaturesEntry - 6, // 102: lnrpc.InvoiceHTLC.state:type_name -> lnrpc.InvoiceHTLCState - 201, // 103: lnrpc.InvoiceHTLC.custom_records:type_name -> lnrpc.InvoiceHTLC.CustomRecordsEntry - 132, // 104: lnrpc.InvoiceHTLC.amp:type_name -> lnrpc.AMP - 130, // 105: lnrpc.ListInvoiceResponse.invoices:type_name -> lnrpc.Invoice - 15, // 106: lnrpc.Payment.status:type_name -> lnrpc.Payment.PaymentStatus - 139, // 107: lnrpc.Payment.htlcs:type_name -> lnrpc.HTLCAttempt - 7, // 108: lnrpc.Payment.failure_reason:type_name -> lnrpc.PaymentFailureReason - 16, // 109: lnrpc.HTLCAttempt.status:type_name -> lnrpc.HTLCAttempt.HTLCStatus - 106, // 110: lnrpc.HTLCAttempt.route:type_name -> lnrpc.Route - 179, // 111: lnrpc.HTLCAttempt.failure:type_name -> lnrpc.Failure - 138, // 112: lnrpc.ListPaymentsResponse.payments:type_name -> lnrpc.Payment - 28, // 113: lnrpc.AbandonChannelRequest.channel_point:type_name -> lnrpc.ChannelPoint - 129, // 114: lnrpc.PayReq.route_hints:type_name -> lnrpc.RouteHint - 202, // 115: lnrpc.PayReq.features:type_name -> lnrpc.PayReq.FeaturesEntry - 152, // 116: lnrpc.FeeReportResponse.channel_fees:type_name -> lnrpc.ChannelFeeReport - 28, // 117: lnrpc.PolicyUpdateRequest.chan_point:type_name -> lnrpc.ChannelPoint - 157, // 118: lnrpc.ForwardingHistoryResponse.forwarding_events:type_name -> lnrpc.ForwardingEvent - 28, // 119: lnrpc.ExportChannelBackupRequest.chan_point:type_name -> lnrpc.ChannelPoint - 28, // 120: lnrpc.ChannelBackup.chan_point:type_name -> lnrpc.ChannelPoint - 28, // 121: lnrpc.MultiChanBackup.chan_points:type_name -> lnrpc.ChannelPoint - 164, // 122: lnrpc.ChanBackupSnapshot.single_chan_backups:type_name -> lnrpc.ChannelBackups - 161, // 123: lnrpc.ChanBackupSnapshot.multi_chan_backup:type_name -> lnrpc.MultiChanBackup - 160, // 124: lnrpc.ChannelBackups.chan_backups:type_name -> lnrpc.ChannelBackup - 164, // 125: lnrpc.RestoreChanBackupRequest.chan_backups:type_name -> lnrpc.ChannelBackups - 169, // 126: lnrpc.BakeMacaroonRequest.permissions:type_name -> lnrpc.MacaroonPermission - 169, // 127: lnrpc.MacaroonPermissionList.permissions:type_name -> lnrpc.MacaroonPermission - 203, // 128: lnrpc.ListPermissionsResponse.method_permissions:type_name -> lnrpc.ListPermissionsResponse.MethodPermissionsEntry - 17, // 129: lnrpc.Failure.code:type_name -> lnrpc.Failure.FailureCode - 180, // 130: lnrpc.Failure.channel_update:type_name -> lnrpc.ChannelUpdate - 182, // 131: lnrpc.MacaroonId.ops:type_name -> lnrpc.Op - 150, // 132: lnrpc.Peer.FeaturesEntry.value:type_name -> lnrpc.Feature - 150, // 133: lnrpc.GetInfoResponse.FeaturesEntry.value:type_name -> lnrpc.Feature - 2, // 134: lnrpc.PendingChannelsResponse.PendingChannel.initiator:type_name -> lnrpc.Initiator - 1, // 135: lnrpc.PendingChannelsResponse.PendingChannel.commitment_type:type_name -> lnrpc.CommitmentType - 188, // 136: lnrpc.PendingChannelsResponse.PendingOpenChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel - 188, // 137: lnrpc.PendingChannelsResponse.WaitingCloseChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel - 191, // 138: lnrpc.PendingChannelsResponse.WaitingCloseChannel.commitments:type_name -> lnrpc.PendingChannelsResponse.Commitments - 188, // 139: lnrpc.PendingChannelsResponse.ClosedChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel - 188, // 140: lnrpc.PendingChannelsResponse.ForceClosedChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel - 88, // 141: lnrpc.PendingChannelsResponse.ForceClosedChannel.pending_htlcs:type_name -> lnrpc.PendingHTLC - 12, // 142: lnrpc.PendingChannelsResponse.ForceClosedChannel.anchor:type_name -> lnrpc.PendingChannelsResponse.ForceClosedChannel.AnchorState - 93, // 143: lnrpc.WalletBalanceResponse.AccountBalanceEntry.value:type_name -> lnrpc.WalletAccountBalance - 150, // 144: lnrpc.LightningNode.FeaturesEntry.value:type_name -> lnrpc.Feature - 117, // 145: lnrpc.NodeMetricsResponse.BetweennessCentralityEntry.value:type_name -> lnrpc.FloatMetric - 150, // 146: lnrpc.NodeUpdate.FeaturesEntry.value:type_name -> lnrpc.Feature - 150, // 147: lnrpc.Invoice.FeaturesEntry.value:type_name -> lnrpc.Feature - 150, // 148: lnrpc.PayReq.FeaturesEntry.value:type_name -> lnrpc.Feature - 176, // 149: lnrpc.ListPermissionsResponse.MethodPermissionsEntry.value:type_name -> lnrpc.MacaroonPermissionList - 94, // 150: lnrpc.Lightning.WalletBalance:input_type -> lnrpc.WalletBalanceRequest - 97, // 151: lnrpc.Lightning.ChannelBalance:input_type -> lnrpc.ChannelBalanceRequest - 20, // 152: lnrpc.Lightning.GetTransactions:input_type -> lnrpc.GetTransactionsRequest - 31, // 153: lnrpc.Lightning.EstimateFee:input_type -> lnrpc.EstimateFeeRequest - 35, // 154: lnrpc.Lightning.SendCoins:input_type -> lnrpc.SendCoinsRequest - 37, // 155: lnrpc.Lightning.ListUnspent:input_type -> lnrpc.ListUnspentRequest - 20, // 156: lnrpc.Lightning.SubscribeTransactions:input_type -> lnrpc.GetTransactionsRequest - 33, // 157: lnrpc.Lightning.SendMany:input_type -> lnrpc.SendManyRequest - 39, // 158: lnrpc.Lightning.NewAddress:input_type -> lnrpc.NewAddressRequest - 41, // 159: lnrpc.Lightning.SignMessage:input_type -> lnrpc.SignMessageRequest - 43, // 160: lnrpc.Lightning.VerifyMessage:input_type -> lnrpc.VerifyMessageRequest - 45, // 161: lnrpc.Lightning.ConnectPeer:input_type -> lnrpc.ConnectPeerRequest - 47, // 162: lnrpc.Lightning.DisconnectPeer:input_type -> lnrpc.DisconnectPeerRequest - 60, // 163: lnrpc.Lightning.ListPeers:input_type -> lnrpc.ListPeersRequest - 62, // 164: lnrpc.Lightning.SubscribePeerEvents:input_type -> lnrpc.PeerEventSubscription - 64, // 165: lnrpc.Lightning.GetInfo:input_type -> lnrpc.GetInfoRequest - 66, // 166: lnrpc.Lightning.GetRecoveryInfo:input_type -> lnrpc.GetRecoveryInfoRequest - 89, // 167: lnrpc.Lightning.PendingChannels:input_type -> lnrpc.PendingChannelsRequest - 52, // 168: lnrpc.Lightning.ListChannels:input_type -> lnrpc.ListChannelsRequest - 91, // 169: lnrpc.Lightning.SubscribeChannelEvents:input_type -> lnrpc.ChannelEventSubscription - 56, // 170: lnrpc.Lightning.ClosedChannels:input_type -> lnrpc.ClosedChannelsRequest - 76, // 171: lnrpc.Lightning.OpenChannelSync:input_type -> lnrpc.OpenChannelRequest - 76, // 172: lnrpc.Lightning.OpenChannel:input_type -> lnrpc.OpenChannelRequest - 86, // 173: lnrpc.Lightning.FundingStateStep:input_type -> lnrpc.FundingTransitionMsg - 27, // 174: lnrpc.Lightning.ChannelAcceptor:input_type -> lnrpc.ChannelAcceptResponse - 72, // 175: lnrpc.Lightning.CloseChannel:input_type -> lnrpc.CloseChannelRequest - 144, // 176: lnrpc.Lightning.AbandonChannel:input_type -> lnrpc.AbandonChannelRequest - 23, // 177: lnrpc.Lightning.SendPayment:input_type -> lnrpc.SendRequest - 23, // 178: lnrpc.Lightning.SendPaymentSync:input_type -> lnrpc.SendRequest - 25, // 179: lnrpc.Lightning.SendToRoute:input_type -> lnrpc.SendToRouteRequest - 25, // 180: lnrpc.Lightning.SendToRouteSync:input_type -> lnrpc.SendToRouteRequest - 130, // 181: lnrpc.Lightning.AddInvoice:input_type -> lnrpc.Invoice - 135, // 182: lnrpc.Lightning.ListInvoices:input_type -> lnrpc.ListInvoiceRequest - 134, // 183: lnrpc.Lightning.LookupInvoice:input_type -> lnrpc.PaymentHash - 137, // 184: lnrpc.Lightning.SubscribeInvoices:input_type -> lnrpc.InvoiceSubscription - 148, // 185: lnrpc.Lightning.DecodePayReq:input_type -> lnrpc.PayReqString - 140, // 186: lnrpc.Lightning.ListPayments:input_type -> lnrpc.ListPaymentsRequest - 142, // 187: lnrpc.Lightning.DeleteAllPayments:input_type -> lnrpc.DeleteAllPaymentsRequest - 113, // 188: lnrpc.Lightning.DescribeGraph:input_type -> lnrpc.ChannelGraphRequest - 115, // 189: lnrpc.Lightning.GetNodeMetrics:input_type -> lnrpc.NodeMetricsRequest - 118, // 190: lnrpc.Lightning.GetChanInfo:input_type -> lnrpc.ChanInfoRequest - 107, // 191: lnrpc.Lightning.GetNodeInfo:input_type -> lnrpc.NodeInfoRequest - 99, // 192: lnrpc.Lightning.QueryRoutes:input_type -> lnrpc.QueryRoutesRequest - 119, // 193: lnrpc.Lightning.GetNetworkInfo:input_type -> lnrpc.NetworkInfoRequest - 121, // 194: lnrpc.Lightning.StopDaemon:input_type -> lnrpc.StopRequest - 123, // 195: lnrpc.Lightning.SubscribeChannelGraph:input_type -> lnrpc.GraphTopologySubscription - 146, // 196: lnrpc.Lightning.DebugLevel:input_type -> lnrpc.DebugLevelRequest - 151, // 197: lnrpc.Lightning.FeeReport:input_type -> lnrpc.FeeReportRequest - 154, // 198: lnrpc.Lightning.UpdateChannelPolicy:input_type -> lnrpc.PolicyUpdateRequest - 156, // 199: lnrpc.Lightning.ForwardingHistory:input_type -> lnrpc.ForwardingHistoryRequest - 159, // 200: lnrpc.Lightning.ExportChannelBackup:input_type -> lnrpc.ExportChannelBackupRequest - 162, // 201: lnrpc.Lightning.ExportAllChannelBackups:input_type -> lnrpc.ChanBackupExportRequest - 163, // 202: lnrpc.Lightning.VerifyChanBackup:input_type -> lnrpc.ChanBackupSnapshot - 165, // 203: lnrpc.Lightning.RestoreChannelBackups:input_type -> lnrpc.RestoreChanBackupRequest - 167, // 204: lnrpc.Lightning.SubscribeChannelBackups:input_type -> lnrpc.ChannelBackupSubscription - 170, // 205: lnrpc.Lightning.BakeMacaroon:input_type -> lnrpc.BakeMacaroonRequest - 172, // 206: lnrpc.Lightning.ListMacaroonIDs:input_type -> lnrpc.ListMacaroonIDsRequest - 174, // 207: lnrpc.Lightning.DeleteMacaroonID:input_type -> lnrpc.DeleteMacaroonIDRequest - 177, // 208: lnrpc.Lightning.ListPermissions:input_type -> lnrpc.ListPermissionsRequest - 95, // 209: lnrpc.Lightning.WalletBalance:output_type -> lnrpc.WalletBalanceResponse - 98, // 210: lnrpc.Lightning.ChannelBalance:output_type -> lnrpc.ChannelBalanceResponse - 21, // 211: lnrpc.Lightning.GetTransactions:output_type -> lnrpc.TransactionDetails - 32, // 212: lnrpc.Lightning.EstimateFee:output_type -> lnrpc.EstimateFeeResponse - 36, // 213: lnrpc.Lightning.SendCoins:output_type -> lnrpc.SendCoinsResponse - 38, // 214: lnrpc.Lightning.ListUnspent:output_type -> lnrpc.ListUnspentResponse - 19, // 215: lnrpc.Lightning.SubscribeTransactions:output_type -> lnrpc.Transaction - 34, // 216: lnrpc.Lightning.SendMany:output_type -> lnrpc.SendManyResponse - 40, // 217: lnrpc.Lightning.NewAddress:output_type -> lnrpc.NewAddressResponse - 42, // 218: lnrpc.Lightning.SignMessage:output_type -> lnrpc.SignMessageResponse - 44, // 219: lnrpc.Lightning.VerifyMessage:output_type -> lnrpc.VerifyMessageResponse - 46, // 220: lnrpc.Lightning.ConnectPeer:output_type -> lnrpc.ConnectPeerResponse - 48, // 221: lnrpc.Lightning.DisconnectPeer:output_type -> lnrpc.DisconnectPeerResponse - 61, // 222: lnrpc.Lightning.ListPeers:output_type -> lnrpc.ListPeersResponse - 63, // 223: lnrpc.Lightning.SubscribePeerEvents:output_type -> lnrpc.PeerEvent - 65, // 224: lnrpc.Lightning.GetInfo:output_type -> lnrpc.GetInfoResponse - 67, // 225: lnrpc.Lightning.GetRecoveryInfo:output_type -> lnrpc.GetRecoveryInfoResponse - 90, // 226: lnrpc.Lightning.PendingChannels:output_type -> lnrpc.PendingChannelsResponse - 53, // 227: lnrpc.Lightning.ListChannels:output_type -> lnrpc.ListChannelsResponse - 92, // 228: lnrpc.Lightning.SubscribeChannelEvents:output_type -> lnrpc.ChannelEventUpdate - 57, // 229: lnrpc.Lightning.ClosedChannels:output_type -> lnrpc.ClosedChannelsResponse - 28, // 230: lnrpc.Lightning.OpenChannelSync:output_type -> lnrpc.ChannelPoint - 77, // 231: lnrpc.Lightning.OpenChannel:output_type -> lnrpc.OpenStatusUpdate - 87, // 232: lnrpc.Lightning.FundingStateStep:output_type -> lnrpc.FundingStateStepResp - 26, // 233: lnrpc.Lightning.ChannelAcceptor:output_type -> lnrpc.ChannelAcceptRequest - 73, // 234: lnrpc.Lightning.CloseChannel:output_type -> lnrpc.CloseStatusUpdate - 145, // 235: lnrpc.Lightning.AbandonChannel:output_type -> lnrpc.AbandonChannelResponse - 24, // 236: lnrpc.Lightning.SendPayment:output_type -> lnrpc.SendResponse - 24, // 237: lnrpc.Lightning.SendPaymentSync:output_type -> lnrpc.SendResponse - 24, // 238: lnrpc.Lightning.SendToRoute:output_type -> lnrpc.SendResponse - 24, // 239: lnrpc.Lightning.SendToRouteSync:output_type -> lnrpc.SendResponse - 133, // 240: lnrpc.Lightning.AddInvoice:output_type -> lnrpc.AddInvoiceResponse - 136, // 241: lnrpc.Lightning.ListInvoices:output_type -> lnrpc.ListInvoiceResponse - 130, // 242: lnrpc.Lightning.LookupInvoice:output_type -> lnrpc.Invoice - 130, // 243: lnrpc.Lightning.SubscribeInvoices:output_type -> lnrpc.Invoice - 149, // 244: lnrpc.Lightning.DecodePayReq:output_type -> lnrpc.PayReq - 141, // 245: lnrpc.Lightning.ListPayments:output_type -> lnrpc.ListPaymentsResponse - 143, // 246: lnrpc.Lightning.DeleteAllPayments:output_type -> lnrpc.DeleteAllPaymentsResponse - 114, // 247: lnrpc.Lightning.DescribeGraph:output_type -> lnrpc.ChannelGraph - 116, // 248: lnrpc.Lightning.GetNodeMetrics:output_type -> lnrpc.NodeMetricsResponse - 112, // 249: lnrpc.Lightning.GetChanInfo:output_type -> lnrpc.ChannelEdge - 108, // 250: lnrpc.Lightning.GetNodeInfo:output_type -> lnrpc.NodeInfo - 102, // 251: lnrpc.Lightning.QueryRoutes:output_type -> lnrpc.QueryRoutesResponse - 120, // 252: lnrpc.Lightning.GetNetworkInfo:output_type -> lnrpc.NetworkInfo - 122, // 253: lnrpc.Lightning.StopDaemon:output_type -> lnrpc.StopResponse - 124, // 254: lnrpc.Lightning.SubscribeChannelGraph:output_type -> lnrpc.GraphTopologyUpdate - 147, // 255: lnrpc.Lightning.DebugLevel:output_type -> lnrpc.DebugLevelResponse - 153, // 256: lnrpc.Lightning.FeeReport:output_type -> lnrpc.FeeReportResponse - 155, // 257: lnrpc.Lightning.UpdateChannelPolicy:output_type -> lnrpc.PolicyUpdateResponse - 158, // 258: lnrpc.Lightning.ForwardingHistory:output_type -> lnrpc.ForwardingHistoryResponse - 160, // 259: lnrpc.Lightning.ExportChannelBackup:output_type -> lnrpc.ChannelBackup - 163, // 260: lnrpc.Lightning.ExportAllChannelBackups:output_type -> lnrpc.ChanBackupSnapshot - 168, // 261: lnrpc.Lightning.VerifyChanBackup:output_type -> lnrpc.VerifyChanBackupResponse - 166, // 262: lnrpc.Lightning.RestoreChannelBackups:output_type -> lnrpc.RestoreBackupResponse - 163, // 263: lnrpc.Lightning.SubscribeChannelBackups:output_type -> lnrpc.ChanBackupSnapshot - 171, // 264: lnrpc.Lightning.BakeMacaroon:output_type -> lnrpc.BakeMacaroonResponse - 173, // 265: lnrpc.Lightning.ListMacaroonIDs:output_type -> lnrpc.ListMacaroonIDsResponse - 175, // 266: lnrpc.Lightning.DeleteMacaroonID:output_type -> lnrpc.DeleteMacaroonIDResponse - 178, // 267: lnrpc.Lightning.ListPermissions:output_type -> lnrpc.ListPermissionsResponse - 209, // [209:268] is the sub-list for method output_type - 150, // [150:209] is the sub-list for method input_type - 150, // [150:150] is the sub-list for extension type_name - 150, // [150:150] is the sub-list for extension extendee - 0, // [0:150] is the sub-list for field type_name + 1, // 38: lnrpc.OpenChannelRequest.commitment_type:type_name -> lnrpc.CommitmentType + 74, // 39: lnrpc.OpenStatusUpdate.chan_pending:type_name -> lnrpc.PendingUpdate + 70, // 40: lnrpc.OpenStatusUpdate.chan_open:type_name -> lnrpc.ChannelOpenUpdate + 75, // 41: lnrpc.OpenStatusUpdate.psbt_fund:type_name -> lnrpc.ReadyForPsbtFunding + 78, // 42: lnrpc.KeyDescriptor.key_loc:type_name -> lnrpc.KeyLocator + 28, // 43: lnrpc.ChanPointShim.chan_point:type_name -> lnrpc.ChannelPoint + 79, // 44: lnrpc.ChanPointShim.local_key:type_name -> lnrpc.KeyDescriptor + 80, // 45: lnrpc.FundingShim.chan_point_shim:type_name -> lnrpc.ChanPointShim + 81, // 46: lnrpc.FundingShim.psbt_shim:type_name -> lnrpc.PsbtShim + 82, // 47: lnrpc.FundingTransitionMsg.shim_register:type_name -> lnrpc.FundingShim + 83, // 48: lnrpc.FundingTransitionMsg.shim_cancel:type_name -> lnrpc.FundingShimCancel + 84, // 49: lnrpc.FundingTransitionMsg.psbt_verify:type_name -> lnrpc.FundingPsbtVerify + 85, // 50: lnrpc.FundingTransitionMsg.psbt_finalize:type_name -> lnrpc.FundingPsbtFinalize + 189, // 51: lnrpc.PendingChannelsResponse.pending_open_channels:type_name -> lnrpc.PendingChannelsResponse.PendingOpenChannel + 192, // 52: lnrpc.PendingChannelsResponse.pending_closing_channels:type_name -> lnrpc.PendingChannelsResponse.ClosedChannel + 193, // 53: lnrpc.PendingChannelsResponse.pending_force_closing_channels:type_name -> lnrpc.PendingChannelsResponse.ForceClosedChannel + 190, // 54: lnrpc.PendingChannelsResponse.waiting_close_channels:type_name -> lnrpc.PendingChannelsResponse.WaitingCloseChannel + 51, // 55: lnrpc.ChannelEventUpdate.open_channel:type_name -> lnrpc.Channel + 54, // 56: lnrpc.ChannelEventUpdate.closed_channel:type_name -> lnrpc.ChannelCloseSummary + 28, // 57: lnrpc.ChannelEventUpdate.active_channel:type_name -> lnrpc.ChannelPoint + 28, // 58: lnrpc.ChannelEventUpdate.inactive_channel:type_name -> lnrpc.ChannelPoint + 74, // 59: lnrpc.ChannelEventUpdate.pending_open_channel:type_name -> lnrpc.PendingUpdate + 28, // 60: lnrpc.ChannelEventUpdate.fully_resolved_channel:type_name -> lnrpc.ChannelPoint + 13, // 61: lnrpc.ChannelEventUpdate.type:type_name -> lnrpc.ChannelEventUpdate.UpdateType + 194, // 62: lnrpc.WalletBalanceResponse.account_balance:type_name -> lnrpc.WalletBalanceResponse.AccountBalanceEntry + 96, // 63: lnrpc.ChannelBalanceResponse.local_balance:type_name -> lnrpc.Amount + 96, // 64: lnrpc.ChannelBalanceResponse.remote_balance:type_name -> lnrpc.Amount + 96, // 65: lnrpc.ChannelBalanceResponse.unsettled_local_balance:type_name -> lnrpc.Amount + 96, // 66: lnrpc.ChannelBalanceResponse.unsettled_remote_balance:type_name -> lnrpc.Amount + 96, // 67: lnrpc.ChannelBalanceResponse.pending_open_local_balance:type_name -> lnrpc.Amount + 96, // 68: lnrpc.ChannelBalanceResponse.pending_open_remote_balance:type_name -> lnrpc.Amount + 22, // 69: lnrpc.QueryRoutesRequest.fee_limit:type_name -> lnrpc.FeeLimit + 101, // 70: lnrpc.QueryRoutesRequest.ignored_edges:type_name -> lnrpc.EdgeLocator + 100, // 71: lnrpc.QueryRoutesRequest.ignored_pairs:type_name -> lnrpc.NodePair + 195, // 72: lnrpc.QueryRoutesRequest.dest_custom_records:type_name -> lnrpc.QueryRoutesRequest.DestCustomRecordsEntry + 129, // 73: lnrpc.QueryRoutesRequest.route_hints:type_name -> lnrpc.RouteHint + 8, // 74: lnrpc.QueryRoutesRequest.dest_features:type_name -> lnrpc.FeatureBit + 106, // 75: lnrpc.QueryRoutesResponse.routes:type_name -> lnrpc.Route + 104, // 76: lnrpc.Hop.mpp_record:type_name -> lnrpc.MPPRecord + 105, // 77: lnrpc.Hop.amp_record:type_name -> lnrpc.AMPRecord + 196, // 78: lnrpc.Hop.custom_records:type_name -> lnrpc.Hop.CustomRecordsEntry + 103, // 79: lnrpc.Route.hops:type_name -> lnrpc.Hop + 109, // 80: lnrpc.NodeInfo.node:type_name -> lnrpc.LightningNode + 112, // 81: lnrpc.NodeInfo.channels:type_name -> lnrpc.ChannelEdge + 110, // 82: lnrpc.LightningNode.addresses:type_name -> lnrpc.NodeAddress + 197, // 83: lnrpc.LightningNode.features:type_name -> lnrpc.LightningNode.FeaturesEntry + 111, // 84: lnrpc.ChannelEdge.node1_policy:type_name -> lnrpc.RoutingPolicy + 111, // 85: lnrpc.ChannelEdge.node2_policy:type_name -> lnrpc.RoutingPolicy + 109, // 86: lnrpc.ChannelGraph.nodes:type_name -> lnrpc.LightningNode + 112, // 87: lnrpc.ChannelGraph.edges:type_name -> lnrpc.ChannelEdge + 5, // 88: lnrpc.NodeMetricsRequest.types:type_name -> lnrpc.NodeMetricType + 198, // 89: lnrpc.NodeMetricsResponse.betweenness_centrality:type_name -> lnrpc.NodeMetricsResponse.BetweennessCentralityEntry + 125, // 90: lnrpc.GraphTopologyUpdate.node_updates:type_name -> lnrpc.NodeUpdate + 126, // 91: lnrpc.GraphTopologyUpdate.channel_updates:type_name -> lnrpc.ChannelEdgeUpdate + 127, // 92: lnrpc.GraphTopologyUpdate.closed_chans:type_name -> lnrpc.ClosedChannelUpdate + 110, // 93: lnrpc.NodeUpdate.node_addresses:type_name -> lnrpc.NodeAddress + 199, // 94: lnrpc.NodeUpdate.features:type_name -> lnrpc.NodeUpdate.FeaturesEntry + 28, // 95: lnrpc.ChannelEdgeUpdate.chan_point:type_name -> lnrpc.ChannelPoint + 111, // 96: lnrpc.ChannelEdgeUpdate.routing_policy:type_name -> lnrpc.RoutingPolicy + 28, // 97: lnrpc.ClosedChannelUpdate.chan_point:type_name -> lnrpc.ChannelPoint + 128, // 98: lnrpc.RouteHint.hop_hints:type_name -> lnrpc.HopHint + 129, // 99: lnrpc.Invoice.route_hints:type_name -> lnrpc.RouteHint + 14, // 100: lnrpc.Invoice.state:type_name -> lnrpc.Invoice.InvoiceState + 131, // 101: lnrpc.Invoice.htlcs:type_name -> lnrpc.InvoiceHTLC + 200, // 102: lnrpc.Invoice.features:type_name -> lnrpc.Invoice.FeaturesEntry + 6, // 103: lnrpc.InvoiceHTLC.state:type_name -> lnrpc.InvoiceHTLCState + 201, // 104: lnrpc.InvoiceHTLC.custom_records:type_name -> lnrpc.InvoiceHTLC.CustomRecordsEntry + 132, // 105: lnrpc.InvoiceHTLC.amp:type_name -> lnrpc.AMP + 130, // 106: lnrpc.ListInvoiceResponse.invoices:type_name -> lnrpc.Invoice + 15, // 107: lnrpc.Payment.status:type_name -> lnrpc.Payment.PaymentStatus + 139, // 108: lnrpc.Payment.htlcs:type_name -> lnrpc.HTLCAttempt + 7, // 109: lnrpc.Payment.failure_reason:type_name -> lnrpc.PaymentFailureReason + 16, // 110: lnrpc.HTLCAttempt.status:type_name -> lnrpc.HTLCAttempt.HTLCStatus + 106, // 111: lnrpc.HTLCAttempt.route:type_name -> lnrpc.Route + 179, // 112: lnrpc.HTLCAttempt.failure:type_name -> lnrpc.Failure + 138, // 113: lnrpc.ListPaymentsResponse.payments:type_name -> lnrpc.Payment + 28, // 114: lnrpc.AbandonChannelRequest.channel_point:type_name -> lnrpc.ChannelPoint + 129, // 115: lnrpc.PayReq.route_hints:type_name -> lnrpc.RouteHint + 202, // 116: lnrpc.PayReq.features:type_name -> lnrpc.PayReq.FeaturesEntry + 152, // 117: lnrpc.FeeReportResponse.channel_fees:type_name -> lnrpc.ChannelFeeReport + 28, // 118: lnrpc.PolicyUpdateRequest.chan_point:type_name -> lnrpc.ChannelPoint + 157, // 119: lnrpc.ForwardingHistoryResponse.forwarding_events:type_name -> lnrpc.ForwardingEvent + 28, // 120: lnrpc.ExportChannelBackupRequest.chan_point:type_name -> lnrpc.ChannelPoint + 28, // 121: lnrpc.ChannelBackup.chan_point:type_name -> lnrpc.ChannelPoint + 28, // 122: lnrpc.MultiChanBackup.chan_points:type_name -> lnrpc.ChannelPoint + 164, // 123: lnrpc.ChanBackupSnapshot.single_chan_backups:type_name -> lnrpc.ChannelBackups + 161, // 124: lnrpc.ChanBackupSnapshot.multi_chan_backup:type_name -> lnrpc.MultiChanBackup + 160, // 125: lnrpc.ChannelBackups.chan_backups:type_name -> lnrpc.ChannelBackup + 164, // 126: lnrpc.RestoreChanBackupRequest.chan_backups:type_name -> lnrpc.ChannelBackups + 169, // 127: lnrpc.BakeMacaroonRequest.permissions:type_name -> lnrpc.MacaroonPermission + 169, // 128: lnrpc.MacaroonPermissionList.permissions:type_name -> lnrpc.MacaroonPermission + 203, // 129: lnrpc.ListPermissionsResponse.method_permissions:type_name -> lnrpc.ListPermissionsResponse.MethodPermissionsEntry + 17, // 130: lnrpc.Failure.code:type_name -> lnrpc.Failure.FailureCode + 180, // 131: lnrpc.Failure.channel_update:type_name -> lnrpc.ChannelUpdate + 182, // 132: lnrpc.MacaroonId.ops:type_name -> lnrpc.Op + 150, // 133: lnrpc.Peer.FeaturesEntry.value:type_name -> lnrpc.Feature + 150, // 134: lnrpc.GetInfoResponse.FeaturesEntry.value:type_name -> lnrpc.Feature + 2, // 135: lnrpc.PendingChannelsResponse.PendingChannel.initiator:type_name -> lnrpc.Initiator + 1, // 136: lnrpc.PendingChannelsResponse.PendingChannel.commitment_type:type_name -> lnrpc.CommitmentType + 188, // 137: lnrpc.PendingChannelsResponse.PendingOpenChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel + 188, // 138: lnrpc.PendingChannelsResponse.WaitingCloseChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel + 191, // 139: lnrpc.PendingChannelsResponse.WaitingCloseChannel.commitments:type_name -> lnrpc.PendingChannelsResponse.Commitments + 188, // 140: lnrpc.PendingChannelsResponse.ClosedChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel + 188, // 141: lnrpc.PendingChannelsResponse.ForceClosedChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel + 88, // 142: lnrpc.PendingChannelsResponse.ForceClosedChannel.pending_htlcs:type_name -> lnrpc.PendingHTLC + 12, // 143: lnrpc.PendingChannelsResponse.ForceClosedChannel.anchor:type_name -> lnrpc.PendingChannelsResponse.ForceClosedChannel.AnchorState + 93, // 144: lnrpc.WalletBalanceResponse.AccountBalanceEntry.value:type_name -> lnrpc.WalletAccountBalance + 150, // 145: lnrpc.LightningNode.FeaturesEntry.value:type_name -> lnrpc.Feature + 117, // 146: lnrpc.NodeMetricsResponse.BetweennessCentralityEntry.value:type_name -> lnrpc.FloatMetric + 150, // 147: lnrpc.NodeUpdate.FeaturesEntry.value:type_name -> lnrpc.Feature + 150, // 148: lnrpc.Invoice.FeaturesEntry.value:type_name -> lnrpc.Feature + 150, // 149: lnrpc.PayReq.FeaturesEntry.value:type_name -> lnrpc.Feature + 176, // 150: lnrpc.ListPermissionsResponse.MethodPermissionsEntry.value:type_name -> lnrpc.MacaroonPermissionList + 94, // 151: lnrpc.Lightning.WalletBalance:input_type -> lnrpc.WalletBalanceRequest + 97, // 152: lnrpc.Lightning.ChannelBalance:input_type -> lnrpc.ChannelBalanceRequest + 20, // 153: lnrpc.Lightning.GetTransactions:input_type -> lnrpc.GetTransactionsRequest + 31, // 154: lnrpc.Lightning.EstimateFee:input_type -> lnrpc.EstimateFeeRequest + 35, // 155: lnrpc.Lightning.SendCoins:input_type -> lnrpc.SendCoinsRequest + 37, // 156: lnrpc.Lightning.ListUnspent:input_type -> lnrpc.ListUnspentRequest + 20, // 157: lnrpc.Lightning.SubscribeTransactions:input_type -> lnrpc.GetTransactionsRequest + 33, // 158: lnrpc.Lightning.SendMany:input_type -> lnrpc.SendManyRequest + 39, // 159: lnrpc.Lightning.NewAddress:input_type -> lnrpc.NewAddressRequest + 41, // 160: lnrpc.Lightning.SignMessage:input_type -> lnrpc.SignMessageRequest + 43, // 161: lnrpc.Lightning.VerifyMessage:input_type -> lnrpc.VerifyMessageRequest + 45, // 162: lnrpc.Lightning.ConnectPeer:input_type -> lnrpc.ConnectPeerRequest + 47, // 163: lnrpc.Lightning.DisconnectPeer:input_type -> lnrpc.DisconnectPeerRequest + 60, // 164: lnrpc.Lightning.ListPeers:input_type -> lnrpc.ListPeersRequest + 62, // 165: lnrpc.Lightning.SubscribePeerEvents:input_type -> lnrpc.PeerEventSubscription + 64, // 166: lnrpc.Lightning.GetInfo:input_type -> lnrpc.GetInfoRequest + 66, // 167: lnrpc.Lightning.GetRecoveryInfo:input_type -> lnrpc.GetRecoveryInfoRequest + 89, // 168: lnrpc.Lightning.PendingChannels:input_type -> lnrpc.PendingChannelsRequest + 52, // 169: lnrpc.Lightning.ListChannels:input_type -> lnrpc.ListChannelsRequest + 91, // 170: lnrpc.Lightning.SubscribeChannelEvents:input_type -> lnrpc.ChannelEventSubscription + 56, // 171: lnrpc.Lightning.ClosedChannels:input_type -> lnrpc.ClosedChannelsRequest + 76, // 172: lnrpc.Lightning.OpenChannelSync:input_type -> lnrpc.OpenChannelRequest + 76, // 173: lnrpc.Lightning.OpenChannel:input_type -> lnrpc.OpenChannelRequest + 86, // 174: lnrpc.Lightning.FundingStateStep:input_type -> lnrpc.FundingTransitionMsg + 27, // 175: lnrpc.Lightning.ChannelAcceptor:input_type -> lnrpc.ChannelAcceptResponse + 72, // 176: lnrpc.Lightning.CloseChannel:input_type -> lnrpc.CloseChannelRequest + 144, // 177: lnrpc.Lightning.AbandonChannel:input_type -> lnrpc.AbandonChannelRequest + 23, // 178: lnrpc.Lightning.SendPayment:input_type -> lnrpc.SendRequest + 23, // 179: lnrpc.Lightning.SendPaymentSync:input_type -> lnrpc.SendRequest + 25, // 180: lnrpc.Lightning.SendToRoute:input_type -> lnrpc.SendToRouteRequest + 25, // 181: lnrpc.Lightning.SendToRouteSync:input_type -> lnrpc.SendToRouteRequest + 130, // 182: lnrpc.Lightning.AddInvoice:input_type -> lnrpc.Invoice + 135, // 183: lnrpc.Lightning.ListInvoices:input_type -> lnrpc.ListInvoiceRequest + 134, // 184: lnrpc.Lightning.LookupInvoice:input_type -> lnrpc.PaymentHash + 137, // 185: lnrpc.Lightning.SubscribeInvoices:input_type -> lnrpc.InvoiceSubscription + 148, // 186: lnrpc.Lightning.DecodePayReq:input_type -> lnrpc.PayReqString + 140, // 187: lnrpc.Lightning.ListPayments:input_type -> lnrpc.ListPaymentsRequest + 142, // 188: lnrpc.Lightning.DeleteAllPayments:input_type -> lnrpc.DeleteAllPaymentsRequest + 113, // 189: lnrpc.Lightning.DescribeGraph:input_type -> lnrpc.ChannelGraphRequest + 115, // 190: lnrpc.Lightning.GetNodeMetrics:input_type -> lnrpc.NodeMetricsRequest + 118, // 191: lnrpc.Lightning.GetChanInfo:input_type -> lnrpc.ChanInfoRequest + 107, // 192: lnrpc.Lightning.GetNodeInfo:input_type -> lnrpc.NodeInfoRequest + 99, // 193: lnrpc.Lightning.QueryRoutes:input_type -> lnrpc.QueryRoutesRequest + 119, // 194: lnrpc.Lightning.GetNetworkInfo:input_type -> lnrpc.NetworkInfoRequest + 121, // 195: lnrpc.Lightning.StopDaemon:input_type -> lnrpc.StopRequest + 123, // 196: lnrpc.Lightning.SubscribeChannelGraph:input_type -> lnrpc.GraphTopologySubscription + 146, // 197: lnrpc.Lightning.DebugLevel:input_type -> lnrpc.DebugLevelRequest + 151, // 198: lnrpc.Lightning.FeeReport:input_type -> lnrpc.FeeReportRequest + 154, // 199: lnrpc.Lightning.UpdateChannelPolicy:input_type -> lnrpc.PolicyUpdateRequest + 156, // 200: lnrpc.Lightning.ForwardingHistory:input_type -> lnrpc.ForwardingHistoryRequest + 159, // 201: lnrpc.Lightning.ExportChannelBackup:input_type -> lnrpc.ExportChannelBackupRequest + 162, // 202: lnrpc.Lightning.ExportAllChannelBackups:input_type -> lnrpc.ChanBackupExportRequest + 163, // 203: lnrpc.Lightning.VerifyChanBackup:input_type -> lnrpc.ChanBackupSnapshot + 165, // 204: lnrpc.Lightning.RestoreChannelBackups:input_type -> lnrpc.RestoreChanBackupRequest + 167, // 205: lnrpc.Lightning.SubscribeChannelBackups:input_type -> lnrpc.ChannelBackupSubscription + 170, // 206: lnrpc.Lightning.BakeMacaroon:input_type -> lnrpc.BakeMacaroonRequest + 172, // 207: lnrpc.Lightning.ListMacaroonIDs:input_type -> lnrpc.ListMacaroonIDsRequest + 174, // 208: lnrpc.Lightning.DeleteMacaroonID:input_type -> lnrpc.DeleteMacaroonIDRequest + 177, // 209: lnrpc.Lightning.ListPermissions:input_type -> lnrpc.ListPermissionsRequest + 95, // 210: lnrpc.Lightning.WalletBalance:output_type -> lnrpc.WalletBalanceResponse + 98, // 211: lnrpc.Lightning.ChannelBalance:output_type -> lnrpc.ChannelBalanceResponse + 21, // 212: lnrpc.Lightning.GetTransactions:output_type -> lnrpc.TransactionDetails + 32, // 213: lnrpc.Lightning.EstimateFee:output_type -> lnrpc.EstimateFeeResponse + 36, // 214: lnrpc.Lightning.SendCoins:output_type -> lnrpc.SendCoinsResponse + 38, // 215: lnrpc.Lightning.ListUnspent:output_type -> lnrpc.ListUnspentResponse + 19, // 216: lnrpc.Lightning.SubscribeTransactions:output_type -> lnrpc.Transaction + 34, // 217: lnrpc.Lightning.SendMany:output_type -> lnrpc.SendManyResponse + 40, // 218: lnrpc.Lightning.NewAddress:output_type -> lnrpc.NewAddressResponse + 42, // 219: lnrpc.Lightning.SignMessage:output_type -> lnrpc.SignMessageResponse + 44, // 220: lnrpc.Lightning.VerifyMessage:output_type -> lnrpc.VerifyMessageResponse + 46, // 221: lnrpc.Lightning.ConnectPeer:output_type -> lnrpc.ConnectPeerResponse + 48, // 222: lnrpc.Lightning.DisconnectPeer:output_type -> lnrpc.DisconnectPeerResponse + 61, // 223: lnrpc.Lightning.ListPeers:output_type -> lnrpc.ListPeersResponse + 63, // 224: lnrpc.Lightning.SubscribePeerEvents:output_type -> lnrpc.PeerEvent + 65, // 225: lnrpc.Lightning.GetInfo:output_type -> lnrpc.GetInfoResponse + 67, // 226: lnrpc.Lightning.GetRecoveryInfo:output_type -> lnrpc.GetRecoveryInfoResponse + 90, // 227: lnrpc.Lightning.PendingChannels:output_type -> lnrpc.PendingChannelsResponse + 53, // 228: lnrpc.Lightning.ListChannels:output_type -> lnrpc.ListChannelsResponse + 92, // 229: lnrpc.Lightning.SubscribeChannelEvents:output_type -> lnrpc.ChannelEventUpdate + 57, // 230: lnrpc.Lightning.ClosedChannels:output_type -> lnrpc.ClosedChannelsResponse + 28, // 231: lnrpc.Lightning.OpenChannelSync:output_type -> lnrpc.ChannelPoint + 77, // 232: lnrpc.Lightning.OpenChannel:output_type -> lnrpc.OpenStatusUpdate + 87, // 233: lnrpc.Lightning.FundingStateStep:output_type -> lnrpc.FundingStateStepResp + 26, // 234: lnrpc.Lightning.ChannelAcceptor:output_type -> lnrpc.ChannelAcceptRequest + 73, // 235: lnrpc.Lightning.CloseChannel:output_type -> lnrpc.CloseStatusUpdate + 145, // 236: lnrpc.Lightning.AbandonChannel:output_type -> lnrpc.AbandonChannelResponse + 24, // 237: lnrpc.Lightning.SendPayment:output_type -> lnrpc.SendResponse + 24, // 238: lnrpc.Lightning.SendPaymentSync:output_type -> lnrpc.SendResponse + 24, // 239: lnrpc.Lightning.SendToRoute:output_type -> lnrpc.SendResponse + 24, // 240: lnrpc.Lightning.SendToRouteSync:output_type -> lnrpc.SendResponse + 133, // 241: lnrpc.Lightning.AddInvoice:output_type -> lnrpc.AddInvoiceResponse + 136, // 242: lnrpc.Lightning.ListInvoices:output_type -> lnrpc.ListInvoiceResponse + 130, // 243: lnrpc.Lightning.LookupInvoice:output_type -> lnrpc.Invoice + 130, // 244: lnrpc.Lightning.SubscribeInvoices:output_type -> lnrpc.Invoice + 149, // 245: lnrpc.Lightning.DecodePayReq:output_type -> lnrpc.PayReq + 141, // 246: lnrpc.Lightning.ListPayments:output_type -> lnrpc.ListPaymentsResponse + 143, // 247: lnrpc.Lightning.DeleteAllPayments:output_type -> lnrpc.DeleteAllPaymentsResponse + 114, // 248: lnrpc.Lightning.DescribeGraph:output_type -> lnrpc.ChannelGraph + 116, // 249: lnrpc.Lightning.GetNodeMetrics:output_type -> lnrpc.NodeMetricsResponse + 112, // 250: lnrpc.Lightning.GetChanInfo:output_type -> lnrpc.ChannelEdge + 108, // 251: lnrpc.Lightning.GetNodeInfo:output_type -> lnrpc.NodeInfo + 102, // 252: lnrpc.Lightning.QueryRoutes:output_type -> lnrpc.QueryRoutesResponse + 120, // 253: lnrpc.Lightning.GetNetworkInfo:output_type -> lnrpc.NetworkInfo + 122, // 254: lnrpc.Lightning.StopDaemon:output_type -> lnrpc.StopResponse + 124, // 255: lnrpc.Lightning.SubscribeChannelGraph:output_type -> lnrpc.GraphTopologyUpdate + 147, // 256: lnrpc.Lightning.DebugLevel:output_type -> lnrpc.DebugLevelResponse + 153, // 257: lnrpc.Lightning.FeeReport:output_type -> lnrpc.FeeReportResponse + 155, // 258: lnrpc.Lightning.UpdateChannelPolicy:output_type -> lnrpc.PolicyUpdateResponse + 158, // 259: lnrpc.Lightning.ForwardingHistory:output_type -> lnrpc.ForwardingHistoryResponse + 160, // 260: lnrpc.Lightning.ExportChannelBackup:output_type -> lnrpc.ChannelBackup + 163, // 261: lnrpc.Lightning.ExportAllChannelBackups:output_type -> lnrpc.ChanBackupSnapshot + 168, // 262: lnrpc.Lightning.VerifyChanBackup:output_type -> lnrpc.VerifyChanBackupResponse + 166, // 263: lnrpc.Lightning.RestoreChannelBackups:output_type -> lnrpc.RestoreBackupResponse + 163, // 264: lnrpc.Lightning.SubscribeChannelBackups:output_type -> lnrpc.ChanBackupSnapshot + 171, // 265: lnrpc.Lightning.BakeMacaroon:output_type -> lnrpc.BakeMacaroonResponse + 173, // 266: lnrpc.Lightning.ListMacaroonIDs:output_type -> lnrpc.ListMacaroonIDsResponse + 175, // 267: lnrpc.Lightning.DeleteMacaroonID:output_type -> lnrpc.DeleteMacaroonIDResponse + 178, // 268: lnrpc.Lightning.ListPermissions:output_type -> lnrpc.ListPermissionsResponse + 210, // [210:269] is the sub-list for method output_type + 151, // [151:210] is the sub-list for method input_type + 151, // [151:151] is the sub-list for extension type_name + 151, // [151:151] is the sub-list for extension extendee + 0, // [0:151] is the sub-list for field type_name } func init() { file_lightning_proto_init() } diff --git a/lnrpc/lightning.proto b/lnrpc/lightning.proto index d25daaa5c..ed6d57e7c 100644 --- a/lnrpc/lightning.proto +++ b/lnrpc/lightning.proto @@ -1115,11 +1115,16 @@ message HTLC { } enum CommitmentType { + /* + Returned when the commitment type isn't known or unavailable. + */ + UNKNOWN_COMMITMENT_TYPE = 0; + /* A channel using the legacy commitment format having tweaked to_remote keys. */ - LEGACY = 0; + LEGACY = 1; /* A channel that uses the modern commitment format where the key in the @@ -1127,19 +1132,14 @@ enum CommitmentType { up and recovery easier as when the channel is closed, the funds go directly to that key. */ - STATIC_REMOTE_KEY = 1; + STATIC_REMOTE_KEY = 2; /* A channel that uses a commitment format that has anchor outputs on the commitments, allowing fee bumping after a force close transaction has been broadcast. */ - ANCHORS = 2; - - /* - Returned when the commitment type isn't known or unavailable. - */ - UNKNOWN_COMMITMENT_TYPE = 999; + ANCHORS = 3; } message ChannelConstraints { @@ -1867,6 +1867,12 @@ message OpenChannelRequest { transaction. */ uint32 max_local_csv = 17; + + /* + The explicit commitment type to use. Note this field will only be used if + the remote peer supports explicit channel negotiation. + */ + CommitmentType commitment_type = 18; } message OpenStatusUpdate { oneof update { diff --git a/lnrpc/lightning.swagger.json b/lnrpc/lightning.swagger.json index 8ffa07c97..42e4f1e6d 100644 --- a/lnrpc/lightning.swagger.json +++ b/lnrpc/lightning.swagger.json @@ -3502,13 +3502,13 @@ "lnrpcCommitmentType": { "type": "string", "enum": [ + "UNKNOWN_COMMITMENT_TYPE", "LEGACY", "STATIC_REMOTE_KEY", - "ANCHORS", - "UNKNOWN_COMMITMENT_TYPE" + "ANCHORS" ], - "default": "LEGACY", - "description": " - LEGACY: A channel using the legacy commitment format having tweaked to_remote\nkeys.\n - STATIC_REMOTE_KEY: A channel that uses the modern commitment format where the key in the\noutput of the remote party does not change each state. This makes back\nup and recovery easier as when the channel is closed, the funds go\ndirectly to that key.\n - ANCHORS: A channel that uses a commitment format that has anchor outputs on the\ncommitments, allowing fee bumping after a force close transaction has\nbeen broadcast.\n - UNKNOWN_COMMITMENT_TYPE: Returned when the commitment type isn't known or unavailable." + "default": "UNKNOWN_COMMITMENT_TYPE", + "description": " - UNKNOWN_COMMITMENT_TYPE: Returned when the commitment type isn't known or unavailable.\n - LEGACY: A channel using the legacy commitment format having tweaked to_remote\nkeys.\n - STATIC_REMOTE_KEY: A channel that uses the modern commitment format where the key in the\noutput of the remote party does not change each state. This makes back\nup and recovery easier as when the channel is closed, the funds go\ndirectly to that key.\n - ANCHORS: A channel that uses a commitment format that has anchor outputs on the\ncommitments, allowing fee bumping after a force close transaction has\nbeen broadcast." }, "lnrpcConnectPeerRequest": { "type": "object", @@ -4923,6 +4923,10 @@ "type": "integer", "format": "int64", "description": "Max local csv is the maximum csv delay we will allow for our own commitment\ntransaction." + }, + "commitment_type": { + "$ref": "#/definitions/lnrpcCommitmentType", + "description": "The explicit commitment type to use. Note this field will only be used if\nthe remote peer supports explicit channel negotiation." } } }, diff --git a/rpcserver.go b/rpcserver.go index e7fa22ac3..c04aa4116 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1912,6 +1912,33 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest, err) } + var channelType *lnwire.ChannelType + switch in.CommitmentType { + case lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE: + break + + case lnrpc.CommitmentType_LEGACY: + channelType = new(lnwire.ChannelType) + *channelType = lnwire.ChannelType(*lnwire.NewRawFeatureVector()) + + case lnrpc.CommitmentType_STATIC_REMOTE_KEY: + channelType = new(lnwire.ChannelType) + *channelType = lnwire.ChannelType(*lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyRequired, + )) + + case lnrpc.CommitmentType_ANCHORS: + channelType = new(lnwire.ChannelType) + *channelType = lnwire.ChannelType(*lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyRequired, + lnwire.AnchorsZeroFeeHtlcTxRequired, + )) + + default: + return nil, fmt.Errorf("unhandled request channel type %v", + in.CommitmentType) + } + // Instruct the server to trigger the necessary events to attempt to // open a new channel. A stream is returned in place, this stream will // be used to consume updates of the state of the pending channel. @@ -1929,6 +1956,7 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest, MaxValueInFlight: maxValue, MaxHtlcs: maxHtlcs, MaxLocalCsv: uint16(in.MaxLocalCsv), + ChannelType: channelType, }, nil } From 031d7b1d556a65d7efc993f194f624216d9f59b3 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Mon, 12 Jul 2021 17:41:50 -0700 Subject: [PATCH 05/11] lnwire: extend RawFeatureVector with helper methods --- lnwire/features.go | 41 ++++++++++++++++++++++++++++++++++---- lnwire/features_test.go | 44 +++++++++++++++++++++++++++++++++++++++++ lnwire/writer_test.go | 8 +++++--- 3 files changed, 86 insertions(+), 7 deletions(-) diff --git a/lnwire/features.go b/lnwire/features.go index 70aa23154..98202841f 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -214,19 +214,51 @@ var Features = map[FeatureBit]string{ // can be serialized and deserialized to/from a byte representation that is // transmitted in Lightning network messages. type RawFeatureVector struct { - features map[FeatureBit]bool + features map[FeatureBit]struct{} } // NewRawFeatureVector creates a feature vector with all of the feature bits // given as arguments enabled. func NewRawFeatureVector(bits ...FeatureBit) *RawFeatureVector { - fv := &RawFeatureVector{features: make(map[FeatureBit]bool)} + fv := &RawFeatureVector{features: make(map[FeatureBit]struct{})} for _, bit := range bits { fv.Set(bit) } return fv } +// IsEmpty returns whether the feature vector contains any feature bits. +func (fv RawFeatureVector) IsEmpty() bool { + return len(fv.features) == 0 +} + +// OnlyContains determines whether only the specified feature bits are found. +func (fv RawFeatureVector) OnlyContains(bits ...FeatureBit) bool { + if len(bits) != len(fv.features) { + return false + } + for _, bit := range bits { + if !fv.IsSet(bit) { + return false + } + } + return true +} + +// Equals determines whether two features vectors contain exactly the same +// features. +func (fv RawFeatureVector) Equals(other *RawFeatureVector) bool { + if len(fv.features) != len(other.features) { + return false + } + for bit := range fv.features { + if _, ok := other.features[bit]; !ok { + return false + } + } + return true +} + // Merges sets all feature bits in other on the receiver's feature vector. func (fv *RawFeatureVector) Merge(other *RawFeatureVector) error { for bit := range other.features { @@ -249,12 +281,13 @@ func (fv *RawFeatureVector) Clone() *RawFeatureVector { // IsSet returns whether a particular feature bit is enabled in the vector. func (fv *RawFeatureVector) IsSet(feature FeatureBit) bool { - return fv.features[feature] + _, ok := fv.features[feature] + return ok } // Set marks a feature as enabled in the vector. func (fv *RawFeatureVector) Set(feature FeatureBit) { - fv.features[feature] = true + fv.features[feature] = struct{}{} } // SafeSet sets the chosen feature bit in the feature vector, but returns an diff --git a/lnwire/features_test.go b/lnwire/features_test.go index 3eed2b1b4..d4be13d4c 100644 --- a/lnwire/features_test.go +++ b/lnwire/features_test.go @@ -353,3 +353,47 @@ func TestFeatures(t *testing.T) { }) } } + +func TestRawFeatureVectorOnlyContains(t *testing.T) { + t.Parallel() + + features := []FeatureBit{ + StaticRemoteKeyOptional, + AnchorsZeroFeeHtlcTxOptional, + ExplicitChannelTypeRequired, + } + fv := NewRawFeatureVector(features...) + require.True(t, fv.OnlyContains(features...)) + require.False(t, fv.OnlyContains(features[:1]...)) +} + +func TestEqualRawFeatureVectors(t *testing.T) { + t.Parallel() + + a := NewRawFeatureVector( + StaticRemoteKeyOptional, + AnchorsZeroFeeHtlcTxOptional, + ExplicitChannelTypeRequired, + ) + b := a.Clone() + require.True(t, a.Equals(b)) + + b.Unset(ExplicitChannelTypeRequired) + require.False(t, a.Equals(b)) + + b.Set(ExplicitChannelTypeOptional) + require.False(t, a.Equals(b)) +} + +func TestIsEmptyFeatureVector(t *testing.T) { + t.Parallel() + + fv := NewRawFeatureVector() + require.True(t, fv.IsEmpty()) + + fv.Set(StaticRemoteKeyOptional) + require.False(t, fv.IsEmpty()) + + fv.Unset(StaticRemoteKeyOptional) + require.True(t, fv.IsEmpty()) +} diff --git a/lnwire/writer_test.go b/lnwire/writer_test.go index 96ef66103..3d16b1336 100644 --- a/lnwire/writer_test.go +++ b/lnwire/writer_test.go @@ -193,9 +193,11 @@ func TestWriteRawFeatureVector(t *testing.T) { require.Equal(t, ErrNilFeatureVector, err) // Create a raw feature vector. - feature := &RawFeatureVector{features: map[FeatureBit]bool{ - InitialRoutingSync: true, // FeatureBit 3. - }} + feature := &RawFeatureVector{ + features: map[FeatureBit]struct{}{ + InitialRoutingSync: {}, // FeatureBit 3. + }, + } expectedBytes := []byte{ 0, 1, // First two bytes encode the length. 8, // Last byte encodes the feature bit (1 << 3). From e7885f2bde37e9d2ab8c496fc66b9e910e7e5d49 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Wed, 9 Jun 2021 12:43:39 -0700 Subject: [PATCH 06/11] funding: add explicit commitment type negotiation support This commit adds the ability for a channel initiator/responder to determine whether the channel to be opened can use a specific commitment type through explicit negotiation. It also includes the existing implicit negotiation logic to fall back on if explicit negotiation is not supported. --- funding/commitment_type_negotiation.go | 120 ++++++++++++ funding/commitment_type_negotiation_test.go | 191 ++++++++++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 funding/commitment_type_negotiation.go create mode 100644 funding/commitment_type_negotiation_test.go diff --git a/funding/commitment_type_negotiation.go b/funding/commitment_type_negotiation.go new file mode 100644 index 000000000..e66dc78b2 --- /dev/null +++ b/funding/commitment_type_negotiation.go @@ -0,0 +1,120 @@ +package funding + +import ( + "errors" + + "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/lnwire" +) + +var ( + // errUnsupportedExplicitNegotiation is an error returned when explicit + // channel commitment negotiation is attempted but either peer of the + // channel does not support it. + errUnsupportedExplicitNegotiation = errors.New("explicit channel " + + "type negotiation not supported") + + // errUnsupportedCommitmentType is an error returned when a specific + // channel commitment type is being explicitly negotiated but either + // peer of the channel does not support it. + errUnsupportedChannelType = errors.New("requested channel type " + + "not supported") +) + +// negotiateCommitmentType negotiates the commitment type of a newly opened +// channel. If a channelType is provided, explicit negotiation for said type +// will be attempted if the set of both local and remote features support it. +// Otherwise, implicit negotiation will be attempted. +func negotiateCommitmentType(channelType *lnwire.ChannelType, + local, remote *lnwire.FeatureVector) (lnwallet.CommitmentType, error) { + + if channelType != nil { + if !hasFeatures(local, remote, lnwire.ExplicitChannelTypeOptional) { + return 0, errUnsupportedExplicitNegotiation + } + return explicitNegotiateCommitmentType( + *channelType, local, remote, + ) + } + + return implicitNegotiateCommitmentType(local, remote), nil +} + +// explicitNegotiateCommitmentType attempts to explicitly negotiate for a +// specific channel type. Since the channel type is comprised of a set of even +// feature bits, we also make sure each feature is supported by both peers. An +// error is returned if either peer does not support said channel type. +func explicitNegotiateCommitmentType(channelType lnwire.ChannelType, + local, remote *lnwire.FeatureVector) (lnwallet.CommitmentType, error) { + + channelFeatures := lnwire.RawFeatureVector(channelType) + + switch { + // Anchors zero fee + static remote key features only. + case channelFeatures.OnlyContains( + lnwire.AnchorsZeroFeeHtlcTxRequired, + lnwire.StaticRemoteKeyRequired, + ): + if !hasFeatures( + local, remote, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.StaticRemoteKeyOptional, + ) { + return 0, errUnsupportedChannelType + } + return lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx, nil + + // Static remote key feature only. + case channelFeatures.OnlyContains(lnwire.StaticRemoteKeyRequired): + if !hasFeatures(local, remote, lnwire.StaticRemoteKeyOptional) { + return 0, errUnsupportedChannelType + } + return lnwallet.CommitmentTypeTweakless, nil + + // No features, use legacy commitment type. + case channelFeatures.IsEmpty(): + return lnwallet.CommitmentTypeLegacy, nil + + default: + return 0, errUnsupportedChannelType + } +} + +// implicitNegotiateCommitmentType negotiates the commitment type of a channel +// implicitly by choosing the latest type supported by the local and remote +// fetures. +func implicitNegotiateCommitmentType(local, + remote *lnwire.FeatureVector) lnwallet.CommitmentType { + + // If both peers are signalling support for anchor commitments with + // zero-fee HTLC transactions, we'll use this type. + if hasFeatures(local, remote, lnwire.AnchorsZeroFeeHtlcTxOptional) { + return lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx + } + + // Since we don't want to support the "legacy" anchor type, we will fall + // back to static remote key if the nodes don't support the zero fee + // HTLC tx anchor type. + // + // If both nodes are signaling the proper feature bit for tweakless + // commitments, we'll use that. + if hasFeatures(local, remote, lnwire.StaticRemoteKeyOptional) { + return lnwallet.CommitmentTypeTweakless + } + + // Otherwise we'll fall back to the legacy type. + return lnwallet.CommitmentTypeLegacy +} + +// hasFeatures determines whether a set of features is supported by both the set +// of local and remote features. +func hasFeatures(local, remote *lnwire.FeatureVector, + features ...lnwire.FeatureBit) bool { + + for _, feature := range features { + if !local.HasFeature(feature) || !remote.HasFeature(feature) { + return false + } + } + return true +} diff --git a/funding/commitment_type_negotiation_test.go b/funding/commitment_type_negotiation_test.go new file mode 100644 index 000000000..c9ac25a7a --- /dev/null +++ b/funding/commitment_type_negotiation_test.go @@ -0,0 +1,191 @@ +package funding + +import ( + "testing" + + "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/lnwire" + "github.com/stretchr/testify/require" +) + +// TestCommitmentTypeNegotiation tests all of the possible paths of a channel +// commitment type negotiation. +func TestCommitmentTypeNegotiation(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + channelFeatures *lnwire.RawFeatureVector + localFeatures *lnwire.RawFeatureVector + remoteFeatures *lnwire.RawFeatureVector + expectsRes lnwallet.CommitmentType + expectsErr error + }{ + { + name: "explicit missing remote negotiation feature", + channelFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyRequired, + lnwire.AnchorsZeroFeeHtlcTxRequired, + ), + localFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + remoteFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + ), + expectsErr: errUnsupportedExplicitNegotiation, + }, + { + name: "explicit missing remote commitment feature", + channelFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyRequired, + lnwire.AnchorsZeroFeeHtlcTxRequired, + ), + localFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + remoteFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.ExplicitChannelTypeOptional, + ), + expectsErr: errUnsupportedChannelType, + }, + { + name: "explicit anchors", + channelFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyRequired, + lnwire.AnchorsZeroFeeHtlcTxRequired, + ), + localFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + remoteFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + expectsRes: lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx, + expectsErr: nil, + }, + { + name: "explicit tweakless", + channelFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyRequired, + ), + localFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + remoteFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + expectsRes: lnwallet.CommitmentTypeTweakless, + expectsErr: nil, + }, + { + name: "explicit legacy", + channelFeatures: lnwire.NewRawFeatureVector(), + localFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + remoteFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + expectsRes: lnwallet.CommitmentTypeLegacy, + expectsErr: nil, + }, + { + name: "implicit anchors", + channelFeatures: nil, + localFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + remoteFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + lnwire.ExplicitChannelTypeOptional, + ), + expectsRes: lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx, + expectsErr: nil, + }, + { + name: "implicit tweakless", + channelFeatures: nil, + localFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + ), + remoteFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + ), + expectsRes: lnwallet.CommitmentTypeTweakless, + expectsErr: nil, + }, + { + name: "implicit legacy", + channelFeatures: nil, + localFeatures: lnwire.NewRawFeatureVector(), + remoteFeatures: lnwire.NewRawFeatureVector( + lnwire.StaticRemoteKeyOptional, + lnwire.AnchorsZeroFeeHtlcTxOptional, + ), + expectsRes: lnwallet.CommitmentTypeLegacy, + expectsErr: nil, + }, + } + + for _, testCase := range testCases { + testCase := testCase + ok := t.Run(testCase.name, func(t *testing.T) { + localFeatures := lnwire.NewFeatureVector( + testCase.localFeatures, lnwire.Features, + ) + remoteFeatures := lnwire.NewFeatureVector( + testCase.remoteFeatures, lnwire.Features, + ) + + var channelType *lnwire.ChannelType + if testCase.channelFeatures != nil { + channelType = new(lnwire.ChannelType) + *channelType = lnwire.ChannelType( + *testCase.channelFeatures, + ) + } + localType, err := negotiateCommitmentType( + channelType, localFeatures, remoteFeatures, + ) + require.Equal(t, testCase.expectsErr, err) + + remoteType, err := negotiateCommitmentType( + channelType, remoteFeatures, localFeatures, + ) + require.Equal(t, testCase.expectsErr, err) + + if testCase.expectsErr != nil { + return + } + + require.Equal(t, testCase.expectsRes, localType) + require.Equal(t, testCase.expectsRes, remoteType) + }) + if !ok { + return + } + } +} From ad758d8499e06d7d5189701527944965019110e4 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 3 Mar 2021 19:43:59 -0800 Subject: [PATCH 07/11] funding: use explicit commitment type negotiation when possible In this commit, we modify the existing logic that defaults to implicit commitment type negotiation to support explicit negotiation if the new feature bit is set. This change allows us to ditch the notion of a "default" commitment type, as we'll now use feature bits to signal our understanding of a commiment type, but allow peers to select which commitment type they actually wish to use. In addition, this explicit negotiation removes the need for using the required bit of any commitment types. Instead, if an implementation wishes to no longer support a commitment type, they should simply stop advertising the optional bit. --- funding/manager.go | 93 +++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 42 deletions(-) diff --git a/funding/manager.go b/funding/manager.go index 2a0473b33..f60039044 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -147,6 +147,10 @@ type reservationWithCtx struct { // maxLocalCsv is the maximum csv we will accept from the remote. maxLocalCsv uint16 + // channelType is the explicit channel type proposed by the initiator of + // the channel. + channelType *lnwire.ChannelType + updateMtx sync.RWMutex lastUpdated time.Time @@ -1137,43 +1141,6 @@ func (f *Manager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) { } } -// commitmentType returns the commitment type to use for the channel, based on -// the features the two peers have available. -func commitmentType(localFeatures, - remoteFeatures *lnwire.FeatureVector) lnwallet.CommitmentType { - - // If both peers are signalling support for anchor commitments with - // zero-fee HTLC transactions, we'll use this type. - localZeroFee := localFeatures.HasFeature( - lnwire.AnchorsZeroFeeHtlcTxOptional, - ) - remoteZeroFee := remoteFeatures.HasFeature( - lnwire.AnchorsZeroFeeHtlcTxOptional, - ) - if localZeroFee && remoteZeroFee { - return lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx - } - - // Since we don't want to support the "legacy" anchor type, we will - // fall back to static remote key if the nodes don't support the zero - // fee HTLC tx anchor type. - localTweakless := localFeatures.HasFeature( - lnwire.StaticRemoteKeyOptional, - ) - remoteTweakless := remoteFeatures.HasFeature( - lnwire.StaticRemoteKeyOptional, - ) - - // If both nodes are signaling the proper feature bit for tweakless - // copmmitments, we'll use that. - if localTweakless && remoteTweakless { - return lnwallet.CommitmentTypeTweakless - } - - // Otherwise we'll fall back to the legacy type. - return lnwallet.CommitmentTypeLegacy -} - // handleFundingOpen creates an initial 'ChannelReservation' within the wallet, // then responds to the source peer with an accept channel message progressing // the funding workflow. @@ -1314,10 +1281,19 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer, // // Before we init the channel, we'll also check to see what commitment // format we can use with this peer. This is dependent on *both* us and - // the remote peer are signaling the proper feature bit. - commitType := commitmentType( - peer.LocalFeatures(), peer.RemoteFeatures(), + // the remote peer are signaling the proper feature bit if we're using + // implicit negotiation, and simply the channel type sent over if we're + // using explicit negotiation. + commitType, err := negotiateCommitmentType( + msg.ChannelType, peer.LocalFeatures(), peer.RemoteFeatures(), ) + if err != nil { + // TODO(roasbeef): should be using soft errors + log.Errorf("channel type negotiation failed: %v", err) + f.failFundingFlow(peer, msg.PendingChannelID, err) + return + } + chainHash := chainhash.Hash(msg.ChainHash) req := &lnwallet.InitFundingReserveMsg{ ChainHash: &chainHash, @@ -1447,6 +1423,7 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer, remoteMaxValue: remoteMaxValue, remoteMaxHtlcs: maxHtlcs, maxLocalCsv: f.cfg.MaxLocalCSVDelay, + channelType: msg.ChannelType, err: make(chan error, 1), peer: peer, } @@ -1519,6 +1496,7 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer, HtlcPoint: ourContribution.HtlcBasePoint.PubKey, FirstCommitmentPoint: ourContribution.FirstCommitmentPoint, UpfrontShutdownScript: ourContribution.UpfrontShutdown, + ChannelType: msg.ChannelType, } if err := peer.SendMessage(true, &fundingAccept); err != nil { @@ -1550,6 +1528,29 @@ func (f *Manager) handleFundingAccept(peer lnpeer.Peer, log.Infof("Recv'd fundingResponse for pending_id(%x)", pendingChanID[:]) + // We'll want to quickly check that ChannelType echoed by the channel + // request recipient matches what we proposed. + // + // TODO: Return errors as funding.Error to give context to remote peer? + if resCtx.channelType != nil { + if msg.ChannelType == nil { + err := errors.New("explicit channel type not echoed back") + f.failFundingFlow(peer, msg.PendingChannelID, err) + return + } + proposedFeatures := lnwire.RawFeatureVector(*resCtx.channelType) + ackedFeatures := lnwire.RawFeatureVector(*msg.ChannelType) + if !proposedFeatures.Equals(&ackedFeatures) { + err := errors.New("channel type mismatch") + f.failFundingFlow(peer, msg.PendingChannelID, err) + return + } + } else if msg.ChannelType != nil { + err := errors.New("received unexpected channel type") + f.failFundingFlow(peer, msg.PendingChannelID, err) + return + } + // The required number of confirmations should not be greater than the // maximum number of confirmations required by the ChainNotifier to // properly dispatch confirmations. @@ -3183,9 +3184,15 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) { // Before we init the channel, we'll also check to see what commitment // format we can use with this peer. This is dependent on *both* us and // the remote peer are signaling the proper feature bit. - commitType := commitmentType( - msg.Peer.LocalFeatures(), msg.Peer.RemoteFeatures(), + commitType, err := negotiateCommitmentType( + msg.ChannelType, msg.Peer.LocalFeatures(), + msg.Peer.RemoteFeatures(), ) + if err != nil { + log.Errorf("channel type negotiation failed: %v", err) + msg.Err <- err + return + } // First, we'll query the fee estimator for a fee that should get the // commitment transaction confirmed by the next few blocks (conf target @@ -3277,6 +3284,7 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) { remoteMaxValue: maxValue, remoteMaxHtlcs: maxHtlcs, maxLocalCsv: maxCSV, + channelType: msg.ChannelType, reservation: reservation, peer: msg.Peer, updates: msg.Updates, @@ -3320,6 +3328,7 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) { FirstCommitmentPoint: ourContribution.FirstCommitmentPoint, ChannelFlags: channelFlags, UpfrontShutdownScript: shutdown, + ChannelType: msg.ChannelType, } if err := msg.Peer.SendMessage(true, &fundingOpen); err != nil { e := fmt.Errorf("unable to send funding request message: %v", From 449f207217bb9d04229c71be5ef7665549f96cd3 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Wed, 9 Jun 2021 12:49:01 -0700 Subject: [PATCH 08/11] lntest: replace `commitType` type with rpc alternative --- lntest/itest/lnd_channel_backup_test.go | 5 +- lntest/itest/lnd_channel_balance_test.go | 10 +-- lntest/itest/lnd_channel_force_close.go | 32 ++++----- lntest/itest/lnd_funding_test.go | 38 +++++------ .../lnd_multi-hop-error-propagation_test.go | 2 +- .../lnd_multi-hop_htlc_aggregation_test.go | 10 +-- ...d_multi-hop_htlc_local_chain_claim_test.go | 11 ++-- .../lnd_multi-hop_htlc_local_timeout_test.go | 4 +- ...ulti-hop_htlc_receiver_chain_claim_test.go | 6 +- ..._multi-hop_htlc_remote_chain_claim_test.go | 11 ++-- ..._force_close_on_chain_htlc_timeout_test.go | 8 ++- ..._force_close_on_chain_htlc_timeout_test.go | 7 +- lntest/itest/lnd_multi-hop_test.go | 16 ++--- lntest/itest/lnd_onchain_test.go | 2 +- lntest/itest/utils.go | 66 ++++--------------- 15 files changed, 96 insertions(+), 132 deletions(-) diff --git a/lntest/itest/lnd_channel_backup_test.go b/lntest/itest/lnd_channel_backup_test.go index d1d42c2e1..ec61dd38c 100644 --- a/lntest/itest/lnd_channel_backup_test.go +++ b/lntest/itest/lnd_channel_backup_test.go @@ -855,7 +855,10 @@ func testChanRestoreScenario(t *harnessTest, net *lntest.NetworkHarness, "--maxbackoff=1s", } if testCase.anchorCommit { - nodeArgs = append(nodeArgs, commitTypeAnchors.Args()...) + anchorNodeArgs := nodeArgsForCommitType( + lnrpc.CommitmentType_ANCHORS, + ) + nodeArgs = append(nodeArgs, anchorNodeArgs...) } // First, we'll create a brand new node we'll use within the test. If diff --git a/lntest/itest/lnd_channel_balance_test.go b/lntest/itest/lnd_channel_balance_test.go index 58beacaa9..d49a27609 100644 --- a/lntest/itest/lnd_channel_balance_test.go +++ b/lntest/itest/lnd_channel_balance_test.go @@ -81,10 +81,10 @@ func testChannelBalance(net *lntest.NetworkHarness, t *harnessTest) { // As this is a single funder channel, Alice's balance should be // exactly 0.5 BTC since now state transitions have taken place yet. - checkChannelBalance(net.Alice, amount-cType.calcStaticFee(0), 0) + checkChannelBalance(net.Alice, amount-calcStaticFee(cType, 0), 0) // Ensure Bob currently has no available balance within the channel. - checkChannelBalance(net.Bob, 0, amount-cType.calcStaticFee(0)) + checkChannelBalance(net.Bob, 0, amount-calcStaticFee(cType, 0)) // Finally close the channel between Alice and Bob, asserting that the // channel has been properly closed on-chain. @@ -174,11 +174,11 @@ func testChannelUnsettledBalance(net *lntest.NetworkHarness, t *harnessTest) { // Check alice's channel balance, which should have zero remote and zero // pending balance. - checkChannelBalance(net.Alice, chanAmt-cType.calcStaticFee(0), 0, 0, 0) + checkChannelBalance(net.Alice, chanAmt-calcStaticFee(cType, 0), 0, 0, 0) // Check carol's channel balance, which should have zero local and zero // pending balance. - checkChannelBalance(carol, 0, chanAmt-cType.calcStaticFee(0), 0, 0) + checkChannelBalance(carol, 0, chanAmt-calcStaticFee(cType, 0), 0, 0) // Channel should be ready for payments. const ( @@ -258,7 +258,7 @@ func testChannelUnsettledBalance(net *lntest.NetworkHarness, t *harnessTest) { // Check alice's channel balance, which should have a remote unsettled // balance that equals to the amount of invoices * payAmt. The remote // balance remains zero. - aliceLocal := chanAmt - cType.calcStaticFee(0) - numInvoices*payAmt + aliceLocal := chanAmt - calcStaticFee(cType, 0) - numInvoices*payAmt checkChannelBalance(net.Alice, aliceLocal, 0, 0, numInvoices*payAmt) // Check carol's channel balance, which should have a local unsettled diff --git a/lntest/itest/lnd_channel_force_close.go b/lntest/itest/lnd_channel_force_close.go index b20ce4453..908d4116e 100644 --- a/lntest/itest/lnd_channel_force_close.go +++ b/lntest/itest/lnd_channel_force_close.go @@ -76,7 +76,7 @@ func testCommitmentTransactionDeadline(net *lntest.NetworkHarness, setupNode := func(name string) *lntest.HarnessNode { // Create the node. args := []string{"--hodl.exit-settle"} - args = append(args, commitTypeAnchors.Args()...) + args = append(args, nodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS)...) node := net.NewNode(t.t, name, args) // Send some coins to the node. @@ -244,9 +244,9 @@ func calculateTxnsFeeRate(t *testing.T, func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { // We'll test the scenario for some of the commitment types, to ensure // outputs can be swept. - commitTypes := []commitType{ - commitTypeLegacy, - commitTypeAnchors, + commitTypes := []lnrpc.CommitmentType{ + lnrpc.CommitmentType_LEGACY, + lnrpc.CommitmentType_ANCHORS, } for _, channelType := range commitTypes { @@ -261,7 +261,7 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { success := t.t.Run(testName, func(t *testing.T) { ht := newHarnessTest(t, net) - args := channelType.Args() + args := nodeArgsForCommitType(channelType) alice := net.NewNode(ht.t, "Alice", args) defer shutdownAndAssert(net, ht, alice) @@ -292,7 +292,7 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { } func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, - alice, carol *lntest.HarnessNode, channelType commitType) { + alice, carol *lntest.HarnessNode, channelType lnrpc.CommitmentType) { ctxb := context.Background() @@ -407,7 +407,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, // sweep the HTLC second level output one block earlier (than the // nursery that waits an additional block, and handles non-anchor // channels). So we set a maturity height that is one less. - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { htlcCsvMaturityHeight = padCLTV( startHeight + defaultCLTV + defaultCSV, ) @@ -495,7 +495,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, // also expect the anchor sweep tx to be in the mempool. expectedTxes := 1 expectedFeeRate := commitFeeRate - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { expectedTxes = 2 expectedFeeRate = actualFeeRate } @@ -528,7 +528,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, // If we expect anchors, add alice's anchor to our expected set of // reports. - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { aliceReports[aliceAnchor.OutPoint.String()] = &lnrpc.Resolution{ ResolutionType: lnrpc.ResolutionType_ANCHOR, Outcome: lnrpc.ResolutionOutcome_CLAIMED, @@ -585,7 +585,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, "limbo") } expectedRecoveredBalance := int64(0) - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { expectedRecoveredBalance = anchorSize } if forceClose.RecoveredBalance != expectedRecoveredBalance { @@ -634,7 +634,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, ) // If we have anchors, add an anchor resolution for carol. - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { carolReports[carolAnchor.OutPoint.String()] = &lnrpc.Resolution{ ResolutionType: lnrpc.ResolutionType_ANCHOR, Outcome: lnrpc.ResolutionOutcome_CLAIMED, @@ -709,7 +709,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, "limbo") } expectedRecoveredBalance := int64(0) - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { expectedRecoveredBalance = anchorSize } if forceClose.RecoveredBalance != expectedRecoveredBalance { @@ -943,7 +943,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, expectedTxes = numInvoices // In case of anchors, the timeout txs will be aggregated into one. - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { expectedTxes = 1 } @@ -961,7 +961,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, // this is an anchor channel, the transactions are aggregated by the // sweeper into one. numInputs := 1 - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { numInputs = numInvoices + 1 } @@ -1089,7 +1089,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, // Advance the chain until just before the 2nd-layer CSV delays expire. // For anchor channels thhis is one block earlier. numBlocks := uint32(defaultCSV - 1) - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { numBlocks = defaultCSV - 2 } @@ -1320,7 +1320,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest, // In addition, if this is an anchor-enabled channel, further add the // anchor size. - if channelType == commitTypeAnchors { + if channelType == lnrpc.CommitmentType_ANCHORS { carolExpectedBalance += btcutil.Amount(anchorSize) } diff --git a/lntest/itest/lnd_funding_test.go b/lntest/itest/lnd_funding_test.go index 45420c0fd..98360405e 100644 --- a/lntest/itest/lnd_funding_test.go +++ b/lntest/itest/lnd_funding_test.go @@ -29,19 +29,19 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) { // Run through the test with combinations of all the different // commitment types. - allTypes := []commitType{ - commitTypeLegacy, - commitTypeTweakless, - commitTypeAnchors, + allTypes := []lnrpc.CommitmentType{ + lnrpc.CommitmentType_LEGACY, + lnrpc.CommitmentType_STATIC_REMOTE_KEY, + lnrpc.CommitmentType_ANCHORS, } // testFunding is a function closure that takes Carol and Dave's // commitment types and test the funding flow. - testFunding := func(carolCommitType, daveCommitType commitType) { + testFunding := func(carolCommitType, daveCommitType lnrpc.CommitmentType) { // Based on the current tweak variable for Carol, we'll // preferentially signal the legacy commitment format. We do // the same for Dave shortly below. - carolArgs := carolCommitType.Args() + carolArgs := nodeArgsForCommitType(carolCommitType) carol := net.NewNode(t.t, "Carol", carolArgs) defer shutdownAndAssert(net, t, carol) @@ -49,7 +49,7 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) { // fund the channel. net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, carol) - daveArgs := daveCommitType.Args() + daveArgs := nodeArgsForCommitType(daveCommitType) dave := net.NewNode(t.t, "Dave", daveArgs) defer shutdownAndAssert(net, t, dave) @@ -81,20 +81,20 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) { // Dave supports anchors, type will be what // Carol supports. - case commitTypeAnchors: + case lnrpc.CommitmentType_ANCHORS: // Dave only supports tweakless, channel will // be downgraded to this type if Carol supports // anchors. - case commitTypeTweakless: - if expType == commitTypeAnchors { - expType = commitTypeTweakless + case lnrpc.CommitmentType_STATIC_REMOTE_KEY: + if expType == lnrpc.CommitmentType_ANCHORS { + expType = lnrpc.CommitmentType_STATIC_REMOTE_KEY } // Dave only supoprts legacy type, channel will // be downgraded to this type. - case commitTypeLegacy: - expType = commitTypeLegacy + case lnrpc.CommitmentType_LEGACY: + expType = lnrpc.CommitmentType_LEGACY default: t.Fatalf("invalid commit type %v", daveCommitType) @@ -103,13 +103,13 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) { // Check that the signalled type matches what we // expect. switch { - case expType == commitTypeAnchors && + case expType == lnrpc.CommitmentType_ANCHORS && chansCommitType == lnrpc.CommitmentType_ANCHORS: - case expType == commitTypeTweakless && + case expType == lnrpc.CommitmentType_STATIC_REMOTE_KEY && chansCommitType == lnrpc.CommitmentType_STATIC_REMOTE_KEY: - case expType == commitTypeLegacy && + case expType == lnrpc.CommitmentType_LEGACY && chansCommitType == lnrpc.CommitmentType_LEGACY: default: @@ -221,7 +221,7 @@ func basicChannelFundingTest(t *harnessTest, net *lntest.NetworkHarness, // With the channel open, ensure that the amount specified above has // properly been pushed to Bob. - aliceLocalBalance := chanAmt - pushAmt - cType.calcStaticFee(0) + aliceLocalBalance := chanAmt - pushAmt - calcStaticFee(cType, 0) checkChannelBalance( alice, aliceChannelBalance, aliceLocalBalance, pushAmt, ) @@ -342,8 +342,8 @@ func testUnconfirmedChannelFunding(net *lntest.NetworkHarness, t *harnessTest) { // // Note that atm we haven't obtained the chanPoint yet, so we use the // type directly. - cType := commitTypeTweakless - carolLocalBalance := chanAmt - pushAmt - cType.calcStaticFee(0) + cType := lnrpc.CommitmentType_STATIC_REMOTE_KEY + carolLocalBalance := chanAmt - pushAmt - calcStaticFee(cType, 0) checkChannelBalance(carol, 0, 0, carolLocalBalance, pushAmt) // For Alice, her local/remote balances should be zero, and the diff --git a/lntest/itest/lnd_multi-hop-error-propagation_test.go b/lntest/itest/lnd_multi-hop-error-propagation_test.go index 199dde38b..3e01628fd 100644 --- a/lntest/itest/lnd_multi-hop-error-propagation_test.go +++ b/lntest/itest/lnd_multi-hop-error-propagation_test.go @@ -39,7 +39,7 @@ func testHtlcErrorPropagation(net *lntest.NetworkHarness, t *harnessTest) { t.Fatalf("unable to get channel type: %v", err) } - commitFee := cType.calcStaticFee(0) + commitFee := calcStaticFee(cType, 0) assertBaseBalance := func() { // Alice has opened a channel with Bob with zero push amount, so // it's remote balance is zero. diff --git a/lntest/itest/lnd_multi-hop_htlc_aggregation_test.go b/lntest/itest/lnd_multi-hop_htlc_aggregation_test.go index dbe2e0cc7..f487293ef 100644 --- a/lntest/itest/lnd_multi-hop_htlc_aggregation_test.go +++ b/lntest/itest/lnd_multi-hop_htlc_aggregation_test.go @@ -23,7 +23,7 @@ import ( // case of anchor channels, the second-level spends can also be aggregated and // properly feebumped, so we'll check that as well. func testMultiHopHtlcAggregation(net *lntest.NetworkHarness, t *harnessTest, - alice, bob *lntest.HarnessNode, c commitType) { + alice, bob *lntest.HarnessNode, c lnrpc.CommitmentType) { const finalCltvDelta = 40 ctxb := context.Background() @@ -188,7 +188,7 @@ func testMultiHopHtlcAggregation(net *lntest.NetworkHarness, t *harnessTest, // Bob's force close transaction should now be found in the mempool. If // there are anchors, we also expect Bob's anchor sweep. expectedTxes := 1 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 2 } @@ -262,7 +262,7 @@ func testMultiHopHtlcAggregation(net *lntest.NetworkHarness, t *harnessTest, // one, the same is the case for the timeout transactions. In this case // Carol will also sweep her anchor output in a separate tx (since it // will be low fee). - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 4 } @@ -298,7 +298,7 @@ func testMultiHopHtlcAggregation(net *lntest.NetworkHarness, t *harnessTest, // In case of anchor we expect all the timeout and success second // levels to be aggregated into one tx. For earlier channel types, they // will be separate transactions. - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { require.Len(t.t, timeoutTxs, 1) require.Len(t.t, successTxs, 1) } else { @@ -374,7 +374,7 @@ func testMultiHopHtlcAggregation(net *lntest.NetworkHarness, t *harnessTest, // Mining one additional block, Bob's second level tx is mature, and he // can sweep the output. - case c == commitTypeAnchors: + case c == lnrpc.CommitmentType_ANCHORS: _ = mineBlocks(t, net, 1, 1) // In case this is a non-anchor channel type, we must mine 2 blocks, as diff --git a/lntest/itest/lnd_multi-hop_htlc_local_chain_claim_test.go b/lntest/itest/lnd_multi-hop_htlc_local_chain_claim_test.go index b21f2c2b7..4af71b526 100644 --- a/lntest/itest/lnd_multi-hop_htlc_local_chain_claim_test.go +++ b/lntest/itest/lnd_multi-hop_htlc_local_chain_claim_test.go @@ -20,7 +20,7 @@ import ( // preimage via the witness beacon, we properly settle the HTLC on-chain using // the HTLC success transaction in order to ensure we don't lose any funds. func testMultiHopHtlcLocalChainClaim(net *lntest.NetworkHarness, t *harnessTest, - alice, bob *lntest.HarnessNode, c commitType) { + alice, bob *lntest.HarnessNode, c lnrpc.CommitmentType) { ctxb := context.Background() @@ -86,13 +86,14 @@ func testMultiHopHtlcLocalChainClaim(net *lntest.NetworkHarness, t *harnessTest, // At this point, Bob decides that he wants to exit the channel // immediately, so he force closes his commitment transaction. bobForceClose := closeChannelAndAssertType( - t, net, bob, aliceChanPoint, c == commitTypeAnchors, true, + t, net, bob, aliceChanPoint, + c == lnrpc.CommitmentType_ANCHORS, true, ) // Alice will sweep her commitment output immediately. If there are // anchors, Alice will also sweep hers. expectedTxes := 1 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 2 } _, err = waitForNTxsInMempool( @@ -161,7 +162,7 @@ func testMultiHopHtlcLocalChainClaim(net *lntest.NetworkHarness, t *harnessTest, // If there are anchors on the commitment, Bob will also sweep his // anchor. expectedTxes = 2 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 3 } txes, err := getNTxsFromMempool( @@ -188,7 +189,7 @@ func testMultiHopHtlcLocalChainClaim(net *lntest.NetworkHarness, t *harnessTest, // If this is a channel of the anchor type, we will subtract one block // from the default CSV, as the Sweeper will handle the input, and the Sweeper // sweeps the input as soon as the lock expires. - case commitTypeAnchors: + case lnrpc.CommitmentType_ANCHORS: secondLevelMaturity = defaultCSV - 1 // For non-anchor channel types, the nursery will handle sweeping the diff --git a/lntest/itest/lnd_multi-hop_htlc_local_timeout_test.go b/lntest/itest/lnd_multi-hop_htlc_local_timeout_test.go index 37e9c56c0..542483cfc 100644 --- a/lntest/itest/lnd_multi-hop_htlc_local_timeout_test.go +++ b/lntest/itest/lnd_multi-hop_htlc_local_timeout_test.go @@ -21,7 +21,7 @@ import ( // canceled backwards. Once the timeout has been reached, then we should sweep // it on-chain, and cancel the HTLC backwards. func testMultiHopHtlcLocalTimeout(net *lntest.NetworkHarness, t *harnessTest, - alice, bob *lntest.HarnessNode, c commitType) { + alice, bob *lntest.HarnessNode, c lnrpc.CommitmentType) { ctxb := context.Background() @@ -104,7 +104,7 @@ func testMultiHopHtlcLocalTimeout(net *lntest.NetworkHarness, t *harnessTest, // Bob's force close transaction should now be found in the mempool. If // there are anchors, we also expect Bob's anchor sweep. expectedTxes := 1 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 2 } diff --git a/lntest/itest/lnd_multi-hop_htlc_receiver_chain_claim_test.go b/lntest/itest/lnd_multi-hop_htlc_receiver_chain_claim_test.go index 2609d2f59..120f508ef 100644 --- a/lntest/itest/lnd_multi-hop_htlc_receiver_chain_claim_test.go +++ b/lntest/itest/lnd_multi-hop_htlc_receiver_chain_claim_test.go @@ -22,7 +22,7 @@ import ( // extract the preimage from the sweep transaction, and finish settling the // HTLC backwards into the route. func testMultiHopReceiverChainClaim(net *lntest.NetworkHarness, t *harnessTest, - alice, bob *lntest.HarnessNode, c commitType) { + alice, bob *lntest.HarnessNode, c lnrpc.CommitmentType) { ctxb := context.Background() @@ -113,7 +113,7 @@ func testMultiHopReceiverChainClaim(net *lntest.NetworkHarness, t *harnessTest, // transaction in order to go to the chain and sweep her HTLC. If there // are anchors, Carol also sweeps hers. expectedTxes := 1 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 2 } _, err = getNTxsFromMempool( @@ -150,7 +150,7 @@ func testMultiHopReceiverChainClaim(net *lntest.NetworkHarness, t *harnessTest, // and settle the HTLC back off-chain. Bob will also sweep his anchor, // if present. expectedTxes = 2 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 3 } txes, err := getNTxsFromMempool( diff --git a/lntest/itest/lnd_multi-hop_htlc_remote_chain_claim_test.go b/lntest/itest/lnd_multi-hop_htlc_remote_chain_claim_test.go index af401cd6d..784065e38 100644 --- a/lntest/itest/lnd_multi-hop_htlc_remote_chain_claim_test.go +++ b/lntest/itest/lnd_multi-hop_htlc_remote_chain_claim_test.go @@ -20,7 +20,7 @@ import ( // HTLC directly on-chain using the preimage in order to ensure that we don't // lose any funds. func testMultiHopHtlcRemoteChainClaim(net *lntest.NetworkHarness, t *harnessTest, - alice, bob *lntest.HarnessNode, c commitType) { + alice, bob *lntest.HarnessNode, c lnrpc.CommitmentType) { ctxb := context.Background() @@ -86,7 +86,8 @@ func testMultiHopHtlcRemoteChainClaim(net *lntest.NetworkHarness, t *harnessTest // immediately force close the channel by broadcast her commitment // transaction. aliceForceClose := closeChannelAndAssertType( - t, net, alice, aliceChanPoint, c == commitTypeAnchors, true, + t, net, alice, aliceChanPoint, + c == lnrpc.CommitmentType_ANCHORS, true, ) // Wait for the channel to be marked pending force close. @@ -96,7 +97,7 @@ func testMultiHopHtlcRemoteChainClaim(net *lntest.NetworkHarness, t *harnessTest // After closeChannelAndAssertType returns, it has mined a block so now // bob will attempt to redeem his anchor commitment (if the channel // type is of that type). - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { _, err = waitForNTxsInMempool( net.Miner.Client, 1, minerMempoolTimeout, ) @@ -146,7 +147,7 @@ func testMultiHopHtlcRemoteChainClaim(net *lntest.NetworkHarness, t *harnessTest require.NoError(t.t, err) expectedTxes := 1 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 2 } @@ -186,7 +187,7 @@ func testMultiHopHtlcRemoteChainClaim(net *lntest.NetworkHarness, t *harnessTest // the output is not timelocked since Carol was the one force closing. // If there are anchors, Bob should also sweep his. expectedTxes = 2 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 3 } txes, err := getNTxsFromMempool( diff --git a/lntest/itest/lnd_multi-hop_local_force_close_on_chain_htlc_timeout_test.go b/lntest/itest/lnd_multi-hop_local_force_close_on_chain_htlc_timeout_test.go index 6b7376e21..c94147304 100644 --- a/lntest/itest/lnd_multi-hop_local_force_close_on_chain_htlc_timeout_test.go +++ b/lntest/itest/lnd_multi-hop_local_force_close_on_chain_htlc_timeout_test.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" @@ -17,7 +18,7 @@ import ( // that's timed out. At this point, the node should timeout the HTLC using the // HTLC timeout transaction, then cancel it backwards as normal. func testMultiHopLocalForceCloseOnChainHtlcTimeout(net *lntest.NetworkHarness, - t *harnessTest, alice, bob *lntest.HarnessNode, c commitType) { + t *harnessTest, alice, bob *lntest.HarnessNode, c lnrpc.CommitmentType) { ctxb := context.Background() @@ -72,7 +73,8 @@ func testMultiHopLocalForceCloseOnChainHtlcTimeout(net *lntest.NetworkHarness, // force close the Bob -> Carol channel. This should trigger contract // resolution mode for both of them. closeChannelAndAssertType( - t, net, bob, bobChanPoint, c == commitTypeAnchors, true, + t, net, bob, bobChanPoint, + c == lnrpc.CommitmentType_ANCHORS, true, ) // At this point, Bob should have a pending force close channel as he @@ -93,7 +95,7 @@ func testMultiHopLocalForceCloseOnChainHtlcTimeout(net *lntest.NetworkHarness, // We'll mine defaultCSV blocks in order to generate the sweep // transaction of Bob's funding output. If there are anchors, mine // Carol's anchor sweep too. - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { _, err = waitForTxInMempool(net.Miner.Client, minerMempoolTimeout) require.NoError(t.t, err) } diff --git a/lntest/itest/lnd_multi-hop_remote_force_close_on_chain_htlc_timeout_test.go b/lntest/itest/lnd_multi-hop_remote_force_close_on_chain_htlc_timeout_test.go index 9388f6a22..86b79c1a0 100644 --- a/lntest/itest/lnd_multi-hop_remote_force_close_on_chain_htlc_timeout_test.go +++ b/lntest/itest/lnd_multi-hop_remote_force_close_on_chain_htlc_timeout_test.go @@ -20,7 +20,7 @@ import ( // transaction once the timeout has expired. Once we sweep the transaction, we // should also cancel back the initial HTLC. func testMultiHopRemoteForceCloseOnChainHtlcTimeout(net *lntest.NetworkHarness, - t *harnessTest, alice, bob *lntest.HarnessNode, c commitType) { + t *harnessTest, alice, bob *lntest.HarnessNode, c lnrpc.CommitmentType) { ctxb := context.Background() @@ -84,7 +84,8 @@ func testMultiHopRemoteForceCloseOnChainHtlcTimeout(net *lntest.NetworkHarness, // expired HTLC on Carol's version of the commitment transaction. If // Carol has an anchor, it will be swept too. closeChannelAndAssertType( - t, net, carol, bobChanPoint, c == commitTypeAnchors, true, + t, net, carol, bobChanPoint, + c == lnrpc.CommitmentType_ANCHORS, true, ) // At this point, Bob should have a pending force close channel as @@ -95,7 +96,7 @@ func testMultiHopRemoteForceCloseOnChainHtlcTimeout(net *lntest.NetworkHarness, // Bob can sweep his output immediately. If there is an anchor, Bob will // sweep that as well. expectedTxes := 1 - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { expectedTxes = 2 } diff --git a/lntest/itest/lnd_multi-hop_test.go b/lntest/itest/lnd_multi-hop_test.go index 8d0cdd1e3..39a6b7405 100644 --- a/lntest/itest/lnd_multi-hop_test.go +++ b/lntest/itest/lnd_multi-hop_test.go @@ -19,7 +19,7 @@ func testMultiHopHtlcClaims(net *lntest.NetworkHarness, t *harnessTest) { type testCase struct { name string test func(net *lntest.NetworkHarness, t *harnessTest, alice, - bob *lntest.HarnessNode, c commitType) + bob *lntest.HarnessNode, c lnrpc.CommitmentType) } subTests := []testCase{ @@ -68,19 +68,19 @@ func testMultiHopHtlcClaims(net *lntest.NetworkHarness, t *harnessTest) { }, } - commitTypes := []commitType{ - commitTypeLegacy, - commitTypeAnchors, + commitTypes := []lnrpc.CommitmentType{ + lnrpc.CommitmentType_LEGACY, + lnrpc.CommitmentType_ANCHORS, } for _, commitType := range commitTypes { + commitType := commitType testName := fmt.Sprintf("committype=%v", commitType.String()) - commitType := commitType success := t.t.Run(testName, func(t *testing.T) { ht := newHarnessTest(t, net) - args := commitType.Args() + args := nodeArgsForCommitType(commitType) alice := net.NewNode(t, "Alice", args) defer shutdownAndAssert(net, ht, alice) @@ -205,7 +205,7 @@ func checkPaymentStatus(node *lntest.HarnessNode, preimage lntypes.Preimage, } func createThreeHopNetwork(t *harnessTest, net *lntest.NetworkHarness, - alice, bob *lntest.HarnessNode, carolHodl bool, c commitType) ( + alice, bob *lntest.HarnessNode, carolHodl bool, c lnrpc.CommitmentType) ( *lnrpc.ChannelPoint, *lnrpc.ChannelPoint, *lntest.HarnessNode) { ctxb := context.Background() @@ -243,7 +243,7 @@ func createThreeHopNetwork(t *harnessTest, net *lntest.NetworkHarness, // Next, we'll create a new node "carol" and have Bob connect to her. If // the carolHodl flag is set, we'll make carol always hold onto the // HTLC, this way it'll force Bob to go to chain to resolve the HTLC. - carolFlags := c.Args() + carolFlags := nodeArgsForCommitType(c) if carolHodl { carolFlags = append(carolFlags, "--hodl.exit-settle") } diff --git a/lntest/itest/lnd_onchain_test.go b/lntest/itest/lnd_onchain_test.go index ee15730a8..b59eeb202 100644 --- a/lntest/itest/lnd_onchain_test.go +++ b/lntest/itest/lnd_onchain_test.go @@ -167,7 +167,7 @@ func testCPFP(net *lntest.NetworkHarness, t *harnessTest) { // wallet. func testAnchorReservedValue(net *lntest.NetworkHarness, t *harnessTest) { // Start two nodes supporting anchor channels. - args := commitTypeAnchors.Args() + args := nodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) alice := net.NewNode(t.t, "Alice", args) defer shutdownAndAssert(net, t, alice) diff --git a/lntest/itest/utils.go b/lntest/itest/utils.go index 5fbed3e07..b0c3da420 100644 --- a/lntest/itest/utils.go +++ b/lntest/itest/utils.go @@ -208,45 +208,15 @@ func getChanInfo(node *lntest.HarnessNode) (*lnrpc.Channel, error) { return channelInfo.Channels[0], nil } -// commitType is a simple enum used to run though the basic funding flow with -// different commitment formats. -type commitType byte - -const ( - // commitTypeLegacy is the old school commitment type. - commitTypeLegacy commitType = iota - - // commiTypeTweakless is the commitment type where the remote key is - // static (non-tweaked). - commitTypeTweakless - - // commitTypeAnchors is the kind of commitment that has extra outputs - // used for anchoring down to commitment using CPFP. - commitTypeAnchors -) - -// String returns that name of the commitment type. -func (c commitType) String() string { - switch c { - case commitTypeLegacy: - return "legacy" - case commitTypeTweakless: - return "tweakless" - case commitTypeAnchors: - return "anchors" - default: - return "invalid" - } -} - -// Args returns the command line flag to supply to enable this commitment type. -func (c commitType) Args() []string { - switch c { - case commitTypeLegacy: +// nodeArgsForCommitType returns the command line flag to supply to enable this +// commitment type. +func nodeArgsForCommitType(commitType lnrpc.CommitmentType) []string { + switch commitType { + case lnrpc.CommitmentType_LEGACY: return []string{"--protocol.legacy.committweak"} - case commitTypeTweakless: + case lnrpc.CommitmentType_STATIC_REMOTE_KEY: return []string{} - case commitTypeAnchors: + case lnrpc.CommitmentType_ANCHORS: return []string{"--protocol.anchors"} } @@ -256,7 +226,7 @@ func (c commitType) Args() []string { // calcStaticFee calculates appropriate fees for commitment transactions. This // function provides a simple way to allow test balance assertions to take fee // calculations into account. -func (c commitType) calcStaticFee(numHTLCs int) btcutil.Amount { +func calcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { const htlcWeight = input.HTLCWeight var ( feePerKw = chainfee.SatPerKVByte(50000).FeePerKWeight() @@ -268,7 +238,7 @@ func (c commitType) calcStaticFee(numHTLCs int) btcutil.Amount { // the value of the two anchors to the resulting fee the initiator // pays. In addition the fee rate is capped at 10 sat/vbyte for anchor // channels. - if c == commitTypeAnchors { + if c == lnrpc.CommitmentType_ANCHORS { feePerKw = chainfee.SatPerKVByte( lnwallet.DefaultAnchorsCommitMaxFeeRateSatPerVByte * 1000, ).FeePerKWeight() @@ -283,7 +253,7 @@ func (c commitType) calcStaticFee(numHTLCs int) btcutil.Amount { // channelCommitType retrieves the active channel commitment type for the given // chan point. func channelCommitType(node *lntest.HarnessNode, - chanPoint *lnrpc.ChannelPoint) (commitType, error) { + chanPoint *lnrpc.ChannelPoint) (lnrpc.CommitmentType, error) { ctxb := context.Background() ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) @@ -296,21 +266,7 @@ func channelCommitType(node *lntest.HarnessNode, for _, c := range channels.Channels { if c.ChannelPoint == txStr(chanPoint) { - switch c.CommitmentType { - - // If the anchor output size is non-zero, we are - // dealing with the anchor type. - case lnrpc.CommitmentType_ANCHORS: - return commitTypeAnchors, nil - - // StaticRemoteKey means it is tweakless, - case lnrpc.CommitmentType_STATIC_REMOTE_KEY: - return commitTypeTweakless, nil - - // Otherwise legacy. - default: - return commitTypeLegacy, nil - } + return c.CommitmentType, nil } } From 523eef5cf49326f750278b23ebbf4ff7c8291647 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Wed, 9 Jun 2021 16:38:45 -0700 Subject: [PATCH 09/11] lntest: use explicit channel commitment negotiation for multi-hop itests --- lntest/harness.go | 5 +++++ lntest/itest/lnd_multi-hop_test.go | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lntest/harness.go b/lntest/harness.go index 004af9dd1..d2648a5d3 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -982,6 +982,10 @@ type OpenChannelParams struct { // SatPerVByte is the amount of satoshis to spend in chain fees per virtual // byte of the transaction. SatPerVByte btcutil.Amount + + // CommitmentType is the commitment type that should be used for the + // channel to be opened. + CommitmentType lnrpc.CommitmentType } // OpenChannel attempts to open a channel between srcNode and destNode with the @@ -1025,6 +1029,7 @@ func (n *NetworkHarness) OpenChannel(srcNode, destNode *HarnessNode, RemoteMaxHtlcs: uint32(p.RemoteMaxHtlcs), FundingShim: p.FundingShim, SatPerByte: int64(p.SatPerVByte), + CommitmentType: p.CommitmentType, } respStream, err := srcNode.OpenChannel(ctx, openReq) diff --git a/lntest/itest/lnd_multi-hop_test.go b/lntest/itest/lnd_multi-hop_test.go index 39a6b7405..0d33e47d5 100644 --- a/lntest/itest/lnd_multi-hop_test.go +++ b/lntest/itest/lnd_multi-hop_test.go @@ -224,7 +224,8 @@ func createThreeHopNetwork(t *harnessTest, net *lntest.NetworkHarness, aliceChanPoint := openChannelAndAssert( t, net, alice, bob, lntest.OpenChannelParams{ - Amt: chanAmt, + Amt: chanAmt, + CommitmentType: c, }, ) @@ -264,7 +265,8 @@ func createThreeHopNetwork(t *harnessTest, net *lntest.NetworkHarness, bobChanPoint := openChannelAndAssert( t, net, bob, carol, lntest.OpenChannelParams{ - Amt: chanAmt, + Amt: chanAmt, + CommitmentType: c, }, ) ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) From 3299af7919ac340b7d878475435606aa0d0b8d91 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Fri, 30 Jul 2021 14:49:57 -0700 Subject: [PATCH 10/11] lncli: add channel type flag to openchannel command --- cmd/lncli/cmd_open_channel.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/cmd/lncli/cmd_open_channel.go b/cmd/lncli/cmd_open_channel.go index a2c1a5303..cac46cae3 100644 --- a/cmd/lncli/cmd_open_channel.go +++ b/cmd/lncli/cmd_open_channel.go @@ -57,6 +57,9 @@ Signed base64 encoded PSBT or hex encoded raw wire TX (or path to text file): ` // the user from choosing a large file by accident and running into out // of memory issues or other weird errors. psbtMaxFileSize = 1024 * 1024 + + channelTypeTweakless = "tweakless" + channelTypeAnchors = "anchors" ) // TODO(roasbeef): change default number of confirmations @@ -200,6 +203,12 @@ var openChannelCommand = cli.Command{ Usage: "(optional) the maximum value in msat that " + "can be pending within the channel at any given time", }, + cli.StringFlag{ + Name: "channel_type", + Usage: fmt.Sprintf("(optional) the type of channel to "+ + "propose to the remote peer (%q, %q)", + channelTypeTweakless, channelTypeAnchors), + }, }, Action: actionDecorator(openChannel), } @@ -307,6 +316,19 @@ func openChannel(ctx *cli.Context) error { req.Private = ctx.Bool("private") + // Parse the channel type and map it to its RPC representation. + channelType := ctx.String("channel_type") + switch channelType { + case "": + break + case channelTypeTweakless: + req.CommitmentType = lnrpc.CommitmentType_STATIC_REMOTE_KEY + case channelTypeAnchors: + req.CommitmentType = lnrpc.CommitmentType_ANCHORS + default: + return fmt.Errorf("unsupported channel type %v", channelType) + } + // PSBT funding is a more involved, interactive process that is too // large to also fit into this already long function. if ctx.Bool("psbt") { From 61a0112765d9a2acaa227d8bf28cd88cb767898e Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Fri, 30 Jul 2021 14:50:19 -0700 Subject: [PATCH 11/11] docs: add explicit channel negotiation text to release notes --- docs/release-notes/release-notes-0.14.0.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/release-notes/release-notes-0.14.0.md b/docs/release-notes/release-notes-0.14.0.md index 1043d4493..1f761e36c 100644 --- a/docs/release-notes/release-notes-0.14.0.md +++ b/docs/release-notes/release-notes-0.14.0.md @@ -38,6 +38,17 @@ instantaneous. Read the [guide on leader election](https://github.com/lightningnetwork/lnd/blob/master/docs/leader_election.md) for more information. +## Protocol Extensions + +### Explicit Channel Negotiation + +[A new protocol extension has been added known as explicit channel negotiation] +(https://github.com/lightningnetwork/lnd/pull/5669). This allows a channel +initiator to signal their desired channel type to use with the remote peer. If +the remote peer supports said channel type and agrees, the previous implicit +negotiation based on the shared set of feature bits is bypassed, and the +proposed channel type is used. + ## RPC Server * [Return payment address and add index from @@ -238,6 +249,7 @@ change](https://github.com/lightningnetwork/lnd/pull/5613). * Eugene Siegel * Martin Habovstiak * Oliver Gugger +* Wilmer Paulino * xanoni * Yong Yu * Zero-1729