Merge pull request #8485 from carlaKC/7298-3-forwardblindedroutes

[3/3]: Blinded Route Error Handling
This commit is contained in:
Olaoluwa Osuntokun 2024-04-26 12:39:11 -07:00 committed by GitHub
commit add2691954
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 1323 additions and 522 deletions

View file

@ -627,9 +627,8 @@ func DefaultConfig() Config {
RejectCacheSize: channeldb.DefaultRejectCacheSize, RejectCacheSize: channeldb.DefaultRejectCacheSize,
ChannelCacheSize: channeldb.DefaultChannelCacheSize, ChannelCacheSize: channeldb.DefaultChannelCacheSize,
}, },
Prometheus: lncfg.DefaultPrometheus(), Prometheus: lncfg.DefaultPrometheus(),
Watchtower: lncfg.DefaultWatchtowerCfg(defaultTowerDir), Watchtower: lncfg.DefaultWatchtowerCfg(defaultTowerDir),
ProtocolOptions: lncfg.DefaultProtocol(),
HealthChecks: &lncfg.HealthCheckConfig{ HealthChecks: &lncfg.HealthCheckConfig{
ChainCheck: &lncfg.CheckConfig{ ChainCheck: &lncfg.CheckConfig{
Interval: defaultChainInterval, Interval: defaultChainInterval,

View file

@ -543,7 +543,7 @@ func (h *htlcIncomingContestResolver) decodePayload() (*hop.Payload,
return nil, nil, err return nil, nil, err
} }
payload, err := iterator.HopPayload() payload, _, err := iterator.HopPayload()
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View file

@ -263,7 +263,7 @@ type mockHopIterator struct {
hop.Iterator hop.Iterator
} }
func (h *mockHopIterator) HopPayload() (*hop.Payload, error) { func (h *mockHopIterator) HopPayload() (*hop.Payload, hop.RouteRole, error) {
var nextAddress [8]byte var nextAddress [8]byte
if !h.isExit { if !h.isExit {
nextAddress = [8]byte{0x01} nextAddress = [8]byte{0x01}
@ -275,7 +275,7 @@ func (h *mockHopIterator) HopPayload() (*hop.Payload, error) {
ForwardAmount: 100, ForwardAmount: 100,
OutgoingCltv: 40, OutgoingCltv: 40,
ExtraBytes: [12]byte{}, ExtraBytes: [12]byte{},
}), nil }), hop.RouteRoleCleartext, nil
} }
func (h *mockHopIterator) EncodeNextHop(w io.Writer) error { func (h *mockHopIterator) EncodeNextHop(w io.Writer) error {

View file

@ -215,8 +215,11 @@ bitcoin peers' feefilter values into account](https://github.com/lightningnetwor
* [Preparatory work](https://github.com/lightningnetwork/lnd/pull/8159) for * [Preparatory work](https://github.com/lightningnetwork/lnd/pull/8159) for
forwarding of blinded routes was added, along with [support](https://github.com/lightningnetwork/lnd/pull/8160) forwarding of blinded routes was added, along with [support](https://github.com/lightningnetwork/lnd/pull/8160)
for forwarding blinded payments. Forwarding of blinded payments is disabled for forwarding blinded payments and [error handling](https://github.com/lightningnetwork/lnd/pull/8485).
by default, and the feature is not yet advertised to the network. With this change, LND is now eligible to be selected as part of a blinded
route and can forward payments on behalf of nodes that have support for
receiving to blinded paths. This upgrade provides a meaningful improvement
to the anonymity set and usability of blinded paths in the Lightning Network.
* Introduced [fee bumper](https://github.com/lightningnetwork/lnd/pull/8424) to * Introduced [fee bumper](https://github.com/lightningnetwork/lnd/pull/8424) to
handle bumping the fees of sweeping transactions properly. A handle bumping the fees of sweeping transactions properly. A

View file

@ -79,6 +79,11 @@ var defaultSetDesc = setDesc{
SetInit: {}, // I SetInit: {}, // I
SetNodeAnn: {}, // N SetNodeAnn: {}, // N
}, },
lnwire.RouteBlindingOptional: {
SetInit: {}, // I
SetNodeAnn: {}, // N
SetInvoice: {}, // 9
},
lnwire.ShutdownAnySegwitOptional: { lnwire.ShutdownAnySegwitOptional: {
SetInit: {}, // I SetInit: {}, // I
SetNodeAnn: {}, // N SetNodeAnn: {}, // N

View file

@ -79,6 +79,12 @@ var deps = depDesc{
lnwire.AnchorsZeroFeeHtlcTxOptional: {}, lnwire.AnchorsZeroFeeHtlcTxOptional: {},
lnwire.ExplicitChannelTypeOptional: {}, lnwire.ExplicitChannelTypeOptional: {},
}, },
lnwire.RouteBlindingOptional: {
lnwire.TLVOnionPayloadOptional: {},
},
lnwire.RouteBlindingRequired: {
lnwire.TLVOnionPayloadRequired: {},
},
} }
// ValidateDeps asserts that a feature vector sets all features and their // ValidateDeps asserts that a feature vector sets all features and their

View file

@ -60,6 +60,9 @@ type Config struct {
// segwit witness versions for co-op closes. // segwit witness versions for co-op closes.
NoAnySegwit bool NoAnySegwit bool
// NoRouteBlinding unsets route blinding feature bits.
NoRouteBlinding bool
// CustomFeatures is a set of custom features to advertise in each // CustomFeatures is a set of custom features to advertise in each
// set. // set.
CustomFeatures map[Set][]lnwire.FeatureBit CustomFeatures map[Set][]lnwire.FeatureBit
@ -123,6 +126,8 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) {
raw.Unset(lnwire.PaymentAddrRequired) raw.Unset(lnwire.PaymentAddrRequired)
raw.Unset(lnwire.MPPOptional) raw.Unset(lnwire.MPPOptional)
raw.Unset(lnwire.MPPRequired) raw.Unset(lnwire.MPPRequired)
raw.Unset(lnwire.RouteBlindingOptional)
raw.Unset(lnwire.RouteBlindingRequired)
raw.Unset(lnwire.AMPOptional) raw.Unset(lnwire.AMPOptional)
raw.Unset(lnwire.AMPRequired) raw.Unset(lnwire.AMPRequired)
raw.Unset(lnwire.KeysendOptional) raw.Unset(lnwire.KeysendOptional)
@ -179,7 +184,10 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) {
raw.Unset(lnwire.SimpleTaprootChannelsOptionalStaging) raw.Unset(lnwire.SimpleTaprootChannelsOptionalStaging)
raw.Unset(lnwire.SimpleTaprootChannelsRequiredStaging) raw.Unset(lnwire.SimpleTaprootChannelsRequiredStaging)
} }
if cfg.NoRouteBlinding {
raw.Unset(lnwire.RouteBlindingOptional)
raw.Unset(lnwire.RouteBlindingRequired)
}
for _, custom := range cfg.CustomFeatures[set] { for _, custom := range cfg.CustomFeatures[set] {
if custom > set.Maximum() { if custom > set.Maximum() {
return nil, fmt.Errorf("feature bit: %v "+ return nil, fmt.Errorf("feature bit: %v "+

View file

@ -205,6 +205,12 @@ func (c *PaymentCircuit) Decode(r io.Reader) error {
// Test encrypter. // Test encrypter.
c.ErrorEncrypter = NewMockObfuscator() c.ErrorEncrypter = NewMockObfuscator()
case hop.EncrypterTypeIntroduction:
c.ErrorEncrypter = hop.NewIntroductionErrorEncrypter()
case hop.EncrypterTypeRelaying:
c.ErrorEncrypter = hop.NewRelayingErrorEncrypter()
default: default:
return UnknownEncrypterType(encrypterType) return UnknownEncrypterType(encrypterType)
} }

View file

@ -25,8 +25,26 @@ const (
// EncrypterTypeMock is used to identify a mock obfuscator instance. // EncrypterTypeMock is used to identify a mock obfuscator instance.
EncrypterTypeMock = 2 EncrypterTypeMock = 2
// EncrypterTypeIntroduction is used to identify a sphinx onion error
// encrypter where we are the introduction node in a blinded route. It
// has the same functionality as EncrypterTypeSphinx, but is used to
// mark our special-case error handling.
EncrypterTypeIntroduction = 3
// EncrypterTypeRelaying is used to identify a sphinx onion error
// encryper where we are a relaying node in a blinded route. It has
// the same functionality as a EncrypterTypeSphinx, but is used to mark
// our special-case error handling.
EncrypterTypeRelaying = 4
) )
// IsBlinded returns a boolean indicating whether the error encrypter belongs
// to a blinded route.
func (e EncrypterType) IsBlinded() bool {
return e == EncrypterTypeIntroduction || e == EncrypterTypeRelaying
}
// ErrorEncrypterExtracter defines a function signature that extracts an // ErrorEncrypterExtracter defines a function signature that extracts an
// ErrorEncrypter from an sphinx OnionPacket. // ErrorEncrypter from an sphinx OnionPacket.
type ErrorEncrypterExtracter func(*btcec.PublicKey) (ErrorEncrypter, type ErrorEncrypterExtracter func(*btcec.PublicKey) (ErrorEncrypter,
@ -197,9 +215,72 @@ func (s *SphinxErrorEncrypter) Reextract(
s.OnionErrorEncrypter = sphinxEncrypter.OnionErrorEncrypter s.OnionErrorEncrypter = sphinxEncrypter.OnionErrorEncrypter
return nil return nil
} }
// A compile time check to ensure SphinxErrorEncrypter implements the // A compile time check to ensure SphinxErrorEncrypter implements the
// ErrorEncrypter interface. // ErrorEncrypter interface.
var _ ErrorEncrypter = (*SphinxErrorEncrypter)(nil) var _ ErrorEncrypter = (*SphinxErrorEncrypter)(nil)
// A compile time check to ensure that IntroductionErrorEncrypter implements
// the ErrorEncrypter interface.
var _ ErrorEncrypter = (*IntroductionErrorEncrypter)(nil)
// IntroductionErrorEncrypter is a wrapper type on SphinxErrorEncrypter which
// is used to signal that we have special HTLC error handling for this hop.
type IntroductionErrorEncrypter struct {
// ErrorEncrypter is the underlying error encrypter, embedded
// directly in the struct so that we don't have to re-implement the
// ErrorEncrypter interface.
ErrorEncrypter
}
// NewIntroductionErrorEncrypter returns a blank IntroductionErrorEncrypter.
func NewIntroductionErrorEncrypter() *IntroductionErrorEncrypter {
return &IntroductionErrorEncrypter{
ErrorEncrypter: NewSphinxErrorEncrypter(),
}
}
// Type returns the identifier for an introduction error encrypter.
func (i *IntroductionErrorEncrypter) Type() EncrypterType {
return EncrypterTypeIntroduction
}
// Reextract rederives the error encrypter from the currently held EphemeralKey,
// relying on the logic in the underlying SphinxErrorEncrypter.
func (i *IntroductionErrorEncrypter) Reextract(
extract ErrorEncrypterExtracter) error {
return i.ErrorEncrypter.Reextract(extract)
}
// A compile time check to ensure that RelayingErrorEncrypte implements
// the ErrorEncrypter interface.
var _ ErrorEncrypter = (*RelayingErrorEncrypter)(nil)
// RelayingErrorEncrypter is a wrapper type on SphinxErrorEncrypter which
// is used to signal that we have special HTLC error handling for this hop.
type RelayingErrorEncrypter struct {
ErrorEncrypter
}
// NewRelayingErrorEncrypter returns a blank RelayingErrorEncrypter with
// an underlying SphinxErrorEncrypter.
func NewRelayingErrorEncrypter() *RelayingErrorEncrypter {
return &RelayingErrorEncrypter{
ErrorEncrypter: NewSphinxErrorEncrypter(),
}
}
// Type returns the identifier for a relaying error encrypter.
func (r *RelayingErrorEncrypter) Type() EncrypterType {
return EncrypterTypeRelaying
}
// Reextract rederives the error encrypter from the currently held EphemeralKey,
// relying on the logic in the underlying SphinxErrorEncrypter.
func (r *RelayingErrorEncrypter) Reextract(
extract ErrorEncrypterExtracter) error {
return r.ErrorEncrypter.Reextract(extract)
}

View file

@ -97,19 +97,37 @@ func hopFromPayload(p *Payload) (*route.Hop, uint64) {
// FuzzPayloadFinal fuzzes final hop payloads, providing the additional context // FuzzPayloadFinal fuzzes final hop payloads, providing the additional context
// that the hop should be final (which is usually obtained by the structure // that the hop should be final (which is usually obtained by the structure
// of the sphinx packet). // of the sphinx packet) for the case where a blinding point was provided in
func FuzzPayloadFinal(f *testing.F) { // UpdateAddHtlc.
fuzzPayload(f, true) func FuzzPayloadFinalBlinding(f *testing.F) {
fuzzPayload(f, true, true)
}
// FuzzPayloadFinal fuzzes final hop payloads, providing the additional context
// that the hop should be final (which is usually obtained by the structure
// of the sphinx packet) for the case where no blinding point was provided in
// UpdateAddHtlc.
func FuzzPayloadFinalNoBlinding(f *testing.F) {
fuzzPayload(f, true, false)
} }
// FuzzPayloadIntermediate fuzzes intermediate hop payloads, providing the // FuzzPayloadIntermediate fuzzes intermediate hop payloads, providing the
// additional context that a hop should be intermediate (which is usually // additional context that a hop should be intermediate (which is usually
// obtained by the structure of the sphinx packet). // obtained by the structure of the sphinx packet) for the case where a
func FuzzPayloadIntermediate(f *testing.F) { // blinding point was provided in UpdateAddHtlc.
fuzzPayload(f, false) func FuzzPayloadIntermediateBlinding(f *testing.F) {
fuzzPayload(f, false, true)
} }
func fuzzPayload(f *testing.F, finalPayload bool) { // FuzzPayloadIntermediate fuzzes intermediate hop payloads, providing the
// additional context that a hop should be intermediate (which is usually
// obtained by the structure of the sphinx packet) for the case where no
// blinding point was provided in UpdateAddHtlc.
func FuzzPayloadIntermediateNoBlinding(f *testing.F) {
fuzzPayload(f, false, false)
}
func fuzzPayload(f *testing.F, finalPayload, updateAddBlinded bool) {
f.Fuzz(func(t *testing.T, data []byte) { f.Fuzz(func(t *testing.T, data []byte) {
if len(data) > sphinx.MaxPayloadSize { if len(data) > sphinx.MaxPayloadSize {
return return
@ -117,17 +135,23 @@ func fuzzPayload(f *testing.F, finalPayload bool) {
r := bytes.NewReader(data) r := bytes.NewReader(data)
payload1, _, err := NewPayloadFromReader(r, finalPayload) payload1, parsed, err := ParseTLVPayload(r)
if err != nil { if err != nil {
return return
} }
if err = ValidateParsedPayloadTypes(
parsed, finalPayload, updateAddBlinded,
); err != nil {
return
}
var b bytes.Buffer var b bytes.Buffer
hop, nextChanID := hopFromPayload(payload1) hop, nextChanID := hopFromPayload(payload1)
err = hop.PackHopPayload(&b, nextChanID, finalPayload) err = hop.PackHopPayload(&b, nextChanID, finalPayload)
switch { switch {
// PackHopPayload refuses to encode an AMP record // PackHopPayload refuses to encode an AMP record
// without an MPP record. However, NewPayloadFromReader // without an MPP record. However, ValidateParsedPayloadTypes
// does allow decoding an AMP record without an MPP // does allow decoding an AMP record without an MPP
// record, since validation is done at a later stage. Do // record, since validation is done at a later stage. Do
// not report a bug for this case. // not report a bug for this case.
@ -136,9 +160,9 @@ func fuzzPayload(f *testing.F, finalPayload bool) {
// PackHopPayload will not encode regular payloads or final // PackHopPayload will not encode regular payloads or final
// hops in blinded routes that do not have an amount or expiry // hops in blinded routes that do not have an amount or expiry
// TLV set. However, NewPayloadFromReader will allow creation // TLV set. However, ValidateParsedPayloadTypes will allow
// of payloads where these TLVs are present, but they have // creation of payloads where these TLVs are present, but they
// zero values because validation is done at a later stage. // have zero values because validation is done at a later stage.
case errors.Is(err, route.ErrMissingField): case errors.Is(err, route.ErrMissingField):
return return
@ -146,7 +170,12 @@ func fuzzPayload(f *testing.F, finalPayload bool) {
require.NoError(t, err) require.NoError(t, err)
} }
payload2, _, err := NewPayloadFromReader(&b, finalPayload) payload2, parsed, err := ParseTLVPayload(&b)
require.NoError(t, err)
err = ValidateParsedPayloadTypes(
parsed, finalPayload, updateAddBlinded,
)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, payload1, payload2) require.Equal(t, payload1, payload2)

View file

@ -17,8 +17,69 @@ import (
var ( var (
// ErrDecodeFailed is returned when we can't decode blinded data. // ErrDecodeFailed is returned when we can't decode blinded data.
ErrDecodeFailed = errors.New("could not decode blinded data") ErrDecodeFailed = errors.New("could not decode blinded data")
// ErrNoBlindingPoint is returned when we have not provided a blinding
// point for a validated payload with encrypted data set.
ErrNoBlindingPoint = errors.New("no blinding point set for validated " +
"blinded hop")
) )
// RouteRole represents the different types of roles a node can have as a
// recipient of a HTLC.
type RouteRole uint8
const (
// RouteRoleCleartext represents a regular route hop.
RouteRoleCleartext RouteRole = iota
// RouteRoleIntroduction represents an introduction node in a blinded
// path, characterized by a blinding point in the onion payload.
RouteRoleIntroduction
// RouteRoleRelaying represents a relaying node in a blinded path,
// characterized by a blinding point in update_add_htlc.
RouteRoleRelaying
)
// String representation of a role in a route.
func (h RouteRole) String() string {
switch h {
case RouteRoleCleartext:
return "cleartext"
case RouteRoleRelaying:
return "blinded relay"
case RouteRoleIntroduction:
return "introduction node"
default:
return fmt.Sprintf("unknown route role: %d", h)
}
}
// NewRouteRole returns the role we're playing in a route depending on the
// blinding points set (or not). If we are in the situation where we received
// blinding points in both the update add message and the payload:
// - We must have had a valid update add blinding point, because we were able
// to decrypt our onion to get the payload blinding point.
// - We return a relaying node role, because an introduction node (by
// definition) does not receive a blinding point in update add.
// - We assume the sending node to be buggy (including a payload blinding
// where it shouldn't), and rely on validation elsewhere to handle this.
func NewRouteRole(updateAddBlinding, payloadBlinding bool) RouteRole {
switch {
case updateAddBlinding:
return RouteRoleRelaying
case payloadBlinding:
return RouteRoleIntroduction
default:
return RouteRoleCleartext
}
}
// Iterator is an interface that abstracts away the routing information // Iterator is an interface that abstracts away the routing information
// included in HTLC's which includes the entirety of the payment path of an // included in HTLC's which includes the entirety of the payment path of an
// HTLC. This interface provides two basic method which carry out: how to // HTLC. This interface provides two basic method which carry out: how to
@ -30,8 +91,11 @@ type Iterator interface {
// information encoded within the returned ForwardingInfo is to be used // information encoded within the returned ForwardingInfo is to be used
// by each hop to authenticate the information given to it by the prior // by each hop to authenticate the information given to it by the prior
// hop. The payload will also contain any additional TLV fields provided // hop. The payload will also contain any additional TLV fields provided
// by the sender. // by the sender. The role that this hop plays in the context of
HopPayload() (*Payload, error) // route blinding (regular, introduction or relaying) is returned
// whenever the payload is successfully parsed, even if we subsequently
// face a validation error.
HopPayload() (*Payload, RouteRole, error)
// EncodeNextHop encodes the onion packet destined for the next hop // EncodeNextHop encodes the onion packet destined for the next hop
// into the passed io.Writer. // into the passed io.Writer.
@ -39,8 +103,8 @@ type Iterator interface {
// ExtractErrorEncrypter returns the ErrorEncrypter needed for this hop, // ExtractErrorEncrypter returns the ErrorEncrypter needed for this hop,
// along with a failure code to signal if the decoding was successful. // along with a failure code to signal if the decoding was successful.
ExtractErrorEncrypter(ErrorEncrypterExtracter) (ErrorEncrypter, ExtractErrorEncrypter(extractor ErrorEncrypterExtracter,
lnwire.FailCode) introductionNode bool) (ErrorEncrypter, lnwire.FailCode)
} }
// sphinxHopIterator is the Sphinx implementation of hop iterator which uses // sphinxHopIterator is the Sphinx implementation of hop iterator which uses
@ -90,29 +154,56 @@ func (r *sphinxHopIterator) EncodeNextHop(w io.Writer) error {
// HopPayload returns the set of fields that detail exactly _how_ this hop // HopPayload returns the set of fields that detail exactly _how_ this hop
// should forward the HTLC to the next hop. Additionally, the information // should forward the HTLC to the next hop. Additionally, the information
// encoded within the returned ForwardingInfo is to be used by each hop to // encoded within the returned ForwardingInfo is to be used by each hop to
// authenticate the information given to it by the prior hop. The payload will // authenticate the information given to it by the prior hop. The role that
// also contain any additional TLV fields provided by the sender. // this hop plays in the context of route blinding (regular, introduction or
// relaying) is returned whenever the payload is successfully parsed, even if
// we subsequently face a validation error. The payload will also contain any
// additional TLV fields provided by the sender.
// //
// NOTE: Part of the HopIterator interface. // NOTE: Part of the HopIterator interface.
func (r *sphinxHopIterator) HopPayload() (*Payload, error) { func (r *sphinxHopIterator) HopPayload() (*Payload, RouteRole, error) {
switch r.processedPacket.Payload.Type { switch r.processedPacket.Payload.Type {
// If this is the legacy payload, then we'll extract the information // If this is the legacy payload, then we'll extract the information
// directly from the pre-populated ForwardingInstructions field. // directly from the pre-populated ForwardingInstructions field.
case sphinx.PayloadLegacy: case sphinx.PayloadLegacy:
fwdInst := r.processedPacket.ForwardingInstructions fwdInst := r.processedPacket.ForwardingInstructions
return NewLegacyPayload(fwdInst), nil return NewLegacyPayload(fwdInst), RouteRoleCleartext, nil
// Otherwise, if this is the TLV payload, then we'll make a new stream // Otherwise, if this is the TLV payload, then we'll make a new stream
// to decode only what we need to make routing decisions. // to decode only what we need to make routing decisions.
case sphinx.PayloadTLV: case sphinx.PayloadTLV:
isFinal := r.processedPacket.Action == sphinx.ExitNode isFinal := r.processedPacket.Action == sphinx.ExitNode
payload, parsed, err := NewPayloadFromReader( payload, parsed, err := ParseTLVPayload(
bytes.NewReader(r.processedPacket.Payload.Payload), bytes.NewReader(r.processedPacket.Payload.Payload),
isFinal,
) )
if err != nil { if err != nil {
return nil, err // If we couldn't even parse our payload then we do
// a best-effort of determining our role in a blinded
// route, accepting that we can't know whether we
// were the introduction node (as the payload
// is not parseable).
routeRole := RouteRoleCleartext
if r.blindingKit.UpdateAddBlinding.IsSome() {
routeRole = RouteRoleRelaying
}
return nil, routeRole, err
}
// Now that we've parsed our payload we can determine which
// role we're playing in the route.
_, payloadBlinding := parsed[record.BlindingPointOnionType]
routeRole := NewRouteRole(
r.blindingKit.UpdateAddBlinding.IsSome(),
payloadBlinding,
)
if err := ValidateTLVPayload(
parsed, isFinal,
r.blindingKit.UpdateAddBlinding.IsSome(),
); err != nil {
return nil, routeRole, err
} }
// If we had an encrypted data payload present, pull out our // If we had an encrypted data payload present, pull out our
@ -122,17 +213,18 @@ func (r *sphinxHopIterator) HopPayload() (*Payload, error) {
payload, isFinal, parsed, payload, isFinal, parsed,
) )
if err != nil { if err != nil {
return nil, err return nil, routeRole, err
} }
payload.FwdInfo = *fwdInfo payload.FwdInfo = *fwdInfo
} }
return payload, err return payload, routeRole, nil
default: default:
return nil, fmt.Errorf("unknown sphinx payload type: %v", return nil, RouteRoleCleartext,
r.processedPacket.Payload.Type) fmt.Errorf("unknown sphinx payload type: %v",
r.processedPacket.Payload.Type)
} }
} }
@ -143,9 +235,31 @@ func (r *sphinxHopIterator) HopPayload() (*Payload, error) {
// //
// NOTE: Part of the HopIterator interface. // NOTE: Part of the HopIterator interface.
func (r *sphinxHopIterator) ExtractErrorEncrypter( func (r *sphinxHopIterator) ExtractErrorEncrypter(
extracter ErrorEncrypterExtracter) (ErrorEncrypter, lnwire.FailCode) { extracter ErrorEncrypterExtracter, introductionNode bool) (
ErrorEncrypter, lnwire.FailCode) {
return extracter(r.ogPacket.EphemeralKey) encrypter, errCode := extracter(r.ogPacket.EphemeralKey)
if errCode != lnwire.CodeNone {
return nil, errCode
}
// If we're in a blinded path, wrap the error encrypter that we just
// derived in a "marker" type which we'll use to know what type of
// error we're handling.
switch {
case introductionNode:
return &IntroductionErrorEncrypter{
ErrorEncrypter: encrypter,
}, errCode
case r.blindingKit.UpdateAddBlinding.IsSome():
return &RelayingErrorEncrypter{
ErrorEncrypter: encrypter,
}, errCode
default:
return encrypter, errCode
}
} }
// BlindingProcessor is an interface that provides the cryptographic operations // BlindingProcessor is an interface that provides the cryptographic operations
@ -182,35 +296,16 @@ type BlindingKit struct {
IncomingAmount lnwire.MilliSatoshi IncomingAmount lnwire.MilliSatoshi
} }
// validateBlindingPoint validates that only one blinding point is present for // getBlindingPoint returns either the payload or updateAddHtlc blinding point,
// the hop and returns the relevant one. // assuming that validation that these values are appropriately set has already
func (b *BlindingKit) validateBlindingPoint(payloadBlinding *btcec.PublicKey, // been handled elsewhere.
isFinalHop bool) (*btcec.PublicKey, error) { func (b *BlindingKit) getBlindingPoint(payloadBlinding *btcec.PublicKey) (
*btcec.PublicKey, error) {
// Bolt 04: if encrypted_recipient_data is present:
// - if blinding_point (in update add) is set:
// - MUST error if current_blinding_point is set (in payload)
// - otherwise:
// - MUST return an error if current_blinding_point is not present
// (in payload)
payloadBlindingSet := payloadBlinding != nil payloadBlindingSet := payloadBlinding != nil
updateBlindingSet := b.UpdateAddBlinding.IsSome() updateBlindingSet := b.UpdateAddBlinding.IsSome()
switch { switch {
case !(payloadBlindingSet || updateBlindingSet):
return nil, ErrInvalidPayload{
Type: record.BlindingPointOnionType,
Violation: OmittedViolation,
FinalHop: isFinalHop,
}
case payloadBlindingSet && updateBlindingSet:
return nil, ErrInvalidPayload{
Type: record.BlindingPointOnionType,
Violation: IncludedViolation,
FinalHop: isFinalHop,
}
case payloadBlindingSet: case payloadBlindingSet:
return payloadBlinding, nil return payloadBlinding, nil
@ -223,9 +318,10 @@ func (b *BlindingKit) validateBlindingPoint(payloadBlinding *btcec.PublicKey,
} }
return pk.Val, nil return pk.Val, nil
}
return nil, fmt.Errorf("expected blinded point set") default:
return nil, ErrNoBlindingPoint
}
} }
// DecryptAndValidateFwdInfo performs all operations required to decrypt and // DecryptAndValidateFwdInfo performs all operations required to decrypt and
@ -235,11 +331,10 @@ func (b *BlindingKit) DecryptAndValidateFwdInfo(payload *Payload,
*ForwardingInfo, error) { *ForwardingInfo, error) {
// We expect this function to be called when we have encrypted data // We expect this function to be called when we have encrypted data
// present, and a blinding key is set either in the payload or the // present, and expect validation to already have ensured that a
// blinding key is set either in the payload or the
// update_add_htlc message. // update_add_htlc message.
blindingPoint, err := b.validateBlindingPoint( blindingPoint, err := b.getBlindingPoint(payload.blindingPoint)
payload.blindingPoint, isFinalHop,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -88,10 +88,10 @@ func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
for i, testCase := range testCases { for i, testCase := range testCases {
iterator.processedPacket = testCase.sphinxPacket iterator.processedPacket = testCase.sphinxPacket
pld, err := iterator.HopPayload() pld, _, pldErr := iterator.HopPayload()
if err != nil { if pldErr != nil {
t.Fatalf("#%v: unable to extract forwarding "+ t.Fatalf("#%v: unable to extract forwarding "+
"instructions: %v", i, err) "instructions: %v", i, pldErr)
} }
fwdInfo := pld.ForwardingInfo() fwdInfo := pld.ForwardingInfo()
@ -216,24 +216,10 @@ func TestDecryptAndValidateFwdInfo(t *testing.T) {
expectedErr error expectedErr error
}{ }{
{ {
name: "no blinding point", name: "no blinding point",
data: validData, data: validData,
processor: &mockProcessor{}, processor: &mockProcessor{},
expectedErr: ErrInvalidPayload{ expectedErr: ErrNoBlindingPoint,
Type: record.BlindingPointOnionType,
Violation: OmittedViolation,
},
},
{
name: "both blinding points",
data: validData,
updateAddBlinding: &btcec.PublicKey{},
payloadBlinding: &btcec.PublicKey{},
processor: &mockProcessor{},
expectedErr: ErrInvalidPayload{
Type: record.BlindingPointOnionType,
Violation: IncludedViolation,
},
}, },
{ {
name: "decryption failed", name: "decryption failed",
@ -265,12 +251,19 @@ func TestDecryptAndValidateFwdInfo(t *testing.T) {
}, },
}, },
{ {
name: "valid", name: "valid using update add",
updateAddBlinding: &btcec.PublicKey{}, updateAddBlinding: &btcec.PublicKey{},
data: validData, data: validData,
processor: &mockProcessor{}, processor: &mockProcessor{},
expectedErr: nil, expectedErr: nil,
}, },
{
name: "valid using payload",
payloadBlinding: &btcec.PublicKey{},
data: validData,
processor: &mockProcessor{},
expectedErr: nil,
},
} }
for _, testCase := range tests { for _, testCase := range tests {

View file

@ -133,14 +133,10 @@ func NewLegacyPayload(f *sphinx.HopData) *Payload {
} }
} }
// NewPayloadFromReader builds a new Hop from the passed io.Reader and returns // ParseTLVPayload builds a new Hop from the passed io.Reader and returns
// a map of all the types that were found in the payload. The reader // a map of all the types that were found in the payload. This function
// should correspond to the bytes encapsulated in a TLV onion payload. The // does not perform validation of TLV types included in the payload.
// final hop bool signals that this payload was the final packet parsed by func ParseTLVPayload(r io.Reader) (*Payload, map[tlv.Type][]byte, error) {
// sphinx.
func NewPayloadFromReader(r io.Reader, finalHop bool) (*Payload,
map[tlv.Type][]byte, error) {
var ( var (
cid uint64 cid uint64
amt uint64 amt uint64
@ -175,23 +171,6 @@ func NewPayloadFromReader(r io.Reader, finalHop bool) (*Payload,
return nil, nil, err return nil, nil, err
} }
// Validate whether the sender properly included or omitted tlv records
// in accordance with BOLT 04.
err = ValidateParsedPayloadTypes(parsedTypes, finalHop)
if err != nil {
return nil, nil, err
}
// Check for violation of the rules for mandatory fields.
violatingType := getMinRequiredViolation(parsedTypes)
if violatingType != nil {
return nil, nil, ErrInvalidPayload{
Type: *violatingType,
Violation: RequiredViolation,
FinalHop: finalHop,
}
}
// If no MPP field was parsed, set the MPP field on the resulting // If no MPP field was parsed, set the MPP field on the resulting
// payload to nil. // payload to nil.
if _, ok := parsedTypes[record.MPPOnionType]; !ok { if _, ok := parsedTypes[record.MPPOnionType]; !ok {
@ -232,7 +211,34 @@ func NewPayloadFromReader(r io.Reader, finalHop bool) (*Payload,
blindingPoint: blindingPoint, blindingPoint: blindingPoint,
customRecords: customRecords, customRecords: customRecords,
totalAmtMsat: lnwire.MilliSatoshi(totalAmtMsat), totalAmtMsat: lnwire.MilliSatoshi(totalAmtMsat),
}, nil, nil }, parsedTypes, nil
}
// ValidateTLVPayload validates the TLV fields that were included in a TLV
// payload.
func ValidateTLVPayload(parsedTypes map[tlv.Type][]byte,
finalHop bool, updateAddBlinding bool) error {
// Validate whether the sender properly included or omitted tlv records
// in accordance with BOLT 04.
err := ValidateParsedPayloadTypes(
parsedTypes, finalHop, updateAddBlinding,
)
if err != nil {
return err
}
// Check for violation of the rules for mandatory fields.
violatingType := getMinRequiredViolation(parsedTypes)
if violatingType != nil {
return ErrInvalidPayload{
Type: *violatingType,
Violation: RequiredViolation,
FinalHop: finalHop,
}
}
return nil
} }
// ForwardingInfo returns the basic parameters required for HTLC forwarding, // ForwardingInfo returns the basic parameters required for HTLC forwarding,
@ -259,7 +265,7 @@ func NewCustomRecords(parsedTypes tlv.TypeMap) record.CustomSet {
// boolean should be true if the payload was parsed for an exit hop. The // boolean should be true if the payload was parsed for an exit hop. The
// requirements for this method are described in BOLT 04. // requirements for this method are described in BOLT 04.
func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap, func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap,
isFinalHop bool) error { isFinalHop, updateAddBlinding bool) error {
_, hasAmt := parsedTypes[record.AmtOnionType] _, hasAmt := parsedTypes[record.AmtOnionType]
_, hasLockTime := parsedTypes[record.LockTimeOnionType] _, hasLockTime := parsedTypes[record.LockTimeOnionType]
@ -267,6 +273,7 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap,
_, hasMPP := parsedTypes[record.MPPOnionType] _, hasMPP := parsedTypes[record.MPPOnionType]
_, hasAMP := parsedTypes[record.AMPOnionType] _, hasAMP := parsedTypes[record.AMPOnionType]
_, hasEncryptedData := parsedTypes[record.EncryptedDataOnionType] _, hasEncryptedData := parsedTypes[record.EncryptedDataOnionType]
_, hasBlinding := parsedTypes[record.BlindingPointOnionType]
// All cleartext hops (including final hop) and the final hop in a // All cleartext hops (including final hop) and the final hop in a
// blinded path require the forwading amount and expiry TLVs to be set. // blinded path require the forwading amount and expiry TLVs to be set.
@ -277,6 +284,32 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap,
needNextHop := !(hasEncryptedData || isFinalHop) needNextHop := !(hasEncryptedData || isFinalHop)
switch { switch {
// Both blinding point being set is invalid.
case hasBlinding && updateAddBlinding:
return ErrInvalidPayload{
Type: record.BlindingPointOnionType,
Violation: IncludedViolation,
FinalHop: isFinalHop,
}
// If encrypted data is not provided, blinding points should not be
// set.
case !hasEncryptedData && (hasBlinding || updateAddBlinding):
return ErrInvalidPayload{
Type: record.EncryptedDataOnionType,
Violation: OmittedViolation,
FinalHop: isFinalHop,
}
// If encrypted data is present, we require that one blinding point
// is set.
case hasEncryptedData && !(hasBlinding || updateAddBlinding):
return ErrInvalidPayload{
Type: record.EncryptedDataOnionType,
Violation: IncludedViolation,
FinalHop: isFinalHop,
}
// Hops that need forwarding info must include an amount to forward. // Hops that need forwarding info must include an amount to forward.
case needFwdInfo && !hasAmt: case needFwdInfo && !hasAmt:
return ErrInvalidPayload{ return ErrInvalidPayload{

View file

@ -26,6 +26,7 @@ type decodePayloadTest struct {
name string name string
payload []byte payload []byte
isFinalHop bool isFinalHop bool
updateAddBlinded bool
expErr error expErr error
expCustomRecords map[uint64][]byte expCustomRecords map[uint64][]byte
shouldHaveMPP bool shouldHaveMPP bool
@ -271,8 +272,9 @@ var decodePayloadTests = []decodePayloadTest{
}, },
}, },
{ {
name: "intermediate hop with encrypted data", name: "intermediate hop with encrypted data",
isFinalHop: false, isFinalHop: false,
updateAddBlinded: true,
payload: []byte{ payload: []byte{
// encrypted data // encrypted data
0x0a, 0x03, 0x03, 0x02, 0x01, 0x0a, 0x03, 0x03, 0x02, 0x01,
@ -365,8 +367,9 @@ var decodePayloadTests = []decodePayloadTest{
shouldHaveTotalAmt: true, shouldHaveTotalAmt: true,
}, },
{ {
name: "final blinded hop with total amount", name: "final blinded hop with total amount",
isFinalHop: true, isFinalHop: true,
updateAddBlinded: true,
payload: []byte{ payload: []byte{
// amount // amount
0x02, 0x00, 0x02, 0x00,
@ -378,8 +381,9 @@ var decodePayloadTests = []decodePayloadTest{
shouldHaveEncData: true, shouldHaveEncData: true,
}, },
{ {
name: "final blinded missing amt", name: "final blinded missing amt",
isFinalHop: true, isFinalHop: true,
updateAddBlinded: true,
payload: []byte{ payload: []byte{
// cltv // cltv
0x04, 0x00, 0x04, 0x00,
@ -394,8 +398,9 @@ var decodePayloadTests = []decodePayloadTest{
}, },
}, },
{ {
name: "final blinded missing cltv", name: "final blinded missing cltv",
isFinalHop: true, isFinalHop: true,
updateAddBlinded: true,
payload: []byte{ payload: []byte{
// amount // amount
0x02, 0x00, 0x02, 0x00,
@ -410,8 +415,9 @@ var decodePayloadTests = []decodePayloadTest{
}, },
}, },
{ {
name: "intermediate blinded has amount", name: "intermediate blinded has amount",
isFinalHop: false, isFinalHop: false,
updateAddBlinded: true,
payload: []byte{ payload: []byte{
// amount // amount
0x02, 0x00, 0x02, 0x00,
@ -425,8 +431,9 @@ var decodePayloadTests = []decodePayloadTest{
}, },
}, },
{ {
name: "intermediate blinded has expiry", name: "intermediate blinded has expiry",
isFinalHop: false, isFinalHop: false,
updateAddBlinded: true,
payload: []byte{ payload: []byte{
// cltv // cltv
0x04, 0x00, 0x04, 0x00,
@ -439,6 +446,67 @@ var decodePayloadTests = []decodePayloadTest{
FinalHop: false, FinalHop: false,
}, },
}, },
{
name: "update add blinding no data",
isFinalHop: false,
payload: []byte{
// cltv
0x04, 0x00,
},
updateAddBlinded: true,
expErr: hop.ErrInvalidPayload{
Type: record.EncryptedDataOnionType,
Violation: hop.OmittedViolation,
FinalHop: false,
},
},
{
name: "onion blinding point no data",
isFinalHop: false,
payload: append([]byte{
// blinding point (type / length)
0x0c, 0x21,
},
// blinding point (value)
testPubKey.SerializeCompressed()...,
),
expErr: hop.ErrInvalidPayload{
Type: record.EncryptedDataOnionType,
Violation: hop.OmittedViolation,
FinalHop: false,
},
},
{
name: "encrypted data no blinding",
isFinalHop: false,
payload: []byte{
// encrypted data
0x0a, 0x03, 0x03, 0x02, 0x01,
},
expErr: hop.ErrInvalidPayload{
Type: record.EncryptedDataOnionType,
Violation: hop.IncludedViolation,
},
},
{
name: "both blinding points",
isFinalHop: false,
updateAddBlinded: true,
payload: append([]byte{
// encrypted data
0x0a, 0x03, 0x03, 0x02, 0x01,
// blinding point (type / length)
0x0c, 0x21,
},
// blinding point (value)
testPubKey.SerializeCompressed()...,
),
expErr: hop.ErrInvalidPayload{
Type: record.BlindingPointOnionType,
Violation: hop.IncludedViolation,
FinalHop: false,
},
},
} }
// TestDecodeHopPayloadRecordValidation asserts that parsing the payloads in the // TestDecodeHopPayloadRecordValidation asserts that parsing the payloads in the
@ -479,8 +547,13 @@ func testDecodeHopPayloadValidation(t *testing.T, test decodePayloadTest) {
testChildIndex = uint32(9) testChildIndex = uint32(9)
) )
p, _, err := hop.NewPayloadFromReader( p, parsedTypes, err := hop.ParseTLVPayload(
bytes.NewReader(test.payload), test.isFinalHop, bytes.NewReader(test.payload),
)
require.NoError(t, err)
err = hop.ValidateTLVPayload(
parsedTypes, test.isFinalHop, test.updateAddBlinded,
) )
if !reflect.DeepEqual(test.expErr, err) { if !reflect.DeepEqual(test.expErr, err) {
t.Fatalf("expected error mismatch, want: %v, got: %v", t.Fatalf("expected error mismatch, want: %v, got: %v",

View file

@ -1793,8 +1793,20 @@ func (l *channelLink) handleDownstreamPkt(pkt *htlcPacket) {
htlc.ID = pkt.incomingHTLCID htlc.ID = pkt.incomingHTLCID
// We send the HTLC message to the peer which initially created // We send the HTLC message to the peer which initially created
// the HTLC. // the HTLC. If the incoming blinding point is non-nil, we
l.cfg.Peer.SendMessage(false, htlc) // know that we are a relaying node in a blinded path.
// Otherwise, we're either an introduction node or not part of
// a blinded path at all.
if err := l.sendIncomingHTLCFailureMsg(
htlc.ID,
pkt.obfuscator,
htlc.Reason,
); err != nil {
l.log.Errorf("unable to send HTLC failure: %v",
err)
return
}
// If the packet does not have a link failure set, it failed // If the packet does not have a link failure set, it failed
// further down the route so we notify a forwarding failure. // further down the route so we notify a forwarding failure.
@ -2030,6 +2042,19 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
failure = &lnwire.FailInvalidOnionKey{ failure = &lnwire.FailInvalidOnionKey{
OnionSHA256: msg.ShaOnionBlob, OnionSHA256: msg.ShaOnionBlob,
} }
// Handle malformed errors that are part of a blinded route.
// This case is slightly different, because we expect every
// relaying node in the blinded portion of the route to send
// malformed errors. If we're also a relaying node, we're
// likely going to switch this error out anyway for our own
// malformed error, but we handle the case here for
// completeness.
case lnwire.CodeInvalidBlinding:
failure = &lnwire.FailInvalidBlinding{
OnionSHA256: msg.ShaOnionBlob,
}
default: default:
l.log.Warnf("unexpected failure code received in "+ l.log.Warnf("unexpected failure code received in "+
"UpdateFailMailformedHTLC: %v", msg.FailureCode) "UpdateFailMailformedHTLC: %v", msg.FailureCode)
@ -3249,7 +3274,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
// DecodeHopIterator function which process the Sphinx packet. // DecodeHopIterator function which process the Sphinx packet.
chanIterator, failureCode := decodeResps[i].Result() chanIterator, failureCode := decodeResps[i].Result()
if failureCode != lnwire.CodeNone { if failureCode != lnwire.CodeNone {
// If we're unable to process the onion blob than we // If we're unable to process the onion blob then we
// should send the malformed htlc error to payment // should send the malformed htlc error to payment
// sender. // sender.
l.sendMalformedHTLCError(pd.HtlcIndex, failureCode, l.sendMalformedHTLCError(pd.HtlcIndex, failureCode,
@ -3260,37 +3285,50 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
continue continue
} }
// Retrieve onion obfuscator from onion blob in order to
// produce initial obfuscation of the onion failureCode.
obfuscator, failureCode := chanIterator.ExtractErrorEncrypter(
l.cfg.ExtractErrorEncrypter,
)
if failureCode != lnwire.CodeNone {
// If we're unable to process the onion blob than we
// should send the malformed htlc error to payment
// sender.
l.sendMalformedHTLCError(
pd.HtlcIndex, failureCode, onionBlob[:], pd.SourceRef,
)
l.log.Errorf("unable to decode onion "+
"obfuscator: %v", failureCode)
continue
}
heightNow := l.cfg.BestHeight() heightNow := l.cfg.BestHeight()
pld, err := chanIterator.HopPayload() pld, routeRole, pldErr := chanIterator.HopPayload()
if err != nil { if pldErr != nil {
// If we're unable to process the onion payload, or we // If we're unable to process the onion payload, or we
// received invalid onion payload failure, then we // received invalid onion payload failure, then we
// should send an error back to the caller so the HTLC // should send an error back to the caller so the HTLC
// can be canceled. // can be canceled.
var failedType uint64 var failedType uint64
if e, ok := err.(hop.ErrInvalidPayload); ok {
// We need to get the underlying error value, so we
// can't use errors.As as suggested by the linter.
//nolint:errorlint
if e, ok := pldErr.(hop.ErrInvalidPayload); ok {
failedType = uint64(e.Type) failedType = uint64(e.Type)
} }
// If we couldn't parse the payload, make our best
// effort at creating an error encrypter that knows
// what blinding type we were, but if we couldn't
// parse the payload we have no way of knowing whether
// we were the introduction node or not.
//
//nolint:lll
obfuscator, failCode := chanIterator.ExtractErrorEncrypter(
l.cfg.ExtractErrorEncrypter,
// We need our route role here because we
// couldn't parse or validate the payload.
routeRole == hop.RouteRoleIntroduction,
)
if failCode != lnwire.CodeNone {
l.log.Errorf("could not extract error "+
"encrypter: %v", pldErr)
// We can't process this htlc, send back
// malformed.
l.sendMalformedHTLCError(
pd.HtlcIndex, failureCode,
onionBlob[:], pd.SourceRef,
)
continue
}
// TODO: currently none of the test unit infrastructure // TODO: currently none of the test unit infrastructure
// is setup to handle TLV payloads, so testing this // is setup to handle TLV payloads, so testing this
// would require implementing a separate mock iterator // would require implementing a separate mock iterator
@ -3303,7 +3341,29 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
) )
l.log.Errorf("unable to decode forwarding "+ l.log.Errorf("unable to decode forwarding "+
"instructions: %v", err) "instructions: %v", pldErr)
continue
}
// Retrieve onion obfuscator from onion blob in order to
// produce initial obfuscation of the onion failureCode.
obfuscator, failureCode := chanIterator.ExtractErrorEncrypter(
l.cfg.ExtractErrorEncrypter,
routeRole == hop.RouteRoleIntroduction,
)
if failureCode != lnwire.CodeNone {
// If we're unable to process the onion blob than we
// should send the malformed htlc error to payment
// sender.
l.sendMalformedHTLCError(
pd.HtlcIndex, failureCode, onionBlob[:],
pd.SourceRef,
)
l.log.Errorf("unable to decode onion "+
"obfuscator: %v", failureCode)
continue continue
} }
@ -3672,11 +3732,14 @@ func (l *channelLink) sendHTLCError(pd *lnwallet.PaymentDescriptor,
return return
} }
l.cfg.Peer.SendMessage(false, &lnwire.UpdateFailHTLC{ // Send the appropriate failure message depending on whether we're
ChanID: l.ChanID(), // in a blinded route or not.
ID: pd.HtlcIndex, if err := l.sendIncomingHTLCFailureMsg(
Reason: reason, pd.HtlcIndex, e, reason,
}) ); err != nil {
l.log.Errorf("unable to send HTLC failure: %v", err)
return
}
// Notify a link failure on our incoming link. Outgoing htlc information // Notify a link failure on our incoming link. Outgoing htlc information
// is not available at this point, because we have not decrypted the // is not available at this point, because we have not decrypted the
@ -3705,6 +3768,95 @@ func (l *channelLink) sendHTLCError(pd *lnwallet.PaymentDescriptor,
) )
} }
// sendPeerHTLCFailure handles sending a HTLC failure message back to the
// peer from which the HTLC was received. This function is primarily used to
// handle the special requirements of route blinding, specifically:
// - Forwarding nodes must switch out any errors with MalformedFailHTLC
// - Introduction nodes should return regular HTLC failure messages.
//
// It accepts the original opaque failure, which will be used in the case
// that we're not part of a blinded route and an error encrypter that'll be
// used if we are the introduction node and need to present an error as if
// we're the failing party.
//
// Note: this function does not yet handle special error cases for receiving
// nodes in blinded paths, as LND does not support blinded receives.
func (l *channelLink) sendIncomingHTLCFailureMsg(htlcIndex uint64,
e hop.ErrorEncrypter,
originalFailure lnwire.OpaqueReason) error {
var msg lnwire.Message
switch {
// Our circuit's error encrypter will be nil if this was a locally
// initiated payment. We can only hit a blinded error for a locally
// initiated payment if we allow ourselves to be picked as the
// introduction node for our own payments and in that case we
// shouldn't reach this code. To prevent the HTLC getting stuck,
// we fail it back and log an error.
// code.
case e == nil:
msg = &lnwire.UpdateFailHTLC{
ChanID: l.ChanID(),
ID: htlcIndex,
Reason: originalFailure,
}
l.log.Errorf("Unexpected blinded failure when "+
"we are the sending node, incoming htlc: %v(%v)",
l.ShortChanID(), htlcIndex)
// For cleartext hops (ie, non-blinded/normal) we don't need any
// transformation on the error message and can just send the original.
case !e.Type().IsBlinded():
msg = &lnwire.UpdateFailHTLC{
ChanID: l.ChanID(),
ID: htlcIndex,
Reason: originalFailure,
}
// When we're the introduction node, we need to convert the error to
// a UpdateFailHTLC.
case e.Type() == hop.EncrypterTypeIntroduction:
l.log.Debugf("Introduction blinded node switching out failure "+
"error: %v", htlcIndex)
// The specification does not require that we set the onion
// blob.
failureMsg := lnwire.NewInvalidBlinding(nil)
reason, err := e.EncryptFirstHop(failureMsg)
if err != nil {
return err
}
msg = &lnwire.UpdateFailHTLC{
ChanID: l.ChanID(),
ID: htlcIndex,
Reason: reason,
}
// If we are a relaying node, we need to switch out any error that
// we've received to a malformed HTLC error.
case e.Type() == hop.EncrypterTypeRelaying:
l.log.Debugf("Relaying blinded node switching out malformed "+
"error: %v", htlcIndex)
msg = &lnwire.UpdateFailMalformedHTLC{
ChanID: l.ChanID(),
ID: htlcIndex,
FailureCode: lnwire.CodeInvalidBlinding,
}
default:
return fmt.Errorf("unexpected encrypter: %d", e)
}
if err := l.cfg.Peer.SendMessage(false, msg); err != nil {
l.log.Warnf("Send update fail failed: %v", err)
}
return nil
}
// sendMalformedHTLCError helper function which sends the malformed HTLC update // sendMalformedHTLCError helper function which sends the malformed HTLC update
// to the payment sender. // to the payment sender.
func (l *channelLink) sendMalformedHTLCError(htlcIndex uint64, func (l *channelLink) sendMalformedHTLCError(htlcIndex uint64,

View file

@ -738,6 +738,7 @@ func (m *memoryMailBox) FailAdd(pkt *htlcPacket) {
sourceRef: pkt.sourceRef, sourceRef: pkt.sourceRef,
hasSource: true, hasSource: true,
localFailure: localFailure, localFailure: localFailure,
obfuscator: pkt.obfuscator,
linkFailure: linkError, linkFailure: linkError,
htlc: &lnwire.UpdateFailHTLC{ htlc: &lnwire.UpdateFailHTLC{
Reason: reason, Reason: reason,

View file

@ -330,10 +330,10 @@ func newMockHopIterator(hops ...*hop.Payload) hop.Iterator {
return &mockHopIterator{hops: hops} return &mockHopIterator{hops: hops}
} }
func (r *mockHopIterator) HopPayload() (*hop.Payload, error) { func (r *mockHopIterator) HopPayload() (*hop.Payload, hop.RouteRole, error) {
h := r.hops[0] h := r.hops[0]
r.hops = r.hops[1:] r.hops = r.hops[1:]
return h, nil return h, hop.RouteRoleCleartext, nil
} }
func (r *mockHopIterator) ExtraOnionBlob() []byte { func (r *mockHopIterator) ExtraOnionBlob() []byte {
@ -341,7 +341,7 @@ func (r *mockHopIterator) ExtraOnionBlob() []byte {
} }
func (r *mockHopIterator) ExtractErrorEncrypter( func (r *mockHopIterator) ExtractErrorEncrypter(
extracter hop.ErrorEncrypterExtracter) (hop.ErrorEncrypter, extracter hop.ErrorEncrypterExtracter, _ bool) (hop.ErrorEncrypter,
lnwire.FailCode) { lnwire.FailCode) {
return extracter(nil) return extracter(nil)

View file

@ -1297,6 +1297,11 @@ func (s *Switch) handlePacketForward(packet *htlcPacket) error {
fail, isFail := htlc.(*lnwire.UpdateFailHTLC) fail, isFail := htlc.(*lnwire.UpdateFailHTLC)
if isFail && !packet.hasSource { if isFail && !packet.hasSource {
// HTLC resolutions and messages restored from disk
// don't have the obfuscator set from the original htlc
// add packet - set it here for use in blinded errors.
packet.obfuscator = circuit.ErrorEncrypter
switch { switch {
// No message to encrypt, locally sourced payment. // No message to encrypt, locally sourced payment.
case circuit.ErrorEncrypter == nil: case circuit.ErrorEncrypter == nil:
@ -1485,6 +1490,7 @@ func (s *Switch) failAddPacket(packet *htlcPacket, failure *LinkError) error {
incomingTimeout: packet.incomingTimeout, incomingTimeout: packet.incomingTimeout,
outgoingTimeout: packet.outgoingTimeout, outgoingTimeout: packet.outgoingTimeout,
circuit: packet.circuit, circuit: packet.circuit,
obfuscator: packet.obfuscator,
linkFailure: failure, linkFailure: failure,
htlc: &lnwire.UpdateFailHTLC{ htlc: &lnwire.UpdateFailHTLC{
Reason: reason, Reason: reason,
@ -1841,6 +1847,10 @@ out:
// resolution message on restart. // resolution message on restart.
resolutionMsg.errChan <- nil resolutionMsg.errChan <- nil
// Create a htlc packet for this resolution. We do
// not have some of the information that we'll need
// for blinded error handling here , so we'll rely on
// our forwarding logic to fill it in later.
pkt := &htlcPacket{ pkt := &htlcPacket{
outgoingChanID: resolutionMsg.SourceChan, outgoingChanID: resolutionMsg.SourceChan,
outgoingHTLCID: resolutionMsg.HtlcIndex, outgoingHTLCID: resolutionMsg.HtlcIndex,
@ -2065,6 +2075,8 @@ func (s *Switch) reforwardResolutions() error {
// The circuit is still open, so we can assume that the link or // The circuit is still open, so we can assume that the link or
// switch (if we are the source) hasn't cleaned it up yet. // switch (if we are the source) hasn't cleaned it up yet.
// We rely on our forwarding logic to fill in details that
// are not currently available to us.
resPkt := &htlcPacket{ resPkt := &htlcPacket{
outgoingChanID: resMsg.SourceChan, outgoingChanID: resMsg.SourceChan,
outgoingHTLCID: resMsg.HtlcIndex, outgoingHTLCID: resMsg.HtlcIndex,
@ -2214,7 +2226,8 @@ func (s *Switch) reforwardSettleFails(fwdPkgs []*channeldb.FwdPkg) {
// we can continue to propagate it. This // we can continue to propagate it. This
// failure originated from another node, so // failure originated from another node, so
// the linkFailure field is not set on this // the linkFailure field is not set on this
// packet. // packet. We rely on the link to fill in
// additional circuit information for us.
failPacket := &htlcPacket{ failPacket := &htlcPacket{
outgoingChanID: fwdPkg.Source, outgoingChanID: fwdPkg.Source,
outgoingHTLCID: pd.ParentIndex, outgoingHTLCID: pd.ParentIndex,

View file

@ -566,6 +566,26 @@ var allTestCases = []*lntest.TestCase{
Name: "forward blinded", Name: "forward blinded",
TestFunc: testForwardBlindedRoute, TestFunc: testForwardBlindedRoute,
}, },
{
Name: "receiver blinded error",
TestFunc: testReceiverBlindedError,
},
{
Name: "relayer blinded error",
TestFunc: testRelayingBlindedError,
},
{
Name: "introduction blinded error",
TestFunc: testIntroductionNodeError,
},
{
Name: "disable introduction node",
TestFunc: testDisableIntroductionNode,
},
{
Name: "on chain to blinded",
TestFunc: testErrorHandlingOnChainFailure,
},
{ {
Name: "removetx", Name: "removetx",
TestFunc: testRemoveTx, TestFunc: testRemoveTx,

View file

@ -355,14 +355,16 @@ func (b *blindedForwardTest) setup(
ctx context.Context) *routing.BlindedPayment { ctx context.Context) *routing.BlindedPayment {
b.carol = b.ht.NewNode("Carol", []string{ b.carol = b.ht.NewNode("Carol", []string{
"requireinterceptor", "--requireinterceptor", "--bitcoin.timelockdelta=18",
}) })
var err error var err error
b.carolInterceptor, err = b.carol.RPC.Router.HtlcInterceptor(ctx) b.carolInterceptor, err = b.carol.RPC.Router.HtlcInterceptor(ctx)
require.NoError(b.ht, err, "interceptor") require.NoError(b.ht, err, "interceptor")
b.dave = b.ht.NewNode("Dave", nil) b.dave = b.ht.NewNode("Dave", []string{
"--bitcoin.timelockdelta=18",
})
b.channels = setupFourHopNetwork(b.ht, b.carol, b.dave) b.channels = setupFourHopNetwork(b.ht, b.carol, b.dave)
@ -448,9 +450,11 @@ func (b *blindedForwardTest) createRouteToBlinded(paymentAmt int64,
return resp.Routes[0] return resp.Routes[0]
} }
// sendBlindedPayment dispatches a payment to the route provided. // sendBlindedPayment dispatches a payment to the route provided, returning a
// cancel function for the payment. Timeout is set for very long to allow
// time for on-chain resolution.
func (b *blindedForwardTest) sendBlindedPayment(ctx context.Context, func (b *blindedForwardTest) sendBlindedPayment(ctx context.Context,
route *lnrpc.Route) { route *lnrpc.Route) func() {
hash := sha256.Sum256(b.preimage[:]) hash := sha256.Sum256(b.preimage[:])
sendReq := &routerrpc.SendToRouteRequest{ sendReq := &routerrpc.SendToRouteRequest{
@ -458,11 +462,13 @@ func (b *blindedForwardTest) sendBlindedPayment(ctx context.Context,
Route: route, Route: route,
} }
// Dispatch in a goroutine because this call is blocking - we assume ctx, cancel := context.WithTimeout(ctx, time.Hour)
// that we'll have assertions that this payment is sent by the caller.
go func() { go func() {
b.ht.Alice.RPC.SendToRouteV2(sendReq) _, err := b.ht.Alice.RPC.Router.SendToRouteV2(ctx, sendReq)
require.NoError(b.ht, err)
}() }()
return cancel
} }
// interceptFinalHop launches a goroutine to intercept Carol's htlcs and // interceptFinalHop launches a goroutine to intercept Carol's htlcs and
@ -524,6 +530,43 @@ func (b *blindedForwardTest) interceptFinalHop() func(routerrpc.ResolveHoldForwa
return resolve return resolve
} }
// drainCarolLiquidity will drain all of the liquidity in Carol's channel in
// the direction requested:
// - incoming: Carol has no incoming liquidity from Bob
// - outgoing: Carol has no outgoing liquidity to Dave.
func (b *blindedForwardTest) drainCarolLiquidity(incoming bool) {
sendingNode := b.carol
receivingNode := b.dave
if incoming {
sendingNode = b.ht.Bob
receivingNode = b.carol
}
resp := sendingNode.RPC.ListChannels(&lnrpc.ListChannelsRequest{
Peer: receivingNode.PubKey[:],
})
require.Len(b.ht, resp.Channels, 1)
// We can't send our channel reserve, and leave some buffer for fees.
paymentAmt := resp.Channels[0].LocalBalance -
int64(resp.Channels[0].RemoteConstraints.ChanReserveSat) - 25000
invoice := receivingNode.RPC.AddInvoice(&lnrpc.Invoice{
// Leave some leeway for fees for the HTLC.
Value: paymentAmt,
})
pmtClient := sendingNode.RPC.SendPayment(
&routerrpc.SendPaymentRequest{
PaymentRequest: invoice.PaymentRequest,
TimeoutSeconds: 60,
},
)
b.ht.AssertPaymentStatusFromStream(pmtClient, lnrpc.Payment_SUCCEEDED)
}
// setupFourHopNetwork creates a network with the following topology and // setupFourHopNetwork creates a network with the following topology and
// liquidity: // liquidity:
// Alice (100k)----- Bob (100k) ----- Carol (100k) ----- Dave // Alice (100k)----- Bob (100k) ----- Carol (100k) ----- Dave
@ -768,7 +811,8 @@ func testForwardBlindedRoute(ht *lntest.HarnessTest) {
resolveHTLC := testCase.interceptFinalHop() resolveHTLC := testCase.interceptFinalHop()
// Once our interceptor is set up, we can send the blinded payment. // Once our interceptor is set up, we can send the blinded payment.
testCase.sendBlindedPayment(ctx, blindedRoute) cancelPmt := testCase.sendBlindedPayment(ctx, blindedRoute)
defer cancelPmt()
// Wait for the HTLC to be active on Alice's channel. // Wait for the HTLC to be active on Alice's channel.
hash := sha256.Sum256(testCase.preimage[:]) hash := sha256.Sum256(testCase.preimage[:])
@ -788,3 +832,227 @@ func testForwardBlindedRoute(ht *lntest.HarnessTest) {
ht.AssertHTLCNotActive(ht.Bob, testCase.channels[1], hash[:]) ht.AssertHTLCNotActive(ht.Bob, testCase.channels[1], hash[:])
ht.AssertHTLCNotActive(ht.Alice, testCase.channels[0], hash[:]) ht.AssertHTLCNotActive(ht.Alice, testCase.channels[0], hash[:])
} }
// Tests handling of errors from the receiving node in a blinded route, testing
// a payment over: Alice -- Bob -- Carol -- Dave, where Bob is the introduction
// node.
//
// Note that at present the payment fails at Dave because we do not yet support
// receiving to blinded routes. In future, we can substitute this test out to
// trigger an IncorrectPaymentDetails failure. In the meantime, this test
// provides valuable coverage for the case where a node in the route is not
// spec compliant (ie, does not return the blinded failure and just uses a
// normal one) because Dave will not appropriately convert the error.
func testReceiverBlindedError(ht *lntest.HarnessTest) {
ctx, testCase := newBlindedForwardTest(ht)
defer testCase.cleanup()
route := testCase.setup(ctx)
sendAndResumeBlindedPayment(ctx, ht, testCase, route, true)
}
// testRelayingBlindedError tests handling of errors from relaying nodes in a
// blinded route, testing a failure over on Carol's outgoing link in the
// following topology: Alice -- Bob -- Carol -- Dave, where Bob is the
// introduction node.
func testRelayingBlindedError(ht *lntest.HarnessTest) {
ctx, testCase := newBlindedForwardTest(ht)
defer testCase.cleanup()
route := testCase.setup(ctx)
// Before we send our payment, drain all of Carol's liquidity
// so that she can't forward the payment to Dave.
testCase.drainCarolLiquidity(false)
// Then dispatch the payment through Carol which will fail due to
// a lack of liquidity. This check only happens _after_ the interceptor
// has given the instruction to resume so we can use test
// infrastructure that will go ahead and intercept the payment.
sendAndResumeBlindedPayment(ctx, ht, testCase, route, true)
}
// sendAndResumeBlindedPayment sends a blinded payment through the test
// network provided, intercepting the payment at Carol and allowing it to
// resume. This utility function allows us to ensure that payments at least
// reach Carol and asserts that all errors appear to originate from the
// introduction node.
func sendAndResumeBlindedPayment(ctx context.Context, ht *lntest.HarnessTest,
testCase *blindedForwardTest, route *routing.BlindedPayment,
interceptAtCarol bool) {
blindedRoute := testCase.createRouteToBlinded(10_000_000, route)
// Before we dispatch the payment, spin up a goroutine that will
// intercept the HTLC on Carol's forward. This allows us to ensure
// that the HTLC actually reaches the location we expect it to.
var resolveHTLC func(routerrpc.ResolveHoldForwardAction)
if interceptAtCarol {
resolveHTLC = testCase.interceptFinalHop()
}
// First, test sending the payment all the way through to Dave. We
// expect this payment to fail, because he does not know how to
// process payments to a blinded route (not yet supported).
cancelPmt := testCase.sendBlindedPayment(ctx, blindedRoute)
defer cancelPmt()
// When Carol intercepts the HTLC, instruct her to resume the payment
// so that it'll reach Dave and fail.
if interceptAtCarol {
resolveHTLC(routerrpc.ResolveHoldForwardAction_RESUME)
}
// Wait for the HTLC to reflect as failed for Alice.
preimage, err := lntypes.MakePreimage(testCase.preimage[:])
require.NoError(ht, err)
pmt := ht.AssertPaymentStatus(ht.Alice, preimage, lnrpc.Payment_FAILED)
require.Len(ht, pmt.Htlcs, 1)
require.EqualValues(
ht, 1, pmt.Htlcs[0].Failure.FailureSourceIndex,
)
require.Equal(
ht, lnrpc.Failure_INVALID_ONION_BLINDING,
pmt.Htlcs[0].Failure.Code,
)
}
// testIntroductionNodeError tests handling of errors in a blinded route when
// the introduction node is the source of the error. This test sends a payment
// over Alice -- Bob -- Carol -- Dave, where Bob is the introduction node and
// has insufficient outgoing liquidity to forward on to carol.
func testIntroductionNodeError(ht *lntest.HarnessTest) {
ctx, testCase := newBlindedForwardTest(ht)
defer testCase.cleanup()
route := testCase.setup(ctx)
// Before we send our payment, drain all of Carol's incoming liquidity
// so that she can't receive the forward from Bob, causing a failure
// at the introduction node.
testCase.drainCarolLiquidity(true)
// Send the payment, but do not expect it to reach Carol at all.
sendAndResumeBlindedPayment(ctx, ht, testCase, route, false)
}
// testDisableIntroductionNode tests disabling of blinded forwards for the
// introduction node.
func testDisableIntroductionNode(ht *lntest.HarnessTest) {
// Disable route blinding for Bob, then re-connect to Alice.
ht.RestartNodeWithExtraArgs(ht.Bob, []string{
"--protocol.no-route-blinding",
})
ht.EnsureConnected(ht.Alice, ht.Bob)
ctx, testCase := newBlindedForwardTest(ht)
defer testCase.cleanup()
route := testCase.setup(ctx)
// We always expect failures to look like they originated at Bob
// because blinded errors are converted. However, our tests intercepts
// all of Carol's forwards and we're not providing it any interceptor
// instructions. This means that the test will hang/timeout at Carol
// if Bob _doesn't_ fail the HTLC back as expected.
sendAndResumeBlindedPayment(ctx, ht, testCase, route, false)
}
// testErrorHandlingOnChainFailure tests handling of blinded errors when we're
// resolving from an on-chain resolution. This test also tests that we're able
// to resolve blinded HTLCs on chain between restarts, as we've got all the
// infrastructure in place already for error testing.
func testErrorHandlingOnChainFailure(ht *lntest.HarnessTest) {
// Setup a test case, note that we don't use its built in clean up
// because we're going to close a channel so we'll close out the
// rest manually.
ctx, testCase := newBlindedForwardTest(ht)
// Note that we send a larger amount here do it'll be worthwhile for
// the sweeper to claim.
route := testCase.setup(ctx)
blindedRoute := testCase.createRouteToBlinded(50_000_000, route)
// Once our interceptor is set up, we can send the blinded payment.
cancelPmt := testCase.sendBlindedPayment(ctx, blindedRoute)
defer cancelPmt()
// Wait for the HTLC to be active on Alice and Bob's channels.
hash := sha256.Sum256(testCase.preimage[:])
ht.AssertOutgoingHTLCActive(ht.Alice, testCase.channels[0], hash[:])
ht.AssertOutgoingHTLCActive(ht.Bob, testCase.channels[1], hash[:])
// Intercept the forward on Carol's link, but do not take any action
// so that we have the chance to force close with this HTLC in flight.
carolHTLC, err := testCase.carolInterceptor.Recv()
require.NoError(ht, err)
// Force close Bob <-> Carol.
closeStream, _ := ht.CloseChannelAssertPending(
ht.Bob, testCase.channels[1], true,
)
ht.AssertStreamChannelForceClosed(
ht.Bob, testCase.channels[1], false, closeStream,
)
// SuspendCarol so that she can't interfere with the resolution of the
// HTLC from now on.
restartCarol := ht.SuspendNode(testCase.carol)
// Mine blocks so that Bob will claim his CSV delayed local commitment,
// we've already mined 1 block so we need one less than our CSV.
ht.MineBlocks(node.DefaultCSV - 1)
ht.AssertNumPendingSweeps(ht.Bob, 1)
ht.MineEmptyBlocks(1)
ht.Miner.MineBlocksAndAssertNumTxes(1, 1)
// Restart bob so that we can test that he's able to recover everything
// he needs to claim a blinded HTLC.
ht.RestartNode(ht.Bob)
// Mine enough blocks for Bob to trigger timeout of his outgoing HTLC.
// Carol's incoming expiry height is Bob's outgoing so we can use this
// value.
info := ht.Bob.RPC.GetInfo()
target := carolHTLC.IncomingExpiry - info.BlockHeight
ht.MineBlocks(target)
// Wait for Bob's timeout transaction in the mempool, since we've
// suspended Carol we don't need to account for her commitment output
// claim.
ht.Miner.MineBlocksAndAssertNumTxes(1, 1)
// Assert that the HTLC has cleared.
ht.AssertHTLCNotActive(ht.Alice, testCase.channels[0], hash[:])
ht.AssertHTLCNotActive(ht.Bob, testCase.channels[0], hash[:])
// Wait for the HTLC to reflect as failed for Alice.
paymentStream := ht.Alice.RPC.TrackPaymentV2(hash[:])
htlcs := ht.ReceiveTrackPayment(paymentStream).Htlcs
require.Len(ht, htlcs, 1)
require.NotNil(ht, htlcs[0].Failure)
require.Equal(
ht, htlcs[0].Failure.Code,
lnrpc.Failure_INVALID_ONION_BLINDING,
)
// Clean up the rest of our force close: mine blocks so that Bob's CSV
// expires plus one block to trigger his sweep and then mine it.
ht.MineBlocks(node.DefaultCSV + 1)
ht.Miner.MineBlocksAndAssertNumTxes(1, 1)
// Bring carol back up so that we can close out the rest of our
// channels cooperatively. She requires an interceptor to start up
// so we just re-register our interceptor.
require.NoError(ht, restartCarol())
_, err = testCase.carol.RPC.Router.HtlcInterceptor(ctx)
require.NoError(ht, err, "interceptor")
// Assert that Carol has started up and reconnected to dave so that
// we can close out channels cooperatively.
ht.EnsureConnected(testCase.carol, testCase.dave)
// Manually close out the rest of our channels and cancel (don't use
// built in cleanup which will try close the already-force-closed
// channel).
ht.CloseChannel(ht.Alice, testCase.channels[0])
ht.CloseChannel(testCase.carol, testCase.channels[2])
testCase.cancel()
}

View file

@ -59,14 +59,6 @@ type ProtocolOptions struct {
NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"` NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"`
} }
// DefaultProtocol returns a protocol config with route blinding turned off,
// temporarily in place until full handling of blinded route errors is merged.
func DefaultProtocol() *ProtocolOptions {
return &ProtocolOptions{
NoRouteBlindingOption: true,
}
}
// Wumbo returns true if lnd should permit the creation and acceptance of wumbo // Wumbo returns true if lnd should permit the creation and acceptance of wumbo
// channels. // channels.
func (l *ProtocolOptions) Wumbo() bool { func (l *ProtocolOptions) Wumbo() bool {

View file

@ -62,13 +62,6 @@ type ProtocolOptions struct {
NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"` NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"`
} }
// DefaultProtocol returns a protocol config with route blinding turned on,
// so that itests can run against route blinding features even while we've
// got it turned off for the daemon (pending completion of error handling).
func DefaultProtocol() *ProtocolOptions {
return &ProtocolOptions{}
}
// Wumbo returns true if lnd should permit the creation and acceptance of wumbo // Wumbo returns true if lnd should permit the creation and acceptance of wumbo
// channels. // channels.
func (l *ProtocolOptions) Wumbo() bool { func (l *ProtocolOptions) Wumbo() bool {

View file

@ -651,6 +651,8 @@ const (
FeatureBit_ANCHORS_OPT FeatureBit = 21 FeatureBit_ANCHORS_OPT FeatureBit = 21
FeatureBit_ANCHORS_ZERO_FEE_HTLC_REQ FeatureBit = 22 FeatureBit_ANCHORS_ZERO_FEE_HTLC_REQ FeatureBit = 22
FeatureBit_ANCHORS_ZERO_FEE_HTLC_OPT FeatureBit = 23 FeatureBit_ANCHORS_ZERO_FEE_HTLC_OPT FeatureBit = 23
FeatureBit_ROUTE_BLINDING_REQUIRED FeatureBit = 24
FeatureBit_ROUTE_BLINDING_OPTIONAL FeatureBit = 25
FeatureBit_AMP_REQ FeatureBit = 30 FeatureBit_AMP_REQ FeatureBit = 30
FeatureBit_AMP_OPT FeatureBit = 31 FeatureBit_AMP_OPT FeatureBit = 31
) )
@ -681,6 +683,8 @@ var (
21: "ANCHORS_OPT", 21: "ANCHORS_OPT",
22: "ANCHORS_ZERO_FEE_HTLC_REQ", 22: "ANCHORS_ZERO_FEE_HTLC_REQ",
23: "ANCHORS_ZERO_FEE_HTLC_OPT", 23: "ANCHORS_ZERO_FEE_HTLC_OPT",
24: "ROUTE_BLINDING_REQUIRED",
25: "ROUTE_BLINDING_OPTIONAL",
30: "AMP_REQ", 30: "AMP_REQ",
31: "AMP_OPT", 31: "AMP_OPT",
} }
@ -708,6 +712,8 @@ var (
"ANCHORS_OPT": 21, "ANCHORS_OPT": 21,
"ANCHORS_ZERO_FEE_HTLC_REQ": 22, "ANCHORS_ZERO_FEE_HTLC_REQ": 22,
"ANCHORS_ZERO_FEE_HTLC_OPT": 23, "ANCHORS_ZERO_FEE_HTLC_OPT": 23,
"ROUTE_BLINDING_REQUIRED": 24,
"ROUTE_BLINDING_OPTIONAL": 25,
"AMP_REQ": 30, "AMP_REQ": 30,
"AMP_OPT": 31, "AMP_OPT": 31,
} }
@ -20669,7 +20675,7 @@ var file_lightning_proto_rawDesc = []byte{
0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x10, 0x04, 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, 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, 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, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x05, 0x2a, 0x89, 0x05, 0x0a, 0x0a, 0x46, 0x65,
0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x41, 0x54, 0x41, 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, 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, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x53, 0x53, 0x5f, 0x50,
@ -20705,338 +20711,342 @@ var file_lightning_proto_rawDesc = []byte{
0x45, 0x52, 0x4f, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x52, 0x45, 0x51, 0x45, 0x52, 0x4f, 0x5f, 0x46, 0x45, 0x45, 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, 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, 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, 0x17, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x42, 0x4c, 0x49, 0x4e, 0x44,
0x0a, 0x07, 0x41, 0x4d, 0x50, 0x5f, 0x4f, 0x50, 0x54, 0x10, 0x1f, 0x2a, 0xac, 0x01, 0x0a, 0x0d, 0x49, 0x4e, 0x47, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x18, 0x12, 0x1b,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x0a, 0x17, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x42, 0x4c, 0x49, 0x4e, 0x44, 0x49, 0x4e, 0x47,
0x16, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x19, 0x12, 0x0b, 0x0a, 0x07, 0x41,
0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x55, 0x50, 0x44, 0x4d, 0x50, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x1e, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4d, 0x50, 0x5f,
0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x4f, 0x50, 0x54, 0x10, 0x1f, 0x2a, 0xac, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x55, 0x50, 0x44, 0x41, 0x54,
0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
0x44, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x4e, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41,
0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12,
0x52, 0x52, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x1c, 0x0a, 0x18, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52,
0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x1f, 0x0a,
0x41, 0x52, 0x41, 0x4d, 0x45, 0x54, 0x45, 0x52, 0x10, 0x04, 0x32, 0xb9, 0x27, 0x0a, 0x09, 0x4c, 0x1b, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f,
0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x4a, 0x0a, 0x0d, 0x57, 0x61, 0x6c, 0x6c, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x03, 0x12, 0x24,
0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x0a, 0x20, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45,
0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x45, 0x54,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x45, 0x52, 0x10, 0x04, 0x32, 0xb9, 0x27, 0x0a, 0x09, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6e, 0x67, 0x12, 0x4a, 0x0a, 0x0d, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c,
0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x42,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d,
0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d,
0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a,
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x12, 0x44, 0x0a, 0x0b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x12, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e,
0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x46, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
0x70, 0x63, 0x2e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x44, 0x0a, 0x0b, 0x45, 0x73,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70,
0x69, 0x6e, 0x73, 0x12, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x63, 0x2e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x71,
0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x73, 0x74,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x12, 0x3e, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x12, 0x17, 0x2e,
0x73, 0x70, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52,
0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53,
0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x15, 0x12, 0x44, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x12,
0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72,
0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x53, 0x65, 0x69, 0x62, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x79, 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x79, 0x52, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x6f, 0x6e, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x79,
0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e,
0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x6e, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x53, 0x69, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12,
0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65,
0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73,
0x12, 0x4a, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x61, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e,
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, 0x1a,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0d, 0x56, 0x65,
0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x2e, 0x6c, 0x6e,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f,
0x50, 0x65, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0e,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1c,
0x65, 0x12, 0x3e, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50,
0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x4c,
0x65, 0x12, 0x47, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x65, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x2e, 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65,
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x10, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x13, 0x53,
0x65, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e,
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x45,
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x1a, 0x10, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, 0x65,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x15, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52,
0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47,
0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47,
0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a,
0x0f, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49,
0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72,
0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52,
0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x65,
0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72,
0x50, 0x0a, 0x0f, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e,
0x6c, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70,
0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66,
0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x50, 0x65, 0x6e,
0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1d, 0x2e, 0x6c,
0x65, 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e,
0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e,
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x4c,
0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x16, 0x53, 0x75, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e,
0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73,
0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62,
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f,
0x30, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x76,
0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a,
0x73, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45,
0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x0e,
0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1c,
0x65, 0x12, 0x41, 0x0a, 0x0f, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x68, 0x61,
0x53, 0x79, 0x6e, 0x63, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c,
0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e,
0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0f, 0x4f,
0x6f, 0x69, 0x6e, 0x74, 0x12, 0x43, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x19,
0x6e, 0x65, 0x6c, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e,
0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x43,
0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x53, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x19, 0x2e,
0x63, 0x68, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x30, 0x01, 0x12, 0x53, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x70, 0x65, 0x6e,
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x0a, 0x10, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
0x65, 0x70, 0x12, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x67, 0x1a, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x10, 0x46, 0x75, 0x6e, 0x64,
0x74, 0x61, 0x74, 0x65, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x12, 0x50, 0x0a, 0x0f, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x1b, 0x2e, 0x6c,
0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e,
0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x67, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70,
0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1b, 0x2e, 0x63, 0x2e, 0x46, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x74,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x12, 0x50, 0x0a, 0x0f, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, 0x12, 0x46, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70,
0x0a, 0x0c, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1a, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71,
0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x75, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, 0x12, 0x46, 0x0a, 0x0c, 0x43, 0x6c, 0x6f, 0x73,
0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71,
0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01,
0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x0e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x65, 0x6c, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64,
0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e,
0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x02, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x3a, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x3f, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12,
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65,
0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x28, 0x01, 0x30, 0x01,
0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x12, 0x3a, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53,
0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x79, 0x6e, 0x63, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64,
0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b,
0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x6e,
0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01,
0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x28, 0x01, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f,
0x0a, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x0e, 0x2e, 0x6c, 0x6e, 0x75, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x49, 0x6e,
0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e,
0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64,
0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x76, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x12, 0x45, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73,
0x0d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x12, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x6f, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e,
0x73, 0x68, 0x1a, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x52,
0x63, 0x65, 0x12, 0x41, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x49, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75,
0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x0e, 0x2e, 0x6c,
0x69, 0x6f, 0x6e, 0x1a, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x11,
0x69, 0x63, 0x65, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x0c, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65,
0x61, 0x79, 0x52, 0x65, 0x71, 0x12, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63,
0x79, 0x52, 0x65, 0x71, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x1a, 0x0d, 0x2e, 0x6c, 0x6e, 0x72, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x0e, 0x2e,
0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x52, 0x65, 0x71, 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x30, 0x01, 0x12,
0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x32, 0x0a, 0x0c, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x79, 0x52, 0x65, 0x71, 0x12,
0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x52, 0x65, 0x71, 0x53, 0x74,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x1a, 0x0d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79,
0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x47, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65,
0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x6e, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d,
0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0d,
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e,
0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d,
0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72,
0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65,
0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x50,
0x62, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c,
0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x47, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4e, 0x12, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x47, 0x72, 0x61, 0x70,
0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x68, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61,
0x64, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x70, 0x68, 0x12, 0x47, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74,
0x65, 0x12, 0x39, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x69, 0x63, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64,
0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x72,
0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x47,
0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72,
0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x75, 0x65, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64,
0x74, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f,
0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44,
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x47, 0x65, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x19, 0x2e,
0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x6c, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x35, 0x0a, 0x0a, 0x53, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f,
0x74, 0x6f, 0x70, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e,
0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
0x73, 0x65, 0x12, 0x57, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x35, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x70, 0x44, 0x61, 0x65,
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x20, 0x2e, 0x6c, 0x6e, 0x6d, 0x6f, 0x6e, 0x12, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x6f, 0x70,
0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x79, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1a, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x15,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
0x6f, 0x67, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x72,
0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x61, 0x70, 0x68, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x75, 0x62, 0x73, 0x63,
0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x47, 0x72, 0x61, 0x70, 0x68, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x55, 0x70, 0x64,
0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65,
0x0a, 0x09, 0x46, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x6e, 0x76, 0x65, 0x6c, 0x12, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75,
0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x65, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c,
0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x46, 0x65, 0x65, 0x52,
0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65,
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74,
0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12,
0x0a, 0x11, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70,
0x6f, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x77, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e,
0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x46, 0x6f, 0x72, 0x77,
0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x2e,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67,
0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x21, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e,
0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x67, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x1a, 0x14, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x4e, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x54, 0x0a, 0x17, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x21, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x41, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63,
0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x6e, 0x72,
0x63, 0x6b, 0x75, 0x70, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70,
0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x12, 0x54, 0x0a, 0x17, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x68, 0x61,
0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x4e, 0x0a, 0x10, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x6e,
0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x78,
0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6e,
0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e,
0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x4e, 0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79,
0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x15, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72,
0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61,
0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65,
0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72,
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, 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, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43,
0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x6e, 0x1a, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x1a, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65,
0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x30, 0x01, 0x12, 0x47, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58,
0x0a, 0x0c, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70,
0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53,
0x70, 0x63, 0x2e, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x19, 0x2e, 0x6c, 0x6e,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x6e,
0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x30, 0x01, 0x12, 0x47, 0x0a, 0x0c, 0x42, 0x61, 0x6b, 0x65,
0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x2e, 0x42, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x71,
0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6b,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1e, 0x2e, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x6e, 0x49, 0x44, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73,
0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63,
0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44,
0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x49, 0x44,
0x12, 0x53, 0x0a, 0x18, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74,
0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x6e,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4d, 0x61, 0x63, 0x50, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69,
0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6e, 0x72,
0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4d, 0x61, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x18, 0x43, 0x68,
0x72, 0x52, 0x50, 0x43, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x12, 0x1c, 0x65, 0x63, 0x6b, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43,
0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1b, 0x2e, 0x6c, 0x68, 0x65, 0x63, 0x6b, 0x4d, 0x61, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b,
0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, 0x12, 0x56, 0x0a, 0x4d, 0x61, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x11, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x56, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x50, 0x43, 0x4d, 0x69,
0x67, 0x65, 0x12, 0x1f, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x2e, 0x52, 0x50, 0x43, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65,
0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1b, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x52,
0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x50, 0x43, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, 0x12, 0x56, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x43,
0x62, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x2e, 0x6c,
0x12, 0x25, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d,
0x62, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x30, 0x01, 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x44, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x19, 0x58, 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x75, 0x73, 0x74,
0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x6c, 0x6e, 0x72,
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x75, 0x73, 0x74,
0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x14, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x48, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
0x74, 0x6c, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x0b, 0x4c, 0x69, 0x73,
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x48, 0x74, 0x6c, 0x63, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63,
0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
0x74, 0x1a, 0x23, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x48, 0x74, 0x6c, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x0a, 0x14, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x48, 0x74, 0x6c, 0x63, 0x52, 0x65, 0x73,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x48, 0x74, 0x6c, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6c, 0x6e,
0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x48, 0x74, 0x6c, 0x63, 0x52, 0x65,
0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 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 ( var (

View file

@ -4311,6 +4311,8 @@ enum FeatureBit {
ANCHORS_OPT = 21; ANCHORS_OPT = 21;
ANCHORS_ZERO_FEE_HTLC_REQ = 22; ANCHORS_ZERO_FEE_HTLC_REQ = 22;
ANCHORS_ZERO_FEE_HTLC_OPT = 23; ANCHORS_ZERO_FEE_HTLC_OPT = 23;
ROUTE_BLINDING_REQUIRED = 24;
ROUTE_BLINDING_OPTIONAL = 25;
AMP_REQ = 30; AMP_REQ = 30;
AMP_OPT = 31; AMP_OPT = 31;
} }

View file

@ -1470,6 +1470,8 @@
"ANCHORS_OPT", "ANCHORS_OPT",
"ANCHORS_ZERO_FEE_HTLC_REQ", "ANCHORS_ZERO_FEE_HTLC_REQ",
"ANCHORS_ZERO_FEE_HTLC_OPT", "ANCHORS_ZERO_FEE_HTLC_OPT",
"ROUTE_BLINDING_REQUIRED",
"ROUTE_BLINDING_OPTIONAL",
"AMP_REQ", "AMP_REQ",
"AMP_OPT" "AMP_OPT"
] ]
@ -4694,6 +4696,8 @@
"ANCHORS_OPT", "ANCHORS_OPT",
"ANCHORS_ZERO_FEE_HTLC_REQ", "ANCHORS_ZERO_FEE_HTLC_REQ",
"ANCHORS_ZERO_FEE_HTLC_OPT", "ANCHORS_ZERO_FEE_HTLC_OPT",
"ROUTE_BLINDING_REQUIRED",
"ROUTE_BLINDING_OPTIONAL",
"AMP_REQ", "AMP_REQ",
"AMP_OPT" "AMP_OPT"
], ],

View file

@ -77,6 +77,8 @@
"ANCHORS_OPT", "ANCHORS_OPT",
"ANCHORS_ZERO_FEE_HTLC_REQ", "ANCHORS_ZERO_FEE_HTLC_REQ",
"ANCHORS_ZERO_FEE_HTLC_OPT", "ANCHORS_ZERO_FEE_HTLC_OPT",
"ROUTE_BLINDING_REQUIRED",
"ROUTE_BLINDING_OPTIONAL",
"AMP_REQ", "AMP_REQ",
"AMP_OPT" "AMP_OPT"
], ],

View file

@ -772,6 +772,8 @@
"ANCHORS_OPT", "ANCHORS_OPT",
"ANCHORS_ZERO_FEE_HTLC_REQ", "ANCHORS_ZERO_FEE_HTLC_REQ",
"ANCHORS_ZERO_FEE_HTLC_OPT", "ANCHORS_ZERO_FEE_HTLC_OPT",
"ROUTE_BLINDING_REQUIRED",
"ROUTE_BLINDING_OPTIONAL",
"AMP_REQ", "AMP_REQ",
"AMP_OPT" "AMP_OPT"
], ],

View file

@ -141,6 +141,14 @@ const (
// transactions, which also imply anchor commitments. // transactions, which also imply anchor commitments.
AnchorsZeroFeeHtlcTxOptional FeatureBit = 23 AnchorsZeroFeeHtlcTxOptional FeatureBit = 23
// RouteBlindingRequired is a required feature bit that signals that
// the node supports blinded payments.
RouteBlindingRequired FeatureBit = 24
// RouteBlindingOptional is an optional feature bit that signals that
// the node supports blinded payments.
RouteBlindingOptional FeatureBit = 25
// ShutdownAnySegwitRequired is an required feature bit that signals // ShutdownAnySegwitRequired is an required feature bit that signals
// that the sender is able to properly handle/parse segwit witness // that the sender is able to properly handle/parse segwit witness
// programs up to version 16. This enables utilization of Taproot // programs up to version 16. This enables utilization of Taproot
@ -315,6 +323,8 @@ var Features = map[FeatureBit]string{
ScidAliasOptional: "scid-alias", ScidAliasOptional: "scid-alias",
ZeroConfRequired: "zero-conf", ZeroConfRequired: "zero-conf",
ZeroConfOptional: "zero-conf", ZeroConfOptional: "zero-conf",
RouteBlindingRequired: "route-blinding",
RouteBlindingOptional: "route-blinding",
ShutdownAnySegwitRequired: "shutdown-any-segwit", ShutdownAnySegwitRequired: "shutdown-any-segwit",
ShutdownAnySegwitOptional: "shutdown-any-segwit", ShutdownAnySegwitOptional: "shutdown-any-segwit",
SimpleTaprootChannelsRequiredFinal: "simple-taproot-chans", SimpleTaprootChannelsRequiredFinal: "simple-taproot-chans",

View file

@ -549,6 +549,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
NoAnySegwit: cfg.ProtocolOptions.NoAnySegwit(), NoAnySegwit: cfg.ProtocolOptions.NoAnySegwit(),
CustomFeatures: cfg.ProtocolOptions.ExperimentalProtocol.CustomFeatures(), CustomFeatures: cfg.ProtocolOptions.ExperimentalProtocol.CustomFeatures(),
NoTaprootChans: !cfg.ProtocolOptions.TaprootChans, NoTaprootChans: !cfg.ProtocolOptions.TaprootChans,
NoRouteBlinding: cfg.ProtocolOptions.NoRouteBlinding(),
}) })
if err != nil { if err != nil {
return nil, err return nil, err