Merge pull request #184 from bhandras/native-segwit

support for native segwit loop-in
pull/196/head
Joost Jager 4 years ago committed by GitHub
commit 33a049f8e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -194,17 +194,17 @@ func (s *Client) FetchSwaps() ([]*SwapInfo, error) {
} }
swaps = append(swaps, &SwapInfo{ swaps = append(swaps, &SwapInfo{
SwapType: swap.TypeOut, SwapType: swap.TypeOut,
SwapContract: swp.Contract.SwapContract, SwapContract: swp.Contract.SwapContract,
SwapStateData: swp.State(), SwapStateData: swp.State(),
SwapHash: swp.Hash, SwapHash: swp.Hash,
LastUpdate: swp.LastUpdateTime(), LastUpdate: swp.LastUpdateTime(),
HtlcAddress: htlc.Address, HtlcAddressP2WSH: htlc.Address,
}) })
} }
for _, swp := range loopInSwaps { for _, swp := range loopInSwaps {
htlc, err := swap.NewHtlc( htlcNP2WSH, err := swap.NewHtlc(
swp.Contract.CltvExpiry, swp.Contract.SenderKey, swp.Contract.CltvExpiry, swp.Contract.SenderKey,
swp.Contract.ReceiverKey, swp.Hash, swap.HtlcNP2WSH, swp.Contract.ReceiverKey, swp.Hash, swap.HtlcNP2WSH,
s.lndServices.ChainParams, s.lndServices.ChainParams,
@ -213,13 +213,23 @@ func (s *Client) FetchSwaps() ([]*SwapInfo, error) {
return nil, err 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{ swaps = append(swaps, &SwapInfo{
SwapType: swap.TypeIn, SwapType: swap.TypeIn,
SwapContract: swp.Contract.SwapContract, SwapContract: swp.Contract.SwapContract,
SwapStateData: swp.State(), SwapStateData: swp.State(),
SwapHash: swp.Hash, SwapHash: swp.Hash,
LastUpdate: swp.LastUpdateTime(), LastUpdate: swp.LastUpdateTime(),
HtlcAddress: htlc.Address, HtlcAddressP2WSH: htlcP2WSH.Address,
HtlcAddressNP2WSH: htlcNP2WSH.Address,
}) })
} }
@ -464,7 +474,7 @@ func (s *Client) waitForInitialized(ctx context.Context) error {
// LoopIn initiates a loop in swap. // LoopIn initiates a loop in swap.
func (s *Client) LoopIn(globalCtx context.Context, 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)", log.Infof("Loop in %v (last hop: %v)",
request.Amount, request.Amount,
@ -472,7 +482,7 @@ func (s *Client) LoopIn(globalCtx context.Context,
) )
if err := s.waitForInitialized(globalCtx); err != nil { if err := s.waitForInitialized(globalCtx); err != nil {
return nil, nil, err return nil, err
} }
// Create a new swap object for this swap. // Create a new swap object for this swap.
@ -486,7 +496,7 @@ func (s *Client) LoopIn(globalCtx context.Context,
globalCtx, &swapCfg, initiationHeight, request, globalCtx, &swapCfg, initiationHeight, request,
) )
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
// Post swap to the main loop. // Post swap to the main loop.
@ -494,7 +504,12 @@ func (s *Client) LoopIn(globalCtx context.Context,
// Return hash so that the caller can identify this swap in the updates // Return hash so that the caller can identify this swap in the updates
// stream. // stream.
return &swap.hash, swap.htlc.Address, nil swapInfo := &LoopInSwapInfo{
SwapHash: swap.hash,
HtlcAddressP2WSH: swap.htlcP2WSH.Address,
HtlcAddressNP2WSH: swap.htlcNP2WSH.Address,
}
return swapInfo, nil
} }
// LoopInQuote takes an amount and returns a break down of estimated // LoopInQuote takes an amount and returns a break down of estimated

@ -153,7 +153,10 @@ func loopIn(ctx *cli.Context) error {
fmt.Printf("Swap initiated\n") fmt.Printf("Swap initiated\n")
fmt.Printf("ID: %v\n", resp.Id) 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.Println()
fmt.Printf("Run `loop monitor` to monitor progress.\n") fmt.Printf("Run `loop monitor` to monitor progress.\n")

@ -225,11 +225,24 @@ func parseAmt(text string) (btcutil.Amount, error) {
} }
func logSwap(swap *looprpc.SwapStatus) { func logSwap(swap *looprpc.SwapStatus) {
fmt.Printf("%v %v %v %v - %v", if swap.Type == looprpc.SwapType_LOOP_OUT {
time.Unix(0, swap.LastUpdateTime).Format(time.RFC3339), fmt.Printf("%v %v %v %v - %v",
swap.Type, swap.State, btcutil.Amount(swap.Amt), time.Unix(0, swap.LastUpdateTime).Format(time.RFC3339),
swap.HtlcAddress, 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 && if swap.State != looprpc.SwapState_INITIATED &&
swap.State != looprpc.SwapState_HTLC_PUBLISHED && swap.State != looprpc.SwapState_HTLC_PUBLISHED &&

@ -235,6 +235,21 @@ type LoopInQuote struct {
CltvDelta int32 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
// 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. // SwapInfoKit contains common swap info fields.
type SwapInfoKit struct { type SwapInfoKit struct {
// Hash is the sha256 hash of the preimage that unlocks the htlcs. It // Hash is the sha256 hash of the preimage that unlocks the htlcs. It
@ -249,15 +264,27 @@ type SwapInfoKit struct {
type SwapInfo struct { type SwapInfo struct {
loopdb.SwapStateData loopdb.SwapStateData
loopdb.SwapContract
// LastUpdateTime is the time of the last state change.
LastUpdate time.Time LastUpdate time.Time
// SwapHash stores the swap preimage hash.
SwapHash lntypes.Hash SwapHash lntypes.Hash
// SwapType describes whether this is a loop in or loop out swap.
SwapType swap.Type SwapType swap.Type
loopdb.SwapContract // HtlcAddressP2WSH stores the address of the P2WSH (native segwit)
// swap htlc. This is used for both loop-in and loop-out.
HtlcAddressP2WSH btcutil.Address
HtlcAddress 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
} }
// LastUpdate returns the last update time of the swap // LastUpdate returns the last update time of the swap

@ -126,27 +126,43 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) (
} }
var swapType looprpc.SwapType var swapType looprpc.SwapType
var htlcAddress, htlcAddressP2WSH, htlcAddressNP2WSH string
switch loopSwap.SwapType { switch loopSwap.SwapType {
case swap.TypeIn: case swap.TypeIn:
swapType = looprpc.SwapType_LOOP_IN swapType = looprpc.SwapType_LOOP_IN
htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress()
if loopSwap.ExternalHtlc {
htlcAddressNP2WSH = loopSwap.HtlcAddressNP2WSH.EncodeAddress()
htlcAddress = htlcAddressNP2WSH
} else {
htlcAddress = htlcAddressP2WSH
}
case swap.TypeOut: case swap.TypeOut:
swapType = looprpc.SwapType_LOOP_OUT swapType = looprpc.SwapType_LOOP_OUT
htlcAddressP2WSH = loopSwap.HtlcAddressP2WSH.EncodeAddress()
htlcAddress = htlcAddressP2WSH
default: default:
return nil, errors.New("unknown swap type") return nil, errors.New("unknown swap type")
} }
return &looprpc.SwapStatus{ return &looprpc.SwapStatus{
Amt: int64(loopSwap.AmountRequested), Amt: int64(loopSwap.AmountRequested),
Id: loopSwap.SwapHash.String(), Id: loopSwap.SwapHash.String(),
IdBytes: loopSwap.SwapHash[:], IdBytes: loopSwap.SwapHash[:],
State: state, State: state,
InitiationTime: loopSwap.InitiationTime.UnixNano(), InitiationTime: loopSwap.InitiationTime.UnixNano(),
LastUpdateTime: loopSwap.LastUpdate.UnixNano(), LastUpdateTime: loopSwap.LastUpdate.UnixNano(),
HtlcAddress: loopSwap.HtlcAddress.EncodeAddress(), HtlcAddress: htlcAddress,
Type: swapType, HtlcAddressP2Wsh: htlcAddressP2WSH,
CostServer: int64(loopSwap.Cost.Server), HtlcAddressNp2Wsh: htlcAddressNP2WSH,
CostOnchain: int64(loopSwap.Cost.Onchain), Type: swapType,
CostOffchain: int64(loopSwap.Cost.Offchain), CostServer: int64(loopSwap.Cost.Server),
CostOnchain: int64(loopSwap.Cost.Onchain),
CostOffchain: int64(loopSwap.Cost.Offchain),
}, nil }, nil
} }
@ -255,6 +271,9 @@ func (s *swapClientServer) ListSwaps(_ context.Context,
err error err error
) )
s.swapsLock.Lock()
defer s.swapsLock.Unlock()
// We can just use the server's in-memory cache as that contains the // 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 // 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 // persisted to disk. The swaps field is a map, that's why we need an
@ -409,17 +428,25 @@ func (s *swapClientServer) LoopIn(ctx context.Context,
} }
req.LastHop = &lastHop req.LastHop = &lastHop
} }
hash, htlc, err := s.impl.LoopIn(ctx, req) swapInfo, err := s.impl.LoopIn(ctx, req)
if err != nil { if err != nil {
log.Errorf("Loop in: %v", err) log.Errorf("Loop in: %v", err)
return nil, err return nil, err
} }
return &looprpc.SwapResponse{ np2wshAddress := swapInfo.HtlcAddressNP2WSH.String()
Id: hash.String(), response := &looprpc.SwapResponse{
IdBytes: hash[:], Id: swapInfo.SwapHash.String(),
HtlcAddress: htlc.String(), IdBytes: swapInfo.SwapHash[:],
}, nil 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. // GetLsatTokens returns all tokens that are contained in the LSAT token store.

@ -48,8 +48,16 @@ var (
type loopInSwap struct { type loopInSwap struct {
swapKit swapKit
executeConfig
loopdb.LoopInContract loopdb.LoopInContract
htlc *swap.Htlc
htlcP2WSH *swap.Htlc
htlcNP2WSH *swap.Htlc
timeoutAddr btcutil.Address timeoutAddr btcutil.Address
} }
@ -148,13 +156,9 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig,
}, },
} }
swapKit, err := newSwapKit( swapKit := newSwapKit(
swapHash, swap.TypeIn, cfg, &contract.SwapContract, swapHash, swap.TypeIn, cfg, &contract.SwapContract,
swap.HtlcNP2WSH,
) )
if err != nil {
return nil, err
}
swapKit.lastUpdateTime = initiationTime swapKit.lastUpdateTime = initiationTime
@ -163,6 +167,10 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig,
swapKit: *swapKit, swapKit: *swapKit,
} }
if err := swap.initHtlcs(); err != nil {
return nil, err
}
// Persist the data before exiting this function, so that the caller can // Persist the data before exiting this function, so that the caller can
// trust that this swap will be resumed on restart. // trust that this swap will be resumed on restart.
err = cfg.store.CreateLoopIn(swapHash, &swap.LoopInContract) err = cfg.store.CreateLoopIn(swapHash, &swap.LoopInContract)
@ -182,19 +190,19 @@ func resumeLoopInSwap(reqContext context.Context, cfg *swapConfig,
log.Infof("Resuming loop in swap %v", hash) log.Infof("Resuming loop in swap %v", hash)
swapKit, err := newSwapKit( swapKit := newSwapKit(
hash, swap.TypeIn, cfg, &pend.Contract.SwapContract, hash, swap.TypeIn, cfg, &pend.Contract.SwapContract,
swap.HtlcNP2WSH,
) )
if err != nil {
return nil, err
}
swap := &loopInSwap{ swap := &loopInSwap{
LoopInContract: *pend.Contract, LoopInContract: *pend.Contract,
swapKit: *swapKit, swapKit: *swapKit,
} }
if err := swap.initHtlcs(); err != nil {
return nil, err
}
lastUpdate := pend.LastUpdate() lastUpdate := pend.LastUpdate()
if lastUpdate == nil { if lastUpdate == nil {
swap.lastUpdateTime = pend.Contract.InitiationTime swap.lastUpdateTime = pend.Contract.InitiationTime
@ -222,6 +230,47 @@ func validateLoopInContract(lnd *lndclient.LndServices,
return nil 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.HtlcAddressP2WSH = s.htlcP2WSH.Address
info.HtlcAddressNP2WSH = s.htlcNP2WSH.Address
info.ExternalHtlc = s.ExternalHtlc
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 // execute starts/resumes the swap. It is a thin wrapper around executeSwap to
// conveniently handle the error case. // conveniently handle the error case.
func (s *loopInSwap) execute(mainCtx context.Context, func (s *loopInSwap) execute(mainCtx context.Context,
@ -340,21 +389,44 @@ func (s *loopInSwap) waitForHtlcConf(globalCtx context.Context) (
ctx, cancel := context.WithCancel(globalCtx) ctx, cancel := context.WithCancel(globalCtx)
defer cancel() 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 { if err != nil {
return nil, err return nil, err
} }
confChanNP2WSH, confErrNP2WSH, err := notifier.RegisterConfirmationsNtfn(
ctx, nil, s.htlcNP2WSH.PkScript, 1, s.InitiationHeight,
)
if err != nil {
return nil, err
}
for { for {
select { select {
// Htlc confirmed. // P2WSH htlc confirmed.
case conf := <-confChan: case conf := <-confChanP2WSH:
s.htlc = s.htlcP2WSH
s.log.Infof("P2WSH htlc confirmed")
return conf, nil 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 := <-confErrP2WSH:
return nil, err
// Conf ntfn error. // Conf ntfn error.
case err := <-confErr: case err := <-confErrNP2WSH:
return nil, err return nil, err
// Keep up with block height. // Keep up with block height.
@ -399,9 +471,11 @@ func (s *loopInSwap) publishOnChainHtlc(ctx context.Context) (bool, error) {
} }
s.log.Infof("Publishing on chain HTLC with fee rate %v", feeRate) 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, tx, err := s.lnd.WalletKit.SendOutputs(ctx,
[]*wire.TxOut{{ []*wire.TxOut{{
PkScript: s.htlc.PkScript, PkScript: s.htlcP2WSH.PkScript,
Value: int64(s.LoopInContract.AmountRequested), Value: int64(s.LoopInContract.AmountRequested),
}}, }},
feeRate, feeRate,

@ -67,6 +67,7 @@ func TestLoopInSuccess(t *testing.T) {
// Expect register for htlc conf. // Expect register for htlc conf.
<-ctx.lnd.RegisterConfChannel <-ctx.lnd.RegisterConfChannel
<-ctx.lnd.RegisterConfChannel
// Confirm htlc. // Confirm htlc.
ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{ ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{
@ -118,20 +119,32 @@ func TestLoopInSuccess(t *testing.T) {
func TestLoopInTimeout(t *testing.T) { func TestLoopInTimeout(t *testing.T) {
testAmt := int64(testLoopInRequest.Amount) testAmt := int64(testLoopInRequest.Amount)
t.Run("internal htlc", func(t *testing.T) { t.Run("internal htlc", func(t *testing.T) {
testLoopInTimeout(t, 0) testLoopInTimeout(t, swap.HtlcP2WSH, 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)
}) })
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)() defer test.Guard(t)()
ctx := newLoopInTestContext(t) ctx := newLoopInTestContext(t)
@ -149,7 +162,7 @@ func testLoopInTimeout(t *testing.T, externalValue int64) {
req.ExternalHtlc = true req.ExternalHtlc = true
} }
swap, err := newLoopInSwap( s, err := newLoopInSwap(
context.Background(), cfg, context.Background(), cfg,
height, &req, height, &req,
) )
@ -161,7 +174,7 @@ func testLoopInTimeout(t *testing.T, externalValue int64) {
errChan := make(chan error) errChan := make(chan error)
go func() { go func() {
err := swap.execute(context.Background(), ctx.cfg, height) err := s.execute(context.Background(), ctx.cfg, height)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} }
@ -179,10 +192,16 @@ func testLoopInTimeout(t *testing.T, externalValue int64) {
htlcTx = <-ctx.lnd.SendOutputsChannel htlcTx = <-ctx.lnd.SendOutputsChannel
} else { } else {
// Create an external htlc publish tx. // 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{ htlcTx = wire.MsgTx{
TxOut: []*wire.TxOut{ TxOut: []*wire.TxOut{
{ {
PkScript: swap.htlc.PkScript, PkScript: pkScript,
Value: externalValue, Value: externalValue,
}, },
}, },
@ -191,6 +210,7 @@ func testLoopInTimeout(t *testing.T, externalValue int64) {
// Expect register for htlc conf. // Expect register for htlc conf.
<-ctx.lnd.RegisterConfChannel <-ctx.lnd.RegisterConfChannel
<-ctx.lnd.RegisterConfChannel
// Confirm htlc. // Confirm htlc.
ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{ ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{
@ -207,7 +227,7 @@ func testLoopInTimeout(t *testing.T, externalValue int64) {
} }
// Let htlc expire. // Let htlc expire.
ctx.blockEpochChan <- swap.LoopInContract.CltvExpiry ctx.blockEpochChan <- s.LoopInContract.CltvExpiry
// Expect a signing request for the htlc tx output value. // Expect a signing request for the htlc tx output value.
signReq := <-ctx.lnd.SignOutputRawChannel signReq := <-ctx.lnd.SignOutputRawChannel
@ -378,6 +398,7 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool) {
// Expect register for htlc conf. // Expect register for htlc conf.
<-ctx.lnd.RegisterConfChannel <-ctx.lnd.RegisterConfChannel
<-ctx.lnd.RegisterConfChannel
// Confirm htlc. // Confirm htlc.
ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{ ctx.lnd.ConfChannel <- &chainntnfs.TxConfirmation{

@ -52,6 +52,10 @@ type loopOutSwap struct {
loopdb.LoopOutContract loopdb.LoopOutContract
executeConfig
htlc *swap.Htlc
swapPaymentChan chan lndclient.PaymentResult swapPaymentChan chan lndclient.PaymentResult
prePaymentChan 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, swapHash, swap.TypeOut, cfg, &contract.SwapContract,
swap.HtlcP2WSH,
) )
swapKit.lastUpdateTime = initiationTime
// Create the htlc.
htlc, err := swapKit.getHtlc(swap.HtlcP2WSH)
if err != nil { if err != nil {
return nil, err return nil, err
} }
swapKit.lastUpdateTime = initiationTime // Log htlc address for debugging.
swapKit.log.Infof("Htlc address: %v", htlc.Address)
swap := &loopOutSwap{ swap := &loopOutSwap{
LoopOutContract: contract, LoopOutContract: contract,
swapKit: *swapKit, swapKit: *swapKit,
htlc: htlc,
} }
// Persist the data before exiting this function, so that the caller // 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) log.Infof("Resuming loop out swap %v", hash)
swapKit, err := newSwapKit( swapKit := newSwapKit(
hash, swap.TypeOut, cfg, &pend.Contract.SwapContract, hash, swap.TypeOut, cfg, &pend.Contract.SwapContract,
swap.HtlcP2WSH,
) )
// Create the htlc.
htlc, err := swapKit.getHtlc(swap.HtlcP2WSH)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Log htlc address for debugging.
swapKit.log.Infof("Htlc address: %v", htlc.Address)
// Create the swap.
swap := &loopOutSwap{ swap := &loopOutSwap{
LoopOutContract: *pend.Contract, LoopOutContract: *pend.Contract,
swapKit: *swapKit, swapKit: *swapKit,
htlc: htlc,
} }
lastUpdate := pend.LastUpdate() lastUpdate := pend.LastUpdate()
@ -192,6 +209,22 @@ func resumeLoopOutSwap(reqContext context.Context, cfg *swapConfig,
return swap, nil 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.HtlcAddressP2WSH = 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 // execute starts/resumes the swap. It is a thin wrapper around
// executeAndFinalize to conveniently handle the error case. // executeAndFinalize to conveniently handle the error case.
func (s *loopOutSwap) execute(mainCtx context.Context, func (s *loopOutSwap) execute(mainCtx context.Context,

@ -379,8 +379,23 @@ type SwapResponse struct {
//the Start() call. Currently this is the hash that locks the htlcs. //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"` IdBytes []byte `protobuf:"bytes,3,opt,name=id_bytes,json=idBytes,proto3" json:"id_bytes,omitempty"`
//* //*
//The address of the on-chain htlc. //DEPRECATED. This field stores the address of the onchain htlc, but
HtlcAddress string `protobuf:"bytes,2,opt,name=htlc_address,json=htlcAddress,proto3" json:"htlc_address,omitempty"` //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_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -426,6 +441,7 @@ func (m *SwapResponse) GetIdBytes() []byte {
return nil return nil
} }
// Deprecated: Do not use.
func (m *SwapResponse) GetHtlcAddress() string { func (m *SwapResponse) GetHtlcAddress() string {
if m != nil { if m != nil {
return m.HtlcAddress return m.HtlcAddress
@ -433,6 +449,20 @@ func (m *SwapResponse) GetHtlcAddress() string {
return "" 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 { type MonitorRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -492,8 +522,18 @@ type SwapStatus struct {
//Initiation time of the swap. //Initiation time of the swap.
LastUpdateTime int64 `protobuf:"varint,6,opt,name=last_update_time,json=lastUpdateTime,proto3" json:"last_update_time,omitempty"` LastUpdateTime int64 `protobuf:"varint,6,opt,name=last_update_time,json=lastUpdateTime,proto3" json:"last_update_time,omitempty"`
//* //*
//Htlc address. //DEPRECATED: This field stores the address of the onchain htlc.
HtlcAddress string `protobuf:"bytes,7,opt,name=htlc_address,json=htlcAddress,proto3" json:"htlc_address,omitempty"` //- 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 /// Swap server cost
CostServer int64 `protobuf:"varint,8,opt,name=cost_server,json=costServer,proto3" json:"cost_server,omitempty"` CostServer int64 `protobuf:"varint,8,opt,name=cost_server,json=costServer,proto3" json:"cost_server,omitempty"`
// On-chain transaction cost // On-chain transaction cost
@ -580,6 +620,7 @@ func (m *SwapStatus) GetLastUpdateTime() int64 {
return 0 return 0
} }
// Deprecated: Do not use.
func (m *SwapStatus) GetHtlcAddress() string { func (m *SwapStatus) GetHtlcAddress() string {
if m != nil { if m != nil {
return m.HtlcAddress return m.HtlcAddress
@ -587,6 +628,20 @@ func (m *SwapStatus) GetHtlcAddress() string {
return "" 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 { func (m *SwapStatus) GetCostServer() int64 {
if m != nil { if m != nil {
return m.CostServer return m.CostServer
@ -1180,98 +1235,101 @@ func init() {
func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) } func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) }
var fileDescriptor_014de31d7ac8c57c = []byte{ var fileDescriptor_014de31d7ac8c57c = []byte{
// 1448 bytes of a gzipped FileDescriptorProto // 1504 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xcb, 0x6e, 0xdb, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xcb, 0x72, 0xdb, 0x46,
0x14, 0x0d, 0x25, 0x59, 0x8f, 0x2b, 0x8a, 0xa2, 0xc7, 0x89, 0x2d, 0xab, 0x0d, 0xe2, 0xb0, 0x4d, 0x16, 0x35, 0xf8, 0xe6, 0x25, 0x08, 0x82, 0x2d, 0x5b, 0xa2, 0x38, 0xe3, 0xb2, 0x8c, 0x19, 0xcf,
0xeb, 0x78, 0x11, 0x35, 0xce, 0xaa, 0x41, 0x51, 0xc0, 0x91, 0x95, 0x58, 0x86, 0x5f, 0xa5, 0xe4, 0xc8, 0xaa, 0x29, 0x71, 0x2c, 0xaf, 0xc6, 0x35, 0x95, 0x2a, 0x99, 0xa2, 0x2d, 0xaa, 0xf4, 0x60,
0x00, 0xc9, 0x86, 0x19, 0x8b, 0x63, 0x9b, 0xa8, 0xc8, 0x61, 0x38, 0xa3, 0xc4, 0x46, 0x90, 0x4d, 0x40, 0xca, 0x55, 0xf6, 0x06, 0x69, 0x11, 0x2d, 0x11, 0x15, 0xe2, 0x61, 0x74, 0xd3, 0x92, 0xca,
0x7f, 0xa1, 0xbb, 0x2e, 0xfb, 0x07, 0x5d, 0xf7, 0x2b, 0x8a, 0xfe, 0x42, 0x3f, 0xa1, 0xdb, 0x02, 0xe5, 0x4d, 0x7e, 0x21, 0xbb, 0x2c, 0xf3, 0x07, 0x59, 0x67, 0x97, 0x3f, 0x48, 0xe5, 0x03, 0xb2,
0xc5, 0x3c, 0x44, 0x91, 0x96, 0x9d, 0x45, 0x76, 0xe6, 0x99, 0x33, 0x67, 0xee, 0xdc, 0xc7, 0x19, 0xc9, 0x27, 0xe4, 0x03, 0x52, 0xfd, 0x20, 0x08, 0x48, 0x94, 0x17, 0xde, 0x11, 0xa7, 0x4f, 0x9f,
0x19, 0xcc, 0xd1, 0x38, 0x20, 0x11, 0x7f, 0x14, 0x27, 0x94, 0x53, 0x54, 0x19, 0x53, 0x1a, 0x27, 0xbe, 0x7d, 0xef, 0xed, 0xd3, 0x4d, 0xd0, 0xc7, 0x53, 0x8f, 0x04, 0x6c, 0x3b, 0x8a, 0x43, 0x16,
0xf1, 0xa8, 0xfd, 0xe5, 0x19, 0xa5, 0x67, 0x63, 0xd2, 0xc1, 0x71, 0xd0, 0xc1, 0x51, 0x44, 0x39, 0xa2, 0xf2, 0x34, 0x0c, 0xa3, 0x38, 0x1a, 0xb7, 0xff, 0x7e, 0x11, 0x86, 0x17, 0x53, 0xd2, 0xc1,
0xe6, 0x01, 0x8d, 0x98, 0xa2, 0x39, 0xbf, 0x15, 0xc1, 0xda, 0xa3, 0x34, 0x3e, 0x9c, 0x70, 0x97, 0x91, 0xd7, 0xc1, 0x41, 0x10, 0x32, 0xcc, 0xbc, 0x30, 0xa0, 0x92, 0x66, 0xfd, 0x90, 0x07, 0xe3,
0xbc, 0x9d, 0x10, 0xc6, 0x91, 0x0d, 0x45, 0x1c, 0xf2, 0x96, 0xb1, 0x66, 0xac, 0x17, 0x5d, 0xf1, 0x30, 0x0c, 0xa3, 0x93, 0x19, 0xb3, 0xc9, 0xfb, 0x19, 0xa1, 0x0c, 0x99, 0x90, 0xc7, 0x3e, 0x6b,
0x27, 0x42, 0x50, 0xf2, 0x09, 0xe3, 0xad, 0xc2, 0x9a, 0xb1, 0x5e, 0x73, 0xe5, 0xdf, 0xa8, 0x03, 0x69, 0x1b, 0xda, 0x66, 0xde, 0xe6, 0x3f, 0x11, 0x82, 0x82, 0x4b, 0x28, 0x6b, 0xe5, 0x36, 0xb4,
0xb7, 0x43, 0x7c, 0xe1, 0xb1, 0xf7, 0x38, 0xf6, 0x12, 0x3a, 0xe1, 0x41, 0x74, 0xe6, 0x9d, 0x12, 0xcd, 0xaa, 0x2d, 0x7e, 0xa3, 0x0e, 0xdc, 0xf7, 0xf1, 0x95, 0x43, 0x2f, 0x71, 0xe4, 0xc4, 0xe1,
0xd2, 0x2a, 0xca, 0x6d, 0x8b, 0x21, 0xbe, 0x18, 0xbc, 0xc7, 0xb1, 0xab, 0x56, 0x9e, 0x13, 0x82, 0x8c, 0x79, 0xc1, 0x85, 0x73, 0x4e, 0x48, 0x2b, 0x2f, 0xa6, 0x35, 0x7d, 0x7c, 0x35, 0xbc, 0xc4,
0x9e, 0xc0, 0xb2, 0xd8, 0x10, 0x27, 0x24, 0xc6, 0x97, 0xb9, 0x2d, 0x25, 0xb9, 0x65, 0x29, 0xc4, 0x91, 0x2d, 0x47, 0x5e, 0x11, 0x82, 0x9e, 0xc3, 0x2a, 0x9f, 0x10, 0xc5, 0x24, 0xc2, 0xd7, 0x99,
0x17, 0x47, 0x72, 0x31, 0xb3, 0x69, 0x0d, 0xcc, 0xf4, 0x14, 0x41, 0x5d, 0x90, 0x54, 0xd0, 0xea, 0x29, 0x05, 0x31, 0x65, 0xc5, 0xc7, 0x57, 0x03, 0x31, 0x98, 0x9a, 0xb4, 0x01, 0x7a, 0xb2, 0x0a,
0x82, 0xf1, 0x35, 0x58, 0x19, 0x59, 0x11, 0x78, 0x59, 0x72, 0xcc, 0x54, 0x6e, 0x2b, 0xe4, 0xc8, 0xa7, 0x16, 0x05, 0x15, 0x94, 0x3a, 0x67, 0xfc, 0x13, 0x8c, 0x94, 0x2c, 0x0f, 0xbc, 0x24, 0x38,
0x81, 0x86, 0x60, 0x85, 0x41, 0x44, 0x12, 0x29, 0x54, 0x91, 0xa4, 0x7a, 0x88, 0x2f, 0xf6, 0x05, 0x7a, 0x22, 0xb7, 0xeb, 0x33, 0x64, 0x41, 0x9d, 0xb3, 0x7c, 0x2f, 0x20, 0xb1, 0x10, 0x2a, 0x0b,
0x26, 0x94, 0xd6, 0xc1, 0x16, 0x39, 0xf3, 0xe8, 0x84, 0x7b, 0xa3, 0x73, 0x1c, 0x45, 0x64, 0xdc, 0x52, 0xcd, 0xc7, 0x57, 0x47, 0x1c, 0xe3, 0x4a, 0x9b, 0x60, 0xf2, 0x9c, 0x39, 0xe1, 0x8c, 0x39,
0xaa, 0xae, 0x19, 0xeb, 0x25, 0xd7, 0x1a, 0xab, 0x0c, 0x75, 0x15, 0x8a, 0x36, 0x60, 0x91, 0xbd, 0xe3, 0x09, 0x0e, 0x02, 0x32, 0x6d, 0x55, 0x36, 0xb4, 0xcd, 0x82, 0x6d, 0x4c, 0x65, 0x86, 0xba,
0x27, 0x24, 0xf6, 0x46, 0x34, 0x3a, 0xf5, 0x38, 0x4e, 0xce, 0x08, 0x6f, 0xd5, 0xd6, 0x8c, 0xf5, 0x12, 0x45, 0x5b, 0xd0, 0xa4, 0x97, 0x84, 0x44, 0xce, 0x38, 0x0c, 0xce, 0x1d, 0x86, 0xe3, 0x0b,
0x05, 0xb7, 0x29, 0x17, 0xba, 0x34, 0x3a, 0x1d, 0x4a, 0x18, 0x3d, 0x85, 0x55, 0x19, 0x7d, 0x3c, 0xc2, 0x5a, 0xd5, 0x0d, 0x6d, 0xb3, 0x68, 0x37, 0xc4, 0x40, 0x37, 0x0c, 0xce, 0x47, 0x02, 0x46,
0x39, 0x19, 0x07, 0x23, 0x99, 0x7b, 0xcf, 0x27, 0xd8, 0x1f, 0x07, 0x11, 0x69, 0x81, 0x94, 0x5f, 0x2f, 0x60, 0x5d, 0x44, 0x1f, 0xcd, 0xce, 0xa6, 0xde, 0x58, 0xe4, 0xde, 0x71, 0x09, 0x76, 0xa7,
0x11, 0x84, 0xa3, 0xd9, 0xfa, 0xb6, 0x5e, 0x76, 0xfe, 0x32, 0xa0, 0x21, 0x8a, 0xd3, 0x8f, 0x6e, 0x5e, 0x40, 0x5a, 0x20, 0xe4, 0xd7, 0x38, 0x61, 0xb0, 0x18, 0xdf, 0x53, 0xc3, 0xd6, 0xaf, 0x1a,
0xae, 0xcd, 0xd5, 0x0c, 0x15, 0xe6, 0x32, 0x34, 0x77, 0xf7, 0xe2, 0xfc, 0xdd, 0x57, 0xa1, 0x3a, 0xd4, 0x79, 0x71, 0xfa, 0xc1, 0xdd, 0xb5, 0xb9, 0x99, 0xa1, 0xdc, 0xad, 0x0c, 0xdd, 0xda, 0x7b,
0xc6, 0x8c, 0x7b, 0xe7, 0x34, 0x96, 0xe5, 0x30, 0xdd, 0x8a, 0xf8, 0xde, 0xa1, 0x31, 0xfa, 0x0a, 0xfe, 0xf6, 0xde, 0xd7, 0xa1, 0x32, 0xc5, 0x94, 0x39, 0x93, 0x30, 0x12, 0xe5, 0xd0, 0xed, 0x32,
0x1a, 0xe4, 0x82, 0x93, 0x24, 0xc2, 0x63, 0xef, 0x9c, 0x8f, 0x47, 0xb2, 0x06, 0x55, 0xd7, 0x9c, 0xff, 0xde, 0x0f, 0x23, 0xf4, 0x0f, 0xa8, 0x93, 0x2b, 0x46, 0xe2, 0x00, 0x4f, 0x9d, 0x09, 0x9b,
0x82, 0x3b, 0x7c, 0x3c, 0x12, 0xb9, 0x13, 0x6b, 0xb9, 0x84, 0x94, 0x65, 0x42, 0x2c, 0x81, 0xcf, 0x8e, 0x45, 0x0d, 0x2a, 0xb6, 0x3e, 0x07, 0xf7, 0xd9, 0x74, 0xcc, 0x73, 0xc7, 0xc7, 0x32, 0x09,
0xf2, 0xe1, 0xbc, 0x01, 0x53, 0x36, 0x06, 0x61, 0x31, 0x8d, 0x18, 0x41, 0x08, 0x0a, 0x81, 0x2f, 0x29, 0x89, 0x84, 0x18, 0x1c, 0x5f, 0xe4, 0xc3, 0xfa, 0x45, 0x03, 0x5d, 0x74, 0x06, 0xa1, 0x51,
0x2f, 0x54, 0x7b, 0x56, 0x68, 0x19, 0x6e, 0x21, 0xf0, 0x45, 0x34, 0x81, 0xef, 0x9d, 0x5c, 0x72, 0x18, 0x50, 0x82, 0x10, 0xe4, 0x3c, 0x57, 0xec, 0xa8, 0xfa, 0x32, 0xd7, 0xd2, 0xec, 0x9c, 0xe7,
0xc2, 0x64, 0xb0, 0xa6, 0x5b, 0x09, 0xfc, 0x67, 0xe2, 0x13, 0xdd, 0x07, 0x53, 0x1e, 0x84, 0x7d, 0xf2, 0x70, 0x3c, 0xd7, 0x39, 0xbb, 0x66, 0x84, 0x8a, 0x68, 0x75, 0xbb, 0xec, 0xb9, 0x2f, 0xf9,
0x3f, 0x21, 0x8c, 0xe9, 0x96, 0xac, 0x0b, 0x6c, 0x4b, 0x41, 0x8e, 0x0d, 0xd6, 0x3e, 0x8d, 0x02, 0x27, 0x7a, 0x02, 0xba, 0x58, 0x09, 0xbb, 0x6e, 0x4c, 0x28, 0x95, 0x3d, 0x29, 0x26, 0xd6, 0x38,
0x4e, 0x13, 0x9d, 0x35, 0xe7, 0xbf, 0x02, 0x80, 0x38, 0x74, 0xc0, 0x31, 0x9f, 0xb0, 0x6b, 0x1b, 0xbe, 0x2b, 0x61, 0xb4, 0x0d, 0x2b, 0x69, 0x9a, 0x13, 0x44, 0x3b, 0x97, 0x74, 0x22, 0xf6, 0x56,
0x5c, 0x04, 0x51, 0xb8, 0x31, 0x88, 0x7a, 0x3e, 0x88, 0x07, 0x50, 0xe2, 0x97, 0xb1, 0x4a, 0xa4, 0xb5, 0x9b, 0x29, 0xe6, 0xb1, 0x18, 0x40, 0xff, 0x01, 0x94, 0xe1, 0x4b, 0x7a, 0x51, 0xd0, 0xcd,
0xb5, 0xb9, 0xf8, 0x48, 0x8f, 0xda, 0x23, 0x71, 0xc6, 0xf0, 0x32, 0x26, 0xae, 0x5c, 0x46, 0xeb, 0x14, 0x7d, 0xc0, 0x71, 0xcb, 0x04, 0xe3, 0x28, 0x0c, 0x3c, 0x16, 0xc6, 0xaa, 0x30, 0xd6, 0xef,
0xb0, 0xc0, 0x38, 0xe6, 0xaa, 0xc1, 0xad, 0x4d, 0x94, 0xe3, 0x89, 0x58, 0x88, 0xab, 0x08, 0xe8, 0x79, 0x00, 0xbe, 0xad, 0x21, 0xc3, 0x6c, 0x46, 0x97, 0x9e, 0x21, 0xbe, 0xcd, 0xdc, 0x9d, 0xdb,
0x5b, 0x68, 0x06, 0x51, 0xc0, 0x03, 0xd5, 0x1e, 0x3c, 0x08, 0xa7, 0x9d, 0x6e, 0xcd, 0xe0, 0x61, 0xac, 0xdd, 0xdc, 0x66, 0x81, 0x5d, 0x47, 0xb2, 0x56, 0xc6, 0x4e, 0x73, 0x5b, 0x9d, 0xe6, 0x6d,
0x10, 0xaa, 0x1e, 0x15, 0x75, 0x9a, 0xc4, 0x3e, 0xe6, 0x44, 0x31, 0x55, 0xbf, 0x5b, 0x02, 0x3f, 0xbe, 0xc6, 0xe8, 0x3a, 0x22, 0xb6, 0x18, 0x46, 0x9b, 0x50, 0xa4, 0x0c, 0x33, 0x79, 0x86, 0x8c,
0x96, 0xb0, 0x64, 0x5e, 0x4d, 0x54, 0x65, 0x2e, 0x51, 0xe8, 0x1e, 0xd4, 0x47, 0x94, 0x71, 0x8f, 0x1d, 0x94, 0xe1, 0xf1, 0x58, 0x88, 0x2d, 0x09, 0xe8, 0xdf, 0xd0, 0xf0, 0x02, 0x8f, 0x79, 0xb2,
0x91, 0xe4, 0x1d, 0x49, 0x64, 0xaf, 0x17, 0x5d, 0x10, 0xd0, 0x40, 0x22, 0x42, 0x43, 0x12, 0x68, 0x03, 0x99, 0xe7, 0xcf, 0x0f, 0x93, 0xb1, 0x80, 0x47, 0x9e, 0x2f, 0x8f, 0x01, 0x6f, 0x85, 0x59,
0x34, 0x3a, 0xc7, 0x41, 0x24, 0x5b, 0xbc, 0xe8, 0xca, 0x4d, 0x87, 0x0a, 0x12, 0xdd, 0xa1, 0x28, 0xe4, 0x62, 0x46, 0x24, 0x53, 0x1e, 0x29, 0x83, 0xe3, 0xa7, 0x02, 0x16, 0xcc, 0x9b, 0xa5, 0x28,
0xa7, 0xa7, 0x8a, 0x03, 0x6a, 0xfa, 0x24, 0x47, 0x63, 0x0e, 0x02, 0x7b, 0x2f, 0x60, 0x5c, 0x5c, 0x2f, 0x2f, 0xc5, 0xf2, 0xd4, 0xea, 0xcb, 0x53, 0x7b, 0x57, 0xe1, 0xea, 0x77, 0x15, 0xee, 0x11,
0x9b, 0x4d, 0x6b, 0xf2, 0x23, 0x2c, 0x66, 0x30, 0xdd, 0x0c, 0x0f, 0x61, 0x41, 0x34, 0x32, 0x6b, 0xd4, 0xc6, 0x21, 0x65, 0x0e, 0x25, 0xf1, 0x07, 0x12, 0x8b, 0x03, 0x9b, 0xb7, 0x81, 0x43, 0x43,
0x19, 0x6b, 0xc5, 0xf5, 0xfa, 0xe6, 0xd2, 0x5c, 0xc6, 0x26, 0xcc, 0x55, 0x0c, 0xe7, 0x3e, 0x34, 0x81, 0xa0, 0xc7, 0xa0, 0x0b, 0x42, 0x18, 0x8c, 0x27, 0xd8, 0x0b, 0xc4, 0x39, 0xcd, 0xdb, 0x62,
0x05, 0xd8, 0x8f, 0x4e, 0xe9, 0x74, 0x38, 0xac, 0xb4, 0x95, 0x4c, 0x51, 0x41, 0xc7, 0x02, 0x73, 0xd2, 0x89, 0x84, 0x78, 0x8b, 0x4b, 0xca, 0xf9, 0xb9, 0xe4, 0x80, 0xb4, 0x10, 0xc1, 0x51, 0x98,
0x48, 0x92, 0x30, 0x3d, 0xf2, 0x23, 0x34, 0xf4, 0xb7, 0x3e, 0xee, 0x1b, 0x68, 0x86, 0x41, 0xa4, 0x85, 0xc0, 0x3c, 0xf4, 0x28, 0xe3, 0x89, 0xa5, 0xf3, 0xaa, 0x7f, 0x05, 0xcd, 0x14, 0xa6, 0x1a,
0x66, 0x07, 0x87, 0x74, 0x12, 0x71, 0x9d, 0xf6, 0x46, 0x18, 0x44, 0x42, 0x7d, 0x4b, 0x82, 0x92, 0xfa, 0x29, 0x14, 0xf9, 0x69, 0xa4, 0x2d, 0x6d, 0x23, 0xbf, 0x59, 0xdb, 0x59, 0xb9, 0x55, 0x93,
0x37, 0x9d, 0x31, 0xcd, 0x2b, 0x6b, 0x9e, 0x1a, 0x33, 0xc5, 0xdb, 0x2d, 0x55, 0x0d, 0xbb, 0xb0, 0x19, 0xb5, 0x25, 0xc3, 0x7a, 0x0c, 0x0d, 0x0e, 0xf6, 0x83, 0xf3, 0x70, 0x7e, 0xc2, 0x8d, 0xe4,
0x5b, 0xaa, 0x16, 0xec, 0xe2, 0x6e, 0xa9, 0x5a, 0xb4, 0x4b, 0xbb, 0xa5, 0x6a, 0xc9, 0x5e, 0xd8, 0x38, 0xe8, 0xbc, 0x47, 0x2c, 0x03, 0xf4, 0x11, 0x89, 0xfd, 0x64, 0xc9, 0x4f, 0x50, 0x57, 0xdf,
0x2d, 0x55, 0x2b, 0x76, 0xd5, 0xf9, 0xdd, 0x00, 0xf3, 0xa7, 0x09, 0xe5, 0xe4, 0xe6, 0x61, 0x96, 0x6a, 0xb9, 0x7f, 0x41, 0xc3, 0xf7, 0x02, 0x69, 0x00, 0xd8, 0x0f, 0x67, 0x01, 0x53, 0x85, 0xad,
0x15, 0x99, 0x4d, 0x50, 0x41, 0x4e, 0x10, 0x8c, 0x66, 0x6e, 0x32, 0x37, 0x8c, 0xc5, 0x6b, 0x86, 0xfb, 0x5e, 0xc0, 0xd5, 0x77, 0x05, 0x28, 0x78, 0x73, 0xa3, 0x50, 0xbc, 0x92, 0xe2, 0x49, 0xaf,
0xf1, 0x93, 0x96, 0x53, 0xfa, 0xb4, 0xe5, 0xfc, 0x61, 0x40, 0x43, 0x07, 0xa9, 0x93, 0xb4, 0x0a, 0x90, 0xbc, 0x83, 0x42, 0x45, 0x33, 0x73, 0x07, 0x85, 0x4a, 0xce, 0xcc, 0x1f, 0x14, 0x2a, 0x79,
0xd5, 0xd4, 0x5c, 0x54, 0xa8, 0x15, 0xa6, 0x9d, 0xe5, 0x2e, 0x40, 0xc6, 0x77, 0x95, 0xf3, 0xd4, 0xb3, 0x70, 0x50, 0xa8, 0x14, 0xcc, 0xe2, 0x41, 0xa1, 0x52, 0x36, 0x2b, 0xd6, 0x8f, 0x1a, 0xe8,
0xe2, 0xd4, 0x74, 0xbf, 0x80, 0xda, 0x55, 0xd3, 0xa9, 0x86, 0x53, 0xc7, 0x91, 0x1e, 0x2a, 0x82, 0x5f, 0xcf, 0x42, 0x46, 0xee, 0x76, 0x24, 0x51, 0x91, 0x85, 0x0d, 0xe4, 0x84, 0x0d, 0xc0, 0x78,
0xc4, 0x97, 0x21, 0x89, 0xb8, 0x27, 0x1f, 0x18, 0x65, 0x3d, 0x4d, 0x19, 0x9c, 0xc2, 0xb7, 0x45, 0x61, 0x89, 0xb7, 0x1c, 0x25, 0xbf, 0xc4, 0x51, 0x3e, 0xeb, 0x9b, 0x85, 0xcf, 0xfb, 0xe6, 0x4f,
0xa2, 0xee, 0x02, 0x8c, 0xc6, 0xfc, 0x9d, 0xe7, 0x93, 0x31, 0xc7, 0xb2, 0x44, 0x0b, 0x6e, 0x4d, 0x1a, 0xd4, 0x55, 0x90, 0x2a, 0x49, 0xeb, 0x50, 0x49, 0x1c, 0x52, 0x86, 0x5a, 0xa6, 0xca, 0x1e,
0x20, 0xdb, 0x02, 0x70, 0x9a, 0xd0, 0x18, 0xd2, 0x9f, 0x49, 0x94, 0x16, 0xfa, 0x07, 0xb0, 0xa6, 0x1f, 0x02, 0xa4, 0x2e, 0x0f, 0x69, 0x9f, 0xd5, 0x28, 0xb9, 0x39, 0xfe, 0x06, 0xd5, 0x9b, 0xce,
0x80, 0xbe, 0xc4, 0x06, 0x94, 0xb9, 0x44, 0x74, 0x67, 0xcd, 0x66, 0x71, 0x8f, 0x61, 0x2e, 0xc9, 0x59, 0xf1, 0xe7, 0xb6, 0x29, 0x2e, 0x02, 0x1e, 0x24, 0xbe, 0xf6, 0x49, 0xc0, 0x1c, 0x71, 0x4b,
0xae, 0x66, 0x38, 0x7f, 0x16, 0xa0, 0x96, 0xa2, 0x22, 0xe3, 0x27, 0x98, 0x11, 0x2f, 0xc4, 0x23, 0x4a, 0xff, 0x6c, 0x88, 0xe0, 0x24, 0xbe, 0xc7, 0x13, 0xf5, 0x10, 0x60, 0x3c, 0x65, 0x1f, 0x1c,
0x9c, 0x50, 0x1a, 0xe9, 0xfe, 0x32, 0x05, 0xb8, 0xaf, 0x31, 0x31, 0x28, 0xd3, 0x7b, 0x9c, 0x63, 0x97, 0x4c, 0x19, 0x16, 0x25, 0x2a, 0xda, 0x55, 0x8e, 0xec, 0x71, 0xc0, 0x6a, 0x40, 0x7d, 0x14,
0x76, 0x2e, 0x53, 0x61, 0xba, 0x75, 0x8d, 0xed, 0x60, 0x76, 0x8e, 0x1e, 0x82, 0x3d, 0xa5, 0xc4, 0x7e, 0x4b, 0x82, 0xa4, 0xd0, 0xff, 0x07, 0x63, 0x0e, 0xa8, 0x4d, 0x6c, 0x41, 0x89, 0x09, 0x44,
0x09, 0x09, 0x42, 0x7c, 0x46, 0xb4, 0xb7, 0x35, 0x35, 0x7e, 0xa4, 0x61, 0x31, 0xe4, 0xaa, 0xcb, 0x75, 0xd6, 0xe2, 0xb4, 0x1f, 0x52, 0xcc, 0x04, 0xd9, 0x56, 0x0c, 0xeb, 0xe7, 0x1c, 0x54, 0x13,
0xbc, 0x18, 0x07, 0xbe, 0x17, 0x32, 0xcc, 0xf5, 0x1b, 0x69, 0x29, 0xfc, 0x08, 0x07, 0xfe, 0x3e, 0x94, 0x67, 0xfc, 0x0c, 0x53, 0xe2, 0xf8, 0x78, 0x8c, 0xe3, 0x30, 0x0c, 0x54, 0x7f, 0xe9, 0x1c,
0xc3, 0x1c, 0x3d, 0x86, 0x3b, 0x99, 0x87, 0x34, 0x43, 0x57, 0x6d, 0x8c, 0x92, 0xf4, 0x25, 0x4d, 0x3c, 0x52, 0x18, 0x3f, 0x28, 0xf3, 0x7d, 0x4c, 0x30, 0x9d, 0x88, 0x54, 0xe8, 0x76, 0x4d, 0x61,
0xb7, 0xdc, 0x07, 0x53, 0xb8, 0x86, 0x37, 0x4a, 0x08, 0xe6, 0xc4, 0xd7, 0x8d, 0x5c, 0x17, 0x58, 0xfb, 0x98, 0x4e, 0xd0, 0x53, 0x30, 0xe7, 0x94, 0x28, 0x26, 0x9e, 0x8f, 0x2f, 0x88, 0xf2, 0xe7,
0x57, 0x41, 0xa8, 0x05, 0x15, 0x72, 0x11, 0x07, 0x09, 0xf1, 0xa5, 0x6b, 0x54, 0xdd, 0xe9, 0xa7, 0x86, 0xc2, 0x07, 0x0a, 0xe6, 0x36, 0x22, 0xbb, 0xcc, 0x89, 0xb0, 0xe7, 0x3a, 0x3e, 0xc5, 0x4c,
0xd8, 0xcc, 0x38, 0x4d, 0xf0, 0x19, 0xf1, 0x22, 0x1c, 0x12, 0x69, 0x19, 0x35, 0xb7, 0xae, 0xb1, 0x5d, 0xf4, 0x86, 0xc4, 0x07, 0xd8, 0x73, 0x8f, 0x28, 0x66, 0xe8, 0x19, 0x3c, 0x48, 0xbd, 0x06,
0x03, 0x1c, 0x92, 0x8d, 0x07, 0x50, 0x9d, 0xda, 0x20, 0x32, 0xa1, 0xba, 0x77, 0x78, 0x78, 0xe4, 0x52, 0x74, 0xd9, 0xc6, 0x28, 0x4e, 0x9e, 0x03, 0xc9, 0x94, 0xc7, 0xa0, 0x73, 0x5f, 0x72, 0xc6,
0x1d, 0x1e, 0x0f, 0xed, 0x5b, 0xa8, 0x0e, 0x15, 0xf9, 0xd5, 0x3f, 0xb0, 0x8d, 0x0d, 0x06, 0xb5, 0x31, 0xc1, 0x8c, 0xb8, 0xaa, 0x91, 0x6b, 0x1c, 0xeb, 0x4a, 0x08, 0xb5, 0xa0, 0x4c, 0xae, 0x22,
0xd4, 0x05, 0x51, 0x03, 0x6a, 0xfd, 0x83, 0xfe, 0xb0, 0xbf, 0x35, 0xec, 0x6d, 0xdb, 0xb7, 0xd0, 0x2f, 0x26, 0xae, 0xf0, 0xa5, 0x8a, 0x3d, 0xff, 0xe4, 0x93, 0x29, 0x0b, 0x63, 0x7c, 0x41, 0x9c,
0x1d, 0x58, 0x3c, 0x72, 0x7b, 0xfd, 0xfd, 0xad, 0x17, 0x3d, 0xcf, 0xed, 0xbd, 0xec, 0x6d, 0xed, 0x00, 0xfb, 0x44, 0x58, 0x46, 0xd5, 0xae, 0x29, 0xec, 0x18, 0xfb, 0x64, 0xeb, 0x09, 0x54, 0xe6,
0xf5, 0xb6, 0x6d, 0x03, 0x21, 0xb0, 0x76, 0x86, 0x7b, 0x5d, 0xef, 0xe8, 0xf8, 0xd9, 0x5e, 0x7f, 0x46, 0x8b, 0x74, 0xa8, 0x1c, 0x9e, 0x9c, 0x0c, 0x9c, 0x93, 0xd3, 0x91, 0x79, 0x0f, 0xd5, 0xa0,
0xb0, 0xd3, 0xdb, 0xb6, 0x0b, 0x42, 0x73, 0x70, 0xdc, 0xed, 0xf6, 0x06, 0x03, 0xbb, 0x88, 0x00, 0x2c, 0xbe, 0xfa, 0xc7, 0xa6, 0xb6, 0x45, 0xa1, 0x9a, 0xf8, 0x2c, 0xaa, 0x43, 0xb5, 0x7f, 0xdc,
0xca, 0xcf, 0xb7, 0xfa, 0x82, 0x5c, 0x42, 0x4b, 0xd0, 0xec, 0x1f, 0xbc, 0x3c, 0xec, 0x77, 0x7b, 0x1f, 0xf5, 0x77, 0x47, 0xbd, 0x3d, 0xf3, 0x1e, 0x7a, 0x00, 0xcd, 0x81, 0xdd, 0xeb, 0x1f, 0xed,
0xde, 0xa0, 0x37, 0x1c, 0x0a, 0x70, 0x61, 0xf3, 0xdf, 0xb2, 0x7a, 0x07, 0xba, 0xf2, 0x87, 0x12, 0xbe, 0xee, 0x39, 0x76, 0xef, 0x4d, 0x6f, 0xf7, 0xb0, 0xb7, 0x67, 0x6a, 0x08, 0x81, 0xb1, 0x3f,
0x72, 0xa1, 0xa2, 0x7f, 0xfa, 0xa0, 0x95, 0x59, 0x3f, 0xe4, 0x7e, 0x0c, 0xb5, 0xef, 0xe4, 0x2c, 0x3a, 0xec, 0x3a, 0x83, 0xd3, 0x97, 0x87, 0xfd, 0xe1, 0x7e, 0x6f, 0xcf, 0xcc, 0x71, 0xcd, 0xe1,
0x68, 0xda, 0x4f, 0xce, 0xca, 0x2f, 0x7f, 0xff, 0xf3, 0x6b, 0x61, 0xd1, 0x31, 0x3b, 0xef, 0x1e, 0x69, 0xb7, 0xdb, 0x1b, 0x0e, 0xcd, 0x3c, 0x02, 0x28, 0xbd, 0xda, 0xed, 0x73, 0x72, 0x01, 0xad,
0x77, 0x04, 0xa3, 0x43, 0x27, 0xfc, 0xa9, 0xb1, 0x81, 0x0e, 0xa1, 0xac, 0x5e, 0x6c, 0xb4, 0x9c, 0x40, 0xa3, 0x7f, 0xfc, 0xe6, 0xa4, 0xdf, 0xed, 0x39, 0xc3, 0xde, 0x68, 0xc4, 0xc1, 0xe2, 0xce,
0x93, 0x4c, 0x9f, 0xf0, 0x9b, 0x14, 0x97, 0xa5, 0xa2, 0xed, 0xd4, 0x53, 0xc5, 0x20, 0x12, 0x82, 0x9f, 0x25, 0x79, 0xd3, 0x74, 0xc5, 0x6b, 0x0f, 0xd9, 0x50, 0x56, 0xef, 0x37, 0xb4, 0xb6, 0xe8,
0xdf, 0x43, 0x45, 0xbf, 0x66, 0x99, 0x20, 0xf3, 0xef, 0x5b, 0xfb, 0x3a, 0x9f, 0xfc, 0xce, 0x40, 0x87, 0xcc, 0x8b, 0xae, 0xfd, 0x20, 0x63, 0x41, 0xf3, 0x7e, 0xb2, 0xd6, 0xbe, 0xfb, 0xed, 0x8f,
0xaf, 0xa1, 0x96, 0x5a, 0x2c, 0x5a, 0x9d, 0x85, 0x73, 0xc5, 0x8a, 0xdb, 0xed, 0xeb, 0x96, 0xf2, 0xef, 0x73, 0x4d, 0x4b, 0xef, 0x7c, 0x78, 0xd6, 0xe1, 0x8c, 0x4e, 0x38, 0x63, 0x2f, 0xb4, 0x2d,
0x61, 0x21, 0x2b, 0x0d, 0x4b, 0xda, 0x2f, 0x3a, 0x56, 0x65, 0x16, 0xf6, 0x8b, 0x5a, 0xb9, 0xe3, 0x74, 0x02, 0x25, 0xf9, 0xec, 0x40, 0xab, 0x19, 0xc9, 0xe4, 0x1d, 0x72, 0x97, 0xe2, 0xaa, 0x50,
0x33, 0x8e, 0x7c, 0x6d, 0x60, 0x4e, 0x5b, 0x4a, 0xde, 0x46, 0x28, 0x27, 0xd9, 0xf9, 0x10, 0xf8, 0x34, 0xad, 0x5a, 0xa2, 0xe8, 0x05, 0x5c, 0xf0, 0x7f, 0x50, 0x56, 0xf7, 0x65, 0x2a, 0xc8, 0xec,
0x1f, 0xd1, 0x2b, 0x30, 0x75, 0x01, 0xa4, 0x53, 0xa3, 0x59, 0xb2, 0xb2, 0x4e, 0xde, 0x5e, 0xbe, 0x0d, 0xda, 0x5e, 0xe6, 0x93, 0xff, 0xd5, 0xd0, 0x3b, 0xa8, 0x26, 0x16, 0x8b, 0xd6, 0x17, 0xe1,
0x0a, 0xeb, 0x68, 0xe7, 0xa5, 0xe9, 0x84, 0x77, 0xb8, 0x94, 0xf2, 0x52, 0x69, 0xe9, 0x6f, 0x19, 0xdc, 0xb0, 0xe2, 0x76, 0x7b, 0xd9, 0x50, 0x36, 0x2c, 0x64, 0x24, 0x61, 0x09, 0xfb, 0x45, 0xa7,
0xe9, 0xac, 0x29, 0x67, 0xa4, 0x73, 0x36, 0xe8, 0xac, 0x49, 0xe9, 0x36, 0x6a, 0xe5, 0xa4, 0xdf, 0xb2, 0xcc, 0xdc, 0x7e, 0x51, 0x2b, 0xb3, 0x7c, 0xca, 0x91, 0x97, 0x06, 0x66, 0xb5, 0x85, 0xe4,
0x0a, 0x4e, 0xe7, 0x03, 0x0e, 0xf9, 0x47, 0xf4, 0x1a, 0xac, 0x17, 0x84, 0xab, 0x62, 0x7f, 0x56, 0x7d, 0x84, 0x32, 0x92, 0x9d, 0x8f, 0x9e, 0xfb, 0x09, 0xbd, 0x05, 0x5d, 0x15, 0x40, 0x38, 0x35,
0xf4, 0xab, 0xf2, 0x88, 0x25, 0xb4, 0x98, 0x69, 0x01, 0x1d, 0xfc, 0x9b, 0x8c, 0xf6, 0x67, 0x85, 0x5a, 0x24, 0x2b, 0xed, 0xe4, 0xed, 0xd5, 0x9b, 0xb0, 0x8a, 0xf6, 0xb6, 0x74, 0x38, 0x63, 0x1d,
0x7f, 0x4f, 0x6a, 0xaf, 0xa2, 0x95, 0xac, 0x76, 0x36, 0xfa, 0x57, 0xd0, 0x10, 0x27, 0x4c, 0x7d, 0x26, 0xa4, 0x9c, 0x44, 0x5a, 0xf8, 0x5b, 0x4a, 0x3a, 0x6d, 0xca, 0x29, 0xe9, 0x8c, 0x0d, 0x5a,
0x8f, 0x65, 0xfa, 0x37, 0x67, 0xae, 0xed, 0x95, 0x39, 0x3c, 0x3f, 0x13, 0xa8, 0x29, 0x8f, 0x60, 0x1b, 0x42, 0xba, 0x8d, 0x5a, 0x19, 0xe9, 0xf7, 0x9c, 0xd3, 0xf9, 0x88, 0x7d, 0xf6, 0x09, 0xbd,
0x98, 0x77, 0x94, 0xa1, 0x9e, 0x94, 0xe5, 0xbf, 0x1a, 0x4f, 0xfe, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x03, 0xe3, 0x35, 0x61, 0xb2, 0xd8, 0x5f, 0x14, 0xfd, 0xba, 0x58, 0x62, 0x05, 0x35, 0x53, 0x2d,
0xc7, 0x1e, 0x66, 0x37, 0xa1, 0x0c, 0x00, 0x00, 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. // Reference imports to suppress errors if they are not otherwise used.

@ -242,9 +242,28 @@ message SwapResponse {
bytes id_bytes = 3; 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 { message MonitorRequest {
@ -292,9 +311,21 @@ message SwapStatus {
int64 last_update_time = 6; 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 /// Swap server cost
int64 cost_server = 8; int64 cost_server = 8;

@ -457,7 +457,15 @@
}, },
"htlc_address": { "htlc_address": {
"type": "string", "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": { "htlc_address": {
"type": "string", "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": { "cost_server": {
"type": "string", "type": "string",

@ -35,16 +35,22 @@ const (
ProtocolVersion_LEGACY ProtocolVersion = 0 ProtocolVersion_LEGACY ProtocolVersion = 0
/// Client may attempt to send the loop out payment in multiple parts. /// Client may attempt to send the loop out payment in multiple parts.
ProtocolVersion_MULTI_LOOP_OUT ProtocolVersion = 1 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{ var ProtocolVersion_name = map[int32]string{
0: "LEGACY", 0: "LEGACY",
1: "MULTI_LOOP_OUT", 1: "MULTI_LOOP_OUT",
2: "NATIVE_SEGWIT_LOOP_IN",
} }
var ProtocolVersion_value = map[string]int32{ var ProtocolVersion_value = map[string]int32{
"LEGACY": 0, "LEGACY": 0,
"MULTI_LOOP_OUT": 1, "MULTI_LOOP_OUT": 1,
"NATIVE_SEGWIT_LOOP_IN": 2,
} }
func (x ProtocolVersion) String() string { func (x ProtocolVersion) String() string {
@ -784,57 +790,58 @@ func init() {
func init() { proto.RegisterFile("server.proto", fileDescriptor_ad098daeda4239f7) } func init() { proto.RegisterFile("server.proto", fileDescriptor_ad098daeda4239f7) }
var fileDescriptor_ad098daeda4239f7 = []byte{ var fileDescriptor_ad098daeda4239f7 = []byte{
// 786 bytes of a gzipped FileDescriptorProto // 810 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xdd, 0x52, 0xda, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xdd, 0x52, 0xe2, 0x48,
0x14, 0x6e, 0x02, 0x82, 0x1c, 0xf9, 0x73, 0xfb, 0x17, 0x50, 0x3a, 0xc8, 0x4c, 0x1d, 0xc6, 0x0b, 0x14, 0xde, 0x04, 0x04, 0x39, 0xf2, 0x67, 0xef, 0xba, 0x1b, 0x50, 0xb6, 0x90, 0xaa, 0xb5, 0x28,
0x9d, 0xda, 0xbb, 0xde, 0x59, 0xad, 0x95, 0x29, 0x2d, 0x1a, 0xb1, 0x33, 0xbd, 0x4a, 0x57, 0x38, 0x2f, 0xb4, 0xca, 0xbd, 0xdb, 0x3b, 0xd6, 0x5f, 0x6a, 0x59, 0xd1, 0x88, 0x6e, 0xed, 0x55, 0xa6,
0x95, 0x4c, 0x43, 0x36, 0x26, 0x0b, 0xca, 0x9b, 0xb4, 0x2f, 0xd1, 0xb7, 0xe9, 0x2b, 0x74, 0xa6, 0x85, 0x1e, 0x49, 0x4d, 0x48, 0xc7, 0xa4, 0x41, 0x79, 0x93, 0x99, 0x97, 0x98, 0xb7, 0x99, 0x57,
0x97, 0x7d, 0x83, 0x4e, 0x36, 0x89, 0x24, 0x21, 0xa8, 0xcc, 0x78, 0x67, 0xce, 0x7e, 0x9e, 0xfd, 0x98, 0xaa, 0xb9, 0x9c, 0x37, 0x98, 0xea, 0xee, 0x44, 0x92, 0x10, 0x54, 0xaa, 0xbc, 0x33, 0xe7,
0xbe, 0xef, 0x9c, 0x6f, 0x81, 0xbc, 0x83, 0xf6, 0x18, 0xed, 0x6d, 0xcb, 0x66, 0x9c, 0x91, 0xac, 0x7c, 0x76, 0x7f, 0xdf, 0x77, 0xce, 0xd7, 0x40, 0xde, 0x23, 0xee, 0x84, 0xb8, 0x7b, 0x8e, 0x4b,
0xc1, 0x98, 0x65, 0x5b, 0xbd, 0xea, 0xfa, 0x05, 0x63, 0x17, 0x06, 0xee, 0x50, 0x4b, 0xdf, 0xa1, 0x19, 0x45, 0x59, 0x8b, 0x52, 0xc7, 0x75, 0xfa, 0xd5, 0xad, 0x3b, 0x4a, 0xef, 0x2c, 0xb2, 0x8f,
0xa6, 0xc9, 0x38, 0xe5, 0x3a, 0x33, 0x1d, 0x0f, 0xd6, 0xf8, 0x2b, 0xc1, 0x93, 0x53, 0xf1, 0x7f, 0x1d, 0x73, 0x1f, 0xdb, 0x36, 0x65, 0x98, 0x99, 0xd4, 0xf6, 0x24, 0xac, 0xf1, 0x4d, 0x81, 0x5f,
0x6d, 0xc6, 0xac, 0xce, 0x88, 0xab, 0x78, 0x39, 0x42, 0x87, 0x93, 0x0d, 0xc8, 0xdb, 0xd8, 0x43, 0xae, 0xc4, 0xff, 0x75, 0x28, 0x75, 0xba, 0x63, 0xa6, 0x93, 0xfb, 0x31, 0xf1, 0x18, 0xda, 0x86,
0x7d, 0x8c, 0xb6, 0xf6, 0x1d, 0x27, 0x8a, 0x54, 0x97, 0x9a, 0x79, 0x75, 0x25, 0xa8, 0x7d, 0xc0, 0xbc, 0x4b, 0xfa, 0xc4, 0x9c, 0x10, 0xd7, 0xf8, 0x40, 0xa6, 0x9a, 0x52, 0x57, 0x9a, 0x79, 0x7d,
0x09, 0x59, 0x83, 0x9c, 0x73, 0x45, 0x2d, 0x6d, 0x40, 0x9d, 0x81, 0x22, 0x8b, 0xf3, 0x65, 0xb7, 0x2d, 0xa8, 0xfd, 0x43, 0xa6, 0x68, 0x13, 0x72, 0xde, 0x03, 0x76, 0x8c, 0x21, 0xf6, 0x86, 0x9a,
0x70, 0x44, 0x9d, 0x01, 0x29, 0x43, 0x8a, 0x0e, 0xb9, 0x92, 0xaa, 0x4b, 0xcd, 0xb4, 0xea, 0xfe, 0x2a, 0xfa, 0xab, 0xbc, 0x70, 0x86, 0xbd, 0x21, 0x2a, 0x43, 0x0a, 0x8f, 0x98, 0x96, 0xaa, 0x2b,
0x49, 0xde, 0x40, 0x45, 0xc0, 0xad, 0xd1, 0xb9, 0xa1, 0xf7, 0x04, 0x0b, 0xad, 0x8f, 0xb4, 0x6f, 0xcd, 0xb4, 0xce, 0xff, 0x44, 0x7f, 0x41, 0x45, 0xc0, 0x9d, 0xf1, 0xad, 0x65, 0xf6, 0x05, 0x0b,
0xe8, 0x26, 0x2a, 0xe9, 0xba, 0xd4, 0x4c, 0xa9, 0xcf, 0x5d, 0xc0, 0xf1, 0xf4, 0xfc, 0xc0, 0x3f, 0x63, 0x40, 0xf0, 0xc0, 0x32, 0x6d, 0xa2, 0xa5, 0xeb, 0x4a, 0x33, 0xa5, 0xff, 0xc6, 0x01, 0x17,
0x26, 0xfb, 0x50, 0x16, 0x7c, 0x7b, 0xcc, 0xd0, 0xc6, 0x68, 0x3b, 0x3a, 0x33, 0x95, 0xa5, 0xba, 0xb3, 0xfe, 0x91, 0xdf, 0x46, 0x87, 0x50, 0x16, 0x7c, 0xfb, 0xd4, 0x32, 0x26, 0xc4, 0xf5, 0x4c,
0xd4, 0x2c, 0xee, 0x2a, 0xdb, 0xbe, 0xd0, 0xed, 0x63, 0x1f, 0xf0, 0xd9, 0x3b, 0x57, 0x4b, 0x56, 0x6a, 0x6b, 0x2b, 0x75, 0xa5, 0x59, 0x3c, 0xd0, 0xf6, 0x7c, 0xa1, 0x7b, 0x17, 0x3e, 0xe0, 0x46,
0xb4, 0xd0, 0xf8, 0x21, 0xc1, 0xd3, 0x98, 0x56, 0xc7, 0x62, 0xa6, 0x83, 0xae, 0x58, 0x41, 0x4d, 0xf6, 0xf5, 0x92, 0x13, 0x2d, 0x34, 0x3e, 0x2a, 0xb0, 0x11, 0xd3, 0xea, 0x39, 0xd4, 0xf6, 0x08,
0x37, 0xc7, 0x4c, 0xef, 0xa1, 0x10, 0x9b, 0x53, 0x57, 0xdc, 0x5a, 0xcb, 0x2b, 0x91, 0x97, 0x50, 0x17, 0x2b, 0xa8, 0x99, 0xf6, 0x84, 0x9a, 0x7d, 0x22, 0xc4, 0xe6, 0xf4, 0x35, 0x5e, 0x6b, 0xcb,
0xb4, 0x6c, 0xb4, 0xe8, 0xe4, 0x06, 0x24, 0x0b, 0x50, 0xc1, 0xab, 0x06, 0xb0, 0x1a, 0x80, 0x83, 0x12, 0xfa, 0x03, 0x8a, 0x8e, 0x4b, 0x1c, 0x3c, 0x7d, 0x02, 0xa9, 0x02, 0x54, 0x90, 0xd5, 0x00,
0x66, 0xdf, 0x37, 0x2d, 0x25, 0x4c, 0xc9, 0x79, 0x15, 0xd7, 0xb2, 0x67, 0x90, 0xc1, 0x6b, 0x4b, 0x56, 0x03, 0xf0, 0x88, 0x3d, 0xf0, 0x4d, 0x4b, 0x09, 0x53, 0x72, 0xb2, 0xc2, 0x2d, 0xfb, 0x15,
0xb7, 0x27, 0x42, 0xf0, 0x92, 0xea, 0x7f, 0x35, 0x7e, 0x49, 0x50, 0x89, 0x50, 0x3b, 0x19, 0x31, 0x32, 0xe4, 0xd1, 0x31, 0xdd, 0xa9, 0x10, 0xbc, 0xa2, 0xfb, 0x5f, 0x8d, 0xcf, 0x0a, 0x54, 0x22,
0x8e, 0xc1, 0x2c, 0x7c, 0x2f, 0xa5, 0x7b, 0x7a, 0x29, 0x2f, 0xee, 0x65, 0x6a, 0x51, 0x2f, 0x7f, 0xd4, 0x2e, 0xc7, 0x94, 0x91, 0x60, 0x16, 0xbe, 0x97, 0xca, 0x2b, 0xbd, 0x54, 0x97, 0xf7, 0x32,
0xca, 0x40, 0x66, 0x09, 0x93, 0x2d, 0x58, 0xf5, 0x78, 0xd1, 0xc9, 0x10, 0x4d, 0xae, 0xf5, 0xd1, 0xb5, 0xac, 0x97, 0x9f, 0x54, 0x40, 0xf3, 0x84, 0xd1, 0x2e, 0xac, 0x4b, 0x5e, 0x78, 0x3a, 0x22,
0xe1, 0xbe, 0x9b, 0x25, 0xc1, 0xc7, 0xab, 0x1f, 0xb8, 0xaa, 0x2a, 0x20, 0xb6, 0x45, 0xfb, 0x86, 0x36, 0x33, 0x06, 0xc4, 0x63, 0xbe, 0x9b, 0x25, 0xc1, 0x47, 0xd6, 0x8f, 0xb8, 0xaa, 0x0a, 0x88,
0x01, 0xe5, 0xac, 0xfb, 0x7d, 0x88, 0x48, 0x36, 0xa1, 0x10, 0x1c, 0x69, 0x36, 0xe5, 0x28, 0xf8, 0x6d, 0x31, 0xde, 0x93, 0x80, 0x72, 0x96, 0x7f, 0x9f, 0x10, 0x82, 0x76, 0xa0, 0x10, 0xb4, 0x0c,
0xa5, 0xde, 0xca, 0x8a, 0xe4, 0x0d, 0xe5, 0x10, 0x51, 0xa5, 0x5c, 0xb8, 0xed, 0x0f, 0xc5, 0xf5, 0x17, 0x33, 0x22, 0xf8, 0xa5, 0xfe, 0x56, 0x35, 0x45, 0x0e, 0xe5, 0x84, 0x10, 0x1d, 0x33, 0xe1,
0x27, 0x2d, 0xfc, 0xc9, 0x79, 0x95, 0xbd, 0x21, 0x27, 0x5b, 0x50, 0x1a, 0xea, 0xa6, 0x26, 0x5a, 0xb6, 0x3f, 0x14, 0xee, 0x4f, 0x5a, 0xf8, 0x93, 0x93, 0x95, 0xd6, 0x88, 0xa1, 0x5d, 0x28, 0x8d,
0xd1, 0x21, 0x1b, 0x99, 0x5c, 0x2c, 0x4d, 0x5a, 0x34, 0x2a, 0x0c, 0x75, 0xf3, 0xf4, 0x8a, 0x5a, 0x4c, 0xdb, 0x10, 0x47, 0xe1, 0x11, 0x1d, 0xdb, 0x4c, 0x2c, 0x4d, 0x5a, 0x1c, 0x54, 0x18, 0x99,
0x7b, 0xe2, 0x40, 0x60, 0xe9, 0x75, 0x04, 0x9b, 0x09, 0x61, 0xe9, 0x75, 0x08, 0x5b, 0x03, 0xe8, 0xf6, 0xd5, 0x03, 0x76, 0x5a, 0xa2, 0x21, 0xb0, 0xf8, 0x31, 0x82, 0xcd, 0x84, 0xb0, 0xf8, 0x31,
0x19, 0x7c, 0xac, 0xf5, 0xd1, 0xe0, 0x54, 0xc9, 0x8a, 0x49, 0xe6, 0xdc, 0xca, 0x81, 0x5b, 0x68, 0x84, 0xad, 0x01, 0xf4, 0x2d, 0x36, 0x31, 0x06, 0xc4, 0x62, 0x58, 0xcb, 0x8a, 0x49, 0xe6, 0x78,
0x7c, 0x8d, 0xcd, 0xb2, 0x8b, 0xf6, 0xd0, 0x09, 0x66, 0x99, 0xe4, 0xbe, 0xb4, 0xa8, 0xfb, 0xfd, 0xe5, 0x88, 0x17, 0x1a, 0xef, 0x62, 0xb3, 0xec, 0x11, 0x77, 0xe4, 0x05, 0xb3, 0x4c, 0x72, 0x5f,
0x98, 0xf9, 0xe2, 0x06, 0xb2, 0x39, 0x2b, 0xd7, 0x5b, 0x99, 0x98, 0xd4, 0xcd, 0x59, 0xa9, 0xb2, 0x59, 0xd6, 0xfd, 0x41, 0xcc, 0x7c, 0x71, 0x03, 0xda, 0x99, 0x97, 0x2b, 0x57, 0x26, 0x26, 0x75,
0x8f, 0x0b, 0xcb, 0x6c, 0xfc, 0x91, 0xe0, 0xf1, 0xf4, 0x9a, 0x96, 0x19, 0x48, 0x88, 0xee, 0xb8, 0x67, 0x5e, 0xaa, 0xea, 0xe3, 0xc2, 0x32, 0x1b, 0x5f, 0x15, 0xf8, 0x79, 0x76, 0x4d, 0xdb, 0x0e,
0x14, 0xdf, 0xf1, 0x05, 0x9f, 0x85, 0x78, 0xf6, 0xd2, 0xb3, 0xd9, 0xab, 0xc0, 0xb2, 0x41, 0x1d, 0x24, 0x44, 0x77, 0x5c, 0x89, 0xef, 0xf8, 0x92, 0xcf, 0x42, 0x3c, 0x7b, 0xe9, 0xf9, 0xec, 0x55,
0xae, 0x0d, 0x98, 0x25, 0x06, 0x98, 0x57, 0xb3, 0xee, 0xf7, 0x11, 0xb3, 0x12, 0xed, 0xcc, 0x2c, 0x60, 0xd5, 0xc2, 0x1e, 0x33, 0x86, 0xd4, 0x11, 0x03, 0xcc, 0xeb, 0x59, 0xfe, 0x7d, 0x46, 0x9d,
0x6a, 0xe7, 0x49, 0xf8, 0x0d, 0x74, 0x75, 0x4e, 0x9f, 0x85, 0xbb, 0xde, 0xc0, 0x69, 0xa0, 0xe5, 0x44, 0x3b, 0x33, 0xcb, 0xda, 0x79, 0x19, 0x7e, 0x03, 0xb9, 0xce, 0xd9, 0xb3, 0xf0, 0xd2, 0x1b,
0x48, 0xa0, 0x2f, 0x41, 0x09, 0xb7, 0xbc, 0x23, 0xce, 0x49, 0x2a, 0xe4, 0x45, 0x55, 0xfc, 0x8e, 0x38, 0x0b, 0xb4, 0x1a, 0x09, 0xf4, 0x3d, 0x68, 0xe1, 0x23, 0x5f, 0x88, 0x73, 0x92, 0x0a, 0x75,
0xbc, 0x21, 0x37, 0x77, 0xfa, 0x5a, 0xc2, 0x69, 0x93, 0xee, 0x48, 0x9b, 0x9c, 0x9c, 0xb6, 0x84, 0x59, 0x15, 0x5f, 0x22, 0x6f, 0xc8, 0xd3, 0x9d, 0xbe, 0x96, 0x70, 0xda, 0x94, 0x17, 0xd2, 0xa6,
0x38, 0xa5, 0x17, 0x88, 0xd3, 0xd2, 0xfd, 0xe2, 0x94, 0x89, 0xc7, 0x49, 0x8b, 0x5a, 0xf9, 0xf0, 0x26, 0xa7, 0x2d, 0x21, 0x4e, 0xe9, 0x25, 0xe2, 0xb4, 0xf2, 0xba, 0x38, 0x65, 0xe2, 0x71, 0x32,
0x69, 0xea, 0xc1, 0xea, 0xcc, 0x05, 0x0f, 0x1d, 0xa6, 0xad, 0x57, 0x50, 0x8a, 0x11, 0x21, 0x00, 0xa2, 0x56, 0xbe, 0x7d, 0x9a, 0xfa, 0xb0, 0x3e, 0x77, 0xc1, 0x5b, 0x87, 0x69, 0xb7, 0x03, 0xa5,
0x99, 0xf6, 0xbb, 0xf7, 0x7b, 0xfb, 0x5f, 0xca, 0x8f, 0x08, 0x81, 0xe2, 0xc7, 0xb3, 0x76, 0xb7, 0x18, 0x11, 0x04, 0x90, 0xe9, 0x1c, 0x9f, 0xb6, 0x0e, 0xff, 0x2f, 0xff, 0x84, 0x10, 0x14, 0xff,
0xa5, 0xb5, 0x3b, 0x9d, 0x63, 0xad, 0x73, 0xd6, 0x2d, 0x4b, 0xbb, 0xff, 0x52, 0x00, 0x6e, 0x07, 0xbd, 0xee, 0xf4, 0xda, 0x46, 0xa7, 0xdb, 0xbd, 0x30, 0xba, 0xd7, 0xbd, 0xb2, 0x82, 0x2a, 0xb0,
0x8f, 0x1c, 0xe9, 0x40, 0x3e, 0x12, 0xf7, 0xc6, 0x8d, 0xc2, 0xb9, 0xaf, 0x4d, 0x75, 0xed, 0x16, 0x71, 0xde, 0xea, 0xb5, 0x6f, 0x8e, 0x8d, 0xab, 0xe3, 0xd3, 0xff, 0xda, 0x3d, 0xd9, 0x6b, 0x9f,
0x0c, 0xe9, 0x40, 0xf1, 0x13, 0x5e, 0xf9, 0x25, 0xf7, 0x22, 0x52, 0x4b, 0x86, 0x07, 0xdd, 0x5e, 0x97, 0xd5, 0x83, 0xef, 0x29, 0x00, 0x7e, 0xb8, 0xe4, 0x8d, 0xba, 0x90, 0x8f, 0xbc, 0x04, 0x8d,
0xcc, 0x3b, 0xf6, 0x77, 0x6c, 0xca, 0xd0, 0xfb, 0x35, 0x98, 0xc3, 0x30, 0x1c, 0x86, 0x79, 0x0c, 0x27, 0xf1, 0x0b, 0x1f, 0xa2, 0xea, 0xe6, 0x33, 0x18, 0xd4, 0x85, 0xe2, 0x39, 0x79, 0xf0, 0x4b,
0xbd, 0x06, 0x6d, 0x58, 0x09, 0xcf, 0x64, 0x23, 0x01, 0x1b, 0x5d, 0x88, 0x6a, 0x75, 0x3e, 0x84, 0xfc, 0x22, 0x54, 0x4b, 0x86, 0x07, 0xa7, 0xfd, 0xbe, 0xa8, 0xed, 0xaf, 0xdf, 0x8c, 0xa1, 0xfc,
0xb4, 0xa1, 0xe0, 0xeb, 0x6d, 0x89, 0x09, 0x92, 0xf5, 0x44, 0x70, 0xd0, 0xaa, 0x36, 0xe7, 0xd4, 0xa1, 0x58, 0xc0, 0x30, 0x9c, 0x93, 0x45, 0x0c, 0xe5, 0x01, 0x1d, 0x58, 0x0b, 0x8f, 0x6b, 0x3b,
0x17, 0xdb, 0x0d, 0xb8, 0x79, 0x54, 0x93, 0xb9, 0x45, 0xa4, 0x36, 0x6e, 0x83, 0x78, 0x5d, 0xcf, 0x01, 0x1b, 0xdd, 0x95, 0x6a, 0x75, 0x31, 0x04, 0x75, 0xa0, 0xe0, 0xeb, 0x6d, 0x8b, 0xe1, 0xa2,
0x33, 0x62, 0x39, 0x5f, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xd4, 0x54, 0xd0, 0xf3, 0xcd, 0x09, 0xad, 0x44, 0x70, 0x70, 0x54, 0x6d, 0x41, 0xd7, 0x17, 0xdb, 0x0b, 0xb8, 0x49, 0xaa, 0xc9, 0xdc,
0x00, 0x00, 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. // Reference imports to suppress errors if they are not otherwise used.

@ -31,6 +31,12 @@ enum ProtocolVersion {
/// Client may attempt to send the loop out payment in multiple parts. /// Client may attempt to send the loop out payment in multiple parts.
MULTI_LOOP_OUT = 1; 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 { message ServerLoopOutRequest {

@ -11,7 +11,6 @@ import (
) )
type swapKit struct { type swapKit struct {
htlc *swap.Htlc
hash lntypes.Hash hash lntypes.Hash
height int32 height int32
@ -19,51 +18,49 @@ type swapKit struct {
log *swap.PrefixLog log *swap.PrefixLog
lastUpdateTime time.Time lastUpdateTime time.Time
cost loopdb.SwapCost
state loopdb.SwapState cost loopdb.SwapCost
executeConfig
swapConfig state loopdb.SwapState
contract *loopdb.SwapContract contract *loopdb.SwapContract
swapType swap.Type swapType swap.Type
swapConfig
} }
func newSwapKit(hash lntypes.Hash, swapType swap.Type, cfg *swapConfig, func newSwapKit(hash lntypes.Hash, swapType swap.Type, cfg *swapConfig,
contract *loopdb.SwapContract, outputType swap.HtlcOutputType) ( contract *loopdb.SwapContract) *swapKit {
*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
}
log := &swap.PrefixLog{ log := &swap.PrefixLog{
Hash: hash, Hash: hash,
Logger: log, Logger: log,
} }
// Log htlc address for debugging.
log.Infof("Htlc address: %v", htlc.Address)
return &swapKit{ return &swapKit{
swapConfig: *cfg, swapConfig: *cfg,
hash: hash, hash: hash,
log: log, log: log,
htlc: htlc,
state: loopdb.StateInitiated, state: loopdb.StateInitiated,
contract: contract, contract: contract,
swapType: swapType, 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. // swapInfo constructs and returns a filled SwapInfo from
func (s *swapKit) sendUpdate(ctx context.Context) error { // the swapKit.
info := &SwapInfo{ func (s *swapKit) swapInfo() *SwapInfo {
return &SwapInfo{
SwapContract: *s.contract, SwapContract: *s.contract,
SwapHash: s.hash, SwapHash: s.hash,
SwapType: s.swapType, SwapType: s.swapType,
@ -72,18 +69,7 @@ func (s *swapKit) sendUpdate(ctx context.Context) error {
State: s.state, State: s.state,
Cost: s.cost, 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 { type genericSwap interface {

@ -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. // NewHtlc returns a new instance.
func NewHtlc(cltvExpiry int32, senderKey, receiverKey [33]byte, func NewHtlc(cltvExpiry int32, senderKey, receiverKey [33]byte,
hash lntypes.Hash, outputType HtlcOutputType, hash lntypes.Hash, outputType HtlcOutputType,

@ -22,7 +22,7 @@ import (
// protocolVersion defines the version of the protocol that is currently // protocolVersion defines the version of the protocol that is currently
// supported by the loop client. // supported by the loop client.
const protocolVersion = looprpc.ProtocolVersion_MULTI_LOOP_OUT const protocolVersion = looprpc.ProtocolVersion_NATIVE_SEGWIT_LOOP_IN
type swapServerClient interface { type swapServerClient interface {
GetLoopOutTerms(ctx context.Context) ( GetLoopOutTerms(ctx context.Context) (

Loading…
Cancel
Save