Merge pull request #258 from carlaKC/65-confirmationparam

loopout: allow per-swap confirmation targets for server HTLC
pull/264/head
Carla Kirk-Cohen 4 years ago committed by GitHub
commit a240c69b75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -27,6 +27,7 @@ var (
Amount: btcutil.Amount(50000),
DestAddr: testAddr,
MaxMinerFee: 50000,
HtlcConfirmations: defaultConfirmations,
SweepConfTarget: 2,
MaxSwapFee: 1050,
MaxPrepayAmount: 100,
@ -36,16 +37,22 @@ var (
swapInvoiceDesc = "swap"
prepayInvoiceDesc = "prepay"
defaultConfirmations = int32(loopdb.DefaultLoopOutHtlcConfirmations)
)
// TestSuccess tests the loop out happy flow.
// TestSuccess tests the loop out happy flow, using a custom htlc confirmation
// target.
func TestSuccess(t *testing.T) {
defer test.Guard(t)()
ctx := createClientTestContext(t, nil)
req := *testRequest
req.HtlcConfirmations = 2
// Initiate loop out.
info, err := ctx.swapClient.LoopOut(context.Background(), testRequest)
info, err := ctx.swapClient.LoopOut(context.Background(), &req)
if err != nil {
t.Fatal(err)
}
@ -57,7 +64,7 @@ func TestSuccess(t *testing.T) {
signalPrepaymentResult := ctx.AssertPaid(prepayInvoiceDesc)
// Expect client to register for conf.
confIntent := ctx.AssertRegisterConf(false)
confIntent := ctx.AssertRegisterConf(false, req.HtlcConfirmations)
testSuccess(ctx, testRequest.Amount, info.SwapHash,
signalPrepaymentResult, signalSwapPaymentResult, false,
@ -83,7 +90,7 @@ func TestFailOffchain(t *testing.T) {
signalSwapPaymentResult := ctx.AssertPaid(swapInvoiceDesc)
signalPrepaymentResult := ctx.AssertPaid(prepayInvoiceDesc)
ctx.AssertRegisterConf(false)
ctx.AssertRegisterConf(false, defaultConfirmations)
signalSwapPaymentResult(
errors.New(lndclient.PaymentResultUnknownPaymentHash),
@ -141,18 +148,25 @@ func TestFailWrongAmount(t *testing.T) {
func TestResume(t *testing.T) {
defer test.Guard(t)()
defaultConfs := loopdb.DefaultLoopOutHtlcConfirmations
t.Run("not expired", func(t *testing.T) {
testResume(t, false, false, true)
testResume(t, defaultConfs, false, false, true)
})
t.Run("not expired, custom confirmations", func(t *testing.T) {
testResume(t, 3, false, false, true)
})
t.Run("expired not revealed", func(t *testing.T) {
testResume(t, true, false, false)
testResume(t, defaultConfs, true, false, false)
})
t.Run("expired revealed", func(t *testing.T) {
testResume(t, true, true, true)
testResume(t, defaultConfs, true, true, true)
})
}
func testResume(t *testing.T, expired, preimageRevealed, expectSuccess bool) {
func testResume(t *testing.T, confs uint32, expired, preimageRevealed,
expectSuccess bool) {
defer test.Guard(t)()
preimage := testPreimage
@ -191,11 +205,13 @@ func testResume(t *testing.T, expired, preimageRevealed, expectSuccess bool) {
update.HtlcTxHash = &chainhash.Hash{1, 2, 6}
}
// Create a pending swap with our custom number of confirmations.
pendingSwap := &loopdb.LoopOut{
Contract: &loopdb.LoopOutContract{
DestAddr: dest,
SwapInvoice: swapPayReq,
SweepConfTarget: 2,
HtlcConfirmations: confs,
MaxSwapRoutingFee: 70000,
PrepayInvoice: prePayReq,
SwapContract: loopdb.SwapContract{
@ -231,8 +247,8 @@ func testResume(t *testing.T, expired, preimageRevealed, expectSuccess bool) {
signalSwapPaymentResult := ctx.AssertPaid(swapInvoiceDesc)
signalPrepaymentResult := ctx.AssertPaid(prepayInvoiceDesc)
// Expect client to register for conf.
confIntent := ctx.AssertRegisterConf(preimageRevealed)
// Expect client to register for our expected number of confirmations.
confIntent := ctx.AssertRegisterConf(preimageRevealed, int32(confs))
signalSwapPaymentResult(nil)
signalPrepaymentResult(nil)

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcutil"
"github.com/lightninglabs/loop"
"github.com/lightninglabs/loop/labels"
"github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/looprpc"
"github.com/urfave/cli"
)
@ -42,6 +43,13 @@ var loopOutCommand = cli.Command{
Name: "amt",
Usage: "the amount in satoshis to loop out",
},
cli.Uint64Flag{
Name: "htlc_confs",
Usage: "the number of of confirmations, in blocks " +
"that we require for the htlc extended by " +
"the server before we reveal the preimage.",
Value: uint64(loopdb.DefaultLoopOutHtlcConfirmations),
},
cli.Uint64Flag{
Name: "conf_target",
Usage: "the number of blocks from the swap " +
@ -135,6 +143,11 @@ func loopOut(ctx *cli.Context) error {
}
sweepConfTarget := int32(ctx.Uint64("conf_target"))
htlcConfs := int32(ctx.Uint64("htlc_confs"))
if htlcConfs == 0 {
return fmt.Errorf("at least 1 confirmation required for htlcs")
}
quoteReq := &looprpc.QuoteRequest{
Amt: int64(amt),
ConfTarget: sweepConfTarget,
@ -179,6 +192,7 @@ func loopOut(ctx *cli.Context) error {
MaxSwapRoutingFee: int64(limits.maxSwapRoutingFee),
OutgoingChanSet: outgoingChanSet,
SweepConfTarget: sweepConfTarget,
HtlcConfirmations: htlcConfs,
SwapPublicationDeadline: uint64(swapDeadline.Unix()),
Label: label,
})

@ -64,6 +64,10 @@ type OutRequest struct {
// client sweep tx.
SweepConfTarget int32
// HtlcConfirmations specifies the number of confirmations we require
// for on chain loop out htlcs.
HtlcConfirmations int32
// OutgoingChanSet optionally specifies the short channel ids of the
// channels that may be used to loop out.
OutgoingChanSet loopdb.ChannelSet

@ -86,6 +86,7 @@ func (s *swapClientServer) LoopOut(ctx context.Context,
MaxSwapRoutingFee: btcutil.Amount(in.MaxSwapRoutingFee),
MaxSwapFee: btcutil.Amount(in.MaxSwapFee),
SweepConfTarget: sweepConfTarget,
HtlcConfirmations: in.HtlcConfirmations,
SwapPublicationDeadline: time.Unix(
int64(in.SwapPublicationDeadline), 0,
),

@ -36,6 +36,10 @@ type LoopOutContract struct {
// client sweep tx.
SweepConfTarget int32
// HtlcConfirmations is the number of confirmations we require the on
// chain htlc to have before proceeding with the swap.
HtlcConfirmations uint32
// OutgoingChanSet is the set of short ids of channels that may be used.
// If empty, any channel may be used.
OutgoingChanSet ChannelSet

@ -77,11 +77,23 @@ var (
// value: concatenation of uint64 channel ids
outgoingChanSetKey = []byte("outgoing-chan-set")
// confirmationsKey is the key that stores the number of confirmations
// that were requested for a loop out swap.
//
// path: loopOutBucket -> swapBucket[hash] -> confirmationsKey
//
// value: uint32 confirmation value
confirmationsKey = []byte("confirmations")
byteOrder = binary.BigEndian
keyLength = 33
)
// DefaultLoopOutHtlcConfirmations is the default number of confirmations we
// set for a loop out htlc.
const DefaultLoopOutHtlcConfirmations uint32 = 1
// fileExists returns true if the file exists, and false otherwise.
func fileExists(path string) bool {
if _, err := os.Stat(path); err != nil {
@ -242,6 +254,23 @@ func (s *boltSwapStore) FetchLoopOutSwaps() ([]*LoopOut, error) {
}
}
// Set our default number of confirmations for the swap.
contract.HtlcConfirmations = DefaultLoopOutHtlcConfirmations
// If we have the number of confirmations stored for
// this swap, we overwrite our default with the stored
// value.
confBytes := swapBucket.Get(confirmationsKey)
if confBytes != nil {
r := bytes.NewReader(confBytes)
err := binary.Read(
r, byteOrder, &contract.HtlcConfirmations,
)
if err != nil {
return err
}
}
updates, err := deserializeUpdates(swapBucket)
if err != nil {
return err
@ -471,6 +500,18 @@ func (s *boltSwapStore) CreateLoopOut(hash lntypes.Hash,
return err
}
// Write our confirmation target under its own key.
var buf bytes.Buffer
err = binary.Write(&buf, byteOrder, swap.HtlcConfirmations)
if err != nil {
return err
}
err = swapBucket.Put(confirmationsKey, buf.Bytes())
if err != nil {
return err
}
// Finally, we'll create an empty updates bucket for this swap
// to track any future updates to the swap itself.
_, err = swapBucket.CreateBucket(updatesBucketKey)

@ -70,6 +70,7 @@ func TestLoopOutStore(t *testing.T) {
SwapInvoice: "swapinvoice",
MaxSwapRoutingFee: 30,
SweepConfTarget: 2,
HtlcConfirmations: 2,
SwapPublicationDeadline: time.Unix(0, initiationTime.UnixNano()),
}

@ -138,6 +138,15 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
return nil, err
}
// If a htlc confirmation target was not provided, we use the default
// number of confirmations. We overwrite this value rather than failing
// it because the field is a new addition to the rpc, and we don't want
// to break older clients that are not aware of this new field.
confs := uint32(request.HtlcConfirmations)
if confs == 0 {
confs = loopdb.DefaultLoopOutHtlcConfirmations
}
// Instantiate a struct that contains all required data to start the
// swap.
initiationTime := time.Now()
@ -147,6 +156,7 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
DestAddr: request.DestAddr,
MaxSwapRoutingFee: request.MaxSwapRoutingFee,
SweepConfTarget: request.SweepConfTarget,
HtlcConfirmations: confs,
PrepayInvoice: swapResp.prepayInvoice,
MaxPrepayRoutingFee: request.MaxPrepayRoutingFee,
SwapPublicationDeadline: request.SwapPublicationDeadline,
@ -606,8 +616,8 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
// Wait for confirmation of the on-chain htlc by watching for a tx
// producing the swap script output.
s.log.Infof(
"Register conf ntfn for swap script on chain (hh=%v)",
s.InitiationHeight,
"Register %v conf ntfn for swap script on chain (hh=%v)",
s.HtlcConfirmations, s.InitiationHeight,
)
// If we've revealed the preimage in a previous run, we expect to have
@ -624,8 +634,8 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
defer cancel()
htlcConfChan, htlcErrChan, err :=
s.lnd.ChainNotifier.RegisterConfirmationsNtfn(
ctx, s.htlcTxHash, s.htlc.PkScript, 1,
s.InitiationHeight,
ctx, s.htlcTxHash, s.htlc.PkScript,
int32(s.HtlcConfirmations), s.InitiationHeight,
)
if err != nil {
return nil, err

@ -116,7 +116,7 @@ func TestLoopOutPaymentParameters(t *testing.T) {
// Swap is expected to register for confirmation of the htlc. Assert
// this to prevent a blocked channel in the mock.
ctx.AssertRegisterConf(false)
ctx.AssertRegisterConf(false, defaultConfirmations)
// Cancel the swap. There is nothing else we need to assert. The payment
// parameters don't play a role in the remainder of the swap process.
@ -191,7 +191,7 @@ func TestLateHtlcPublish(t *testing.T) {
signalPrepaymentResult := ctx.AssertPaid(prepayInvoiceDesc)
// Expect client to register for conf
ctx.AssertRegisterConf(false)
ctx.AssertRegisterConf(false, defaultConfirmations)
// // Wait too long before publishing htlc.
blockEpochChan <- int32(swap.CltvExpiry - 10)
@ -290,7 +290,7 @@ func TestCustomSweepConfTarget(t *testing.T) {
signalPrepaymentResult(nil)
// Notify the confirmation notification for the HTLC.
ctx.AssertRegisterConf(false)
ctx.AssertRegisterConf(false, defaultConfirmations)
blockEpochChan <- ctx.Lnd.Height + 1
@ -494,7 +494,7 @@ func TestPreimagePush(t *testing.T) {
signalPrepaymentResult(nil)
// Notify the confirmation notification for the HTLC.
ctx.AssertRegisterConf(false)
ctx.AssertRegisterConf(false, defaultConfirmations)
blockEpochChan <- ctx.Lnd.Height + 1

@ -231,6 +231,10 @@ type LoopOutRequest struct {
//The number of blocks from the on-chain HTLC's confirmation height that it
//should be swept within.
SweepConfTarget int32 `protobuf:"varint,9,opt,name=sweep_conf_target,json=sweepConfTarget,proto3" json:"sweep_conf_target,omitempty"`
//
//The number of confirmations that we require for the on chain htlc that will
//be published by the server before we reveal the preimage.
HtlcConfirmations int32 `protobuf:"varint,13,opt,name=htlc_confirmations,json=htlcConfirmations,proto3" json:"htlc_confirmations,omitempty"`
//*
//The latest time (in unix seconds) we allow the server to wait before
//publishing the HTLC on chain. Setting this to a larger value will give the
@ -344,6 +348,13 @@ func (m *LoopOutRequest) GetSweepConfTarget() int32 {
return 0
}
func (m *LoopOutRequest) GetHtlcConfirmations() int32 {
if m != nil {
return m.HtlcConfirmations
}
return 0
}
func (m *LoopOutRequest) GetSwapPublicationDeadline() uint64 {
if m != nil {
return m.SwapPublicationDeadline
@ -1499,122 +1510,123 @@ func init() {
func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) }
var fileDescriptor_014de31d7ac8c57c = []byte{
// 1827 bytes of a gzipped FileDescriptorProto
// 1846 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xdd, 0x6e, 0x23, 0x49,
0x15, 0x5e, 0xff, 0xc5, 0xf6, 0x71, 0xbb, 0xdd, 0xa9, 0xcc, 0x24, 0x8e, 0x19, 0x34, 0x9e, 0xde,
0x1d, 0xc8, 0x86, 0xd5, 0x98, 0xcd, 0x5e, 0xb1, 0x02, 0x24, 0x8f, 0xd3, 0xd9, 0x38, 0x4a, 0x6c,
0x15, 0x1e, 0xff, 0xc5, 0xf6, 0x71, 0xbb, 0xdd, 0xa9, 0xcc, 0x4c, 0x1c, 0x33, 0x68, 0x3c, 0xbd,
0x3b, 0x90, 0x0d, 0xcb, 0x98, 0xcd, 0x5e, 0xb1, 0x02, 0x24, 0x8f, 0xd3, 0xd9, 0x38, 0x4a, 0x6c,
0xd3, 0x76, 0x06, 0x2d, 0x42, 0x6a, 0x55, 0xec, 0x4a, 0xdc, 0xc2, 0xfd, 0xb3, 0x5d, 0xe5, 0x99,
0x44, 0x2b, 0x84, 0xc4, 0x0b, 0x70, 0xc1, 0x1b, 0xf0, 0x0c, 0xdc, 0xf1, 0x0a, 0x5c, 0xc1, 0x0b,
0x70, 0x81, 0x84, 0xb8, 0xe0, 0x15, 0x10, 0xaa, 0x53, 0xed, 0x76, 0xb7, 0xf3, 0x83, 0xb8, 0xe0,
0x2e, 0xfd, 0x9d, 0xaf, 0x4e, 0x9d, 0x9f, 0x3a, 0x3f, 0x0e, 0x68, 0xd3, 0x85, 0xcb, 0x7c, 0xf1,
0x26, 0x8c, 0x02, 0x11, 0x90, 0xf2, 0x22, 0x08, 0xc2, 0x28, 0x9c, 0xb6, 0x5e, 0xdc, 0x04, 0xc1,
0xcd, 0x82, 0x75, 0x68, 0xe8, 0x76, 0xa8, 0xef, 0x07, 0x82, 0x0a, 0x37, 0xf0, 0xb9, 0xa2, 0x99,
0x7f, 0x2b, 0x80, 0x7e, 0x1e, 0x04, 0xe1, 0x70, 0x29, 0x6c, 0xf6, 0xcd, 0x92, 0x71, 0x41, 0x0c,
0x28, 0x50, 0x4f, 0x34, 0x73, 0xed, 0xdc, 0x41, 0xc1, 0x96, 0x7f, 0x12, 0x02, 0xc5, 0x19, 0xe3,
0xa2, 0x99, 0x6f, 0xe7, 0x0e, 0xaa, 0x36, 0xfe, 0x4d, 0x3a, 0xf0, 0xcc, 0xa3, 0xb7, 0x0e, 0xff,
0x40, 0x43, 0x27, 0x0a, 0x96, 0xc2, 0xf5, 0x6f, 0x9c, 0x6b, 0xc6, 0x9a, 0x05, 0x3c, 0xb6, 0xed,
0xd1, 0xdb, 0xf1, 0x07, 0x1a, 0xda, 0x4a, 0x72, 0xc2, 0x18, 0xf9, 0x02, 0x76, 0xe5, 0x81, 0x30,
0x62, 0x21, 0xbd, 0xcb, 0x1c, 0x29, 0xe2, 0x91, 0x1d, 0x8f, 0xde, 0x8e, 0x50, 0x98, 0x3a, 0xd4,
0x06, 0x2d, 0xb9, 0x45, 0x52, 0x4b, 0x48, 0x85, 0x58, 0xbb, 0x64, 0x7c, 0x02, 0x7a, 0x4a, 0xad,
0x34, 0x7c, 0x0b, 0x39, 0x5a, 0xa2, 0xae, 0xeb, 0x09, 0x62, 0x42, 0x5d, 0xb2, 0x3c, 0xd7, 0x67,
0x11, 0x2a, 0x2a, 0x23, 0xa9, 0xe6, 0xd1, 0xdb, 0x0b, 0x89, 0x49, 0x4d, 0x9f, 0x81, 0x21, 0x63,
0xe6, 0x04, 0x4b, 0xe1, 0x4c, 0xe7, 0xd4, 0xf7, 0xd9, 0xa2, 0x59, 0x69, 0xe7, 0x0e, 0x8a, 0x6f,
0xf3, 0xcd, 0x9c, 0xad, 0x2f, 0x54, 0x94, 0x7a, 0x4a, 0x42, 0x0e, 0x61, 0x3b, 0x58, 0x8a, 0x9b,
0x40, 0x3a, 0x21, 0xd9, 0x0e, 0x67, 0xa2, 0x59, 0x6b, 0x17, 0x0e, 0x8a, 0x76, 0x63, 0x25, 0x90,
0xdc, 0x31, 0x13, 0x92, 0xcb, 0x3f, 0x30, 0x16, 0x3a, 0xd3, 0xc0, 0xbf, 0x76, 0x04, 0x8d, 0x6e,
0x98, 0x68, 0x56, 0xdb, 0xb9, 0x83, 0x92, 0xdd, 0x40, 0x41, 0x2f, 0xf0, 0xaf, 0x27, 0x08, 0x93,
0x2f, 0x61, 0x1f, 0xbd, 0x0d, 0x97, 0x57, 0x0b, 0x77, 0x8a, 0xb9, 0x72, 0x66, 0x8c, 0xce, 0x16,
0xae, 0xcf, 0x9a, 0x20, 0xcd, 0xb1, 0xf7, 0x24, 0x61, 0xb4, 0x96, 0x1f, 0xc7, 0x62, 0xf2, 0x0c,
0x4a, 0x0b, 0x7a, 0xc5, 0x16, 0x4d, 0x0d, 0x13, 0xa5, 0x3e, 0xcc, 0x7f, 0xe4, 0xa0, 0x2e, 0x53,
0xdc, 0xf7, 0x1f, 0xcf, 0xf0, 0x66, 0x9c, 0xf3, 0xf7, 0xe2, 0x7c, 0x2f, 0x82, 0x85, 0xfb, 0x11,
0xdc, 0x87, 0xca, 0x82, 0x72, 0xe1, 0xcc, 0x83, 0x10, 0x93, 0xaa, 0xd9, 0x65, 0xf9, 0x7d, 0x1a,
0x84, 0xe4, 0x63, 0xa8, 0xb3, 0x5b, 0xc1, 0x22, 0x9f, 0x2e, 0x9c, 0xb9, 0x58, 0x4c, 0x31, 0x93,
0x15, 0x5b, 0x5b, 0x81, 0xa7, 0x62, 0x31, 0x25, 0x07, 0x60, 0x48, 0x59, 0x26, 0x4c, 0x5b, 0x18,
0x26, 0x5d, 0xe2, 0xa9, 0x28, 0x25, 0x9e, 0x96, 0xd3, 0x9e, 0xfe, 0x33, 0x07, 0x1a, 0xbe, 0x3a,
0xc6, 0xc3, 0xc0, 0xe7, 0x8c, 0x10, 0xc8, 0xbb, 0x33, 0xf4, 0xb3, 0x8a, 0x49, 0xcc, 0xbb, 0x33,
0x69, 0xa4, 0x3b, 0x73, 0xae, 0xee, 0x04, 0xe3, 0xe8, 0x83, 0x66, 0x97, 0xdd, 0xd9, 0x5b, 0xf9,
0x49, 0x5e, 0x83, 0x86, 0xf7, 0xd3, 0xd9, 0x2c, 0x62, 0x9c, 0xab, 0xf7, 0x8e, 0x07, 0x6b, 0x12,
0xef, 0x2a, 0x98, 0xbc, 0x81, 0x9d, 0x34, 0xcd, 0xf1, 0xc3, 0xa3, 0x0f, 0x7c, 0x8e, 0x1e, 0x57,
0xed, 0xed, 0x14, 0x73, 0x80, 0x02, 0xf2, 0x19, 0x90, 0x0c, 0x5f, 0xd1, 0x4b, 0x48, 0x37, 0x52,
0xf4, 0x11, 0xb2, 0x5f, 0x83, 0xce, 0x59, 0xf4, 0x9e, 0x45, 0x8e, 0xc7, 0x38, 0xa7, 0x37, 0x0c,
0x43, 0x50, 0xb5, 0xeb, 0x0a, 0xbd, 0x50, 0xa0, 0x69, 0x80, 0x7e, 0x11, 0xf8, 0xae, 0x08, 0xa2,
0x38, 0xab, 0xe6, 0x1f, 0x8b, 0x00, 0xd2, 0xfb, 0xb1, 0xa0, 0x62, 0xc9, 0x1f, 0x2c, 0x63, 0x19,
0x8d, 0xfc, 0xa3, 0xd1, 0xa8, 0x6d, 0x46, 0xa3, 0x28, 0xee, 0x42, 0x95, 0x68, 0xfd, 0x68, 0xfb,
0x4d, 0xdc, 0x50, 0xde, 0xc8, 0x3b, 0x26, 0x77, 0x21, 0xb3, 0x51, 0x4c, 0x0e, 0xa0, 0xc4, 0x05,
0x15, 0xaa, 0x8c, 0xf5, 0x23, 0x92, 0xe1, 0x49, 0x5b, 0x98, 0xad, 0x08, 0xe4, 0x27, 0xa0, 0x5f,
0x53, 0x77, 0xb1, 0x8c, 0x98, 0x13, 0x31, 0xca, 0x03, 0xbf, 0xa9, 0xe3, 0x91, 0xdd, 0xe4, 0xc8,
0x89, 0x12, 0xdb, 0x28, 0xb5, 0xeb, 0xd7, 0xe9, 0x4f, 0xf2, 0x7d, 0x68, 0xb8, 0xbe, 0x2b, 0x5c,
0x55, 0x13, 0xc2, 0xf5, 0x56, 0xed, 0x40, 0x5f, 0xc3, 0x13, 0xd7, 0x93, 0x16, 0x19, 0xf8, 0x0c,
0x97, 0xe1, 0x8c, 0x0a, 0xa6, 0x98, 0xaa, 0x29, 0xe8, 0x12, 0xbf, 0x44, 0x18, 0x99, 0x9b, 0x09,
0x2f, 0x3f, 0x9c, 0xf0, 0x87, 0x13, 0xa8, 0x3d, 0x92, 0xc0, 0x47, 0x9e, 0x47, 0xfd, 0xb1, 0xe7,
0xf1, 0x12, 0x6a, 0xd3, 0x80, 0x0b, 0x47, 0xe5, 0x17, 0x5b, 0x4e, 0xc1, 0x06, 0x09, 0x8d, 0x11,
0x21, 0xaf, 0x40, 0x43, 0x42, 0xe0, 0x4f, 0xe7, 0xd4, 0xf5, 0xb1, 0x73, 0x14, 0x6c, 0x3c, 0x34,
0x54, 0x90, 0x2c, 0x2f, 0x45, 0xb9, 0xbe, 0x56, 0x1c, 0x50, 0x4d, 0x10, 0x39, 0x31, 0xb6, 0x2e,
0x9a, 0x46, 0xba, 0x68, 0x08, 0x18, 0xe7, 0x2e, 0x17, 0x32, 0x5b, 0x7c, 0xf5, 0x94, 0x7e, 0x0a,
0xdb, 0x29, 0x2c, 0x2e, 0xa6, 0x4f, 0xa1, 0x24, 0xfb, 0x03, 0x6f, 0xe6, 0xda, 0x85, 0x83, 0xda,
0xd1, 0xce, 0xbd, 0x44, 0x2f, 0xb9, 0xad, 0x18, 0xe6, 0x2b, 0x68, 0x48, 0xb0, 0xef, 0x5f, 0x07,
0xab, 0x9e, 0xa3, 0x27, 0xa5, 0xa8, 0xc9, 0x87, 0x67, 0xea, 0xa0, 0x4d, 0x58, 0xe4, 0x25, 0x57,
0xfe, 0x06, 0x1a, 0x7d, 0x3f, 0x46, 0xe2, 0x0b, 0xbf, 0x07, 0x0d, 0xcf, 0xf5, 0x55, 0x53, 0xa2,
0x5e, 0xb0, 0xf4, 0x45, 0x9c, 0xf0, 0xba, 0xe7, 0xfa, 0x52, 0x7f, 0x17, 0x41, 0xe4, 0xad, 0x9a,
0x57, 0xcc, 0xdb, 0x8a, 0x79, 0xaa, 0x7f, 0x29, 0xde, 0x59, 0xb1, 0x92, 0x33, 0xf2, 0x67, 0xc5,
0x4a, 0xde, 0x28, 0x9c, 0x15, 0x2b, 0x05, 0xa3, 0x78, 0x56, 0xac, 0x14, 0x8d, 0xd2, 0x59, 0xb1,
0x52, 0x36, 0x2a, 0xe6, 0x9f, 0x73, 0x60, 0x0c, 0x97, 0xe2, 0xff, 0x6a, 0x02, 0x4e, 0x2b, 0xd7,
0x77, 0xa6, 0x0b, 0xf1, 0xde, 0x99, 0xb1, 0x85, 0xa0, 0x98, 0xee, 0x92, 0xad, 0x79, 0xae, 0xdf,
0x5b, 0x88, 0xf7, 0xc7, 0x12, 0x5b, 0xcd, 0xb4, 0x14, 0xab, 0x1a, 0xb3, 0xe8, 0x6d, 0xc2, 0xfa,
0x2f, 0xee, 0xfc, 0x21, 0x07, 0xda, 0xcf, 0x96, 0x81, 0x60, 0x8f, 0x37, 0x7d, 0x7c, 0x78, 0xeb,
0x4e, 0x9b, 0xc7, 0x3b, 0x60, 0xba, 0xee, 0xb2, 0xf7, 0x9a, 0x76, 0xe1, 0x81, 0xa6, 0xfd, 0xe4,
0xc0, 0x2a, 0x3e, 0x39, 0xb0, 0xcc, 0xdf, 0xe5, 0x64, 0xd6, 0x63, 0x33, 0xe3, 0x90, 0xb7, 0x41,
0x5b, 0x8d, 0x21, 0x87, 0xd3, 0x95, 0xc1, 0xc0, 0xd5, 0x1c, 0x1a, 0x53, 0x5c, 0x3d, 0xb0, 0xc0,
0xf0, 0x46, 0x3e, 0x4f, 0x98, 0xf1, 0xea, 0x21, 0x65, 0x23, 0x25, 0x8a, 0x0f, 0x7c, 0x17, 0x20,
0x15, 0xcb, 0x12, 0xfa, 0x59, 0x9d, 0xa6, 0x02, 0xa9, 0x42, 0x58, 0x34, 0x4a, 0xe6, 0x5f, 0xd4,
0x2b, 0xf8, 0x5f, 0x4d, 0xfa, 0x04, 0xf4, 0xf5, 0x06, 0x82, 0x1c, 0x35, 0x41, 0xb5, 0x70, 0xb5,
0x82, 0x48, 0xd6, 0x0f, 0xe2, 0x3e, 0xa2, 0x96, 0x81, 0xac, 0xd9, 0x0d, 0x29, 0x19, 0x4b, 0x41,
0xac, 0x12, 0x97, 0x06, 0x19, 0x57, 0x7a, 0xe7, 0x31, 0x5f, 0x38, 0xb8, 0x81, 0xa9, 0xa9, 0xda,
0xc0, 0x78, 0x2a, 0xfc, 0x58, 0xe6, 0xf6, 0x69, 0x07, 0xcd, 0x06, 0xd4, 0x27, 0xc1, 0xaf, 0x98,
0x9f, 0x14, 0xdb, 0x8f, 0x41, 0x5f, 0x01, 0xb1, 0x8b, 0x87, 0xb0, 0x25, 0x10, 0x89, 0xab, 0x7b,
0xdd, 0xc6, 0xcf, 0x39, 0x15, 0x48, 0xb6, 0x63, 0x86, 0xf9, 0xa7, 0x3c, 0x54, 0x13, 0x54, 0x3e,
0x92, 0x2b, 0xca, 0x99, 0xe3, 0xd1, 0x29, 0x8d, 0x82, 0xc0, 0x8f, 0x6b, 0x5c, 0x93, 0xe0, 0x45,
0x8c, 0xc9, 0x16, 0xb6, 0xf2, 0x63, 0x4e, 0xf9, 0x1c, 0xa3, 0xa3, 0xd9, 0xb5, 0x18, 0x3b, 0xa5,
0x7c, 0x4e, 0x3e, 0x05, 0x63, 0x45, 0x09, 0x23, 0xe6, 0x7a, 0x72, 0xf2, 0xa9, 0xf9, 0xdc, 0x88,
0xf1, 0x51, 0x0c, 0xcb, 0x06, 0xaf, 0x8a, 0xcc, 0x09, 0xa9, 0x3b, 0x73, 0x3c, 0x19, 0x45, 0xb5,
0x44, 0xea, 0x0a, 0x1f, 0x51, 0x77, 0x76, 0xc1, 0xa9, 0x20, 0x9f, 0xc3, 0xf3, 0xd4, 0xa6, 0x99,
0xa2, 0xab, 0x2a, 0x26, 0x51, 0xb2, 0x6a, 0x26, 0x47, 0x5e, 0x81, 0x26, 0x27, 0x86, 0x33, 0x8d,
0x18, 0x15, 0x6c, 0x16, 0xd7, 0x71, 0x4d, 0x62, 0x3d, 0x05, 0x91, 0x26, 0x94, 0xd9, 0x6d, 0xe8,
0x46, 0x6c, 0x86, 0x13, 0xa3, 0x62, 0xaf, 0x3e, 0xe5, 0x61, 0x2e, 0x82, 0x88, 0xde, 0x30, 0xc7,
0xa7, 0x1e, 0xc3, 0xea, 0xae, 0xda, 0xb5, 0x18, 0x1b, 0x50, 0x8f, 0x1d, 0xbe, 0x86, 0xca, 0x6a,
0x82, 0x12, 0x0d, 0x2a, 0xe7, 0xc3, 0xe1, 0xc8, 0x19, 0x5e, 0x4e, 0x8c, 0x8f, 0x48, 0x0d, 0xca,
0xf8, 0xd5, 0x1f, 0x18, 0xb9, 0x43, 0x0e, 0xd5, 0x64, 0x80, 0x92, 0x3a, 0x54, 0xfb, 0x83, 0xfe,
0xa4, 0xdf, 0x9d, 0x58, 0xc7, 0xc6, 0x47, 0xe4, 0x39, 0x6c, 0x8f, 0x6c, 0xab, 0x7f, 0xd1, 0xfd,
0xca, 0x72, 0x6c, 0xeb, 0x9d, 0xd5, 0x3d, 0xb7, 0x8e, 0x8d, 0x1c, 0x21, 0xa0, 0x9f, 0x4e, 0xce,
0x7b, 0xce, 0xe8, 0xf2, 0xed, 0x79, 0x7f, 0x7c, 0x6a, 0x1d, 0x1b, 0x79, 0xa9, 0x73, 0x7c, 0xd9,
0xeb, 0x59, 0xe3, 0xb1, 0x51, 0x20, 0x00, 0x5b, 0x27, 0xdd, 0xbe, 0x24, 0x17, 0xc9, 0x0e, 0x34,
0xfa, 0x83, 0x77, 0xc3, 0x7e, 0xcf, 0x72, 0xc6, 0xd6, 0x64, 0x22, 0xc1, 0xd2, 0xe1, 0xbf, 0x72,
0x50, 0xcf, 0xcc, 0x60, 0xb2, 0x07, 0x3b, 0xf2, 0xc8, 0xa5, 0x2d, 0x6f, 0xea, 0x8e, 0x87, 0x03,
0x67, 0x30, 0x1c, 0x58, 0xc6, 0x47, 0xe4, 0x3b, 0xb0, 0xb7, 0x21, 0x18, 0x9e, 0x9c, 0xf4, 0x4e,
0xbb, 0xd2, 0x78, 0xd2, 0x82, 0xdd, 0x0d, 0xe1, 0xa4, 0x7f, 0x61, 0x49, 0x2f, 0xf3, 0xa4, 0x0d,
0x2f, 0x36, 0x64, 0xe3, 0x9f, 0x5b, 0xd6, 0x28, 0x61, 0x14, 0xc8, 0x6b, 0x78, 0xb5, 0xc1, 0xe8,
0x0f, 0xc6, 0x97, 0x27, 0x27, 0xfd, 0x5e, 0xdf, 0x1a, 0x4c, 0x9c, 0x77, 0xdd, 0xf3, 0x4b, 0xcb,
0x28, 0x92, 0x17, 0xd0, 0xdc, 0xbc, 0xc4, 0xba, 0x18, 0x0d, 0xed, 0xae, 0xfd, 0xb5, 0x51, 0x22,
0x1f, 0xc3, 0xcb, 0x7b, 0x4a, 0x7a, 0x43, 0xdb, 0xb6, 0x7a, 0x13, 0xa7, 0x7b, 0x31, 0xbc, 0x1c,
0x4c, 0x8c, 0xad, 0xa3, 0x7f, 0x6f, 0xa9, 0x95, 0xa9, 0x87, 0xbf, 0x9c, 0x88, 0x0d, 0xe5, 0xf8,
0xb7, 0x10, 0xd9, 0x5b, 0xbf, 0xff, 0xcc, 0xaf, 0xa3, 0xd6, 0xf3, 0xcc, 0xd8, 0x5b, 0xd5, 0x8f,
0xb9, 0xf7, 0xdb, 0xbf, 0xfe, 0xfd, 0xf7, 0xf9, 0x6d, 0x53, 0xeb, 0xbc, 0xff, 0xbc, 0x23, 0x19,
0x9d, 0x60, 0x29, 0xbe, 0xcc, 0x1d, 0x92, 0x21, 0x6c, 0xa9, 0xe5, 0x9b, 0xec, 0x66, 0x54, 0x26,
0xdb, 0xf8, 0x63, 0x1a, 0x77, 0x51, 0xa3, 0x61, 0xd6, 0x12, 0x8d, 0xae, 0x2f, 0x15, 0xfe, 0x08,
0xca, 0xf1, 0xe2, 0x97, 0x32, 0x32, 0xbb, 0x0a, 0xb6, 0x1e, 0x9a, 0xcd, 0x3f, 0xcc, 0x91, 0x5f,
0x40, 0x35, 0x19, 0xeb, 0x64, 0x7f, 0x6d, 0xce, 0xc6, 0xf8, 0x6f, 0xb5, 0x1e, 0x12, 0x65, 0xcd,
0x22, 0x7a, 0x62, 0x16, 0x8e, 0x7c, 0x72, 0xa9, 0x9e, 0xb5, 0x1c, 0xf9, 0xa4, 0x99, 0xb9, 0x3e,
0xb5, 0x05, 0x3c, 0x68, 0x98, 0xd9, 0x42, 0x95, 0xcf, 0x08, 0xc9, 0xa8, 0xec, 0x7c, 0xeb, 0xce,
0x7e, 0x4d, 0x7e, 0x09, 0x5a, 0x9c, 0x00, 0x1c, 0xcc, 0x64, 0x1d, 0xac, 0xf4, 0xf6, 0xd0, 0x5a,
0x3b, 0xb3, 0x39, 0xc2, 0x1f, 0xd0, 0x1e, 0x2c, 0x45, 0x47, 0xa0, 0xb6, 0xab, 0x44, 0x3b, 0x36,
0xfc, 0x94, 0xf6, 0xf4, 0xe8, 0xcc, 0x6a, 0xcf, 0x8c, 0x06, 0xb3, 0x8d, 0xda, 0x5b, 0xa4, 0x99,
0xd1, 0xfe, 0x8d, 0xe4, 0x74, 0xbe, 0xa5, 0x9e, 0x90, 0x1e, 0xe8, 0x5f, 0x31, 0xa1, 0x52, 0xfe,
0xa4, 0x0f, 0xeb, 0xa8, 0x6d, 0x2c, 0x42, 0xe6, 0x3e, 0x5e, 0xb2, 0x43, 0xb6, 0x53, 0x4f, 0x21,
0xf1, 0x60, 0xad, 0xfd, 0x49, 0x1f, 0xd2, 0xda, 0xb3, 0x2e, 0xbc, 0x44, 0xed, 0xfb, 0x64, 0x2f,
0xad, 0x3d, 0xed, 0xc1, 0xd7, 0x50, 0x97, 0x77, 0xac, 0x3a, 0x3e, 0x4f, 0xbd, 0xe4, 0xcc, 0x58,
0x69, 0xed, 0xdd, 0xc3, 0xb3, 0xd5, 0x41, 0x1a, 0x78, 0x05, 0xa7, 0xa2, 0xa3, 0x46, 0xc9, 0xd5,
0x16, 0xfe, 0x17, 0xe2, 0x8b, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x34, 0x6b, 0xfd, 0xc4, 0xbc,
0x10, 0x00, 0x00,
0x44, 0x2b, 0x84, 0xc4, 0x0b, 0xec, 0x05, 0x6f, 0xc0, 0x33, 0x70, 0xc7, 0x2b, 0x70, 0x05, 0xaf,
0x80, 0x84, 0xb8, 0xe0, 0x15, 0x10, 0xaa, 0x53, 0xdd, 0xed, 0xb6, 0xf3, 0x83, 0xb8, 0xd8, 0xbb,
0xf4, 0x77, 0xbe, 0x3a, 0x55, 0xe7, 0xff, 0x38, 0xa0, 0x4d, 0x17, 0x2e, 0xf3, 0xc5, 0x9b, 0x30,
0x0a, 0x44, 0x40, 0xca, 0x8b, 0x20, 0x08, 0xa3, 0x70, 0xda, 0x7a, 0x71, 0x1d, 0x04, 0xd7, 0x0b,
0xd6, 0xa1, 0xa1, 0xdb, 0xa1, 0xbe, 0x1f, 0x08, 0x2a, 0xdc, 0xc0, 0xe7, 0x8a, 0x66, 0x7e, 0x5b,
0x04, 0xfd, 0x2c, 0x08, 0xc2, 0xe1, 0x52, 0xd8, 0xec, 0xeb, 0x25, 0xe3, 0x82, 0x18, 0x50, 0xa0,
0x9e, 0x68, 0xe6, 0xda, 0xb9, 0xfd, 0x82, 0x2d, 0xff, 0x24, 0x04, 0x8a, 0x33, 0xc6, 0x45, 0x33,
0xdf, 0xce, 0xed, 0x57, 0x6d, 0xfc, 0x9b, 0x74, 0xe0, 0xa9, 0x47, 0x6f, 0x1c, 0xfe, 0x81, 0x86,
0x4e, 0x14, 0x2c, 0x85, 0xeb, 0x5f, 0x3b, 0x57, 0x8c, 0x35, 0x0b, 0x78, 0x6c, 0xdb, 0xa3, 0x37,
0xe3, 0x0f, 0x34, 0xb4, 0x95, 0xe4, 0x98, 0x31, 0xf2, 0x39, 0x3c, 0x97, 0x07, 0xc2, 0x88, 0x85,
0xf4, 0x76, 0xed, 0x48, 0x11, 0x8f, 0xec, 0x78, 0xf4, 0x66, 0x84, 0xc2, 0xcc, 0xa1, 0x36, 0x68,
0xe9, 0x2d, 0x92, 0x5a, 0x42, 0x2a, 0xc4, 0xda, 0x25, 0xe3, 0x63, 0xd0, 0x33, 0x6a, 0xe5, 0xc3,
0xb7, 0x90, 0xa3, 0xa5, 0xea, 0xba, 0x9e, 0x20, 0x26, 0xd4, 0x25, 0xcb, 0x73, 0x7d, 0x16, 0xa1,
0xa2, 0x32, 0x92, 0x6a, 0x1e, 0xbd, 0x39, 0x97, 0x98, 0xd4, 0xf4, 0x29, 0x18, 0xd2, 0x67, 0x4e,
0xb0, 0x14, 0xce, 0x74, 0x4e, 0x7d, 0x9f, 0x2d, 0x9a, 0x95, 0x76, 0x6e, 0xbf, 0xf8, 0x36, 0xdf,
0xcc, 0xd9, 0xfa, 0x42, 0x79, 0xa9, 0xa7, 0x24, 0xe4, 0x00, 0xb6, 0x83, 0xa5, 0xb8, 0x0e, 0xa4,
0x11, 0x92, 0xed, 0x70, 0x26, 0x9a, 0xb5, 0x76, 0x61, 0xbf, 0x68, 0x37, 0x12, 0x81, 0xe4, 0x8e,
0x99, 0x90, 0x5c, 0xfe, 0x81, 0xb1, 0xd0, 0x99, 0x06, 0xfe, 0x95, 0x23, 0x68, 0x74, 0xcd, 0x44,
0xb3, 0xda, 0xce, 0xed, 0x97, 0xec, 0x06, 0x0a, 0x7a, 0x81, 0x7f, 0x35, 0x41, 0x98, 0xfc, 0x18,
0xc8, 0x5c, 0x2c, 0xa6, 0x48, 0x75, 0x23, 0x4f, 0x05, 0xab, 0x59, 0x47, 0xf2, 0xb6, 0x94, 0xf4,
0xb2, 0x02, 0xf2, 0x05, 0xec, 0xa1, 0x73, 0xc2, 0xe5, 0xe5, 0xc2, 0x9d, 0x22, 0xe8, 0xcc, 0x18,
0x9d, 0x2d, 0x5c, 0x9f, 0x35, 0x41, 0xbe, 0xde, 0xde, 0x95, 0x84, 0xd1, 0x4a, 0x7e, 0x14, 0x8b,
0xc9, 0x53, 0x28, 0x2d, 0xe8, 0x25, 0x5b, 0x34, 0x35, 0x8c, 0xab, 0xfa, 0x30, 0xff, 0x99, 0x83,
0xba, 0xcc, 0x88, 0xbe, 0xff, 0x70, 0x42, 0x6c, 0x86, 0x25, 0x7f, 0x27, 0x2c, 0x77, 0x1c, 0x5e,
0xb8, 0xeb, 0xf0, 0x3d, 0xa8, 0x2c, 0x28, 0x17, 0xce, 0x3c, 0x08, 0x31, 0x07, 0x34, 0xbb, 0x2c,
0xbf, 0x4f, 0x82, 0x90, 0x7c, 0x04, 0x75, 0x76, 0x23, 0x58, 0xe4, 0xd3, 0x85, 0x23, 0x8d, 0xc6,
0xc0, 0x57, 0x6c, 0x2d, 0x01, 0x4f, 0xc4, 0x62, 0x4a, 0xf6, 0xc1, 0x48, 0x5d, 0x95, 0x78, 0x75,
0x0b, 0x1d, 0xa5, 0x27, 0x8e, 0x8a, 0x9d, 0x9a, 0x5a, 0x5a, 0xce, 0x5a, 0xfa, 0xaf, 0x1c, 0x68,
0x98, 0xa4, 0x8c, 0x87, 0x81, 0xcf, 0x19, 0x21, 0x90, 0x77, 0x67, 0x68, 0x67, 0x15, 0x63, 0x9e,
0x77, 0x67, 0xf2, 0x91, 0xee, 0xcc, 0xb9, 0xbc, 0x15, 0x8c, 0xa3, 0x0d, 0x9a, 0x5d, 0x76, 0x67,
0x6f, 0xe5, 0x27, 0x79, 0x0d, 0x1a, 0xde, 0x4f, 0x67, 0xb3, 0x88, 0x71, 0xae, 0xca, 0x03, 0x0f,
0xd6, 0x24, 0xde, 0x55, 0x30, 0x79, 0x03, 0x3b, 0x59, 0x9a, 0xe3, 0x87, 0x87, 0x1f, 0xf8, 0x1c,
0x2d, 0xae, 0xaa, 0x90, 0xc6, 0xcc, 0x01, 0x0a, 0xc8, 0xa7, 0x71, 0x06, 0x24, 0x7c, 0x45, 0x2f,
0x21, 0xdd, 0xc8, 0xd0, 0x47, 0xc8, 0x7e, 0x0d, 0x3a, 0x67, 0xd1, 0x7b, 0x16, 0x39, 0x1e, 0xe3,
0x9c, 0x5e, 0x33, 0x74, 0x41, 0xd5, 0xae, 0x2b, 0xf4, 0x5c, 0x81, 0xa6, 0x01, 0xfa, 0x79, 0xe0,
0xbb, 0x22, 0x88, 0xe2, 0xa8, 0x9a, 0x7f, 0x2e, 0x02, 0x48, 0xeb, 0xc7, 0x82, 0x8a, 0x25, 0xbf,
0xb7, 0xea, 0xa5, 0x37, 0xf2, 0x0f, 0x7a, 0xa3, 0xb6, 0xe9, 0x8d, 0xa2, 0xb8, 0x0d, 0x55, 0xa0,
0xf5, 0xc3, 0xed, 0x37, 0x71, 0xff, 0x79, 0x23, 0xef, 0x98, 0xdc, 0x86, 0xcc, 0x46, 0x31, 0xd9,
0x87, 0x12, 0x17, 0x54, 0xa8, 0xaa, 0xd7, 0x0f, 0xc9, 0x1a, 0x4f, 0xbe, 0x85, 0xd9, 0x8a, 0x40,
0x7e, 0x0e, 0xfa, 0x15, 0x75, 0x17, 0xcb, 0x88, 0x39, 0x11, 0xa3, 0x3c, 0xf0, 0x9b, 0x3a, 0x1e,
0x79, 0x9e, 0x1e, 0x39, 0x56, 0x62, 0x1b, 0xa5, 0x76, 0xfd, 0x2a, 0xfb, 0x49, 0x7e, 0x08, 0x0d,
0xd7, 0x77, 0x85, 0xab, 0x6a, 0x42, 0xb8, 0x5e, 0xd2, 0x3d, 0xf4, 0x15, 0x3c, 0x71, 0x3d, 0xf9,
0x22, 0x03, 0xd3, 0x70, 0x19, 0xce, 0xa8, 0x60, 0x8a, 0xa9, 0x7a, 0x88, 0x2e, 0xf1, 0x0b, 0x84,
0x91, 0xb9, 0x19, 0xf0, 0xf2, 0xfd, 0x01, 0xbf, 0x3f, 0x80, 0xda, 0x03, 0x01, 0x7c, 0x20, 0x3d,
0xea, 0x0f, 0xa5, 0xc7, 0x4b, 0xa8, 0x4d, 0x03, 0x2e, 0x1c, 0x15, 0x5f, 0xec, 0x50, 0x05, 0x1b,
0x24, 0x34, 0x46, 0x84, 0xbc, 0x02, 0x0d, 0x09, 0x81, 0x3f, 0x9d, 0x53, 0xd7, 0xc7, 0x46, 0x53,
0xb0, 0xf1, 0xd0, 0x50, 0x41, 0xb2, 0xbc, 0x14, 0xe5, 0xea, 0x4a, 0x71, 0x40, 0xf5, 0x4c, 0xe4,
0xc4, 0xd8, 0xaa, 0x68, 0x1a, 0xd9, 0xa2, 0x21, 0x60, 0x9c, 0xb9, 0x5c, 0xc8, 0x68, 0xf1, 0x24,
0x95, 0x7e, 0x01, 0xdb, 0x19, 0x2c, 0x2e, 0xa6, 0x4f, 0xa0, 0x24, 0xfb, 0x03, 0x6f, 0xe6, 0xda,
0x85, 0xfd, 0xda, 0xe1, 0xce, 0x9d, 0x40, 0x2f, 0xb9, 0xad, 0x18, 0xe6, 0x2b, 0x68, 0x48, 0xb0,
0xef, 0x5f, 0x05, 0x49, 0xcf, 0xd1, 0xd3, 0x52, 0xd4, 0x64, 0xe2, 0x99, 0x3a, 0x68, 0x13, 0x16,
0x79, 0xe9, 0x95, 0xbf, 0x87, 0x46, 0xdf, 0x8f, 0x91, 0xf8, 0xc2, 0x1f, 0x40, 0xc3, 0x73, 0x7d,
0xd5, 0x94, 0xa8, 0x17, 0x2c, 0x7d, 0x11, 0x07, 0xbc, 0xee, 0xb9, 0xbe, 0xd4, 0xdf, 0x45, 0x10,
0x79, 0x49, 0xf3, 0x8a, 0x79, 0x5b, 0x31, 0x4f, 0xf5, 0x2f, 0xc5, 0x3b, 0x2d, 0x56, 0x72, 0x46,
0xfe, 0xb4, 0x58, 0xc9, 0x1b, 0x85, 0xd3, 0x62, 0xa5, 0x60, 0x14, 0x4f, 0x8b, 0x95, 0xa2, 0x51,
0x3a, 0x2d, 0x56, 0xca, 0x46, 0xc5, 0xfc, 0x6b, 0x0e, 0x8c, 0xe1, 0x52, 0x7c, 0xa7, 0x4f, 0xc0,
0xe1, 0xe6, 0xfa, 0xce, 0x74, 0x21, 0xde, 0x3b, 0x33, 0xb6, 0x10, 0x14, 0xc3, 0x5d, 0xb2, 0x35,
0xcf, 0xf5, 0x7b, 0x0b, 0xf1, 0xfe, 0x48, 0x62, 0xc9, 0x08, 0xcc, 0xb0, 0xaa, 0x31, 0x8b, 0xde,
0xa4, 0xac, 0xff, 0x61, 0xce, 0x9f, 0x72, 0xa0, 0xfd, 0x72, 0x19, 0x08, 0xf6, 0x70, 0xd3, 0xc7,
0xc4, 0x5b, 0x75, 0xda, 0x3c, 0xde, 0x01, 0xd3, 0x55, 0x97, 0xbd, 0xd3, 0xb4, 0x0b, 0xf7, 0x34,
0xed, 0x47, 0x07, 0x56, 0xf1, 0xd1, 0x81, 0x65, 0x7e, 0x9b, 0x93, 0x51, 0x8f, 0x9f, 0x19, 0xbb,
0xbc, 0x0d, 0x5a, 0x32, 0x86, 0x1c, 0x4e, 0x93, 0x07, 0x03, 0x57, 0x73, 0x68, 0x4c, 0x71, 0x53,
0xc1, 0x02, 0xc3, 0x1b, 0xf9, 0x3c, 0x65, 0xc6, 0x9b, 0x8a, 0x94, 0x8d, 0x94, 0x28, 0x3e, 0xf0,
0x7d, 0x80, 0x8c, 0x2f, 0x4b, 0x68, 0x67, 0x75, 0x9a, 0x71, 0xa4, 0x72, 0x61, 0xd1, 0x28, 0x99,
0x7f, 0x53, 0x59, 0xf0, 0xff, 0x3e, 0xe9, 0x63, 0xd0, 0x57, 0x0b, 0x0b, 0x72, 0xd4, 0x04, 0xd5,
0xc2, 0x64, 0x63, 0x91, 0xac, 0x1f, 0xc5, 0x7d, 0x44, 0xed, 0x0e, 0xeb, 0xcf, 0x6e, 0x48, 0xc9,
0x58, 0x0a, 0x62, 0x95, 0xb8, 0x63, 0x48, 0xbf, 0xd2, 0x5b, 0x8f, 0xf9, 0xc2, 0xc1, 0x85, 0x4d,
0x4d, 0xd5, 0x06, 0xfa, 0x53, 0xe1, 0x47, 0x32, 0xb6, 0x8f, 0x1b, 0x68, 0x36, 0xa0, 0x3e, 0x09,
0x7e, 0xcb, 0xfc, 0xb4, 0xd8, 0x7e, 0x06, 0x7a, 0x02, 0xc4, 0x26, 0x1e, 0xc0, 0x96, 0x40, 0x24,
0xae, 0xee, 0x55, 0x1b, 0x3f, 0xe3, 0x54, 0x20, 0xd9, 0x8e, 0x19, 0xe6, 0x5f, 0xf2, 0x50, 0x4d,
0x51, 0x99, 0x24, 0x97, 0x94, 0x33, 0xc7, 0xa3, 0x53, 0x1a, 0x05, 0x81, 0x1f, 0xd7, 0xb8, 0x26,
0xc1, 0xf3, 0x18, 0x93, 0x2d, 0x2c, 0xb1, 0x63, 0x4e, 0xf9, 0x1c, 0xbd, 0xa3, 0xd9, 0xb5, 0x18,
0x3b, 0xa1, 0x7c, 0x4e, 0x3e, 0x01, 0x23, 0xa1, 0x84, 0x11, 0x73, 0x3d, 0x39, 0xf9, 0xd4, 0x7c,
0x6e, 0xc4, 0xf8, 0x28, 0x86, 0x65, 0x83, 0x57, 0x45, 0xe6, 0x84, 0xd4, 0x9d, 0x39, 0x9e, 0xf4,
0xa2, 0xda, 0x39, 0x75, 0x85, 0x8f, 0xa8, 0x3b, 0x3b, 0xe7, 0x54, 0x90, 0xcf, 0xe0, 0x59, 0x66,
0x31, 0xcd, 0xd0, 0x55, 0x15, 0x93, 0x28, 0xdd, 0x4c, 0xd3, 0x23, 0xaf, 0x40, 0x93, 0x13, 0xc3,
0x99, 0x46, 0x8c, 0x0a, 0x36, 0x8b, 0xeb, 0xb8, 0x26, 0xb1, 0x9e, 0x82, 0x48, 0x13, 0xca, 0xec,
0x26, 0x74, 0x23, 0x36, 0xc3, 0x89, 0x51, 0xb1, 0x93, 0x4f, 0x79, 0x98, 0x8b, 0x20, 0xa2, 0xd7,
0xcc, 0xf1, 0xa9, 0xc7, 0xb0, 0xba, 0xab, 0x76, 0x2d, 0xc6, 0x06, 0xd4, 0x63, 0x07, 0xaf, 0xa1,
0x92, 0x4c, 0x50, 0xa2, 0x41, 0xe5, 0x6c, 0x38, 0x1c, 0x39, 0xc3, 0x8b, 0x89, 0xf1, 0x84, 0xd4,
0xa0, 0x8c, 0x5f, 0xfd, 0x81, 0x91, 0x3b, 0xe0, 0x50, 0x4d, 0x07, 0x28, 0xa9, 0x43, 0xb5, 0x3f,
0xe8, 0x4f, 0xfa, 0xdd, 0x89, 0x75, 0x64, 0x3c, 0x21, 0xcf, 0x60, 0x7b, 0x64, 0x5b, 0xfd, 0xf3,
0xee, 0x97, 0x96, 0x63, 0x5b, 0xef, 0xac, 0xee, 0x99, 0x75, 0x64, 0xe4, 0x08, 0x01, 0xfd, 0x64,
0x72, 0xd6, 0x73, 0x46, 0x17, 0x6f, 0xcf, 0xfa, 0xe3, 0x13, 0xeb, 0xc8, 0xc8, 0x4b, 0x9d, 0xe3,
0x8b, 0x5e, 0xcf, 0x1a, 0x8f, 0x8d, 0x02, 0x01, 0xd8, 0x3a, 0xee, 0xf6, 0x25, 0xb9, 0x48, 0x76,
0xa0, 0xd1, 0x1f, 0xbc, 0x1b, 0xf6, 0x7b, 0x96, 0x33, 0xb6, 0x26, 0x13, 0x09, 0x96, 0x0e, 0xfe,
0x9d, 0x83, 0xfa, 0xda, 0x0c, 0x26, 0xbb, 0xb0, 0x23, 0x8f, 0x5c, 0xd8, 0xf2, 0xa6, 0xee, 0x78,
0x38, 0x70, 0x06, 0xc3, 0x81, 0x65, 0x3c, 0x21, 0xdf, 0x83, 0xdd, 0x0d, 0xc1, 0xf0, 0xf8, 0xb8,
0x77, 0xd2, 0x95, 0x8f, 0x27, 0x2d, 0x78, 0xbe, 0x21, 0x9c, 0xf4, 0xcf, 0x2d, 0x69, 0x65, 0x9e,
0xb4, 0xe1, 0xc5, 0x86, 0x6c, 0xfc, 0x2b, 0xcb, 0x1a, 0xa5, 0x8c, 0x02, 0x79, 0x0d, 0xaf, 0x36,
0x18, 0xfd, 0xc1, 0xf8, 0xe2, 0xf8, 0xb8, 0xdf, 0xeb, 0x5b, 0x83, 0x89, 0xf3, 0xae, 0x7b, 0x76,
0x61, 0x19, 0x45, 0xf2, 0x02, 0x9a, 0x9b, 0x97, 0x58, 0xe7, 0xa3, 0xa1, 0xdd, 0xb5, 0xbf, 0x32,
0x4a, 0xe4, 0x23, 0x78, 0x79, 0x47, 0x49, 0x6f, 0x68, 0xdb, 0x56, 0x6f, 0xe2, 0x74, 0xcf, 0x87,
0x17, 0x83, 0x89, 0xb1, 0x75, 0xf8, 0x9f, 0x2d, 0xb5, 0x32, 0xf5, 0xf0, 0x87, 0x16, 0xb1, 0xa1,
0x1c, 0xff, 0x74, 0x22, 0xbb, 0xab, 0xfc, 0x5f, 0xfb, 0x31, 0xd5, 0x7a, 0xb6, 0x36, 0xf6, 0x92,
0xfa, 0x31, 0x77, 0xff, 0xf0, 0xf7, 0x7f, 0xfc, 0x31, 0xbf, 0x6d, 0x6a, 0x9d, 0xf7, 0x9f, 0x75,
0x24, 0xa3, 0x13, 0x2c, 0xc5, 0x17, 0xb9, 0x03, 0x32, 0x84, 0x2d, 0xb5, 0x7c, 0x93, 0xe7, 0x6b,
0x2a, 0xd3, 0x6d, 0xfc, 0x21, 0x8d, 0xcf, 0x51, 0xa3, 0x61, 0xd6, 0x52, 0x8d, 0xae, 0x2f, 0x15,
0xfe, 0x14, 0xca, 0xf1, 0xe2, 0x97, 0x79, 0xe4, 0xfa, 0x2a, 0xd8, 0xba, 0x6f, 0x36, 0xff, 0x24,
0x47, 0x7e, 0x0d, 0xd5, 0x74, 0xac, 0x93, 0xbd, 0xd5, 0x73, 0x36, 0xc6, 0x7f, 0xab, 0x75, 0x9f,
0x68, 0xfd, 0x59, 0x44, 0x4f, 0x9f, 0x85, 0x23, 0x9f, 0x5c, 0xa8, 0xb4, 0x96, 0x23, 0x9f, 0x34,
0xd7, 0xae, 0xcf, 0x6c, 0x01, 0xf7, 0x3e, 0xcc, 0x6c, 0xa1, 0xca, 0xa7, 0x84, 0xac, 0xa9, 0xec,
0x7c, 0xe3, 0xce, 0x7e, 0x47, 0x7e, 0x03, 0x5a, 0x1c, 0x00, 0x1c, 0xcc, 0x64, 0xe5, 0xac, 0xec,
0xf6, 0xd0, 0x5a, 0x19, 0xb3, 0x39, 0xc2, 0xef, 0xd1, 0x1e, 0x2c, 0x45, 0x47, 0xa0, 0xb6, 0xcb,
0x54, 0x3b, 0x36, 0xfc, 0x8c, 0xf6, 0xec, 0xe8, 0x5c, 0xd7, 0xbe, 0x36, 0x1a, 0xcc, 0x36, 0x6a,
0x6f, 0x91, 0xe6, 0x9a, 0xf6, 0xaf, 0x25, 0xa7, 0xf3, 0x0d, 0xf5, 0x84, 0xb4, 0x40, 0xff, 0x92,
0x09, 0x15, 0xf2, 0x47, 0x6d, 0x58, 0x79, 0x6d, 0x63, 0x11, 0x32, 0xf7, 0xf0, 0x92, 0x1d, 0xb2,
0x9d, 0x49, 0x85, 0xd4, 0x82, 0x95, 0xf6, 0x47, 0x6d, 0xc8, 0x6a, 0x5f, 0x37, 0xe1, 0x25, 0x6a,
0xdf, 0x23, 0xbb, 0x59, 0xed, 0x59, 0x0b, 0xbe, 0x82, 0xba, 0xbc, 0x23, 0xe9, 0xf8, 0x3c, 0x93,
0xc9, 0x6b, 0x63, 0xa5, 0xb5, 0x7b, 0x07, 0x5f, 0xaf, 0x0e, 0xd2, 0xc0, 0x2b, 0x38, 0x15, 0x1d,
0x35, 0x4a, 0x2e, 0xb7, 0xf0, 0x9f, 0x16, 0x9f, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x3b, 0x20,
0x13, 0x25, 0xeb, 0x10, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

@ -182,6 +182,12 @@ message LoopOutRequest {
*/
int32 sweep_conf_target = 9;
/*
The number of confirmations that we require for the on chain htlc that will
be published by the server before we reveal the preimage.
*/
int32 htlc_confirmations = 13;
/**
The latest time (in unix seconds) we allow the server to wait before
publishing the HTLC on chain. Setting this to a larger value will give the

@ -473,6 +473,11 @@
"format": "int32",
"description": "*\nThe number of blocks from the on-chain HTLC's confirmation height that it\nshould be swept within."
},
"htlc_confirmations": {
"type": "integer",
"format": "int32",
"description": "The number of confirmations that we require for the on chain htlc that will\nbe published by the server before we reveal the preimage."
},
"swap_publication_deadline": {
"type": "string",
"format": "uint64",

@ -12,6 +12,7 @@ import (
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/zpay32"
"github.com/stretchr/testify/require"
)
// Context contains shared test context functions.
@ -113,7 +114,7 @@ func (ctx *Context) AssertTrackPayment() TrackPaymentMessage {
}
// AssertRegisterConf asserts that a register for conf has been received.
func (ctx *Context) AssertRegisterConf(expectTxHash bool) *ConfRegistration {
func (ctx *Context) AssertRegisterConf(expectTxHash bool, confs int32) *ConfRegistration {
ctx.T.Helper()
// Expect client to register for conf
@ -127,6 +128,11 @@ func (ctx *Context) AssertRegisterConf(expectTxHash bool) *ConfRegistration {
case !expectTxHash && confIntent.TxID != nil:
ctx.T.Fatalf("expected script only registration")
}
// Require that we registered for the number of confirmations
// the test expects.
require.Equal(ctx.T, confs, confIntent.NumConfs)
case <-time.After(Timeout):
ctx.T.Fatalf("htlc confirmed not subscribed to")
}

Loading…
Cancel
Save