mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-20 02:27:21 +01:00
Merge pull request #6831 from bottlepay/interceptor-watchdog
htlcswitch: interceptor watchdog
This commit is contained in:
commit
7274cf40d0
@ -28,7 +28,14 @@
|
||||
Similar to TrackPaymentV2, but for any inflight payment.
|
||||
|
||||
* [Catch and throw an error](https://github.com/lightningnetwork/lnd/pull/6945)
|
||||
during `openchannel` if the local funding amount given is zero.
|
||||
during `openchannel` if the local funding amount given is zero.
|
||||
|
||||
* [Extend](https://github.com/lightningnetwork/lnd/pull/6831) the HTLC
|
||||
interceptor server implementation with watchdog functionality to cancel back
|
||||
HTLCs for which an interceptor client does not provide a resolution in time.
|
||||
If an HTLC expires, the counterparty will claim it back on-chain and the
|
||||
receiver will lose it. Therefore the receiver can just as well fail off-chain
|
||||
a few blocks before so that the channel is saved.
|
||||
|
||||
* [Make remote channel reserve amount configurable for
|
||||
`openchannel`](https://github.com/lightningnetwork/lnd/pull/6956)
|
||||
@ -167,6 +174,7 @@ details.
|
||||
* Graham Krizek
|
||||
* hieblmi
|
||||
* Jesse de Wit
|
||||
* Joost Jager
|
||||
* Jordi Montes
|
||||
* Matt Morehouse
|
||||
* Michael Street
|
||||
|
89
htlcswitch/held_htlc_set.go
Normal file
89
htlcswitch/held_htlc_set.go
Normal file
@ -0,0 +1,89 @@
|
||||
package htlcswitch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
)
|
||||
|
||||
// heldHtlcSet keeps track of outstanding intercepted forwards. It exposes
|
||||
// several methods to manipulate the underlying map structure in a consistent
|
||||
// way.
|
||||
type heldHtlcSet struct {
|
||||
set map[channeldb.CircuitKey]InterceptedForward
|
||||
}
|
||||
|
||||
func newHeldHtlcSet() *heldHtlcSet {
|
||||
return &heldHtlcSet{
|
||||
set: make(map[channeldb.CircuitKey]InterceptedForward),
|
||||
}
|
||||
}
|
||||
|
||||
// forEach iterates over all held forwards and calls the given callback for each
|
||||
// of them.
|
||||
func (h *heldHtlcSet) forEach(cb func(InterceptedForward)) {
|
||||
for _, fwd := range h.set {
|
||||
cb(fwd)
|
||||
}
|
||||
}
|
||||
|
||||
// popAll calls the callback for each forward and removes them from the set.
|
||||
func (h *heldHtlcSet) popAll(cb func(InterceptedForward)) {
|
||||
for _, fwd := range h.set {
|
||||
cb(fwd)
|
||||
}
|
||||
|
||||
h.set = make(map[channeldb.CircuitKey]InterceptedForward)
|
||||
}
|
||||
|
||||
// popAutoFails calls the callback for each forward that has an auto-fail height
|
||||
// equal or less then the specified pop height and removes them from the set.
|
||||
func (h *heldHtlcSet) popAutoFails(height uint32, cb func(InterceptedForward)) {
|
||||
for key, fwd := range h.set {
|
||||
if uint32(fwd.Packet().AutoFailHeight) > height {
|
||||
continue
|
||||
}
|
||||
|
||||
cb(fwd)
|
||||
|
||||
delete(h.set, key)
|
||||
}
|
||||
}
|
||||
|
||||
// pop returns the specified forward and removes it from the set.
|
||||
func (h *heldHtlcSet) pop(key channeldb.CircuitKey) (InterceptedForward, error) {
|
||||
intercepted, ok := h.set[key]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("fwd %v not found", key)
|
||||
}
|
||||
|
||||
delete(h.set, key)
|
||||
|
||||
return intercepted, nil
|
||||
}
|
||||
|
||||
// exists tests whether the specified forward is part of the set.
|
||||
func (h *heldHtlcSet) exists(key channeldb.CircuitKey) bool {
|
||||
_, ok := h.set[key]
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
// push adds the specified forward to the set. An error is returned if the
|
||||
// forward exists already.
|
||||
func (h *heldHtlcSet) push(key channeldb.CircuitKey,
|
||||
fwd InterceptedForward) error {
|
||||
|
||||
if fwd == nil {
|
||||
return errors.New("nil fwd pushed")
|
||||
}
|
||||
|
||||
if h.exists(key) {
|
||||
return errors.New("htlc already exists in set")
|
||||
}
|
||||
|
||||
h.set[key] = fwd
|
||||
|
||||
return nil
|
||||
}
|
126
htlcswitch/held_htlc_set_test.go
Normal file
126
htlcswitch/held_htlc_set_test.go
Normal file
@ -0,0 +1,126 @@
|
||||
package htlcswitch
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHeldHtlcSetEmpty(t *testing.T) {
|
||||
set := newHeldHtlcSet()
|
||||
|
||||
// Test operations on an empty set.
|
||||
require.False(t, set.exists(channeldb.CircuitKey{}))
|
||||
|
||||
_, err := set.pop(channeldb.CircuitKey{})
|
||||
require.Error(t, err)
|
||||
|
||||
set.popAll(
|
||||
func(_ InterceptedForward) {
|
||||
require.Fail(t, "unexpected fwd")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestHeldHtlcSet(t *testing.T) {
|
||||
set := newHeldHtlcSet()
|
||||
|
||||
key := channeldb.CircuitKey{
|
||||
ChanID: lnwire.NewShortChanIDFromInt(1),
|
||||
HtlcID: 2,
|
||||
}
|
||||
|
||||
// Test pushing a nil forward.
|
||||
require.Error(t, set.push(key, nil))
|
||||
|
||||
// Test pushing a forward.
|
||||
fwd := &interceptedForward{
|
||||
htlc: &lnwire.UpdateAddHTLC{},
|
||||
}
|
||||
require.NoError(t, set.push(key, fwd))
|
||||
|
||||
// Re-pushing should fail.
|
||||
require.Error(t, set.push(key, fwd))
|
||||
|
||||
// Test popping the fwd.
|
||||
poppedFwd, err := set.pop(key)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fwd, poppedFwd)
|
||||
|
||||
_, err = set.pop(key)
|
||||
require.Error(t, err)
|
||||
|
||||
// Pushing the forward again.
|
||||
require.NoError(t, set.push(key, fwd))
|
||||
|
||||
// Test for each.
|
||||
var cbCalled bool
|
||||
set.forEach(func(_ InterceptedForward) {
|
||||
cbCalled = true
|
||||
|
||||
require.Equal(t, fwd, poppedFwd)
|
||||
})
|
||||
require.True(t, cbCalled)
|
||||
|
||||
// Test popping all forwards.
|
||||
cbCalled = false
|
||||
set.popAll(
|
||||
func(_ InterceptedForward) {
|
||||
cbCalled = true
|
||||
|
||||
require.Equal(t, fwd, poppedFwd)
|
||||
},
|
||||
)
|
||||
require.True(t, cbCalled)
|
||||
|
||||
_, err = set.pop(key)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestHeldHtlcSetAutoFails(t *testing.T) {
|
||||
set := newHeldHtlcSet()
|
||||
|
||||
key := channeldb.CircuitKey{
|
||||
ChanID: lnwire.NewShortChanIDFromInt(1),
|
||||
HtlcID: 2,
|
||||
}
|
||||
|
||||
const autoFailHeight = 100
|
||||
fwd := &interceptedForward{
|
||||
packet: &htlcPacket{},
|
||||
htlc: &lnwire.UpdateAddHTLC{},
|
||||
autoFailHeight: autoFailHeight,
|
||||
}
|
||||
require.NoError(t, set.push(key, fwd))
|
||||
|
||||
// Test popping auto fails up to one block before the auto-fail height
|
||||
// of our forward.
|
||||
set.popAutoFails(
|
||||
autoFailHeight-1,
|
||||
func(_ InterceptedForward) {
|
||||
require.Fail(t, "unexpected fwd")
|
||||
},
|
||||
)
|
||||
|
||||
// Popping succeeds at the auto-fail height.
|
||||
cbCalled := false
|
||||
set.popAutoFails(
|
||||
autoFailHeight,
|
||||
func(poppedFwd InterceptedForward) {
|
||||
cbCalled = true
|
||||
|
||||
require.Equal(t, fwd, poppedFwd)
|
||||
},
|
||||
)
|
||||
require.True(t, cbCalled)
|
||||
|
||||
// After this, there should be nothing more to pop.
|
||||
set.popAutoFails(
|
||||
autoFailHeight,
|
||||
func(_ InterceptedForward) {
|
||||
require.Fail(t, "unexpected fwd")
|
||||
},
|
||||
)
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
@ -20,6 +21,8 @@ var (
|
||||
// ErrUnsupportedFailureCode when processing of an unsupported failure
|
||||
// code is attempted.
|
||||
ErrUnsupportedFailureCode = errors.New("unsupported failure code")
|
||||
|
||||
errBlockStreamStopped = errors.New("block epoch stream stopped")
|
||||
)
|
||||
|
||||
// InterceptableSwitch is an implementation of ForwardingSwitch interface.
|
||||
@ -54,13 +57,32 @@ type InterceptableSwitch struct {
|
||||
// interceptor is the handler for intercepted packets.
|
||||
interceptor ForwardInterceptor
|
||||
|
||||
// holdForwards keeps track of outstanding intercepted forwards.
|
||||
holdForwards map[channeldb.CircuitKey]InterceptedForward
|
||||
// heldHtlcSet keeps track of outstanding intercepted forwards.
|
||||
heldHtlcSet *heldHtlcSet
|
||||
|
||||
// cltvRejectDelta defines the number of blocks before the expiry of the
|
||||
// htlc where we no longer intercept it and instead cancel it back.
|
||||
cltvRejectDelta uint32
|
||||
|
||||
// cltvInterceptDelta defines the number of blocks before the expiry of
|
||||
// the htlc where we don't intercept anymore. This value must be greater
|
||||
// than CltvRejectDelta, because we don't want to offer htlcs to the
|
||||
// interceptor client for which there is no time left to resolve them
|
||||
// anymore.
|
||||
cltvInterceptDelta uint32
|
||||
|
||||
// notifier is an instance of a chain notifier that we'll use to signal
|
||||
// the switch when a new block has arrived.
|
||||
notifier chainntnfs.ChainNotifier
|
||||
|
||||
// blockEpochStream is an active block epoch event stream backed by an
|
||||
// active ChainNotifier instance. This will be used to retrieve the
|
||||
// latest height of the chain.
|
||||
blockEpochStream *chainntnfs.BlockEpochEvent
|
||||
|
||||
// currentHeight is the currently best known height.
|
||||
currentHeight int32
|
||||
|
||||
wg sync.WaitGroup
|
||||
quit chan struct{}
|
||||
}
|
||||
@ -111,22 +133,57 @@ type fwdResolution struct {
|
||||
errChan chan error
|
||||
}
|
||||
|
||||
// InterceptableSwitchConfig contains the configuration of InterceptableSwitch.
|
||||
type InterceptableSwitchConfig struct {
|
||||
// Switch is a reference to the actual switch implementation that
|
||||
// packets get sent to on resume.
|
||||
Switch *Switch
|
||||
|
||||
// Notifier is an instance of a chain notifier that we'll use to signal
|
||||
// the switch when a new block has arrived.
|
||||
Notifier chainntnfs.ChainNotifier
|
||||
|
||||
// CltvRejectDelta defines the number of blocks before the expiry of the
|
||||
// htlc where we auto-fail an intercepted htlc to prevent channel
|
||||
// force-closure.
|
||||
CltvRejectDelta uint32
|
||||
|
||||
// CltvInterceptDelta defines the number of blocks before the expiry of
|
||||
// the htlc where we don't intercept anymore. This value must be greater
|
||||
// than CltvRejectDelta, because we don't want to offer htlcs to the
|
||||
// interceptor client for which there is no time left to resolve them
|
||||
// anymore.
|
||||
CltvInterceptDelta uint32
|
||||
|
||||
// RequireInterceptor indicates whether processing should block if no
|
||||
// interceptor is connected.
|
||||
RequireInterceptor bool
|
||||
}
|
||||
|
||||
// NewInterceptableSwitch returns an instance of InterceptableSwitch.
|
||||
func NewInterceptableSwitch(s *Switch, cltvRejectDelta uint32,
|
||||
requireInterceptor bool) *InterceptableSwitch {
|
||||
func NewInterceptableSwitch(cfg *InterceptableSwitchConfig) (
|
||||
*InterceptableSwitch, error) {
|
||||
|
||||
if cfg.CltvInterceptDelta <= cfg.CltvRejectDelta {
|
||||
return nil, fmt.Errorf("cltv intercept delta %v not greater "+
|
||||
"than cltv reject delta %v",
|
||||
cfg.CltvInterceptDelta, cfg.CltvRejectDelta)
|
||||
}
|
||||
|
||||
return &InterceptableSwitch{
|
||||
htlcSwitch: s,
|
||||
htlcSwitch: cfg.Switch,
|
||||
intercepted: make(chan *interceptedPackets),
|
||||
onchainIntercepted: make(chan InterceptedForward),
|
||||
interceptorRegistration: make(chan ForwardInterceptor),
|
||||
holdForwards: make(map[channeldb.CircuitKey]InterceptedForward),
|
||||
heldHtlcSet: newHeldHtlcSet(),
|
||||
resolutionChan: make(chan *fwdResolution),
|
||||
requireInterceptor: requireInterceptor,
|
||||
cltvRejectDelta: cltvRejectDelta,
|
||||
requireInterceptor: cfg.RequireInterceptor,
|
||||
cltvRejectDelta: cfg.CltvRejectDelta,
|
||||
cltvInterceptDelta: cfg.CltvInterceptDelta,
|
||||
notifier: cfg.Notifier,
|
||||
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetInterceptor sets the ForwardInterceptor to be used. A nil argument
|
||||
@ -144,11 +201,20 @@ func (s *InterceptableSwitch) SetInterceptor(
|
||||
}
|
||||
|
||||
func (s *InterceptableSwitch) Start() error {
|
||||
blockEpochStream, err := s.notifier.RegisterBlockEpochNtfn(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.blockEpochStream = blockEpochStream
|
||||
|
||||
s.wg.Add(1)
|
||||
go func() {
|
||||
defer s.wg.Done()
|
||||
|
||||
s.run()
|
||||
err := s.run()
|
||||
if err != nil {
|
||||
log.Errorf("InterceptableSwitch stopped: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
@ -158,10 +224,28 @@ func (s *InterceptableSwitch) Stop() error {
|
||||
close(s.quit)
|
||||
s.wg.Wait()
|
||||
|
||||
s.blockEpochStream.Cancel()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *InterceptableSwitch) run() {
|
||||
func (s *InterceptableSwitch) run() error {
|
||||
// The block epoch stream will immediately stream the current height.
|
||||
// Read it out here.
|
||||
select {
|
||||
case currentBlock, ok := <-s.blockEpochStream.Epochs:
|
||||
if !ok {
|
||||
return errBlockStreamStopped
|
||||
}
|
||||
s.currentHeight = currentBlock.Height
|
||||
|
||||
case <-s.quit:
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debugf("InterceptableSwitch running: height=%v, "+
|
||||
"requireInterceptor=%v", s.currentHeight, s.requireInterceptor)
|
||||
|
||||
for {
|
||||
select {
|
||||
// An interceptor registration or de-registration came in.
|
||||
@ -171,7 +255,14 @@ func (s *InterceptableSwitch) run() {
|
||||
case packets := <-s.intercepted:
|
||||
var notIntercepted []*htlcPacket
|
||||
for _, p := range packets.packets {
|
||||
if !s.interceptForward(p, packets.isReplay) {
|
||||
intercepted, err := s.interceptForward(
|
||||
p, packets.isReplay,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !intercepted {
|
||||
notIntercepted = append(
|
||||
notIntercepted, p,
|
||||
)
|
||||
@ -192,16 +283,44 @@ func (s *InterceptableSwitch) run() {
|
||||
// already intercepted in the off-chain flow. And even
|
||||
// if not, it is safe to signal replay so that we won't
|
||||
// unexpectedly skip over this htlc.
|
||||
s.forward(fwd, true)
|
||||
if _, err := s.forward(fwd, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case res := <-s.resolutionChan:
|
||||
res.errChan <- s.resolve(res.resolution)
|
||||
|
||||
case currentBlock, ok := <-s.blockEpochStream.Epochs:
|
||||
if !ok {
|
||||
return errBlockStreamStopped
|
||||
}
|
||||
|
||||
s.currentHeight = currentBlock.Height
|
||||
|
||||
// A new block is appended. Fail any held htlcs that
|
||||
// expire at this height to prevent channel force-close.
|
||||
s.failExpiredHtlcs()
|
||||
|
||||
case <-s.quit:
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *InterceptableSwitch) failExpiredHtlcs() {
|
||||
s.heldHtlcSet.popAutoFails(
|
||||
uint32(s.currentHeight),
|
||||
func(fwd InterceptedForward) {
|
||||
err := fwd.FailWithCode(
|
||||
lnwire.CodeTemporaryChannelFailure,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("Cannot fail packet: %v", err)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (s *InterceptableSwitch) sendForward(fwd InterceptedForward) {
|
||||
err := s.interceptor(fwd.Packet())
|
||||
if err != nil {
|
||||
@ -220,9 +339,7 @@ func (s *InterceptableSwitch) setInterceptor(interceptor ForwardInterceptor) {
|
||||
if interceptor != nil {
|
||||
log.Debugf("Interceptor connected")
|
||||
|
||||
for _, fwd := range s.holdForwards {
|
||||
s.sendForward(fwd)
|
||||
}
|
||||
s.heldHtlcSet.forEach(s.sendForward)
|
||||
|
||||
return
|
||||
}
|
||||
@ -238,20 +355,19 @@ func (s *InterceptableSwitch) setInterceptor(interceptor ForwardInterceptor) {
|
||||
// Interceptor is not required. Release held forwards.
|
||||
log.Infof("Interceptor disconnected, resolving held packets")
|
||||
|
||||
for _, fwd := range s.holdForwards {
|
||||
if err := fwd.Resume(); err != nil {
|
||||
s.heldHtlcSet.popAll(func(fwd InterceptedForward) {
|
||||
err := fwd.Resume()
|
||||
if err != nil {
|
||||
log.Errorf("Failed to resume hold forward %v", err)
|
||||
}
|
||||
}
|
||||
s.holdForwards = make(map[channeldb.CircuitKey]InterceptedForward)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *InterceptableSwitch) resolve(res *FwdResolution) error {
|
||||
intercepted, ok := s.holdForwards[res.Key]
|
||||
if !ok {
|
||||
return fmt.Errorf("fwd %v not found", res.Key)
|
||||
intercepted, err := s.heldHtlcSet.pop(res.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(s.holdForwards, res.Key)
|
||||
|
||||
switch res.Action {
|
||||
case FwdActionResume:
|
||||
@ -338,19 +454,21 @@ func (s *InterceptableSwitch) ForwardPacket(
|
||||
// interceptForward forwards the packet to the external interceptor after
|
||||
// checking the interception criteria.
|
||||
func (s *InterceptableSwitch) interceptForward(packet *htlcPacket,
|
||||
isReplay bool) bool {
|
||||
isReplay bool) (bool, error) {
|
||||
|
||||
switch htlc := packet.htlc.(type) {
|
||||
case *lnwire.UpdateAddHTLC:
|
||||
// We are not interested in intercepting initiated payments.
|
||||
if packet.incomingChanID == hop.Source {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
intercepted := &interceptedForward{
|
||||
htlc: htlc,
|
||||
packet: packet,
|
||||
htlcSwitch: s.htlcSwitch,
|
||||
autoFailHeight: int32(packet.incomingTimeout -
|
||||
s.cltvRejectDelta),
|
||||
}
|
||||
|
||||
// Handle forwards that are too close to expiry.
|
||||
@ -368,28 +486,28 @@ func (s *InterceptableSwitch) interceptForward(packet *htlcPacket,
|
||||
// will remain stuck and potentially force-close the
|
||||
// channel. But in the end, we should never get here, so
|
||||
// the actual return value doesn't matter that much.
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
if handled {
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return s.forward(intercepted, isReplay)
|
||||
|
||||
default:
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// forward records the intercepted htlc and forwards it to the interceptor.
|
||||
func (s *InterceptableSwitch) forward(
|
||||
fwd InterceptedForward, isReplay bool) bool {
|
||||
fwd InterceptedForward, isReplay bool) (bool, error) {
|
||||
|
||||
inKey := fwd.Packet().IncomingCircuit
|
||||
|
||||
// Ignore already held htlcs.
|
||||
if _, ok := s.holdForwards[inKey]; ok {
|
||||
return true
|
||||
if s.heldHtlcSet.exists(inKey) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// If there is no interceptor currently registered, configuration and packet
|
||||
@ -397,7 +515,7 @@ func (s *InterceptableSwitch) forward(
|
||||
if s.interceptor == nil {
|
||||
// Process normally if an interceptor is not required.
|
||||
if !s.requireInterceptor {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// We are in interceptor-required mode. If this is a new packet, it is
|
||||
@ -411,23 +529,28 @@ func (s *InterceptableSwitch) forward(
|
||||
log.Errorf("Cannot fail packet: %v", err)
|
||||
}
|
||||
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// This packet is a replay. It is not safe to fail back, because the
|
||||
// interceptor may still signal otherwise upon reconnect. Keep the
|
||||
// packet in the queue until then.
|
||||
s.holdForwards[inKey] = fwd
|
||||
if err := s.heldHtlcSet.push(inKey, fwd); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// There is an interceptor registered. We can forward the packet right now.
|
||||
// Hold it in the queue too to track what is outstanding.
|
||||
s.holdForwards[inKey] = fwd
|
||||
if err := s.heldHtlcSet.push(inKey, fwd); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
s.sendForward(fwd)
|
||||
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// handleExpired checks that the htlc isn't too close to the channel
|
||||
@ -435,8 +558,8 @@ func (s *InterceptableSwitch) forward(
|
||||
func (s *InterceptableSwitch) handleExpired(fwd *interceptedForward) (
|
||||
bool, error) {
|
||||
|
||||
height := s.htlcSwitch.BestHeight()
|
||||
if fwd.packet.incomingTimeout >= height+s.cltvRejectDelta {
|
||||
height := uint32(s.currentHeight)
|
||||
if fwd.packet.incomingTimeout >= height+s.cltvInterceptDelta {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@ -460,9 +583,10 @@ func (s *InterceptableSwitch) handleExpired(fwd *interceptedForward) (
|
||||
// It is passed from the switch to external interceptors that are interested
|
||||
// in holding forwards and resolve them manually.
|
||||
type interceptedForward struct {
|
||||
htlc *lnwire.UpdateAddHTLC
|
||||
packet *htlcPacket
|
||||
htlcSwitch *Switch
|
||||
htlc *lnwire.UpdateAddHTLC
|
||||
packet *htlcPacket
|
||||
htlcSwitch *Switch
|
||||
autoFailHeight int32
|
||||
}
|
||||
|
||||
// Packet returns the intercepted htlc packet.
|
||||
@ -480,6 +604,7 @@ func (f *interceptedForward) Packet() InterceptedPacket {
|
||||
IncomingExpiry: f.packet.incomingTimeout,
|
||||
CustomRecords: f.packet.customRecords,
|
||||
OnionBlob: f.htlc.OnionBlob,
|
||||
AutoFailHeight: f.autoFailHeight,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,6 +312,10 @@ type InterceptedPacket struct {
|
||||
|
||||
// OnionBlob is the onion packet for the next hop
|
||||
OnionBlob [lnwire.OnionPacketSize]byte
|
||||
|
||||
// AutoFailHeight is the block height at which this intercept will be
|
||||
// failed back automatically.
|
||||
AutoFailHeight int32
|
||||
}
|
||||
|
||||
// InterceptedForward is passed to the ForwardInterceptor for every forwarded
|
||||
|
@ -14,10 +14,12 @@ import (
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/contractcourt"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hodl"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lntest/mock"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
@ -3702,6 +3704,8 @@ func (m *mockForwardInterceptor) InterceptForwardHtlc(
|
||||
}
|
||||
|
||||
func (m *mockForwardInterceptor) getIntercepted() InterceptedPacket {
|
||||
m.t.Helper()
|
||||
|
||||
select {
|
||||
case p := <-m.interceptedChan:
|
||||
return p
|
||||
@ -3750,6 +3754,8 @@ func assertOutgoingLinkReceive(t *testing.T, targetLink *mockChannelLink,
|
||||
func assertOutgoingLinkReceiveIntercepted(t *testing.T,
|
||||
targetLink *mockChannelLink) {
|
||||
|
||||
t.Helper()
|
||||
|
||||
select {
|
||||
case <-targetLink.packets:
|
||||
case <-time.After(time.Second):
|
||||
@ -3757,8 +3763,24 @@ func assertOutgoingLinkReceiveIntercepted(t *testing.T,
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwitchHoldForward(t *testing.T) {
|
||||
t.Parallel()
|
||||
type interceptableSwitchTestContext struct {
|
||||
t *testing.T
|
||||
|
||||
preimage [sha256.Size]byte
|
||||
rhash [32]byte
|
||||
onionBlob [1366]byte
|
||||
incomingHtlcID uint64
|
||||
cltvRejectDelta uint32
|
||||
cltvInterceptDelta uint32
|
||||
|
||||
forwardInterceptor *mockForwardInterceptor
|
||||
aliceChannelLink *mockChannelLink
|
||||
bobChannelLink *mockChannelLink
|
||||
s *Switch
|
||||
}
|
||||
|
||||
func newInterceptableSwitchTestContext(
|
||||
t *testing.T) *interceptableSwitchTestContext {
|
||||
|
||||
chanID1, chanID2, aliceChanID, bobChanID := genIDs()
|
||||
|
||||
@ -3783,12 +3805,6 @@ func TestSwitchHoldForward(t *testing.T) {
|
||||
t.Fatalf("unable to start switch: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := s.Stop(); err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
aliceChannelLink := newMockChannelLink(
|
||||
s, chanID1, aliceChanID, emptyScid, alicePeer, true, false,
|
||||
false, false,
|
||||
@ -3804,72 +3820,106 @@ func TestSwitchHoldForward(t *testing.T) {
|
||||
t.Fatalf("unable to add bob link: %v", err)
|
||||
}
|
||||
|
||||
// Create request which should be forwarded from Alice channel link to
|
||||
// bob channel link.
|
||||
preimage := [sha256.Size]byte{1}
|
||||
rhash := sha256.Sum256(preimage[:])
|
||||
onionBlob := [1366]byte{4, 5, 6}
|
||||
incomingHtlcID := uint64(0)
|
||||
|
||||
const cltvRejectDelta = 13
|
||||
|
||||
createTestPacket := func() *htlcPacket {
|
||||
incomingHtlcID++
|
||||
|
||||
return &htlcPacket{
|
||||
incomingChanID: aliceChannelLink.ShortChanID(),
|
||||
incomingHTLCID: incomingHtlcID,
|
||||
incomingTimeout: testStartingHeight + cltvRejectDelta + 1,
|
||||
outgoingChanID: bobChannelLink.ShortChanID(),
|
||||
obfuscator: NewMockObfuscator(),
|
||||
htlc: &lnwire.UpdateAddHTLC{
|
||||
PaymentHash: rhash,
|
||||
Amount: 1,
|
||||
OnionBlob: onionBlob,
|
||||
},
|
||||
}
|
||||
ctx := &interceptableSwitchTestContext{
|
||||
t: t,
|
||||
preimage: preimage,
|
||||
rhash: sha256.Sum256(preimage[:]),
|
||||
onionBlob: [1366]byte{4, 5, 6},
|
||||
incomingHtlcID: uint64(0),
|
||||
cltvRejectDelta: 10,
|
||||
cltvInterceptDelta: 13,
|
||||
forwardInterceptor: &mockForwardInterceptor{
|
||||
t: t,
|
||||
interceptedChan: make(chan InterceptedPacket),
|
||||
},
|
||||
aliceChannelLink: aliceChannelLink,
|
||||
bobChannelLink: bobChannelLink,
|
||||
s: s,
|
||||
}
|
||||
|
||||
createSettlePacket := func(outgoingHTLCID uint64) *htlcPacket {
|
||||
return &htlcPacket{
|
||||
outgoingChanID: bobChannelLink.ShortChanID(),
|
||||
outgoingHTLCID: outgoingHTLCID,
|
||||
amount: 1,
|
||||
htlc: &lnwire.UpdateFulfillHTLC{
|
||||
PaymentPreimage: preimage,
|
||||
},
|
||||
}
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
forwardInterceptor := &mockForwardInterceptor{
|
||||
t: t,
|
||||
interceptedChan: make(chan InterceptedPacket),
|
||||
func (c *interceptableSwitchTestContext) createTestPacket() *htlcPacket {
|
||||
c.incomingHtlcID++
|
||||
|
||||
return &htlcPacket{
|
||||
incomingChanID: c.aliceChannelLink.ShortChanID(),
|
||||
incomingHTLCID: c.incomingHtlcID,
|
||||
incomingTimeout: testStartingHeight + c.cltvInterceptDelta + 1,
|
||||
outgoingChanID: c.bobChannelLink.ShortChanID(),
|
||||
obfuscator: NewMockObfuscator(),
|
||||
htlc: &lnwire.UpdateAddHTLC{
|
||||
PaymentHash: c.rhash,
|
||||
Amount: 1,
|
||||
OnionBlob: c.onionBlob,
|
||||
},
|
||||
}
|
||||
switchForwardInterceptor := NewInterceptableSwitch(
|
||||
s, cltvRejectDelta, false,
|
||||
}
|
||||
|
||||
func (c *interceptableSwitchTestContext) finish() {
|
||||
if err := c.s.Stop(); err != nil {
|
||||
c.t.Fatalf(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *interceptableSwitchTestContext) createSettlePacket(
|
||||
outgoingHTLCID uint64) *htlcPacket {
|
||||
|
||||
return &htlcPacket{
|
||||
outgoingChanID: c.bobChannelLink.ShortChanID(),
|
||||
outgoingHTLCID: outgoingHTLCID,
|
||||
amount: 1,
|
||||
htlc: &lnwire.UpdateFulfillHTLC{
|
||||
PaymentPreimage: c.preimage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwitchHoldForward(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := newInterceptableSwitchTestContext(t)
|
||||
defer c.finish()
|
||||
|
||||
notifier := &mock.ChainNotifier{
|
||||
EpochChan: make(chan *chainntnfs.BlockEpoch, 1),
|
||||
}
|
||||
notifier.EpochChan <- &chainntnfs.BlockEpoch{Height: testStartingHeight}
|
||||
|
||||
switchForwardInterceptor, err := NewInterceptableSwitch(
|
||||
&InterceptableSwitchConfig{
|
||||
Switch: c.s,
|
||||
CltvRejectDelta: c.cltvRejectDelta,
|
||||
CltvInterceptDelta: c.cltvInterceptDelta,
|
||||
Notifier: notifier,
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, switchForwardInterceptor.Start())
|
||||
|
||||
switchForwardInterceptor.SetInterceptor(forwardInterceptor.InterceptForwardHtlc)
|
||||
switchForwardInterceptor.SetInterceptor(c.forwardInterceptor.InterceptForwardHtlc)
|
||||
linkQuit := make(chan struct{})
|
||||
|
||||
// Test a forward that expires too soon.
|
||||
packet := createTestPacket()
|
||||
packet.incomingTimeout = testStartingHeight + cltvRejectDelta - 1
|
||||
packet := c.createTestPacket()
|
||||
packet.incomingTimeout = testStartingHeight + c.cltvRejectDelta - 1
|
||||
|
||||
err = switchForwardInterceptor.ForwardPackets(linkQuit, false, packet)
|
||||
require.NoError(t, err, "can't forward htlc packet")
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertOutgoingLinkReceiveIntercepted(t, aliceChannelLink)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
assertOutgoingLinkReceiveIntercepted(t, c.aliceChannelLink)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
// Test a forward that expires too soon and can't be failed.
|
||||
packet = createTestPacket()
|
||||
packet.incomingTimeout = testStartingHeight + cltvRejectDelta - 1
|
||||
packet = c.createTestPacket()
|
||||
packet.incomingTimeout = testStartingHeight + c.cltvRejectDelta - 1
|
||||
|
||||
// Simulate an error during the composition of the failure message.
|
||||
currentCallback := s.cfg.FetchLastChannelUpdate
|
||||
s.cfg.FetchLastChannelUpdate = func(
|
||||
currentCallback := c.s.cfg.FetchLastChannelUpdate
|
||||
c.s.cfg.FetchLastChannelUpdate = func(
|
||||
lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) {
|
||||
|
||||
return nil, errors.New("cannot fetch update")
|
||||
@ -3877,137 +3927,137 @@ func TestSwitchHoldForward(t *testing.T) {
|
||||
|
||||
err = switchForwardInterceptor.ForwardPackets(linkQuit, false, packet)
|
||||
require.NoError(t, err, "can't forward htlc packet")
|
||||
receivedPkt := assertOutgoingLinkReceive(t, bobChannelLink, true)
|
||||
assertNumCircuits(t, s, 1, 1)
|
||||
receivedPkt := assertOutgoingLinkReceive(t, c.bobChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 1, 1)
|
||||
|
||||
require.NoError(t, switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false,
|
||||
createSettlePacket(receivedPkt.outgoingHTLCID),
|
||||
c.createSettlePacket(receivedPkt.outgoingHTLCID),
|
||||
))
|
||||
|
||||
assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
s.cfg.FetchLastChannelUpdate = currentCallback
|
||||
c.s.cfg.FetchLastChannelUpdate = currentCallback
|
||||
|
||||
// Test resume a hold forward.
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
err = switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false, createTestPacket(),
|
||||
linkQuit, false, c.createTestPacket(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
|
||||
require.NoError(t, switchForwardInterceptor.Resolve(&FwdResolution{
|
||||
Action: FwdActionResume,
|
||||
Key: forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
Key: c.forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
}))
|
||||
receivedPkt = assertOutgoingLinkReceive(t, bobChannelLink, true)
|
||||
assertNumCircuits(t, s, 1, 1)
|
||||
receivedPkt = assertOutgoingLinkReceive(t, c.bobChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 1, 1)
|
||||
|
||||
// settling the htlc to close the circuit.
|
||||
err = switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false,
|
||||
createSettlePacket(receivedPkt.outgoingHTLCID),
|
||||
c.createSettlePacket(receivedPkt.outgoingHTLCID),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
// Test resume a hold forward after disconnection.
|
||||
require.NoError(t, switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false, createTestPacket(),
|
||||
linkQuit, false, c.createTestPacket(),
|
||||
))
|
||||
|
||||
// Wait until the packet is offered to the interceptor.
|
||||
_ = forwardInterceptor.getIntercepted()
|
||||
_ = c.forwardInterceptor.getIntercepted()
|
||||
|
||||
// No forward expected yet.
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
|
||||
// Disconnect should resume the forwarding.
|
||||
switchForwardInterceptor.SetInterceptor(nil)
|
||||
|
||||
receivedPkt = assertOutgoingLinkReceive(t, bobChannelLink, true)
|
||||
assertNumCircuits(t, s, 1, 1)
|
||||
receivedPkt = assertOutgoingLinkReceive(t, c.bobChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 1, 1)
|
||||
|
||||
// Settle the htlc to close the circuit.
|
||||
require.NoError(t, switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false,
|
||||
createSettlePacket(receivedPkt.outgoingHTLCID),
|
||||
c.createSettlePacket(receivedPkt.outgoingHTLCID),
|
||||
))
|
||||
|
||||
assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
// Test failing a hold forward
|
||||
switchForwardInterceptor.SetInterceptor(
|
||||
forwardInterceptor.InterceptForwardHtlc,
|
||||
c.forwardInterceptor.InterceptForwardHtlc,
|
||||
)
|
||||
|
||||
require.NoError(t, switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false, createTestPacket(),
|
||||
linkQuit, false, c.createTestPacket(),
|
||||
))
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
|
||||
require.NoError(t, switchForwardInterceptor.Resolve(&FwdResolution{
|
||||
Action: FwdActionFail,
|
||||
Key: forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
Key: c.forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
FailureCode: lnwire.CodeTemporaryChannelFailure,
|
||||
}))
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
// Test failing a hold forward with a failure message.
|
||||
require.NoError(t,
|
||||
switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false, createTestPacket(),
|
||||
linkQuit, false, c.createTestPacket(),
|
||||
),
|
||||
)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
|
||||
reason := lnwire.OpaqueReason([]byte{1, 2, 3})
|
||||
require.NoError(t, switchForwardInterceptor.Resolve(&FwdResolution{
|
||||
Action: FwdActionFail,
|
||||
Key: forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
Key: c.forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
FailureMessage: reason,
|
||||
}))
|
||||
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
packet = assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
packet = assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
|
||||
require.Equal(t, reason, packet.htlc.(*lnwire.UpdateFailHTLC).Reason)
|
||||
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
// Test failing a hold forward with a malformed htlc failure.
|
||||
err = switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false, createTestPacket(),
|
||||
linkQuit, false, c.createTestPacket(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
|
||||
code := lnwire.CodeInvalidOnionKey
|
||||
require.NoError(t, switchForwardInterceptor.Resolve(&FwdResolution{
|
||||
Action: FwdActionFail,
|
||||
Key: forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
Key: c.forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
FailureCode: code,
|
||||
}))
|
||||
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
packet = assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
packet = assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
failPacket := packet.htlc.(*lnwire.UpdateFailHTLC)
|
||||
|
||||
shaOnionBlob := sha256.Sum256(onionBlob[:])
|
||||
shaOnionBlob := sha256.Sum256(c.onionBlob[:])
|
||||
expectedFailure := &lnwire.FailInvalidOnionKey{
|
||||
OnionSHA256: shaOnionBlob,
|
||||
}
|
||||
@ -4016,39 +4066,53 @@ func TestSwitchHoldForward(t *testing.T) {
|
||||
|
||||
assert.Equal(t, lnwire.OpaqueReason(b.Bytes()), failPacket.Reason)
|
||||
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
// Test settling a hold forward
|
||||
require.NoError(t, switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false, createTestPacket(),
|
||||
linkQuit, false, c.createTestPacket(),
|
||||
))
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
|
||||
require.NoError(t, switchForwardInterceptor.Resolve(&FwdResolution{
|
||||
Key: forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
Key: c.forwardInterceptor.getIntercepted().IncomingCircuit,
|
||||
Action: FwdActionSettle,
|
||||
Preimage: preimage,
|
||||
Preimage: c.preimage,
|
||||
}))
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
require.NoError(t, switchForwardInterceptor.Stop())
|
||||
|
||||
// Test always-on interception.
|
||||
switchForwardInterceptor = NewInterceptableSwitch(s, cltvRejectDelta, true)
|
||||
notifier = &mock.ChainNotifier{
|
||||
EpochChan: make(chan *chainntnfs.BlockEpoch, 1),
|
||||
}
|
||||
notifier.EpochChan <- &chainntnfs.BlockEpoch{Height: testStartingHeight}
|
||||
|
||||
switchForwardInterceptor, err = NewInterceptableSwitch(
|
||||
&InterceptableSwitchConfig{
|
||||
Switch: c.s,
|
||||
CltvRejectDelta: c.cltvRejectDelta,
|
||||
CltvInterceptDelta: c.cltvInterceptDelta,
|
||||
RequireInterceptor: true,
|
||||
Notifier: notifier,
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, switchForwardInterceptor.Start())
|
||||
|
||||
// Forward a fresh packet. It is expected to be failed immediately,
|
||||
// because there is no interceptor registered.
|
||||
require.NoError(t, switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, false, createTestPacket(),
|
||||
linkQuit, false, c.createTestPacket(),
|
||||
))
|
||||
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
// Forward a replayed packet. It is expected to be held until the
|
||||
// interceptor connects. To continue the test, it needs to be ran in a
|
||||
@ -4056,54 +4120,115 @@ func TestSwitchHoldForward(t *testing.T) {
|
||||
errChan := make(chan error)
|
||||
go func() {
|
||||
errChan <- switchForwardInterceptor.ForwardPackets(
|
||||
linkQuit, true, createTestPacket(),
|
||||
linkQuit, true, c.createTestPacket(),
|
||||
)
|
||||
}()
|
||||
|
||||
// Assert that nothing is forward to the switch.
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
// Register an interceptor.
|
||||
switchForwardInterceptor.SetInterceptor(
|
||||
forwardInterceptor.InterceptForwardHtlc,
|
||||
c.forwardInterceptor.InterceptForwardHtlc,
|
||||
)
|
||||
|
||||
// Expect the ForwardPackets call to unblock.
|
||||
require.NoError(t, <-errChan)
|
||||
|
||||
// Now expect the queued packet to come through.
|
||||
forwardInterceptor.getIntercepted()
|
||||
c.forwardInterceptor.getIntercepted()
|
||||
|
||||
// Disconnect and reconnect interceptor.
|
||||
switchForwardInterceptor.SetInterceptor(nil)
|
||||
switchForwardInterceptor.SetInterceptor(
|
||||
forwardInterceptor.InterceptForwardHtlc,
|
||||
c.forwardInterceptor.InterceptForwardHtlc,
|
||||
)
|
||||
|
||||
// A replay of the held packet is expected.
|
||||
intercepted := forwardInterceptor.getIntercepted()
|
||||
intercepted := c.forwardInterceptor.getIntercepted()
|
||||
|
||||
// Settle the packet.
|
||||
require.NoError(t, switchForwardInterceptor.Resolve(&FwdResolution{
|
||||
Key: intercepted.IncomingCircuit,
|
||||
Action: FwdActionSettle,
|
||||
Preimage: preimage,
|
||||
Preimage: c.preimage,
|
||||
}))
|
||||
assertOutgoingLinkReceive(t, bobChannelLink, false)
|
||||
assertOutgoingLinkReceive(t, aliceChannelLink, true)
|
||||
assertNumCircuits(t, s, 0, 0)
|
||||
assertOutgoingLinkReceive(t, c.bobChannelLink, false)
|
||||
assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
assertNumCircuits(t, c.s, 0, 0)
|
||||
|
||||
require.NoError(t, switchForwardInterceptor.Stop())
|
||||
|
||||
select {
|
||||
case <-forwardInterceptor.interceptedChan:
|
||||
case <-c.forwardInterceptor.interceptedChan:
|
||||
require.Fail(t, "unexpected interception")
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterceptableSwitchWatchDog(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := newInterceptableSwitchTestContext(t)
|
||||
defer c.finish()
|
||||
|
||||
// Start interceptable switch.
|
||||
notifier := &mock.ChainNotifier{
|
||||
EpochChan: make(chan *chainntnfs.BlockEpoch, 1),
|
||||
}
|
||||
notifier.EpochChan <- &chainntnfs.BlockEpoch{Height: testStartingHeight}
|
||||
|
||||
switchForwardInterceptor, err := NewInterceptableSwitch(
|
||||
&InterceptableSwitchConfig{
|
||||
Switch: c.s,
|
||||
CltvRejectDelta: c.cltvRejectDelta,
|
||||
CltvInterceptDelta: c.cltvInterceptDelta,
|
||||
Notifier: notifier,
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, switchForwardInterceptor.Start())
|
||||
|
||||
// Set interceptor.
|
||||
switchForwardInterceptor.SetInterceptor(
|
||||
c.forwardInterceptor.InterceptForwardHtlc,
|
||||
)
|
||||
|
||||
// Receive a packet.
|
||||
linkQuit := make(chan struct{})
|
||||
|
||||
packet := c.createTestPacket()
|
||||
|
||||
err = switchForwardInterceptor.ForwardPackets(linkQuit, false, packet)
|
||||
require.NoError(t, err, "can't forward htlc packet")
|
||||
|
||||
// Intercept the packet.
|
||||
intercepted := c.forwardInterceptor.getIntercepted()
|
||||
|
||||
require.Equal(t,
|
||||
int32(packet.incomingTimeout-c.cltvRejectDelta),
|
||||
intercepted.AutoFailHeight,
|
||||
)
|
||||
|
||||
// Htlc expires before a resolution from the interceptor.
|
||||
notifier.EpochChan <- &chainntnfs.BlockEpoch{
|
||||
Height: int32(packet.incomingTimeout) -
|
||||
int32(c.cltvRejectDelta),
|
||||
}
|
||||
|
||||
// Expect the htlc to be failed back.
|
||||
assertOutgoingLinkReceive(t, c.aliceChannelLink, true)
|
||||
|
||||
// It is too late now to resolve. Expect an error.
|
||||
require.Error(t, switchForwardInterceptor.Resolve(&FwdResolution{
|
||||
Action: FwdActionSettle,
|
||||
Key: intercepted.IncomingCircuit,
|
||||
Preimage: c.preimage,
|
||||
}))
|
||||
}
|
||||
|
||||
// TestSwitchDustForwarding tests that the switch properly fails HTLC's which
|
||||
// have incoming or outgoing links that breach their dust thresholds.
|
||||
func TestSwitchDustForwarding(t *testing.T) {
|
||||
@ -5329,7 +5454,21 @@ func testSwitchAliasInterceptFail(t *testing.T, zeroConf bool) {
|
||||
t: t,
|
||||
interceptedChan: make(chan InterceptedPacket),
|
||||
}
|
||||
interceptSwitch := NewInterceptableSwitch(s, 0, false)
|
||||
|
||||
notifier := &mock.ChainNotifier{
|
||||
EpochChan: make(chan *chainntnfs.BlockEpoch, 1),
|
||||
}
|
||||
notifier.EpochChan <- &chainntnfs.BlockEpoch{Height: testStartingHeight}
|
||||
|
||||
interceptSwitch, err := NewInterceptableSwitch(
|
||||
&InterceptableSwitchConfig{
|
||||
Switch: s,
|
||||
Notifier: notifier,
|
||||
CltvRejectDelta: 10,
|
||||
CltvInterceptDelta: 13,
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, interceptSwitch.Start())
|
||||
interceptSwitch.SetInterceptor(forwardInterceptor.InterceptForwardHtlc)
|
||||
|
||||
|
@ -40,6 +40,13 @@ const (
|
||||
// push us in the broadcast window.
|
||||
DefaultFinalCltvRejectDelta = DefaultIncomingBroadcastDelta + 3
|
||||
|
||||
// DefaultCltvInterceptDelta defines the number of blocks before the
|
||||
// expiry of the htlc where we don't intercept anymore. This value must
|
||||
// be greater than CltvRejectDelta, because we don't want to offer htlcs
|
||||
// to the interceptor client for which there is no time left to resolve
|
||||
// them anymore.
|
||||
DefaultCltvInterceptDelta = DefaultFinalCltvRejectDelta + 3
|
||||
|
||||
// DefaultOutgoingBroadcastDelta defines the number of blocks before the
|
||||
// expiry of an outgoing htlc at which we force close the channel. We
|
||||
// are not in a hurry to force close, because there is nothing to claim
|
||||
|
@ -90,6 +90,7 @@ func (r *forwardInterceptor) onIntercept(
|
||||
IncomingExpiry: htlc.IncomingExpiry,
|
||||
CustomRecords: htlc.CustomRecords,
|
||||
OnionBlob: htlc.OnionBlob[:],
|
||||
AutoFailHeight: htlc.AutoFailHeight,
|
||||
}
|
||||
|
||||
return r.stream.Send(interceptionRequest)
|
||||
|
@ -2590,6 +2590,9 @@ type ForwardHtlcInterceptRequest struct {
|
||||
CustomRecords map[uint64][]byte `protobuf:"bytes,8,rep,name=custom_records,json=customRecords,proto3" json:"custom_records,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
// The onion blob for the next hop
|
||||
OnionBlob []byte `protobuf:"bytes,9,opt,name=onion_blob,json=onionBlob,proto3" json:"onion_blob,omitempty"`
|
||||
// The block height at which this htlc will be auto-failed to prevent the
|
||||
// channel from force-closing.
|
||||
AutoFailHeight int32 `protobuf:"varint,10,opt,name=auto_fail_height,json=autoFailHeight,proto3" json:"auto_fail_height,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ForwardHtlcInterceptRequest) Reset() {
|
||||
@ -2687,6 +2690,13 @@ func (x *ForwardHtlcInterceptRequest) GetOnionBlob() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ForwardHtlcInterceptRequest) GetAutoFailHeight() int32 {
|
||||
if x != nil {
|
||||
return x.AutoFailHeight
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// *
|
||||
// ForwardHtlcInterceptResponse enables the caller to resolve a previously hold
|
||||
// forward. The caller can choose either to:
|
||||
@ -3178,7 +3188,7 @@ var file_routerrpc_router_proto_rawDesc = []byte{
|
||||
0x75, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x49, 0x64, 0x12,
|
||||
0x17, 0x0a, 0x07, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
|
||||
0x52, 0x06, 0x68, 0x74, 0x6c, 0x63, 0x49, 0x64, 0x22, 0xbf, 0x04, 0x0a, 0x1b, 0x46, 0x6f, 0x72,
|
||||
0x52, 0x06, 0x68, 0x74, 0x6c, 0x63, 0x49, 0x64, 0x22, 0xe9, 0x04, 0x0a, 0x1b, 0x46, 0x6f, 0x72,
|
||||
0x77, 0x61, 0x72, 0x64, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70,
|
||||
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x14, 0x69, 0x6e, 0x63, 0x6f,
|
||||
0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f, 0x6b, 0x65, 0x79,
|
||||
@ -3210,194 +3220,196 @@ var file_routerrpc_router_proto_rawDesc = []byte{
|
||||
0x63, 0x6f, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x63, 0x75, 0x73, 0x74,
|
||||
0x6f, 0x6d, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x6e, 0x69,
|
||||
0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f,
|
||||
0x6e, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x62, 0x1a, 0x40, 0x0a, 0x12, 0x43, 0x75, 0x73, 0x74,
|
||||
0x6f, 0x6d, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa8, 0x02, 0x0a, 0x1c, 0x46,
|
||||
0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63,
|
||||
0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x14, 0x69,
|
||||
0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x4b, 0x65, 0x79,
|
||||
0x52, 0x12, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69,
|
||||
0x74, 0x4b, 0x65, 0x79, 0x12, 0x3b, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x48, 0x6f, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x77,
|
||||
0x61, 0x72, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x27, 0x0a,
|
||||
0x0f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72,
|
||||
0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6c,
|
||||
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x46, 0x61, 0x69,
|
||||
0x6c, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0b, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72,
|
||||
0x65, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x43, 0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x32, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e,
|
||||
0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x41, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1a, 0x0a, 0x18, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x81, 0x04, 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75,
|
||||
0x72, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e,
|
||||
0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x44, 0x45, 0x54, 0x41,
|
||||
0x49, 0x4c, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x4e, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45,
|
||||
0x43, 0x4f, 0x44, 0x45, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x4e,
|
||||
0x4f, 0x54, 0x5f, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a,
|
||||
0x10, 0x4f, 0x4e, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55,
|
||||
0x54, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x45, 0x58, 0x43, 0x45,
|
||||
0x45, 0x44, 0x53, 0x5f, 0x4d, 0x41, 0x58, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x49, 0x4e, 0x53,
|
||||
0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43,
|
||||
0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54,
|
||||
0x45, 0x5f, 0x46, 0x4f, 0x52, 0x57, 0x41, 0x52, 0x44, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x48,
|
||||
0x54, 0x4c, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x08,
|
||||
0x12, 0x15, 0x0a, 0x11, 0x46, 0x4f, 0x52, 0x57, 0x41, 0x52, 0x44, 0x53, 0x5f, 0x44, 0x49, 0x53,
|
||||
0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x09, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x56, 0x4f, 0x49,
|
||||
0x43, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x15, 0x0a,
|
||||
0x11, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x50, 0x41,
|
||||
0x49, 0x44, 0x10, 0x0b, 0x12, 0x1b, 0x0a, 0x17, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f,
|
||||
0x45, 0x58, 0x50, 0x49, 0x52, 0x59, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x53, 0x4f, 0x4f, 0x4e, 0x10,
|
||||
0x0c, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x4e, 0x4f, 0x54,
|
||||
0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x10, 0x0d, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x50, 0x50, 0x5f, 0x49,
|
||||
0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x0e,
|
||||
0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4d, 0x49, 0x53, 0x4d,
|
||||
0x41, 0x54, 0x43, 0x48, 0x10, 0x0f, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x45, 0x54, 0x5f, 0x54, 0x4f,
|
||||
0x54, 0x41, 0x4c, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x10, 0x12, 0x15,
|
||||
0x0a, 0x11, 0x53, 0x45, 0x54, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x5f, 0x54, 0x4f, 0x4f, 0x5f,
|
||||
0x4c, 0x4f, 0x57, 0x10, 0x11, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x45, 0x54, 0x5f, 0x4f, 0x56, 0x45,
|
||||
0x52, 0x50, 0x41, 0x49, 0x44, 0x10, 0x12, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f,
|
||||
0x57, 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x10, 0x13, 0x12, 0x13, 0x0a, 0x0f,
|
||||
0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x45, 0x4e, 0x44, 0x10,
|
||||
0x14, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x50, 0x50, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47,
|
||||
0x52, 0x45, 0x53, 0x53, 0x10, 0x15, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, 0x52, 0x43, 0x55, 0x4c,
|
||||
0x41, 0x52, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10, 0x16, 0x2a, 0xae, 0x01, 0x0a, 0x0c, 0x50,
|
||||
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49,
|
||||
0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55,
|
||||
0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x41, 0x49,
|
||||
0x4c, 0x45, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x02, 0x12, 0x13, 0x0a,
|
||||
0x0f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45,
|
||||
0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x45, 0x52, 0x52,
|
||||
0x4f, 0x52, 0x10, 0x04, 0x12, 0x24, 0x0a, 0x20, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x49,
|
||||
0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54,
|
||||
0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x10, 0x05, 0x12, 0x1f, 0x0a, 0x1b, 0x46, 0x41,
|
||||
0x49, 0x4c, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e,
|
||||
0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x06, 0x2a, 0x3c, 0x0a, 0x18, 0x52,
|
||||
0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x48, 0x6f, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72,
|
||||
0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x54, 0x54, 0x4c,
|
||||
0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a,
|
||||
0x06, 0x52, 0x45, 0x53, 0x55, 0x4d, 0x45, 0x10, 0x02, 0x2a, 0x35, 0x0a, 0x10, 0x43, 0x68, 0x61,
|
||||
0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a,
|
||||
0x06, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49, 0x53,
|
||||
0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x55, 0x54, 0x4f, 0x10, 0x02,
|
||||
0x32, 0xb5, 0x0c, 0x0a, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0d, 0x53,
|
||||
0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x32, 0x12, 0x1d, 0x2e, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x6c, 0x6e,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x42, 0x0a,
|
||||
0x0e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x32, 0x12,
|
||||
0x1e, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x63,
|
||||
0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x30,
|
||||
0x01, 0x12, 0x42, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x73, 0x12, 0x1f, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x54,
|
||||
0x72, 0x61, 0x63, 0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x4b, 0x0a, 0x10, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74,
|
||||
0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x65, 0x65, 0x12, 0x1a, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x51, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x12, 0x1d, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65,
|
||||
0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1e, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e,
|
||||
0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x42, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x56, 0x32, 0x12, 0x1d, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x54,
|
||||
0x4c, 0x43, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x12, 0x64, 0x0a, 0x13, 0x52, 0x65, 0x73,
|
||||
0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x12, 0x25, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73,
|
||||
0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6e, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x28, 0x0a, 0x10, 0x61, 0x75, 0x74, 0x6f,
|
||||
0x5f, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0a, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x48, 0x65, 0x69, 0x67,
|
||||
0x68, 0x74, 0x1a, 0x40, 0x0a, 0x12, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x63, 0x6f,
|
||||
0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x3a, 0x02, 0x38, 0x01, 0x22, 0xa8, 0x02, 0x0a, 0x1c, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64,
|
||||
0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x14, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e,
|
||||
0x67, 0x5f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x12, 0x69, 0x6e, 0x63, 0x6f,
|
||||
0x6d, 0x69, 0x6e, 0x67, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x3b,
|
||||
0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23,
|
||||
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c,
|
||||
0x76, 0x65, 0x48, 0x6f, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x41, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70,
|
||||
0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70,
|
||||
0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x61, 0x69, 0x6c, 0x75,
|
||||
0x72, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x12, 0x3d, 0x0a, 0x0c, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x46,
|
||||
0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x43, 0x6f,
|
||||
0x64, 0x65, 0x52, 0x0b, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x22,
|
||||
0x82, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x0a, 0x63,
|
||||
0x68, 0x61, 0x6e, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x13, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12,
|
||||
0x33, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e,
|
||||
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1a, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68,
|
||||
0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x2a, 0x81, 0x04, 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x44, 0x65, 0x74, 0x61,
|
||||
0x69, 0x6c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12,
|
||||
0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x10, 0x01, 0x12, 0x10,
|
||||
0x0a, 0x0c, 0x4f, 0x4e, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x02,
|
||||
0x12, 0x15, 0x0a, 0x11, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x4c, 0x49,
|
||||
0x47, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x4e, 0x5f, 0x43, 0x48,
|
||||
0x41, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x04, 0x12, 0x14, 0x0a,
|
||||
0x10, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x53, 0x5f, 0x4d, 0x41,
|
||||
0x58, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49,
|
||||
0x45, 0x4e, 0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a,
|
||||
0x12, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x46, 0x4f, 0x52, 0x57,
|
||||
0x41, 0x52, 0x44, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x41, 0x44,
|
||||
0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x08, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x4f,
|
||||
0x52, 0x57, 0x41, 0x52, 0x44, 0x53, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10,
|
||||
0x09, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x43, 0x41, 0x4e,
|
||||
0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x15, 0x0a, 0x11, 0x49, 0x4e, 0x56, 0x4f, 0x49,
|
||||
0x43, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x50, 0x41, 0x49, 0x44, 0x10, 0x0b, 0x12, 0x1b,
|
||||
0x0a, 0x17, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x59,
|
||||
0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x53, 0x4f, 0x4f, 0x4e, 0x10, 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x49,
|
||||
0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x10,
|
||||
0x0d, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x50, 0x50, 0x5f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45,
|
||||
0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x0e, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44,
|
||||
0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x0f,
|
||||
0x12, 0x16, 0x0a, 0x12, 0x53, 0x45, 0x54, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x5f, 0x4d, 0x49,
|
||||
0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x10, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x45, 0x54, 0x5f,
|
||||
0x54, 0x4f, 0x54, 0x41, 0x4c, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x11, 0x12,
|
||||
0x10, 0x0a, 0x0c, 0x53, 0x45, 0x54, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x50, 0x41, 0x49, 0x44, 0x10,
|
||||
0x12, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x49, 0x4e, 0x56,
|
||||
0x4f, 0x49, 0x43, 0x45, 0x10, 0x13, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49,
|
||||
0x44, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x45, 0x4e, 0x44, 0x10, 0x14, 0x12, 0x13, 0x0a, 0x0f, 0x4d,
|
||||
0x50, 0x50, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x15,
|
||||
0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, 0x52, 0x43, 0x55, 0x4c, 0x41, 0x52, 0x5f, 0x52, 0x4f, 0x55,
|
||||
0x54, 0x45, 0x10, 0x16, 0x2a, 0xae, 0x01, 0x0a, 0x0c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47,
|
||||
0x48, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45,
|
||||
0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x49,
|
||||
0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x46, 0x41, 0x49, 0x4c, 0x45,
|
||||
0x44, 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c,
|
||||
0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x24,
|
||||
0x0a, 0x20, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45,
|
||||
0x43, 0x54, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49,
|
||||
0x4c, 0x53, 0x10, 0x05, 0x12, 0x1f, 0x0a, 0x1b, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x49,
|
||||
0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41,
|
||||
0x4e, 0x43, 0x45, 0x10, 0x06, 0x2a, 0x3c, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65,
|
||||
0x48, 0x6f, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a,
|
||||
0x04, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x53, 0x55, 0x4d,
|
||||
0x45, 0x10, 0x02, 0x2a, 0x35, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x4e, 0x41, 0x42, 0x4c,
|
||||
0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01,
|
||||
0x12, 0x08, 0x0a, 0x04, 0x41, 0x55, 0x54, 0x4f, 0x10, 0x02, 0x32, 0xb5, 0x0c, 0x0a, 0x06, 0x52,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x56, 0x32, 0x12, 0x1d, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x63, 0x6b,
|
||||
0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x32, 0x12, 0x1e, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x6c, 0x6e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x0d, 0x54,
|
||||
0x72, 0x61, 0x63, 0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e,
|
||||
0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12,
|
||||
0x4b, 0x0a, 0x10, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x46, 0x65, 0x65, 0x12, 0x1a, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1b, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0b,
|
||||
0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x72, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12,
|
||||
0x42, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x56, 0x32,
|
||||
0x12, 0x1d, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e,
|
||||
0x64, 0x54, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x54, 0x4c, 0x43, 0x41, 0x74, 0x74, 0x65,
|
||||
0x6d, 0x70, 0x74, 0x12, 0x64, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x25, 0x2e, 0x72, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x26, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65,
|
||||
0x73, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x13, 0x51, 0x75, 0x65,
|
||||
0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x12, 0x25, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65,
|
||||
0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x64, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x25, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e,
|
||||
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d,
|
||||
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x15, 0x58, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x27,
|
||||
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x58, 0x49, 0x6d, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x58, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x70, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x2e, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f,
|
||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29,
|
||||
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x69,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72,
|
||||
0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x22, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x62, 0x61,
|
||||
0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e,
|
||||
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50,
|
||||
0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x49, 0x0a, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x12, 0x1c, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x69,
|
||||
0x6c, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d,
|
||||
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64,
|
||||
0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a,
|
||||
0x13, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76,
|
||||
0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76,
|
||||
0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76, 0x65, 0x6e,
|
||||
0x74, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x12, 0x1d, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53,
|
||||
0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x18, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x03, 0x88, 0x02, 0x01,
|
||||
0x30, 0x01, 0x12, 0x4f, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x54,
|
||||
0x72, 0x61, 0x63, 0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x50,
|
||||
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x03, 0x88, 0x02,
|
||||
0x01, 0x30, 0x01, 0x12, 0x66, 0x0a, 0x0f, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x27, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a,
|
||||
0x26, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x77,
|
||||
0x61, 0x72, 0x64, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, 0x12, 0x5b, 0x0a, 0x10, 0x55,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
|
||||
0x22, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x31, 0x5a, 0x2f, 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, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x6a, 0x0a, 0x15, 0x58, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x27, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x72, 0x72, 0x70, 0x63, 0x2e, 0x58, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x28, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x58, 0x49,
|
||||
0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x17, 0x47,
|
||||
0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a,
|
||||
0x17, 0x53, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x53, 0x65, 0x74, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x5b, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c,
|
||||
0x69, 0x74, 0x79, 0x12, 0x22, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69,
|
||||
0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0a,
|
||||
0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x72, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x72, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x73, 0x63,
|
||||
0x72, 0x69, 0x62, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25,
|
||||
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63,
|
||||
0x72, 0x69, 0x62, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x48, 0x74, 0x6c, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x4d, 0x0a,
|
||||
0x0b, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x2e, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x03, 0x88, 0x02, 0x01, 0x30, 0x01, 0x12, 0x4f, 0x0a, 0x0c,
|
||||
0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x03, 0x88, 0x02, 0x01, 0x30, 0x01, 0x12, 0x66, 0x0a,
|
||||
0x0f, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72,
|
||||
0x12, 0x27, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72,
|
||||
0x77, 0x61, 0x72, 0x64, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x26, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x48, 0x74, 0x6c,
|
||||
0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x28, 0x01, 0x30, 0x01, 0x12, 0x5b, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43,
|
||||
0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e,
|
||||
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e,
|
||||
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x43, 0x68, 0x61, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x42, 0x31, 0x5a, 0x2f, 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, 0x2f, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -792,6 +792,10 @@ message ForwardHtlcInterceptRequest {
|
||||
|
||||
// The onion blob for the next hop
|
||||
bytes onion_blob = 9;
|
||||
|
||||
// The block height at which this htlc will be auto-failed to prevent the
|
||||
// channel from force-closing.
|
||||
int32 auto_fail_height = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1229,6 +1229,11 @@
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"title": "The onion blob for the next hop"
|
||||
},
|
||||
"auto_fail_height": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "The block height at which this htlc will be auto-failed to prevent the\nchannel from force-closing."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -359,6 +359,24 @@ func createTestPeer(t *testing.T, notifier chainntnfs.ChainNotifier,
|
||||
ChainNet: wire.SimNet,
|
||||
}
|
||||
|
||||
interceptableSwitchNotifier := &mock.ChainNotifier{
|
||||
EpochChan: make(chan *chainntnfs.BlockEpoch, 1),
|
||||
}
|
||||
interceptableSwitchNotifier.EpochChan <- &chainntnfs.BlockEpoch{
|
||||
Height: 1,
|
||||
}
|
||||
|
||||
interceptableSwitch, err := htlcswitch.NewInterceptableSwitch(
|
||||
&htlcswitch.InterceptableSwitchConfig{
|
||||
CltvRejectDelta: testCltvRejectDelta,
|
||||
CltvInterceptDelta: testCltvRejectDelta + 3,
|
||||
Notifier: interceptableSwitchNotifier,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cfg := &Config{
|
||||
Addr: cfgAddr,
|
||||
PubKeyBytes: pubKey,
|
||||
@ -366,16 +384,14 @@ func createTestPeer(t *testing.T, notifier chainntnfs.ChainNotifier,
|
||||
ChainIO: chainIO,
|
||||
Switch: mockSwitch,
|
||||
ChanActiveTimeout: chanActiveTimeout,
|
||||
InterceptSwitch: htlcswitch.NewInterceptableSwitch(
|
||||
nil, testCltvRejectDelta, false,
|
||||
),
|
||||
ChannelDB: dbAlice.ChannelStateDB(),
|
||||
FeeEstimator: estimator,
|
||||
Wallet: wallet,
|
||||
ChainNotifier: notifier,
|
||||
ChanStatusMgr: chanStatusMgr,
|
||||
Features: lnwire.NewFeatureVector(nil, lnwire.Features),
|
||||
DisconnectPeer: func(b *btcec.PublicKey) error { return nil },
|
||||
InterceptSwitch: interceptableSwitch,
|
||||
ChannelDB: dbAlice.ChannelStateDB(),
|
||||
FeeEstimator: estimator,
|
||||
Wallet: wallet,
|
||||
ChainNotifier: notifier,
|
||||
ChanStatusMgr: chanStatusMgr,
|
||||
Features: lnwire.NewFeatureVector(nil, lnwire.Features),
|
||||
DisconnectPeer: func(b *btcec.PublicKey) error { return nil },
|
||||
}
|
||||
|
||||
alicePeer := NewBrontide(*cfg)
|
||||
|
14
server.go
14
server.go
@ -666,10 +666,18 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.interceptableSwitch = htlcswitch.NewInterceptableSwitch(
|
||||
s.htlcSwitch, lncfg.DefaultFinalCltvRejectDelta,
|
||||
s.cfg.RequireInterceptor,
|
||||
s.interceptableSwitch, err = htlcswitch.NewInterceptableSwitch(
|
||||
&htlcswitch.InterceptableSwitchConfig{
|
||||
Switch: s.htlcSwitch,
|
||||
CltvRejectDelta: lncfg.DefaultFinalCltvRejectDelta,
|
||||
CltvInterceptDelta: lncfg.DefaultCltvInterceptDelta,
|
||||
RequireInterceptor: s.cfg.RequireInterceptor,
|
||||
Notifier: s.cc.ChainNotifier,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.witnessBeacon = newPreimageBeacon(
|
||||
dbs.ChanStateDB.NewWitnessCache(),
|
||||
|
Loading…
Reference in New Issue
Block a user