Merge pull request #248 from joostjager/user-expiry

loopout: user-specified expiry
pull/254/head
Joost Jager 4 years ago committed by GitHub
commit 2f40064639
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,6 +3,7 @@ package loop
import (
"context"
"errors"
"fmt"
"strings"
"sync"
"sync/atomic"
@ -33,20 +34,10 @@ var (
// more than the server maximum.
ErrSwapAmountTooHigh = errors.New("swap amount too high")
// ErrExpiryTooSoon is returned when the server proposes an expiry that
// is too soon for us.
ErrExpiryTooSoon = errors.New("swap expiry too soon")
// ErrExpiryTooFar is returned when the server proposes an expiry that
// is too soon for us.
ErrExpiryTooFar = errors.New("swap expiry too far")
// ErrSweepConfTargetTooFar is returned when the client proposes a
// confirmation target to sweep the on-chain HTLC of a Loop Out that is
// beyond the expiration height proposed by the server.
ErrSweepConfTargetTooFar = errors.New("sweep confirmation target is " +
"beyond swap expiration height")
// serverRPCTimeout is the maximum time a gRPC request to the server
// should be allowed to take.
serverRPCTimeout = 30 * time.Second
@ -363,8 +354,21 @@ func (s *Client) LoopOut(globalCtx context.Context,
return nil, err
}
// Create a new swap object for this swap.
// Calculate htlc expiry height.
terms, err := s.Server.GetLoopOutTerms(globalCtx)
if err != nil {
return nil, err
}
initiationHeight := s.executor.height()
request.Expiry, err = s.getExpiry(
initiationHeight, terms, request.SweepConfTarget,
)
if err != nil {
return nil, err
}
// Create a new swap object for this swap.
swapCfg := newSwapConfig(s.lndServices, s.Store, s.Server)
initResult, err := newLoopOutSwap(
globalCtx, swapCfg, initiationHeight, request,
@ -386,6 +390,24 @@ func (s *Client) LoopOut(globalCtx context.Context,
}, nil
}
// getExpiry returns an absolute expiry height based on the sweep confirmation
// target, constrained by the server terms.
func (s *Client) getExpiry(height int32, terms *LoopOutTerms,
confTarget int32) (int32, error) {
switch {
case confTarget < terms.MinCltvDelta:
return height + terms.MinCltvDelta, nil
case confTarget > terms.MaxCltvDelta:
return 0, fmt.Errorf("confirmation target %v exceeds maximum "+
"server cltv delta of %v", confTarget,
terms.MaxCltvDelta)
}
return height + confTarget, nil
}
// LoopOutQuote takes a LoopOut amount and returns a break down of estimated
// costs for the client. Both the swap server and the on-chain fee estimator
// are queried to get to build the quote response.
@ -405,8 +427,14 @@ func (s *Client) LoopOutQuote(ctx context.Context,
return nil, ErrSwapAmountTooHigh
}
height := s.executor.height()
expiry, err := s.getExpiry(height, terms, request.SweepConfTarget)
if err != nil {
return nil, err
}
quote, err := s.Server.GetLoopOutQuote(
ctx, request.Amount, request.SwapPublicationDeadline,
ctx, request.Amount, expiry, request.SwapPublicationDeadline,
)
if err != nil {
return nil, err
@ -440,7 +468,6 @@ func (s *Client) LoopOutQuote(ctx context.Context,
MinerFee: minerFee,
PrepayAmount: quote.PrepayAmount,
SwapPaymentDest: quote.SwapPaymentDest,
CltvDelta: quote.CltvDelta,
}, nil
}

@ -39,6 +39,9 @@ func terms(ctx *cli.Context) error {
loopOutTerms.MinSwapAmount,
loopOutTerms.MaxSwapAmount,
)
fmt.Printf("Cltv delta: %d - %d\n",
loopOutTerms.MinCltvDelta, loopOutTerms.MaxCltvDelta,
)
}
fmt.Println()

@ -71,6 +71,9 @@ type OutRequest struct {
// SwapPublicationDeadline can be set by the client to allow the server
// delaying publication of the swap HTLC to save on chain fees.
SwapPublicationDeadline time.Time
// Expiry is the absolute expiry height of the on-chain htlc.
Expiry int32
}
// Out contains the full details of a loop out request. This includes things
@ -124,6 +127,12 @@ type LoopOutTerms struct {
// MaxSwapAmount is the maximum amount that the server accepts for a
// swap.
MaxSwapAmount btcutil.Amount
// MinCltvDelta is the minimum expiry delta for loop out swaps.
MinCltvDelta int32
// MaxCltvDelta is the maximum expiry delta for loop out swaps.
MaxCltvDelta int32
}
// LoopOutQuote contains estimates for the fees making up the total swap cost
@ -140,10 +149,6 @@ type LoopOutQuote struct {
// sweep the htlc.
MinerFee btcutil.Amount
// Time lock delta relative to current block height that swap server
// will accept on the swap initiation call.
CltvDelta int32
// SwapPaymentDest is the node pubkey where to swap payment needs to be
// sent to.
SwapPaymentDest [33]byte

@ -341,6 +341,8 @@ func (s *swapClientServer) LoopOutTerms(ctx context.Context,
return &looprpc.OutTermsResponse{
MinSwapAmount: int64(terms.MinSwapAmount),
MaxSwapAmount: int64(terms.MaxSwapAmount),
MinCltvDelta: terms.MinCltvDelta,
MaxCltvDelta: terms.MaxCltvDelta,
}, nil
}
@ -371,7 +373,6 @@ func (s *swapClientServer) LoopOutQuote(ctx context.Context,
PrepayAmtSat: int64(quote.PrepayAmount),
SwapFeeSat: int64(quote.SwapFee),
SwapPaymentDest: quote.SwapPaymentDest[:],
CltvDelta: quote.CltvDelta,
}, nil
}

@ -106,13 +106,14 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
// Post the swap parameters to the swap server. The response contains
// the server revocation key and the swap and prepay invoices.
log.Infof("Initiating swap request at height %v", currentHeight)
log.Infof("Initiating swap request at height %v: amt=%v, expiry=%v",
currentHeight, request.Amount, request.Expiry)
// The swap deadline will be given to the server for it to use as the
// latest swap publication time.
swapResp, err := cfg.server.NewLoopOutSwap(
globalCtx, swapHash, request.Amount, receiverKey,
request.SwapPublicationDeadline,
globalCtx, swapHash, request.Amount, request.Expiry,
receiverKey, request.SwapPublicationDeadline,
)
if err != nil {
return nil, fmt.Errorf("cannot initiate swap: %v", err)
@ -150,7 +151,7 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
SenderKey: swapResp.senderKey,
Preimage: swapPreimage,
AmountRequested: request.Amount,
CltvExpiry: swapResp.expiry,
CltvExpiry: request.Expiry,
MaxMinerFee: request.MaxMinerFee,
MaxSwapFee: request.MaxSwapFee,
},
@ -994,18 +995,5 @@ func validateLoopOutContract(lnd *lndclient.LndServices,
return ErrPrepayAmountTooHigh
}
if response.expiry-height < MinLoopOutPreimageRevealDelta {
log.Warnf("Proposed expiry %v (delta %v) too soon",
response.expiry, response.expiry-height)
return ErrExpiryTooSoon
}
// Ensure the client has provided a sweep confirmation target that does
// not exceed the height at which we revert back to using the default.
if height+request.SweepConfTarget >= response.expiry-DefaultSweepConfTargetDelta {
return ErrSweepConfTargetTooFar
}
return nil
}

@ -151,6 +151,8 @@ func TestLateHtlcPublish(t *testing.T) {
cfg := newSwapConfig(&lnd.LndServices, store, server)
testRequest.Expiry = height + testLoopOutMinOnChainCltvDelta
initResult, err := newLoopOutSwap(
context.Background(), cfg, height, testRequest,
)
@ -225,12 +227,14 @@ func TestCustomSweepConfTarget(t *testing.T) {
// Use the highest sweep confirmation target before we attempt to use
// the default.
testRequest.SweepConfTarget = testLoopOutOnChainCltvDelta -
testReq := *testRequest
testReq.SweepConfTarget = testLoopOutMinOnChainCltvDelta -
DefaultSweepConfTargetDelta - 1
// Set up custom fee estimates such that the lower confirmation target
// yields a much higher fee rate.
ctx.Lnd.SetFeeEstimate(testRequest.SweepConfTarget, 250)
ctx.Lnd.SetFeeEstimate(testReq.SweepConfTarget, 250)
ctx.Lnd.SetFeeEstimate(DefaultSweepConfTarget, 10000)
cfg := newSwapConfig(
@ -238,7 +242,7 @@ func TestCustomSweepConfTarget(t *testing.T) {
)
initResult, err := newLoopOutSwap(
context.Background(), cfg, ctx.Lnd.Height, testRequest,
context.Background(), cfg, ctx.Lnd.Height, &testReq,
)
if err != nil {
t.Fatal(err)
@ -357,7 +361,7 @@ func TestCustomSweepConfTarget(t *testing.T) {
// The sweep should have a fee that corresponds to the custom
// confirmation target.
_ = assertSweepTx(testRequest.SweepConfTarget)
_ = assertSweepTx(testReq.SweepConfTarget)
// Once we have published an on chain sweep, we expect a preimage to
// have been pushed to our server.
@ -374,8 +378,8 @@ func TestCustomSweepConfTarget(t *testing.T) {
// We'll then notify the height at which we begin using the default
// confirmation target.
defaultConfTargetHeight := ctx.Lnd.Height + testLoopOutOnChainCltvDelta -
DefaultSweepConfTargetDelta
defaultConfTargetHeight := ctx.Lnd.Height +
testLoopOutMinOnChainCltvDelta - DefaultSweepConfTargetDelta
blockEpochChan <- int32(defaultConfTargetHeight)
expiryChan <- time.Now()
@ -424,15 +428,17 @@ func TestPreimagePush(t *testing.T) {
// Start with a high confirmation delta which will have a very high fee
// attached to it.
testRequest.SweepConfTarget = testLoopOutOnChainCltvDelta -
testReq := *testRequest
testReq.SweepConfTarget = testLoopOutMinOnChainCltvDelta -
DefaultSweepConfTargetDelta - 1
testReq.Expiry = ctx.Lnd.Height + testLoopOutMinOnChainCltvDelta
// We set our mock fee estimate for our target sweep confs to be our
// max miner fee *2, so that our fee will definitely be above what we
// are willing to pay, and we will not sweep.
ctx.Lnd.SetFeeEstimate(
testRequest.SweepConfTarget, chainfee.SatPerKWeight(
testRequest.MaxMinerFee*2,
testReq.SweepConfTarget, chainfee.SatPerKWeight(
testReq.MaxMinerFee*2,
),
)
@ -446,7 +452,7 @@ func TestPreimagePush(t *testing.T) {
)
initResult, err := newLoopOutSwap(
context.Background(), cfg, ctx.Lnd.Height, testRequest,
context.Background(), cfg, ctx.Lnd.Height, &testReq,
)
require.NoError(t, err)
swap := initResult.swap
@ -517,7 +523,7 @@ func TestPreimagePush(t *testing.T) {
// Now, we notify the height at which the client will start using the
// default confirmation target. This has the effect of lowering our fees
// so that the client still start sweeping.
defaultConfTargetHeight := ctx.Lnd.Height + testLoopOutOnChainCltvDelta -
defaultConfTargetHeight := ctx.Lnd.Height + testLoopOutMinOnChainCltvDelta -
DefaultSweepConfTargetDelta
blockEpochChan <- defaultConfTargetHeight

@ -890,7 +890,11 @@ type OutTermsResponse struct {
MinSwapAmount int64 `protobuf:"varint,5,opt,name=min_swap_amount,json=minSwapAmount,proto3" json:"min_swap_amount,omitempty"`
//*
//Maximum swap amount (sat)
MaxSwapAmount int64 `protobuf:"varint,6,opt,name=max_swap_amount,json=maxSwapAmount,proto3" json:"max_swap_amount,omitempty"`
MaxSwapAmount int64 `protobuf:"varint,6,opt,name=max_swap_amount,json=maxSwapAmount,proto3" json:"max_swap_amount,omitempty"`
// The minimally accepted cltv delta of the on-chain htlc.
MinCltvDelta int32 `protobuf:"varint,8,opt,name=min_cltv_delta,json=minCltvDelta,proto3" json:"min_cltv_delta,omitempty"`
// The maximally accepted cltv delta of the on-chain htlc.
MaxCltvDelta int32 `protobuf:"varint,9,opt,name=max_cltv_delta,json=maxCltvDelta,proto3" json:"max_cltv_delta,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -935,6 +939,20 @@ func (m *OutTermsResponse) GetMaxSwapAmount() int64 {
return 0
}
func (m *OutTermsResponse) GetMinCltvDelta() int32 {
if m != nil {
return m.MinCltvDelta
}
return 0
}
func (m *OutTermsResponse) GetMaxCltvDelta() int32 {
if m != nil {
return m.MaxCltvDelta
}
return 0
}
type QuoteRequest struct {
//*
//The amount to swap in satoshis.
@ -1374,109 +1392,111 @@ func init() {
func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) }
var fileDescriptor_014de31d7ac8c57c = []byte{
// 1619 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xdd, 0x6e, 0x23, 0x49,
// 1651 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xdd, 0x6e, 0x23, 0x49,
0x15, 0xde, 0xf6, 0x4f, 0x6c, 0x1f, 0xb7, 0xdb, 0x9d, 0xca, 0xce, 0xc4, 0xb1, 0x40, 0xeb, 0x69,
0x76, 0x20, 0x1b, 0x56, 0x63, 0x36, 0x7b, 0xc5, 0x0a, 0x21, 0x65, 0x12, 0xef, 0xc6, 0x51, 0x7e,
0x4c, 0xdb, 0x59, 0x09, 0x84, 0xd4, 0xaa, 0xb8, 0x2b, 0x71, 0x0b, 0x77, 0x57, 0x6f, 0x57, 0x79,
0x26, 0xd1, 0x08, 0x81, 0x78, 0x01, 0x2e, 0x78, 0x03, 0x5e, 0x83, 0x37, 0xe0, 0x0e, 0x78, 0x00,
0x6e, 0xb8, 0xe1, 0x25, 0x10, 0xaa, 0x53, 0xdd, 0xed, 0xee, 0xfc, 0x49, 0x5c, 0x71, 0xe7, 0xfe,
0xea, 0xab, 0x53, 0xe7, 0xa7, 0xce, 0x77, 0xca, 0x60, 0xce, 0x97, 0x01, 0x8b, 0xe4, 0x9b, 0x38,
0xe1, 0x92, 0x93, 0xc6, 0x92, 0xf3, 0x38, 0x89, 0xe7, 0xfd, 0xef, 0xdd, 0x70, 0x7e, 0xb3, 0x64,
0x43, 0x1a, 0x07, 0x43, 0x1a, 0x45, 0x5c, 0x52, 0x19, 0xf0, 0x48, 0x68, 0x9a, 0xf3, 0xd7, 0x2a,
0x58, 0xa7, 0x9c, 0xc7, 0x17, 0x2b, 0xe9, 0xb2, 0xef, 0x56, 0x4c, 0x48, 0x62, 0x43, 0x95, 0x86,
0xb2, 0x67, 0x0c, 0x8c, 0xdd, 0xaa, 0xab, 0x7e, 0x12, 0x02, 0x35, 0x9f, 0x09, 0xd9, 0xab, 0x0c,
0x8c, 0xdd, 0x96, 0x8b, 0xbf, 0xc9, 0x10, 0x3e, 0x0e, 0xe9, 0xad, 0x27, 0xde, 0xd3, 0xd8, 0x4b,
0xf8, 0x4a, 0x06, 0xd1, 0x8d, 0x77, 0xcd, 0x58, 0xaf, 0x8a, 0xdb, 0x36, 0x43, 0x7a, 0x3b, 0x7d,
0x4f, 0x63, 0x57, 0xaf, 0x7c, 0xcd, 0x18, 0xf9, 0x12, 0x5e, 0xaa, 0x0d, 0x71, 0xc2, 0x62, 0x7a,
0x57, 0xda, 0x52, 0xc3, 0x2d, 0x5b, 0x21, 0xbd, 0x9d, 0xe0, 0x62, 0x61, 0xd3, 0x00, 0xcc, 0xfc,
0x14, 0x45, 0xad, 0x23, 0x15, 0x52, 0xeb, 0x8a, 0xf1, 0x29, 0x58, 0x05, 0xb3, 0xca, 0xf1, 0x0d,
0xe4, 0x98, 0xb9, 0xb9, 0x83, 0x50, 0x12, 0x07, 0x3a, 0x8a, 0x15, 0x06, 0x11, 0x4b, 0xd0, 0x50,
0x03, 0x49, 0xed, 0x90, 0xde, 0x9e, 0x29, 0x4c, 0x59, 0xfa, 0x1c, 0x6c, 0x95, 0x33, 0x8f, 0xaf,
0xa4, 0x37, 0x5f, 0xd0, 0x28, 0x62, 0xcb, 0x5e, 0x73, 0x60, 0xec, 0xd6, 0xde, 0x56, 0x7a, 0x86,
0x6b, 0x2d, 0x75, 0x96, 0x0e, 0xf5, 0x0a, 0xd9, 0x83, 0x4d, 0xbe, 0x92, 0x37, 0x5c, 0x05, 0xa1,
0xd8, 0x9e, 0x60, 0xb2, 0xd7, 0x1e, 0x54, 0x77, 0x6b, 0x6e, 0x37, 0x5b, 0x50, 0xdc, 0x29, 0x93,
0x8a, 0x2b, 0xde, 0x33, 0x16, 0x7b, 0x73, 0x1e, 0x5d, 0x7b, 0x92, 0x26, 0x37, 0x4c, 0xf6, 0x5a,
0x03, 0x63, 0xb7, 0xee, 0x76, 0x71, 0xe1, 0x90, 0x47, 0xd7, 0x33, 0x84, 0xc9, 0x57, 0xb0, 0x83,
0xd1, 0xc6, 0xab, 0xab, 0x65, 0x30, 0xc7, 0x5a, 0x79, 0x3e, 0xa3, 0xfe, 0x32, 0x88, 0x58, 0x0f,
0x94, 0x3b, 0xee, 0xb6, 0x22, 0x4c, 0xd6, 0xeb, 0x47, 0xe9, 0xb2, 0xf3, 0x37, 0x03, 0x3a, 0xaa,
0x98, 0xe3, 0xe8, 0xe9, 0x5a, 0xde, 0xcf, 0x68, 0xe5, 0x41, 0x46, 0x1f, 0xe4, 0xaa, 0xfa, 0x30,
0x57, 0x3b, 0xd0, 0x5c, 0x52, 0x21, 0xbd, 0x05, 0x8f, 0xb1, 0x7c, 0xa6, 0xdb, 0x50, 0xdf, 0xc7,
0x3c, 0x26, 0x3f, 0x80, 0x0e, 0xbb, 0x95, 0x2c, 0x89, 0xe8, 0xd2, 0x5b, 0xc8, 0xe5, 0x1c, 0x6b,
0xd6, 0x74, 0xcd, 0x0c, 0x3c, 0x96, 0xcb, 0x39, 0xd9, 0x05, 0x5b, 0xad, 0x95, 0x12, 0xb2, 0x81,
0x09, 0xb1, 0x14, 0xbe, 0xce, 0x87, 0xf3, 0x6f, 0x03, 0x4c, 0xbc, 0x49, 0x4c, 0xc4, 0x3c, 0x12,
0x8c, 0x10, 0xa8, 0x04, 0x3e, 0x46, 0xd4, 0xc2, 0xc2, 0x54, 0x02, 0x5f, 0xb9, 0x13, 0xf8, 0xde,
0xd5, 0x9d, 0x64, 0x02, 0xbd, 0x35, 0xdd, 0x46, 0xe0, 0xbf, 0x55, 0x9f, 0xe4, 0x35, 0x98, 0x78,
0x12, 0xf5, 0xfd, 0x84, 0x09, 0xa1, 0xef, 0x30, 0x6e, 0x6c, 0x2b, 0xfc, 0x40, 0xc3, 0xe4, 0x0d,
0x6c, 0x15, 0x69, 0x5e, 0x14, 0xef, 0xbf, 0x17, 0x0b, 0x8c, 0xad, 0xe5, 0x6e, 0x16, 0x98, 0xe7,
0xb8, 0x40, 0x3e, 0x07, 0x52, 0xe2, 0x6b, 0x7a, 0x1d, 0xe9, 0x76, 0x81, 0x3e, 0x41, 0xf6, 0x6b,
0xb0, 0x04, 0x4b, 0xde, 0xb1, 0xc4, 0x0b, 0x99, 0x10, 0xf4, 0x86, 0x61, 0xb0, 0x2d, 0xb7, 0xa3,
0xd1, 0x33, 0x0d, 0x3a, 0x36, 0x58, 0x67, 0x3c, 0x0a, 0x24, 0x4f, 0xd2, 0xfa, 0x39, 0xff, 0xac,
0x02, 0xa8, 0xe8, 0xa7, 0x92, 0xca, 0x95, 0x78, 0xb4, 0x35, 0x55, 0x36, 0x2a, 0x4f, 0x66, 0xa3,
0x7d, 0x3f, 0x1b, 0x35, 0x79, 0x17, 0xeb, 0x92, 0x5a, 0xfb, 0x9b, 0x6f, 0x52, 0x91, 0x78, 0xa3,
0xce, 0x98, 0xdd, 0xc5, 0xcc, 0xc5, 0x65, 0xb2, 0x0b, 0x75, 0x21, 0xa9, 0xd4, 0xad, 0x69, 0xed,
0x93, 0x12, 0x4f, 0xf9, 0xc2, 0x5c, 0x4d, 0x20, 0x3f, 0x82, 0x6e, 0x10, 0x05, 0x32, 0xd0, 0x17,
0x55, 0x06, 0x61, 0xd6, 0xa3, 0xd6, 0x1a, 0x9e, 0x05, 0xa1, 0x32, 0x69, 0xe3, 0x8d, 0x59, 0xc5,
0x3e, 0x95, 0x4c, 0x33, 0x75, 0xa7, 0x5a, 0x0a, 0xbf, 0x44, 0x18, 0x99, 0xf7, 0x2b, 0xd6, 0x78,
0xbc, 0x62, 0x8f, 0x57, 0xc0, 0x7c, 0xa2, 0x02, 0x4f, 0xd4, 0xb7, 0xf3, 0x54, 0x7d, 0x3f, 0x81,
0xf6, 0x9c, 0x0b, 0xe9, 0xe9, 0x02, 0xa1, 0x0e, 0x54, 0x5d, 0x50, 0xd0, 0x14, 0x11, 0xf2, 0x0a,
0x4c, 0x24, 0xf0, 0x68, 0xbe, 0xa0, 0x41, 0x84, 0xed, 0x5c, 0x75, 0x71, 0xd3, 0x85, 0x86, 0x54,
0x27, 0x68, 0xca, 0xf5, 0xb5, 0xe6, 0x80, 0x56, 0x26, 0xe4, 0xa4, 0x98, 0x43, 0xc0, 0x3e, 0x0d,
0x84, 0x54, 0x89, 0x15, 0x59, 0xd5, 0x7f, 0x0e, 0x9b, 0x05, 0x2c, 0xbd, 0xf7, 0x9f, 0x41, 0x5d,
0x35, 0xad, 0xe8, 0x19, 0x83, 0xea, 0x6e, 0x7b, 0x7f, 0xeb, 0x41, 0x4d, 0x56, 0xc2, 0xd5, 0x0c,
0xe7, 0x15, 0x74, 0x15, 0x38, 0x8e, 0xae, 0x79, 0x26, 0x04, 0x56, 0xde, 0x35, 0xa6, 0xba, 0x23,
0x8e, 0x05, 0xe6, 0x8c, 0x25, 0x61, 0x7e, 0xe4, 0xef, 0xa0, 0x3b, 0x8e, 0x52, 0x24, 0x3d, 0xf0,
0x87, 0xd0, 0x0d, 0x83, 0x48, 0x2b, 0x05, 0x0d, 0xf9, 0x2a, 0x92, 0x69, 0x69, 0x3b, 0x61, 0x10,
0x29, 0xfb, 0x07, 0x08, 0x22, 0x2f, 0x53, 0x94, 0x94, 0xb7, 0x91, 0xf2, 0xb4, 0xa8, 0x68, 0xde,
0x49, 0xad, 0x69, 0xd8, 0x95, 0x93, 0x5a, 0xb3, 0x62, 0x57, 0x4f, 0x6a, 0xcd, 0xaa, 0x5d, 0x3b,
0xa9, 0x35, 0x6b, 0x76, 0xfd, 0xa4, 0xd6, 0x6c, 0xd8, 0x4d, 0xe7, 0xf7, 0x06, 0xd8, 0x17, 0x2b,
0xf9, 0xff, 0x74, 0xe1, 0xcf, 0x06, 0x98, 0xbf, 0x58, 0x71, 0xc9, 0x9e, 0x56, 0x4f, 0xbc, 0x16,
0x6b, 0xc9, 0xaa, 0xa0, 0x64, 0xc1, 0x7c, 0x2d, 0xdf, 0x0f, 0xd4, 0xaf, 0xfa, 0x88, 0xfa, 0x3d,
0xab, 0xf1, 0xb5, 0xe7, 0x35, 0xfe, 0x8f, 0x86, 0xaa, 0x54, 0xea, 0x66, 0x9a, 0xa6, 0x01, 0x98,
0x99, 0x9e, 0x7b, 0x82, 0x66, 0x0e, 0x83, 0xd0, 0x82, 0x3e, 0xa5, 0x38, 0xad, 0xf1, 0xfa, 0xe3,
0x89, 0x62, 0x91, 0x33, 0xd3, 0x69, 0xad, 0xd6, 0x26, 0x7a, 0x29, 0xdd, 0xf0, 0x7d, 0x80, 0xf9,
0x52, 0xbe, 0xf3, 0x7c, 0xb6, 0x94, 0x14, 0x93, 0x5e, 0x77, 0x5b, 0x0a, 0x39, 0x52, 0x40, 0x9e,
0xc2, 0x9a, 0x5d, 0x77, 0xfe, 0xae, 0x2b, 0xf7, 0xbf, 0xba, 0xf4, 0x29, 0x58, 0xeb, 0xa1, 0x8d,
0x1c, 0x3d, 0x8a, 0xcc, 0x38, 0x9b, 0xda, 0x8a, 0xf5, 0xe3, 0xb4, 0xcb, 0xf5, 0xfc, 0x2c, 0xbb,
0xdd, 0x55, 0x2b, 0x53, 0xb5, 0x90, 0x9a, 0xc4, 0x39, 0xab, 0xf2, 0x4a, 0xef, 0x42, 0x16, 0x49,
0x0f, 0x1f, 0x2d, 0x7a, 0x3c, 0x75, 0x31, 0x9f, 0x1a, 0x3f, 0x52, 0xb5, 0x7d, 0x3e, 0x40, 0xa7,
0x0b, 0x9d, 0x19, 0xff, 0x0d, 0x8b, 0xf2, 0x06, 0xf9, 0x19, 0x58, 0x19, 0x90, 0x86, 0xb8, 0x07,
0x1b, 0x12, 0x91, 0xb4, 0x23, 0xd7, 0x2a, 0x79, 0x2a, 0xa8, 0x44, 0xb2, 0x9b, 0x32, 0x9c, 0xbf,
0x54, 0xa0, 0x95, 0xa3, 0xea, 0x92, 0x5c, 0x51, 0xc1, 0xbc, 0x90, 0xce, 0x69, 0xc2, 0x79, 0x94,
0xf6, 0xa5, 0xa9, 0xc0, 0xb3, 0x14, 0x53, 0x02, 0x93, 0xc5, 0xb1, 0xa0, 0x62, 0x81, 0xd9, 0x31,
0xdd, 0x76, 0x8a, 0x1d, 0x53, 0xb1, 0x20, 0x9f, 0x81, 0x9d, 0x51, 0xe2, 0x84, 0x05, 0xa1, 0x1a,
0x2c, 0x7a, 0xfc, 0x75, 0x53, 0x7c, 0x92, 0xc2, 0x4a, 0x7e, 0x75, 0x63, 0x78, 0x31, 0x0d, 0x7c,
0x2f, 0x54, 0x59, 0xd4, 0xef, 0x2e, 0x4b, 0xe3, 0x13, 0x1a, 0xf8, 0x67, 0x82, 0x4a, 0xf2, 0x05,
0xbc, 0x28, 0x3c, 0xce, 0x0a, 0x74, 0xdd, 0x79, 0x24, 0xc9, 0x5f, 0x67, 0xf9, 0x96, 0x57, 0x60,
0x2a, 0x3d, 0xf7, 0xe6, 0x09, 0xa3, 0x92, 0xf9, 0x69, 0xef, 0xb5, 0x15, 0x76, 0xa8, 0x21, 0xd2,
0x83, 0x06, 0xbb, 0x8d, 0x83, 0x84, 0xf9, 0xa8, 0xe7, 0x4d, 0x37, 0xfb, 0x54, 0x9b, 0x85, 0xe4,
0x09, 0xbd, 0x61, 0x5e, 0x44, 0x43, 0x86, 0x52, 0xdb, 0x72, 0xdb, 0x29, 0x76, 0x4e, 0x43, 0xb6,
0xf7, 0x1a, 0x9a, 0xd9, 0x80, 0x22, 0x26, 0x34, 0x4f, 0x2f, 0x2e, 0x26, 0xde, 0xc5, 0xe5, 0xcc,
0xfe, 0x88, 0xb4, 0xa1, 0x81, 0x5f, 0xe3, 0x73, 0xdb, 0xd8, 0x13, 0xd0, 0xca, 0xe7, 0x13, 0xe9,
0x40, 0x6b, 0x7c, 0x3e, 0x9e, 0x8d, 0x0f, 0x66, 0xa3, 0x23, 0xfb, 0x23, 0xf2, 0x02, 0x36, 0x27,
0xee, 0x68, 0x7c, 0x76, 0xf0, 0xcd, 0xc8, 0x73, 0x47, 0xdf, 0x8e, 0x0e, 0x4e, 0x47, 0x47, 0xb6,
0x41, 0x08, 0x58, 0xc7, 0xb3, 0xd3, 0x43, 0x6f, 0x72, 0xf9, 0xf6, 0x74, 0x3c, 0x3d, 0x1e, 0x1d,
0xd9, 0x15, 0x65, 0x73, 0x7a, 0x79, 0x78, 0x38, 0x9a, 0x4e, 0xed, 0x2a, 0x01, 0xd8, 0xf8, 0xfa,
0x60, 0xac, 0xc8, 0x35, 0xb2, 0x05, 0xdd, 0xf1, 0xf9, 0xb7, 0x17, 0xe3, 0xc3, 0x91, 0x37, 0x1d,
0xcd, 0x66, 0x0a, 0xac, 0xef, 0xff, 0x67, 0x43, 0x4f, 0xe8, 0x43, 0x7c, 0x7c, 0x13, 0x17, 0x1a,
0xe9, 0x73, 0x9a, 0x6c, 0xaf, 0xef, 0x43, 0xe9, 0x81, 0xdd, 0x7f, 0x51, 0x92, 0xee, 0xec, 0x3e,
0x39, 0xdb, 0x7f, 0xf8, 0xc7, 0xbf, 0xfe, 0x54, 0xd9, 0x74, 0xcc, 0xe1, 0xbb, 0x2f, 0x86, 0x8a,
0x31, 0xe4, 0x2b, 0xf9, 0x95, 0xb1, 0x47, 0x2e, 0x60, 0x43, 0xbf, 0xea, 0xc8, 0xcb, 0x92, 0xc9,
0xfc, 0x99, 0xf7, 0x94, 0xc5, 0x97, 0x68, 0xd1, 0x76, 0xda, 0xb9, 0xc5, 0x20, 0x52, 0x06, 0x7f,
0x0a, 0x8d, 0xf4, 0x9d, 0x51, 0x70, 0xb2, 0xfc, 0xf2, 0xe8, 0x3f, 0x36, 0x5f, 0x7e, 0x62, 0x90,
0x5f, 0x41, 0x2b, 0x1f, 0x4d, 0x64, 0x67, 0xed, 0xce, 0xbd, 0x11, 0xd6, 0xef, 0x3f, 0xb6, 0x54,
0x76, 0x8b, 0x58, 0xb9, 0x5b, 0x38, 0xb6, 0xc8, 0xa5, 0x2e, 0xb3, 0x1a, 0x5b, 0xa4, 0x57, 0x3a,
0xbe, 0x30, 0xc9, 0x1e, 0x75, 0xcc, 0xe9, 0xa3, 0xc9, 0x8f, 0x09, 0x29, 0x99, 0x1c, 0x7e, 0x08,
0xfc, 0xdf, 0x92, 0x5f, 0x83, 0x99, 0x16, 0x00, 0x87, 0x0b, 0x59, 0x27, 0xab, 0x38, 0x01, 0xfb,
0xeb, 0x60, 0xee, 0x8f, 0xa1, 0x47, 0xac, 0xf3, 0x95, 0x1c, 0x4a, 0xb4, 0x76, 0x95, 0x5b, 0x47,
0x01, 0x2c, 0x58, 0x2f, 0x8e, 0x92, 0xb2, 0xf5, 0x92, 0x54, 0x3a, 0x03, 0xb4, 0xde, 0x27, 0xbd,
0x92, 0xf5, 0xef, 0x14, 0x67, 0xf8, 0x81, 0x86, 0x52, 0x45, 0x60, 0x7d, 0xc3, 0xa4, 0x2e, 0xf9,
0xb3, 0x31, 0xac, 0xb3, 0x76, 0x6f, 0x98, 0x3b, 0x3b, 0x78, 0xc8, 0x16, 0xd9, 0x2c, 0x5c, 0x85,
0x3c, 0x82, 0xb5, 0xf5, 0x67, 0x63, 0x28, 0x5a, 0x2f, 0x87, 0xf0, 0x09, 0x5a, 0xdf, 0x21, 0xdb,
0x45, 0xeb, 0xc5, 0x08, 0x7e, 0x09, 0x1d, 0x75, 0x46, 0xa6, 0x80, 0xa2, 0x70, 0x93, 0x4b, 0x32,
0xdb, 0xdf, 0x7e, 0x80, 0x97, 0xbb, 0x83, 0x74, 0xf1, 0x08, 0x41, 0xe5, 0x50, 0x4b, 0xeb, 0xd5,
0x06, 0xfe, 0x91, 0xfd, 0xf2, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x3e, 0x0d, 0x16, 0xff,
0x0e, 0x00, 0x00,
0x76, 0x20, 0x1b, 0x56, 0x63, 0x36, 0x7b, 0xc5, 0x0a, 0x21, 0x65, 0x1c, 0xef, 0xc6, 0x51, 0x7e,
0x4c, 0xdb, 0x59, 0x09, 0x84, 0xd4, 0xaa, 0xd8, 0x95, 0xb8, 0x85, 0xbb, 0xab, 0xb7, 0xab, 0x3c,
0x93, 0x68, 0x85, 0x90, 0x78, 0x01, 0x2e, 0x78, 0x03, 0x5e, 0x83, 0x37, 0x40, 0xdc, 0x00, 0x0f,
0xc0, 0x0d, 0x37, 0xbc, 0x04, 0x42, 0x75, 0xaa, 0xbb, 0xdd, 0x9d, 0x38, 0x41, 0x5c, 0xec, 0x9d,
0xfb, 0xab, 0xaf, 0x4e, 0x9d, 0x9f, 0x3a, 0xe7, 0x2b, 0x83, 0x39, 0x5b, 0xfa, 0x2c, 0x94, 0x6f,
0xa2, 0x98, 0x4b, 0x4e, 0x6a, 0x4b, 0xce, 0xa3, 0x38, 0x9a, 0x75, 0xbf, 0x77, 0xcb, 0xf9, 0xed,
0x92, 0xf5, 0x69, 0xe4, 0xf7, 0x69, 0x18, 0x72, 0x49, 0xa5, 0xcf, 0x43, 0xa1, 0x69, 0xce, 0x5f,
0xca, 0x60, 0x9d, 0x71, 0x1e, 0x5d, 0xae, 0xa4, 0xcb, 0xbe, 0x59, 0x31, 0x21, 0x89, 0x0d, 0x65,
0x1a, 0xc8, 0x8e, 0xd1, 0x33, 0xf6, 0xcb, 0xae, 0xfa, 0x49, 0x08, 0x54, 0xe6, 0x4c, 0xc8, 0x4e,
0xa9, 0x67, 0xec, 0x37, 0x5c, 0xfc, 0x4d, 0xfa, 0xf0, 0x61, 0x40, 0xef, 0x3c, 0xf1, 0x9e, 0x46,
0x5e, 0xcc, 0x57, 0xd2, 0x0f, 0x6f, 0xbd, 0x1b, 0xc6, 0x3a, 0x65, 0xdc, 0xb6, 0x1d, 0xd0, 0xbb,
0xc9, 0x7b, 0x1a, 0xb9, 0x7a, 0xe5, 0x4b, 0xc6, 0xc8, 0xe7, 0xf0, 0x52, 0x6d, 0x88, 0x62, 0x16,
0xd1, 0xfb, 0xc2, 0x96, 0x0a, 0x6e, 0xd9, 0x09, 0xe8, 0xdd, 0x18, 0x17, 0x73, 0x9b, 0x7a, 0x60,
0x66, 0xa7, 0x28, 0x6a, 0x15, 0xa9, 0x90, 0x58, 0x57, 0x8c, 0x8f, 0xc1, 0xca, 0x99, 0x55, 0x8e,
0x6f, 0x21, 0xc7, 0xcc, 0xcc, 0x1d, 0x05, 0x92, 0x38, 0xd0, 0x52, 0xac, 0xc0, 0x0f, 0x59, 0x8c,
0x86, 0x6a, 0x48, 0x6a, 0x06, 0xf4, 0xee, 0x5c, 0x61, 0xca, 0xd2, 0xa7, 0x60, 0xab, 0x9c, 0x79,
0x7c, 0x25, 0xbd, 0xd9, 0x82, 0x86, 0x21, 0x5b, 0x76, 0xea, 0x3d, 0x63, 0xbf, 0xf2, 0xb6, 0xd4,
0x31, 0x5c, 0x6b, 0xa9, 0xb3, 0x34, 0xd0, 0x2b, 0xe4, 0x00, 0xb6, 0xf9, 0x4a, 0xde, 0x72, 0x15,
0x84, 0x62, 0x7b, 0x82, 0xc9, 0x4e, 0xb3, 0x57, 0xde, 0xaf, 0xb8, 0xed, 0x74, 0x41, 0x71, 0x27,
0x4c, 0x2a, 0xae, 0x78, 0xcf, 0x58, 0xe4, 0xcd, 0x78, 0x78, 0xe3, 0x49, 0x1a, 0xdf, 0x32, 0xd9,
0x69, 0xf4, 0x8c, 0xfd, 0xaa, 0xdb, 0xc6, 0x85, 0x01, 0x0f, 0x6f, 0xa6, 0x08, 0x93, 0x2f, 0x60,
0x0f, 0xa3, 0x8d, 0x56, 0xd7, 0x4b, 0x7f, 0x86, 0xb5, 0xf2, 0xe6, 0x8c, 0xce, 0x97, 0x7e, 0xc8,
0x3a, 0xa0, 0xdc, 0x71, 0x77, 0x15, 0x61, 0xbc, 0x5e, 0x3f, 0x4e, 0x96, 0x9d, 0xbf, 0x19, 0xd0,
0x52, 0xc5, 0x1c, 0x85, 0x4f, 0xd7, 0xf2, 0x61, 0x46, 0x4b, 0x8f, 0x32, 0xfa, 0x28, 0x57, 0xe5,
0xc7, 0xb9, 0xda, 0x83, 0xfa, 0x92, 0x0a, 0xe9, 0x2d, 0x78, 0x84, 0xe5, 0x33, 0xdd, 0x9a, 0xfa,
0x3e, 0xe1, 0x11, 0xf9, 0x01, 0xb4, 0xd8, 0x9d, 0x64, 0x71, 0x48, 0x97, 0xde, 0x42, 0x2e, 0x67,
0x58, 0xb3, 0xba, 0x6b, 0xa6, 0xe0, 0x89, 0x5c, 0xce, 0xc8, 0x3e, 0xd8, 0x6a, 0xad, 0x90, 0x90,
0x2d, 0x4c, 0x88, 0xa5, 0xf0, 0x75, 0x3e, 0x9c, 0x7f, 0x1b, 0x60, 0xe2, 0x4d, 0x62, 0x22, 0xe2,
0xa1, 0x60, 0x84, 0x40, 0xc9, 0x9f, 0x63, 0x44, 0x0d, 0x2c, 0x4c, 0xc9, 0x9f, 0x2b, 0x77, 0xfc,
0xb9, 0x77, 0x7d, 0x2f, 0x99, 0x40, 0x6f, 0x4d, 0xb7, 0xe6, 0xcf, 0xdf, 0xaa, 0x4f, 0xf2, 0x1a,
0x4c, 0x3c, 0x89, 0xce, 0xe7, 0x31, 0x13, 0x42, 0xdf, 0x61, 0xdc, 0xd8, 0x54, 0xf8, 0x91, 0x86,
0xc9, 0x1b, 0xd8, 0xc9, 0xd3, 0xbc, 0x30, 0x3a, 0x7c, 0x2f, 0x16, 0x18, 0x5b, 0xc3, 0xdd, 0xce,
0x31, 0x2f, 0x70, 0x81, 0x7c, 0x0a, 0xa4, 0xc0, 0xd7, 0xf4, 0x2a, 0xd2, 0xed, 0x1c, 0x7d, 0x8c,
0xec, 0xd7, 0x60, 0x09, 0x16, 0xbf, 0x63, 0xb1, 0x17, 0x30, 0x21, 0xe8, 0x2d, 0xc3, 0x60, 0x1b,
0x6e, 0x4b, 0xa3, 0xe7, 0x1a, 0x74, 0x6c, 0xb0, 0xce, 0x79, 0xe8, 0x4b, 0x1e, 0x27, 0xf5, 0x73,
0xfe, 0x59, 0x06, 0x50, 0xd1, 0x4f, 0x24, 0x95, 0x2b, 0xb1, 0xb1, 0x35, 0x55, 0x36, 0x4a, 0x4f,
0x66, 0xa3, 0xf9, 0x30, 0x1b, 0x15, 0x79, 0x1f, 0xe9, 0x92, 0x5a, 0x87, 0xdb, 0x6f, 0x92, 0x21,
0xf1, 0x46, 0x9d, 0x31, 0xbd, 0x8f, 0x98, 0x8b, 0xcb, 0x64, 0x1f, 0xaa, 0x42, 0x52, 0xa9, 0x5b,
0xd3, 0x3a, 0x24, 0x05, 0x9e, 0xf2, 0x85, 0xb9, 0x9a, 0x40, 0x7e, 0x04, 0x6d, 0x3f, 0xf4, 0xa5,
0xaf, 0x2f, 0xaa, 0xf4, 0x83, 0xb4, 0x47, 0xad, 0x35, 0x3c, 0xf5, 0x03, 0x65, 0xd2, 0xc6, 0x1b,
0xb3, 0x8a, 0xe6, 0x54, 0x32, 0xcd, 0xd4, 0x9d, 0x6a, 0x29, 0xfc, 0x0a, 0x61, 0x64, 0x3e, 0xac,
0x58, 0x6d, 0x73, 0xc5, 0x36, 0x57, 0xc0, 0x7c, 0xa2, 0x02, 0x4f, 0xd4, 0xb7, 0xf5, 0x54, 0x7d,
0x3f, 0x82, 0xe6, 0x8c, 0x0b, 0xe9, 0xe9, 0x02, 0xe1, 0x1c, 0x28, 0xbb, 0xa0, 0xa0, 0x09, 0x22,
0xe4, 0x15, 0x98, 0x48, 0xe0, 0xe1, 0x6c, 0x41, 0xfd, 0x10, 0xdb, 0xb9, 0xec, 0xe2, 0xa6, 0x4b,
0x0d, 0xa9, 0x4e, 0xd0, 0x94, 0x9b, 0x1b, 0xcd, 0x01, 0x3d, 0x99, 0x90, 0x93, 0x60, 0x0e, 0x01,
0xfb, 0xcc, 0x17, 0x52, 0x25, 0x56, 0xa4, 0x55, 0xff, 0x39, 0x6c, 0xe7, 0xb0, 0xe4, 0xde, 0x7f,
0x02, 0x55, 0xd5, 0xb4, 0xa2, 0x63, 0xf4, 0xca, 0xfb, 0xcd, 0xc3, 0x9d, 0x47, 0x35, 0x59, 0x09,
0x57, 0x33, 0x9c, 0x57, 0xd0, 0x56, 0xe0, 0x28, 0xbc, 0xe1, 0xe9, 0x20, 0xb0, 0xb2, 0xae, 0x31,
0xd5, 0x1d, 0x71, 0x2c, 0x30, 0xa7, 0x2c, 0x0e, 0xb2, 0x23, 0x7f, 0x07, 0xed, 0x51, 0x98, 0x20,
0xc9, 0x81, 0x3f, 0x84, 0x76, 0xe0, 0x87, 0x7a, 0x52, 0xd0, 0x80, 0xaf, 0x42, 0x99, 0x94, 0xb6,
0x15, 0xf8, 0xa1, 0xb2, 0x7f, 0x84, 0x20, 0xf2, 0xd2, 0x89, 0x92, 0xf0, 0xb6, 0x12, 0x9e, 0x1e,
0x2a, 0x9a, 0x77, 0x5a, 0xa9, 0x1b, 0x76, 0xe9, 0xb4, 0x52, 0x2f, 0xd9, 0xe5, 0xd3, 0x4a, 0xbd,
0x6c, 0x57, 0x4e, 0x2b, 0xf5, 0x8a, 0x5d, 0x3d, 0xad, 0xd4, 0x6b, 0x76, 0xdd, 0xf9, 0xab, 0x01,
0xf6, 0xe5, 0x4a, 0x7e, 0xa7, 0x2e, 0xa0, 0x58, 0xf8, 0xa1, 0x37, 0x5b, 0xca, 0x77, 0xde, 0x9c,
0x2d, 0x25, 0xc5, 0xc2, 0x56, 0x5d, 0x33, 0xf0, 0xc3, 0xc1, 0x52, 0xbe, 0x3b, 0x56, 0x58, 0x2a,
0x29, 0x39, 0x56, 0x23, 0x61, 0xd1, 0xbb, 0x8c, 0xf5, 0x3f, 0xc2, 0xf9, 0x93, 0x01, 0xe6, 0x2f,
0x56, 0x5c, 0xb2, 0xa7, 0x27, 0x31, 0x5e, 0xb1, 0xf5, 0xf8, 0x2b, 0xe1, 0x19, 0x30, 0x5b, 0x4b,
0xc1, 0xa3, 0x49, 0x5a, 0xde, 0x30, 0x49, 0x9f, 0xd5, 0x8b, 0xca, 0xf3, 0x7a, 0xf1, 0x07, 0x43,
0x55, 0x3d, 0x71, 0x33, 0x49, 0x79, 0x0f, 0xcc, 0x54, 0x1b, 0x3c, 0x41, 0x53, 0x87, 0x41, 0x68,
0x71, 0x98, 0x50, 0x54, 0x7e, 0x6c, 0x25, 0x3c, 0x51, 0x2c, 0x32, 0x66, 0xa2, 0xfc, 0x6a, 0x6d,
0xac, 0x97, 0x92, 0x0d, 0xdf, 0x07, 0xc8, 0xe5, 0xb2, 0x8a, 0x71, 0x36, 0x66, 0xb9, 0x44, 0xea,
0x14, 0x56, 0xec, 0xaa, 0xf3, 0x77, 0x7d, 0x0b, 0xfe, 0x5f, 0x97, 0x3e, 0x06, 0x6b, 0xfd, 0x00,
0x40, 0x8e, 0x96, 0x35, 0x33, 0x4a, 0x5f, 0x00, 0x8a, 0xf5, 0xe3, 0x64, 0x62, 0x68, 0x2d, 0x2e,
0xba, 0xdd, 0x56, 0x2b, 0x13, 0xb5, 0x90, 0x98, 0x44, 0xcd, 0x56, 0x79, 0xa5, 0xf7, 0x01, 0x0b,
0xa5, 0x87, 0x0f, 0x20, 0x2d, 0x75, 0x6d, 0xcc, 0xa7, 0xc6, 0x8f, 0x55, 0x6d, 0x9f, 0x0f, 0xd0,
0x69, 0x43, 0x6b, 0xca, 0x7f, 0xc3, 0xc2, 0xac, 0xd9, 0x7e, 0x06, 0x56, 0x0a, 0x24, 0x21, 0x1e,
0xc0, 0x96, 0x44, 0x24, 0xe9, 0xee, 0xf5, 0xc4, 0x3d, 0x13, 0x54, 0x22, 0xd9, 0x4d, 0x18, 0xce,
0x9f, 0x4b, 0xd0, 0xc8, 0x50, 0x75, 0x49, 0xae, 0xa9, 0x60, 0x5e, 0x40, 0x67, 0x34, 0xe6, 0x3c,
0x4c, 0x7a, 0xdc, 0x54, 0xe0, 0x79, 0x82, 0xa9, 0x61, 0x95, 0xc6, 0xb1, 0xa0, 0x62, 0x81, 0xd9,
0x31, 0xdd, 0x66, 0x82, 0x9d, 0x50, 0xb1, 0x20, 0x9f, 0x80, 0x9d, 0x52, 0xa2, 0x98, 0xf9, 0x81,
0x12, 0x29, 0x2d, 0xa5, 0xed, 0x04, 0x1f, 0x27, 0xb0, 0x1a, 0xe5, 0xba, 0xc9, 0xbc, 0x88, 0xfa,
0x73, 0x2f, 0x50, 0x59, 0xd4, 0x6f, 0x38, 0x4b, 0xe3, 0x63, 0xea, 0xcf, 0xcf, 0x05, 0x95, 0xe4,
0x33, 0x78, 0x91, 0x7b, 0xe8, 0xe5, 0xe8, 0xba, 0x8b, 0x49, 0x9c, 0xbd, 0xf4, 0xb2, 0x2d, 0xaf,
0xc0, 0x54, 0xda, 0xe0, 0xcd, 0x62, 0x46, 0x25, 0x9b, 0x27, 0x7d, 0xdc, 0x54, 0xd8, 0x40, 0x43,
0xa4, 0x03, 0x35, 0x76, 0x17, 0xf9, 0x31, 0x9b, 0xa3, 0x36, 0xd4, 0xdd, 0xf4, 0x53, 0x6d, 0x16,
0x92, 0xc7, 0xf4, 0x96, 0x79, 0x21, 0x0d, 0x18, 0x76, 0x77, 0xc3, 0x6d, 0x26, 0xd8, 0x05, 0x0d,
0xd8, 0xc1, 0x6b, 0xa8, 0xa7, 0x62, 0x47, 0x4c, 0xa8, 0x9f, 0x5d, 0x5e, 0x8e, 0xbd, 0xcb, 0xab,
0xa9, 0xfd, 0x01, 0x69, 0x42, 0x0d, 0xbf, 0x46, 0x17, 0xb6, 0x71, 0x20, 0xa0, 0x91, 0x69, 0x1d,
0x69, 0x41, 0x63, 0x74, 0x31, 0x9a, 0x8e, 0x8e, 0xa6, 0xc3, 0x63, 0xfb, 0x03, 0xf2, 0x02, 0xb6,
0xc7, 0xee, 0x70, 0x74, 0x7e, 0xf4, 0xd5, 0xd0, 0x73, 0x87, 0x5f, 0x0f, 0x8f, 0xce, 0x86, 0xc7,
0xb6, 0x41, 0x08, 0x58, 0x27, 0xd3, 0xb3, 0x81, 0x37, 0xbe, 0x7a, 0x7b, 0x36, 0x9a, 0x9c, 0x0c,
0x8f, 0xed, 0x92, 0xb2, 0x39, 0xb9, 0x1a, 0x0c, 0x86, 0x93, 0x89, 0x5d, 0x26, 0x00, 0x5b, 0x5f,
0x1e, 0x8d, 0x14, 0xb9, 0x42, 0x76, 0xa0, 0x3d, 0xba, 0xf8, 0xfa, 0x72, 0x34, 0x18, 0x7a, 0x93,
0xe1, 0x74, 0xaa, 0xc0, 0xea, 0xe1, 0x7f, 0xb6, 0xb4, 0xda, 0x0f, 0xf0, 0x21, 0x4f, 0x5c, 0xa8,
0x25, 0x4f, 0x73, 0xb2, 0xbb, 0xbe, 0x0f, 0x85, 0xc7, 0x7a, 0xf7, 0x45, 0x41, 0x06, 0xd2, 0xfb,
0xe4, 0xec, 0xfe, 0xfe, 0x1f, 0xff, 0xfa, 0x63, 0x69, 0xdb, 0x31, 0xfb, 0xef, 0x3e, 0xeb, 0x2b,
0x46, 0x9f, 0xaf, 0xe4, 0x17, 0xc6, 0x01, 0xb9, 0x84, 0x2d, 0xfd, 0x42, 0x24, 0x2f, 0x0b, 0x26,
0xb3, 0x27, 0xe3, 0x53, 0x16, 0x5f, 0xa2, 0x45, 0xdb, 0x69, 0x66, 0x16, 0xfd, 0x50, 0x19, 0xfc,
0x29, 0xd4, 0x92, 0x37, 0x4b, 0xce, 0xc9, 0xe2, 0x2b, 0xa6, 0xbb, 0x49, 0xab, 0x7e, 0x62, 0x90,
0x5f, 0x41, 0x23, 0x93, 0x39, 0xb2, 0xb7, 0x76, 0xe7, 0x81, 0x1c, 0x76, 0xbb, 0x9b, 0x96, 0x8a,
0x6e, 0x11, 0x2b, 0x73, 0x0b, 0x25, 0x90, 0x5c, 0xe9, 0x32, 0x2b, 0x09, 0x24, 0x9d, 0xc2, 0xf1,
0x39, 0x55, 0xdc, 0xe8, 0x98, 0xd3, 0x45, 0x93, 0x1f, 0x12, 0x52, 0x30, 0xd9, 0xff, 0xd6, 0x9f,
0xff, 0x96, 0xfc, 0x1a, 0xcc, 0xa4, 0x00, 0x28, 0x54, 0x64, 0x9d, 0xac, 0xbc, 0x9a, 0x76, 0xd7,
0xc1, 0x3c, 0x94, 0xb4, 0x0d, 0xd6, 0xf9, 0x4a, 0xf6, 0x25, 0x5a, 0xbb, 0xce, 0xac, 0xe3, 0x00,
0xcc, 0x59, 0xcf, 0x4b, 0x49, 0xd1, 0x7a, 0x61, 0x54, 0x3a, 0x3d, 0xb4, 0xde, 0x25, 0x9d, 0x82,
0xf5, 0x6f, 0x14, 0xa7, 0xff, 0x2d, 0x0d, 0xa4, 0x8a, 0xc0, 0xfa, 0x8a, 0x49, 0x5d, 0xf2, 0x67,
0x63, 0x58, 0x67, 0xed, 0xc1, 0xc3, 0xc0, 0xd9, 0xc3, 0x43, 0x76, 0xc8, 0x76, 0xee, 0x2a, 0x64,
0x11, 0xac, 0xad, 0x3f, 0x1b, 0x43, 0xde, 0x7a, 0x31, 0x84, 0x8f, 0xd0, 0xfa, 0x1e, 0xd9, 0xcd,
0x5b, 0xcf, 0x47, 0xf0, 0x4b, 0x68, 0xa9, 0x33, 0xd2, 0x09, 0x28, 0x72, 0x37, 0xb9, 0x30, 0x66,
0xbb, 0xbb, 0x8f, 0xf0, 0x62, 0x77, 0x90, 0x36, 0x1e, 0x21, 0xa8, 0xec, 0xeb, 0xd1, 0x7a, 0xbd,
0x85, 0x7f, 0x8a, 0x3f, 0xff, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x67, 0x1f, 0xc0, 0xa6, 0x4b,
0x0f, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

@ -447,6 +447,12 @@ message OutTermsResponse {
Maximum swap amount (sat)
*/
int64 max_swap_amount = 6;
// The minimally accepted cltv delta of the on-chain htlc.
int32 min_cltv_delta = 8;
// The maximally accepted cltv delta of the on-chain htlc.
int32 max_cltv_delta = 9;
}
message QuoteRequest {

@ -548,6 +548,16 @@
"type": "string",
"format": "int64",
"title": "*\nMaximum swap amount (sat)"
},
"min_cltv_delta": {
"type": "integer",
"format": "int32",
"description": "The minimally accepted cltv delta of the on-chain htlc."
},
"max_cltv_delta": {
"type": "integer",
"format": "int32",
"description": "The maximally accepted cltv delta of the on-chain htlc."
}
}
},

@ -47,6 +47,8 @@ const (
//incoming liquidity more quickly than if the server waited for the on chain
//claim tx).
ProtocolVersion_PREIMAGE_PUSH_LOOP_OUT ProtocolVersion = 3
// The client will propose a cltv expiry height for loop out.
ProtocolVersion_USER_EXPIRY_LOOP_OUT ProtocolVersion = 4
)
var ProtocolVersion_name = map[int32]string{
@ -54,6 +56,7 @@ var ProtocolVersion_name = map[int32]string{
1: "MULTI_LOOP_OUT",
2: "NATIVE_SEGWIT_LOOP_IN",
3: "PREIMAGE_PUSH_LOOP_OUT",
4: "USER_EXPIRY_LOOP_OUT",
}
var ProtocolVersion_value = map[string]int32{
@ -61,6 +64,7 @@ var ProtocolVersion_value = map[string]int32{
"MULTI_LOOP_OUT": 1,
"NATIVE_SEGWIT_LOOP_IN": 2,
"PREIMAGE_PUSH_LOOP_OUT": 3,
"USER_EXPIRY_LOOP_OUT": 4,
}
func (x ProtocolVersion) String() string {
@ -157,10 +161,14 @@ type ServerLoopOutRequest struct {
/// The unix time in seconds we want the on-chain swap to be published by.
SwapPublicationDeadline int64 `protobuf:"varint,4,opt,name=swap_publication_deadline,json=swapPublicationDeadline,proto3" json:"swap_publication_deadline,omitempty"`
/// The protocol version that the client adheres to.
ProtocolVersion ProtocolVersion `protobuf:"varint,5,opt,name=protocol_version,json=protocolVersion,proto3,enum=looprpc.ProtocolVersion" json:"protocol_version,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
ProtocolVersion ProtocolVersion `protobuf:"varint,5,opt,name=protocol_version,json=protocolVersion,proto3,enum=looprpc.ProtocolVersion" json:"protocol_version,omitempty"`
// The requested absolute block height of the on-chain htlc. This is
// subjected to min and max constraints as reported in the LoopOutTerms
// response.
Expiry int32 `protobuf:"varint,6,opt,name=expiry,proto3" json:"expiry,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ServerLoopOutRequest) Reset() { *m = ServerLoopOutRequest{} }
@ -223,11 +231,20 @@ func (m *ServerLoopOutRequest) GetProtocolVersion() ProtocolVersion {
return ProtocolVersion_LEGACY
}
func (m *ServerLoopOutRequest) GetExpiry() int32 {
if m != nil {
return m.Expiry
}
return 0
}
type ServerLoopOutResponse struct {
SwapInvoice string `protobuf:"bytes,1,opt,name=swap_invoice,json=swapInvoice,proto3" json:"swap_invoice,omitempty"`
PrepayInvoice string `protobuf:"bytes,2,opt,name=prepay_invoice,json=prepayInvoice,proto3" json:"prepay_invoice,omitempty"`
SenderKey []byte `protobuf:"bytes,3,opt,name=sender_key,json=senderKey,proto3" json:"sender_key,omitempty"`
Expiry int32 `protobuf:"varint,4,opt,name=expiry,proto3" json:"expiry,omitempty"`
// The height at which the on-chain htlc will expire. Deprecated because the
// field is already specified in the request.
Expiry int32 `protobuf:"varint,4,opt,name=expiry,proto3" json:"expiry,omitempty"` // Deprecated: Do not use.
// A human-readable message from the loop server.
ServerMessage string `protobuf:"bytes,5,opt,name=server_message,json=serverMessage,proto3" json:"server_message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -281,6 +298,7 @@ func (m *ServerLoopOutResponse) GetSenderKey() []byte {
return nil
}
// Deprecated: Do not use.
func (m *ServerLoopOutResponse) GetExpiry() int32 {
if m != nil {
return m.Expiry
@ -301,10 +319,14 @@ type ServerLoopOutQuoteRequest struct {
/// The unix time in seconds we want the on-chain swap to be published by.
SwapPublicationDeadline int64 `protobuf:"varint,2,opt,name=swap_publication_deadline,json=swapPublicationDeadline,proto3" json:"swap_publication_deadline,omitempty"`
/// The protocol version that the client adheres to.
ProtocolVersion ProtocolVersion `protobuf:"varint,3,opt,name=protocol_version,json=protocolVersion,proto3,enum=looprpc.ProtocolVersion" json:"protocol_version,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
ProtocolVersion ProtocolVersion `protobuf:"varint,3,opt,name=protocol_version,json=protocolVersion,proto3,enum=looprpc.ProtocolVersion" json:"protocol_version,omitempty"`
// The requested absolute block height of the on-chain htlc. This is
// subjected to min and max constraints as reported in the LoopOutTerms
// response.
Expiry int32 `protobuf:"varint,4,opt,name=expiry,proto3" json:"expiry,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ServerLoopOutQuoteRequest) Reset() { *m = ServerLoopOutQuoteRequest{} }
@ -353,16 +375,25 @@ func (m *ServerLoopOutQuoteRequest) GetProtocolVersion() ProtocolVersion {
return ProtocolVersion_LEGACY
}
func (m *ServerLoopOutQuoteRequest) GetExpiry() int32 {
if m != nil {
return m.Expiry
}
return 0
}
type ServerLoopOutQuote struct {
SwapPaymentDest string `protobuf:"bytes,1,opt,name=swap_payment_dest,json=swapPaymentDest,proto3" json:"swap_payment_dest,omitempty"`
/// The total estimated swap fee given the quote amt.
SwapFee int64 `protobuf:"varint,2,opt,name=swap_fee,json=swapFee,proto3" json:"swap_fee,omitempty"`
/// Deprecated, total swap fee given quote amt is calculated in swap_fee.
SwapFeeRate int64 `protobuf:"varint,3,opt,name=swap_fee_rate,json=swapFeeRate,proto3" json:"swap_fee_rate,omitempty"` // Deprecated: Do not use.
PrepayAmt uint64 `protobuf:"varint,4,opt,name=prepay_amt,json=prepayAmt,proto3" json:"prepay_amt,omitempty"`
MinSwapAmount uint64 `protobuf:"varint,5,opt,name=min_swap_amount,json=minSwapAmount,proto3" json:"min_swap_amount,omitempty"` // Deprecated: Do not use.
MaxSwapAmount uint64 `protobuf:"varint,6,opt,name=max_swap_amount,json=maxSwapAmount,proto3" json:"max_swap_amount,omitempty"` // Deprecated: Do not use.
CltvDelta int32 `protobuf:"varint,7,opt,name=cltv_delta,json=cltvDelta,proto3" json:"cltv_delta,omitempty"`
SwapFeeRate int64 `protobuf:"varint,3,opt,name=swap_fee_rate,json=swapFeeRate,proto3" json:"swap_fee_rate,omitempty"` // Deprecated: Do not use.
PrepayAmt uint64 `protobuf:"varint,4,opt,name=prepay_amt,json=prepayAmt,proto3" json:"prepay_amt,omitempty"`
MinSwapAmount uint64 `protobuf:"varint,5,opt,name=min_swap_amount,json=minSwapAmount,proto3" json:"min_swap_amount,omitempty"` // Deprecated: Do not use.
MaxSwapAmount uint64 `protobuf:"varint,6,opt,name=max_swap_amount,json=maxSwapAmount,proto3" json:"max_swap_amount,omitempty"` // Deprecated: Do not use.
// The server-proposed cltv delta of the on-chain htlc. Deprecated because
// the field is already specified in the request.
CltvDelta int32 `protobuf:"varint,7,opt,name=cltv_delta,json=cltvDelta,proto3" json:"cltv_delta,omitempty"` // Deprecated: Do not use.
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -438,6 +469,7 @@ func (m *ServerLoopOutQuote) GetMaxSwapAmount() uint64 {
return 0
}
// Deprecated: Do not use.
func (m *ServerLoopOutQuote) GetCltvDelta() int32 {
if m != nil {
return m.CltvDelta
@ -486,8 +518,12 @@ func (m *ServerLoopOutTermsRequest) GetProtocolVersion() ProtocolVersion {
}
type ServerLoopOutTerms struct {
MinSwapAmount uint64 `protobuf:"varint,1,opt,name=min_swap_amount,json=minSwapAmount,proto3" json:"min_swap_amount,omitempty"`
MaxSwapAmount uint64 `protobuf:"varint,2,opt,name=max_swap_amount,json=maxSwapAmount,proto3" json:"max_swap_amount,omitempty"`
MinSwapAmount uint64 `protobuf:"varint,1,opt,name=min_swap_amount,json=minSwapAmount,proto3" json:"min_swap_amount,omitempty"`
MaxSwapAmount uint64 `protobuf:"varint,2,opt,name=max_swap_amount,json=maxSwapAmount,proto3" json:"max_swap_amount,omitempty"`
// The minimally accepted cltv delta of the on-chain htlc.
MinCltvDelta int32 `protobuf:"varint,3,opt,name=min_cltv_delta,json=minCltvDelta,proto3" json:"min_cltv_delta,omitempty"`
// The maximally accepted cltv delta of the on-chain htlc.
MaxCltvDelta int32 `protobuf:"varint,4,opt,name=max_cltv_delta,json=maxCltvDelta,proto3" json:"max_cltv_delta,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -532,6 +568,20 @@ func (m *ServerLoopOutTerms) GetMaxSwapAmount() uint64 {
return 0
}
func (m *ServerLoopOutTerms) GetMinCltvDelta() int32 {
if m != nil {
return m.MinCltvDelta
}
return 0
}
func (m *ServerLoopOutTerms) GetMaxCltvDelta() int32 {
if m != nil {
return m.MaxCltvDelta
}
return 0
}
type ServerLoopInRequest struct {
SenderKey []byte `protobuf:"bytes,1,opt,name=sender_key,json=senderKey,proto3" json:"sender_key,omitempty"`
SwapHash []byte `protobuf:"bytes,2,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"`
@ -1135,83 +1185,87 @@ func init() {
func init() { proto.RegisterFile("server.proto", fileDescriptor_ad098daeda4239f7) }
var fileDescriptor_ad098daeda4239f7 = []byte{
// 1203 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcd, 0x72, 0xe2, 0x46,
0x10, 0x8e, 0x04, 0x06, 0xd3, 0x80, 0xad, 0x9d, 0xdd, 0xf5, 0x62, 0x76, 0xed, 0x60, 0x52, 0x71,
0x1c, 0x1f, 0xbc, 0x5b, 0x9b, 0x5b, 0x6e, 0x5a, 0x10, 0x46, 0xb5, 0x20, 0x11, 0x21, 0xec, 0xe4,
0x34, 0x91, 0x61, 0x62, 0x54, 0x01, 0x49, 0x2b, 0x09, 0xff, 0x54, 0x8e, 0x79, 0x8a, 0xbc, 0x44,
0x72, 0xca, 0x39, 0x4f, 0x91, 0x57, 0x48, 0x55, 0xde, 0x22, 0xa5, 0xd1, 0x08, 0x24, 0x90, 0x7f,
0xa8, 0x72, 0x6e, 0x56, 0xf7, 0x37, 0xd3, 0xfd, 0x7d, 0x3d, 0x5f, 0x63, 0x28, 0x79, 0xc4, 0xbd,
0x22, 0xee, 0x89, 0xe3, 0xda, 0xbe, 0x8d, 0xf2, 0x13, 0xdb, 0x76, 0x5c, 0x67, 0x58, 0x7d, 0x73,
0x69, 0xdb, 0x97, 0x13, 0xf2, 0xd6, 0x70, 0xcc, 0xb7, 0x86, 0x65, 0xd9, 0xbe, 0xe1, 0x9b, 0xb6,
0xe5, 0x85, 0xb0, 0xfa, 0xbf, 0x1c, 0xbc, 0xe8, 0xd3, 0x73, 0x1d, 0xdb, 0x76, 0xd4, 0x99, 0xaf,
0x91, 0x4f, 0x33, 0xe2, 0xf9, 0xe8, 0x00, 0x4a, 0x2e, 0x19, 0x12, 0xf3, 0x8a, 0xb8, 0xf8, 0x67,
0x72, 0x5b, 0xe1, 0x6a, 0xdc, 0x51, 0x49, 0x2b, 0x46, 0xb1, 0x8f, 0xe4, 0x16, 0xbd, 0x86, 0x82,
0x77, 0x6d, 0x38, 0x78, 0x6c, 0x78, 0xe3, 0x0a, 0x4f, 0xf3, 0x9b, 0x41, 0xa0, 0x6d, 0x78, 0x63,
0x24, 0x40, 0xc6, 0x98, 0xfa, 0x95, 0x4c, 0x8d, 0x3b, 0xca, 0x6a, 0xc1, 0x9f, 0xe8, 0x5b, 0xd8,
0xa5, 0x70, 0x67, 0x76, 0x31, 0x31, 0x87, 0xb4, 0x0b, 0x3c, 0x22, 0xc6, 0x68, 0x62, 0x5a, 0xa4,
0x92, 0xad, 0x71, 0x47, 0x19, 0xed, 0x55, 0x00, 0xe8, 0x2d, 0xf2, 0x4d, 0x96, 0x46, 0x0d, 0x10,
0x68, 0xbf, 0x43, 0x7b, 0x82, 0xaf, 0x88, 0xeb, 0x99, 0xb6, 0x55, 0xd9, 0xa8, 0x71, 0x47, 0x5b,
0xef, 0x2b, 0x27, 0x8c, 0xe8, 0x49, 0x8f, 0x01, 0xce, 0xc2, 0xbc, 0xb6, 0xed, 0x24, 0x03, 0xf5,
0xbf, 0x38, 0x78, 0xb9, 0xc4, 0xd5, 0x73, 0x6c, 0xcb, 0x23, 0x01, 0x59, 0xda, 0x9a, 0x69, 0x5d,
0xd9, 0xe6, 0x90, 0x50, 0xb2, 0x05, 0xad, 0x18, 0xc4, 0xe4, 0x30, 0x84, 0xbe, 0x84, 0x2d, 0xc7,
0x25, 0x8e, 0x71, 0x3b, 0x07, 0xf1, 0x14, 0x54, 0x0e, 0xa3, 0x11, 0x6c, 0x0f, 0xc0, 0x23, 0xd6,
0x88, 0x89, 0x96, 0xa1, 0xa2, 0x14, 0xc2, 0x48, 0x20, 0xd9, 0x0e, 0xe4, 0xc8, 0x8d, 0x63, 0xba,
0xb7, 0x94, 0xf0, 0x86, 0xc6, 0xbe, 0x82, 0xdb, 0xc3, 0xe9, 0xe1, 0x29, 0xf1, 0x3c, 0xe3, 0x92,
0x50, 0x76, 0x05, 0xad, 0x1c, 0x46, 0xbb, 0x61, 0xb0, 0xfe, 0x3b, 0x07, 0xbb, 0x09, 0x06, 0xdf,
0xcd, 0x6c, 0x9f, 0x44, 0x23, 0x63, 0x92, 0x73, 0x8f, 0x94, 0x9c, 0x5f, 0x5f, 0xf2, 0xcc, 0xba,
0x92, 0xff, 0xc6, 0x03, 0x5a, 0x6d, 0x18, 0x1d, 0xc3, 0xb3, 0xb0, 0x2f, 0xe3, 0x76, 0x4a, 0x2c,
0x1f, 0x8f, 0x88, 0xe7, 0x33, 0xd1, 0xb7, 0x69, 0x3f, 0x61, 0xbc, 0x19, 0xb0, 0xda, 0x05, 0xfa,
0xa8, 0xf0, 0x4f, 0x24, 0x6a, 0x39, 0x1f, 0x7c, 0xb7, 0x08, 0x41, 0x87, 0x50, 0x8e, 0x52, 0xd8,
0x35, 0x7c, 0x42, 0xfb, 0xcb, 0x7c, 0xe0, 0x2b, 0x5c, 0x38, 0xbb, 0x16, 0x21, 0x9a, 0xe1, 0xd3,
0xa1, 0xb0, 0xd9, 0x05, 0xfa, 0x64, 0xa9, 0x3e, 0x85, 0x30, 0x22, 0x4e, 0x7d, 0x74, 0x0c, 0xdb,
0x53, 0xd3, 0xc2, 0xf4, 0x2a, 0x63, 0x6a, 0xcf, 0x2c, 0x9f, 0xaa, 0x9f, 0xa5, 0x17, 0x95, 0xa7,
0xa6, 0xd5, 0xbf, 0x36, 0x1c, 0x91, 0x26, 0x28, 0xd6, 0xb8, 0x49, 0x60, 0x73, 0x31, 0xac, 0x71,
0x13, 0xc3, 0xee, 0x01, 0x0c, 0x27, 0xfe, 0x15, 0x1e, 0x91, 0x89, 0x6f, 0x54, 0xf2, 0x74, 0xe0,
0x85, 0x20, 0xd2, 0x0c, 0x02, 0xf5, 0x1f, 0x97, 0x66, 0xa9, 0x13, 0x77, 0xea, 0x45, 0xb3, 0x4c,
0x53, 0x9f, 0x5b, 0x57, 0xfd, 0xd1, 0x92, 0xf8, 0xb4, 0x02, 0x3a, 0x5c, 0xa5, 0x1b, 0x3e, 0x99,
0x25, 0xaa, 0x87, 0xab, 0x54, 0x79, 0x86, 0x8b, 0xd3, 0xac, 0xff, 0xc3, 0xc1, 0xf3, 0x45, 0x19,
0xd9, 0x8a, 0x28, 0x24, 0xad, 0xc0, 0x2d, 0x5b, 0x61, 0xcd, 0xed, 0xb1, 0x6c, 0xd1, 0xec, 0xaa,
0x45, 0x77, 0x61, 0x73, 0x62, 0x78, 0x3e, 0x1e, 0xdb, 0x0e, 0x1d, 0x60, 0x49, 0xcb, 0x07, 0xdf,
0x6d, 0xdb, 0x49, 0x95, 0x33, 0xb7, 0xae, 0x9c, 0x37, 0xf1, 0x55, 0x19, 0xf0, 0x5c, 0x6c, 0x8f,
0x87, 0x56, 0xe5, 0xc2, 0xf7, 0xfc, 0x03, 0xbe, 0xcf, 0xa4, 0xf9, 0xfe, 0x13, 0x54, 0xe2, 0x95,
0x1f, 0x70, 0x7d, 0x1a, 0x59, 0x7e, 0x5d, 0xb2, 0x7f, 0x27, 0x56, 0xcd, 0xbc, 0x26, 0xa3, 0x1c,
0x37, 0x25, 0xf7, 0x80, 0x29, 0xf9, 0x74, 0x53, 0xa6, 0xb8, 0x2e, 0xbb, 0x86, 0xeb, 0x36, 0x1e,
0xe7, 0xba, 0xdc, 0xb2, 0xeb, 0x70, 0x52, 0xca, 0xa7, 0x37, 0xdd, 0x10, 0x9e, 0xad, 0x14, 0x78,
0x72, 0xcf, 0xfd, 0xca, 0x41, 0x2d, 0x61, 0xed, 0xde, 0xcc, 0x1b, 0xf7, 0x5c, 0x62, 0x4e, 0x8d,
0x4b, 0xf2, 0x94, 0x74, 0x50, 0x15, 0x36, 0x1d, 0x76, 0x6f, 0xe4, 0xd2, 0xe8, 0xbb, 0xfe, 0x05,
0x1c, 0xdc, 0xd3, 0x44, 0xf8, 0x54, 0xea, 0xbf, 0xc0, 0xab, 0xfe, 0xec, 0xc2, 0x1b, 0xba, 0xe6,
0x05, 0x19, 0x38, 0x23, 0xc3, 0x27, 0x4f, 0xaa, 0xf7, 0xbd, 0x7b, 0xa4, 0xee, 0xc3, 0xe7, 0xf3,
0xe2, 0xac, 0xc9, 0x79, 0x0f, 0x0b, 0xf7, 0xfa, 0xe6, 0x94, 0x78, 0xbe, 0x31, 0x75, 0xb0, 0xe5,
0xb1, 0xe7, 0x5c, 0x9c, 0xc7, 0x14, 0x0f, 0x9d, 0xc0, 0x86, 0xe7, 0x47, 0x4f, 0x39, 0xde, 0x5c,
0xc8, 0x3e, 0x98, 0x4b, 0x3f, 0xc8, 0x6b, 0x21, 0xac, 0xee, 0xc1, 0x7e, 0xa2, 0xaa, 0x6c, 0xfd,
0xff, 0x45, 0x8f, 0xc7, 0xb0, 0xbd, 0xa4, 0x15, 0x02, 0xc8, 0x75, 0xa4, 0x53, 0xb1, 0xf1, 0x83,
0xf0, 0x19, 0x42, 0xb0, 0xd5, 0x1d, 0x74, 0x74, 0x19, 0x77, 0x54, 0xb5, 0x87, 0xd5, 0x81, 0x2e,
0x70, 0x68, 0x17, 0x5e, 0x2a, 0xa2, 0x2e, 0x9f, 0x49, 0xb8, 0x2f, 0x9d, 0x9e, 0xcb, 0x7a, 0x98,
0x93, 0x15, 0x81, 0x47, 0x55, 0xd8, 0xe9, 0x69, 0x92, 0xdc, 0x15, 0x4f, 0x25, 0xdc, 0x1b, 0xf4,
0xdb, 0x8b, 0x63, 0x99, 0xe3, 0x3f, 0x79, 0xd8, 0x5e, 0x6a, 0x02, 0x95, 0xa1, 0x20, 0x2b, 0xb2,
0x2e, 0x8b, 0xba, 0xd4, 0x0c, 0xab, 0xb5, 0xf5, 0x4e, 0x03, 0xf7, 0x06, 0x1f, 0x3a, 0x72, 0xbf,
0x2d, 0x35, 0x05, 0x0e, 0x15, 0x21, 0xdf, 0x1f, 0x34, 0x1a, 0x52, 0xbf, 0x2f, 0xf0, 0x01, 0xa0,
0x25, 0xca, 0x1d, 0xa9, 0x89, 0x07, 0xca, 0x47, 0x45, 0x3d, 0x57, 0x84, 0x4c, 0x2c, 0xa6, 0xa8,
0x38, 0x38, 0x2e, 0x64, 0xd1, 0x3e, 0x54, 0x59, 0x4c, 0x56, 0xce, 0xc4, 0x8e, 0xdc, 0xa4, 0x09,
0x2c, 0x76, 0xd5, 0x81, 0xa2, 0x0b, 0x1b, 0xe8, 0x0d, 0x54, 0x58, 0x5e, 0x6d, 0xb5, 0x70, 0xa3,
0x2d, 0xca, 0x0a, 0xd6, 0xe5, 0xae, 0x14, 0x74, 0x9a, 0x8b, 0xdd, 0x18, 0xc5, 0xf2, 0xa8, 0x02,
0x2f, 0x58, 0xac, 0x7f, 0x2e, 0xf6, 0x70, 0x53, 0x12, 0x9b, 0x1d, 0x59, 0x91, 0x84, 0x4d, 0xf4,
0x1a, 0x5e, 0xb1, 0xcc, 0xa2, 0xf7, 0x86, 0xa8, 0xcb, 0xaa, 0x22, 0x14, 0xd0, 0x4b, 0x78, 0xc6,
0xee, 0x88, 0x91, 0x02, 0xb4, 0x03, 0x68, 0xa0, 0x48, 0xdf, 0xf7, 0xa4, 0x86, 0x2e, 0x35, 0x71,
0x70, 0x7c, 0xa0, 0x49, 0x42, 0x71, 0x2e, 0x40, 0x43, 0x55, 0x5a, 0xb2, 0xd6, 0x95, 0x9a, 0x42,
0xe9, 0xfd, 0x1f, 0x39, 0x00, 0xaa, 0x18, 0xd5, 0x0e, 0xa9, 0x50, 0x4a, 0xfc, 0x2e, 0xd7, 0x97,
0x26, 0x9c, 0xf2, 0x6f, 0x41, 0xf5, 0xf5, 0x3d, 0x18, 0xa4, 0xc2, 0x96, 0x42, 0xae, 0x59, 0x28,
0x28, 0x84, 0xf6, 0xd2, 0xe1, 0xd1, 0x6d, 0xfb, 0x77, 0xa5, 0xd9, 0x2b, 0x9d, 0xc0, 0xf3, 0x14,
0x67, 0xa3, 0xaf, 0xd3, 0x8f, 0xa5, 0xac, 0xa0, 0xea, 0xf1, 0x63, 0xa0, 0xac, 0xda, 0x42, 0x8f,
0xf0, 0x9f, 0xc4, 0x3b, 0xf4, 0x88, 0xff, 0xf8, 0xdd, 0xa5, 0x47, 0x78, 0x41, 0x07, 0x8a, 0xf1,
0x1d, 0x7c, 0x90, 0x82, 0x4d, 0xfe, 0x00, 0x54, 0xab, 0x77, 0x43, 0x50, 0x07, 0xca, 0x4c, 0x5d,
0x99, 0x6e, 0x6c, 0xf4, 0x26, 0x15, 0x1c, 0x5d, 0xb5, 0x77, 0x47, 0x96, 0x91, 0xd5, 0xa3, 0xde,
0xc2, 0x56, 0xd3, 0x7b, 0x4b, 0x50, 0xad, 0xdf, 0x07, 0x61, 0xb7, 0x5e, 0xc6, 0x76, 0x6d, 0x72,
0xdd, 0xa1, 0xda, 0xe2, 0x78, 0xfa, 0x36, 0xae, 0x1e, 0xad, 0x22, 0xd2, 0x57, 0xe6, 0x3b, 0x0e,
0x11, 0xd8, 0x49, 0xdf, 0x70, 0x8f, 0xa8, 0xf3, 0x55, 0x7a, 0x9d, 0x95, 0x25, 0xf9, 0x8e, 0xbb,
0xc8, 0xd1, 0x65, 0xff, 0xcd, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x2c, 0xcd, 0x43, 0xb7, 0xdb,
0x0e, 0x00, 0x00,
// 1275 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x72, 0xdb, 0x44,
0x14, 0x46, 0xb2, 0xe3, 0xc4, 0xc7, 0x4e, 0xa2, 0x6e, 0xdb, 0xd4, 0x71, 0x9b, 0xe2, 0x08, 0x28,
0x21, 0x17, 0x69, 0xa7, 0xdc, 0x71, 0xa7, 0xda, 0x4a, 0xa3, 0xa9, 0x23, 0x1b, 0x59, 0xee, 0xcf,
0xd5, 0xb2, 0x71, 0x96, 0x44, 0x83, 0xf5, 0x53, 0x49, 0x4e, 0x93, 0xe1, 0x0a, 0x78, 0x0e, 0x9e,
0x01, 0x6e, 0x78, 0x02, 0x66, 0x78, 0x03, 0x5e, 0x81, 0xe7, 0x60, 0x76, 0xb5, 0xb2, 0x25, 0x5b,
0x49, 0x13, 0x26, 0xdc, 0x59, 0xe7, 0x7c, 0xda, 0x73, 0xbe, 0xef, 0xec, 0xf9, 0x64, 0xa8, 0x47,
0x34, 0x3c, 0xa3, 0xe1, 0x5e, 0x10, 0xfa, 0xb1, 0x8f, 0x96, 0xc7, 0xbe, 0x1f, 0x84, 0xc1, 0xa8,
0xf9, 0xe8, 0xc4, 0xf7, 0x4f, 0xc6, 0xf4, 0x29, 0x09, 0x9c, 0xa7, 0xc4, 0xf3, 0xfc, 0x98, 0xc4,
0x8e, 0xef, 0x45, 0x09, 0x4c, 0xfd, 0x49, 0x86, 0x7b, 0x03, 0xfe, 0x5e, 0xd7, 0xf7, 0x83, 0xde,
0x24, 0xb6, 0xe8, 0xfb, 0x09, 0x8d, 0x62, 0xb4, 0x0d, 0xf5, 0x90, 0x8e, 0xa8, 0x73, 0x46, 0x43,
0xfc, 0x03, 0xbd, 0x68, 0x48, 0x2d, 0x69, 0xa7, 0x6e, 0xd5, 0xd2, 0xd8, 0x2b, 0x7a, 0x81, 0x1e,
0x42, 0x35, 0xfa, 0x40, 0x02, 0x7c, 0x4a, 0xa2, 0xd3, 0x86, 0xcc, 0xf3, 0x2b, 0x2c, 0x70, 0x40,
0xa2, 0x53, 0xa4, 0x40, 0x89, 0xb8, 0x71, 0xa3, 0xd4, 0x92, 0x76, 0xca, 0x16, 0xfb, 0x89, 0xbe,
0x81, 0x4d, 0x0e, 0x0f, 0x26, 0x47, 0x63, 0x67, 0xc4, 0xbb, 0xc0, 0xc7, 0x94, 0x1c, 0x8f, 0x1d,
0x8f, 0x36, 0xca, 0x2d, 0x69, 0xa7, 0x64, 0x3d, 0x60, 0x80, 0xfe, 0x2c, 0xdf, 0x11, 0x69, 0xd4,
0x06, 0x85, 0xf7, 0x3b, 0xf2, 0xc7, 0xf8, 0x8c, 0x86, 0x91, 0xe3, 0x7b, 0x8d, 0xa5, 0x96, 0xb4,
0xb3, 0xf6, 0xbc, 0xb1, 0x27, 0x88, 0xee, 0xf5, 0x05, 0xe0, 0x75, 0x92, 0xb7, 0xd6, 0x83, 0x7c,
0x00, 0x6d, 0x40, 0x85, 0x9e, 0x07, 0x4e, 0x78, 0xd1, 0xa8, 0xb4, 0xa4, 0x9d, 0x25, 0x4b, 0x3c,
0xa9, 0x7f, 0x4a, 0x70, 0x7f, 0x4e, 0x83, 0x28, 0xf0, 0xbd, 0x88, 0x32, 0x11, 0x78, 0xcb, 0x8e,
0x77, 0xe6, 0x3b, 0x23, 0xca, 0x45, 0xa8, 0x5a, 0x35, 0x16, 0x33, 0x92, 0x10, 0xfa, 0x02, 0xd6,
0x82, 0x90, 0x06, 0xe4, 0x62, 0x0a, 0x92, 0x39, 0x68, 0x35, 0x89, 0xa6, 0xb0, 0x2d, 0x80, 0x88,
0x7a, 0xc7, 0x42, 0xcc, 0x12, 0x17, 0xab, 0x9a, 0x44, 0x98, 0x94, 0xcd, 0x69, 0x6b, 0x4c, 0x88,
0xa5, 0x17, 0x72, 0x43, 0x4a, 0xdb, 0x63, 0x15, 0x92, 0xc9, 0x62, 0x97, 0x46, 0x11, 0x39, 0xa1,
0x9c, 0x79, 0xd5, 0x5a, 0x4d, 0xa2, 0x87, 0x49, 0x50, 0xfd, 0x4b, 0x82, 0xcd, 0x1c, 0x8b, 0x6f,
0x27, 0x7e, 0x4c, 0xd3, 0x71, 0x8a, 0x71, 0x48, 0xd7, 0x1c, 0x87, 0x7c, 0xf3, 0x71, 0x94, 0xfe,
0xfb, 0x38, 0xca, 0xb9, 0x71, 0xfc, 0x2a, 0x03, 0x5a, 0x24, 0x82, 0x76, 0xe1, 0x4e, 0xd2, 0x2f,
0xb9, 0x70, 0xa9, 0x17, 0xe3, 0x63, 0x1a, 0xc5, 0x62, 0x20, 0xeb, 0xbc, 0xcf, 0x24, 0xde, 0x61,
0x6c, 0x37, 0x81, 0x5f, 0x44, 0xfc, 0x3d, 0x4d, 0xa9, 0x2c, 0xb3, 0xe7, 0x7d, 0x4a, 0xd1, 0x13,
0x58, 0x4d, 0x53, 0x38, 0x24, 0x31, 0xe5, 0x7d, 0x97, 0xb8, 0xe0, 0x35, 0x81, 0xb1, 0x48, 0xcc,
0x07, 0x26, 0xe6, 0xca, 0x74, 0x2b, 0x73, 0xdd, 0xaa, 0x49, 0x44, 0x73, 0x63, 0xb4, 0x0b, 0xeb,
0xae, 0xe3, 0x61, 0x7e, 0x14, 0x71, 0xfd, 0x89, 0x17, 0xf3, 0xa9, 0x94, 0xf9, 0x41, 0xab, 0xae,
0xe3, 0x0d, 0x3e, 0x90, 0x40, 0xe3, 0x09, 0x8e, 0x25, 0xe7, 0x39, 0x6c, 0x25, 0x83, 0x25, 0xe7,
0x19, 0xec, 0x36, 0xc0, 0x68, 0x1c, 0x9f, 0xe1, 0x63, 0x3a, 0x8e, 0x49, 0x63, 0x79, 0x7a, 0x19,
0xaa, 0x2c, 0xda, 0x61, 0x41, 0xf5, 0xbb, 0xb9, 0x39, 0xdb, 0x34, 0x74, 0xa3, 0x74, 0xce, 0x45,
0x93, 0x91, 0x6e, 0x38, 0x19, 0xf5, 0x77, 0x69, 0x6e, 0x02, 0xbc, 0x04, 0x7a, 0xb2, 0xc8, 0x39,
0xb9, 0x4f, 0x73, 0x7c, 0x9f, 0x2c, 0xf2, 0x95, 0x05, 0x2e, 0xc7, 0xf5, 0x73, 0x58, 0x63, 0xe7,
0x65, 0xf8, 0x96, 0xf8, 0x45, 0xa8, 0xbb, 0x8e, 0xd7, 0x4e, 0xe9, 0x72, 0x14, 0x39, 0xcf, 0xa2,
0xca, 0x02, 0x45, 0xce, 0xa7, 0x28, 0xf5, 0x1f, 0x09, 0xee, 0xce, 0x5a, 0x36, 0xbc, 0x54, 0x8f,
0xfc, 0xde, 0x49, 0xf3, 0x7b, 0x77, 0x43, 0x0b, 0x9b, 0xf7, 0x83, 0xf2, 0xa2, 0x1f, 0x6c, 0xc2,
0xca, 0x98, 0x44, 0x31, 0x3e, 0xf5, 0x03, 0x7e, 0x23, 0xea, 0xd6, 0x32, 0x7b, 0x3e, 0xf0, 0x83,
0xc2, 0xd9, 0x54, 0x6e, 0x3a, 0x9b, 0xf3, 0xac, 0x5f, 0x33, 0x9e, 0x33, 0xab, 0xfa, 0x98, 0x5f,
0xcf, 0x16, 0x4e, 0xce, 0x2e, 0x5c, 0x81, 0xc1, 0x94, 0x8a, 0x0c, 0xe6, 0x3d, 0x34, 0xb2, 0x95,
0x3f, 0x62, 0x2f, 0x45, 0x64, 0xe5, 0x9b, 0x92, 0xfd, 0x3b, 0xe7, 0x69, 0xd3, 0x9a, 0x82, 0x72,
0x76, 0xcb, 0xa5, 0x8f, 0x6c, 0xb9, 0x5c, 0xbc, 0xe5, 0x05, 0x6b, 0x5c, 0xbe, 0xc1, 0x1a, 0x2f,
0x5d, 0xb6, 0xc6, 0x5b, 0xb9, 0x35, 0x4e, 0x3e, 0x37, 0x99, 0x15, 0xc6, 0x79, 0x29, 0x6f, 0x7f,
0x83, 0x47, 0x70, 0x67, 0xa1, 0xc0, 0x6d, 0xef, 0xaf, 0xfa, 0x8b, 0x04, 0xad, 0x9c, 0x4d, 0xf4,
0x27, 0xd1, 0x69, 0x3f, 0xa4, 0x8e, 0x4b, 0x4e, 0xe8, 0x6d, 0xd2, 0x41, 0x4d, 0x58, 0x09, 0xc4,
0xb9, 0xe9, 0x96, 0xa6, 0xcf, 0xea, 0x67, 0xb0, 0x7d, 0x45, 0x13, 0xc9, 0x55, 0x51, 0x7f, 0x84,
0x07, 0x83, 0xc9, 0x51, 0x34, 0x0a, 0x9d, 0x23, 0x3a, 0x0c, 0x8e, 0x49, 0x4c, 0x6f, 0x55, 0xef,
0x2b, 0x7d, 0x44, 0x8d, 0xe1, 0xd3, 0x69, 0x71, 0xd1, 0xe4, 0xb4, 0x87, 0xd9, 0xf6, 0xc6, 0x8e,
0x4b, 0xa3, 0x98, 0xb8, 0x01, 0xf6, 0x22, 0x71, 0x9d, 0x6b, 0xd3, 0x98, 0x19, 0xa1, 0x3d, 0x58,
0x8a, 0xe2, 0xf4, 0x2a, 0x67, 0x9b, 0x4b, 0xd8, 0xb3, 0xb9, 0x0c, 0x58, 0xde, 0x4a, 0x60, 0x6a,
0x04, 0x8f, 0x73, 0x55, 0x0d, 0xef, 0xff, 0x2f, 0xba, 0xfb, 0xb3, 0x04, 0xeb, 0x73, 0x62, 0x21,
0x80, 0x4a, 0x57, 0x7f, 0xa9, 0xb5, 0xdf, 0x29, 0x9f, 0x20, 0x04, 0x6b, 0x87, 0xc3, 0xae, 0x6d,
0xe0, 0x6e, 0xaf, 0xd7, 0xc7, 0xbd, 0xa1, 0xad, 0x48, 0x68, 0x13, 0xee, 0x9b, 0x9a, 0x6d, 0xbc,
0xd6, 0xf1, 0x40, 0x7f, 0xf9, 0xc6, 0xb0, 0x93, 0x9c, 0x61, 0x2a, 0x32, 0x6a, 0xc2, 0x46, 0xdf,
0xd2, 0x8d, 0x43, 0xed, 0xa5, 0x8e, 0xfb, 0xc3, 0xc1, 0xc1, 0xec, 0xb5, 0x12, 0x6a, 0xc0, 0xbd,
0xe1, 0x40, 0xb7, 0xb0, 0xfe, 0xb6, 0x6f, 0x58, 0xef, 0x66, 0x99, 0xf2, 0xee, 0x1f, 0x32, 0xac,
0xcf, 0xf5, 0x87, 0x56, 0xa1, 0x6a, 0x98, 0x86, 0x6d, 0x68, 0xb6, 0xde, 0x49, 0xfa, 0x38, 0xb0,
0xbb, 0x6d, 0xdc, 0x1f, 0xbe, 0xe8, 0x1a, 0x83, 0x03, 0xbd, 0xa3, 0x48, 0xa8, 0x06, 0xcb, 0x83,
0x61, 0xbb, 0xad, 0x0f, 0x06, 0x8a, 0xcc, 0x00, 0xfb, 0x9a, 0xd1, 0xd5, 0x3b, 0x78, 0x68, 0xbe,
0x32, 0x7b, 0x6f, 0x4c, 0xa5, 0x94, 0x89, 0x99, 0x3d, 0xcc, 0x5e, 0x57, 0xca, 0xe8, 0x31, 0x34,
0x45, 0xcc, 0x30, 0x5f, 0x6b, 0x5d, 0xa3, 0xc3, 0x13, 0x58, 0x3b, 0xec, 0x0d, 0x4d, 0x5b, 0x59,
0x42, 0x8f, 0xa0, 0x21, 0xf2, 0xbd, 0xfd, 0x7d, 0xdc, 0x3e, 0xd0, 0x0c, 0x13, 0xdb, 0xc6, 0xa1,
0xce, 0x3a, 0xad, 0x64, 0x4e, 0x4c, 0x63, 0xcb, 0x8c, 0x97, 0x88, 0x0d, 0xde, 0x68, 0x7d, 0xdc,
0xd1, 0xb5, 0x4e, 0xd7, 0x30, 0x75, 0x65, 0x05, 0x3d, 0x84, 0x07, 0x22, 0x33, 0xeb, 0xbd, 0xad,
0xd9, 0x46, 0xcf, 0x54, 0xaa, 0xe8, 0x3e, 0xdc, 0x11, 0x67, 0x64, 0x48, 0x01, 0xda, 0x00, 0x34,
0x34, 0xf5, 0xb7, 0x7d, 0xbd, 0x6d, 0xeb, 0x1d, 0xcc, 0x5e, 0x1f, 0x5a, 0xba, 0x52, 0x9b, 0x0a,
0xd0, 0xee, 0x99, 0xfb, 0x86, 0x75, 0xa8, 0x77, 0x94, 0xfa, 0xf3, 0xdf, 0x2a, 0x00, 0x5c, 0x31,
0xae, 0x1d, 0xea, 0x41, 0x3d, 0xf7, 0xf9, 0x57, 0xe7, 0x86, 0x5f, 0xf0, 0xf7, 0xa3, 0xf9, 0xf0,
0x0a, 0x0c, 0xea, 0xc1, 0x9a, 0x49, 0x3f, 0x88, 0x10, 0x2b, 0x84, 0xb6, 0x8a, 0xe1, 0xe9, 0x69,
0x8f, 0x2f, 0x4b, 0x8b, 0x0b, 0x3c, 0x86, 0xbb, 0x05, 0x4b, 0x8f, 0xbe, 0x2a, 0x7e, 0xad, 0xc0,
0x9d, 0x9a, 0xbb, 0xd7, 0x81, 0x8a, 0x6a, 0x33, 0x3d, 0x92, 0x3f, 0xa4, 0x97, 0xe8, 0x91, 0xfd,
0x2e, 0x5e, 0xa6, 0x47, 0x72, 0x40, 0x17, 0x6a, 0x59, 0x7b, 0xde, 0x2e, 0xc0, 0xe6, 0xbf, 0x0d,
0xcd, 0xe6, 0xe5, 0x10, 0xd4, 0x85, 0x55, 0xa1, 0xae, 0xc1, 0xcd, 0x1c, 0x3d, 0x2a, 0x04, 0xa7,
0x47, 0x6d, 0x5d, 0x92, 0x15, 0x64, 0xed, 0xb4, 0xb7, 0xa4, 0xd5, 0xe2, 0xde, 0x72, 0x54, 0xd5,
0xab, 0x20, 0xe2, 0xd4, 0x93, 0x8c, 0x0d, 0xe7, 0x9d, 0x10, 0xb5, 0x66, 0xaf, 0x17, 0x1b, 0x75,
0x73, 0x67, 0x11, 0x51, 0xec, 0xa6, 0xcf, 0x24, 0x44, 0x61, 0xa3, 0xd8, 0xfc, 0xae, 0x51, 0xe7,
0xcb, 0xe2, 0x3a, 0x0b, 0xfe, 0xf9, 0x4c, 0x3a, 0xaa, 0xf0, 0xef, 0xc0, 0xd7, 0xff, 0x06, 0x00,
0x00, 0xff, 0xff, 0x95, 0x8b, 0xab, 0x97, 0x7b, 0x0f, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

@ -54,6 +54,9 @@ enum ProtocolVersion {
claim tx).
*/
PREIMAGE_PUSH_LOOP_OUT = 3;
// The client will propose a cltv expiry height for loop out.
USER_EXPIRY_LOOP_OUT = 4;
}
message ServerLoopOutRequest {
@ -68,6 +71,11 @@ message ServerLoopOutRequest {
/// The protocol version that the client adheres to.
ProtocolVersion protocol_version = 5;
// The requested absolute block height of the on-chain htlc. This is
// subjected to min and max constraints as reported in the LoopOutTerms
// response.
int32 expiry = 6;
}
message ServerLoopOutResponse {
@ -77,7 +85,9 @@ message ServerLoopOutResponse {
bytes sender_key = 3;
int32 expiry = 4;
// The height at which the on-chain htlc will expire. Deprecated because the
// field is already specified in the request.
int32 expiry = 4 [deprecated = true];
// A human-readable message from the loop server.
string server_message = 5;
@ -92,6 +102,11 @@ message ServerLoopOutQuoteRequest {
/// The protocol version that the client adheres to.
ProtocolVersion protocol_version = 3;
// The requested absolute block height of the on-chain htlc. This is
// subjected to min and max constraints as reported in the LoopOutTerms
// response.
int32 expiry = 4;
}
message ServerLoopOutQuote {
@ -109,7 +124,9 @@ message ServerLoopOutQuote {
uint64 max_swap_amount = 6 [deprecated = true];
int32 cltv_delta = 7;
// The server-proposed cltv delta of the on-chain htlc. Deprecated because
// the field is already specified in the request.
int32 cltv_delta = 7 [deprecated = true];
}
message ServerLoopOutTermsRequest {
@ -120,6 +137,12 @@ message ServerLoopOutTermsRequest {
message ServerLoopOutTerms {
uint64 min_swap_amount = 1;
uint64 max_swap_amount = 2;
// The minimally accepted cltv delta of the on-chain htlc.
int32 min_cltv_delta = 3;
// The maximally accepted cltv delta of the on-chain htlc.
int32 max_cltv_delta = 4;
}
message ServerLoopInRequest {

@ -18,12 +18,13 @@ import (
var (
testTime = time.Date(2018, time.January, 9, 14, 00, 00, 0, time.UTC)
testLoopOutOnChainCltvDelta = int32(30)
testChargeOnChainCltvDelta = int32(100)
testSwapFee = btcutil.Amount(210)
testFixedPrepayAmount = btcutil.Amount(100)
testMinSwapAmount = btcutil.Amount(10000)
testMaxSwapAmount = btcutil.Amount(1000000)
testLoopOutMinOnChainCltvDelta = int32(30)
testLoopOutMaxOnChainCltvDelta = int32(40)
testChargeOnChainCltvDelta = int32(100)
testSwapFee = btcutil.Amount(210)
testFixedPrepayAmount = btcutil.Amount(100)
testMinSwapAmount = btcutil.Amount(10000)
testMaxSwapAmount = btcutil.Amount(1000000)
)
// serverMock is used in client unit tests to simulate swap server behaviour.
@ -58,7 +59,7 @@ func newServerMock() *serverMock {
}
func (s *serverMock) NewLoopOutSwap(ctx context.Context,
swapHash lntypes.Hash, amount btcutil.Amount,
swapHash lntypes.Hash, amount btcutil.Amount, expiry int32,
receiverKey [33]byte, _ time.Time) (
*newLoopOutResponse, error) {
@ -87,7 +88,6 @@ func (s *serverMock) NewLoopOutSwap(ctx context.Context,
senderKey: senderKeyArray,
swapInvoice: swapPayReqString,
prepayInvoice: prePayReqString,
expiry: s.height + testLoopOutOnChainCltvDelta,
}, nil
}
@ -97,18 +97,19 @@ func (s *serverMock) GetLoopOutTerms(ctx context.Context) (
return &LoopOutTerms{
MinSwapAmount: testMinSwapAmount,
MaxSwapAmount: testMaxSwapAmount,
MinCltvDelta: testLoopOutMinOnChainCltvDelta,
MaxCltvDelta: testLoopOutMaxOnChainCltvDelta,
}, nil
}
func (s *serverMock) GetLoopOutQuote(ctx context.Context, amt btcutil.Amount,
_ time.Time) (*LoopOutQuote, error) {
expiry int32, _ time.Time) (*LoopOutQuote, error) {
dest := [33]byte{1, 2, 3}
return &LoopOutQuote{
SwapFee: testSwapFee,
SwapPaymentDest: dest,
CltvDelta: testLoopOutOnChainCltvDelta,
PrepayAmount: testFixedPrepayAmount,
}, nil
}

@ -25,7 +25,7 @@ import (
// protocolVersion defines the version of the protocol that is currently
// supported by the loop client.
const protocolVersion = looprpc.ProtocolVersion_PREIMAGE_PUSH_LOOP_OUT
const protocolVersion = looprpc.ProtocolVersion_USER_EXPIRY_LOOP_OUT
var (
// errServerSubscriptionComplete is returned when our subscription to
@ -46,7 +46,7 @@ type swapServerClient interface {
GetLoopOutTerms(ctx context.Context) (
*LoopOutTerms, error)
GetLoopOutQuote(ctx context.Context, amt btcutil.Amount,
GetLoopOutQuote(ctx context.Context, amt btcutil.Amount, expiry int32,
swapPublicationDeadline time.Time) (
*LoopOutQuote, error)
@ -57,7 +57,7 @@ type swapServerClient interface {
*LoopInQuote, error)
NewLoopOutSwap(ctx context.Context,
swapHash lntypes.Hash, amount btcutil.Amount,
swapHash lntypes.Hash, amount btcutil.Amount, expiry int32,
receiverKey [33]byte,
swapPublicationDeadline time.Time) (
*newLoopOutResponse, error)
@ -140,11 +140,13 @@ func (s *grpcSwapServerClient) GetLoopOutTerms(ctx context.Context) (
return &LoopOutTerms{
MinSwapAmount: btcutil.Amount(terms.MinSwapAmount),
MaxSwapAmount: btcutil.Amount(terms.MaxSwapAmount),
MinCltvDelta: terms.MinCltvDelta,
MaxCltvDelta: terms.MaxCltvDelta,
}, nil
}
func (s *grpcSwapServerClient) GetLoopOutQuote(ctx context.Context,
amt btcutil.Amount, swapPublicationDeadline time.Time) (
amt btcutil.Amount, expiry int32, swapPublicationDeadline time.Time) (
*LoopOutQuote, error) {
rpcCtx, rpcCancel := context.WithTimeout(ctx, globalCallTimeout)
@ -154,6 +156,7 @@ func (s *grpcSwapServerClient) GetLoopOutQuote(ctx context.Context,
Amt: uint64(amt),
SwapPublicationDeadline: swapPublicationDeadline.Unix(),
ProtocolVersion: protocolVersion,
Expiry: expiry,
},
)
if err != nil {
@ -173,7 +176,6 @@ func (s *grpcSwapServerClient) GetLoopOutQuote(ctx context.Context,
return &LoopOutQuote{
PrepayAmount: btcutil.Amount(quoteResp.PrepayAmt),
SwapFee: btcutil.Amount(quoteResp.SwapFee),
CltvDelta: quoteResp.CltvDelta,
SwapPaymentDest: destArray,
}, nil
}
@ -220,7 +222,7 @@ func (s *grpcSwapServerClient) GetLoopInQuote(ctx context.Context,
}
func (s *grpcSwapServerClient) NewLoopOutSwap(ctx context.Context,
swapHash lntypes.Hash, amount btcutil.Amount,
swapHash lntypes.Hash, amount btcutil.Amount, expiry int32,
receiverKey [33]byte, swapPublicationDeadline time.Time) (
*newLoopOutResponse, error) {
@ -233,6 +235,7 @@ func (s *grpcSwapServerClient) NewLoopOutSwap(ctx context.Context,
ReceiverKey: receiverKey[:],
SwapPublicationDeadline: swapPublicationDeadline.Unix(),
ProtocolVersion: protocolVersion,
Expiry: expiry,
},
)
if err != nil {
@ -252,7 +255,6 @@ func (s *grpcSwapServerClient) NewLoopOutSwap(ctx context.Context,
swapInvoice: swapResp.SwapInvoice,
prepayInvoice: swapResp.PrepayInvoice,
senderKey: senderKey,
expiry: swapResp.Expiry,
serverMessage: swapResp.ServerMessage,
}, nil
}
@ -526,7 +528,6 @@ type newLoopOutResponse struct {
swapInvoice string
prepayInvoice string
senderKey [33]byte
expiry int32
serverMessage string
}

Loading…
Cancel
Save