From 7a44eec36fde4a4008091132973b060142a76c7d Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Wed, 29 Apr 2020 18:30:44 +0200 Subject: [PATCH 1/9] loopin: refactor LoopIn to return struct instead of tuple --- client.go | 12 ++++++++---- interface.go | 11 +++++++++++ loopd/swapclient_server.go | 8 ++++---- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/client.go b/client.go index d5eece9..720b99b 100644 --- a/client.go +++ b/client.go @@ -464,7 +464,7 @@ func (s *Client) waitForInitialized(ctx context.Context) error { // LoopIn initiates a loop in swap. func (s *Client) LoopIn(globalCtx context.Context, - request *LoopInRequest) (*lntypes.Hash, btcutil.Address, error) { + request *LoopInRequest) (*LoopInSwapInfo, error) { log.Infof("Loop in %v (last hop: %v)", request.Amount, @@ -472,7 +472,7 @@ func (s *Client) LoopIn(globalCtx context.Context, ) if err := s.waitForInitialized(globalCtx); err != nil { - return nil, nil, err + return nil, err } // Create a new swap object for this swap. @@ -486,7 +486,7 @@ func (s *Client) LoopIn(globalCtx context.Context, globalCtx, &swapCfg, initiationHeight, request, ) if err != nil { - return nil, nil, err + return nil, err } // Post swap to the main loop. @@ -494,7 +494,11 @@ func (s *Client) LoopIn(globalCtx context.Context, // Return hash so that the caller can identify this swap in the updates // stream. - return &swap.hash, swap.htlc.Address, nil + swapInfo := &LoopInSwapInfo{ + SwapHash: swap.hash, + HtlcAddress: swap.htlc.Address, + } + return swapInfo, nil } // LoopInQuote takes an amount and returns a break down of estimated diff --git a/interface.go b/interface.go index 98850b8..e718178 100644 --- a/interface.go +++ b/interface.go @@ -235,6 +235,17 @@ type LoopInQuote struct { CltvDelta int32 } +// LoopInSwapInfo contains essential information of a loop-in swap after the +// swap is initiated. +type LoopInSwapInfo struct { // nolint + // SwapHash contains the sha256 hash of the swap preimage. + SwapHash lntypes.Hash + + // HtlcAddress contains the swap htlc address, where the loop-in + // funds will be paid. + HtlcAddress btcutil.Address +} + // SwapInfoKit contains common swap info fields. type SwapInfoKit struct { // Hash is the sha256 hash of the preimage that unlocks the htlcs. It diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index c896d5c..f3528d9 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -409,16 +409,16 @@ func (s *swapClientServer) LoopIn(ctx context.Context, } req.LastHop = &lastHop } - hash, htlc, err := s.impl.LoopIn(ctx, req) + swapInfo, err := s.impl.LoopIn(ctx, req) if err != nil { log.Errorf("Loop in: %v", err) return nil, err } return &looprpc.SwapResponse{ - Id: hash.String(), - IdBytes: hash[:], - HtlcAddress: htlc.String(), + Id: swapInfo.SwapHash.String(), + IdBytes: swapInfo.SwapHash[:], + HtlcAddress: swapInfo.HtlcAddress.String(), }, nil } From b2b0bad951e588cf2df08d296305156893125b78 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Wed, 29 Apr 2020 19:47:27 +0200 Subject: [PATCH 2/9] loopin+loopout: move htlc out of swapKit This commit moves htlc out of swapkit in preparation of adding separate p2wsh and np2wsh htlcs to loop-in swaps. --- loopin.go | 42 ++++++++++++++++++++++++++++++++++----- loopout.go | 43 +++++++++++++++++++++++++++++++++++----- swap.go | 58 +++++++++++++++++++++--------------------------------- 3 files changed, 97 insertions(+), 46 deletions(-) diff --git a/loopin.go b/loopin.go index 98a979e..510facc 100644 --- a/loopin.go +++ b/loopin.go @@ -48,8 +48,12 @@ var ( type loopInSwap struct { swapKit + executeConfig + loopdb.LoopInContract + htlc *swap.Htlc + timeoutAddr btcutil.Address } @@ -148,19 +152,25 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig, }, } - swapKit, err := newSwapKit( + swapKit := newSwapKit( swapHash, swap.TypeIn, cfg, &contract.SwapContract, - swap.HtlcNP2WSH, ) + + swapKit.lastUpdateTime = initiationTime + + // Create the htlc. + htlc, err := swapKit.getHtlc(swap.HtlcNP2WSH) if err != nil { return nil, err } - swapKit.lastUpdateTime = initiationTime + // Log htlc address for debugging. + swapKit.log.Infof("Htlc address: %v", htlc.Address) swap := &loopInSwap{ LoopInContract: contract, swapKit: *swapKit, + htlc: htlc, } // Persist the data before exiting this function, so that the caller can @@ -182,17 +192,23 @@ func resumeLoopInSwap(reqContext context.Context, cfg *swapConfig, log.Infof("Resuming loop in swap %v", hash) - swapKit, err := newSwapKit( + swapKit := newSwapKit( hash, swap.TypeIn, cfg, &pend.Contract.SwapContract, - swap.HtlcNP2WSH, ) + + // Create the htlc. + htlc, err := swapKit.getHtlc(swap.HtlcNP2WSH) if err != nil { return nil, err } + // Log htlc address for debugging. + swapKit.log.Infof("Htlc address: %v", htlc.Address) + swap := &loopInSwap{ LoopInContract: *pend.Contract, swapKit: *swapKit, + htlc: htlc, } lastUpdate := pend.LastUpdate() @@ -222,6 +238,22 @@ func validateLoopInContract(lnd *lndclient.LndServices, return nil } +// sendUpdate reports an update to the swap state. +func (s *loopInSwap) sendUpdate(ctx context.Context) error { + info := s.swapInfo() + s.log.Infof("Loop in swap state: %v", info.State) + + info.HtlcAddress = s.htlc.Address + + select { + case s.statusChan <- *info: + case <-ctx.Done(): + return ctx.Err() + } + + return nil +} + // execute starts/resumes the swap. It is a thin wrapper around executeSwap to // conveniently handle the error case. func (s *loopInSwap) execute(mainCtx context.Context, diff --git a/loopout.go b/loopout.go index ab3ed5d..15c08b3 100644 --- a/loopout.go +++ b/loopout.go @@ -52,6 +52,10 @@ type loopOutSwap struct { loopdb.LoopOutContract + executeConfig + + htlc *swap.Htlc + swapPaymentChan chan lndclient.PaymentResult prePaymentChan chan lndclient.PaymentResult } @@ -134,19 +138,25 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig, }, } - swapKit, err := newSwapKit( + swapKit := newSwapKit( swapHash, swap.TypeOut, cfg, &contract.SwapContract, - swap.HtlcP2WSH, ) + + swapKit.lastUpdateTime = initiationTime + + // Create the htlc. + htlc, err := swapKit.getHtlc(swap.HtlcP2WSH) if err != nil { return nil, err } - swapKit.lastUpdateTime = initiationTime + // Log htlc address for debugging. + swapKit.log.Infof("Htlc address: %v", htlc.Address) swap := &loopOutSwap{ LoopOutContract: contract, swapKit: *swapKit, + htlc: htlc, } // Persist the data before exiting this function, so that the caller @@ -168,17 +178,24 @@ func resumeLoopOutSwap(reqContext context.Context, cfg *swapConfig, log.Infof("Resuming loop out swap %v", hash) - swapKit, err := newSwapKit( + swapKit := newSwapKit( hash, swap.TypeOut, cfg, &pend.Contract.SwapContract, - swap.HtlcP2WSH, ) + + // Create the htlc. + htlc, err := swapKit.getHtlc(swap.HtlcP2WSH) if err != nil { return nil, err } + // Log htlc address for debugging. + swapKit.log.Infof("Htlc address: %v", htlc.Address) + + // Create the swap. swap := &loopOutSwap{ LoopOutContract: *pend.Contract, swapKit: *swapKit, + htlc: htlc, } lastUpdate := pend.LastUpdate() @@ -192,6 +209,22 @@ func resumeLoopOutSwap(reqContext context.Context, cfg *swapConfig, return swap, nil } +// sendUpdate reports an update to the swap state. +func (s *loopOutSwap) sendUpdate(ctx context.Context) error { + info := s.swapInfo() + s.log.Infof("Loop out swap state: %v", info.State) + + info.HtlcAddress = s.htlc.Address + + select { + case s.statusChan <- *info: + case <-ctx.Done(): + return ctx.Err() + } + + return nil +} + // execute starts/resumes the swap. It is a thin wrapper around // executeAndFinalize to conveniently handle the error case. func (s *loopOutSwap) execute(mainCtx context.Context, diff --git a/swap.go b/swap.go index a6261ef..a00e4b8 100644 --- a/swap.go +++ b/swap.go @@ -11,7 +11,6 @@ import ( ) type swapKit struct { - htlc *swap.Htlc hash lntypes.Hash height int32 @@ -19,51 +18,49 @@ type swapKit struct { log *swap.PrefixLog lastUpdateTime time.Time - cost loopdb.SwapCost - state loopdb.SwapState - executeConfig - swapConfig + + cost loopdb.SwapCost + + state loopdb.SwapState contract *loopdb.SwapContract + swapType swap.Type + + swapConfig } func newSwapKit(hash lntypes.Hash, swapType swap.Type, cfg *swapConfig, - contract *loopdb.SwapContract, outputType swap.HtlcOutputType) ( - *swapKit, error) { - - // Compose expected on-chain swap script - htlc, err := swap.NewHtlc( - contract.CltvExpiry, contract.SenderKey, - contract.ReceiverKey, hash, outputType, - cfg.lnd.ChainParams, - ) - if err != nil { - return nil, err - } + contract *loopdb.SwapContract) *swapKit { log := &swap.PrefixLog{ Hash: hash, Logger: log, } - // Log htlc address for debugging. - log.Infof("Htlc address: %v", htlc.Address) - return &swapKit{ swapConfig: *cfg, hash: hash, log: log, - htlc: htlc, state: loopdb.StateInitiated, contract: contract, swapType: swapType, - }, nil + } +} + +// getHtlc composes and returns the on-chain swap script. +func (s *swapKit) getHtlc(outputType swap.HtlcOutputType) (*swap.Htlc, error) { + return swap.NewHtlc( + s.contract.CltvExpiry, s.contract.SenderKey, + s.contract.ReceiverKey, s.hash, outputType, + s.swapConfig.lnd.ChainParams, + ) } -// sendUpdate reports an update to the swap state. -func (s *swapKit) sendUpdate(ctx context.Context) error { - info := &SwapInfo{ +// swapInfo constructs and returns a filled SwapInfo from +// the swapKit. +func (s *swapKit) swapInfo() *SwapInfo { + return &SwapInfo{ SwapContract: *s.contract, SwapHash: s.hash, SwapType: s.swapType, @@ -72,18 +69,7 @@ func (s *swapKit) sendUpdate(ctx context.Context) error { State: s.state, Cost: s.cost, }, - HtlcAddress: s.htlc.Address, } - - s.log.Infof("state %v", info.State) - - select { - case s.statusChan <- *info: - case <-ctx.Done(): - return ctx.Err() - } - - return nil } type genericSwap interface { From 87cc5571efcd40a8c8c211b8cb7d3071e096c0d7 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Thu, 30 Apr 2020 15:54:48 +0200 Subject: [PATCH 3/9] general: add ExternalHtlc to SwapInfo and add comments --- interface.go | 11 +++++++++-- loopin.go | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/interface.go b/interface.go index e718178..6f1942c 100644 --- a/interface.go +++ b/interface.go @@ -260,15 +260,22 @@ type SwapInfoKit struct { type SwapInfo struct { loopdb.SwapStateData + loopdb.SwapContract + + // LastUpdateTime is the time of the last state change. LastUpdate time.Time + // SwapHash stores the swap preimage hash. SwapHash lntypes.Hash + // SwapType describes whether this is a loop in or loop out swap. SwapType swap.Type - loopdb.SwapContract - + // HtlcAddress holds the HTLC address of the swap. HtlcAddress btcutil.Address + + // ExternalHtlc is set to true for external loop-in swaps. + ExternalHtlc bool } // LastUpdate returns the last update time of the swap diff --git a/loopin.go b/loopin.go index 510facc..1cd2633 100644 --- a/loopin.go +++ b/loopin.go @@ -244,6 +244,7 @@ func (s *loopInSwap) sendUpdate(ctx context.Context) error { s.log.Infof("Loop in swap state: %v", info.State) info.HtlcAddress = s.htlc.Address + info.ExternalHtlc = s.ExternalHtlc select { case s.statusChan <- *info: From 60661504a5acef513ab9f829b840b98878d53d48 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Thu, 30 Apr 2020 15:37:01 +0200 Subject: [PATCH 4/9] htlc: add string representation for HtlcOutputType enum --- swap/htlc.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/swap/htlc.go b/swap/htlc.go index 539a187..c207b3d 100644 --- a/swap/htlc.go +++ b/swap/htlc.go @@ -50,6 +50,20 @@ var ( ) ) +// String returns the string value of HtlcOutputType. +func (h HtlcOutputType) String() string { + switch h { + case HtlcP2WSH: + return "P2WSH" + + case HtlcNP2WSH: + return "NP2WSH" + + default: + return "unknown" + } +} + // NewHtlc returns a new instance. func NewHtlc(cltvExpiry int32, senderKey, receiverKey [33]byte, hash lntypes.Hash, outputType HtlcOutputType, From 62f654eef1cd48b2732fd9eb8aac0eab827ebefa Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Thu, 30 Apr 2020 15:48:58 +0200 Subject: [PATCH 5/9] client: make ListSwaps thread safe --- loopd/swapclient_server.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index f3528d9..0616cc8 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -255,6 +255,9 @@ func (s *swapClientServer) ListSwaps(_ context.Context, err error ) + s.swapsLock.Lock() + defer s.swapsLock.Unlock() + // We can just use the server's in-memory cache as that contains the // most up-to-date state including temporary failures which aren't // persisted to disk. The swaps field is a map, that's why we need an From f0aff9b7bdb9260c94a35178bba07ff1f0d55744 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Fri, 24 Apr 2020 17:35:32 +0200 Subject: [PATCH 6/9] looprpc+loopin: support for native segwit htlcs This commit extends SwapResponse and SwapStatus with np2wsh and p2wsh htlc output addresses to support both nested and native segwit htlcs in loop-in. Furthermore the commit adds support for native segwith loop-in htlcs. When the htlc is paid internally, as of this commit we'll use NP2WSH, otherwise users are free to select whether to pay the NP2WSH or the P2WSH htlc. --- client.go | 41 +++--- interface.go | 19 ++- loopd/swapclient_server.go | 53 +++++--- loopin.go | 94 ++++++++++---- loopin_test.go | 51 +++++--- loopout.go | 2 +- looprpc/client.pb.go | 250 ++++++++++++++++++++++-------------- looprpc/client.proto | 39 +++++- looprpc/client.swagger.json | 20 ++- 9 files changed, 388 insertions(+), 181 deletions(-) diff --git a/client.go b/client.go index 720b99b..9b8161f 100644 --- a/client.go +++ b/client.go @@ -194,17 +194,17 @@ func (s *Client) FetchSwaps() ([]*SwapInfo, error) { } swaps = append(swaps, &SwapInfo{ - SwapType: swap.TypeOut, - SwapContract: swp.Contract.SwapContract, - SwapStateData: swp.State(), - SwapHash: swp.Hash, - LastUpdate: swp.LastUpdateTime(), - HtlcAddress: htlc.Address, + SwapType: swap.TypeOut, + SwapContract: swp.Contract.SwapContract, + SwapStateData: swp.State(), + SwapHash: swp.Hash, + LastUpdate: swp.LastUpdateTime(), + HtlcAddressP2WSH: htlc.Address, }) } for _, swp := range loopInSwaps { - htlc, err := swap.NewHtlc( + htlcNP2WSH, err := swap.NewHtlc( swp.Contract.CltvExpiry, swp.Contract.SenderKey, swp.Contract.ReceiverKey, swp.Hash, swap.HtlcNP2WSH, s.lndServices.ChainParams, @@ -213,13 +213,23 @@ func (s *Client) FetchSwaps() ([]*SwapInfo, error) { return nil, err } + htlcP2WSH, err := swap.NewHtlc( + swp.Contract.CltvExpiry, swp.Contract.SenderKey, + swp.Contract.ReceiverKey, swp.Hash, swap.HtlcP2WSH, + s.lndServices.ChainParams, + ) + if err != nil { + return nil, err + } + swaps = append(swaps, &SwapInfo{ - SwapType: swap.TypeIn, - SwapContract: swp.Contract.SwapContract, - SwapStateData: swp.State(), - SwapHash: swp.Hash, - LastUpdate: swp.LastUpdateTime(), - HtlcAddress: htlc.Address, + SwapType: swap.TypeIn, + SwapContract: swp.Contract.SwapContract, + SwapStateData: swp.State(), + SwapHash: swp.Hash, + LastUpdate: swp.LastUpdateTime(), + HtlcAddressP2WSH: htlcP2WSH.Address, + HtlcAddressNP2WSH: htlcNP2WSH.Address, }) } @@ -495,8 +505,9 @@ func (s *Client) LoopIn(globalCtx context.Context, // Return hash so that the caller can identify this swap in the updates // stream. swapInfo := &LoopInSwapInfo{ - SwapHash: swap.hash, - HtlcAddress: swap.htlc.Address, + SwapHash: swap.hash, + HtlcAddressP2WSH: swap.htlcP2WSH.Address, + HtlcAddressNP2WSH: swap.htlcNP2WSH.Address, } return swapInfo, nil } diff --git a/interface.go b/interface.go index 6f1942c..f702a45 100644 --- a/interface.go +++ b/interface.go @@ -241,9 +241,13 @@ type LoopInSwapInfo struct { // nolint // SwapHash contains the sha256 hash of the swap preimage. SwapHash lntypes.Hash - // HtlcAddress contains the swap htlc address, where the loop-in - // funds will be paid. - HtlcAddress btcutil.Address + // HtlcAddressP2WSH contains the native segwit swap htlc address, + // where the loop-in funds may be paid. + HtlcAddressP2WSH btcutil.Address + + // HtlcAddressNP2WSH contains the nested segwit swap htlc address, + // where the loop-in funds may be paid. + HtlcAddressNP2WSH btcutil.Address } // SwapInfoKit contains common swap info fields. @@ -271,8 +275,13 @@ type SwapInfo struct { // SwapType describes whether this is a loop in or loop out swap. SwapType swap.Type - // HtlcAddress holds the HTLC address of the swap. - HtlcAddress btcutil.Address + // HtlcAddressP2WSH stores the address of the P2WSH (native segwit) + // swap htlc. This is used for both loop-in and loop-out. + HtlcAddressP2WSH btcutil.Address + + // HtlcAddressNP2WSH stores the address of the NP2WSH (nested segwit) + // swap htlc. This is only used for external loop-in. + HtlcAddressNP2WSH btcutil.Address // ExternalHtlc is set to true for external loop-in swaps. ExternalHtlc bool diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index 0616cc8..8fae91d 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -126,27 +126,40 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) ( } var swapType looprpc.SwapType + var htlcAddress, htlcAddressP2WSH, htlcAddressNP2WSH string + switch loopSwap.SwapType { case swap.TypeIn: swapType = looprpc.SwapType_LOOP_IN + if loopSwap.ExternalHtlc { + htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress() + } + htlcAddressNP2WSH = loopSwap.HtlcAddressNP2WSH.EncodeAddress() + htlcAddress = htlcAddressNP2WSH + case swap.TypeOut: swapType = looprpc.SwapType_LOOP_OUT + htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress() + htlcAddress = htlcAddressP2WSH + default: return nil, errors.New("unknown swap type") } return &looprpc.SwapStatus{ - Amt: int64(loopSwap.AmountRequested), - Id: loopSwap.SwapHash.String(), - IdBytes: loopSwap.SwapHash[:], - State: state, - InitiationTime: loopSwap.InitiationTime.UnixNano(), - LastUpdateTime: loopSwap.LastUpdate.UnixNano(), - HtlcAddress: loopSwap.HtlcAddress.EncodeAddress(), - Type: swapType, - CostServer: int64(loopSwap.Cost.Server), - CostOnchain: int64(loopSwap.Cost.Onchain), - CostOffchain: int64(loopSwap.Cost.Offchain), + Amt: int64(loopSwap.AmountRequested), + Id: loopSwap.SwapHash.String(), + IdBytes: loopSwap.SwapHash[:], + State: state, + InitiationTime: loopSwap.InitiationTime.UnixNano(), + LastUpdateTime: loopSwap.LastUpdate.UnixNano(), + HtlcAddress: htlcAddress, + HtlcAddressP2Wsh: htlcAddressP2WSH, + HtlcAddressNp2Wsh: htlcAddressNP2WSH, + Type: swapType, + CostServer: int64(loopSwap.Cost.Server), + CostOnchain: int64(loopSwap.Cost.Onchain), + CostOffchain: int64(loopSwap.Cost.Offchain), }, nil } @@ -418,11 +431,19 @@ func (s *swapClientServer) LoopIn(ctx context.Context, return nil, err } - return &looprpc.SwapResponse{ - Id: swapInfo.SwapHash.String(), - IdBytes: swapInfo.SwapHash[:], - HtlcAddress: swapInfo.HtlcAddress.String(), - }, nil + np2wshAddress := swapInfo.HtlcAddressNP2WSH.String() + response := &looprpc.SwapResponse{ + Id: swapInfo.SwapHash.String(), + IdBytes: swapInfo.SwapHash[:], + HtlcAddress: np2wshAddress, + HtlcAddressNp2Wsh: np2wshAddress, + } + + if req.ExternalHtlc { + response.HtlcAddressP2Wsh = swapInfo.HtlcAddressP2WSH.String() + } + + return response, nil } // GetLsatTokens returns all tokens that are contained in the LSAT token store. diff --git a/loopin.go b/loopin.go index 1cd2633..8b1bcdb 100644 --- a/loopin.go +++ b/loopin.go @@ -54,6 +54,10 @@ type loopInSwap struct { htlc *swap.Htlc + htlcP2WSH *swap.Htlc + + htlcNP2WSH *swap.Htlc + timeoutAddr btcutil.Address } @@ -158,19 +162,13 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig, swapKit.lastUpdateTime = initiationTime - // Create the htlc. - htlc, err := swapKit.getHtlc(swap.HtlcNP2WSH) - if err != nil { - return nil, err - } - - // Log htlc address for debugging. - swapKit.log.Infof("Htlc address: %v", htlc.Address) - swap := &loopInSwap{ LoopInContract: contract, swapKit: *swapKit, - htlc: htlc, + } + + if err := swap.initHtlcs(); err != nil { + return nil, err } // Persist the data before exiting this function, so that the caller can @@ -196,19 +194,13 @@ func resumeLoopInSwap(reqContext context.Context, cfg *swapConfig, hash, swap.TypeIn, cfg, &pend.Contract.SwapContract, ) - // Create the htlc. - htlc, err := swapKit.getHtlc(swap.HtlcNP2WSH) - if err != nil { - return nil, err - } - - // Log htlc address for debugging. - swapKit.log.Infof("Htlc address: %v", htlc.Address) - swap := &loopInSwap{ LoopInContract: *pend.Contract, swapKit: *swapKit, - htlc: htlc, + } + + if err := swap.initHtlcs(); err != nil { + return nil, err } lastUpdate := pend.LastUpdate() @@ -238,12 +230,36 @@ func validateLoopInContract(lnd *lndclient.LndServices, return nil } +// initHtlcs creates and updates the native and nested segwit htlcs +// of the loopInSwap. +func (s *loopInSwap) initHtlcs() error { + htlcP2WSH, err := s.swapKit.getHtlc(swap.HtlcP2WSH) + if err != nil { + return err + } + + htlcNP2WSH, err := s.swapKit.getHtlc(swap.HtlcNP2WSH) + if err != nil { + return err + } + + // Log htlc addresses for debugging. + s.swapKit.log.Infof("Htlc address (P2WSH): %v", htlcP2WSH.Address) + s.swapKit.log.Infof("Htlc address (NP2WSH): %v", htlcNP2WSH.Address) + + s.htlcP2WSH = htlcP2WSH + s.htlcNP2WSH = htlcNP2WSH + + return nil +} + // sendUpdate reports an update to the swap state. func (s *loopInSwap) sendUpdate(ctx context.Context) error { info := s.swapInfo() s.log.Infof("Loop in swap state: %v", info.State) - info.HtlcAddress = s.htlc.Address + info.HtlcAddressP2WSH = s.htlcP2WSH.Address + info.HtlcAddressNP2WSH = s.htlcNP2WSH.Address info.ExternalHtlc = s.ExternalHtlc select { @@ -373,21 +389,44 @@ func (s *loopInSwap) waitForHtlcConf(globalCtx context.Context) ( ctx, cancel := context.WithCancel(globalCtx) defer cancel() - confChan, confErr, err := s.lnd.ChainNotifier.RegisterConfirmationsNtfn( - ctx, nil, s.htlc.PkScript, 1, s.InitiationHeight, + + notifier := s.lnd.ChainNotifier + + confChanP2WSH, confErrP2WSH, err := notifier.RegisterConfirmationsNtfn( + ctx, nil, s.htlcP2WSH.PkScript, 1, s.InitiationHeight, + ) + if err != nil { + return nil, err + } + + confChanNP2WSH, confErrNP2WSH, err := notifier.RegisterConfirmationsNtfn( + ctx, nil, s.htlcNP2WSH.PkScript, 1, s.InitiationHeight, ) if err != nil { return nil, err } + for { select { - // Htlc confirmed. - case conf := <-confChan: + // P2WSH htlc confirmed. + case conf := <-confChanP2WSH: + s.htlc = s.htlcP2WSH + s.log.Infof("P2WSH htlc confirmed") + return conf, nil + + // NP2WSH htlc confirmed. + case conf := <-confChanNP2WSH: + s.htlc = s.htlcNP2WSH + s.log.Infof("NP2WSH htlc confirmed") return conf, nil // Conf ntfn error. - case err := <-confErr: + case err := <-confErrP2WSH: + return nil, err + + // Conf ntfn error. + case err := <-confErrNP2WSH: return nil, err // Keep up with block height. @@ -432,9 +471,10 @@ func (s *loopInSwap) publishOnChainHtlc(ctx context.Context) (bool, error) { } s.log.Infof("Publishing on chain HTLC with fee rate %v", feeRate) + tx, err := s.lnd.WalletKit.SendOutputs(ctx, []*wire.TxOut{{ - PkScript: s.htlc.PkScript, + PkScript: s.htlcNP2WSH.PkScript, Value: int64(s.LoopInContract.AmountRequested), }}, feeRate, diff --git a/loopin_test.go b/loopin_test.go index f74ac75..8c15705 100644 --- a/loopin_test.go +++ b/loopin_test.go @@ -67,6 +67,7 @@ func TestLoopInSuccess(t *testing.T) { // Expect register for htlc conf. <-ctx.lnd.RegisterConfChannel + <-ctx.lnd.RegisterConfChannel // Confirm htlc. ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{ @@ -118,20 +119,32 @@ func TestLoopInSuccess(t *testing.T) { func TestLoopInTimeout(t *testing.T) { testAmt := int64(testLoopInRequest.Amount) t.Run("internal htlc", func(t *testing.T) { - testLoopInTimeout(t, 0) - }) - t.Run("external htlc", func(t *testing.T) { - testLoopInTimeout(t, testAmt) - }) - t.Run("external amount too high", func(t *testing.T) { - testLoopInTimeout(t, testAmt+1) - }) - t.Run("external amount too low", func(t *testing.T) { - testLoopInTimeout(t, testAmt-1) + testLoopInTimeout(t, swap.HtlcNP2WSH, 0) }) + + outputTypes := []swap.HtlcOutputType{swap.HtlcP2WSH, swap.HtlcNP2WSH} + + for _, outputType := range outputTypes { + outputType := outputType + t.Run(outputType.String(), func(t *testing.T) { + t.Run("external htlc", func(t *testing.T) { + testLoopInTimeout(t, outputType, testAmt) + }) + + t.Run("external amount too high", func(t *testing.T) { + testLoopInTimeout(t, outputType, testAmt+1) + }) + + t.Run("external amount too low", func(t *testing.T) { + testLoopInTimeout(t, outputType, testAmt-1) + }) + }) + } } -func testLoopInTimeout(t *testing.T, externalValue int64) { +func testLoopInTimeout(t *testing.T, + outputType swap.HtlcOutputType, externalValue int64) { + defer test.Guard(t)() ctx := newLoopInTestContext(t) @@ -149,7 +162,7 @@ func testLoopInTimeout(t *testing.T, externalValue int64) { req.ExternalHtlc = true } - swap, err := newLoopInSwap( + s, err := newLoopInSwap( context.Background(), cfg, height, &req, ) @@ -161,7 +174,7 @@ func testLoopInTimeout(t *testing.T, externalValue int64) { errChan := make(chan error) go func() { - err := swap.execute(context.Background(), ctx.cfg, height) + err := s.execute(context.Background(), ctx.cfg, height) if err != nil { log.Error(err) } @@ -179,10 +192,16 @@ func testLoopInTimeout(t *testing.T, externalValue int64) { htlcTx = <-ctx.lnd.SendOutputsChannel } else { // Create an external htlc publish tx. + var pkScript []byte + if outputType == swap.HtlcNP2WSH { + pkScript = s.htlcNP2WSH.PkScript + } else { + pkScript = s.htlcP2WSH.PkScript + } htlcTx = wire.MsgTx{ TxOut: []*wire.TxOut{ { - PkScript: swap.htlc.PkScript, + PkScript: pkScript, Value: externalValue, }, }, @@ -191,6 +210,7 @@ func testLoopInTimeout(t *testing.T, externalValue int64) { // Expect register for htlc conf. <-ctx.lnd.RegisterConfChannel + <-ctx.lnd.RegisterConfChannel // Confirm htlc. ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{ @@ -207,7 +227,7 @@ func testLoopInTimeout(t *testing.T, externalValue int64) { } // Let htlc expire. - ctx.blockEpochChan <- swap.LoopInContract.CltvExpiry + ctx.blockEpochChan <- s.LoopInContract.CltvExpiry // Expect a signing request for the htlc tx output value. signReq := <-ctx.lnd.SignOutputRawChannel @@ -378,6 +398,7 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool) { // Expect register for htlc conf. <-ctx.lnd.RegisterConfChannel + <-ctx.lnd.RegisterConfChannel // Confirm htlc. ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{ diff --git a/loopout.go b/loopout.go index 15c08b3..7204dc9 100644 --- a/loopout.go +++ b/loopout.go @@ -214,7 +214,7 @@ func (s *loopOutSwap) sendUpdate(ctx context.Context) error { info := s.swapInfo() s.log.Infof("Loop out swap state: %v", info.State) - info.HtlcAddress = s.htlc.Address + info.HtlcAddressP2WSH = s.htlc.Address select { case s.statusChan <- *info: diff --git a/looprpc/client.pb.go b/looprpc/client.pb.go index 51bd965..e40bae0 100644 --- a/looprpc/client.pb.go +++ b/looprpc/client.pb.go @@ -379,8 +379,23 @@ type SwapResponse struct { //the Start() call. Currently this is the hash that locks the htlcs. IdBytes []byte `protobuf:"bytes,3,opt,name=id_bytes,json=idBytes,proto3" json:"id_bytes,omitempty"` //* - //The address of the on-chain htlc. - HtlcAddress string `protobuf:"bytes,2,opt,name=htlc_address,json=htlcAddress,proto3" json:"htlc_address,omitempty"` + //DEPRECATED. This field stores the address of the onchain htlc, but + //depending on the request, the semantics are different. + //- For internal loop-in htlc_address contains the address of the + //native segwit (P2WSH) htlc. + //- For external loop-in htlc_address contains the address of the + //nested segwit (NP2WSH) htlc. + //- For loop-out htlc_address always contains the native segwit (P2WSH) + //htlc address. + HtlcAddress string `protobuf:"bytes,2,opt,name=htlc_address,json=htlcAddress,proto3" json:"htlc_address,omitempty"` // Deprecated: Do not use. + //* + //The nested segwit address of the on-chain htlc. + //This field remains empty for loop-out. + HtlcAddressNp2Wsh string `protobuf:"bytes,4,opt,name=htlc_address_np2wsh,json=htlcAddressNp2wsh,proto3" json:"htlc_address_np2wsh,omitempty"` + //* + //The native segwit address of the on-chain htlc. + //Used for both loop-in and loop-out. + HtlcAddressP2Wsh string `protobuf:"bytes,5,opt,name=htlc_address_p2wsh,json=htlcAddressP2wsh,proto3" json:"htlc_address_p2wsh,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -426,6 +441,7 @@ func (m *SwapResponse) GetIdBytes() []byte { return nil } +// Deprecated: Do not use. func (m *SwapResponse) GetHtlcAddress() string { if m != nil { return m.HtlcAddress @@ -433,6 +449,20 @@ func (m *SwapResponse) GetHtlcAddress() string { return "" } +func (m *SwapResponse) GetHtlcAddressNp2Wsh() string { + if m != nil { + return m.HtlcAddressNp2Wsh + } + return "" +} + +func (m *SwapResponse) GetHtlcAddressP2Wsh() string { + if m != nil { + return m.HtlcAddressP2Wsh + } + return "" +} + type MonitorRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -492,8 +522,18 @@ type SwapStatus struct { //Initiation time of the swap. LastUpdateTime int64 `protobuf:"varint,6,opt,name=last_update_time,json=lastUpdateTime,proto3" json:"last_update_time,omitempty"` //* - //Htlc address. - HtlcAddress string `protobuf:"bytes,7,opt,name=htlc_address,json=htlcAddress,proto3" json:"htlc_address,omitempty"` + //DEPRECATED: This field stores the address of the onchain htlc. + //- For internal loop-in htlc_address contains the address of the + //native segwit (P2WSH) htlc. + //- For external loop-in htlc_address contains the nested segwit (NP2WSH) + //address. + //- For loop-out htlc_address always contains the native segwit (P2WSH) + //htlc address. + HtlcAddress string `protobuf:"bytes,7,opt,name=htlc_address,json=htlcAddress,proto3" json:"htlc_address,omitempty"` // Deprecated: Do not use. + // HTLC address (native segwit), used in loop-in and loop-out swaps. + HtlcAddressP2Wsh string `protobuf:"bytes,12,opt,name=htlc_address_p2wsh,json=htlcAddressP2wsh,proto3" json:"htlc_address_p2wsh,omitempty"` + // HTLC address (nested segwit), used in loop-in swaps only. + HtlcAddressNp2Wsh string `protobuf:"bytes,13,opt,name=htlc_address_np2wsh,json=htlcAddressNp2wsh,proto3" json:"htlc_address_np2wsh,omitempty"` /// Swap server cost CostServer int64 `protobuf:"varint,8,opt,name=cost_server,json=costServer,proto3" json:"cost_server,omitempty"` // On-chain transaction cost @@ -580,6 +620,7 @@ func (m *SwapStatus) GetLastUpdateTime() int64 { return 0 } +// Deprecated: Do not use. func (m *SwapStatus) GetHtlcAddress() string { if m != nil { return m.HtlcAddress @@ -587,6 +628,20 @@ func (m *SwapStatus) GetHtlcAddress() string { return "" } +func (m *SwapStatus) GetHtlcAddressP2Wsh() string { + if m != nil { + return m.HtlcAddressP2Wsh + } + return "" +} + +func (m *SwapStatus) GetHtlcAddressNp2Wsh() string { + if m != nil { + return m.HtlcAddressNp2Wsh + } + return "" +} + func (m *SwapStatus) GetCostServer() int64 { if m != nil { return m.CostServer @@ -1180,98 +1235,101 @@ func init() { func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) } var fileDescriptor_014de31d7ac8c57c = []byte{ - // 1448 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xcb, 0x6e, 0xdb, 0x46, - 0x14, 0x0d, 0x25, 0x59, 0x8f, 0x2b, 0x8a, 0xa2, 0xc7, 0x89, 0x2d, 0xab, 0x0d, 0xe2, 0xb0, 0x4d, - 0xeb, 0x78, 0x11, 0x35, 0xce, 0xaa, 0x41, 0x51, 0xc0, 0x91, 0x95, 0x58, 0x86, 0x5f, 0xa5, 0xe4, - 0x00, 0xc9, 0x86, 0x19, 0x8b, 0x63, 0x9b, 0xa8, 0xc8, 0x61, 0x38, 0xa3, 0xc4, 0x46, 0x90, 0x4d, - 0x7f, 0xa1, 0xbb, 0x2e, 0xfb, 0x07, 0x5d, 0xf7, 0x2b, 0x8a, 0xfe, 0x42, 0x3f, 0xa1, 0xdb, 0x02, - 0xc5, 0x3c, 0x44, 0x91, 0x96, 0x9d, 0x45, 0x76, 0xe6, 0x99, 0x33, 0x67, 0xee, 0xdc, 0xc7, 0x19, - 0x19, 0xcc, 0xd1, 0x38, 0x20, 0x11, 0x7f, 0x14, 0x27, 0x94, 0x53, 0x54, 0x19, 0x53, 0x1a, 0x27, - 0xf1, 0xa8, 0xfd, 0xe5, 0x19, 0xa5, 0x67, 0x63, 0xd2, 0xc1, 0x71, 0xd0, 0xc1, 0x51, 0x44, 0x39, - 0xe6, 0x01, 0x8d, 0x98, 0xa2, 0x39, 0xbf, 0x15, 0xc1, 0xda, 0xa3, 0x34, 0x3e, 0x9c, 0x70, 0x97, - 0xbc, 0x9d, 0x10, 0xc6, 0x91, 0x0d, 0x45, 0x1c, 0xf2, 0x96, 0xb1, 0x66, 0xac, 0x17, 0x5d, 0xf1, - 0x27, 0x42, 0x50, 0xf2, 0x09, 0xe3, 0xad, 0xc2, 0x9a, 0xb1, 0x5e, 0x73, 0xe5, 0xdf, 0xa8, 0x03, - 0xb7, 0x43, 0x7c, 0xe1, 0xb1, 0xf7, 0x38, 0xf6, 0x12, 0x3a, 0xe1, 0x41, 0x74, 0xe6, 0x9d, 0x12, - 0xd2, 0x2a, 0xca, 0x6d, 0x8b, 0x21, 0xbe, 0x18, 0xbc, 0xc7, 0xb1, 0xab, 0x56, 0x9e, 0x13, 0x82, - 0x9e, 0xc0, 0xb2, 0xd8, 0x10, 0x27, 0x24, 0xc6, 0x97, 0xb9, 0x2d, 0x25, 0xb9, 0x65, 0x29, 0xc4, - 0x17, 0x47, 0x72, 0x31, 0xb3, 0x69, 0x0d, 0xcc, 0xf4, 0x14, 0x41, 0x5d, 0x90, 0x54, 0xd0, 0xea, - 0x82, 0xf1, 0x35, 0x58, 0x19, 0x59, 0x11, 0x78, 0x59, 0x72, 0xcc, 0x54, 0x6e, 0x2b, 0xe4, 0xc8, - 0x81, 0x86, 0x60, 0x85, 0x41, 0x44, 0x12, 0x29, 0x54, 0x91, 0xa4, 0x7a, 0x88, 0x2f, 0xf6, 0x05, - 0x26, 0x94, 0xd6, 0xc1, 0x16, 0x39, 0xf3, 0xe8, 0x84, 0x7b, 0xa3, 0x73, 0x1c, 0x45, 0x64, 0xdc, - 0xaa, 0xae, 0x19, 0xeb, 0x25, 0xd7, 0x1a, 0xab, 0x0c, 0x75, 0x15, 0x8a, 0x36, 0x60, 0x91, 0xbd, - 0x27, 0x24, 0xf6, 0x46, 0x34, 0x3a, 0xf5, 0x38, 0x4e, 0xce, 0x08, 0x6f, 0xd5, 0xd6, 0x8c, 0xf5, - 0x05, 0xb7, 0x29, 0x17, 0xba, 0x34, 0x3a, 0x1d, 0x4a, 0x18, 0x3d, 0x85, 0x55, 0x19, 0x7d, 0x3c, - 0x39, 0x19, 0x07, 0x23, 0x99, 0x7b, 0xcf, 0x27, 0xd8, 0x1f, 0x07, 0x11, 0x69, 0x81, 0x94, 0x5f, - 0x11, 0x84, 0xa3, 0xd9, 0xfa, 0xb6, 0x5e, 0x76, 0xfe, 0x32, 0xa0, 0x21, 0x8a, 0xd3, 0x8f, 0x6e, - 0xae, 0xcd, 0xd5, 0x0c, 0x15, 0xe6, 0x32, 0x34, 0x77, 0xf7, 0xe2, 0xfc, 0xdd, 0x57, 0xa1, 0x3a, - 0xc6, 0x8c, 0x7b, 0xe7, 0x34, 0x96, 0xe5, 0x30, 0xdd, 0x8a, 0xf8, 0xde, 0xa1, 0x31, 0xfa, 0x0a, - 0x1a, 0xe4, 0x82, 0x93, 0x24, 0xc2, 0x63, 0xef, 0x9c, 0x8f, 0x47, 0xb2, 0x06, 0x55, 0xd7, 0x9c, - 0x82, 0x3b, 0x7c, 0x3c, 0x12, 0xb9, 0x13, 0x6b, 0xb9, 0x84, 0x94, 0x65, 0x42, 0x2c, 0x81, 0xcf, - 0xf2, 0xe1, 0xbc, 0x01, 0x53, 0x36, 0x06, 0x61, 0x31, 0x8d, 0x18, 0x41, 0x08, 0x0a, 0x81, 0x2f, - 0x2f, 0x54, 0x7b, 0x56, 0x68, 0x19, 0x6e, 0x21, 0xf0, 0x45, 0x34, 0x81, 0xef, 0x9d, 0x5c, 0x72, - 0xc2, 0x64, 0xb0, 0xa6, 0x5b, 0x09, 0xfc, 0x67, 0xe2, 0x13, 0xdd, 0x07, 0x53, 0x1e, 0x84, 0x7d, - 0x3f, 0x21, 0x8c, 0xe9, 0x96, 0xac, 0x0b, 0x6c, 0x4b, 0x41, 0x8e, 0x0d, 0xd6, 0x3e, 0x8d, 0x02, - 0x4e, 0x13, 0x9d, 0x35, 0xe7, 0xbf, 0x02, 0x80, 0x38, 0x74, 0xc0, 0x31, 0x9f, 0xb0, 0x6b, 0x1b, - 0x5c, 0x04, 0x51, 0xb8, 0x31, 0x88, 0x7a, 0x3e, 0x88, 0x07, 0x50, 0xe2, 0x97, 0xb1, 0x4a, 0xa4, - 0xb5, 0xb9, 0xf8, 0x48, 0x8f, 0xda, 0x23, 0x71, 0xc6, 0xf0, 0x32, 0x26, 0xae, 0x5c, 0x46, 0xeb, - 0xb0, 0xc0, 0x38, 0xe6, 0xaa, 0xc1, 0xad, 0x4d, 0x94, 0xe3, 0x89, 0x58, 0x88, 0xab, 0x08, 0xe8, - 0x5b, 0x68, 0x06, 0x51, 0xc0, 0x03, 0xd5, 0x1e, 0x3c, 0x08, 0xa7, 0x9d, 0x6e, 0xcd, 0xe0, 0x61, - 0x10, 0xaa, 0x1e, 0x15, 0x75, 0x9a, 0xc4, 0x3e, 0xe6, 0x44, 0x31, 0x55, 0xbf, 0x5b, 0x02, 0x3f, - 0x96, 0xb0, 0x64, 0x5e, 0x4d, 0x54, 0x65, 0x2e, 0x51, 0xe8, 0x1e, 0xd4, 0x47, 0x94, 0x71, 0x8f, - 0x91, 0xe4, 0x1d, 0x49, 0x64, 0xaf, 0x17, 0x5d, 0x10, 0xd0, 0x40, 0x22, 0x42, 0x43, 0x12, 0x68, - 0x34, 0x3a, 0xc7, 0x41, 0x24, 0x5b, 0xbc, 0xe8, 0xca, 0x4d, 0x87, 0x0a, 0x12, 0xdd, 0xa1, 0x28, - 0xa7, 0xa7, 0x8a, 0x03, 0x6a, 0xfa, 0x24, 0x47, 0x63, 0x0e, 0x02, 0x7b, 0x2f, 0x60, 0x5c, 0x5c, - 0x9b, 0x4d, 0x6b, 0xf2, 0x23, 0x2c, 0x66, 0x30, 0xdd, 0x0c, 0x0f, 0x61, 0x41, 0x34, 0x32, 0x6b, - 0x19, 0x6b, 0xc5, 0xf5, 0xfa, 0xe6, 0xd2, 0x5c, 0xc6, 0x26, 0xcc, 0x55, 0x0c, 0xe7, 0x3e, 0x34, - 0x05, 0xd8, 0x8f, 0x4e, 0xe9, 0x74, 0x38, 0xac, 0xb4, 0x95, 0x4c, 0x51, 0x41, 0xc7, 0x02, 0x73, - 0x48, 0x92, 0x30, 0x3d, 0xf2, 0x23, 0x34, 0xf4, 0xb7, 0x3e, 0xee, 0x1b, 0x68, 0x86, 0x41, 0xa4, - 0x66, 0x07, 0x87, 0x74, 0x12, 0x71, 0x9d, 0xf6, 0x46, 0x18, 0x44, 0x42, 0x7d, 0x4b, 0x82, 0x92, - 0x37, 0x9d, 0x31, 0xcd, 0x2b, 0x6b, 0x9e, 0x1a, 0x33, 0xc5, 0xdb, 0x2d, 0x55, 0x0d, 0xbb, 0xb0, - 0x5b, 0xaa, 0x16, 0xec, 0xe2, 0x6e, 0xa9, 0x5a, 0xb4, 0x4b, 0xbb, 0xa5, 0x6a, 0xc9, 0x5e, 0xd8, - 0x2d, 0x55, 0x2b, 0x76, 0xd5, 0xf9, 0xdd, 0x00, 0xf3, 0xa7, 0x09, 0xe5, 0xe4, 0xe6, 0x61, 0x96, - 0x15, 0x99, 0x4d, 0x50, 0x41, 0x4e, 0x10, 0x8c, 0x66, 0x6e, 0x32, 0x37, 0x8c, 0xc5, 0x6b, 0x86, - 0xf1, 0x93, 0x96, 0x53, 0xfa, 0xb4, 0xe5, 0xfc, 0x61, 0x40, 0x43, 0x07, 0xa9, 0x93, 0xb4, 0x0a, - 0xd5, 0xd4, 0x5c, 0x54, 0xa8, 0x15, 0xa6, 0x9d, 0xe5, 0x2e, 0x40, 0xc6, 0x77, 0x95, 0xf3, 0xd4, - 0xe2, 0xd4, 0x74, 0xbf, 0x80, 0xda, 0x55, 0xd3, 0xa9, 0x86, 0x53, 0xc7, 0x91, 0x1e, 0x2a, 0x82, - 0xc4, 0x97, 0x21, 0x89, 0xb8, 0x27, 0x1f, 0x18, 0x65, 0x3d, 0x4d, 0x19, 0x9c, 0xc2, 0xb7, 0x45, - 0xa2, 0xee, 0x02, 0x8c, 0xc6, 0xfc, 0x9d, 0xe7, 0x93, 0x31, 0xc7, 0xb2, 0x44, 0x0b, 0x6e, 0x4d, - 0x20, 0xdb, 0x02, 0x70, 0x9a, 0xd0, 0x18, 0xd2, 0x9f, 0x49, 0x94, 0x16, 0xfa, 0x07, 0xb0, 0xa6, - 0x80, 0xbe, 0xc4, 0x06, 0x94, 0xb9, 0x44, 0x74, 0x67, 0xcd, 0x66, 0x71, 0x8f, 0x61, 0x2e, 0xc9, - 0xae, 0x66, 0x38, 0x7f, 0x16, 0xa0, 0x96, 0xa2, 0x22, 0xe3, 0x27, 0x98, 0x11, 0x2f, 0xc4, 0x23, - 0x9c, 0x50, 0x1a, 0xe9, 0xfe, 0x32, 0x05, 0xb8, 0xaf, 0x31, 0x31, 0x28, 0xd3, 0x7b, 0x9c, 0x63, - 0x76, 0x2e, 0x53, 0x61, 0xba, 0x75, 0x8d, 0xed, 0x60, 0x76, 0x8e, 0x1e, 0x82, 0x3d, 0xa5, 0xc4, - 0x09, 0x09, 0x42, 0x7c, 0x46, 0xb4, 0xb7, 0x35, 0x35, 0x7e, 0xa4, 0x61, 0x31, 0xe4, 0xaa, 0xcb, - 0xbc, 0x18, 0x07, 0xbe, 0x17, 0x32, 0xcc, 0xf5, 0x1b, 0x69, 0x29, 0xfc, 0x08, 0x07, 0xfe, 0x3e, - 0xc3, 0x1c, 0x3d, 0x86, 0x3b, 0x99, 0x87, 0x34, 0x43, 0x57, 0x6d, 0x8c, 0x92, 0xf4, 0x25, 0x4d, - 0xb7, 0xdc, 0x07, 0x53, 0xb8, 0x86, 0x37, 0x4a, 0x08, 0xe6, 0xc4, 0xd7, 0x8d, 0x5c, 0x17, 0x58, - 0x57, 0x41, 0xa8, 0x05, 0x15, 0x72, 0x11, 0x07, 0x09, 0xf1, 0xa5, 0x6b, 0x54, 0xdd, 0xe9, 0xa7, - 0xd8, 0xcc, 0x38, 0x4d, 0xf0, 0x19, 0xf1, 0x22, 0x1c, 0x12, 0x69, 0x19, 0x35, 0xb7, 0xae, 0xb1, - 0x03, 0x1c, 0x92, 0x8d, 0x07, 0x50, 0x9d, 0xda, 0x20, 0x32, 0xa1, 0xba, 0x77, 0x78, 0x78, 0xe4, - 0x1d, 0x1e, 0x0f, 0xed, 0x5b, 0xa8, 0x0e, 0x15, 0xf9, 0xd5, 0x3f, 0xb0, 0x8d, 0x0d, 0x06, 0xb5, - 0xd4, 0x05, 0x51, 0x03, 0x6a, 0xfd, 0x83, 0xfe, 0xb0, 0xbf, 0x35, 0xec, 0x6d, 0xdb, 0xb7, 0xd0, - 0x1d, 0x58, 0x3c, 0x72, 0x7b, 0xfd, 0xfd, 0xad, 0x17, 0x3d, 0xcf, 0xed, 0xbd, 0xec, 0x6d, 0xed, - 0xf5, 0xb6, 0x6d, 0x03, 0x21, 0xb0, 0x76, 0x86, 0x7b, 0x5d, 0xef, 0xe8, 0xf8, 0xd9, 0x5e, 0x7f, - 0xb0, 0xd3, 0xdb, 0xb6, 0x0b, 0x42, 0x73, 0x70, 0xdc, 0xed, 0xf6, 0x06, 0x03, 0xbb, 0x88, 0x00, - 0xca, 0xcf, 0xb7, 0xfa, 0x82, 0x5c, 0x42, 0x4b, 0xd0, 0xec, 0x1f, 0xbc, 0x3c, 0xec, 0x77, 0x7b, - 0xde, 0xa0, 0x37, 0x1c, 0x0a, 0x70, 0x61, 0xf3, 0xdf, 0xb2, 0x7a, 0x07, 0xba, 0xf2, 0x87, 0x12, - 0x72, 0xa1, 0xa2, 0x7f, 0xfa, 0xa0, 0x95, 0x59, 0x3f, 0xe4, 0x7e, 0x0c, 0xb5, 0xef, 0xe4, 0x2c, - 0x68, 0xda, 0x4f, 0xce, 0xca, 0x2f, 0x7f, 0xff, 0xf3, 0x6b, 0x61, 0xd1, 0x31, 0x3b, 0xef, 0x1e, - 0x77, 0x04, 0xa3, 0x43, 0x27, 0xfc, 0xa9, 0xb1, 0x81, 0x0e, 0xa1, 0xac, 0x5e, 0x6c, 0xb4, 0x9c, - 0x93, 0x4c, 0x9f, 0xf0, 0x9b, 0x14, 0x97, 0xa5, 0xa2, 0xed, 0xd4, 0x53, 0xc5, 0x20, 0x12, 0x82, - 0xdf, 0x43, 0x45, 0xbf, 0x66, 0x99, 0x20, 0xf3, 0xef, 0x5b, 0xfb, 0x3a, 0x9f, 0xfc, 0xce, 0x40, - 0xaf, 0xa1, 0x96, 0x5a, 0x2c, 0x5a, 0x9d, 0x85, 0x73, 0xc5, 0x8a, 0xdb, 0xed, 0xeb, 0x96, 0xf2, - 0x61, 0x21, 0x2b, 0x0d, 0x4b, 0xda, 0x2f, 0x3a, 0x56, 0x65, 0x16, 0xf6, 0x8b, 0x5a, 0xb9, 0xe3, - 0x33, 0x8e, 0x7c, 0x6d, 0x60, 0x4e, 0x5b, 0x4a, 0xde, 0x46, 0x28, 0x27, 0xd9, 0xf9, 0x10, 0xf8, - 0x1f, 0xd1, 0x2b, 0x30, 0x75, 0x01, 0xa4, 0x53, 0xa3, 0x59, 0xb2, 0xb2, 0x4e, 0xde, 0x5e, 0xbe, - 0x0a, 0xeb, 0x68, 0xe7, 0xa5, 0xe9, 0x84, 0x77, 0xb8, 0x94, 0xf2, 0x52, 0x69, 0xe9, 0x6f, 0x19, - 0xe9, 0xac, 0x29, 0x67, 0xa4, 0x73, 0x36, 0xe8, 0xac, 0x49, 0xe9, 0x36, 0x6a, 0xe5, 0xa4, 0xdf, - 0x0a, 0x4e, 0xe7, 0x03, 0x0e, 0xf9, 0x47, 0xf4, 0x1a, 0xac, 0x17, 0x84, 0xab, 0x62, 0x7f, 0x56, - 0xf4, 0xab, 0xf2, 0x88, 0x25, 0xb4, 0x98, 0x69, 0x01, 0x1d, 0xfc, 0x9b, 0x8c, 0xf6, 0x67, 0x85, - 0x7f, 0x4f, 0x6a, 0xaf, 0xa2, 0x95, 0xac, 0x76, 0x36, 0xfa, 0x57, 0xd0, 0x10, 0x27, 0x4c, 0x7d, - 0x8f, 0x65, 0xfa, 0x37, 0x67, 0xae, 0xed, 0x95, 0x39, 0x3c, 0x3f, 0x13, 0xa8, 0x29, 0x8f, 0x60, - 0x98, 0x77, 0x94, 0xa1, 0x9e, 0x94, 0xe5, 0xbf, 0x1a, 0x4f, 0xfe, 0x0f, 0x00, 0x00, 0xff, 0xff, - 0xc7, 0x1e, 0x66, 0x37, 0xa1, 0x0c, 0x00, 0x00, + // 1504 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xcb, 0x72, 0xdb, 0x46, + 0x16, 0x35, 0xf8, 0xe6, 0x25, 0x08, 0x82, 0x2d, 0x5b, 0xa2, 0x38, 0xe3, 0xb2, 0x8c, 0x19, 0xcf, + 0xc8, 0xaa, 0x29, 0x71, 0x2c, 0xaf, 0xc6, 0x35, 0x95, 0x2a, 0x99, 0xa2, 0x2d, 0xaa, 0xf4, 0x60, + 0x40, 0xca, 0x55, 0xf6, 0x06, 0x69, 0x11, 0x2d, 0x11, 0x15, 0xe2, 0x61, 0x74, 0xd3, 0x92, 0xca, + 0xe5, 0x4d, 0x7e, 0x21, 0xbb, 0x2c, 0xf3, 0x07, 0x59, 0x67, 0x97, 0x3f, 0x48, 0xe5, 0x03, 0xb2, + 0xc9, 0x27, 0xe4, 0x03, 0x52, 0xfd, 0x20, 0x08, 0x48, 0x94, 0x17, 0xde, 0x11, 0xa7, 0x4f, 0x9f, + 0xbe, 0x7d, 0xef, 0xed, 0xd3, 0x4d, 0xd0, 0xc7, 0x53, 0x8f, 0x04, 0x6c, 0x3b, 0x8a, 0x43, 0x16, + 0xa2, 0xf2, 0x34, 0x0c, 0xa3, 0x38, 0x1a, 0xb7, 0xff, 0x7e, 0x11, 0x86, 0x17, 0x53, 0xd2, 0xc1, + 0x91, 0xd7, 0xc1, 0x41, 0x10, 0x32, 0xcc, 0xbc, 0x30, 0xa0, 0x92, 0x66, 0xfd, 0x90, 0x07, 0xe3, + 0x30, 0x0c, 0xa3, 0x93, 0x19, 0xb3, 0xc9, 0xfb, 0x19, 0xa1, 0x0c, 0x99, 0x90, 0xc7, 0x3e, 0x6b, + 0x69, 0x1b, 0xda, 0x66, 0xde, 0xe6, 0x3f, 0x11, 0x82, 0x82, 0x4b, 0x28, 0x6b, 0xe5, 0x36, 0xb4, + 0xcd, 0xaa, 0x2d, 0x7e, 0xa3, 0x0e, 0xdc, 0xf7, 0xf1, 0x95, 0x43, 0x2f, 0x71, 0xe4, 0xc4, 0xe1, + 0x8c, 0x79, 0xc1, 0x85, 0x73, 0x4e, 0x48, 0x2b, 0x2f, 0xa6, 0x35, 0x7d, 0x7c, 0x35, 0xbc, 0xc4, + 0x91, 0x2d, 0x47, 0x5e, 0x11, 0x82, 0x9e, 0xc3, 0x2a, 0x9f, 0x10, 0xc5, 0x24, 0xc2, 0xd7, 0x99, + 0x29, 0x05, 0x31, 0x65, 0xc5, 0xc7, 0x57, 0x03, 0x31, 0x98, 0x9a, 0xb4, 0x01, 0x7a, 0xb2, 0x0a, + 0xa7, 0x16, 0x05, 0x15, 0x94, 0x3a, 0x67, 0xfc, 0x13, 0x8c, 0x94, 0x2c, 0x0f, 0xbc, 0x24, 0x38, + 0x7a, 0x22, 0xb7, 0xeb, 0x33, 0x64, 0x41, 0x9d, 0xb3, 0x7c, 0x2f, 0x20, 0xb1, 0x10, 0x2a, 0x0b, + 0x52, 0xcd, 0xc7, 0x57, 0x47, 0x1c, 0xe3, 0x4a, 0x9b, 0x60, 0xf2, 0x9c, 0x39, 0xe1, 0x8c, 0x39, + 0xe3, 0x09, 0x0e, 0x02, 0x32, 0x6d, 0x55, 0x36, 0xb4, 0xcd, 0x82, 0x6d, 0x4c, 0x65, 0x86, 0xba, + 0x12, 0x45, 0x5b, 0xd0, 0xa4, 0x97, 0x84, 0x44, 0xce, 0x38, 0x0c, 0xce, 0x1d, 0x86, 0xe3, 0x0b, + 0xc2, 0x5a, 0xd5, 0x0d, 0x6d, 0xb3, 0x68, 0x37, 0xc4, 0x40, 0x37, 0x0c, 0xce, 0x47, 0x02, 0x46, + 0x2f, 0x60, 0x5d, 0x44, 0x1f, 0xcd, 0xce, 0xa6, 0xde, 0x58, 0xe4, 0xde, 0x71, 0x09, 0x76, 0xa7, + 0x5e, 0x40, 0x5a, 0x20, 0xe4, 0xd7, 0x38, 0x61, 0xb0, 0x18, 0xdf, 0x53, 0xc3, 0xd6, 0xaf, 0x1a, + 0xd4, 0x79, 0x71, 0xfa, 0xc1, 0xdd, 0xb5, 0xb9, 0x99, 0xa1, 0xdc, 0xad, 0x0c, 0xdd, 0xda, 0x7b, + 0xfe, 0xf6, 0xde, 0xd7, 0xa1, 0x32, 0xc5, 0x94, 0x39, 0x93, 0x30, 0x12, 0xe5, 0xd0, 0xed, 0x32, + 0xff, 0xde, 0x0f, 0x23, 0xf4, 0x0f, 0xa8, 0x93, 0x2b, 0x46, 0xe2, 0x00, 0x4f, 0x9d, 0x09, 0x9b, + 0x8e, 0x45, 0x0d, 0x2a, 0xb6, 0x3e, 0x07, 0xf7, 0xd9, 0x74, 0xcc, 0x73, 0xc7, 0xc7, 0x32, 0x09, + 0x29, 0x89, 0x84, 0x18, 0x1c, 0x5f, 0xe4, 0xc3, 0xfa, 0x45, 0x03, 0x5d, 0x74, 0x06, 0xa1, 0x51, + 0x18, 0x50, 0x82, 0x10, 0xe4, 0x3c, 0x57, 0xec, 0xa8, 0xfa, 0x32, 0xd7, 0xd2, 0xec, 0x9c, 0xe7, + 0xf2, 0x70, 0x3c, 0xd7, 0x39, 0xbb, 0x66, 0x84, 0x8a, 0x68, 0x75, 0xbb, 0xec, 0xb9, 0x2f, 0xf9, + 0x27, 0x7a, 0x02, 0xba, 0x58, 0x09, 0xbb, 0x6e, 0x4c, 0x28, 0x95, 0x3d, 0x29, 0x26, 0xd6, 0x38, + 0xbe, 0x2b, 0x61, 0xb4, 0x0d, 0x2b, 0x69, 0x9a, 0x13, 0x44, 0x3b, 0x97, 0x74, 0x22, 0xf6, 0x56, + 0xb5, 0x9b, 0x29, 0xe6, 0xb1, 0x18, 0x40, 0xff, 0x01, 0x94, 0xe1, 0x4b, 0x7a, 0x51, 0xd0, 0xcd, + 0x14, 0x7d, 0xc0, 0x71, 0xcb, 0x04, 0xe3, 0x28, 0x0c, 0x3c, 0x16, 0xc6, 0xaa, 0x30, 0xd6, 0xef, + 0x79, 0x00, 0xbe, 0xad, 0x21, 0xc3, 0x6c, 0x46, 0x97, 0x9e, 0x21, 0xbe, 0xcd, 0xdc, 0x9d, 0xdb, + 0xac, 0xdd, 0xdc, 0x66, 0x81, 0x5d, 0x47, 0xb2, 0x56, 0xc6, 0x4e, 0x73, 0x5b, 0x9d, 0xe6, 0x6d, + 0xbe, 0xc6, 0xe8, 0x3a, 0x22, 0xb6, 0x18, 0x46, 0x9b, 0x50, 0xa4, 0x0c, 0x33, 0x79, 0x86, 0x8c, + 0x1d, 0x94, 0xe1, 0xf1, 0x58, 0x88, 0x2d, 0x09, 0xe8, 0xdf, 0xd0, 0xf0, 0x02, 0x8f, 0x79, 0xb2, + 0x03, 0x99, 0xe7, 0xcf, 0x0f, 0x93, 0xb1, 0x80, 0x47, 0x9e, 0x2f, 0x8f, 0x01, 0x6f, 0x85, 0x59, + 0xe4, 0x62, 0x46, 0x24, 0x53, 0x1e, 0x29, 0x83, 0xe3, 0xa7, 0x02, 0x16, 0xcc, 0x9b, 0xa5, 0x28, + 0x2f, 0x2f, 0xc5, 0xf2, 0xd4, 0xea, 0xcb, 0x53, 0x7b, 0x57, 0xe1, 0xea, 0x77, 0x15, 0xee, 0x11, + 0xd4, 0xc6, 0x21, 0x65, 0x0e, 0x25, 0xf1, 0x07, 0x12, 0x8b, 0x03, 0x9b, 0xb7, 0x81, 0x43, 0x43, + 0x81, 0xa0, 0xc7, 0xa0, 0x0b, 0x42, 0x18, 0x8c, 0x27, 0xd8, 0x0b, 0xc4, 0x39, 0xcd, 0xdb, 0x62, + 0xd2, 0x89, 0x84, 0x78, 0x8b, 0x4b, 0xca, 0xf9, 0xb9, 0xe4, 0x80, 0xb4, 0x10, 0xc1, 0x51, 0x98, + 0x85, 0xc0, 0x3c, 0xf4, 0x28, 0xe3, 0x89, 0xa5, 0xf3, 0xaa, 0x7f, 0x05, 0xcd, 0x14, 0xa6, 0x1a, + 0xfa, 0x29, 0x14, 0xf9, 0x69, 0xa4, 0x2d, 0x6d, 0x23, 0xbf, 0x59, 0xdb, 0x59, 0xb9, 0x55, 0x93, + 0x19, 0xb5, 0x25, 0xc3, 0x7a, 0x0c, 0x0d, 0x0e, 0xf6, 0x83, 0xf3, 0x70, 0x7e, 0xc2, 0x8d, 0xe4, + 0x38, 0xe8, 0xbc, 0x47, 0x2c, 0x03, 0xf4, 0x11, 0x89, 0xfd, 0x64, 0xc9, 0x4f, 0x50, 0x57, 0xdf, + 0x6a, 0xb9, 0x7f, 0x41, 0xc3, 0xf7, 0x02, 0x69, 0x00, 0xd8, 0x0f, 0x67, 0x01, 0x53, 0x85, 0xad, + 0xfb, 0x5e, 0xc0, 0xd5, 0x77, 0x05, 0x28, 0x78, 0x73, 0xa3, 0x50, 0xbc, 0x92, 0xe2, 0x49, 0xaf, + 0x90, 0xbc, 0x83, 0x42, 0x45, 0x33, 0x73, 0x07, 0x85, 0x4a, 0xce, 0xcc, 0x1f, 0x14, 0x2a, 0x79, + 0xb3, 0x70, 0x50, 0xa8, 0x14, 0xcc, 0xe2, 0x41, 0xa1, 0x52, 0x36, 0x2b, 0xd6, 0x8f, 0x1a, 0xe8, + 0x5f, 0xcf, 0x42, 0x46, 0xee, 0x76, 0x24, 0x51, 0x91, 0x85, 0x0d, 0xe4, 0x84, 0x0d, 0xc0, 0x78, + 0x61, 0x89, 0xb7, 0x1c, 0x25, 0xbf, 0xc4, 0x51, 0x3e, 0xeb, 0x9b, 0x85, 0xcf, 0xfb, 0xe6, 0x4f, + 0x1a, 0xd4, 0x55, 0x90, 0x2a, 0x49, 0xeb, 0x50, 0x49, 0x1c, 0x52, 0x86, 0x5a, 0xa6, 0xca, 0x1e, + 0x1f, 0x02, 0xa4, 0x2e, 0x0f, 0x69, 0x9f, 0xd5, 0x28, 0xb9, 0x39, 0xfe, 0x06, 0xd5, 0x9b, 0xce, + 0x59, 0xf1, 0xe7, 0xb6, 0x29, 0x2e, 0x02, 0x1e, 0x24, 0xbe, 0xf6, 0x49, 0xc0, 0x1c, 0x71, 0x4b, + 0x4a, 0xff, 0x6c, 0x88, 0xe0, 0x24, 0xbe, 0xc7, 0x13, 0xf5, 0x10, 0x60, 0x3c, 0x65, 0x1f, 0x1c, + 0x97, 0x4c, 0x19, 0x16, 0x25, 0x2a, 0xda, 0x55, 0x8e, 0xec, 0x71, 0xc0, 0x6a, 0x40, 0x7d, 0x14, + 0x7e, 0x4b, 0x82, 0xa4, 0xd0, 0xff, 0x07, 0x63, 0x0e, 0xa8, 0x4d, 0x6c, 0x41, 0x89, 0x09, 0x44, + 0x75, 0xd6, 0xe2, 0xb4, 0x1f, 0x52, 0xcc, 0x04, 0xd9, 0x56, 0x0c, 0xeb, 0xe7, 0x1c, 0x54, 0x13, + 0x94, 0x67, 0xfc, 0x0c, 0x53, 0xe2, 0xf8, 0x78, 0x8c, 0xe3, 0x30, 0x0c, 0x54, 0x7f, 0xe9, 0x1c, + 0x3c, 0x52, 0x18, 0x3f, 0x28, 0xf3, 0x7d, 0x4c, 0x30, 0x9d, 0x88, 0x54, 0xe8, 0x76, 0x4d, 0x61, + 0xfb, 0x98, 0x4e, 0xd0, 0x53, 0x30, 0xe7, 0x94, 0x28, 0x26, 0x9e, 0x8f, 0x2f, 0x88, 0xf2, 0xe7, + 0x86, 0xc2, 0x07, 0x0a, 0xe6, 0x36, 0x22, 0xbb, 0xcc, 0x89, 0xb0, 0xe7, 0x3a, 0x3e, 0xc5, 0x4c, + 0x5d, 0xf4, 0x86, 0xc4, 0x07, 0xd8, 0x73, 0x8f, 0x28, 0x66, 0xe8, 0x19, 0x3c, 0x48, 0xbd, 0x06, + 0x52, 0x74, 0xd9, 0xc6, 0x28, 0x4e, 0x9e, 0x03, 0xc9, 0x94, 0xc7, 0xa0, 0x73, 0x5f, 0x72, 0xc6, + 0x31, 0xc1, 0x8c, 0xb8, 0xaa, 0x91, 0x6b, 0x1c, 0xeb, 0x4a, 0x08, 0xb5, 0xa0, 0x4c, 0xae, 0x22, + 0x2f, 0x26, 0xae, 0xf0, 0xa5, 0x8a, 0x3d, 0xff, 0xe4, 0x93, 0x29, 0x0b, 0x63, 0x7c, 0x41, 0x9c, + 0x00, 0xfb, 0x44, 0x58, 0x46, 0xd5, 0xae, 0x29, 0xec, 0x18, 0xfb, 0x64, 0xeb, 0x09, 0x54, 0xe6, + 0x46, 0x8b, 0x74, 0xa8, 0x1c, 0x9e, 0x9c, 0x0c, 0x9c, 0x93, 0xd3, 0x91, 0x79, 0x0f, 0xd5, 0xa0, + 0x2c, 0xbe, 0xfa, 0xc7, 0xa6, 0xb6, 0x45, 0xa1, 0x9a, 0xf8, 0x2c, 0xaa, 0x43, 0xb5, 0x7f, 0xdc, + 0x1f, 0xf5, 0x77, 0x47, 0xbd, 0x3d, 0xf3, 0x1e, 0x7a, 0x00, 0xcd, 0x81, 0xdd, 0xeb, 0x1f, 0xed, + 0xbe, 0xee, 0x39, 0x76, 0xef, 0x4d, 0x6f, 0xf7, 0xb0, 0xb7, 0x67, 0x6a, 0x08, 0x81, 0xb1, 0x3f, + 0x3a, 0xec, 0x3a, 0x83, 0xd3, 0x97, 0x87, 0xfd, 0xe1, 0x7e, 0x6f, 0xcf, 0xcc, 0x71, 0xcd, 0xe1, + 0x69, 0xb7, 0xdb, 0x1b, 0x0e, 0xcd, 0x3c, 0x02, 0x28, 0xbd, 0xda, 0xed, 0x73, 0x72, 0x01, 0xad, + 0x40, 0xa3, 0x7f, 0xfc, 0xe6, 0xa4, 0xdf, 0xed, 0x39, 0xc3, 0xde, 0x68, 0xc4, 0xc1, 0xe2, 0xce, + 0x9f, 0x25, 0x79, 0xd3, 0x74, 0xc5, 0x6b, 0x0f, 0xd9, 0x50, 0x56, 0xef, 0x37, 0xb4, 0xb6, 0xe8, + 0x87, 0xcc, 0x8b, 0xae, 0xfd, 0x20, 0x63, 0x41, 0xf3, 0x7e, 0xb2, 0xd6, 0xbe, 0xfb, 0xed, 0x8f, + 0xef, 0x73, 0x4d, 0x4b, 0xef, 0x7c, 0x78, 0xd6, 0xe1, 0x8c, 0x4e, 0x38, 0x63, 0x2f, 0xb4, 0x2d, + 0x74, 0x02, 0x25, 0xf9, 0xec, 0x40, 0xab, 0x19, 0xc9, 0xe4, 0x1d, 0x72, 0x97, 0xe2, 0xaa, 0x50, + 0x34, 0xad, 0x5a, 0xa2, 0xe8, 0x05, 0x5c, 0xf0, 0x7f, 0x50, 0x56, 0xf7, 0x65, 0x2a, 0xc8, 0xec, + 0x0d, 0xda, 0x5e, 0xe6, 0x93, 0xff, 0xd5, 0xd0, 0x3b, 0xa8, 0x26, 0x16, 0x8b, 0xd6, 0x17, 0xe1, + 0xdc, 0xb0, 0xe2, 0x76, 0x7b, 0xd9, 0x50, 0x36, 0x2c, 0x64, 0x24, 0x61, 0x09, 0xfb, 0x45, 0xa7, + 0xb2, 0xcc, 0xdc, 0x7e, 0x51, 0x2b, 0xb3, 0x7c, 0xca, 0x91, 0x97, 0x06, 0x66, 0xb5, 0x85, 0xe4, + 0x7d, 0x84, 0x32, 0x92, 0x9d, 0x8f, 0x9e, 0xfb, 0x09, 0xbd, 0x05, 0x5d, 0x15, 0x40, 0x38, 0x35, + 0x5a, 0x24, 0x2b, 0xed, 0xe4, 0xed, 0xd5, 0x9b, 0xb0, 0x8a, 0xf6, 0xb6, 0x74, 0x38, 0x63, 0x1d, + 0x26, 0xa4, 0x9c, 0x44, 0x5a, 0xf8, 0x5b, 0x4a, 0x3a, 0x6d, 0xca, 0x29, 0xe9, 0x8c, 0x0d, 0x5a, + 0x1b, 0x42, 0xba, 0x8d, 0x5a, 0x19, 0xe9, 0xf7, 0x9c, 0xd3, 0xf9, 0x88, 0x7d, 0xf6, 0x09, 0xbd, + 0x03, 0xe3, 0x35, 0x61, 0xb2, 0xd8, 0x5f, 0x14, 0xfd, 0xba, 0x58, 0x62, 0x05, 0x35, 0x53, 0x2d, + 0xa0, 0x82, 0xff, 0x26, 0xa5, 0xfd, 0x45, 0xe1, 0x3f, 0x12, 0xda, 0xeb, 0x68, 0x2d, 0xad, 0x9d, + 0x8e, 0xfe, 0x2d, 0xd4, 0xf9, 0x0a, 0x73, 0xdf, 0xa3, 0xa9, 0xfe, 0xcd, 0x98, 0x6b, 0x7b, 0xed, + 0x16, 0x9e, 0x3d, 0x13, 0xa8, 0x21, 0x96, 0xa0, 0x98, 0x75, 0xa4, 0xa1, 0x9e, 0x95, 0xc4, 0xff, + 0xa5, 0xe7, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x46, 0x6c, 0x13, 0xa0, 0x66, 0x0d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/looprpc/client.proto b/looprpc/client.proto index 0e58de7..8d3d38b 100644 --- a/looprpc/client.proto +++ b/looprpc/client.proto @@ -242,9 +242,28 @@ message SwapResponse { bytes id_bytes = 3; /** - The address of the on-chain htlc. + DEPRECATED. This field stores the address of the onchain htlc, but + depending on the request, the semantics are different. + - For internal loop-in htlc_address contains the address of the + native segwit (P2WSH) htlc. + - For external loop-in htlc_address contains the address of the + nested segwit (NP2WSH) htlc. + - For loop-out htlc_address always contains the native segwit (P2WSH) + htlc address. */ - string htlc_address = 2; + string htlc_address = 2 [deprecated = true]; + + /** + The nested segwit address of the on-chain htlc. + This field remains empty for loop-out. + */ + string htlc_address_np2wsh = 4; + + /** + The native segwit address of the on-chain htlc. + Used for both loop-in and loop-out. + */ + string htlc_address_p2wsh = 5; } message MonitorRequest { @@ -292,9 +311,21 @@ message SwapStatus { int64 last_update_time = 6; /** - Htlc address. + DEPRECATED: This field stores the address of the onchain htlc. + - For internal loop-in htlc_address contains the address of the + native segwit (P2WSH) htlc. + - For external loop-in htlc_address contains the nested segwit (NP2WSH) + address. + - For loop-out htlc_address always contains the native segwit (P2WSH) + htlc address. */ - string htlc_address = 7; + string htlc_address = 7 [deprecated = true]; + + // HTLC address (native segwit), used in loop-in and loop-out swaps. + string htlc_address_p2wsh = 12; + + // HTLC address (nested segwit), used in loop-in swaps only. + string htlc_address_np2wsh = 13; /// Swap server cost int64 cost_server = 8; diff --git a/looprpc/client.swagger.json b/looprpc/client.swagger.json index 388cda6..75875ff 100644 --- a/looprpc/client.swagger.json +++ b/looprpc/client.swagger.json @@ -457,7 +457,15 @@ }, "htlc_address": { "type": "string", - "description": "*\nThe address of the on-chain htlc." + "description": "*\nDEPRECATED. This field stores the address of the onchain htlc, but\ndepending on the request, the semantics are different.\n- For internal loop-in htlc_address contains the address of the\nnative segwit (P2WSH) htlc.\n- For external loop-in htlc_address contains the address of the\nnested segwit (NP2WSH) htlc.\n- For loop-out htlc_address always contains the native segwit (P2WSH)\nhtlc address." + }, + "htlc_address_np2wsh": { + "type": "string", + "description": "*\nThe nested segwit address of the on-chain htlc.\nThis field remains empty for loop-out." + }, + "htlc_address_p2wsh": { + "type": "string", + "description": "*\nThe native segwit address of the on-chain htlc.\nUsed for both loop-in and loop-out." } } }, @@ -511,7 +519,15 @@ }, "htlc_address": { "type": "string", - "description": "*\nHtlc address." + "description": "*\nDEPRECATED: This field stores the address of the onchain htlc.\n- For internal loop-in htlc_address contains the address of the\nnative segwit (P2WSH) htlc.\n- For external loop-in htlc_address contains the nested segwit (NP2WSH)\naddress.\n- For loop-out htlc_address always contains the native segwit (P2WSH)\nhtlc address." + }, + "htlc_address_p2wsh": { + "type": "string", + "description": "HTLC address (native segwit), used in loop-in and loop-out swaps." + }, + "htlc_address_np2wsh": { + "type": "string", + "description": "HTLC address (nested segwit), used in loop-in swaps only." }, "cost_server": { "type": "string", From 0aa978bd09c1a9da59d88af0713e5f0e79252dc6 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Tue, 28 Apr 2020 17:30:20 +0200 Subject: [PATCH 7/9] loopin: modify internally published htlc to use p2wsh --- loopd/swapclient_server.go | 9 ++++++--- loopin.go | 3 ++- loopin_test.go | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index 8fae91d..8cf1754 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -131,11 +131,14 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) ( switch loopSwap.SwapType { case swap.TypeIn: swapType = looprpc.SwapType_LOOP_IN + htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress() + if loopSwap.ExternalHtlc { - htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress() + htlcAddressNP2WSH = loopSwap.HtlcAddressNP2WSH.EncodeAddress() + htlcAddress = htlcAddressNP2WSH + } else { + htlcAddress = htlcAddressP2WSH } - htlcAddressNP2WSH = loopSwap.HtlcAddressNP2WSH.EncodeAddress() - htlcAddress = htlcAddressNP2WSH case swap.TypeOut: swapType = looprpc.SwapType_LOOP_OUT diff --git a/loopin.go b/loopin.go index 8b1bcdb..b72359c 100644 --- a/loopin.go +++ b/loopin.go @@ -472,9 +472,10 @@ func (s *loopInSwap) publishOnChainHtlc(ctx context.Context) (bool, error) { s.log.Infof("Publishing on chain HTLC with fee rate %v", feeRate) + // Internal loop-in is always P2WSH. tx, err := s.lnd.WalletKit.SendOutputs(ctx, []*wire.TxOut{{ - PkScript: s.htlcNP2WSH.PkScript, + PkScript: s.htlcP2WSH.PkScript, Value: int64(s.LoopInContract.AmountRequested), }}, feeRate, diff --git a/loopin_test.go b/loopin_test.go index 8c15705..08f3fd3 100644 --- a/loopin_test.go +++ b/loopin_test.go @@ -119,7 +119,7 @@ func TestLoopInSuccess(t *testing.T) { func TestLoopInTimeout(t *testing.T) { testAmt := int64(testLoopInRequest.Amount) t.Run("internal htlc", func(t *testing.T) { - testLoopInTimeout(t, swap.HtlcNP2WSH, 0) + testLoopInTimeout(t, swap.HtlcP2WSH, 0) }) outputTypes := []swap.HtlcOutputType{swap.HtlcP2WSH, swap.HtlcNP2WSH} From 5215222ced8ef91c4a13ed29a292f450c523a8b4 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Wed, 29 Apr 2020 10:54:58 +0200 Subject: [PATCH 8/9] cmd: print both htlc addresses when monitoring a loop-in --- cmd/loop/loopin.go | 5 ++++- cmd/loop/main.go | 23 ++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/cmd/loop/loopin.go b/cmd/loop/loopin.go index dee777f..ec0c795 100644 --- a/cmd/loop/loopin.go +++ b/cmd/loop/loopin.go @@ -153,7 +153,10 @@ func loopIn(ctx *cli.Context) error { fmt.Printf("Swap initiated\n") fmt.Printf("ID: %v\n", resp.Id) - fmt.Printf("HTLC address: %v\n", resp.HtlcAddress) + if external { + fmt.Printf("HTLC address (NP2WSH): %v\n", resp.HtlcAddressNp2Wsh) + } + fmt.Printf("HTLC address (P2WSH): %v\n", resp.HtlcAddressP2Wsh) fmt.Println() fmt.Printf("Run `loop monitor` to monitor progress.\n") diff --git a/cmd/loop/main.go b/cmd/loop/main.go index 9d11e47..abb1536 100644 --- a/cmd/loop/main.go +++ b/cmd/loop/main.go @@ -225,11 +225,24 @@ func parseAmt(text string) (btcutil.Amount, error) { } func logSwap(swap *looprpc.SwapStatus) { - fmt.Printf("%v %v %v %v - %v", - time.Unix(0, swap.LastUpdateTime).Format(time.RFC3339), - swap.Type, swap.State, btcutil.Amount(swap.Amt), - swap.HtlcAddress, - ) + if swap.Type == looprpc.SwapType_LOOP_OUT { + fmt.Printf("%v %v %v %v - %v", + time.Unix(0, swap.LastUpdateTime).Format(time.RFC3339), + swap.Type, swap.State, btcutil.Amount(swap.Amt), + swap.HtlcAddressP2Wsh, + ) + } else { + fmt.Printf("%v %v %v %v -", + time.Unix(0, swap.LastUpdateTime).Format(time.RFC3339), + swap.Type, swap.State, btcutil.Amount(swap.Amt)) + if swap.HtlcAddressP2Wsh != "" { + fmt.Printf(" P2WSH: %v", swap.HtlcAddressP2Wsh) + } + + if swap.HtlcAddressNp2Wsh != "" { + fmt.Printf(" NP2WSH: %v", swap.HtlcAddressNp2Wsh) + } + } if swap.State != looprpc.SwapState_INITIATED && swap.State != looprpc.SwapState_HTLC_PUBLISHED && From c6e3829acd0eaefee4449d695bef4a4a65563327 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Tue, 5 May 2020 09:14:26 +0200 Subject: [PATCH 9/9] looprpc: bump protocol version --- looprpc/server.pb.go | 113 ++++++++++++++++++++++-------------------- looprpc/server.proto | 6 +++ swap_server_client.go | 2 +- 3 files changed, 67 insertions(+), 54 deletions(-) diff --git a/looprpc/server.pb.go b/looprpc/server.pb.go index 382092d..46d8156 100644 --- a/looprpc/server.pb.go +++ b/looprpc/server.pb.go @@ -35,16 +35,22 @@ const ( ProtocolVersion_LEGACY ProtocolVersion = 0 /// Client may attempt to send the loop out payment in multiple parts. ProtocolVersion_MULTI_LOOP_OUT ProtocolVersion = 1 + //* + //Loop will use native segwit (P2WSH) htlcs by default, while externally + //published htlcs may use native (P2WSH) or nested (NP2WSH) segwit as well. + ProtocolVersion_NATIVE_SEGWIT_LOOP_IN ProtocolVersion = 2 ) var ProtocolVersion_name = map[int32]string{ 0: "LEGACY", 1: "MULTI_LOOP_OUT", + 2: "NATIVE_SEGWIT_LOOP_IN", } var ProtocolVersion_value = map[string]int32{ - "LEGACY": 0, - "MULTI_LOOP_OUT": 1, + "LEGACY": 0, + "MULTI_LOOP_OUT": 1, + "NATIVE_SEGWIT_LOOP_IN": 2, } func (x ProtocolVersion) String() string { @@ -784,57 +790,58 @@ func init() { func init() { proto.RegisterFile("server.proto", fileDescriptor_ad098daeda4239f7) } var fileDescriptor_ad098daeda4239f7 = []byte{ - // 786 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xdd, 0x52, 0xda, 0x40, - 0x14, 0x6e, 0x02, 0x82, 0x1c, 0xf9, 0x73, 0xfb, 0x17, 0x50, 0x3a, 0xc8, 0x4c, 0x1d, 0xc6, 0x0b, - 0x9d, 0xda, 0xbb, 0xde, 0x59, 0xad, 0x95, 0x29, 0x2d, 0x1a, 0xb1, 0x33, 0xbd, 0x4a, 0x57, 0x38, - 0x95, 0x4c, 0x43, 0x36, 0x26, 0x0b, 0xca, 0x9b, 0xb4, 0x2f, 0xd1, 0xb7, 0xe9, 0x2b, 0x74, 0xa6, - 0x97, 0x7d, 0x83, 0x4e, 0x36, 0x89, 0x24, 0x21, 0xa8, 0xcc, 0x78, 0x67, 0xce, 0x7e, 0x9e, 0xfd, - 0xbe, 0xef, 0x9c, 0x6f, 0x81, 0xbc, 0x83, 0xf6, 0x18, 0xed, 0x6d, 0xcb, 0x66, 0x9c, 0x91, 0xac, - 0xc1, 0x98, 0x65, 0x5b, 0xbd, 0xea, 0xfa, 0x05, 0x63, 0x17, 0x06, 0xee, 0x50, 0x4b, 0xdf, 0xa1, - 0xa6, 0xc9, 0x38, 0xe5, 0x3a, 0x33, 0x1d, 0x0f, 0xd6, 0xf8, 0x2b, 0xc1, 0x93, 0x53, 0xf1, 0x7f, - 0x6d, 0xc6, 0xac, 0xce, 0x88, 0xab, 0x78, 0x39, 0x42, 0x87, 0x93, 0x0d, 0xc8, 0xdb, 0xd8, 0x43, - 0x7d, 0x8c, 0xb6, 0xf6, 0x1d, 0x27, 0x8a, 0x54, 0x97, 0x9a, 0x79, 0x75, 0x25, 0xa8, 0x7d, 0xc0, - 0x09, 0x59, 0x83, 0x9c, 0x73, 0x45, 0x2d, 0x6d, 0x40, 0x9d, 0x81, 0x22, 0x8b, 0xf3, 0x65, 0xb7, - 0x70, 0x44, 0x9d, 0x01, 0x29, 0x43, 0x8a, 0x0e, 0xb9, 0x92, 0xaa, 0x4b, 0xcd, 0xb4, 0xea, 0xfe, - 0x49, 0xde, 0x40, 0x45, 0xc0, 0xad, 0xd1, 0xb9, 0xa1, 0xf7, 0x04, 0x0b, 0xad, 0x8f, 0xb4, 0x6f, - 0xe8, 0x26, 0x2a, 0xe9, 0xba, 0xd4, 0x4c, 0xa9, 0xcf, 0x5d, 0xc0, 0xf1, 0xf4, 0xfc, 0xc0, 0x3f, - 0x26, 0xfb, 0x50, 0x16, 0x7c, 0x7b, 0xcc, 0xd0, 0xc6, 0x68, 0x3b, 0x3a, 0x33, 0x95, 0xa5, 0xba, - 0xd4, 0x2c, 0xee, 0x2a, 0xdb, 0xbe, 0xd0, 0xed, 0x63, 0x1f, 0xf0, 0xd9, 0x3b, 0x57, 0x4b, 0x56, - 0xb4, 0xd0, 0xf8, 0x21, 0xc1, 0xd3, 0x98, 0x56, 0xc7, 0x62, 0xa6, 0x83, 0xae, 0x58, 0x41, 0x4d, - 0x37, 0xc7, 0x4c, 0xef, 0xa1, 0x10, 0x9b, 0x53, 0x57, 0xdc, 0x5a, 0xcb, 0x2b, 0x91, 0x97, 0x50, - 0xb4, 0x6c, 0xb4, 0xe8, 0xe4, 0x06, 0x24, 0x0b, 0x50, 0xc1, 0xab, 0x06, 0xb0, 0x1a, 0x80, 0x83, - 0x66, 0xdf, 0x37, 0x2d, 0x25, 0x4c, 0xc9, 0x79, 0x15, 0xd7, 0xb2, 0x67, 0x90, 0xc1, 0x6b, 0x4b, - 0xb7, 0x27, 0x42, 0xf0, 0x92, 0xea, 0x7f, 0x35, 0x7e, 0x49, 0x50, 0x89, 0x50, 0x3b, 0x19, 0x31, - 0x8e, 0xc1, 0x2c, 0x7c, 0x2f, 0xa5, 0x7b, 0x7a, 0x29, 0x2f, 0xee, 0x65, 0x6a, 0x51, 0x2f, 0x7f, - 0xca, 0x40, 0x66, 0x09, 0x93, 0x2d, 0x58, 0xf5, 0x78, 0xd1, 0xc9, 0x10, 0x4d, 0xae, 0xf5, 0xd1, - 0xe1, 0xbe, 0x9b, 0x25, 0xc1, 0xc7, 0xab, 0x1f, 0xb8, 0xaa, 0x2a, 0x20, 0xb6, 0x45, 0xfb, 0x86, - 0x01, 0xe5, 0xac, 0xfb, 0x7d, 0x88, 0x48, 0x36, 0xa1, 0x10, 0x1c, 0x69, 0x36, 0xe5, 0x28, 0xf8, - 0xa5, 0xde, 0xca, 0x8a, 0xe4, 0x0d, 0xe5, 0x10, 0x51, 0xa5, 0x5c, 0xb8, 0xed, 0x0f, 0xc5, 0xf5, - 0x27, 0x2d, 0xfc, 0xc9, 0x79, 0x95, 0xbd, 0x21, 0x27, 0x5b, 0x50, 0x1a, 0xea, 0xa6, 0x26, 0x5a, - 0xd1, 0x21, 0x1b, 0x99, 0x5c, 0x2c, 0x4d, 0x5a, 0x34, 0x2a, 0x0c, 0x75, 0xf3, 0xf4, 0x8a, 0x5a, - 0x7b, 0xe2, 0x40, 0x60, 0xe9, 0x75, 0x04, 0x9b, 0x09, 0x61, 0xe9, 0x75, 0x08, 0x5b, 0x03, 0xe8, - 0x19, 0x7c, 0xac, 0xf5, 0xd1, 0xe0, 0x54, 0xc9, 0x8a, 0x49, 0xe6, 0xdc, 0xca, 0x81, 0x5b, 0x68, - 0x7c, 0x8d, 0xcd, 0xb2, 0x8b, 0xf6, 0xd0, 0x09, 0x66, 0x99, 0xe4, 0xbe, 0xb4, 0xa8, 0xfb, 0xfd, - 0x98, 0xf9, 0xe2, 0x06, 0xb2, 0x39, 0x2b, 0xd7, 0x5b, 0x99, 0x98, 0xd4, 0xcd, 0x59, 0xa9, 0xb2, - 0x8f, 0x0b, 0xcb, 0x6c, 0xfc, 0x91, 0xe0, 0xf1, 0xf4, 0x9a, 0x96, 0x19, 0x48, 0x88, 0xee, 0xb8, - 0x14, 0xdf, 0xf1, 0x05, 0x9f, 0x85, 0x78, 0xf6, 0xd2, 0xb3, 0xd9, 0xab, 0xc0, 0xb2, 0x41, 0x1d, - 0xae, 0x0d, 0x98, 0x25, 0x06, 0x98, 0x57, 0xb3, 0xee, 0xf7, 0x11, 0xb3, 0x12, 0xed, 0xcc, 0x2c, - 0x6a, 0xe7, 0x49, 0xf8, 0x0d, 0x74, 0x75, 0x4e, 0x9f, 0x85, 0xbb, 0xde, 0xc0, 0x69, 0xa0, 0xe5, - 0x48, 0xa0, 0x2f, 0x41, 0x09, 0xb7, 0xbc, 0x23, 0xce, 0x49, 0x2a, 0xe4, 0x45, 0x55, 0xfc, 0x8e, - 0xbc, 0x21, 0x37, 0x77, 0xfa, 0x5a, 0xc2, 0x69, 0x93, 0xee, 0x48, 0x9b, 0x9c, 0x9c, 0xb6, 0x84, - 0x38, 0xa5, 0x17, 0x88, 0xd3, 0xd2, 0xfd, 0xe2, 0x94, 0x89, 0xc7, 0x49, 0x8b, 0x5a, 0xf9, 0xf0, - 0x69, 0xea, 0xc1, 0xea, 0xcc, 0x05, 0x0f, 0x1d, 0xa6, 0xad, 0x57, 0x50, 0x8a, 0x11, 0x21, 0x00, - 0x99, 0xf6, 0xbb, 0xf7, 0x7b, 0xfb, 0x5f, 0xca, 0x8f, 0x08, 0x81, 0xe2, 0xc7, 0xb3, 0x76, 0xb7, - 0xa5, 0xb5, 0x3b, 0x9d, 0x63, 0xad, 0x73, 0xd6, 0x2d, 0x4b, 0xbb, 0xff, 0x52, 0x00, 0x6e, 0x07, - 0x8f, 0x1c, 0xe9, 0x40, 0x3e, 0x12, 0xf7, 0xc6, 0x8d, 0xc2, 0xb9, 0xaf, 0x4d, 0x75, 0xed, 0x16, - 0x0c, 0xe9, 0x40, 0xf1, 0x13, 0x5e, 0xf9, 0x25, 0xf7, 0x22, 0x52, 0x4b, 0x86, 0x07, 0xdd, 0x5e, - 0xcc, 0x3b, 0xf6, 0x77, 0x6c, 0xca, 0xd0, 0xfb, 0x35, 0x98, 0xc3, 0x30, 0x1c, 0x86, 0x79, 0x0c, - 0xbd, 0x06, 0x6d, 0x58, 0x09, 0xcf, 0x64, 0x23, 0x01, 0x1b, 0x5d, 0x88, 0x6a, 0x75, 0x3e, 0x84, - 0xb4, 0xa1, 0xe0, 0xeb, 0x6d, 0x89, 0x09, 0x92, 0xf5, 0x44, 0x70, 0xd0, 0xaa, 0x36, 0xe7, 0xd4, - 0x17, 0xdb, 0x0d, 0xb8, 0x79, 0x54, 0x93, 0xb9, 0x45, 0xa4, 0x36, 0x6e, 0x83, 0x78, 0x5d, 0xcf, - 0x33, 0x62, 0x39, 0x5f, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xd4, 0x54, 0xd0, 0xf3, 0xcd, 0x09, - 0x00, 0x00, + // 810 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xdd, 0x52, 0xe2, 0x48, + 0x14, 0xde, 0x04, 0x04, 0x39, 0xf2, 0x67, 0xef, 0xba, 0x1b, 0x50, 0xb6, 0x90, 0xaa, 0xb5, 0x28, + 0x2f, 0xb4, 0xca, 0xbd, 0xdb, 0x3b, 0xd6, 0x5f, 0x6a, 0x59, 0xd1, 0x88, 0x6e, 0xed, 0x55, 0xa6, + 0x85, 0x1e, 0x49, 0x4d, 0x48, 0xc7, 0xa4, 0x41, 0x79, 0x93, 0x99, 0x97, 0x98, 0xb7, 0x99, 0x57, + 0x98, 0xaa, 0xb9, 0x9c, 0x37, 0x98, 0xea, 0xee, 0x44, 0x92, 0x10, 0x54, 0xaa, 0xbc, 0x33, 0xe7, + 0x7c, 0x76, 0x7f, 0xdf, 0x77, 0xce, 0xd7, 0x40, 0xde, 0x23, 0xee, 0x84, 0xb8, 0x7b, 0x8e, 0x4b, + 0x19, 0x45, 0x59, 0x8b, 0x52, 0xc7, 0x75, 0xfa, 0xd5, 0xad, 0x3b, 0x4a, 0xef, 0x2c, 0xb2, 0x8f, + 0x1d, 0x73, 0x1f, 0xdb, 0x36, 0x65, 0x98, 0x99, 0xd4, 0xf6, 0x24, 0xac, 0xf1, 0x4d, 0x81, 0x5f, + 0xae, 0xc4, 0xff, 0x75, 0x28, 0x75, 0xba, 0x63, 0xa6, 0x93, 0xfb, 0x31, 0xf1, 0x18, 0xda, 0x86, + 0xbc, 0x4b, 0xfa, 0xc4, 0x9c, 0x10, 0xd7, 0xf8, 0x40, 0xa6, 0x9a, 0x52, 0x57, 0x9a, 0x79, 0x7d, + 0x2d, 0xa8, 0xfd, 0x43, 0xa6, 0x68, 0x13, 0x72, 0xde, 0x03, 0x76, 0x8c, 0x21, 0xf6, 0x86, 0x9a, + 0x2a, 0xfa, 0xab, 0xbc, 0x70, 0x86, 0xbd, 0x21, 0x2a, 0x43, 0x0a, 0x8f, 0x98, 0x96, 0xaa, 0x2b, + 0xcd, 0xb4, 0xce, 0xff, 0x44, 0x7f, 0x41, 0x45, 0xc0, 0x9d, 0xf1, 0xad, 0x65, 0xf6, 0x05, 0x0b, + 0x63, 0x40, 0xf0, 0xc0, 0x32, 0x6d, 0xa2, 0xa5, 0xeb, 0x4a, 0x33, 0xa5, 0xff, 0xc6, 0x01, 0x17, + 0xb3, 0xfe, 0x91, 0xdf, 0x46, 0x87, 0x50, 0x16, 0x7c, 0xfb, 0xd4, 0x32, 0x26, 0xc4, 0xf5, 0x4c, + 0x6a, 0x6b, 0x2b, 0x75, 0xa5, 0x59, 0x3c, 0xd0, 0xf6, 0x7c, 0xa1, 0x7b, 0x17, 0x3e, 0xe0, 0x46, + 0xf6, 0xf5, 0x92, 0x13, 0x2d, 0x34, 0x3e, 0x2a, 0xb0, 0x11, 0xd3, 0xea, 0x39, 0xd4, 0xf6, 0x08, + 0x17, 0x2b, 0xa8, 0x99, 0xf6, 0x84, 0x9a, 0x7d, 0x22, 0xc4, 0xe6, 0xf4, 0x35, 0x5e, 0x6b, 0xcb, + 0x12, 0xfa, 0x03, 0x8a, 0x8e, 0x4b, 0x1c, 0x3c, 0x7d, 0x02, 0xa9, 0x02, 0x54, 0x90, 0xd5, 0x00, + 0x56, 0x03, 0xf0, 0x88, 0x3d, 0xf0, 0x4d, 0x4b, 0x09, 0x53, 0x72, 0xb2, 0xc2, 0x2d, 0xfb, 0x15, + 0x32, 0xe4, 0xd1, 0x31, 0xdd, 0xa9, 0x10, 0xbc, 0xa2, 0xfb, 0x5f, 0x8d, 0xcf, 0x0a, 0x54, 0x22, + 0xd4, 0x2e, 0xc7, 0x94, 0x91, 0x60, 0x16, 0xbe, 0x97, 0xca, 0x2b, 0xbd, 0x54, 0x97, 0xf7, 0x32, + 0xb5, 0xac, 0x97, 0x9f, 0x54, 0x40, 0xf3, 0x84, 0xd1, 0x2e, 0xac, 0x4b, 0x5e, 0x78, 0x3a, 0x22, + 0x36, 0x33, 0x06, 0xc4, 0x63, 0xbe, 0x9b, 0x25, 0xc1, 0x47, 0xd6, 0x8f, 0xb8, 0xaa, 0x0a, 0x88, + 0x6d, 0x31, 0xde, 0x93, 0x80, 0x72, 0x96, 0x7f, 0x9f, 0x10, 0x82, 0x76, 0xa0, 0x10, 0xb4, 0x0c, + 0x17, 0x33, 0x22, 0xf8, 0xa5, 0xfe, 0x56, 0x35, 0x45, 0x0e, 0xe5, 0x84, 0x10, 0x1d, 0x33, 0xe1, + 0xb6, 0x3f, 0x14, 0xee, 0x4f, 0x5a, 0xf8, 0x93, 0x93, 0x95, 0xd6, 0x88, 0xa1, 0x5d, 0x28, 0x8d, + 0x4c, 0xdb, 0x10, 0x47, 0xe1, 0x11, 0x1d, 0xdb, 0x4c, 0x2c, 0x4d, 0x5a, 0x1c, 0x54, 0x18, 0x99, + 0xf6, 0xd5, 0x03, 0x76, 0x5a, 0xa2, 0x21, 0xb0, 0xf8, 0x31, 0x82, 0xcd, 0x84, 0xb0, 0xf8, 0x31, + 0x84, 0xad, 0x01, 0xf4, 0x2d, 0x36, 0x31, 0x06, 0xc4, 0x62, 0x58, 0xcb, 0x8a, 0x49, 0xe6, 0x78, + 0xe5, 0x88, 0x17, 0x1a, 0xef, 0x62, 0xb3, 0xec, 0x11, 0x77, 0xe4, 0x05, 0xb3, 0x4c, 0x72, 0x5f, + 0x59, 0xd6, 0xfd, 0x41, 0xcc, 0x7c, 0x71, 0x03, 0xda, 0x99, 0x97, 0x2b, 0x57, 0x26, 0x26, 0x75, + 0x67, 0x5e, 0xaa, 0xea, 0xe3, 0xc2, 0x32, 0x1b, 0x5f, 0x15, 0xf8, 0x79, 0x76, 0x4d, 0xdb, 0x0e, + 0x24, 0x44, 0x77, 0x5c, 0x89, 0xef, 0xf8, 0x92, 0xcf, 0x42, 0x3c, 0x7b, 0xe9, 0xf9, 0xec, 0x55, + 0x60, 0xd5, 0xc2, 0x1e, 0x33, 0x86, 0xd4, 0x11, 0x03, 0xcc, 0xeb, 0x59, 0xfe, 0x7d, 0x46, 0x9d, + 0x44, 0x3b, 0x33, 0xcb, 0xda, 0x79, 0x19, 0x7e, 0x03, 0xb9, 0xce, 0xd9, 0xb3, 0xf0, 0xd2, 0x1b, + 0x38, 0x0b, 0xb4, 0x1a, 0x09, 0xf4, 0x3d, 0x68, 0xe1, 0x23, 0x5f, 0x88, 0x73, 0x92, 0x0a, 0x75, + 0x59, 0x15, 0x5f, 0x22, 0x6f, 0xc8, 0xd3, 0x9d, 0xbe, 0x96, 0x70, 0xda, 0x94, 0x17, 0xd2, 0xa6, + 0x26, 0xa7, 0x2d, 0x21, 0x4e, 0xe9, 0x25, 0xe2, 0xb4, 0xf2, 0xba, 0x38, 0x65, 0xe2, 0x71, 0x32, + 0xa2, 0x56, 0xbe, 0x7d, 0x9a, 0xfa, 0xb0, 0x3e, 0x77, 0xc1, 0x5b, 0x87, 0x69, 0xb7, 0x03, 0xa5, + 0x18, 0x11, 0x04, 0x90, 0xe9, 0x1c, 0x9f, 0xb6, 0x0e, 0xff, 0x2f, 0xff, 0x84, 0x10, 0x14, 0xff, + 0xbd, 0xee, 0xf4, 0xda, 0x46, 0xa7, 0xdb, 0xbd, 0x30, 0xba, 0xd7, 0xbd, 0xb2, 0x82, 0x2a, 0xb0, + 0x71, 0xde, 0xea, 0xb5, 0x6f, 0x8e, 0x8d, 0xab, 0xe3, 0xd3, 0xff, 0xda, 0x3d, 0xd9, 0x6b, 0x9f, + 0x97, 0xd5, 0x83, 0xef, 0x29, 0x00, 0x7e, 0xb8, 0xe4, 0x8d, 0xba, 0x90, 0x8f, 0xbc, 0x04, 0x8d, + 0x27, 0xf1, 0x0b, 0x1f, 0xa2, 0xea, 0xe6, 0x33, 0x18, 0xd4, 0x85, 0xe2, 0x39, 0x79, 0xf0, 0x4b, + 0xfc, 0x22, 0x54, 0x4b, 0x86, 0x07, 0xa7, 0xfd, 0xbe, 0xa8, 0xed, 0xaf, 0xdf, 0x8c, 0xa1, 0xfc, + 0xa1, 0x58, 0xc0, 0x30, 0x9c, 0x93, 0x45, 0x0c, 0xe5, 0x01, 0x1d, 0x58, 0x0b, 0x8f, 0x6b, 0x3b, + 0x01, 0x1b, 0xdd, 0x95, 0x6a, 0x75, 0x31, 0x04, 0x75, 0xa0, 0xe0, 0xeb, 0x6d, 0x8b, 0xe1, 0xa2, + 0xad, 0x44, 0x70, 0x70, 0x54, 0x6d, 0x41, 0xd7, 0x17, 0xdb, 0x0b, 0xb8, 0x49, 0xaa, 0xc9, 0xdc, + 0x22, 0x52, 0x1b, 0xcf, 0x41, 0xe4, 0xa9, 0xb7, 0x19, 0xb1, 0xb7, 0x7f, 0xfe, 0x08, 0x00, 0x00, + 0xff, 0xff, 0xd3, 0x5d, 0x9c, 0x31, 0xe8, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/looprpc/server.proto b/looprpc/server.proto index 706ee50..de8996e 100644 --- a/looprpc/server.proto +++ b/looprpc/server.proto @@ -31,6 +31,12 @@ enum ProtocolVersion { /// Client may attempt to send the loop out payment in multiple parts. MULTI_LOOP_OUT = 1; + + /** + Loop will use native segwit (P2WSH) htlcs by default, while externally + published htlcs may use native (P2WSH) or nested (NP2WSH) segwit as well. + */ + NATIVE_SEGWIT_LOOP_IN = 2; } message ServerLoopOutRequest { diff --git a/swap_server_client.go b/swap_server_client.go index cdd1e9d..c679668 100644 --- a/swap_server_client.go +++ b/swap_server_client.go @@ -22,7 +22,7 @@ import ( // protocolVersion defines the version of the protocol that is currently // supported by the loop client. -const protocolVersion = looprpc.ProtocolVersion_MULTI_LOOP_OUT +const protocolVersion = looprpc.ProtocolVersion_NATIVE_SEGWIT_LOOP_IN type swapServerClient interface { GetLoopOutTerms(ctx context.Context) (