Merge pull request #2198 from Roasbeef/sendall-rpc

multi: add ability to sweep all coins in the the wallet to an addr to sendcoins
This commit is contained in:
Olaoluwa Osuntokun 2019-01-15 14:49:17 -08:00 committed by GitHub
commit 509bed614c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1761 additions and 712 deletions

@ -807,13 +807,13 @@ func (bo *breachedOutput) SignDesc() *lnwallet.SignDescriptor {
return &bo.signDesc
}
// BuildWitness computes a valid witness that allows us to spend from the
// CraftInputScript computes a valid witness that allows us to spend from the
// breached output. It does so by first generating and memoizing the witness
// generation function, which parameterized primarily by the witness type and
// sign descriptor. The method then returns the witness computed by invoking
// this function on the first and subsequent calls.
func (bo *breachedOutput) BuildWitness(signer lnwallet.Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) ([][]byte, error) {
func (bo *breachedOutput) CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) (*lnwallet.InputScript, error) {
// First, we ensure that the witness generation function has been
// initialized for this breached output.
@ -1082,15 +1082,16 @@ func (b *breachArbiter) sweepSpendableOutputsTxn(txWeight int64,
// First, we construct a valid witness for this outpoint and
// transaction using the SpendableOutput's witness generation
// function.
witness, err := so.BuildWitness(b.cfg.Signer, txn, hashCache,
idx)
inputScript, err := so.CraftInputScript(
b.cfg.Signer, txn, hashCache, idx,
)
if err != nil {
return err
}
// Then, we add the witness to the transaction at the
// appropriate txin index.
txn.TxIn[idx].Witness = witness
txn.TxIn[idx].Witness = inputScript.Witness
return nil
}

@ -161,7 +161,13 @@ var sendCoinsCommand = cli.Command{
Name: "addr",
Usage: "the BASE58 encoded bitcoin address to send coins to on-chain",
},
// TODO(roasbeef): switch to BTC on command line? int may not be sufficient
cli.BoolFlag{
Name: "sweepall",
Usage: "if set, then the amount field will be ignored, " +
"and all the wallet will attempt to sweep all " +
"outputs within the wallet to the target " +
"address",
},
cli.Int64Flag{
Name: "amt",
Usage: "the number of bitcoin denominated in satoshis to send",
@ -215,14 +221,18 @@ func sendCoins(ctx *cli.Context) error {
amt = ctx.Int64("amt")
case args.Present():
amt, err = strconv.ParseInt(args.First(), 10, 64)
default:
case !ctx.Bool("sweepall"):
return fmt.Errorf("Amount argument missing")
}
if err != nil {
return fmt.Errorf("unable to decode amount: %v", err)
}
if amt != 0 && ctx.Bool("sweepall") {
return fmt.Errorf("amount cannot be set if attempting to " +
"sweep all coins out of the wallet")
}
ctxb := context.Background()
client, cleanUp := getClient(ctx)
defer cleanUp()
@ -232,6 +242,7 @@ func sendCoins(ctx *cli.Context) error {
Amount: amt,
TargetConf: int32(ctx.Int64("conf_target")),
SatPerByte: ctx.Int64("sat_per_byte"),
SendAll: ctx.Bool("sweepall"),
}
txid, err := client.SendCoins(ctxb, req)
if err != nil {

@ -476,7 +476,10 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
// TODO: Use time-based sweeper and result chan.
var err error
h.sweepTx, err = h.Sweeper.CreateSweepTx(
[]sweep.Input{&input}, sweepConfTarget, 0,
[]sweep.Input{&input},
sweep.FeePreference{
ConfTarget: sweepConfTarget,
}, 0,
)
if err != nil {
return nil, err
@ -1270,7 +1273,10 @@ func (c *commitSweepResolver) Resolve() (ContractResolver, error) {
//
// TODO: Use time-based sweeper and result chan.
c.sweepTx, err = c.Sweeper.CreateSweepTx(
[]sweep.Input{&input}, sweepConfTarget, 0,
[]sweep.Input{&input},
sweep.FeePreference{
ConfTarget: sweepConfTarget,
}, 0,
)
if err != nil {
return nil, err

@ -12617,12 +12617,95 @@ func testAbandonChannel(net *lntest.NetworkHarness, t *harnessTest) {
cleanupForceClose(t, net, net.Bob, chanPoint)
}
// testSweepAllCoins tests that we're able to properly sweep all coins from the
// wallet into a single target address at the specified fee rate.
func testSweepAllCoins(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
// First, we'll make a new node, ainz who'll we'll use to test wallet
// sweeping.
ainz, err := net.NewNode("Ainz", nil)
if err != nil {
t.Fatalf("unable to create new node: %v", err)
}
defer shutdownAndAssert(net, t, ainz)
// Next, we'll give Ainz exactly 2 utxos of 1 BTC each, with one of
// them being p2wkh and the other being a n2wpkh address.
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
err = net.SendCoins(ctxt, btcutil.SatoshiPerBitcoin, ainz)
if err != nil {
t.Fatalf("unable to send coins to eve: %v", err)
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = net.SendCoinsNP2WKH(ctxt, btcutil.SatoshiPerBitcoin, ainz)
if err != nil {
t.Fatalf("unable to send coins to eve: %v", err)
}
// With the two coins above mined, we'll now instruct ainz to sweep all
// the coins to an external address not under its control.
minerAddr, err := net.Miner.NewAddress()
if err != nil {
t.Fatalf("unable to create new miner addr: %v", err)
}
sweepReq := &lnrpc.SendCoinsRequest{
Addr: minerAddr.String(),
SendAll: true,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
_, err = ainz.SendCoins(ctxt, sweepReq)
if err != nil {
t.Fatalf("unable to sweep coins: %v", err)
}
// We'll mine a block wish should include the sweep transaction we
// generated above.
block := mineBlocks(t, net, 1, 1)[0]
// The sweep transaction should have exactly two inputs as we only had
// two UTXOs in the wallet.
sweepTx := block.Transactions[1]
if len(sweepTx.TxIn) != 2 {
t.Fatalf("expected 2 inputs instead have %v", len(sweepTx.TxIn))
}
// Finally, Ainz should now have no coins at all within his wallet.
balReq := &lnrpc.WalletBalanceRequest{}
resp, err := ainz.WalletBalance(ctxt, balReq)
if err != nil {
t.Fatalf("unable to get ainz's balance: %v", err)
}
switch {
case resp.ConfirmedBalance != 0:
t.Fatalf("expected no confirmed balance, instead have %v",
resp.ConfirmedBalance)
case resp.UnconfirmedBalance != 0:
t.Fatalf("expected no unconfirmed balance, instead have %v",
resp.UnconfirmedBalance)
}
// If we try again, but this time specifying an amount, then the call
// should fail.
sweepReq.Amount = 10000
_, err = ainz.SendCoins(ctxt, sweepReq)
if err == nil {
t.Fatalf("sweep attempt should fail")
}
}
type testCase struct {
name string
test func(net *lntest.NetworkHarness, t *harnessTest)
}
var testsCases = []*testCase{
{
name: "sweep coins",
test: testSweepAllCoins,
},
{
name: "onchain fund recovery",
test: testOnchainFundRecovery,

@ -49,7 +49,7 @@ func (x AddressType) String() string {
return proto.EnumName(AddressType_name, int32(x))
}
func (AddressType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{0}
return fileDescriptor_rpc_e66000aa8614d793, []int{0}
}
type ChannelCloseSummary_ClosureType int32
@ -84,7 +84,7 @@ func (x ChannelCloseSummary_ClosureType) String() string {
return proto.EnumName(ChannelCloseSummary_ClosureType_name, int32(x))
}
func (ChannelCloseSummary_ClosureType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{38, 0}
return fileDescriptor_rpc_e66000aa8614d793, []int{38, 0}
}
type Invoice_InvoiceState int32
@ -107,7 +107,7 @@ func (x Invoice_InvoiceState) String() string {
return proto.EnumName(Invoice_InvoiceState_name, int32(x))
}
func (Invoice_InvoiceState) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{86, 0}
return fileDescriptor_rpc_e66000aa8614d793, []int{86, 0}
}
type GenSeedRequest struct {
@ -128,7 +128,7 @@ func (m *GenSeedRequest) Reset() { *m = GenSeedRequest{} }
func (m *GenSeedRequest) String() string { return proto.CompactTextString(m) }
func (*GenSeedRequest) ProtoMessage() {}
func (*GenSeedRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{0}
return fileDescriptor_rpc_e66000aa8614d793, []int{0}
}
func (m *GenSeedRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GenSeedRequest.Unmarshal(m, b)
@ -183,7 +183,7 @@ func (m *GenSeedResponse) Reset() { *m = GenSeedResponse{} }
func (m *GenSeedResponse) String() string { return proto.CompactTextString(m) }
func (*GenSeedResponse) ProtoMessage() {}
func (*GenSeedResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{1}
return fileDescriptor_rpc_e66000aa8614d793, []int{1}
}
func (m *GenSeedResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GenSeedResponse.Unmarshal(m, b)
@ -248,7 +248,7 @@ func (m *InitWalletRequest) Reset() { *m = InitWalletRequest{} }
func (m *InitWalletRequest) String() string { return proto.CompactTextString(m) }
func (*InitWalletRequest) ProtoMessage() {}
func (*InitWalletRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{2}
return fileDescriptor_rpc_e66000aa8614d793, []int{2}
}
func (m *InitWalletRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InitWalletRequest.Unmarshal(m, b)
@ -306,7 +306,7 @@ func (m *InitWalletResponse) Reset() { *m = InitWalletResponse{} }
func (m *InitWalletResponse) String() string { return proto.CompactTextString(m) }
func (*InitWalletResponse) ProtoMessage() {}
func (*InitWalletResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{3}
return fileDescriptor_rpc_e66000aa8614d793, []int{3}
}
func (m *InitWalletResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InitWalletResponse.Unmarshal(m, b)
@ -348,7 +348,7 @@ func (m *UnlockWalletRequest) Reset() { *m = UnlockWalletRequest{} }
func (m *UnlockWalletRequest) String() string { return proto.CompactTextString(m) }
func (*UnlockWalletRequest) ProtoMessage() {}
func (*UnlockWalletRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{4}
return fileDescriptor_rpc_e66000aa8614d793, []int{4}
}
func (m *UnlockWalletRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UnlockWalletRequest.Unmarshal(m, b)
@ -392,7 +392,7 @@ func (m *UnlockWalletResponse) Reset() { *m = UnlockWalletResponse{} }
func (m *UnlockWalletResponse) String() string { return proto.CompactTextString(m) }
func (*UnlockWalletResponse) ProtoMessage() {}
func (*UnlockWalletResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{5}
return fileDescriptor_rpc_e66000aa8614d793, []int{5}
}
func (m *UnlockWalletResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UnlockWalletResponse.Unmarshal(m, b)
@ -430,7 +430,7 @@ func (m *ChangePasswordRequest) Reset() { *m = ChangePasswordRequest{} }
func (m *ChangePasswordRequest) String() string { return proto.CompactTextString(m) }
func (*ChangePasswordRequest) ProtoMessage() {}
func (*ChangePasswordRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{6}
return fileDescriptor_rpc_e66000aa8614d793, []int{6}
}
func (m *ChangePasswordRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChangePasswordRequest.Unmarshal(m, b)
@ -474,7 +474,7 @@ func (m *ChangePasswordResponse) Reset() { *m = ChangePasswordResponse{}
func (m *ChangePasswordResponse) String() string { return proto.CompactTextString(m) }
func (*ChangePasswordResponse) ProtoMessage() {}
func (*ChangePasswordResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{7}
return fileDescriptor_rpc_e66000aa8614d793, []int{7}
}
func (m *ChangePasswordResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChangePasswordResponse.Unmarshal(m, b)
@ -518,7 +518,7 @@ func (m *Utxo) Reset() { *m = Utxo{} }
func (m *Utxo) String() string { return proto.CompactTextString(m) }
func (*Utxo) ProtoMessage() {}
func (*Utxo) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{8}
return fileDescriptor_rpc_e66000aa8614d793, []int{8}
}
func (m *Utxo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Utxo.Unmarshal(m, b)
@ -606,7 +606,7 @@ func (m *Transaction) Reset() { *m = Transaction{} }
func (m *Transaction) String() string { return proto.CompactTextString(m) }
func (*Transaction) ProtoMessage() {}
func (*Transaction) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{9}
return fileDescriptor_rpc_e66000aa8614d793, []int{9}
}
func (m *Transaction) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Transaction.Unmarshal(m, b)
@ -692,7 +692,7 @@ func (m *GetTransactionsRequest) Reset() { *m = GetTransactionsRequest{}
func (m *GetTransactionsRequest) String() string { return proto.CompactTextString(m) }
func (*GetTransactionsRequest) ProtoMessage() {}
func (*GetTransactionsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{10}
return fileDescriptor_rpc_e66000aa8614d793, []int{10}
}
func (m *GetTransactionsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetTransactionsRequest.Unmarshal(m, b)
@ -724,7 +724,7 @@ func (m *TransactionDetails) Reset() { *m = TransactionDetails{} }
func (m *TransactionDetails) String() string { return proto.CompactTextString(m) }
func (*TransactionDetails) ProtoMessage() {}
func (*TransactionDetails) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{11}
return fileDescriptor_rpc_e66000aa8614d793, []int{11}
}
func (m *TransactionDetails) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TransactionDetails.Unmarshal(m, b)
@ -765,7 +765,7 @@ func (m *FeeLimit) Reset() { *m = FeeLimit{} }
func (m *FeeLimit) String() string { return proto.CompactTextString(m) }
func (*FeeLimit) ProtoMessage() {}
func (*FeeLimit) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{12}
return fileDescriptor_rpc_e66000aa8614d793, []int{12}
}
func (m *FeeLimit) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FeeLimit.Unmarshal(m, b)
@ -921,7 +921,7 @@ func (m *SendRequest) Reset() { *m = SendRequest{} }
func (m *SendRequest) String() string { return proto.CompactTextString(m) }
func (*SendRequest) ProtoMessage() {}
func (*SendRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{13}
return fileDescriptor_rpc_e66000aa8614d793, []int{13}
}
func (m *SendRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendRequest.Unmarshal(m, b)
@ -1011,7 +1011,7 @@ func (m *SendResponse) Reset() { *m = SendResponse{} }
func (m *SendResponse) String() string { return proto.CompactTextString(m) }
func (*SendResponse) ProtoMessage() {}
func (*SendResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{14}
return fileDescriptor_rpc_e66000aa8614d793, []int{14}
}
func (m *SendResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendResponse.Unmarshal(m, b)
@ -1075,7 +1075,7 @@ func (m *SendToRouteRequest) Reset() { *m = SendToRouteRequest{} }
func (m *SendToRouteRequest) String() string { return proto.CompactTextString(m) }
func (*SendToRouteRequest) ProtoMessage() {}
func (*SendToRouteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{15}
return fileDescriptor_rpc_e66000aa8614d793, []int{15}
}
func (m *SendToRouteRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendToRouteRequest.Unmarshal(m, b)
@ -1132,7 +1132,7 @@ func (m *ChannelPoint) Reset() { *m = ChannelPoint{} }
func (m *ChannelPoint) String() string { return proto.CompactTextString(m) }
func (*ChannelPoint) ProtoMessage() {}
func (*ChannelPoint) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{16}
return fileDescriptor_rpc_e66000aa8614d793, []int{16}
}
func (m *ChannelPoint) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelPoint.Unmarshal(m, b)
@ -1276,7 +1276,7 @@ func (m *LightningAddress) Reset() { *m = LightningAddress{} }
func (m *LightningAddress) String() string { return proto.CompactTextString(m) }
func (*LightningAddress) ProtoMessage() {}
func (*LightningAddress) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{17}
return fileDescriptor_rpc_e66000aa8614d793, []int{17}
}
func (m *LightningAddress) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LightningAddress.Unmarshal(m, b)
@ -1326,7 +1326,7 @@ func (m *SendManyRequest) Reset() { *m = SendManyRequest{} }
func (m *SendManyRequest) String() string { return proto.CompactTextString(m) }
func (*SendManyRequest) ProtoMessage() {}
func (*SendManyRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{18}
return fileDescriptor_rpc_e66000aa8614d793, []int{18}
}
func (m *SendManyRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendManyRequest.Unmarshal(m, b)
@ -1379,7 +1379,7 @@ func (m *SendManyResponse) Reset() { *m = SendManyResponse{} }
func (m *SendManyResponse) String() string { return proto.CompactTextString(m) }
func (*SendManyResponse) ProtoMessage() {}
func (*SendManyResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{19}
return fileDescriptor_rpc_e66000aa8614d793, []int{19}
}
func (m *SendManyResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendManyResponse.Unmarshal(m, b)
@ -1414,7 +1414,12 @@ type SendCoinsRequest struct {
// / The target number of blocks that this transaction should be confirmed by.
TargetConf int32 `protobuf:"varint,3,opt,name=target_conf,json=targetConf,proto3" json:"target_conf,omitempty"`
// / A manual fee rate set in sat/byte that should be used when crafting the transaction.
SatPerByte int64 `protobuf:"varint,5,opt,name=sat_per_byte,json=satPerByte,proto3" json:"sat_per_byte,omitempty"`
SatPerByte int64 `protobuf:"varint,5,opt,name=sat_per_byte,json=satPerByte,proto3" json:"sat_per_byte,omitempty"`
// *
// If set, then the amount field will be ignored, and lnd will attempt to
// send all the coins under control of the internal wallet to the specified
// address.
SendAll bool `protobuf:"varint,6,opt,name=send_all,json=sendAll,proto3" json:"send_all,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1424,7 +1429,7 @@ func (m *SendCoinsRequest) Reset() { *m = SendCoinsRequest{} }
func (m *SendCoinsRequest) String() string { return proto.CompactTextString(m) }
func (*SendCoinsRequest) ProtoMessage() {}
func (*SendCoinsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{20}
return fileDescriptor_rpc_e66000aa8614d793, []int{20}
}
func (m *SendCoinsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendCoinsRequest.Unmarshal(m, b)
@ -1472,6 +1477,13 @@ func (m *SendCoinsRequest) GetSatPerByte() int64 {
return 0
}
func (m *SendCoinsRequest) GetSendAll() bool {
if m != nil {
return m.SendAll
}
return false
}
type SendCoinsResponse struct {
// / The transaction ID of the transaction
Txid string `protobuf:"bytes,1,opt,name=txid,proto3" json:"txid,omitempty"`
@ -1484,7 +1496,7 @@ func (m *SendCoinsResponse) Reset() { *m = SendCoinsResponse{} }
func (m *SendCoinsResponse) String() string { return proto.CompactTextString(m) }
func (*SendCoinsResponse) ProtoMessage() {}
func (*SendCoinsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{21}
return fileDescriptor_rpc_e66000aa8614d793, []int{21}
}
func (m *SendCoinsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendCoinsResponse.Unmarshal(m, b)
@ -1525,7 +1537,7 @@ func (m *ListUnspentRequest) Reset() { *m = ListUnspentRequest{} }
func (m *ListUnspentRequest) String() string { return proto.CompactTextString(m) }
func (*ListUnspentRequest) ProtoMessage() {}
func (*ListUnspentRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{22}
return fileDescriptor_rpc_e66000aa8614d793, []int{22}
}
func (m *ListUnspentRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListUnspentRequest.Unmarshal(m, b)
@ -1571,7 +1583,7 @@ func (m *ListUnspentResponse) Reset() { *m = ListUnspentResponse{} }
func (m *ListUnspentResponse) String() string { return proto.CompactTextString(m) }
func (*ListUnspentResponse) ProtoMessage() {}
func (*ListUnspentResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{23}
return fileDescriptor_rpc_e66000aa8614d793, []int{23}
}
func (m *ListUnspentResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListUnspentResponse.Unmarshal(m, b)
@ -1610,7 +1622,7 @@ func (m *NewAddressRequest) Reset() { *m = NewAddressRequest{} }
func (m *NewAddressRequest) String() string { return proto.CompactTextString(m) }
func (*NewAddressRequest) ProtoMessage() {}
func (*NewAddressRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{24}
return fileDescriptor_rpc_e66000aa8614d793, []int{24}
}
func (m *NewAddressRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NewAddressRequest.Unmarshal(m, b)
@ -1649,7 +1661,7 @@ func (m *NewAddressResponse) Reset() { *m = NewAddressResponse{} }
func (m *NewAddressResponse) String() string { return proto.CompactTextString(m) }
func (*NewAddressResponse) ProtoMessage() {}
func (*NewAddressResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{25}
return fileDescriptor_rpc_e66000aa8614d793, []int{25}
}
func (m *NewAddressResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NewAddressResponse.Unmarshal(m, b)
@ -1688,7 +1700,7 @@ func (m *SignMessageRequest) Reset() { *m = SignMessageRequest{} }
func (m *SignMessageRequest) String() string { return proto.CompactTextString(m) }
func (*SignMessageRequest) ProtoMessage() {}
func (*SignMessageRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{26}
return fileDescriptor_rpc_e66000aa8614d793, []int{26}
}
func (m *SignMessageRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SignMessageRequest.Unmarshal(m, b)
@ -1727,7 +1739,7 @@ func (m *SignMessageResponse) Reset() { *m = SignMessageResponse{} }
func (m *SignMessageResponse) String() string { return proto.CompactTextString(m) }
func (*SignMessageResponse) ProtoMessage() {}
func (*SignMessageResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{27}
return fileDescriptor_rpc_e66000aa8614d793, []int{27}
}
func (m *SignMessageResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SignMessageResponse.Unmarshal(m, b)
@ -1768,7 +1780,7 @@ func (m *VerifyMessageRequest) Reset() { *m = VerifyMessageRequest{} }
func (m *VerifyMessageRequest) String() string { return proto.CompactTextString(m) }
func (*VerifyMessageRequest) ProtoMessage() {}
func (*VerifyMessageRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{28}
return fileDescriptor_rpc_e66000aa8614d793, []int{28}
}
func (m *VerifyMessageRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VerifyMessageRequest.Unmarshal(m, b)
@ -1816,7 +1828,7 @@ func (m *VerifyMessageResponse) Reset() { *m = VerifyMessageResponse{} }
func (m *VerifyMessageResponse) String() string { return proto.CompactTextString(m) }
func (*VerifyMessageResponse) ProtoMessage() {}
func (*VerifyMessageResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{29}
return fileDescriptor_rpc_e66000aa8614d793, []int{29}
}
func (m *VerifyMessageResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VerifyMessageResponse.Unmarshal(m, b)
@ -1865,7 +1877,7 @@ func (m *ConnectPeerRequest) Reset() { *m = ConnectPeerRequest{} }
func (m *ConnectPeerRequest) String() string { return proto.CompactTextString(m) }
func (*ConnectPeerRequest) ProtoMessage() {}
func (*ConnectPeerRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{30}
return fileDescriptor_rpc_e66000aa8614d793, []int{30}
}
func (m *ConnectPeerRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ConnectPeerRequest.Unmarshal(m, b)
@ -1909,7 +1921,7 @@ func (m *ConnectPeerResponse) Reset() { *m = ConnectPeerResponse{} }
func (m *ConnectPeerResponse) String() string { return proto.CompactTextString(m) }
func (*ConnectPeerResponse) ProtoMessage() {}
func (*ConnectPeerResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{31}
return fileDescriptor_rpc_e66000aa8614d793, []int{31}
}
func (m *ConnectPeerResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ConnectPeerResponse.Unmarshal(m, b)
@ -1941,7 +1953,7 @@ func (m *DisconnectPeerRequest) Reset() { *m = DisconnectPeerRequest{} }
func (m *DisconnectPeerRequest) String() string { return proto.CompactTextString(m) }
func (*DisconnectPeerRequest) ProtoMessage() {}
func (*DisconnectPeerRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{32}
return fileDescriptor_rpc_e66000aa8614d793, []int{32}
}
func (m *DisconnectPeerRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DisconnectPeerRequest.Unmarshal(m, b)
@ -1978,7 +1990,7 @@ func (m *DisconnectPeerResponse) Reset() { *m = DisconnectPeerResponse{}
func (m *DisconnectPeerResponse) String() string { return proto.CompactTextString(m) }
func (*DisconnectPeerResponse) ProtoMessage() {}
func (*DisconnectPeerResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{33}
return fileDescriptor_rpc_e66000aa8614d793, []int{33}
}
func (m *DisconnectPeerResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DisconnectPeerResponse.Unmarshal(m, b)
@ -2012,7 +2024,7 @@ func (m *HTLC) Reset() { *m = HTLC{} }
func (m *HTLC) String() string { return proto.CompactTextString(m) }
func (*HTLC) ProtoMessage() {}
func (*HTLC) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{34}
return fileDescriptor_rpc_e66000aa8614d793, []int{34}
}
func (m *HTLC) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_HTLC.Unmarshal(m, b)
@ -2124,7 +2136,7 @@ func (m *Channel) Reset() { *m = Channel{} }
func (m *Channel) String() string { return proto.CompactTextString(m) }
func (*Channel) ProtoMessage() {}
func (*Channel) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{35}
return fileDescriptor_rpc_e66000aa8614d793, []int{35}
}
func (m *Channel) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Channel.Unmarshal(m, b)
@ -2277,7 +2289,7 @@ func (m *ListChannelsRequest) Reset() { *m = ListChannelsRequest{} }
func (m *ListChannelsRequest) String() string { return proto.CompactTextString(m) }
func (*ListChannelsRequest) ProtoMessage() {}
func (*ListChannelsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{36}
return fileDescriptor_rpc_e66000aa8614d793, []int{36}
}
func (m *ListChannelsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListChannelsRequest.Unmarshal(m, b)
@ -2337,7 +2349,7 @@ func (m *ListChannelsResponse) Reset() { *m = ListChannelsResponse{} }
func (m *ListChannelsResponse) String() string { return proto.CompactTextString(m) }
func (*ListChannelsResponse) ProtoMessage() {}
func (*ListChannelsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{37}
return fileDescriptor_rpc_e66000aa8614d793, []int{37}
}
func (m *ListChannelsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListChannelsResponse.Unmarshal(m, b)
@ -2394,7 +2406,7 @@ func (m *ChannelCloseSummary) Reset() { *m = ChannelCloseSummary{} }
func (m *ChannelCloseSummary) String() string { return proto.CompactTextString(m) }
func (*ChannelCloseSummary) ProtoMessage() {}
func (*ChannelCloseSummary) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{38}
return fileDescriptor_rpc_e66000aa8614d793, []int{38}
}
func (m *ChannelCloseSummary) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelCloseSummary.Unmarshal(m, b)
@ -2500,7 +2512,7 @@ func (m *ClosedChannelsRequest) Reset() { *m = ClosedChannelsRequest{} }
func (m *ClosedChannelsRequest) String() string { return proto.CompactTextString(m) }
func (*ClosedChannelsRequest) ProtoMessage() {}
func (*ClosedChannelsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{39}
return fileDescriptor_rpc_e66000aa8614d793, []int{39}
}
func (m *ClosedChannelsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ClosedChannelsRequest.Unmarshal(m, b)
@ -2573,7 +2585,7 @@ func (m *ClosedChannelsResponse) Reset() { *m = ClosedChannelsResponse{}
func (m *ClosedChannelsResponse) String() string { return proto.CompactTextString(m) }
func (*ClosedChannelsResponse) ProtoMessage() {}
func (*ClosedChannelsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{40}
return fileDescriptor_rpc_e66000aa8614d793, []int{40}
}
func (m *ClosedChannelsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ClosedChannelsResponse.Unmarshal(m, b)
@ -2626,7 +2638,7 @@ func (m *Peer) Reset() { *m = Peer{} }
func (m *Peer) String() string { return proto.CompactTextString(m) }
func (*Peer) ProtoMessage() {}
func (*Peer) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{41}
return fileDescriptor_rpc_e66000aa8614d793, []int{41}
}
func (m *Peer) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Peer.Unmarshal(m, b)
@ -2712,7 +2724,7 @@ func (m *ListPeersRequest) Reset() { *m = ListPeersRequest{} }
func (m *ListPeersRequest) String() string { return proto.CompactTextString(m) }
func (*ListPeersRequest) ProtoMessage() {}
func (*ListPeersRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{42}
return fileDescriptor_rpc_e66000aa8614d793, []int{42}
}
func (m *ListPeersRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListPeersRequest.Unmarshal(m, b)
@ -2744,7 +2756,7 @@ func (m *ListPeersResponse) Reset() { *m = ListPeersResponse{} }
func (m *ListPeersResponse) String() string { return proto.CompactTextString(m) }
func (*ListPeersResponse) ProtoMessage() {}
func (*ListPeersResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{43}
return fileDescriptor_rpc_e66000aa8614d793, []int{43}
}
func (m *ListPeersResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListPeersResponse.Unmarshal(m, b)
@ -2781,7 +2793,7 @@ func (m *GetInfoRequest) Reset() { *m = GetInfoRequest{} }
func (m *GetInfoRequest) String() string { return proto.CompactTextString(m) }
func (*GetInfoRequest) ProtoMessage() {}
func (*GetInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{44}
return fileDescriptor_rpc_e66000aa8614d793, []int{44}
}
func (m *GetInfoRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetInfoRequest.Unmarshal(m, b)
@ -2841,7 +2853,7 @@ func (m *GetInfoResponse) Reset() { *m = GetInfoResponse{} }
func (m *GetInfoResponse) String() string { return proto.CompactTextString(m) }
func (*GetInfoResponse) ProtoMessage() {}
func (*GetInfoResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{45}
return fileDescriptor_rpc_e66000aa8614d793, []int{45}
}
func (m *GetInfoResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetInfoResponse.Unmarshal(m, b)
@ -2961,7 +2973,9 @@ func (m *GetInfoResponse) GetChains() []*Chain {
}
type Chain struct {
Chain string `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"`
// / The blockchain the node is on (eg bitcoin, litecoin)
Chain string `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"`
// / The network the node is on (eg regtest, testnet, mainnet)
Network string `protobuf:"bytes,2,opt,name=network,proto3" json:"network,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@ -2972,7 +2986,7 @@ func (m *Chain) Reset() { *m = Chain{} }
func (m *Chain) String() string { return proto.CompactTextString(m) }
func (*Chain) ProtoMessage() {}
func (*Chain) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{46}
return fileDescriptor_rpc_e66000aa8614d793, []int{46}
}
func (m *Chain) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Chain.Unmarshal(m, b)
@ -3019,7 +3033,7 @@ func (m *ConfirmationUpdate) Reset() { *m = ConfirmationUpdate{} }
func (m *ConfirmationUpdate) String() string { return proto.CompactTextString(m) }
func (*ConfirmationUpdate) ProtoMessage() {}
func (*ConfirmationUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{47}
return fileDescriptor_rpc_e66000aa8614d793, []int{47}
}
func (m *ConfirmationUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ConfirmationUpdate.Unmarshal(m, b)
@ -3071,7 +3085,7 @@ func (m *ChannelOpenUpdate) Reset() { *m = ChannelOpenUpdate{} }
func (m *ChannelOpenUpdate) String() string { return proto.CompactTextString(m) }
func (*ChannelOpenUpdate) ProtoMessage() {}
func (*ChannelOpenUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{48}
return fileDescriptor_rpc_e66000aa8614d793, []int{48}
}
func (m *ChannelOpenUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelOpenUpdate.Unmarshal(m, b)
@ -3110,7 +3124,7 @@ func (m *ChannelCloseUpdate) Reset() { *m = ChannelCloseUpdate{} }
func (m *ChannelCloseUpdate) String() string { return proto.CompactTextString(m) }
func (*ChannelCloseUpdate) ProtoMessage() {}
func (*ChannelCloseUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{49}
return fileDescriptor_rpc_e66000aa8614d793, []int{49}
}
func (m *ChannelCloseUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelCloseUpdate.Unmarshal(m, b)
@ -3165,7 +3179,7 @@ func (m *CloseChannelRequest) Reset() { *m = CloseChannelRequest{} }
func (m *CloseChannelRequest) String() string { return proto.CompactTextString(m) }
func (*CloseChannelRequest) ProtoMessage() {}
func (*CloseChannelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{50}
return fileDescriptor_rpc_e66000aa8614d793, []int{50}
}
func (m *CloseChannelRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CloseChannelRequest.Unmarshal(m, b)
@ -3227,7 +3241,7 @@ func (m *CloseStatusUpdate) Reset() { *m = CloseStatusUpdate{} }
func (m *CloseStatusUpdate) String() string { return proto.CompactTextString(m) }
func (*CloseStatusUpdate) ProtoMessage() {}
func (*CloseStatusUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{51}
return fileDescriptor_rpc_e66000aa8614d793, []int{51}
}
func (m *CloseStatusUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CloseStatusUpdate.Unmarshal(m, b)
@ -3370,7 +3384,7 @@ func (m *PendingUpdate) Reset() { *m = PendingUpdate{} }
func (m *PendingUpdate) String() string { return proto.CompactTextString(m) }
func (*PendingUpdate) ProtoMessage() {}
func (*PendingUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{52}
return fileDescriptor_rpc_e66000aa8614d793, []int{52}
}
func (m *PendingUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingUpdate.Unmarshal(m, b)
@ -3436,7 +3450,7 @@ func (m *OpenChannelRequest) Reset() { *m = OpenChannelRequest{} }
func (m *OpenChannelRequest) String() string { return proto.CompactTextString(m) }
func (*OpenChannelRequest) ProtoMessage() {}
func (*OpenChannelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{53}
return fileDescriptor_rpc_e66000aa8614d793, []int{53}
}
func (m *OpenChannelRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_OpenChannelRequest.Unmarshal(m, b)
@ -3547,7 +3561,7 @@ func (m *OpenStatusUpdate) Reset() { *m = OpenStatusUpdate{} }
func (m *OpenStatusUpdate) String() string { return proto.CompactTextString(m) }
func (*OpenStatusUpdate) ProtoMessage() {}
func (*OpenStatusUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{54}
return fileDescriptor_rpc_e66000aa8614d793, []int{54}
}
func (m *OpenStatusUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_OpenStatusUpdate.Unmarshal(m, b)
@ -3703,7 +3717,7 @@ func (m *PendingHTLC) Reset() { *m = PendingHTLC{} }
func (m *PendingHTLC) String() string { return proto.CompactTextString(m) }
func (*PendingHTLC) ProtoMessage() {}
func (*PendingHTLC) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{55}
return fileDescriptor_rpc_e66000aa8614d793, []int{55}
}
func (m *PendingHTLC) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingHTLC.Unmarshal(m, b)
@ -3775,7 +3789,7 @@ func (m *PendingChannelsRequest) Reset() { *m = PendingChannelsRequest{}
func (m *PendingChannelsRequest) String() string { return proto.CompactTextString(m) }
func (*PendingChannelsRequest) ProtoMessage() {}
func (*PendingChannelsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{56}
return fileDescriptor_rpc_e66000aa8614d793, []int{56}
}
func (m *PendingChannelsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingChannelsRequest.Unmarshal(m, b)
@ -3815,7 +3829,7 @@ func (m *PendingChannelsResponse) Reset() { *m = PendingChannelsResponse
func (m *PendingChannelsResponse) String() string { return proto.CompactTextString(m) }
func (*PendingChannelsResponse) ProtoMessage() {}
func (*PendingChannelsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{57}
return fileDescriptor_rpc_e66000aa8614d793, []int{57}
}
func (m *PendingChannelsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingChannelsResponse.Unmarshal(m, b)
@ -3887,7 +3901,7 @@ func (m *PendingChannelsResponse_PendingChannel) Reset() {
func (m *PendingChannelsResponse_PendingChannel) String() string { return proto.CompactTextString(m) }
func (*PendingChannelsResponse_PendingChannel) ProtoMessage() {}
func (*PendingChannelsResponse_PendingChannel) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{57, 0}
return fileDescriptor_rpc_e66000aa8614d793, []int{57, 0}
}
func (m *PendingChannelsResponse_PendingChannel) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingChannelsResponse_PendingChannel.Unmarshal(m, b)
@ -3974,7 +3988,7 @@ func (m *PendingChannelsResponse_PendingOpenChannel) String() string {
}
func (*PendingChannelsResponse_PendingOpenChannel) ProtoMessage() {}
func (*PendingChannelsResponse_PendingOpenChannel) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{57, 1}
return fileDescriptor_rpc_e66000aa8614d793, []int{57, 1}
}
func (m *PendingChannelsResponse_PendingOpenChannel) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingChannelsResponse_PendingOpenChannel.Unmarshal(m, b)
@ -4047,7 +4061,7 @@ func (m *PendingChannelsResponse_WaitingCloseChannel) String() string {
}
func (*PendingChannelsResponse_WaitingCloseChannel) ProtoMessage() {}
func (*PendingChannelsResponse_WaitingCloseChannel) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{57, 2}
return fileDescriptor_rpc_e66000aa8614d793, []int{57, 2}
}
func (m *PendingChannelsResponse_WaitingCloseChannel) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingChannelsResponse_WaitingCloseChannel.Unmarshal(m, b)
@ -4095,7 +4109,7 @@ func (m *PendingChannelsResponse_ClosedChannel) Reset() { *m = PendingCh
func (m *PendingChannelsResponse_ClosedChannel) String() string { return proto.CompactTextString(m) }
func (*PendingChannelsResponse_ClosedChannel) ProtoMessage() {}
func (*PendingChannelsResponse_ClosedChannel) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{57, 3}
return fileDescriptor_rpc_e66000aa8614d793, []int{57, 3}
}
func (m *PendingChannelsResponse_ClosedChannel) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingChannelsResponse_ClosedChannel.Unmarshal(m, b)
@ -4159,7 +4173,7 @@ func (m *PendingChannelsResponse_ForceClosedChannel) String() string {
}
func (*PendingChannelsResponse_ForceClosedChannel) ProtoMessage() {}
func (*PendingChannelsResponse_ForceClosedChannel) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{57, 4}
return fileDescriptor_rpc_e66000aa8614d793, []int{57, 4}
}
func (m *PendingChannelsResponse_ForceClosedChannel) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PendingChannelsResponse_ForceClosedChannel.Unmarshal(m, b)
@ -4238,7 +4252,7 @@ func (m *WalletBalanceRequest) Reset() { *m = WalletBalanceRequest{} }
func (m *WalletBalanceRequest) String() string { return proto.CompactTextString(m) }
func (*WalletBalanceRequest) ProtoMessage() {}
func (*WalletBalanceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{58}
return fileDescriptor_rpc_e66000aa8614d793, []int{58}
}
func (m *WalletBalanceRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_WalletBalanceRequest.Unmarshal(m, b)
@ -4274,7 +4288,7 @@ func (m *WalletBalanceResponse) Reset() { *m = WalletBalanceResponse{} }
func (m *WalletBalanceResponse) String() string { return proto.CompactTextString(m) }
func (*WalletBalanceResponse) ProtoMessage() {}
func (*WalletBalanceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{59}
return fileDescriptor_rpc_e66000aa8614d793, []int{59}
}
func (m *WalletBalanceResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_WalletBalanceResponse.Unmarshal(m, b)
@ -4325,7 +4339,7 @@ func (m *ChannelBalanceRequest) Reset() { *m = ChannelBalanceRequest{} }
func (m *ChannelBalanceRequest) String() string { return proto.CompactTextString(m) }
func (*ChannelBalanceRequest) ProtoMessage() {}
func (*ChannelBalanceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{60}
return fileDescriptor_rpc_e66000aa8614d793, []int{60}
}
func (m *ChannelBalanceRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelBalanceRequest.Unmarshal(m, b)
@ -4359,7 +4373,7 @@ func (m *ChannelBalanceResponse) Reset() { *m = ChannelBalanceResponse{}
func (m *ChannelBalanceResponse) String() string { return proto.CompactTextString(m) }
func (*ChannelBalanceResponse) ProtoMessage() {}
func (*ChannelBalanceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{61}
return fileDescriptor_rpc_e66000aa8614d793, []int{61}
}
func (m *ChannelBalanceResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelBalanceResponse.Unmarshal(m, b)
@ -4417,7 +4431,7 @@ func (m *QueryRoutesRequest) Reset() { *m = QueryRoutesRequest{} }
func (m *QueryRoutesRequest) String() string { return proto.CompactTextString(m) }
func (*QueryRoutesRequest) ProtoMessage() {}
func (*QueryRoutesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{62}
return fileDescriptor_rpc_e66000aa8614d793, []int{62}
}
func (m *QueryRoutesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryRoutesRequest.Unmarshal(m, b)
@ -4483,7 +4497,7 @@ func (m *QueryRoutesResponse) Reset() { *m = QueryRoutesResponse{} }
func (m *QueryRoutesResponse) String() string { return proto.CompactTextString(m) }
func (*QueryRoutesResponse) ProtoMessage() {}
func (*QueryRoutesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{63}
return fileDescriptor_rpc_e66000aa8614d793, []int{63}
}
func (m *QueryRoutesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryRoutesResponse.Unmarshal(m, b)
@ -4535,7 +4549,7 @@ func (m *Hop) Reset() { *m = Hop{} }
func (m *Hop) String() string { return proto.CompactTextString(m) }
func (*Hop) ProtoMessage() {}
func (*Hop) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{64}
return fileDescriptor_rpc_e66000aa8614d793, []int{64}
}
func (m *Hop) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Hop.Unmarshal(m, b)
@ -4656,7 +4670,7 @@ func (m *Route) Reset() { *m = Route{} }
func (m *Route) String() string { return proto.CompactTextString(m) }
func (*Route) ProtoMessage() {}
func (*Route) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{65}
return fileDescriptor_rpc_e66000aa8614d793, []int{65}
}
func (m *Route) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Route.Unmarshal(m, b)
@ -4732,7 +4746,7 @@ func (m *NodeInfoRequest) Reset() { *m = NodeInfoRequest{} }
func (m *NodeInfoRequest) String() string { return proto.CompactTextString(m) }
func (*NodeInfoRequest) ProtoMessage() {}
func (*NodeInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{66}
return fileDescriptor_rpc_e66000aa8614d793, []int{66}
}
func (m *NodeInfoRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeInfoRequest.Unmarshal(m, b)
@ -4777,7 +4791,7 @@ func (m *NodeInfo) Reset() { *m = NodeInfo{} }
func (m *NodeInfo) String() string { return proto.CompactTextString(m) }
func (*NodeInfo) ProtoMessage() {}
func (*NodeInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{67}
return fileDescriptor_rpc_e66000aa8614d793, []int{67}
}
func (m *NodeInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeInfo.Unmarshal(m, b)
@ -4838,7 +4852,7 @@ func (m *LightningNode) Reset() { *m = LightningNode{} }
func (m *LightningNode) String() string { return proto.CompactTextString(m) }
func (*LightningNode) ProtoMessage() {}
func (*LightningNode) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{68}
return fileDescriptor_rpc_e66000aa8614d793, []int{68}
}
func (m *LightningNode) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LightningNode.Unmarshal(m, b)
@ -4905,7 +4919,7 @@ func (m *NodeAddress) Reset() { *m = NodeAddress{} }
func (m *NodeAddress) String() string { return proto.CompactTextString(m) }
func (*NodeAddress) ProtoMessage() {}
func (*NodeAddress) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{69}
return fileDescriptor_rpc_e66000aa8614d793, []int{69}
}
func (m *NodeAddress) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeAddress.Unmarshal(m, b)
@ -4954,7 +4968,7 @@ func (m *RoutingPolicy) Reset() { *m = RoutingPolicy{} }
func (m *RoutingPolicy) String() string { return proto.CompactTextString(m) }
func (*RoutingPolicy) ProtoMessage() {}
func (*RoutingPolicy) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{70}
return fileDescriptor_rpc_e66000aa8614d793, []int{70}
}
func (m *RoutingPolicy) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RoutingPolicy.Unmarshal(m, b)
@ -5037,7 +5051,7 @@ func (m *ChannelEdge) Reset() { *m = ChannelEdge{} }
func (m *ChannelEdge) String() string { return proto.CompactTextString(m) }
func (*ChannelEdge) ProtoMessage() {}
func (*ChannelEdge) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{71}
return fileDescriptor_rpc_e66000aa8614d793, []int{71}
}
func (m *ChannelEdge) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelEdge.Unmarshal(m, b)
@ -5128,7 +5142,7 @@ func (m *ChannelGraphRequest) Reset() { *m = ChannelGraphRequest{} }
func (m *ChannelGraphRequest) String() string { return proto.CompactTextString(m) }
func (*ChannelGraphRequest) ProtoMessage() {}
func (*ChannelGraphRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{72}
return fileDescriptor_rpc_e66000aa8614d793, []int{72}
}
func (m *ChannelGraphRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelGraphRequest.Unmarshal(m, b)
@ -5170,7 +5184,7 @@ func (m *ChannelGraph) Reset() { *m = ChannelGraph{} }
func (m *ChannelGraph) String() string { return proto.CompactTextString(m) }
func (*ChannelGraph) ProtoMessage() {}
func (*ChannelGraph) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{73}
return fileDescriptor_rpc_e66000aa8614d793, []int{73}
}
func (m *ChannelGraph) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelGraph.Unmarshal(m, b)
@ -5219,7 +5233,7 @@ func (m *ChanInfoRequest) Reset() { *m = ChanInfoRequest{} }
func (m *ChanInfoRequest) String() string { return proto.CompactTextString(m) }
func (*ChanInfoRequest) ProtoMessage() {}
func (*ChanInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{74}
return fileDescriptor_rpc_e66000aa8614d793, []int{74}
}
func (m *ChanInfoRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChanInfoRequest.Unmarshal(m, b)
@ -5256,7 +5270,7 @@ func (m *NetworkInfoRequest) Reset() { *m = NetworkInfoRequest{} }
func (m *NetworkInfoRequest) String() string { return proto.CompactTextString(m) }
func (*NetworkInfoRequest) ProtoMessage() {}
func (*NetworkInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{75}
return fileDescriptor_rpc_e66000aa8614d793, []int{75}
}
func (m *NetworkInfoRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NetworkInfoRequest.Unmarshal(m, b)
@ -5295,7 +5309,7 @@ func (m *NetworkInfo) Reset() { *m = NetworkInfo{} }
func (m *NetworkInfo) String() string { return proto.CompactTextString(m) }
func (*NetworkInfo) ProtoMessage() {}
func (*NetworkInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{76}
return fileDescriptor_rpc_e66000aa8614d793, []int{76}
}
func (m *NetworkInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NetworkInfo.Unmarshal(m, b)
@ -5388,7 +5402,7 @@ func (m *StopRequest) Reset() { *m = StopRequest{} }
func (m *StopRequest) String() string { return proto.CompactTextString(m) }
func (*StopRequest) ProtoMessage() {}
func (*StopRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{77}
return fileDescriptor_rpc_e66000aa8614d793, []int{77}
}
func (m *StopRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StopRequest.Unmarshal(m, b)
@ -5418,7 +5432,7 @@ func (m *StopResponse) Reset() { *m = StopResponse{} }
func (m *StopResponse) String() string { return proto.CompactTextString(m) }
func (*StopResponse) ProtoMessage() {}
func (*StopResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{78}
return fileDescriptor_rpc_e66000aa8614d793, []int{78}
}
func (m *StopResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StopResponse.Unmarshal(m, b)
@ -5448,7 +5462,7 @@ func (m *GraphTopologySubscription) Reset() { *m = GraphTopologySubscrip
func (m *GraphTopologySubscription) String() string { return proto.CompactTextString(m) }
func (*GraphTopologySubscription) ProtoMessage() {}
func (*GraphTopologySubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{79}
return fileDescriptor_rpc_e66000aa8614d793, []int{79}
}
func (m *GraphTopologySubscription) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GraphTopologySubscription.Unmarshal(m, b)
@ -5481,7 +5495,7 @@ func (m *GraphTopologyUpdate) Reset() { *m = GraphTopologyUpdate{} }
func (m *GraphTopologyUpdate) String() string { return proto.CompactTextString(m) }
func (*GraphTopologyUpdate) ProtoMessage() {}
func (*GraphTopologyUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{80}
return fileDescriptor_rpc_e66000aa8614d793, []int{80}
}
func (m *GraphTopologyUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GraphTopologyUpdate.Unmarshal(m, b)
@ -5536,7 +5550,7 @@ func (m *NodeUpdate) Reset() { *m = NodeUpdate{} }
func (m *NodeUpdate) String() string { return proto.CompactTextString(m) }
func (*NodeUpdate) ProtoMessage() {}
func (*NodeUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{81}
return fileDescriptor_rpc_e66000aa8614d793, []int{81}
}
func (m *NodeUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeUpdate.Unmarshal(m, b)
@ -5604,7 +5618,7 @@ func (m *ChannelEdgeUpdate) Reset() { *m = ChannelEdgeUpdate{} }
func (m *ChannelEdgeUpdate) String() string { return proto.CompactTextString(m) }
func (*ChannelEdgeUpdate) ProtoMessage() {}
func (*ChannelEdgeUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{82}
return fileDescriptor_rpc_e66000aa8614d793, []int{82}
}
func (m *ChannelEdgeUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelEdgeUpdate.Unmarshal(m, b)
@ -5684,7 +5698,7 @@ func (m *ClosedChannelUpdate) Reset() { *m = ClosedChannelUpdate{} }
func (m *ClosedChannelUpdate) String() string { return proto.CompactTextString(m) }
func (*ClosedChannelUpdate) ProtoMessage() {}
func (*ClosedChannelUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{83}
return fileDescriptor_rpc_e66000aa8614d793, []int{83}
}
func (m *ClosedChannelUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ClosedChannelUpdate.Unmarshal(m, b)
@ -5754,7 +5768,7 @@ func (m *HopHint) Reset() { *m = HopHint{} }
func (m *HopHint) String() string { return proto.CompactTextString(m) }
func (*HopHint) ProtoMessage() {}
func (*HopHint) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{84}
return fileDescriptor_rpc_e66000aa8614d793, []int{84}
}
func (m *HopHint) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_HopHint.Unmarshal(m, b)
@ -5823,7 +5837,7 @@ func (m *RouteHint) Reset() { *m = RouteHint{} }
func (m *RouteHint) String() string { return proto.CompactTextString(m) }
func (*RouteHint) ProtoMessage() {}
func (*RouteHint) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{85}
return fileDescriptor_rpc_e66000aa8614d793, []int{85}
}
func (m *RouteHint) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RouteHint.Unmarshal(m, b)
@ -5938,7 +5952,7 @@ func (m *Invoice) Reset() { *m = Invoice{} }
func (m *Invoice) String() string { return proto.CompactTextString(m) }
func (*Invoice) ProtoMessage() {}
func (*Invoice) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{86}
return fileDescriptor_rpc_e66000aa8614d793, []int{86}
}
func (m *Invoice) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Invoice.Unmarshal(m, b)
@ -6130,7 +6144,7 @@ func (m *AddInvoiceResponse) Reset() { *m = AddInvoiceResponse{} }
func (m *AddInvoiceResponse) String() string { return proto.CompactTextString(m) }
func (*AddInvoiceResponse) ProtoMessage() {}
func (*AddInvoiceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{87}
return fileDescriptor_rpc_e66000aa8614d793, []int{87}
}
func (m *AddInvoiceResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddInvoiceResponse.Unmarshal(m, b)
@ -6187,7 +6201,7 @@ func (m *PaymentHash) Reset() { *m = PaymentHash{} }
func (m *PaymentHash) String() string { return proto.CompactTextString(m) }
func (*PaymentHash) ProtoMessage() {}
func (*PaymentHash) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{88}
return fileDescriptor_rpc_e66000aa8614d793, []int{88}
}
func (m *PaymentHash) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PaymentHash.Unmarshal(m, b)
@ -6243,7 +6257,7 @@ func (m *ListInvoiceRequest) Reset() { *m = ListInvoiceRequest{} }
func (m *ListInvoiceRequest) String() string { return proto.CompactTextString(m) }
func (*ListInvoiceRequest) ProtoMessage() {}
func (*ListInvoiceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{89}
return fileDescriptor_rpc_e66000aa8614d793, []int{89}
}
func (m *ListInvoiceRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListInvoiceRequest.Unmarshal(m, b)
@ -6313,7 +6327,7 @@ func (m *ListInvoiceResponse) Reset() { *m = ListInvoiceResponse{} }
func (m *ListInvoiceResponse) String() string { return proto.CompactTextString(m) }
func (*ListInvoiceResponse) ProtoMessage() {}
func (*ListInvoiceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{90}
return fileDescriptor_rpc_e66000aa8614d793, []int{90}
}
func (m *ListInvoiceResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListInvoiceResponse.Unmarshal(m, b)
@ -6376,7 +6390,7 @@ func (m *InvoiceSubscription) Reset() { *m = InvoiceSubscription{} }
func (m *InvoiceSubscription) String() string { return proto.CompactTextString(m) }
func (*InvoiceSubscription) ProtoMessage() {}
func (*InvoiceSubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{91}
return fileDescriptor_rpc_e66000aa8614d793, []int{91}
}
func (m *InvoiceSubscription) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InvoiceSubscription.Unmarshal(m, b)
@ -6436,7 +6450,7 @@ func (m *Payment) Reset() { *m = Payment{} }
func (m *Payment) String() string { return proto.CompactTextString(m) }
func (*Payment) ProtoMessage() {}
func (*Payment) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{92}
return fileDescriptor_rpc_e66000aa8614d793, []int{92}
}
func (m *Payment) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Payment.Unmarshal(m, b)
@ -6523,7 +6537,7 @@ func (m *ListPaymentsRequest) Reset() { *m = ListPaymentsRequest{} }
func (m *ListPaymentsRequest) String() string { return proto.CompactTextString(m) }
func (*ListPaymentsRequest) ProtoMessage() {}
func (*ListPaymentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{93}
return fileDescriptor_rpc_e66000aa8614d793, []int{93}
}
func (m *ListPaymentsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListPaymentsRequest.Unmarshal(m, b)
@ -6555,7 +6569,7 @@ func (m *ListPaymentsResponse) Reset() { *m = ListPaymentsResponse{} }
func (m *ListPaymentsResponse) String() string { return proto.CompactTextString(m) }
func (*ListPaymentsResponse) ProtoMessage() {}
func (*ListPaymentsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{94}
return fileDescriptor_rpc_e66000aa8614d793, []int{94}
}
func (m *ListPaymentsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListPaymentsResponse.Unmarshal(m, b)
@ -6592,7 +6606,7 @@ func (m *DeleteAllPaymentsRequest) Reset() { *m = DeleteAllPaymentsReque
func (m *DeleteAllPaymentsRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteAllPaymentsRequest) ProtoMessage() {}
func (*DeleteAllPaymentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{95}
return fileDescriptor_rpc_e66000aa8614d793, []int{95}
}
func (m *DeleteAllPaymentsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteAllPaymentsRequest.Unmarshal(m, b)
@ -6622,7 +6636,7 @@ func (m *DeleteAllPaymentsResponse) Reset() { *m = DeleteAllPaymentsResp
func (m *DeleteAllPaymentsResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteAllPaymentsResponse) ProtoMessage() {}
func (*DeleteAllPaymentsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{96}
return fileDescriptor_rpc_e66000aa8614d793, []int{96}
}
func (m *DeleteAllPaymentsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteAllPaymentsResponse.Unmarshal(m, b)
@ -6653,7 +6667,7 @@ func (m *AbandonChannelRequest) Reset() { *m = AbandonChannelRequest{} }
func (m *AbandonChannelRequest) String() string { return proto.CompactTextString(m) }
func (*AbandonChannelRequest) ProtoMessage() {}
func (*AbandonChannelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{97}
return fileDescriptor_rpc_e66000aa8614d793, []int{97}
}
func (m *AbandonChannelRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AbandonChannelRequest.Unmarshal(m, b)
@ -6690,7 +6704,7 @@ func (m *AbandonChannelResponse) Reset() { *m = AbandonChannelResponse{}
func (m *AbandonChannelResponse) String() string { return proto.CompactTextString(m) }
func (*AbandonChannelResponse) ProtoMessage() {}
func (*AbandonChannelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{98}
return fileDescriptor_rpc_e66000aa8614d793, []int{98}
}
func (m *AbandonChannelResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AbandonChannelResponse.Unmarshal(m, b)
@ -6722,7 +6736,7 @@ func (m *DebugLevelRequest) Reset() { *m = DebugLevelRequest{} }
func (m *DebugLevelRequest) String() string { return proto.CompactTextString(m) }
func (*DebugLevelRequest) ProtoMessage() {}
func (*DebugLevelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{99}
return fileDescriptor_rpc_e66000aa8614d793, []int{99}
}
func (m *DebugLevelRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DebugLevelRequest.Unmarshal(m, b)
@ -6767,7 +6781,7 @@ func (m *DebugLevelResponse) Reset() { *m = DebugLevelResponse{} }
func (m *DebugLevelResponse) String() string { return proto.CompactTextString(m) }
func (*DebugLevelResponse) ProtoMessage() {}
func (*DebugLevelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{100}
return fileDescriptor_rpc_e66000aa8614d793, []int{100}
}
func (m *DebugLevelResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DebugLevelResponse.Unmarshal(m, b)
@ -6806,7 +6820,7 @@ func (m *PayReqString) Reset() { *m = PayReqString{} }
func (m *PayReqString) String() string { return proto.CompactTextString(m) }
func (*PayReqString) ProtoMessage() {}
func (*PayReqString) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{101}
return fileDescriptor_rpc_e66000aa8614d793, []int{101}
}
func (m *PayReqString) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PayReqString.Unmarshal(m, b)
@ -6853,7 +6867,7 @@ func (m *PayReq) Reset() { *m = PayReq{} }
func (m *PayReq) String() string { return proto.CompactTextString(m) }
func (*PayReq) ProtoMessage() {}
func (*PayReq) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{102}
return fileDescriptor_rpc_e66000aa8614d793, []int{102}
}
func (m *PayReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PayReq.Unmarshal(m, b)
@ -6953,7 +6967,7 @@ func (m *FeeReportRequest) Reset() { *m = FeeReportRequest{} }
func (m *FeeReportRequest) String() string { return proto.CompactTextString(m) }
func (*FeeReportRequest) ProtoMessage() {}
func (*FeeReportRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{103}
return fileDescriptor_rpc_e66000aa8614d793, []int{103}
}
func (m *FeeReportRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FeeReportRequest.Unmarshal(m, b)
@ -6991,7 +7005,7 @@ func (m *ChannelFeeReport) Reset() { *m = ChannelFeeReport{} }
func (m *ChannelFeeReport) String() string { return proto.CompactTextString(m) }
func (*ChannelFeeReport) ProtoMessage() {}
func (*ChannelFeeReport) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{104}
return fileDescriptor_rpc_e66000aa8614d793, []int{104}
}
func (m *ChannelFeeReport) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChannelFeeReport.Unmarshal(m, b)
@ -7057,7 +7071,7 @@ func (m *FeeReportResponse) Reset() { *m = FeeReportResponse{} }
func (m *FeeReportResponse) String() string { return proto.CompactTextString(m) }
func (*FeeReportResponse) ProtoMessage() {}
func (*FeeReportResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{105}
return fileDescriptor_rpc_e66000aa8614d793, []int{105}
}
func (m *FeeReportResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FeeReportResponse.Unmarshal(m, b)
@ -7125,7 +7139,7 @@ func (m *PolicyUpdateRequest) Reset() { *m = PolicyUpdateRequest{} }
func (m *PolicyUpdateRequest) String() string { return proto.CompactTextString(m) }
func (*PolicyUpdateRequest) ProtoMessage() {}
func (*PolicyUpdateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{106}
return fileDescriptor_rpc_e66000aa8614d793, []int{106}
}
func (m *PolicyUpdateRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PolicyUpdateRequest.Unmarshal(m, b)
@ -7286,7 +7300,7 @@ func (m *PolicyUpdateResponse) Reset() { *m = PolicyUpdateResponse{} }
func (m *PolicyUpdateResponse) String() string { return proto.CompactTextString(m) }
func (*PolicyUpdateResponse) ProtoMessage() {}
func (*PolicyUpdateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{107}
return fileDescriptor_rpc_e66000aa8614d793, []int{107}
}
func (m *PolicyUpdateResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PolicyUpdateResponse.Unmarshal(m, b)
@ -7324,7 +7338,7 @@ func (m *ForwardingHistoryRequest) Reset() { *m = ForwardingHistoryReque
func (m *ForwardingHistoryRequest) String() string { return proto.CompactTextString(m) }
func (*ForwardingHistoryRequest) ProtoMessage() {}
func (*ForwardingHistoryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{108}
return fileDescriptor_rpc_e66000aa8614d793, []int{108}
}
func (m *ForwardingHistoryRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ForwardingHistoryRequest.Unmarshal(m, b)
@ -7396,7 +7410,7 @@ func (m *ForwardingEvent) Reset() { *m = ForwardingEvent{} }
func (m *ForwardingEvent) String() string { return proto.CompactTextString(m) }
func (*ForwardingEvent) ProtoMessage() {}
func (*ForwardingEvent) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{109}
return fileDescriptor_rpc_e66000aa8614d793, []int{109}
}
func (m *ForwardingEvent) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ForwardingEvent.Unmarshal(m, b)
@ -7479,7 +7493,7 @@ func (m *ForwardingHistoryResponse) Reset() { *m = ForwardingHistoryResp
func (m *ForwardingHistoryResponse) String() string { return proto.CompactTextString(m) }
func (*ForwardingHistoryResponse) ProtoMessage() {}
func (*ForwardingHistoryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rpc_b1b9aa8c9dfaad66, []int{110}
return fileDescriptor_rpc_e66000aa8614d793, []int{110}
}
func (m *ForwardingHistoryResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ForwardingHistoryResponse.Unmarshal(m, b)
@ -9909,428 +9923,430 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{
Metadata: "rpc.proto",
}
func init() { proto.RegisterFile("rpc.proto", fileDescriptor_rpc_b1b9aa8c9dfaad66) }
func init() { proto.RegisterFile("rpc.proto", fileDescriptor_rpc_e66000aa8614d793) }
var fileDescriptor_rpc_b1b9aa8c9dfaad66 = []byte{
// 6718 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7c, 0x5b, 0x6c, 0x24, 0xd9,
0x59, 0xff, 0x54, 0xbb, 0xdb, 0xee, 0xfe, 0xba, 0xed, 0x6e, 0x1f, 0xdf, 0x7a, 0x7a, 0x67, 0x67,
0x67, 0x4f, 0x26, 0x3b, 0x13, 0xff, 0xf7, 0x3f, 0x9e, 0x9d, 0x24, 0xcb, 0x66, 0x17, 0x02, 0x1e,
0xdb, 0x33, 0x9e, 0xc4, 0x3b, 0xe3, 0x94, 0x67, 0x32, 0x64, 0x03, 0xea, 0x94, 0xbb, 0x8f, 0xdb,
0x95, 0xe9, 0xae, 0xea, 0x54, 0x55, 0xdb, 0xd3, 0x59, 0x56, 0xe2, 0x26, 0x90, 0x10, 0x11, 0x02,
0x5e, 0x08, 0x12, 0x42, 0x0a, 0x48, 0x24, 0x8f, 0xbc, 0x44, 0x48, 0xc0, 0x1b, 0x2f, 0x20, 0x21,
0x84, 0xf2, 0x88, 0xc4, 0x0b, 0xbc, 0x00, 0x82, 0x07, 0x24, 0x1e, 0x78, 0x00, 0xa1, 0xf3, 0x9d,
0x4b, 0x9d, 0x53, 0x55, 0x3d, 0x9e, 0x5c, 0xe0, 0xc9, 0x7d, 0x7e, 0xe7, 0xab, 0x73, 0xfd, 0x6e,
0xe7, 0x3b, 0xdf, 0x31, 0xd4, 0xa2, 0x71, 0xef, 0xd6, 0x38, 0x0a, 0x93, 0x90, 0x54, 0x86, 0x41,
0x34, 0xee, 0x75, 0xae, 0x0c, 0xc2, 0x70, 0x30, 0x64, 0x5b, 0xde, 0xd8, 0xdf, 0xf2, 0x82, 0x20,
0x4c, 0xbc, 0xc4, 0x0f, 0x83, 0x58, 0x10, 0xd1, 0xaf, 0xc0, 0xd2, 0x7d, 0x16, 0x1c, 0x31, 0xd6,
0x77, 0xd9, 0xd7, 0x26, 0x2c, 0x4e, 0xc8, 0xff, 0x83, 0x65, 0x8f, 0x7d, 0x9d, 0xb1, 0x7e, 0x77,
0xec, 0xc5, 0xf1, 0xf8, 0x34, 0xf2, 0x62, 0xd6, 0x76, 0xae, 0x39, 0x37, 0x1b, 0x6e, 0x4b, 0x54,
0x1c, 0x6a, 0x9c, 0xbc, 0x0e, 0x8d, 0x98, 0x93, 0xb2, 0x20, 0x89, 0xc2, 0xf1, 0xb4, 0x5d, 0x42,
0xba, 0x3a, 0xc7, 0xf6, 0x04, 0x44, 0x87, 0xd0, 0xd4, 0x3d, 0xc4, 0xe3, 0x30, 0x88, 0x19, 0xb9,
0x0d, 0xab, 0x3d, 0x7f, 0x7c, 0xca, 0xa2, 0x2e, 0x7e, 0x3c, 0x0a, 0xd8, 0x28, 0x0c, 0xfc, 0x5e,
0xdb, 0xb9, 0x36, 0x77, 0xb3, 0xe6, 0x12, 0x51, 0xc7, 0xbf, 0x78, 0x5f, 0xd6, 0x90, 0x1b, 0xd0,
0x64, 0x81, 0xc0, 0x59, 0x1f, 0xbf, 0x92, 0x5d, 0x2d, 0xa5, 0x30, 0xff, 0x80, 0xfe, 0x85, 0x03,
0xcb, 0x0f, 0x02, 0x3f, 0x79, 0xea, 0x0d, 0x87, 0x2c, 0x51, 0x73, 0xba, 0x01, 0xcd, 0x73, 0x04,
0x70, 0x4e, 0xe7, 0x61, 0xd4, 0x97, 0x33, 0x5a, 0x12, 0xf0, 0xa1, 0x44, 0x67, 0x8e, 0xac, 0x34,
0x73, 0x64, 0x85, 0xcb, 0x35, 0x37, 0x63, 0xb9, 0x6e, 0x40, 0x33, 0x62, 0xbd, 0xf0, 0x8c, 0x45,
0xd3, 0xee, 0xb9, 0x1f, 0xf4, 0xc3, 0xf3, 0x76, 0xf9, 0x9a, 0x73, 0xb3, 0xe2, 0x2e, 0x29, 0xf8,
0x29, 0xa2, 0x74, 0x15, 0x88, 0x39, 0x0b, 0xb1, 0x6e, 0x74, 0x00, 0x2b, 0x4f, 0x82, 0x61, 0xd8,
0x7b, 0xf6, 0x03, 0xce, 0xae, 0xa0, 0xfb, 0x52, 0x61, 0xf7, 0xeb, 0xb0, 0x6a, 0x77, 0x24, 0x07,
0xc0, 0x60, 0x6d, 0xe7, 0xd4, 0x0b, 0x06, 0x4c, 0x35, 0xa9, 0x86, 0xf0, 0x09, 0x68, 0xf5, 0x26,
0x51, 0xc4, 0x82, 0xdc, 0x18, 0x9a, 0x12, 0xd7, 0x83, 0x78, 0x1d, 0x1a, 0x01, 0x3b, 0x4f, 0xc9,
0x24, 0xcb, 0x04, 0xec, 0x5c, 0x91, 0xd0, 0x36, 0xac, 0x67, 0xbb, 0x91, 0x03, 0xf8, 0x57, 0x07,
0xca, 0x4f, 0x92, 0xe7, 0x21, 0xb9, 0x05, 0xe5, 0x64, 0x3a, 0x16, 0x8c, 0xb9, 0x74, 0x87, 0xdc,
0x42, 0x5e, 0xbf, 0xb5, 0xdd, 0xef, 0x47, 0x2c, 0x8e, 0x1f, 0x4f, 0xc7, 0xcc, 0x6d, 0x78, 0xa2,
0xd0, 0xe5, 0x74, 0xa4, 0x0d, 0x0b, 0xb2, 0x8c, 0x1d, 0xd6, 0x5c, 0x55, 0x24, 0x57, 0x01, 0xbc,
0x51, 0x38, 0x09, 0x92, 0x6e, 0xec, 0x25, 0xb8, 0x73, 0x73, 0xae, 0x81, 0x90, 0xeb, 0xb0, 0x18,
0xf7, 0x22, 0x7f, 0x9c, 0x74, 0xc7, 0x93, 0xe3, 0x67, 0x6c, 0x8a, 0x3b, 0x56, 0x73, 0x6d, 0x90,
0x6c, 0x41, 0x35, 0x9c, 0x24, 0xe3, 0xd0, 0x0f, 0x92, 0x76, 0xe5, 0x9a, 0x73, 0xb3, 0x7e, 0x67,
0x45, 0x8e, 0x89, 0xcf, 0x24, 0x60, 0xc3, 0x43, 0x5e, 0xe5, 0x6a, 0x22, 0xde, 0x6c, 0x2f, 0x0c,
0x4e, 0xfc, 0x68, 0x24, 0xe4, 0xb1, 0x3d, 0x8f, 0x3d, 0xdb, 0x20, 0xfd, 0x66, 0x09, 0xea, 0x8f,
0x23, 0x2f, 0x88, 0xbd, 0x1e, 0x07, 0xf8, 0x34, 0x92, 0xe7, 0xdd, 0x53, 0x2f, 0x3e, 0xc5, 0x99,
0xd7, 0x5c, 0x55, 0x24, 0xeb, 0x30, 0x2f, 0x06, 0x8d, 0xf3, 0x9b, 0x73, 0x65, 0x89, 0xbc, 0x09,
0xcb, 0xc1, 0x64, 0xd4, 0xb5, 0xfb, 0x9a, 0xc3, 0x5d, 0xcf, 0x57, 0xf0, 0xc5, 0x38, 0xe6, 0xfb,
0x2e, 0xba, 0x10, 0x33, 0x35, 0x10, 0x42, 0xa1, 0x21, 0x4b, 0xcc, 0x1f, 0x9c, 0x8a, 0xa9, 0x56,
0x5c, 0x0b, 0xe3, 0x6d, 0x24, 0xfe, 0x88, 0x75, 0xe3, 0xc4, 0x1b, 0x8d, 0xe5, 0xb4, 0x0c, 0x04,
0xeb, 0xc3, 0xc4, 0x1b, 0x76, 0x4f, 0x18, 0x8b, 0xdb, 0x0b, 0xb2, 0x5e, 0x23, 0xe4, 0x0d, 0x58,
0xea, 0xb3, 0x38, 0xe9, 0xca, 0x0d, 0x62, 0x71, 0xbb, 0x8a, 0xd2, 0x97, 0x41, 0x39, 0x97, 0xdc,
0x67, 0x89, 0xb1, 0x3a, 0xb1, 0xe4, 0x46, 0x7a, 0x00, 0xc4, 0x80, 0x77, 0x59, 0xe2, 0xf9, 0xc3,
0x98, 0xbc, 0x0d, 0x8d, 0xc4, 0x20, 0x46, 0x6d, 0x53, 0xd7, 0xac, 0x63, 0x7c, 0xe0, 0x5a, 0x74,
0xf4, 0x3e, 0x54, 0xef, 0x31, 0x76, 0xe0, 0x8f, 0xfc, 0x84, 0xac, 0x43, 0xe5, 0xc4, 0x7f, 0xce,
0x04, 0x73, 0xcf, 0xed, 0x5f, 0x72, 0x45, 0x91, 0x74, 0x60, 0x61, 0xcc, 0xa2, 0x1e, 0x53, 0xcb,
0xbf, 0x7f, 0xc9, 0x55, 0xc0, 0xdd, 0x05, 0xa8, 0x0c, 0xf9, 0xc7, 0xf4, 0xdb, 0x25, 0xa8, 0x1f,
0xb1, 0x40, 0x0b, 0x0d, 0x81, 0x32, 0x9f, 0x92, 0x14, 0x14, 0xfc, 0x4d, 0x5e, 0x83, 0x3a, 0x4e,
0x33, 0x4e, 0x22, 0x3f, 0x18, 0x48, 0x5e, 0x05, 0x0e, 0x1d, 0x21, 0x42, 0x5a, 0x30, 0xe7, 0x8d,
0x14, 0x9f, 0xf2, 0x9f, 0x5c, 0xa0, 0xc6, 0xde, 0x74, 0xc4, 0x65, 0x4f, 0xef, 0x5a, 0xc3, 0xad,
0x4b, 0x6c, 0x9f, 0x6f, 0xdb, 0x2d, 0x58, 0x31, 0x49, 0x54, 0xeb, 0x15, 0x6c, 0x7d, 0xd9, 0xa0,
0x94, 0x9d, 0xdc, 0x80, 0xa6, 0xa2, 0x8f, 0xc4, 0x60, 0x71, 0x1f, 0x6b, 0xee, 0x92, 0x84, 0xd5,
0x14, 0x6e, 0x42, 0xeb, 0xc4, 0x0f, 0xbc, 0x61, 0xb7, 0x37, 0x4c, 0xce, 0xba, 0x7d, 0x36, 0x4c,
0x3c, 0xdc, 0xd1, 0x8a, 0xbb, 0x84, 0xf8, 0xce, 0x30, 0x39, 0xdb, 0xe5, 0x28, 0x79, 0x13, 0x6a,
0x27, 0x8c, 0x75, 0x71, 0x25, 0xda, 0x55, 0x94, 0x90, 0xa6, 0x5c, 0x7a, 0xb5, 0xba, 0x6e, 0xf5,
0x44, 0xfe, 0xa2, 0x7f, 0xe2, 0x40, 0x43, 0x2c, 0x95, 0x34, 0x19, 0xd7, 0x61, 0x51, 0x8d, 0x88,
0x45, 0x51, 0x18, 0x49, 0xf6, 0xb7, 0x41, 0xb2, 0x09, 0x2d, 0x05, 0x8c, 0x23, 0xe6, 0x8f, 0xbc,
0x01, 0x93, 0xfa, 0x25, 0x87, 0x93, 0x3b, 0x69, 0x8b, 0x51, 0x38, 0x49, 0x84, 0xd2, 0xae, 0xdf,
0x69, 0xc8, 0x41, 0xb9, 0x1c, 0x73, 0x6d, 0x12, 0xce, 0xfe, 0x05, 0x4b, 0x6d, 0x61, 0xf4, 0x1b,
0x0e, 0x10, 0x3e, 0xf4, 0xc7, 0xa1, 0x68, 0x42, 0xae, 0x54, 0x76, 0x97, 0x9c, 0x97, 0xde, 0xa5,
0xd2, 0xac, 0x5d, 0xba, 0x0e, 0xf3, 0x38, 0x2c, 0x2e, 0xcf, 0x73, 0xb9, 0xa1, 0xcb, 0x3a, 0xfa,
0x2d, 0x07, 0x1a, 0xa6, 0x0e, 0x22, 0xb7, 0x81, 0x9c, 0x4c, 0x82, 0xbe, 0x1f, 0x0c, 0xba, 0xc9,
0x73, 0xbf, 0xdf, 0x3d, 0x9e, 0xf2, 0x26, 0x70, 0x3c, 0xfb, 0x97, 0xdc, 0x82, 0x3a, 0xf2, 0x26,
0xb4, 0x2c, 0x34, 0x4e, 0x22, 0x31, 0xaa, 0xfd, 0x4b, 0x6e, 0xae, 0x86, 0x2f, 0x12, 0xd7, 0x72,
0x93, 0xa4, 0xeb, 0x07, 0x7d, 0xf6, 0x1c, 0xd7, 0x75, 0xd1, 0xb5, 0xb0, 0xbb, 0x4b, 0xd0, 0x30,
0xbf, 0xa3, 0x9f, 0x85, 0xd6, 0x01, 0x57, 0x1e, 0x81, 0x1f, 0x0c, 0xa4, 0x12, 0xe7, 0x1a, 0x4d,
0x6a, 0x5c, 0xb1, 0xd7, 0xb2, 0xc4, 0xc5, 0xe6, 0x34, 0x8c, 0x13, 0xb9, 0x2e, 0xf8, 0x9b, 0xfe,
0x83, 0x03, 0x4d, 0xbe, 0xe8, 0xef, 0x7b, 0xc1, 0x54, 0xad, 0xf8, 0x01, 0x34, 0x78, 0x53, 0x8f,
0xc3, 0x6d, 0xa1, 0x17, 0x85, 0xbc, 0xdf, 0x94, 0x8b, 0x94, 0xa1, 0xbe, 0x65, 0x92, 0x72, 0xd7,
0x65, 0xea, 0x5a, 0x5f, 0x73, 0xc1, 0x4c, 0xbc, 0x68, 0xc0, 0x12, 0xd4, 0x98, 0x52, 0x83, 0x82,
0x80, 0x76, 0xc2, 0xe0, 0x84, 0x5c, 0x83, 0x46, 0xec, 0x25, 0xdd, 0x31, 0x8b, 0x70, 0xd5, 0x50,
0xb8, 0xe6, 0x5c, 0x88, 0xbd, 0xe4, 0x90, 0x45, 0x77, 0xa7, 0x09, 0xeb, 0xfc, 0x24, 0x2c, 0xe7,
0x7a, 0xe1, 0xf2, 0x9c, 0x4e, 0x91, 0xff, 0x24, 0xab, 0x50, 0x39, 0xf3, 0x86, 0x13, 0x26, 0x15,
0xb9, 0x28, 0xbc, 0x5b, 0x7a, 0xc7, 0xa1, 0x6f, 0x40, 0x2b, 0x1d, 0xb6, 0x14, 0x0c, 0x02, 0x65,
0xbe, 0x82, 0xb2, 0x01, 0xfc, 0x4d, 0x7f, 0xc1, 0x11, 0x84, 0x3b, 0xa1, 0xaf, 0x95, 0x22, 0x27,
0xe4, 0xba, 0x53, 0x11, 0xf2, 0xdf, 0x33, 0x8d, 0xc6, 0x0f, 0x3f, 0x59, 0x7a, 0x03, 0x96, 0x8d,
0x21, 0xbc, 0x60, 0xb0, 0x0f, 0x81, 0x1c, 0xf8, 0x71, 0xf2, 0x24, 0x88, 0xc7, 0x86, 0x62, 0x79,
0x05, 0x6a, 0x23, 0x3f, 0xc0, 0xee, 0x05, 0x6f, 0x56, 0xdc, 0xea, 0xc8, 0x0f, 0x78, 0xe7, 0x31,
0x56, 0x7a, 0xcf, 0x65, 0x65, 0x49, 0x56, 0x7a, 0xcf, 0xb1, 0x92, 0xbe, 0x03, 0x2b, 0x56, 0x7b,
0xb2, 0xeb, 0xd7, 0xa1, 0x32, 0x49, 0x9e, 0x87, 0x4a, 0xed, 0xd7, 0x25, 0x1b, 0x70, 0x67, 0xc2,
0x15, 0x35, 0xf4, 0x3d, 0x58, 0x7e, 0xc8, 0xce, 0x25, 0xfb, 0xa9, 0x81, 0xbc, 0x71, 0xa1, 0xa3,
0x81, 0xf5, 0xf4, 0x16, 0x10, 0xf3, 0x63, 0xd9, 0xab, 0xe1, 0x76, 0x38, 0x96, 0xdb, 0x41, 0xdf,
0x00, 0x72, 0xe4, 0x0f, 0x82, 0xf7, 0x59, 0x1c, 0x7b, 0x03, 0xad, 0x25, 0x5a, 0x30, 0x37, 0x8a,
0x07, 0x52, 0x39, 0xf0, 0x9f, 0xf4, 0x93, 0xb0, 0x62, 0xd1, 0xc9, 0x86, 0xaf, 0x40, 0x2d, 0xf6,
0x07, 0x81, 0x97, 0x4c, 0x22, 0x26, 0x9b, 0x4e, 0x01, 0x7a, 0x0f, 0x56, 0xbf, 0xc8, 0x22, 0xff,
0x64, 0x7a, 0x51, 0xf3, 0x76, 0x3b, 0xa5, 0x6c, 0x3b, 0x7b, 0xb0, 0x96, 0x69, 0x47, 0x76, 0x2f,
0x78, 0x54, 0xee, 0x64, 0xd5, 0x15, 0x05, 0x43, 0x62, 0x4b, 0xa6, 0xc4, 0xd2, 0x27, 0x40, 0x76,
0xc2, 0x20, 0x60, 0xbd, 0xe4, 0x90, 0xb1, 0x28, 0x3d, 0x68, 0xa4, 0x0c, 0x59, 0xbf, 0xb3, 0x21,
0x57, 0x36, 0xab, 0x06, 0x24, 0xa7, 0x12, 0x28, 0x8f, 0x59, 0x34, 0xc2, 0x86, 0xab, 0x2e, 0xfe,
0xa6, 0x6b, 0xb0, 0x62, 0x35, 0x2b, 0x7d, 0xc4, 0xb7, 0x60, 0x6d, 0xd7, 0x8f, 0x7b, 0xf9, 0x0e,
0xdb, 0xb0, 0x30, 0x9e, 0x1c, 0x77, 0x53, 0x71, 0x53, 0x45, 0xee, 0x4a, 0x64, 0x3f, 0x91, 0x8d,
0xfd, 0x8a, 0x03, 0xe5, 0xfd, 0xc7, 0x07, 0x3b, 0xa4, 0x03, 0x55, 0x3f, 0xe8, 0x85, 0x23, 0xae,
0x91, 0xc5, 0xa4, 0x75, 0x79, 0xa6, 0x18, 0x5d, 0x81, 0x1a, 0x2a, 0x72, 0xee, 0x1d, 0xc9, 0x33,
0x41, 0x0a, 0x70, 0xcf, 0x8c, 0x3d, 0x1f, 0xfb, 0x11, 0xba, 0x5e, 0xca, 0xa1, 0x2a, 0xa3, 0xb2,
0xcc, 0x57, 0xd0, 0xff, 0x2e, 0xc3, 0x82, 0x54, 0xe3, 0xd8, 0x5f, 0x2f, 0xf1, 0xcf, 0x98, 0x1c,
0x89, 0x2c, 0x71, 0x23, 0x19, 0xb1, 0x51, 0x98, 0xb0, 0xae, 0xb5, 0x0d, 0x36, 0x88, 0x9e, 0xa7,
0x68, 0xa8, 0x2b, 0xfc, 0xd5, 0x39, 0x41, 0x65, 0x81, 0x7c, 0xb1, 0x38, 0xd0, 0xf5, 0xfb, 0x38,
0xa6, 0xb2, 0xab, 0x8a, 0x7c, 0x25, 0x7a, 0xde, 0xd8, 0xeb, 0xf9, 0xc9, 0x54, 0xca, 0xbd, 0x2e,
0xf3, 0xb6, 0x87, 0x61, 0xcf, 0x1b, 0x76, 0x8f, 0xbd, 0xa1, 0x17, 0xf4, 0x98, 0xf2, 0x6a, 0x2d,
0x90, 0x7b, 0x78, 0x72, 0x48, 0x8a, 0x4c, 0x78, 0x81, 0x19, 0x94, 0x7b, 0x8a, 0xbd, 0x70, 0x34,
0xf2, 0x13, 0xee, 0x18, 0xa2, 0xd3, 0x30, 0xe7, 0x1a, 0x88, 0xf0, 0xa1, 0xb1, 0x74, 0x2e, 0x56,
0xaf, 0xa6, 0x7c, 0x68, 0x03, 0xe4, 0xad, 0x70, 0xcf, 0x83, 0xeb, 0xaa, 0x67, 0xe7, 0x6d, 0x10,
0xad, 0xa4, 0x08, 0xdf, 0x87, 0x49, 0x10, 0xb3, 0x24, 0x19, 0xb2, 0xbe, 0x1e, 0x50, 0x1d, 0xc9,
0xf2, 0x15, 0xe4, 0x36, 0xac, 0x08, 0x5f, 0x35, 0xf6, 0x92, 0x30, 0x3e, 0xf5, 0xe3, 0x6e, 0xcc,
0xbd, 0xbe, 0x06, 0xd2, 0x17, 0x55, 0x91, 0x77, 0x60, 0x23, 0x03, 0x47, 0xac, 0xc7, 0xfc, 0x33,
0xd6, 0x6f, 0x2f, 0xe2, 0x57, 0xb3, 0xaa, 0xc9, 0x35, 0xa8, 0x73, 0x17, 0x7d, 0x32, 0xee, 0x7b,
0xdc, 0x44, 0x2f, 0xe1, 0x3e, 0x98, 0x10, 0x79, 0x0b, 0x16, 0xc7, 0x4c, 0xd8, 0xd1, 0xd3, 0x64,
0xd8, 0x8b, 0xdb, 0x4d, 0x4b, 0xbb, 0x71, 0xce, 0x75, 0x6d, 0x0a, 0xce, 0x94, 0xbd, 0x18, 0x7d,
0x35, 0x6f, 0xda, 0x6e, 0x21, 0xbb, 0xa5, 0x00, 0xca, 0x48, 0xe4, 0x9f, 0x79, 0x09, 0x6b, 0x2f,
0x23, 0x6f, 0xa9, 0x22, 0xfd, 0x7d, 0x47, 0x28, 0x56, 0xc9, 0x84, 0x5a, 0x41, 0xbe, 0x06, 0x75,
0xc1, 0x7e, 0xdd, 0x30, 0x18, 0x4e, 0x25, 0x47, 0x82, 0x80, 0x1e, 0x05, 0xc3, 0x29, 0xf9, 0x18,
0x2c, 0xfa, 0x81, 0x49, 0x22, 0x64, 0xb8, 0xa1, 0x40, 0x24, 0x7a, 0x0d, 0xea, 0xe3, 0xc9, 0xf1,
0xd0, 0xef, 0x09, 0x92, 0x39, 0xd1, 0x8a, 0x80, 0x90, 0x80, 0xfb, 0x4f, 0x62, 0x24, 0x82, 0xa2,
0x8c, 0x14, 0x75, 0x89, 0x71, 0x12, 0x7a, 0x17, 0x56, 0xed, 0x01, 0x4a, 0x65, 0xb5, 0x09, 0x55,
0xc9, 0xdb, 0x71, 0xbb, 0x8e, 0xeb, 0xb3, 0x64, 0x9f, 0xcd, 0x5c, 0x5d, 0x4f, 0xbf, 0x5b, 0x86,
0x15, 0x89, 0xee, 0x0c, 0xc3, 0x98, 0x1d, 0x4d, 0x46, 0x23, 0x2f, 0x2a, 0x10, 0x1a, 0xe7, 0x02,
0xa1, 0x29, 0xd9, 0x42, 0xc3, 0x59, 0xf9, 0xd4, 0xf3, 0x03, 0xe1, 0xfc, 0x09, 0x89, 0x33, 0x10,
0x72, 0x13, 0x9a, 0xbd, 0x61, 0x18, 0x0b, 0x87, 0xc8, 0x3c, 0x7d, 0x65, 0xe1, 0xbc, 0x90, 0x57,
0x8a, 0x84, 0xdc, 0x14, 0xd2, 0xf9, 0x8c, 0x90, 0x52, 0x68, 0xf0, 0x46, 0x99, 0xd2, 0x39, 0x0b,
0xc2, 0x41, 0x33, 0x31, 0x3e, 0x9e, 0xac, 0x48, 0x08, 0xf9, 0x6b, 0x16, 0x09, 0x04, 0x3f, 0xdc,
0x71, 0x9d, 0x66, 0x50, 0xd7, 0xa4, 0x40, 0xe4, 0xab, 0xc8, 0x3d, 0x00, 0xd1, 0x17, 0x1a, 0x56,
0x40, 0xc3, 0xfa, 0x86, 0xbd, 0x23, 0xe6, 0xda, 0xdf, 0xe2, 0x85, 0x49, 0xc4, 0xd0, 0xd8, 0x1a,
0x5f, 0xd2, 0x5f, 0x73, 0xa0, 0x6e, 0xd4, 0x91, 0x35, 0x58, 0xde, 0x79, 0xf4, 0xe8, 0x70, 0xcf,
0xdd, 0x7e, 0xfc, 0xe0, 0x8b, 0x7b, 0xdd, 0x9d, 0x83, 0x47, 0x47, 0x7b, 0xad, 0x4b, 0x1c, 0x3e,
0x78, 0xb4, 0xb3, 0x7d, 0xd0, 0xbd, 0xf7, 0xc8, 0xdd, 0x51, 0xb0, 0x43, 0xd6, 0x81, 0xb8, 0x7b,
0xef, 0x3f, 0x7a, 0xbc, 0x67, 0xe1, 0x25, 0xd2, 0x82, 0xc6, 0x5d, 0x77, 0x6f, 0x7b, 0x67, 0x5f,
0x22, 0x73, 0x64, 0x15, 0x5a, 0xf7, 0x9e, 0x3c, 0xdc, 0x7d, 0xf0, 0xf0, 0x7e, 0x77, 0x67, 0xfb,
0xe1, 0xce, 0xde, 0xc1, 0xde, 0x6e, 0xab, 0x4c, 0x16, 0xa1, 0xb6, 0x7d, 0x77, 0xfb, 0xe1, 0xee,
0xa3, 0x87, 0x7b, 0xbb, 0xad, 0x0a, 0xfd, 0x7b, 0x07, 0xd6, 0x70, 0xd4, 0xfd, 0xac, 0x80, 0x5c,
0x83, 0x7a, 0x2f, 0x0c, 0xc7, 0x8c, 0xeb, 0x73, 0xad, 0xb2, 0x4d, 0x88, 0x33, 0xbf, 0x50, 0x90,
0x27, 0x61, 0xd4, 0x63, 0x52, 0x3e, 0x00, 0xa1, 0x7b, 0x1c, 0xe1, 0xcc, 0x2f, 0xb7, 0x57, 0x50,
0x08, 0xf1, 0xa8, 0x0b, 0x4c, 0x90, 0xac, 0xc3, 0xfc, 0x71, 0xc4, 0xbc, 0xde, 0xa9, 0x94, 0x0c,
0x59, 0x22, 0x9f, 0x48, 0x7d, 0xf7, 0x1e, 0x5f, 0xfd, 0x21, 0xeb, 0x23, 0xc7, 0x54, 0xdd, 0xa6,
0xc4, 0x77, 0x24, 0xcc, 0x35, 0x83, 0x77, 0xec, 0x05, 0xfd, 0x30, 0x60, 0x7d, 0x64, 0x9a, 0xaa,
0x9b, 0x02, 0xf4, 0x10, 0xd6, 0xb3, 0xf3, 0x93, 0xf2, 0xf5, 0xb6, 0x21, 0x5f, 0xc2, 0xbb, 0xea,
0xcc, 0xde, 0x4d, 0x43, 0xd6, 0xfe, 0xd9, 0x81, 0x32, 0x37, 0xb6, 0xb3, 0x0d, 0xb3, 0xe9, 0x3f,
0xcd, 0xe5, 0xc2, 0x36, 0x78, 0x38, 0x11, 0xea, 0x57, 0x98, 0x28, 0x03, 0x49, 0xeb, 0x23, 0xd6,
0x3b, 0xc3, 0x19, 0xeb, 0x7a, 0x8e, 0x70, 0x01, 0xe1, 0x1e, 0x2c, 0x7e, 0x2d, 0x05, 0x44, 0x95,
0x55, 0x1d, 0x7e, 0xb9, 0x90, 0xd6, 0xe1, 0x77, 0x6d, 0x58, 0xf0, 0x83, 0xe3, 0x70, 0x12, 0xf4,
0x51, 0x20, 0xaa, 0xae, 0x2a, 0xf2, 0xe5, 0x1b, 0xa3, 0xa0, 0xfa, 0x23, 0xc5, 0xfe, 0x29, 0x40,
0x09, 0x3f, 0xe1, 0xc4, 0xe8, 0x5c, 0xe8, 0x38, 0xc5, 0xdb, 0xb0, 0x6c, 0x60, 0xa9, 0xa3, 0x3a,
0xe6, 0x40, 0xc6, 0x51, 0x45, 0xaf, 0x44, 0xd4, 0xd0, 0x16, 0x2c, 0xdd, 0x67, 0xc9, 0x83, 0xe0,
0x24, 0x54, 0x2d, 0xfd, 0x51, 0x19, 0x9a, 0x1a, 0x92, 0x0d, 0xdd, 0x84, 0xa6, 0xdf, 0x67, 0x41,
0xe2, 0x27, 0xd3, 0xae, 0x75, 0x90, 0xca, 0xc2, 0xdc, 0x9b, 0xf3, 0x86, 0xbe, 0xa7, 0x42, 0x63,
0xa2, 0x40, 0xee, 0xc0, 0x2a, 0x37, 0x35, 0xca, 0x7a, 0xe8, 0x2d, 0x16, 0xe7, 0xb9, 0xc2, 0x3a,
0xae, 0x0c, 0x38, 0x2e, 0xb5, 0xbd, 0xfe, 0x44, 0x78, 0x35, 0x45, 0x55, 0x7c, 0xd5, 0x44, 0x4b,
0x7c, 0xca, 0x15, 0x61, 0x8e, 0x34, 0x90, 0x8b, 0x37, 0xcd, 0x0b, 0x55, 0x95, 0x8d, 0x37, 0x19,
0x31, 0xab, 0x6a, 0x2e, 0x66, 0xc5, 0x55, 0xd9, 0x34, 0xe8, 0xb1, 0x7e, 0x37, 0x09, 0xbb, 0xa8,
0x72, 0x71, 0x77, 0xaa, 0x6e, 0x16, 0x26, 0x57, 0x60, 0x21, 0x61, 0x71, 0x12, 0xb0, 0x04, 0xb5,
0x52, 0xf5, 0x6e, 0xa9, 0xed, 0xb8, 0x0a, 0xe2, 0x2e, 0xe8, 0x24, 0xf2, 0xe3, 0x76, 0x03, 0xa3,
0x51, 0xf8, 0x9b, 0x7c, 0x0a, 0xd6, 0x8e, 0x59, 0x9c, 0x74, 0x4f, 0x99, 0xd7, 0x67, 0x11, 0xee,
0xb4, 0x08, 0x7b, 0x09, 0xcb, 0x5e, 0x5c, 0xc9, 0x79, 0xe8, 0x8c, 0x45, 0xb1, 0x1f, 0x06, 0x68,
0xd3, 0x6b, 0xae, 0x2a, 0xf2, 0xf6, 0xf8, 0xe4, 0xb5, 0xbd, 0xd4, 0x2b, 0xd8, 0xc4, 0x89, 0x17,
0x57, 0x92, 0xeb, 0x30, 0x8f, 0x13, 0x88, 0xdb, 0x2d, 0x2b, 0x10, 0xb0, 0xc3, 0x41, 0x57, 0xd6,
0x7d, 0xae, 0x5c, 0xad, 0xb7, 0x1a, 0xf4, 0xc7, 0xa0, 0x82, 0x30, 0xdf, 0x74, 0xb1, 0x18, 0x82,
0x29, 0x44, 0x81, 0x0f, 0x2d, 0x60, 0xc9, 0x79, 0x18, 0x3d, 0x53, 0x71, 0x52, 0x59, 0xa4, 0x5f,
0x47, 0x27, 0x5e, 0xc7, 0x0a, 0x9f, 0xa0, 0x07, 0xc2, 0x8f, 0x62, 0x62, 0xa9, 0xe3, 0x53, 0x4f,
0x9e, 0x2b, 0xaa, 0x08, 0x1c, 0x9d, 0x7a, 0x5c, 0x6d, 0x59, 0xbb, 0x27, 0x8e, 0x6a, 0x75, 0xc4,
0xf6, 0xc5, 0xe6, 0x5d, 0x87, 0x25, 0x15, 0x85, 0x8c, 0xbb, 0x43, 0x76, 0x92, 0xa8, 0x70, 0x41,
0x30, 0x19, 0xe1, 0x79, 0xee, 0x80, 0x9d, 0x24, 0xf4, 0x21, 0x2c, 0x4b, 0x55, 0xf2, 0x68, 0xcc,
0x54, 0xd7, 0x9f, 0x29, 0x32, 0xc9, 0x33, 0xe2, 0xae, 0x36, 0x25, 0x75, 0x81, 0x98, 0xaa, 0x49,
0x36, 0x28, 0xed, 0xa2, 0x0a, 0x4a, 0xc8, 0xe9, 0x58, 0x18, 0x5f, 0x9f, 0x78, 0xd2, 0xeb, 0xa9,
0x38, 0x72, 0xd5, 0x55, 0x45, 0xfa, 0x6d, 0x07, 0x56, 0xb0, 0x35, 0xe5, 0x54, 0x48, 0xf5, 0xff,
0xce, 0xf7, 0x31, 0xcc, 0x46, 0xcf, 0x0c, 0xd4, 0xac, 0x42, 0xc5, 0x34, 0x08, 0xa2, 0xf0, 0xfd,
0x9f, 0xcd, 0xcb, 0xb9, 0xb3, 0xf9, 0xef, 0x38, 0xb0, 0x2c, 0x74, 0x72, 0xe2, 0x25, 0x93, 0x58,
0x4e, 0xff, 0xc7, 0x61, 0x51, 0x18, 0x57, 0x29, 0xd5, 0x72, 0xa0, 0xab, 0x5a, 0x01, 0x21, 0x2a,
0x88, 0xf7, 0x2f, 0xb9, 0x36, 0x31, 0x79, 0x0f, 0x1d, 0x9c, 0xa0, 0x8b, 0xa8, 0x8c, 0xa5, 0x5d,
0x2e, 0x30, 0x03, 0xfa, 0x7b, 0x83, 0xfc, 0x6e, 0x15, 0xe6, 0x85, 0x47, 0x4b, 0xef, 0xc3, 0xa2,
0xd5, 0x91, 0x15, 0x32, 0x68, 0x88, 0x90, 0x41, 0x2e, 0xc2, 0x54, 0xca, 0x47, 0x98, 0xe8, 0x1f,
0xcf, 0x01, 0xe1, 0xcc, 0x92, 0xd9, 0x0d, 0xee, 0x52, 0x87, 0x7d, 0xeb, 0x80, 0xd4, 0x70, 0x4d,
0x88, 0xdc, 0x02, 0x62, 0x14, 0x55, 0x10, 0x4e, 0x58, 0x9f, 0x82, 0x1a, 0xae, 0x26, 0xa5, 0xf1,
0x96, 0x66, 0x56, 0x1e, 0x05, 0xc5, 0xb2, 0x17, 0xd6, 0x71, 0x03, 0x33, 0x9e, 0xc4, 0xa7, 0x78,
0xe3, 0x20, 0x8f, 0x50, 0xaa, 0x9c, 0xdd, 0xdf, 0xf9, 0x0b, 0xf7, 0x77, 0x21, 0xbb, 0xbf, 0xa6,
0x13, 0x5f, 0xb5, 0x9c, 0x78, 0xee, 0x3c, 0x8e, 0xb8, 0xcb, 0x99, 0x0c, 0x7b, 0xdd, 0x11, 0xef,
0x5d, 0x9e, 0x98, 0x2c, 0x90, 0x6c, 0x42, 0x4b, 0xba, 0x1b, 0xe9, 0x49, 0x01, 0x70, 0x8d, 0x73,
0x38, 0xd7, 0xdf, 0x69, 0xa0, 0xa6, 0x8e, 0x83, 0x4d, 0x01, 0x7e, 0xb6, 0x8a, 0x39, 0x87, 0x74,
0x27, 0x81, 0xbc, 0x68, 0x60, 0x7d, 0x3c, 0x2b, 0x55, 0xdd, 0x7c, 0x05, 0xfd, 0x2d, 0x07, 0x5a,
0x7c, 0xcf, 0x2c, 0xb6, 0x7c, 0x17, 0x50, 0x2a, 0x5e, 0x92, 0x2b, 0x2d, 0x5a, 0xf2, 0x0e, 0xd4,
0xb0, 0x1c, 0x8e, 0x59, 0x20, 0x79, 0xb2, 0x6d, 0xf3, 0x64, 0xaa, 0x4f, 0xf6, 0x2f, 0xb9, 0x29,
0xb1, 0xc1, 0x91, 0x7f, 0xe3, 0x40, 0x5d, 0xf6, 0xf2, 0x03, 0x07, 0x02, 0x3a, 0xc6, 0xed, 0x90,
0xe0, 0xa4, 0xf4, 0x22, 0xe8, 0x26, 0x34, 0x47, 0x5e, 0x32, 0x89, 0xb8, 0x3d, 0xb6, 0x82, 0x00,
0x59, 0x98, 0x1b, 0x57, 0x54, 0x9d, 0x71, 0x37, 0xf1, 0x87, 0x5d, 0x55, 0x2b, 0xef, 0x60, 0x8a,
0xaa, 0xb8, 0x06, 0x89, 0x13, 0x6f, 0xc0, 0xa4, 0xdd, 0x14, 0x05, 0xda, 0x86, 0x75, 0x39, 0xa1,
0x8c, 0xab, 0x4a, 0xff, 0xbc, 0x01, 0x1b, 0xb9, 0x2a, 0x7d, 0x69, 0x2b, 0x4f, 0xb7, 0x43, 0x7f,
0x74, 0x1c, 0x6a, 0x3f, 0xdf, 0x31, 0x0f, 0xbe, 0x56, 0x15, 0x19, 0xc0, 0x9a, 0x72, 0x10, 0xf8,
0x9a, 0xa6, 0xc6, 0xac, 0x84, 0x56, 0xea, 0x2d, 0x7b, 0x0b, 0xb3, 0x1d, 0x2a, 0xdc, 0x14, 0xe2,
0xe2, 0xf6, 0xc8, 0x29, 0xb4, 0xb5, 0x27, 0x22, 0x95, 0xb5, 0xe1, 0xad, 0xf0, 0xbe, 0xde, 0xbc,
0xa0, 0x2f, 0xcb, 0xb3, 0x75, 0x67, 0xb6, 0x46, 0xa6, 0x70, 0x55, 0xd5, 0xa1, 0x36, 0xce, 0xf7,
0x57, 0x7e, 0xa9, 0xb9, 0xa1, 0xcf, 0x6e, 0x77, 0x7a, 0x41, 0xc3, 0xe4, 0xab, 0xb0, 0x7e, 0xee,
0xf9, 0x89, 0x1a, 0x96, 0xe1, 0x1b, 0x54, 0xb0, 0xcb, 0x3b, 0x17, 0x74, 0xf9, 0x54, 0x7c, 0x6c,
0x99, 0xa8, 0x19, 0x2d, 0x76, 0xfe, 0xca, 0x81, 0x25, 0xbb, 0x1d, 0xce, 0xa6, 0x52, 0xf6, 0x95,
0x0e, 0x54, 0xde, 0x64, 0x06, 0xce, 0x1f, 0x95, 0x4b, 0x45, 0x47, 0x65, 0xf3, 0x80, 0x3a, 0x77,
0x51, 0x14, 0xa9, 0xfc, 0x72, 0x51, 0xa4, 0x4a, 0x51, 0x14, 0xa9, 0xf3, 0x1f, 0x0e, 0x90, 0x3c,
0x2f, 0x91, 0xfb, 0xe2, 0xac, 0x1e, 0xb0, 0xa1, 0x54, 0x29, 0xff, 0xff, 0xe5, 0xf8, 0x51, 0xad,
0x9d, 0xfa, 0x9a, 0x0b, 0x86, 0x79, 0x89, 0x6a, 0x3a, 0x3b, 0x8b, 0x6e, 0x51, 0x55, 0x26, 0xae,
0x55, 0xbe, 0x38, 0xae, 0x55, 0xb9, 0x38, 0xae, 0x35, 0x9f, 0x8d, 0x6b, 0x75, 0x7e, 0xd9, 0x81,
0x95, 0x82, 0x4d, 0xff, 0xd1, 0x4d, 0x9c, 0x6f, 0x93, 0xa5, 0x0b, 0x4a, 0x72, 0x9b, 0x4c, 0xb0,
0xf3, 0x73, 0xb0, 0x68, 0x31, 0xfa, 0x8f, 0xae, 0xff, 0xac, 0xbf, 0x26, 0xf8, 0xcc, 0xc2, 0x3a,
0xff, 0x52, 0x02, 0x92, 0x17, 0xb6, 0xff, 0xd3, 0x31, 0xe4, 0xd7, 0x69, 0xae, 0x60, 0x9d, 0xfe,
0x57, 0xed, 0xc0, 0x9b, 0xb0, 0x2c, 0x33, 0x3c, 0x8c, 0x08, 0x8d, 0xe0, 0x98, 0x7c, 0x05, 0xf7,
0x58, 0xed, 0xa0, 0x62, 0xd5, 0xba, 0x29, 0x37, 0x8c, 0x61, 0x26, 0xb6, 0x48, 0xd7, 0x61, 0x55,
0x64, 0x8c, 0xdc, 0x15, 0x4d, 0x29, 0xbb, 0xf2, 0x7b, 0x0e, 0xac, 0x65, 0x2a, 0xd2, 0x7b, 0x5d,
0x61, 0x3a, 0x6c, 0x7b, 0x62, 0x83, 0x7c, 0xfc, 0xda, 0x4b, 0xc8, 0x70, 0x5b, 0xbe, 0x82, 0xaf,
0x8f, 0xe1, 0x55, 0x64, 0x56, 0xbd, 0xa8, 0x8a, 0x6e, 0x88, 0xbc, 0x96, 0x80, 0x0d, 0x33, 0x03,
0x3f, 0x11, 0x99, 0x28, 0x66, 0x45, 0x7a, 0xb3, 0x63, 0x0f, 0x59, 0x15, 0xb9, 0x43, 0x68, 0x99,
0x29, 0x7b, 0xbc, 0x85, 0x75, 0xf4, 0xbb, 0x0e, 0x90, 0x2f, 0x4c, 0x58, 0x34, 0xc5, 0xbb, 0x5b,
0x1d, 0x3a, 0xda, 0xc8, 0x06, 0x46, 0xe6, 0xc7, 0x93, 0xe3, 0xcf, 0xb3, 0xa9, 0xca, 0x02, 0x28,
0xa5, 0x59, 0x00, 0xaf, 0x02, 0xf0, 0x83, 0x94, 0xbe, 0x10, 0x46, 0x47, 0x2c, 0x98, 0x8c, 0x44,
0x83, 0x85, 0x17, 0xf5, 0xe5, 0x8b, 0x2f, 0xea, 0x2b, 0x17, 0x5d, 0xd4, 0xbf, 0x07, 0x2b, 0xd6,
0xb8, 0xf5, 0xb6, 0xaa, 0xab, 0x69, 0xe7, 0x05, 0x57, 0xd3, 0xbf, 0x5a, 0x82, 0xb9, 0xfd, 0x70,
0x6c, 0x86, 0x4d, 0x1d, 0x3b, 0x6c, 0x2a, 0x6d, 0x49, 0x57, 0x9b, 0x0a, 0xa9, 0x62, 0x2c, 0x90,
0x6c, 0xc2, 0x92, 0x37, 0x4a, 0xf8, 0x39, 0xfe, 0x24, 0x8c, 0xce, 0xbd, 0xa8, 0x2f, 0xf6, 0x1a,
0x8f, 0xef, 0x99, 0x1a, 0xb2, 0x0a, 0x73, 0x5a, 0xe9, 0x22, 0x01, 0x2f, 0x72, 0xc7, 0x0d, 0xaf,
0x5c, 0xa6, 0x32, 0x04, 0x21, 0x4b, 0x9c, 0x95, 0xec, 0xef, 0x85, 0xd7, 0x2c, 0x44, 0xa7, 0xa8,
0x8a, 0xdb, 0x35, 0xbe, 0x7c, 0x48, 0x26, 0x63, 0x47, 0xaa, 0x6c, 0xc6, 0xb9, 0xaa, 0xf6, 0x05,
0xd4, 0x3f, 0x39, 0x50, 0xc1, 0xb5, 0xe1, 0x6a, 0x40, 0xf0, 0xbe, 0x8e, 0x9c, 0xe2, 0x9a, 0x2c,
0xba, 0x59, 0x98, 0x50, 0x2b, 0x8f, 0xa6, 0xa4, 0x27, 0x64, 0xe6, 0xd2, 0x5c, 0x83, 0x9a, 0x28,
0xe9, 0x9c, 0x11, 0x24, 0x49, 0x41, 0x72, 0x15, 0xca, 0xa7, 0xe1, 0x58, 0xf9, 0x2d, 0xa0, 0x2e,
0x0e, 0xc2, 0xb1, 0x8b, 0x78, 0x3a, 0x1e, 0xde, 0x9e, 0x98, 0x96, 0xb0, 0x46, 0x59, 0x98, 0xdb,
0x63, 0xdd, 0xac, 0xb9, 0x4c, 0x19, 0x94, 0x6e, 0x42, 0xf3, 0x61, 0xd8, 0x67, 0x46, 0xf8, 0x6a,
0x26, 0x9f, 0xd3, 0x9f, 0x77, 0xa0, 0xaa, 0x88, 0xc9, 0x4d, 0x28, 0x73, 0x27, 0x23, 0x73, 0x02,
0xd0, 0x17, 0x86, 0x9c, 0xce, 0x45, 0x0a, 0xae, 0x95, 0x31, 0xaa, 0x90, 0x3a, 0x9c, 0x2a, 0xa6,
0x90, 0xfa, 0x53, 0x7a, 0xb8, 0x19, 0x37, 0x24, 0x83, 0xd2, 0xef, 0x38, 0xb0, 0x68, 0xf5, 0xc1,
0xcf, 0x90, 0x43, 0x2f, 0x4e, 0xe4, 0x25, 0x8c, 0xdc, 0x1e, 0x13, 0x32, 0x37, 0xba, 0x64, 0x07,
0x34, 0x75, 0xa8, 0x6d, 0xce, 0x0c, 0xb5, 0xdd, 0x86, 0x5a, 0x9a, 0xed, 0x54, 0xb6, 0xb4, 0x2d,
0xef, 0x51, 0x5d, 0x85, 0xa6, 0x44, 0x18, 0xbd, 0x09, 0x87, 0x61, 0x24, 0xa3, 0xff, 0xa2, 0x40,
0xdf, 0x83, 0xba, 0x41, 0x6f, 0x06, 0x73, 0x1c, 0x2b, 0x98, 0xa3, 0x93, 0x01, 0x4a, 0x69, 0x32,
0x00, 0xfd, 0x4b, 0x07, 0x16, 0x39, 0x0f, 0xfa, 0xc1, 0xe0, 0x30, 0x1c, 0xfa, 0xbd, 0x29, 0xee,
0xbd, 0x62, 0x37, 0xa9, 0x33, 0x14, 0x2f, 0xda, 0x30, 0xe7, 0x7a, 0x75, 0x84, 0x94, 0x22, 0xaa,
0xcb, 0x5c, 0x86, 0xb9, 0x04, 0x1c, 0x7b, 0xb1, 0x14, 0x0b, 0x69, 0xfe, 0x2c, 0x90, 0x4b, 0x1a,
0x07, 0x22, 0x2f, 0x61, 0xdd, 0x91, 0x3f, 0x1c, 0xfa, 0x82, 0x56, 0x38, 0x47, 0x45, 0x55, 0xbc,
0xcf, 0xbe, 0x1f, 0x7b, 0xc7, 0x69, 0x44, 0x5b, 0x97, 0xe9, 0x9f, 0x96, 0xa0, 0x2e, 0x15, 0xf7,
0x5e, 0x7f, 0xc0, 0xe4, 0xf5, 0x0b, 0xba, 0x9f, 0x5a, 0xc9, 0x18, 0x88, 0xaa, 0xb7, 0x1c, 0x56,
0x03, 0xc9, 0x6e, 0xf9, 0x5c, 0x7e, 0xcb, 0xaf, 0x40, 0x8d, 0xb3, 0xde, 0x5b, 0xe8, 0x19, 0x8b,
0xab, 0x9b, 0x14, 0x50, 0xb5, 0x77, 0xb0, 0xb6, 0x92, 0xd6, 0x22, 0xf0, 0xc2, 0xcb, 0x9a, 0x77,
0xa0, 0x21, 0x9b, 0xc1, 0x3d, 0x41, 0x9d, 0x92, 0x32, 0xbf, 0xb5, 0x5f, 0xae, 0x45, 0xa9, 0xbe,
0xbc, 0xa3, 0xbe, 0xac, 0x5e, 0xf4, 0xa5, 0xa2, 0xa4, 0xf7, 0xf5, 0x1d, 0xd8, 0xfd, 0xc8, 0x1b,
0x9f, 0x2a, 0x29, 0xbd, 0x0d, 0x2b, 0x7e, 0xd0, 0x1b, 0x4e, 0xfa, 0xac, 0x3b, 0x09, 0xbc, 0x20,
0x08, 0x27, 0x41, 0x8f, 0xa9, 0x14, 0x80, 0xa2, 0x2a, 0xda, 0xd7, 0xa9, 0x47, 0xd8, 0x10, 0xd9,
0x84, 0x0a, 0xef, 0x48, 0x59, 0x85, 0x62, 0x11, 0x16, 0x24, 0xe4, 0x26, 0x54, 0x58, 0x7f, 0xc0,
0xd4, 0x69, 0x91, 0xd8, 0xe7, 0x76, 0xbe, 0xab, 0xae, 0x20, 0xe0, 0x0a, 0x85, 0xa3, 0x19, 0x85,
0x62, 0x5b, 0x94, 0x79, 0x5e, 0x7c, 0xd0, 0xa7, 0xab, 0x40, 0x1e, 0x0a, 0x19, 0x30, 0xc3, 0xe7,
0xbf, 0x34, 0x07, 0x75, 0x03, 0xe6, 0xba, 0x61, 0xc0, 0x07, 0xdc, 0xed, 0xfb, 0xde, 0x88, 0x25,
0x2c, 0x92, 0x7c, 0x9f, 0x41, 0x39, 0x9d, 0x77, 0x36, 0xe8, 0x86, 0x93, 0xa4, 0xdb, 0x67, 0x83,
0x88, 0x09, 0x23, 0xcf, 0x8d, 0x8e, 0x85, 0x72, 0xba, 0x91, 0xf7, 0xdc, 0xa4, 0x13, 0x1c, 0x94,
0x41, 0x55, 0x30, 0x5c, 0xac, 0x51, 0x39, 0x0d, 0x86, 0x8b, 0x15, 0xc9, 0x6a, 0xb5, 0x4a, 0x81,
0x56, 0x7b, 0x1b, 0xd6, 0x85, 0xfe, 0x92, 0x92, 0xde, 0xcd, 0x30, 0xd6, 0x8c, 0x5a, 0xb2, 0x09,
0x2d, 0x3e, 0x66, 0x25, 0x12, 0xb1, 0xff, 0x75, 0x11, 0x58, 0x72, 0xdc, 0x1c, 0xce, 0x69, 0x31,
0xc2, 0x63, 0xd2, 0x8a, 0xcb, 0xc1, 0x1c, 0x8e, 0xb4, 0xde, 0x73, 0x9b, 0xb6, 0x26, 0x69, 0x33,
0x38, 0x5d, 0x84, 0xfa, 0x51, 0x12, 0x8e, 0xd5, 0xa6, 0x2c, 0x41, 0x43, 0x14, 0x65, 0x2a, 0xc6,
0x2b, 0x70, 0x19, 0xb9, 0xe8, 0x71, 0x38, 0x0e, 0x87, 0xe1, 0x60, 0x7a, 0x34, 0x39, 0x16, 0x39,
0xb8, 0x7e, 0x18, 0xd0, 0xbf, 0x76, 0x60, 0xc5, 0xaa, 0x95, 0xd1, 0xa3, 0x4f, 0x09, 0x21, 0xd0,
0x77, 0xe8, 0x82, 0xf1, 0x96, 0x0d, 0xe5, 0x2a, 0x08, 0x45, 0x0c, 0xf0, 0x89, 0xbc, 0x56, 0xdf,
0x86, 0xa6, 0x1a, 0x99, 0xfa, 0x50, 0x70, 0x61, 0x3b, 0xcf, 0x85, 0xf2, 0xfb, 0x25, 0xf9, 0x81,
0x6a, 0xe2, 0x27, 0xe4, 0x25, 0x6b, 0x1f, 0xe7, 0xa8, 0xe2, 0x10, 0xfa, 0x62, 0xcc, 0x3c, 0x8d,
0xa8, 0x11, 0xf4, 0x34, 0x18, 0xd3, 0x5f, 0x77, 0x00, 0xd2, 0xd1, 0xe1, 0xd5, 0x9c, 0x36, 0x10,
0x22, 0x4d, 0xde, 0x30, 0x06, 0xaf, 0x43, 0x43, 0x5f, 0xe9, 0xa4, 0x36, 0xa7, 0xae, 0x30, 0xee,
0x30, 0xde, 0x80, 0xe6, 0x60, 0x18, 0x1e, 0xa3, 0xc1, 0xc6, 0xdc, 0x9e, 0x58, 0x26, 0xa4, 0x2c,
0x09, 0xf8, 0x9e, 0x44, 0x53, 0x03, 0x55, 0x36, 0x0c, 0x14, 0xfd, 0x46, 0x49, 0x47, 0xe0, 0xd3,
0x39, 0xcf, 0x94, 0x32, 0x72, 0x27, 0xa7, 0x4e, 0x67, 0x04, 0xbc, 0x31, 0xe2, 0x76, 0x78, 0x61,
0x40, 0xe0, 0x3d, 0x58, 0x8a, 0x84, 0xbe, 0x52, 0xca, 0xac, 0xfc, 0x02, 0x65, 0xb6, 0x18, 0x59,
0x56, 0xec, 0x13, 0xd0, 0xf2, 0xfa, 0x67, 0x2c, 0x4a, 0x7c, 0x3c, 0x92, 0xa1, 0x0b, 0x21, 0x54,
0x70, 0xd3, 0xc0, 0xd1, 0xb2, 0xdf, 0x80, 0xa6, 0x4c, 0x02, 0xd2, 0x94, 0x32, 0xef, 0x35, 0x85,
0x39, 0x21, 0xfd, 0x03, 0x15, 0xec, 0xb7, 0xf7, 0x70, 0xf6, 0x8a, 0x98, 0xb3, 0x2b, 0x65, 0x66,
0xf7, 0x31, 0x19, 0x78, 0xef, 0xab, 0x73, 0xdf, 0x9c, 0x71, 0x21, 0xdf, 0x97, 0x17, 0x25, 0xf6,
0x92, 0x96, 0x5f, 0x66, 0x49, 0xe9, 0xf7, 0x1c, 0x58, 0xd8, 0x0f, 0xc7, 0xfb, 0x32, 0x35, 0x01,
0x05, 0x41, 0x67, 0xdf, 0xa9, 0xe2, 0x0b, 0x92, 0x16, 0x0a, 0x2d, 0xf7, 0x62, 0xd6, 0x72, 0xff,
0x14, 0xbc, 0x82, 0x51, 0x87, 0x28, 0x1c, 0x87, 0x11, 0x17, 0x46, 0x6f, 0x28, 0xcc, 0x74, 0x18,
0x24, 0xa7, 0x4a, 0x8d, 0xbd, 0x88, 0x04, 0x8f, 0x77, 0xfc, 0x58, 0x22, 0x9c, 0x6e, 0xe9, 0x69,
0x08, 0xed, 0x96, 0xaf, 0xa0, 0x9f, 0x81, 0x1a, 0xba, 0xca, 0x38, 0xad, 0x37, 0xa1, 0x76, 0x1a,
0x8e, 0xbb, 0xa7, 0x7e, 0x90, 0x28, 0xe1, 0x5e, 0x4a, 0x7d, 0xd8, 0x7d, 0x5c, 0x10, 0x4d, 0x40,
0xff, 0xb3, 0x02, 0x0b, 0x0f, 0x82, 0xb3, 0xd0, 0xef, 0xe1, 0xc5, 0xc2, 0x88, 0x8d, 0x42, 0x95,
0x8b, 0xc8, 0x7f, 0x93, 0x2b, 0xb0, 0x80, 0xc9, 0x37, 0x63, 0xc1, 0xb4, 0x0d, 0x71, 0x01, 0x28,
0x21, 0xee, 0x24, 0x44, 0x69, 0x5e, 0xb1, 0x10, 0x1f, 0x03, 0xe1, 0x87, 0x88, 0xc8, 0xcc, 0x0b,
0x96, 0xa5, 0x34, 0xa1, 0xb3, 0x62, 0x24, 0x74, 0xf2, 0xbe, 0x64, 0x2a, 0x85, 0xb8, 0x6b, 0x17,
0x7d, 0x49, 0x08, 0x0f, 0x3e, 0x11, 0x13, 0x51, 0x23, 0x74, 0x39, 0x16, 0xe4, 0xc1, 0xc7, 0x04,
0xb9, 0x5b, 0x22, 0x3e, 0x10, 0x34, 0x42, 0x09, 0x9b, 0x10, 0x77, 0xe1, 0xb2, 0x99, 0xdc, 0x35,
0xc1, 0xfb, 0x19, 0x98, 0x6b, 0xea, 0x3e, 0xd3, 0x0a, 0x55, 0xcc, 0x03, 0x44, 0xee, 0x74, 0x16,
0x37, 0x8e, 0x4b, 0x22, 0x4f, 0x4a, 0x1d, 0x97, 0x38, 0xc3, 0x78, 0xc3, 0xe1, 0xb1, 0xd7, 0x7b,
0x86, 0x89, 0xfa, 0x18, 0xea, 0xaf, 0xb9, 0x36, 0x88, 0x09, 0x11, 0xe9, 0xae, 0xe2, 0x55, 0x69,
0xd9, 0x35, 0x21, 0x72, 0x07, 0xea, 0x78, 0x44, 0x94, 0xfb, 0xba, 0x84, 0xfb, 0xda, 0x32, 0xcf,
0x90, 0xb8, 0xb3, 0x26, 0x91, 0x79, 0xe9, 0xd1, 0xb4, 0x2f, 0x3d, 0x84, 0xf2, 0x94, 0x77, 0x45,
0x2d, 0xec, 0x2d, 0x05, 0xb8, 0x55, 0x95, 0x0b, 0x26, 0x08, 0x96, 0x91, 0xc0, 0xc2, 0xc8, 0x55,
0xa8, 0xf2, 0xe3, 0xcb, 0xd8, 0xf3, 0xfb, 0x6d, 0xa2, 0x4f, 0x51, 0x1a, 0xe3, 0x6d, 0xa8, 0xdf,
0x78, 0xa7, 0xb3, 0x82, 0xab, 0x62, 0x61, 0x7c, 0x6d, 0x74, 0x19, 0x85, 0x69, 0x55, 0xec, 0xa8,
0x05, 0x92, 0xb7, 0x30, 0x62, 0x9f, 0xb0, 0xf6, 0x1a, 0xa6, 0xc5, 0xbc, 0x22, 0xe7, 0x2c, 0x99,
0x56, 0xfd, 0x3d, 0xe2, 0x24, 0xae, 0xa0, 0xa4, 0x1f, 0x87, 0x86, 0x09, 0x93, 0x2a, 0x94, 0x1f,
0x1d, 0xee, 0x3d, 0x6c, 0x5d, 0x22, 0x75, 0x58, 0x38, 0xda, 0x7b, 0xfc, 0xf8, 0x60, 0x6f, 0xb7,
0xe5, 0xd0, 0x04, 0xc8, 0x76, 0xbf, 0x2f, 0x29, 0xf5, 0x41, 0x3d, 0xe5, 0x59, 0xc7, 0xe2, 0xd9,
0x02, 0xbe, 0x29, 0x15, 0xf3, 0xcd, 0x0b, 0x57, 0x97, 0xee, 0x41, 0xfd, 0xd0, 0x48, 0x71, 0x47,
0x11, 0x52, 0xc9, 0xed, 0x52, 0xf4, 0x0c, 0xc4, 0x18, 0x4e, 0xc9, 0x1c, 0x0e, 0xfd, 0x43, 0x47,
0x64, 0x09, 0xeb, 0xe1, 0x8b, 0xbe, 0x29, 0x34, 0x74, 0x38, 0x25, 0x4d, 0x3e, 0xb3, 0x30, 0x4e,
0x83, 0x43, 0xe9, 0x86, 0x27, 0x27, 0x31, 0x53, 0xa9, 0x22, 0x16, 0xc6, 0x79, 0x9f, 0x7b, 0x51,
0xdc, 0x23, 0xf1, 0x45, 0x0f, 0xb1, 0x4c, 0x19, 0xc9, 0xe1, 0x5c, 0x93, 0x47, 0xec, 0x8c, 0x45,
0xb1, 0x4e, 0x92, 0xd1, 0x65, 0x9d, 0x23, 0x97, 0x5d, 0xe5, 0x4d, 0xa8, 0xea, 0x76, 0x6d, 0x25,
0xa5, 0x28, 0x75, 0x3d, 0x57, 0x86, 0x78, 0xae, 0xb0, 0x06, 0x2d, 0x14, 0x73, 0xbe, 0x82, 0xdc,
0x02, 0x72, 0xe2, 0x47, 0x59, 0xf2, 0x39, 0x24, 0x2f, 0xa8, 0xa1, 0x4f, 0x61, 0x45, 0x31, 0x8b,
0xe1, 0x3e, 0xd9, 0x9b, 0xe8, 0x5c, 0x24, 0x22, 0xa5, 0xbc, 0x88, 0xd0, 0xff, 0x72, 0x60, 0x41,
0xee, 0x74, 0xee, 0x99, 0x84, 0xd8, 0x67, 0x0b, 0x23, 0x6d, 0x2b, 0xcb, 0x1d, 0xe5, 0x49, 0x2a,
0xc6, 0x9c, 0xea, 0x9b, 0x2b, 0x52, 0x7d, 0x04, 0xca, 0x63, 0x2f, 0x39, 0xc5, 0xd3, 0x72, 0xcd,
0xc5, 0xdf, 0xa4, 0x25, 0x62, 0x3b, 0x42, 0xcd, 0x62, 0x5c, 0xa7, 0xe8, 0x41, 0x88, 0xb0, 0xe8,
0xf9, 0x07, 0x21, 0x57, 0xa0, 0x86, 0x03, 0xe8, 0xa6, 0xa1, 0x9b, 0x14, 0xe0, 0x9c, 0x2b, 0x0a,
0x28, 0xbb, 0x32, 0x17, 0x35, 0x45, 0xe8, 0x9a, 0xd8, 0x79, 0xb9, 0x04, 0xfa, 0x46, 0x4d, 0xe6,
0x24, 0xa6, 0x70, 0xca, 0x11, 0x72, 0x00, 0x59, 0x8e, 0x90, 0xa4, 0xae, 0xae, 0xa7, 0x1d, 0x68,
0xef, 0xb2, 0x21, 0x4b, 0xd8, 0xf6, 0x70, 0x98, 0x6d, 0xff, 0x15, 0xb8, 0x5c, 0x50, 0x27, 0x3d,
0xe6, 0x2f, 0xc0, 0xda, 0xb6, 0xc8, 0xdf, 0xfa, 0x51, 0xe5, 0x24, 0xd0, 0x36, 0xac, 0x67, 0x9b,
0x94, 0x9d, 0xdd, 0x83, 0xe5, 0x5d, 0x76, 0x3c, 0x19, 0x1c, 0xb0, 0xb3, 0xb4, 0x23, 0x02, 0xe5,
0xf8, 0x34, 0x3c, 0x97, 0x82, 0x89, 0xbf, 0xc9, 0xab, 0x00, 0x43, 0x4e, 0xd3, 0x8d, 0xc7, 0xac,
0xa7, 0x72, 0xce, 0x11, 0x39, 0x1a, 0xb3, 0x1e, 0x7d, 0x1b, 0x88, 0xd9, 0x8e, 0x5c, 0x2f, 0x6e,
0xe9, 0x26, 0xc7, 0xdd, 0x78, 0x1a, 0x27, 0x6c, 0xa4, 0x92, 0xe9, 0x4d, 0x88, 0xde, 0x80, 0xc6,
0xa1, 0x37, 0x75, 0xd9, 0xd7, 0xe4, 0xeb, 0x98, 0x0d, 0x58, 0x18, 0x7b, 0x53, 0xae, 0xa6, 0x74,
0x4c, 0x09, 0xab, 0xe9, 0xbf, 0x97, 0x60, 0x5e, 0x50, 0xf2, 0x56, 0xfb, 0x2c, 0x4e, 0xfc, 0x00,
0x19, 0x4b, 0xb5, 0x6a, 0x40, 0x39, 0x56, 0x2e, 0x15, 0xb0, 0xb2, 0x3c, 0x97, 0xa9, 0xfc, 0x5d,
0xc9, 0xaf, 0x16, 0xc6, 0x99, 0x2b, 0x4d, 0x0e, 0x12, 0x41, 0x8d, 0x14, 0xc8, 0x84, 0x1f, 0x53,
0x7b, 0x2a, 0xc6, 0xa7, 0xa4, 0x54, 0x72, 0xae, 0x09, 0x15, 0x5a, 0xed, 0x05, 0xc1, 0xe0, 0x39,
0xab, 0x9d, 0xb3, 0xce, 0xd5, 0x97, 0xb0, 0xce, 0xe2, 0xb0, 0xf6, 0x22, 0xeb, 0x0c, 0x2f, 0x61,
0x9d, 0x29, 0x81, 0xd6, 0x3d, 0xc6, 0x5c, 0xc6, 0xfd, 0x3f, 0xc5, 0xbb, 0xdf, 0x74, 0xa0, 0x25,
0xb9, 0x48, 0xd7, 0x91, 0xd7, 0x2d, 0x3f, 0xb7, 0x30, 0xcb, 0xf6, 0x3a, 0x2c, 0xa2, 0xf7, 0xa9,
0xe3, 0xac, 0x32, 0x28, 0x6c, 0x81, 0x7c, 0x1e, 0xea, 0x32, 0x6c, 0xe4, 0x0f, 0xe5, 0xa6, 0x98,
0x90, 0x0a, 0xd5, 0x46, 0x9e, 0x4c, 0x92, 0x71, 0x5c, 0x5d, 0xa6, 0x7f, 0xe6, 0xc0, 0xb2, 0x31,
0x60, 0xc9, 0x85, 0xef, 0x81, 0x92, 0x06, 0x11, 0x74, 0x15, 0x92, 0xbb, 0x61, 0x8b, 0x4d, 0xfa,
0x99, 0x45, 0x8c, 0x9b, 0xe9, 0x4d, 0x71, 0x80, 0xf1, 0x64, 0x24, 0x95, 0xa8, 0x09, 0x71, 0x46,
0x3a, 0x67, 0xec, 0x99, 0x26, 0x11, 0x6a, 0xdc, 0xc2, 0x30, 0x83, 0x83, 0x7b, 0xcd, 0x9a, 0x48,
0xd8, 0x33, 0x1b, 0xa4, 0x7f, 0xe7, 0xc0, 0x8a, 0x38, 0xfe, 0xc8, 0xc3, 0xa5, 0x7e, 0x02, 0x31,
0x2f, 0xce, 0x7b, 0x42, 0x22, 0xf7, 0x2f, 0xb9, 0xb2, 0x4c, 0x3e, 0xfd, 0x92, 0x47, 0x36, 0x9d,
0xb9, 0x33, 0x63, 0x2f, 0xe6, 0x8a, 0xf6, 0xe2, 0x05, 0x2b, 0x5d, 0x14, 0x64, 0xac, 0x14, 0x06,
0x19, 0xef, 0x2e, 0x40, 0x25, 0xee, 0x85, 0x63, 0x46, 0xd7, 0x61, 0xd5, 0x9e, 0x9c, 0x54, 0x41,
0xdf, 0x72, 0xa0, 0x7d, 0x4f, 0x04, 0xe3, 0xfd, 0x60, 0xb0, 0xef, 0xc7, 0x49, 0x18, 0xe9, 0xe7,
0x60, 0x57, 0x01, 0xe2, 0xc4, 0x8b, 0x12, 0x91, 0x9f, 0x29, 0x43, 0x80, 0x29, 0xc2, 0xc7, 0xc8,
0x82, 0xbe, 0xa8, 0x15, 0x7b, 0xa3, 0xcb, 0x39, 0x1f, 0x42, 0x1e, 0xd0, 0x2c, 0x4b, 0xfc, 0x86,
0xc8, 0x64, 0xe3, 0xbe, 0x02, 0x3b, 0x43, 0xbd, 0x2e, 0x4e, 0x3e, 0x19, 0x94, 0xfe, 0xad, 0x03,
0xcd, 0x74, 0x90, 0x7b, 0x1c, 0xb4, 0xb5, 0x83, 0x34, 0xbf, 0xa9, 0x76, 0x50, 0xc1, 0x49, 0x9f,
0xdb, 0x63, 0x39, 0x36, 0x03, 0x41, 0x89, 0x95, 0xa5, 0x70, 0xa2, 0x1c, 0x1c, 0x13, 0x12, 0x79,
0x29, 0xdc, 0x13, 0x90, 0x5e, 0x8d, 0x2c, 0x61, 0x7a, 0xed, 0x28, 0xc1, 0xaf, 0xe6, 0xc5, 0xd1,
0x4f, 0x16, 0x95, 0x29, 0x5d, 0x40, 0x14, 0x4d, 0xa9, 0x79, 0xb1, 0x51, 0x15, 0xeb, 0xa3, 0xca,
0xf4, 0x37, 0x1c, 0xb8, 0x5c, 0xb0, 0xf0, 0x52, 0x6a, 0x76, 0x61, 0xf9, 0x44, 0x57, 0xaa, 0xc5,
0x11, 0xa2, 0xb3, 0xae, 0x6e, 0x96, 0xec, 0x05, 0x71, 0xf3, 0x1f, 0x68, 0xbf, 0x48, 0x2c, 0xb7,
0x95, 0xf9, 0x95, 0xaf, 0xd8, 0xfc, 0x2c, 0xd4, 0x8d, 0x37, 0x5a, 0x64, 0x03, 0x56, 0x9e, 0x3e,
0x78, 0xfc, 0x70, 0xef, 0xe8, 0xa8, 0x7b, 0xf8, 0xe4, 0xee, 0xe7, 0xf7, 0xbe, 0xd4, 0xdd, 0xdf,
0x3e, 0xda, 0x6f, 0x5d, 0x22, 0xeb, 0x40, 0x1e, 0xee, 0x1d, 0x3d, 0xde, 0xdb, 0xb5, 0x70, 0xe7,
0xce, 0x6f, 0xce, 0xc1, 0x92, 0xb8, 0xb1, 0x14, 0x0f, 0xe1, 0x59, 0x44, 0xde, 0x87, 0x05, 0xf9,
0x8f, 0x0c, 0xc8, 0x9a, 0x1c, 0xb6, 0xfd, 0xaf, 0x13, 0x3a, 0xeb, 0x59, 0x58, 0xf2, 0xe5, 0xca,
0x2f, 0x7e, 0xef, 0x1f, 0x7f, 0xbb, 0xb4, 0x48, 0xea, 0x5b, 0x67, 0x6f, 0x6d, 0x0d, 0x58, 0x10,
0xf3, 0x36, 0x7e, 0x06, 0x20, 0x7d, 0xe2, 0x4f, 0xda, 0xda, 0x1f, 0xcc, 0xfc, 0xef, 0x82, 0xce,
0xe5, 0x82, 0x1a, 0xd9, 0xee, 0x65, 0x6c, 0x77, 0x85, 0x2e, 0xf1, 0x76, 0xfd, 0xc0, 0x4f, 0xc4,
0x7b, 0xff, 0x77, 0x9d, 0x4d, 0xd2, 0x87, 0x86, 0xf9, 0x82, 0x9f, 0xa8, 0xc0, 0x53, 0xc1, 0xff,
0x0f, 0xe8, 0xbc, 0x52, 0x58, 0xa7, 0xa2, 0x6e, 0xd8, 0xc7, 0x1a, 0x6d, 0xf1, 0x3e, 0x26, 0x48,
0x91, 0xf6, 0x32, 0x84, 0x25, 0xfb, 0xa1, 0x3e, 0xb9, 0x62, 0xa8, 0x8c, 0xdc, 0xbf, 0x09, 0xe8,
0xbc, 0x3a, 0xa3, 0x56, 0xf6, 0xf5, 0x2a, 0xf6, 0xb5, 0x41, 0x09, 0xef, 0xab, 0x87, 0x34, 0xea,
0xdf, 0x04, 0xbc, 0xeb, 0x6c, 0xde, 0xf9, 0xb7, 0xd7, 0xa0, 0xa6, 0x43, 0xc5, 0xe4, 0xab, 0xb0,
0x68, 0x5d, 0x29, 0x13, 0x35, 0x8d, 0xa2, 0x1b, 0xe8, 0xce, 0x95, 0xe2, 0x4a, 0xd9, 0xf1, 0x55,
0xec, 0xb8, 0x4d, 0xd6, 0x79, 0xc7, 0xf2, 0x4e, 0x76, 0x0b, 0x2f, 0xd2, 0x45, 0x56, 0xec, 0x33,
0x31, 0xcf, 0xf4, 0x1a, 0xd8, 0x9a, 0x67, 0xee, 0xda, 0xd8, 0x9a, 0x67, 0xfe, 0xee, 0x98, 0x5e,
0xc1, 0xee, 0xd6, 0xc9, 0xaa, 0xd9, 0x9d, 0x0e, 0xe1, 0x32, 0x4c, 0xe5, 0x36, 0xdf, 0xb5, 0x93,
0x57, 0x35, 0x63, 0x15, 0xbd, 0x77, 0xd7, 0x2c, 0x92, 0x7f, 0xf4, 0x4e, 0xdb, 0xd8, 0x15, 0x21,
0xb8, 0x7d, 0xe6, 0xb3, 0x76, 0xf2, 0x65, 0xa8, 0xe9, 0x07, 0x9a, 0x64, 0xc3, 0x78, 0x15, 0x6b,
0xbe, 0x1a, 0xed, 0xb4, 0xf3, 0x15, 0x45, 0x8c, 0x61, 0xb6, 0xcc, 0x19, 0xe3, 0x29, 0xd4, 0x8d,
0x47, 0x98, 0xe4, 0xb2, 0x0e, 0xf4, 0x67, 0x1f, 0x7a, 0x76, 0x3a, 0x45, 0x55, 0xb2, 0x8b, 0x65,
0xec, 0xa2, 0x4e, 0x6a, 0xc8, 0x7b, 0xc9, 0xf3, 0x30, 0x26, 0x07, 0xb0, 0x26, 0x0f, 0x2e, 0xc7,
0xec, 0xfb, 0x59, 0xa2, 0x82, 0x67, 0xfe, 0xb7, 0x1d, 0xf2, 0x1e, 0x54, 0xd5, 0x83, 0x5a, 0xb2,
0x5e, 0xfc, 0x30, 0xb8, 0xb3, 0x91, 0xc3, 0xa5, 0x5a, 0xfb, 0x12, 0x40, 0xfa, 0xe2, 0x53, 0x0b,
0x70, 0xee, 0x05, 0xa9, 0xde, 0x9d, 0xfc, 0xf3, 0x50, 0xba, 0x8e, 0x13, 0x6c, 0x11, 0x14, 0xe0,
0x80, 0x9d, 0xab, 0xc7, 0x0d, 0x5f, 0x81, 0xba, 0xf1, 0xe8, 0x53, 0x2f, 0x5f, 0xfe, 0xc1, 0xa8,
0x5e, 0xbe, 0x82, 0x37, 0xa2, 0xb4, 0x83, 0xad, 0xaf, 0xd2, 0x26, 0x6f, 0x3d, 0xf6, 0x07, 0xc1,
0x48, 0x10, 0xf0, 0x0d, 0x3a, 0x85, 0x45, 0xeb, 0x65, 0xa7, 0x96, 0x9e, 0xa2, 0x77, 0xa3, 0x5a,
0x7a, 0x0a, 0x1f, 0x83, 0x2a, 0x76, 0xa6, 0xcb, 0xbc, 0x9f, 0x33, 0x24, 0x31, 0x7a, 0xfa, 0x00,
0xea, 0xc6, 0x2b, 0x4d, 0x3d, 0x97, 0xfc, 0x83, 0x50, 0x3d, 0x97, 0xa2, 0x47, 0x9d, 0xab, 0xd8,
0xc7, 0x12, 0x45, 0x56, 0xc0, 0xb7, 0x01, 0xbc, 0xed, 0xaf, 0xc2, 0x92, 0xfd, 0x6e, 0x53, 0xcb,
0x65, 0xe1, 0x0b, 0x50, 0x2d, 0x97, 0x33, 0x1e, 0x7b, 0x4a, 0x96, 0xde, 0x5c, 0xd1, 0x9d, 0x6c,
0x7d, 0x28, 0x2f, 0x6e, 0x3f, 0x22, 0x5f, 0xe0, 0xca, 0x47, 0x3e, 0xd6, 0x20, 0x1b, 0x06, 0xd7,
0x9a, 0x4f, 0x3a, 0xb4, 0xbc, 0xe4, 0xde, 0x75, 0xd8, 0xcc, 0x2c, 0x5e, 0x37, 0xa0, 0x45, 0xc1,
0x47, 0x1b, 0x86, 0x45, 0x31, 0xdf, 0x75, 0x18, 0x16, 0xc5, 0x7a, 0xdb, 0x91, 0xb5, 0x28, 0x89,
0xcf, 0xdb, 0x08, 0xa0, 0x99, 0x49, 0x5f, 0xd2, 0x52, 0x51, 0x9c, 0xef, 0xd9, 0xb9, 0xfa, 0xe2,
0xac, 0x27, 0x5b, 0x51, 0x29, 0x05, 0xb5, 0xa5, 0xb2, 0x6b, 0x7f, 0x16, 0x1a, 0xe6, 0x7b, 0x3b,
0x62, 0x8a, 0x72, 0xb6, 0xa7, 0x57, 0x0a, 0xeb, 0xec, 0xcd, 0x25, 0x0d, 0xb3, 0x1b, 0xbe, 0xb9,
0xf6, 0x83, 0xa3, 0x54, 0xe9, 0x16, 0xbd, 0xb3, 0x4a, 0x95, 0x6e, 0xe1, 0x2b, 0x25, 0xb5, 0xb9,
0x64, 0xc5, 0x9a, 0x8b, 0x88, 0xb1, 0x93, 0x0f, 0xa0, 0x69, 0xe4, 0x06, 0x1e, 0x4d, 0x83, 0x9e,
0x66, 0xd4, 0x7c, 0x12, 0x79, 0xa7, 0xc8, 0x2f, 0xa6, 0x1b, 0xd8, 0xfe, 0x32, 0xb5, 0x26, 0xc1,
0x99, 0x74, 0x07, 0xea, 0x66, 0xde, 0xe1, 0x0b, 0xda, 0xdd, 0x30, 0xaa, 0xcc, 0x1c, 0xe8, 0xdb,
0x0e, 0xf9, 0x5d, 0x07, 0x1a, 0x56, 0x16, 0x9f, 0x75, 0x93, 0x94, 0x69, 0xa7, 0x6d, 0xd6, 0x99,
0x0d, 0x51, 0x17, 0x07, 0x79, 0xb0, 0xf9, 0x39, 0x6b, 0x11, 0x3e, 0xb4, 0xce, 0x57, 0xb7, 0xb2,
0xff, 0xd1, 0xe1, 0xa3, 0x2c, 0x81, 0x99, 0x68, 0xff, 0xd1, 0x6d, 0x87, 0x7c, 0xc7, 0x81, 0x25,
0x3b, 0x2a, 0xa0, 0xb7, 0xaa, 0x30, 0xfe, 0xa0, 0xb7, 0x6a, 0x46, 0x28, 0xe1, 0x03, 0x1c, 0xe5,
0xe3, 0x4d, 0xd7, 0x1a, 0xa5, 0x7c, 0x8a, 0xf6, 0xc3, 0x8d, 0x96, 0xbc, 0x2b, 0xfe, 0x07, 0x8b,
0x0a, 0x55, 0x11, 0x43, 0xbb, 0x67, 0xb7, 0xd7, 0xfc, 0x07, 0x24, 0x37, 0x9d, 0xdb, 0x0e, 0xf9,
0x8a, 0xf8, 0x27, 0x13, 0xf2, 0x5b, 0xe4, 0x92, 0x97, 0xfd, 0x9e, 0x5e, 0xc7, 0x39, 0x5d, 0xa5,
0x97, 0xad, 0x39, 0x65, 0xed, 0xe6, 0xb6, 0x18, 0x9d, 0xfc, 0xdf, 0x21, 0xa9, 0xe2, 0xcf, 0xfd,
0x3f, 0x91, 0xd9, 0x83, 0x1c, 0x89, 0x41, 0x4a, 0x72, 0x8b, 0x95, 0x5f, 0xb2, 0x19, 0xba, 0x89,
0x63, 0xbd, 0x4e, 0x5f, 0x9b, 0x39, 0xd6, 0x2d, 0x3c, 0xdb, 0xf3, 0x11, 0x1f, 0x02, 0xa4, 0x61,
0x65, 0x92, 0x09, 0x6b, 0x6a, 0xdb, 0x97, 0x8f, 0x3c, 0xdb, 0xf2, 0xa2, 0xa2, 0x9f, 0xbc, 0xc5,
0x2f, 0x0b, 0xb5, 0xf2, 0x40, 0x05, 0x44, 0x4d, 0xe7, 0xc1, 0x8e, 0xff, 0x5a, 0xce, 0x43, 0xb6,
0x7d, 0x4b, 0xa9, 0xe8, 0xe8, 0xea, 0x13, 0x58, 0x3c, 0x08, 0xc3, 0x67, 0x93, 0xb1, 0xbe, 0x06,
0xb2, 0xc3, 0x6e, 0xfb, 0x5e, 0x7c, 0xda, 0xc9, 0xcc, 0x82, 0x5e, 0xc3, 0xa6, 0x3a, 0xa4, 0x6d,
0x34, 0xb5, 0xf5, 0x61, 0x1a, 0xb6, 0xfe, 0x88, 0x78, 0xb0, 0xac, 0xdd, 0x12, 0x3d, 0xf0, 0x8e,
0xdd, 0x8c, 0x19, 0x70, 0xcd, 0x75, 0x61, 0x79, 0xa0, 0x6a, 0xb4, 0x5b, 0xb1, 0x6a, 0xf3, 0xb6,
0x43, 0x0e, 0xa1, 0xb1, 0xcb, 0x7a, 0x61, 0x9f, 0xc9, 0xd8, 0xd5, 0x4a, 0x3a, 0x70, 0x1d, 0xf4,
0xea, 0x2c, 0x5a, 0xa0, 0xad, 0xbf, 0xc7, 0xde, 0x34, 0x62, 0x5f, 0xdb, 0xfa, 0x50, 0x46, 0xc5,
0x3e, 0x52, 0xfa, 0x5b, 0x85, 0x0d, 0x2d, 0xfd, 0x9d, 0x89, 0x33, 0x5a, 0xfa, 0x3b, 0x17, 0x67,
0xb4, 0x96, 0x5a, 0x85, 0x2d, 0xc9, 0x10, 0x96, 0x73, 0xa1, 0x49, 0xf2, 0x9a, 0xb2, 0xc0, 0x33,
0x02, 0x9a, 0x9d, 0x6b, 0xb3, 0x09, 0xec, 0xde, 0x36, 0xed, 0xde, 0x8e, 0x60, 0x71, 0x97, 0x89,
0xc5, 0x12, 0xb9, 0x26, 0x99, 0x37, 0xa8, 0x66, 0x26, 0x4b, 0x56, 0x81, 0x63, 0x9d, 0x6d, 0xa0,
0x31, 0xd1, 0x83, 0x7c, 0x19, 0xea, 0xf7, 0x59, 0xa2, 0x92, 0x4b, 0xb4, 0x8b, 0x98, 0xc9, 0x36,
0xe9, 0x14, 0xe4, 0xa6, 0xd8, 0x3c, 0x83, 0xad, 0x6d, 0xb1, 0xfe, 0x80, 0x09, 0xe5, 0xd4, 0xf5,
0xfb, 0x1f, 0x91, 0x9f, 0xc6, 0xc6, 0x75, 0x76, 0xdb, 0xba, 0x91, 0x93, 0x60, 0x36, 0xde, 0xcc,
0xe0, 0x45, 0x2d, 0x07, 0x61, 0x9f, 0x19, 0xae, 0x4a, 0x00, 0x75, 0x23, 0x29, 0x53, 0x0b, 0x50,
0x3e, 0xc1, 0x54, 0x0b, 0x50, 0x41, 0x0e, 0x27, 0xbd, 0x89, 0xfd, 0x50, 0x72, 0x2d, 0xed, 0x47,
0xe4, 0x6d, 0xa6, 0x3d, 0x6d, 0x7d, 0xe8, 0x8d, 0x92, 0x8f, 0xc8, 0x53, 0x7c, 0x8f, 0x6a, 0x26,
0xd0, 0xa4, 0x3e, 0x6f, 0x36, 0xd7, 0x46, 0x2f, 0x96, 0x51, 0x65, 0xfb, 0xc1, 0xa2, 0x2b, 0xf4,
0x68, 0x3e, 0x0d, 0x70, 0x94, 0x84, 0xe3, 0x5d, 0x8f, 0x8d, 0xc2, 0x20, 0xd5, 0xb5, 0x69, 0x92,
0x48, 0xaa, 0xbf, 0x8c, 0x4c, 0x11, 0xf2, 0xd4, 0x38, 0x24, 0x58, 0xf9, 0x47, 0x8a, 0xb9, 0x66,
0xe6, 0x91, 0xe8, 0x05, 0x29, 0xc8, 0x25, 0xb9, 0xed, 0x90, 0x6d, 0x80, 0x34, 0x36, 0xad, 0x5d,
0xfe, 0x5c, 0xd8, 0x5b, 0xab, 0xbd, 0x82, 0x40, 0xf6, 0x21, 0xd4, 0xd2, 0x60, 0xe7, 0x46, 0x9a,
0x58, 0x6b, 0x85, 0x46, 0xb5, 0x05, 0xcf, 0x85, 0x20, 0x69, 0x0b, 0x97, 0x0a, 0x48, 0x95, 0x2f,
0x15, 0xc6, 0x15, 0x7d, 0x58, 0x11, 0x03, 0xd4, 0xee, 0x08, 0xa6, 0x3d, 0xa8, 0x99, 0x14, 0x84,
0x01, 0xb5, 0x34, 0x17, 0x46, 0xd1, 0xac, 0xa8, 0x02, 0xe7, 0x56, 0x91, 0x72, 0xc1, 0x55, 0xf3,
0x08, 0x96, 0x73, 0x61, 0x1e, 0x2d, 0xd2, 0xb3, 0x22, 0x6f, 0x5a, 0xa4, 0x67, 0x46, 0x88, 0xe8,
0x1a, 0x76, 0xd9, 0xa4, 0x80, 0x27, 0x95, 0x73, 0x3f, 0xe9, 0x9d, 0xbe, 0xeb, 0x6c, 0xde, 0xbd,
0xf1, 0xc1, 0xc7, 0x07, 0x7e, 0x72, 0x3a, 0x39, 0xbe, 0xd5, 0x0b, 0x47, 0x5b, 0x43, 0x75, 0xf4,
0x97, 0xc9, 0x4b, 0x5b, 0xc3, 0xa0, 0xbf, 0x85, 0x2d, 0x1f, 0xcf, 0xe3, 0x3f, 0xb3, 0xfc, 0xe4,
0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xb0, 0xe2, 0xcc, 0xfe, 0x52, 0x00, 0x00,
var fileDescriptor_rpc_e66000aa8614d793 = []byte{
// 6738 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7c, 0x5d, 0x6c, 0x24, 0xd9,
0x55, 0xff, 0x54, 0xbb, 0xdb, 0xee, 0x3e, 0xdd, 0xb6, 0xdb, 0xd7, 0x5f, 0x3d, 0xbd, 0xb3, 0xb3,
0xb3, 0x37, 0x93, 0x9d, 0x89, 0xff, 0xfb, 0x1f, 0xcf, 0x4e, 0x92, 0x65, 0xb3, 0x0b, 0x01, 0x8f,
0xed, 0x19, 0x4f, 0xe2, 0x9d, 0x71, 0xca, 0x33, 0x19, 0xb2, 0x01, 0x75, 0xca, 0xdd, 0xd7, 0xed,
0xca, 0x54, 0x57, 0x75, 0xaa, 0xaa, 0xed, 0xe9, 0x2c, 0x2b, 0x21, 0x40, 0x20, 0x21, 0x22, 0x04,
0xbc, 0x10, 0x04, 0x42, 0x0a, 0x48, 0x24, 0x8f, 0xbc, 0x44, 0x48, 0xc0, 0x1b, 0x2f, 0x20, 0x21,
0x84, 0xf2, 0x88, 0xc4, 0x0b, 0xbc, 0x00, 0x82, 0x07, 0x24, 0x1e, 0x78, 0x00, 0xa1, 0x7b, 0xee,
0x47, 0xdd, 0x5b, 0x55, 0x1e, 0x4f, 0x3e, 0xe0, 0xc9, 0xbe, 0xbf, 0x7b, 0xea, 0x7e, 0x9e, 0xaf,
0x7b, 0xee, 0xb9, 0x0d, 0x8d, 0x78, 0xdc, 0xbf, 0x35, 0x8e, 0xa3, 0x34, 0x22, 0xb5, 0x20, 0x8c,
0xc7, 0xfd, 0xee, 0x95, 0x61, 0x14, 0x0d, 0x03, 0xb6, 0xe9, 0x8d, 0xfd, 0x4d, 0x2f, 0x0c, 0xa3,
0xd4, 0x4b, 0xfd, 0x28, 0x4c, 0x04, 0x11, 0xfd, 0x0a, 0x2c, 0xdc, 0x67, 0xe1, 0x21, 0x63, 0x03,
0x97, 0x7d, 0x6d, 0xc2, 0x92, 0x94, 0xfc, 0x3f, 0x58, 0xf2, 0xd8, 0xd7, 0x19, 0x1b, 0xf4, 0xc6,
0x5e, 0x92, 0x8c, 0x4f, 0x62, 0x2f, 0x61, 0x1d, 0xe7, 0x9a, 0x73, 0xb3, 0xe5, 0xb6, 0x45, 0xc5,
0x81, 0xc6, 0xc9, 0xeb, 0xd0, 0x4a, 0x38, 0x29, 0x0b, 0xd3, 0x38, 0x1a, 0x4f, 0x3b, 0x15, 0xa4,
0x6b, 0x72, 0x6c, 0x57, 0x40, 0x34, 0x80, 0x45, 0xdd, 0x43, 0x32, 0x8e, 0xc2, 0x84, 0x91, 0xdb,
0xb0, 0xd2, 0xf7, 0xc7, 0x27, 0x2c, 0xee, 0xe1, 0xc7, 0xa3, 0x90, 0x8d, 0xa2, 0xd0, 0xef, 0x77,
0x9c, 0x6b, 0x33, 0x37, 0x1b, 0x2e, 0x11, 0x75, 0xfc, 0x8b, 0xf7, 0x65, 0x0d, 0xb9, 0x01, 0x8b,
0x2c, 0x14, 0x38, 0x1b, 0xe0, 0x57, 0xb2, 0xab, 0x85, 0x0c, 0xe6, 0x1f, 0xd0, 0xbf, 0x70, 0x60,
0xe9, 0x41, 0xe8, 0xa7, 0x4f, 0xbd, 0x20, 0x60, 0xa9, 0x9a, 0xd3, 0x0d, 0x58, 0x3c, 0x43, 0x00,
0xe7, 0x74, 0x16, 0xc5, 0x03, 0x39, 0xa3, 0x05, 0x01, 0x1f, 0x48, 0xf4, 0xdc, 0x91, 0x55, 0xce,
0x1d, 0x59, 0xe9, 0x72, 0xcd, 0x9c, 0xb3, 0x5c, 0x37, 0x60, 0x31, 0x66, 0xfd, 0xe8, 0x94, 0xc5,
0xd3, 0xde, 0x99, 0x1f, 0x0e, 0xa2, 0xb3, 0x4e, 0xf5, 0x9a, 0x73, 0xb3, 0xe6, 0x2e, 0x28, 0xf8,
0x29, 0xa2, 0x74, 0x05, 0x88, 0x39, 0x0b, 0xb1, 0x6e, 0x74, 0x08, 0xcb, 0x4f, 0xc2, 0x20, 0xea,
0x3f, 0xfb, 0x01, 0x67, 0x57, 0xd2, 0x7d, 0xa5, 0xb4, 0xfb, 0x35, 0x58, 0xb1, 0x3b, 0x92, 0x03,
0x60, 0xb0, 0xba, 0x7d, 0xe2, 0x85, 0x43, 0xa6, 0x9a, 0x54, 0x43, 0xf8, 0x04, 0xb4, 0xfb, 0x93,
0x38, 0x66, 0x61, 0x61, 0x0c, 0x8b, 0x12, 0xd7, 0x83, 0x78, 0x1d, 0x5a, 0x21, 0x3b, 0xcb, 0xc8,
0x24, 0xcb, 0x84, 0xec, 0x4c, 0x91, 0xd0, 0x0e, 0xac, 0xe5, 0xbb, 0x91, 0x03, 0xf8, 0x57, 0x07,
0xaa, 0x4f, 0xd2, 0xe7, 0x11, 0xb9, 0x05, 0xd5, 0x74, 0x3a, 0x16, 0x8c, 0xb9, 0x70, 0x87, 0xdc,
0x42, 0x5e, 0xbf, 0xb5, 0x35, 0x18, 0xc4, 0x2c, 0x49, 0x1e, 0x4f, 0xc7, 0xcc, 0x6d, 0x79, 0xa2,
0xd0, 0xe3, 0x74, 0xa4, 0x03, 0x73, 0xb2, 0x8c, 0x1d, 0x36, 0x5c, 0x55, 0x24, 0x57, 0x01, 0xbc,
0x51, 0x34, 0x09, 0xd3, 0x5e, 0xe2, 0xa5, 0xb8, 0x73, 0x33, 0xae, 0x81, 0x90, 0xeb, 0x30, 0x9f,
0xf4, 0x63, 0x7f, 0x9c, 0xf6, 0xc6, 0x93, 0xa3, 0x67, 0x6c, 0x8a, 0x3b, 0xd6, 0x70, 0x6d, 0x90,
0x6c, 0x42, 0x3d, 0x9a, 0xa4, 0xe3, 0xc8, 0x0f, 0xd3, 0x4e, 0xed, 0x9a, 0x73, 0xb3, 0x79, 0x67,
0x59, 0x8e, 0x89, 0xcf, 0x24, 0x64, 0xc1, 0x01, 0xaf, 0x72, 0x35, 0x11, 0x6f, 0xb6, 0x1f, 0x85,
0xc7, 0x7e, 0x3c, 0x12, 0xf2, 0xd8, 0x99, 0xc5, 0x9e, 0x6d, 0x90, 0x7e, 0xb3, 0x02, 0xcd, 0xc7,
0xb1, 0x17, 0x26, 0x5e, 0x9f, 0x03, 0x7c, 0x1a, 0xe9, 0xf3, 0xde, 0x89, 0x97, 0x9c, 0xe0, 0xcc,
0x1b, 0xae, 0x2a, 0x92, 0x35, 0x98, 0x15, 0x83, 0xc6, 0xf9, 0xcd, 0xb8, 0xb2, 0x44, 0xde, 0x84,
0xa5, 0x70, 0x32, 0xea, 0xd9, 0x7d, 0xcd, 0xe0, 0xae, 0x17, 0x2b, 0xf8, 0x62, 0x1c, 0xf1, 0x7d,
0x17, 0x5d, 0x88, 0x99, 0x1a, 0x08, 0xa1, 0xd0, 0x92, 0x25, 0xe6, 0x0f, 0x4f, 0xc4, 0x54, 0x6b,
0xae, 0x85, 0xf1, 0x36, 0x52, 0x7f, 0xc4, 0x7a, 0x49, 0xea, 0x8d, 0xc6, 0x72, 0x5a, 0x06, 0x82,
0xf5, 0x51, 0xea, 0x05, 0xbd, 0x63, 0xc6, 0x92, 0xce, 0x9c, 0xac, 0xd7, 0x08, 0x79, 0x03, 0x16,
0x06, 0x2c, 0x49, 0x7b, 0x72, 0x83, 0x58, 0xd2, 0xa9, 0xa3, 0xf4, 0xe5, 0x50, 0xce, 0x25, 0xf7,
0x59, 0x6a, 0xac, 0x4e, 0x22, 0xb9, 0x91, 0xee, 0x03, 0x31, 0xe0, 0x1d, 0x96, 0x7a, 0x7e, 0x90,
0x90, 0xb7, 0xa1, 0x95, 0x1a, 0xc4, 0xa8, 0x6d, 0x9a, 0x9a, 0x75, 0x8c, 0x0f, 0x5c, 0x8b, 0x8e,
0xde, 0x87, 0xfa, 0x3d, 0xc6, 0xf6, 0xfd, 0x91, 0x9f, 0x92, 0x35, 0xa8, 0x1d, 0xfb, 0xcf, 0x99,
0x60, 0xee, 0x99, 0xbd, 0x4b, 0xae, 0x28, 0x92, 0x2e, 0xcc, 0x8d, 0x59, 0xdc, 0x67, 0x6a, 0xf9,
0xf7, 0x2e, 0xb9, 0x0a, 0xb8, 0x3b, 0x07, 0xb5, 0x80, 0x7f, 0x4c, 0xbf, 0x5d, 0x81, 0xe6, 0x21,
0x0b, 0xb5, 0xd0, 0x10, 0xa8, 0xf2, 0x29, 0x49, 0x41, 0xc1, 0xff, 0xc9, 0x6b, 0xd0, 0xc4, 0x69,
0x26, 0x69, 0xec, 0x87, 0x43, 0xc9, 0xab, 0xc0, 0xa1, 0x43, 0x44, 0x48, 0x1b, 0x66, 0xbc, 0x91,
0xe2, 0x53, 0xfe, 0x2f, 0x17, 0xa8, 0xb1, 0x37, 0x1d, 0x71, 0xd9, 0xd3, 0xbb, 0xd6, 0x72, 0x9b,
0x12, 0xdb, 0xe3, 0xdb, 0x76, 0x0b, 0x96, 0x4d, 0x12, 0xd5, 0x7a, 0x0d, 0x5b, 0x5f, 0x32, 0x28,
0x65, 0x27, 0x37, 0x60, 0x51, 0xd1, 0xc7, 0x62, 0xb0, 0xb8, 0x8f, 0x0d, 0x77, 0x41, 0xc2, 0x6a,
0x0a, 0x37, 0xa1, 0x7d, 0xec, 0x87, 0x5e, 0xd0, 0xeb, 0x07, 0xe9, 0x69, 0x6f, 0xc0, 0x82, 0xd4,
0xc3, 0x1d, 0xad, 0xb9, 0x0b, 0x88, 0x6f, 0x07, 0xe9, 0xe9, 0x0e, 0x47, 0xc9, 0x9b, 0xd0, 0x38,
0x66, 0xac, 0x87, 0x2b, 0xd1, 0xa9, 0xa3, 0x84, 0x2c, 0xca, 0xa5, 0x57, 0xab, 0xeb, 0xd6, 0x8f,
0xe5, 0x7f, 0xf4, 0x4f, 0x1c, 0x68, 0x89, 0xa5, 0x92, 0x26, 0xe3, 0x3a, 0xcc, 0xab, 0x11, 0xb1,
0x38, 0x8e, 0x62, 0xc9, 0xfe, 0x36, 0x48, 0x36, 0xa0, 0xad, 0x80, 0x71, 0xcc, 0xfc, 0x91, 0x37,
0x64, 0x52, 0xbf, 0x14, 0x70, 0x72, 0x27, 0x6b, 0x31, 0x8e, 0x26, 0xa9, 0x50, 0xda, 0xcd, 0x3b,
0x2d, 0x39, 0x28, 0x97, 0x63, 0xae, 0x4d, 0xc2, 0xd9, 0xbf, 0x64, 0xa9, 0x2d, 0x8c, 0x7e, 0xc3,
0x01, 0xc2, 0x87, 0xfe, 0x38, 0x12, 0x4d, 0xc8, 0x95, 0xca, 0xef, 0x92, 0xf3, 0xd2, 0xbb, 0x54,
0x39, 0x6f, 0x97, 0xae, 0xc3, 0x2c, 0x0e, 0x8b, 0xcb, 0xf3, 0x4c, 0x61, 0xe8, 0xb2, 0x8e, 0x7e,
0xcb, 0x81, 0x96, 0xa9, 0x83, 0xc8, 0x6d, 0x20, 0xc7, 0x93, 0x70, 0xe0, 0x87, 0xc3, 0x5e, 0xfa,
0xdc, 0x1f, 0xf4, 0x8e, 0xa6, 0xbc, 0x09, 0x1c, 0xcf, 0xde, 0x25, 0xb7, 0xa4, 0x8e, 0xbc, 0x09,
0x6d, 0x0b, 0x4d, 0xd2, 0x58, 0x8c, 0x6a, 0xef, 0x92, 0x5b, 0xa8, 0xe1, 0x8b, 0xc4, 0xb5, 0xdc,
0x24, 0xed, 0xf9, 0xe1, 0x80, 0x3d, 0xc7, 0x75, 0x9d, 0x77, 0x2d, 0xec, 0xee, 0x02, 0xb4, 0xcc,
0xef, 0xe8, 0x67, 0xa1, 0xbd, 0xcf, 0x95, 0x47, 0xe8, 0x87, 0x43, 0xa9, 0xc4, 0xb9, 0x46, 0x93,
0x1a, 0x57, 0xec, 0xb5, 0x2c, 0x71, 0xb1, 0x39, 0x89, 0x92, 0x54, 0xae, 0x0b, 0xfe, 0x4f, 0xff,
0xc1, 0x81, 0x45, 0xbe, 0xe8, 0xef, 0x7b, 0xe1, 0x54, 0xad, 0xf8, 0x3e, 0xb4, 0x78, 0x53, 0x8f,
0xa3, 0x2d, 0xa1, 0x17, 0x85, 0xbc, 0xdf, 0x94, 0x8b, 0x94, 0xa3, 0xbe, 0x65, 0x92, 0x72, 0xd7,
0x65, 0xea, 0x5a, 0x5f, 0x73, 0xc1, 0x4c, 0xbd, 0x78, 0xc8, 0x52, 0xd4, 0x98, 0x52, 0x83, 0x82,
0x80, 0xb6, 0xa3, 0xf0, 0x98, 0x5c, 0x83, 0x56, 0xe2, 0xa5, 0xbd, 0x31, 0x8b, 0x71, 0xd5, 0x50,
0xb8, 0x66, 0x5c, 0x48, 0xbc, 0xf4, 0x80, 0xc5, 0x77, 0xa7, 0x29, 0xeb, 0xfe, 0x24, 0x2c, 0x15,
0x7a, 0xe1, 0xf2, 0x9c, 0x4d, 0x91, 0xff, 0x4b, 0x56, 0xa0, 0x76, 0xea, 0x05, 0x13, 0x26, 0x15,
0xb9, 0x28, 0xbc, 0x5b, 0x79, 0xc7, 0xa1, 0x6f, 0x40, 0x3b, 0x1b, 0xb6, 0x14, 0x0c, 0x02, 0x55,
0xbe, 0x82, 0xb2, 0x01, 0xfc, 0x9f, 0xfe, 0xae, 0x23, 0x08, 0xb7, 0x23, 0x5f, 0x2b, 0x45, 0x4e,
0xc8, 0x75, 0xa7, 0x22, 0xe4, 0xff, 0x9f, 0x6b, 0x34, 0x7e, 0xf8, 0xc9, 0x92, 0xcb, 0x50, 0x4f,
0x58, 0x38, 0xe8, 0x79, 0x41, 0x80, 0xba, 0xa3, 0xee, 0xce, 0xf1, 0xf2, 0x56, 0x10, 0xd0, 0x1b,
0xb0, 0x64, 0x8c, 0xee, 0x05, 0xf3, 0x78, 0x08, 0x64, 0xdf, 0x4f, 0xd2, 0x27, 0x61, 0x32, 0x36,
0x74, 0xce, 0x2b, 0xd0, 0x18, 0xf9, 0x21, 0x8e, 0x4c, 0xb0, 0x6d, 0xcd, 0xad, 0x8f, 0xfc, 0x90,
0x8f, 0x2b, 0xc1, 0x4a, 0xef, 0xb9, 0xac, 0xac, 0xc8, 0x4a, 0xef, 0x39, 0x56, 0xd2, 0x77, 0x60,
0xd9, 0x6a, 0x4f, 0x76, 0xfd, 0x3a, 0xd4, 0x26, 0xe9, 0xf3, 0x48, 0x59, 0x84, 0xa6, 0xe4, 0x10,
0xee, 0x67, 0xb8, 0xa2, 0x86, 0xbe, 0x07, 0x4b, 0x0f, 0xd9, 0x99, 0xe4, 0x4c, 0x35, 0x90, 0x37,
0x2e, 0xf4, 0x41, 0xb0, 0x9e, 0xde, 0x02, 0x62, 0x7e, 0x2c, 0x7b, 0x35, 0x3c, 0x12, 0xc7, 0xf2,
0x48, 0xe8, 0x1b, 0x40, 0x0e, 0xfd, 0x61, 0xf8, 0x3e, 0x4b, 0x12, 0x6f, 0xa8, 0x15, 0x48, 0x1b,
0x66, 0x46, 0xc9, 0x50, 0xea, 0x0d, 0xfe, 0x2f, 0xfd, 0x24, 0x2c, 0x5b, 0x74, 0xb2, 0xe1, 0x2b,
0xd0, 0x48, 0xfc, 0x61, 0xe8, 0xa5, 0x93, 0x98, 0xc9, 0xa6, 0x33, 0x80, 0xde, 0x83, 0x95, 0x2f,
0xb2, 0xd8, 0x3f, 0x9e, 0x5e, 0xd4, 0xbc, 0xdd, 0x4e, 0x25, 0xdf, 0xce, 0x2e, 0xac, 0xe6, 0xda,
0x91, 0xdd, 0x0b, 0xf6, 0x95, 0x3b, 0x59, 0x77, 0x45, 0xc1, 0x10, 0xe6, 0x8a, 0x29, 0xcc, 0xf4,
0x09, 0x90, 0xed, 0x28, 0x0c, 0x59, 0x3f, 0x3d, 0x60, 0x2c, 0xce, 0xce, 0x20, 0x19, 0xaf, 0x36,
0xef, 0xac, 0xcb, 0x95, 0xcd, 0x6b, 0x08, 0xc9, 0xc4, 0x04, 0xaa, 0x63, 0x16, 0x8f, 0xb0, 0xe1,
0xba, 0x8b, 0xff, 0xd3, 0x55, 0x58, 0xb6, 0x9a, 0x95, 0xee, 0xe3, 0x5b, 0xb0, 0xba, 0xe3, 0x27,
0xfd, 0x62, 0x87, 0x1d, 0x98, 0x1b, 0x4f, 0x8e, 0x7a, 0x99, 0x24, 0xaa, 0x22, 0xf7, 0x32, 0xf2,
0x9f, 0xc8, 0xc6, 0x7e, 0xd9, 0x81, 0xea, 0xde, 0xe3, 0xfd, 0x6d, 0xd2, 0x85, 0xba, 0x1f, 0xf6,
0xa3, 0x11, 0x57, 0xd6, 0x62, 0xd2, 0xba, 0x7c, 0xae, 0x84, 0x5d, 0x81, 0x06, 0xea, 0x78, 0xee,
0x38, 0xc9, 0xe3, 0x42, 0x06, 0x70, 0xa7, 0x8d, 0x3d, 0x1f, 0xfb, 0x31, 0x7a, 0x65, 0xca, 0xd7,
0xaa, 0xa2, 0x1e, 0x2d, 0x56, 0xd0, 0xff, 0xae, 0xc2, 0x9c, 0xd4, 0xf0, 0xd8, 0x5f, 0x3f, 0xf5,
0x4f, 0x99, 0x1c, 0x89, 0x2c, 0x71, 0xfb, 0x19, 0xb3, 0x51, 0x94, 0xb2, 0x9e, 0xb5, 0x0d, 0x36,
0x88, 0x4e, 0xa9, 0x68, 0xa8, 0x27, 0x5c, 0xd9, 0x19, 0x41, 0x65, 0x81, 0x7c, 0xb1, 0x38, 0xd0,
0xf3, 0x07, 0x38, 0xa6, 0xaa, 0xab, 0x8a, 0x7c, 0x25, 0xfa, 0xde, 0xd8, 0xeb, 0xfb, 0xe9, 0x54,
0xaa, 0x04, 0x5d, 0xe6, 0x6d, 0x07, 0x51, 0xdf, 0x0b, 0x7a, 0x47, 0x5e, 0xe0, 0x85, 0x7d, 0xa6,
0x1c, 0x5e, 0x0b, 0xe4, 0xce, 0x9f, 0x1c, 0x92, 0x22, 0x13, 0x0e, 0x62, 0x0e, 0xe5, 0x4e, 0x64,
0x3f, 0x1a, 0x8d, 0xfc, 0x94, 0xfb, 0x8c, 0xe8, 0x4f, 0xcc, 0xb8, 0x06, 0x22, 0xdc, 0x6b, 0x2c,
0x9d, 0x89, 0xd5, 0x6b, 0x28, 0xf7, 0xda, 0x00, 0x79, 0x2b, 0xdc, 0x29, 0xe1, 0x6a, 0xec, 0xd9,
0x59, 0x07, 0x44, 0x2b, 0x19, 0xc2, 0xf7, 0x61, 0x12, 0x26, 0x2c, 0x4d, 0x03, 0x36, 0xd0, 0x03,
0x6a, 0x22, 0x59, 0xb1, 0x82, 0xdc, 0x86, 0x65, 0xe1, 0xc6, 0x26, 0x5e, 0x1a, 0x25, 0x27, 0x7e,
0xd2, 0x4b, 0xb8, 0x43, 0xd8, 0x42, 0xfa, 0xb2, 0x2a, 0xf2, 0x0e, 0xac, 0xe7, 0xe0, 0x98, 0xf5,
0x99, 0x7f, 0xca, 0x06, 0x9d, 0x79, 0xfc, 0xea, 0xbc, 0x6a, 0x72, 0x0d, 0x9a, 0xdc, 0x7b, 0x9f,
0x8c, 0x07, 0x1e, 0xb7, 0xde, 0x0b, 0xb8, 0x0f, 0x26, 0x44, 0xde, 0x82, 0xf9, 0x31, 0x13, 0x26,
0xf6, 0x24, 0x0d, 0xfa, 0x49, 0x67, 0xd1, 0xd2, 0x6e, 0x9c, 0x73, 0x5d, 0x9b, 0x82, 0x33, 0x65,
0x3f, 0x41, 0x37, 0xce, 0x9b, 0x76, 0xda, 0xc8, 0x6e, 0x19, 0x80, 0x32, 0x12, 0xfb, 0xa7, 0x5e,
0xca, 0x3a, 0x4b, 0x42, 0xa1, 0xcb, 0x22, 0xfd, 0x7d, 0x47, 0x28, 0x56, 0xc9, 0x84, 0x5a, 0x41,
0xbe, 0x06, 0x4d, 0xc1, 0x7e, 0xbd, 0x28, 0x0c, 0xa6, 0x92, 0x23, 0x41, 0x40, 0x8f, 0xc2, 0x60,
0x4a, 0x3e, 0x06, 0xf3, 0x7e, 0x68, 0x92, 0x08, 0x19, 0x6e, 0x29, 0x10, 0x89, 0x5e, 0x83, 0xe6,
0x78, 0x72, 0x14, 0xf8, 0x7d, 0x41, 0x32, 0x23, 0x5a, 0x11, 0x10, 0x12, 0x70, 0xd7, 0x4a, 0x8c,
0x44, 0x50, 0x54, 0x91, 0xa2, 0x29, 0x31, 0x4e, 0x42, 0xef, 0xc2, 0x8a, 0x3d, 0x40, 0xa9, 0xac,
0x36, 0xa0, 0x2e, 0x79, 0x3b, 0xe9, 0x34, 0x71, 0x7d, 0x16, 0xec, 0x63, 0x9b, 0xab, 0xeb, 0xe9,
0x77, 0xab, 0xb0, 0x2c, 0xd1, 0xed, 0x20, 0x4a, 0xd8, 0xe1, 0x64, 0x34, 0xf2, 0xe2, 0x12, 0xa1,
0x71, 0x2e, 0x10, 0x9a, 0x8a, 0x2d, 0x34, 0x9c, 0x95, 0x4f, 0x3c, 0x3f, 0x14, 0x7e, 0xa1, 0x90,
0x38, 0x03, 0x21, 0x37, 0x61, 0xb1, 0x1f, 0x44, 0x89, 0xf0, 0x95, 0xcc, 0x83, 0x59, 0x1e, 0x2e,
0x0a, 0x79, 0xad, 0x4c, 0xc8, 0x4d, 0x21, 0x9d, 0xcd, 0x09, 0x29, 0x85, 0x16, 0x6f, 0x94, 0x29,
0x9d, 0x33, 0x27, 0x7c, 0x37, 0x13, 0xe3, 0xe3, 0xc9, 0x8b, 0x84, 0x90, 0xbf, 0xc5, 0x32, 0x81,
0xe0, 0xe7, 0x3e, 0xae, 0xd3, 0x0c, 0xea, 0x86, 0x14, 0x88, 0x62, 0x15, 0xb9, 0x07, 0x20, 0xfa,
0x42, 0xc3, 0x0a, 0x68, 0x58, 0xdf, 0xb0, 0x77, 0xc4, 0x5c, 0xfb, 0x5b, 0xbc, 0x30, 0x89, 0x19,
0x1a, 0x5b, 0xe3, 0x4b, 0xfa, 0xab, 0x0e, 0x34, 0x8d, 0x3a, 0xb2, 0x0a, 0x4b, 0xdb, 0x8f, 0x1e,
0x1d, 0xec, 0xba, 0x5b, 0x8f, 0x1f, 0x7c, 0x71, 0xb7, 0xb7, 0xbd, 0xff, 0xe8, 0x70, 0xb7, 0x7d,
0x89, 0xc3, 0xfb, 0x8f, 0xb6, 0xb7, 0xf6, 0x7b, 0xf7, 0x1e, 0xb9, 0xdb, 0x0a, 0x76, 0xc8, 0x1a,
0x10, 0x77, 0xf7, 0xfd, 0x47, 0x8f, 0x77, 0x2d, 0xbc, 0x42, 0xda, 0xd0, 0xba, 0xeb, 0xee, 0x6e,
0x6d, 0xef, 0x49, 0x64, 0x86, 0xac, 0x40, 0xfb, 0xde, 0x93, 0x87, 0x3b, 0x0f, 0x1e, 0xde, 0xef,
0x6d, 0x6f, 0x3d, 0xdc, 0xde, 0xdd, 0xdf, 0xdd, 0x69, 0x57, 0xc9, 0x3c, 0x34, 0xb6, 0xee, 0x6e,
0x3d, 0xdc, 0x79, 0xf4, 0x70, 0x77, 0xa7, 0x5d, 0xa3, 0x7f, 0xef, 0xc0, 0x2a, 0x8e, 0x7a, 0x90,
0x17, 0x90, 0x6b, 0xd0, 0xec, 0x47, 0xd1, 0x98, 0x71, 0x7d, 0xae, 0x55, 0xb6, 0x09, 0x71, 0xe6,
0x17, 0x0a, 0xf2, 0x38, 0x8a, 0xfb, 0x4c, 0xca, 0x07, 0x20, 0x74, 0x8f, 0x23, 0x9c, 0xf9, 0xe5,
0xf6, 0x0a, 0x0a, 0x21, 0x1e, 0x4d, 0x81, 0x09, 0x92, 0x35, 0x98, 0x3d, 0x8a, 0x99, 0xd7, 0x3f,
0x91, 0x92, 0x21, 0x4b, 0xe4, 0x13, 0x99, 0x5b, 0xdf, 0xe7, 0xab, 0x1f, 0xb0, 0x01, 0x72, 0x4c,
0xdd, 0x5d, 0x94, 0xf8, 0xb6, 0x84, 0xb9, 0x66, 0xf0, 0x8e, 0xbc, 0x70, 0x10, 0x85, 0x6c, 0x20,
0xdd, 0xb9, 0x0c, 0xa0, 0x07, 0xb0, 0x96, 0x9f, 0x9f, 0x94, 0xaf, 0xb7, 0x0d, 0xf9, 0x12, 0xde,
0x55, 0xf7, 0xfc, 0xdd, 0x34, 0x64, 0xed, 0x9f, 0x1d, 0xa8, 0x72, 0x63, 0x7b, 0xbe, 0x61, 0x36,
0xfd, 0xa7, 0x99, 0x42, 0x44, 0x07, 0xcf, 0x2d, 0x42, 0xfd, 0x0a, 0x13, 0x65, 0x20, 0x59, 0x7d,
0xcc, 0xfa, 0xa7, 0x38, 0x63, 0x5d, 0xcf, 0x11, 0x2e, 0x20, 0xdc, 0xb9, 0xc5, 0xaf, 0xa5, 0x80,
0xa8, 0xb2, 0xaa, 0xc3, 0x2f, 0xe7, 0xb2, 0x3a, 0xfc, 0xae, 0x03, 0x73, 0x7e, 0x78, 0x14, 0x4d,
0xc2, 0x01, 0x0a, 0x44, 0xdd, 0x55, 0x45, 0xbe, 0x7c, 0x63, 0x14, 0x54, 0x7f, 0xa4, 0xd8, 0x3f,
0x03, 0x28, 0xe1, 0x87, 0x9f, 0x04, 0x9d, 0x0b, 0x1d, 0xc2, 0x78, 0x1b, 0x96, 0x0c, 0x2c, 0x73,
0x54, 0xc7, 0x1c, 0xc8, 0x39, 0xaa, 0xe8, 0x95, 0x88, 0x1a, 0xda, 0x86, 0x85, 0xfb, 0x2c, 0x7d,
0x10, 0x1e, 0x47, 0xaa, 0xa5, 0x3f, 0xaa, 0xc2, 0xa2, 0x86, 0x64, 0x43, 0x37, 0x61, 0xd1, 0x1f,
0xb0, 0x30, 0xf5, 0xd3, 0x69, 0xcf, 0x3a, 0x63, 0xe5, 0x61, 0xee, 0xcd, 0x79, 0x81, 0xef, 0xa9,
0xa8, 0x99, 0x28, 0x90, 0x3b, 0xb0, 0xc2, 0x4d, 0x8d, 0xb2, 0x1e, 0x7a, 0x8b, 0xc5, 0x51, 0xaf,
0xb4, 0x8e, 0x2b, 0x03, 0x8e, 0x4b, 0x6d, 0xaf, 0x3f, 0x11, 0x5e, 0x4d, 0x59, 0x15, 0x5f, 0x35,
0xd1, 0x12, 0x9f, 0x72, 0x4d, 0x98, 0x23, 0x0d, 0x14, 0x42, 0x51, 0xb3, 0x42, 0x55, 0xe5, 0x43,
0x51, 0x46, 0x38, 0xab, 0x5e, 0x08, 0x67, 0x71, 0x55, 0x36, 0x0d, 0xfb, 0x6c, 0xd0, 0x4b, 0xa3,
0x1e, 0xaa, 0x5c, 0xdc, 0x9d, 0xba, 0x9b, 0x87, 0xc9, 0x15, 0x98, 0x4b, 0x59, 0x92, 0x86, 0x2c,
0x45, 0xad, 0x54, 0xbf, 0x5b, 0xe9, 0x38, 0xae, 0x82, 0xb8, 0x0b, 0x3a, 0x89, 0xfd, 0xa4, 0xd3,
0xc2, 0x40, 0x15, 0xfe, 0x4f, 0x3e, 0x05, 0xab, 0x47, 0x2c, 0x49, 0x7b, 0x27, 0xcc, 0x1b, 0xb0,
0x18, 0x77, 0x5a, 0x44, 0xc4, 0x84, 0x65, 0x2f, 0xaf, 0xe4, 0x3c, 0x74, 0xca, 0xe2, 0xc4, 0x8f,
0x42, 0xb4, 0xe9, 0x0d, 0x57, 0x15, 0x79, 0x7b, 0x7c, 0xf2, 0xda, 0x5e, 0xea, 0x15, 0x5c, 0xc4,
0x89, 0x97, 0x57, 0x92, 0xeb, 0x30, 0x8b, 0x13, 0x48, 0x3a, 0x6d, 0x2b, 0x46, 0xb0, 0xcd, 0x41,
0x57, 0xd6, 0x7d, 0xae, 0x5a, 0x6f, 0xb6, 0x5b, 0xf4, 0xc7, 0xa0, 0x86, 0x30, 0xdf, 0x74, 0xb1,
0x18, 0x82, 0x29, 0x44, 0x81, 0x0f, 0x2d, 0x64, 0xe9, 0x59, 0x14, 0x3f, 0x53, 0x21, 0x54, 0x59,
0xa4, 0x5f, 0x47, 0x27, 0x5e, 0x87, 0x11, 0x9f, 0xa0, 0x07, 0xc2, 0x8f, 0x62, 0x62, 0xa9, 0x93,
0x13, 0x4f, 0x9e, 0x2b, 0xea, 0x08, 0x1c, 0x9e, 0x78, 0x5c, 0x6d, 0x59, 0xbb, 0x27, 0x8e, 0x6a,
0x4d, 0xc4, 0xf6, 0xc4, 0xe6, 0x5d, 0x87, 0x05, 0x15, 0xa0, 0x4c, 0x7a, 0x01, 0x3b, 0x4e, 0x55,
0x24, 0x21, 0x9c, 0x8c, 0xf0, 0x3c, 0xb7, 0xcf, 0x8e, 0x53, 0xfa, 0x10, 0x96, 0xa4, 0x2a, 0x79,
0x34, 0x66, 0xaa, 0xeb, 0xcf, 0x94, 0x99, 0xe4, 0x73, 0x42, 0xb2, 0x36, 0x25, 0x75, 0x81, 0x98,
0xaa, 0x49, 0x36, 0x28, 0xed, 0xa2, 0x8a, 0x57, 0xc8, 0xe9, 0x58, 0x18, 0x5f, 0x9f, 0x64, 0xd2,
0xef, 0xab, 0x10, 0x33, 0x3f, 0xf0, 0x8a, 0x22, 0xfd, 0xb6, 0x03, 0xcb, 0xd8, 0x9a, 0x72, 0x2a,
0xa4, 0xfa, 0x7f, 0xe7, 0xfb, 0x18, 0x66, 0xab, 0x6f, 0xc6, 0x70, 0x56, 0xa0, 0x66, 0x1a, 0x04,
0x51, 0xf8, 0xfe, 0x8f, 0xed, 0xd5, 0xfc, 0xb1, 0x9d, 0xfe, 0xb6, 0x03, 0x4b, 0x42, 0x27, 0xa7,
0x5e, 0x3a, 0x49, 0xe4, 0xf4, 0x7f, 0x1c, 0xe6, 0x85, 0x71, 0x95, 0x52, 0x2d, 0x07, 0xba, 0xa2,
0x15, 0x10, 0xa2, 0x82, 0x78, 0xef, 0x92, 0x6b, 0x13, 0x93, 0xf7, 0xd0, 0xc1, 0x09, 0x7b, 0x88,
0xca, 0x30, 0xdb, 0xe5, 0x12, 0x33, 0xa0, 0xbf, 0x37, 0xc8, 0xef, 0xd6, 0x61, 0x56, 0x78, 0xb4,
0xf4, 0x3e, 0xcc, 0x5b, 0x1d, 0x59, 0x21, 0x83, 0x96, 0x08, 0x19, 0x14, 0x82, 0x4f, 0x95, 0x62,
0xf0, 0x89, 0xfe, 0xf1, 0x0c, 0x10, 0xce, 0x2c, 0xb9, 0xdd, 0xe0, 0x2e, 0x75, 0x34, 0xb0, 0x0e,
0x48, 0x2d, 0xd7, 0x84, 0xc8, 0x2d, 0x20, 0x46, 0x51, 0xc5, 0xe7, 0x84, 0xf5, 0x29, 0xa9, 0xe1,
0x6a, 0x52, 0x1a, 0x6f, 0x69, 0x66, 0xe5, 0x51, 0x50, 0x2c, 0x7b, 0x69, 0x1d, 0x37, 0x30, 0xe3,
0x49, 0x72, 0x82, 0x97, 0x11, 0xf2, 0x08, 0xa5, 0xca, 0xf9, 0xfd, 0x9d, 0xbd, 0x70, 0x7f, 0xe7,
0x0a, 0x61, 0x19, 0xc3, 0x89, 0xaf, 0x5b, 0x4e, 0x3c, 0x77, 0x1e, 0x47, 0xdc, 0xe5, 0x4c, 0x83,
0x7e, 0x6f, 0xc4, 0x7b, 0x97, 0x27, 0x26, 0x0b, 0x24, 0x1b, 0xd0, 0x96, 0xee, 0x46, 0x76, 0x52,
0x00, 0x5c, 0xe3, 0x02, 0xce, 0xf5, 0x77, 0x16, 0xa8, 0x69, 0xe2, 0x60, 0x33, 0x80, 0x9f, 0xad,
0x12, 0xce, 0x21, 0xbd, 0x49, 0x28, 0xef, 0x20, 0xd8, 0x00, 0xcf, 0x4a, 0x75, 0xb7, 0x58, 0x41,
0x7f, 0xd3, 0x81, 0x36, 0xdf, 0x33, 0x8b, 0x2d, 0xdf, 0x05, 0x94, 0x8a, 0x97, 0xe4, 0x4a, 0x8b,
0x96, 0xbc, 0x03, 0x0d, 0x2c, 0x47, 0x63, 0x16, 0x4a, 0x9e, 0xec, 0xd8, 0x3c, 0x99, 0xe9, 0x93,
0xbd, 0x4b, 0x6e, 0x46, 0x6c, 0x70, 0xe4, 0xdf, 0x38, 0xd0, 0x94, 0xbd, 0xfc, 0xc0, 0x81, 0x80,
0xae, 0x71, 0x71, 0x24, 0x38, 0x29, 0xbb, 0x23, 0xba, 0x09, 0x8b, 0x23, 0x2f, 0x9d, 0xc4, 0xdc,
0x1e, 0x5b, 0x41, 0x80, 0x3c, 0xcc, 0x8d, 0x2b, 0xaa, 0xce, 0xa4, 0x97, 0xfa, 0x41, 0x4f, 0xd5,
0xca, 0xeb, 0x99, 0xb2, 0x2a, 0xae, 0x41, 0x92, 0xd4, 0x1b, 0x32, 0x69, 0x37, 0x45, 0x81, 0x76,
0x60, 0x4d, 0x4e, 0x28, 0xe7, 0xaa, 0xd2, 0x3f, 0x6f, 0xc1, 0x7a, 0xa1, 0x4a, 0xdf, 0xe7, 0xca,
0xd3, 0x6d, 0xe0, 0x8f, 0x8e, 0x22, 0xed, 0xe7, 0x3b, 0xe6, 0xc1, 0xd7, 0xaa, 0x22, 0x43, 0x58,
0x55, 0x0e, 0x02, 0x5f, 0xd3, 0xcc, 0x98, 0x55, 0xd0, 0x4a, 0xbd, 0x65, 0x6f, 0x61, 0xbe, 0x43,
0x85, 0x9b, 0x42, 0x5c, 0xde, 0x1e, 0x39, 0x81, 0x8e, 0xf6, 0x44, 0xa4, 0xb2, 0x36, 0xbc, 0x15,
0xde, 0xd7, 0x9b, 0x17, 0xf4, 0x65, 0x79, 0xb6, 0xee, 0xb9, 0xad, 0x91, 0x29, 0x5c, 0x55, 0x75,
0xa8, 0x8d, 0x8b, 0xfd, 0x55, 0x5f, 0x6a, 0x6e, 0xe8, 0xb3, 0xdb, 0x9d, 0x5e, 0xd0, 0x30, 0xf9,
0x2a, 0xac, 0x9d, 0x79, 0x7e, 0xaa, 0x86, 0x65, 0xf8, 0x06, 0x35, 0xec, 0xf2, 0xce, 0x05, 0x5d,
0x3e, 0x15, 0x1f, 0x5b, 0x26, 0xea, 0x9c, 0x16, 0xbb, 0x7f, 0xe5, 0xc0, 0x82, 0xdd, 0x0e, 0x67,
0x53, 0x29, 0xfb, 0x4a, 0x07, 0x2a, 0x6f, 0x32, 0x07, 0x17, 0x8f, 0xca, 0x95, 0xb2, 0xa3, 0xb2,
0x79, 0x40, 0x9d, 0xb9, 0x28, 0x8a, 0x54, 0x7d, 0xb9, 0x28, 0x52, 0xad, 0x2c, 0x8a, 0xd4, 0xfd,
0x0f, 0x07, 0x48, 0x91, 0x97, 0xc8, 0x7d, 0x71, 0x56, 0x0f, 0x59, 0x20, 0x55, 0xca, 0xff, 0x7f,
0x39, 0x7e, 0x54, 0x6b, 0xa7, 0xbe, 0xe6, 0x82, 0x61, 0xde, 0xaf, 0x9a, 0xce, 0xce, 0xbc, 0x5b,
0x56, 0x95, 0x8b, 0x6b, 0x55, 0x2f, 0x8e, 0x6b, 0xd5, 0x2e, 0x8e, 0x6b, 0xcd, 0xe6, 0xe3, 0x5a,
0xdd, 0x5f, 0x72, 0x60, 0xb9, 0x64, 0xd3, 0x7f, 0x74, 0x13, 0xe7, 0xdb, 0x64, 0xe9, 0x82, 0x8a,
0xdc, 0x26, 0x13, 0xec, 0xfe, 0x1c, 0xcc, 0x5b, 0x8c, 0xfe, 0xa3, 0xeb, 0x3f, 0xef, 0xaf, 0x09,
0x3e, 0xb3, 0xb0, 0xee, 0xbf, 0x54, 0x80, 0x14, 0x85, 0xed, 0xff, 0x74, 0x0c, 0xc5, 0x75, 0x9a,
0x29, 0x59, 0xa7, 0xff, 0x55, 0x3b, 0xf0, 0x26, 0x2c, 0xc9, 0xe4, 0x0f, 0x23, 0x42, 0x23, 0x38,
0xa6, 0x58, 0xc1, 0x3d, 0x56, 0x3b, 0xa8, 0x58, 0xb7, 0x2e, 0xd1, 0x0d, 0x63, 0x98, 0x8b, 0x2d,
0xd2, 0x35, 0x58, 0x11, 0xc9, 0x24, 0x77, 0x45, 0x53, 0xca, 0xae, 0xfc, 0x9e, 0x03, 0xab, 0xb9,
0x8a, 0xec, 0xca, 0x57, 0x98, 0x0e, 0xdb, 0x9e, 0xd8, 0x20, 0x1f, 0xbf, 0xf6, 0x12, 0x72, 0xdc,
0x56, 0xac, 0xe0, 0xeb, 0x63, 0x78, 0x15, 0xb9, 0x55, 0x2f, 0xab, 0xa2, 0xeb, 0x22, 0xe5, 0x25,
0x64, 0x41, 0x6e, 0xe0, 0xc7, 0x22, 0x49, 0xc5, 0xac, 0xc8, 0x6e, 0x76, 0xec, 0x21, 0xab, 0x22,
0x77, 0x08, 0x2d, 0x33, 0x65, 0x8f, 0xb7, 0xb4, 0x8e, 0x7e, 0xd7, 0x01, 0xf2, 0x85, 0x09, 0x8b,
0xa7, 0x78, 0xad, 0xab, 0x43, 0x47, 0xeb, 0xf9, 0xc0, 0xc8, 0xec, 0x78, 0x72, 0xf4, 0x79, 0x36,
0x55, 0x09, 0x02, 0x95, 0x2c, 0x41, 0xe0, 0x55, 0x00, 0x7e, 0x90, 0xd2, 0x77, 0xc5, 0xe8, 0x88,
0x85, 0x93, 0x91, 0x68, 0xb0, 0xf4, 0x0e, 0xbf, 0x7a, 0xf1, 0x1d, 0x7e, 0xed, 0xa2, 0x3b, 0xfc,
0xf7, 0x60, 0xd9, 0x1a, 0xb7, 0xde, 0x56, 0x75, 0x6b, 0xed, 0xbc, 0xe0, 0xd6, 0xfa, 0x57, 0x2a,
0x30, 0xb3, 0x17, 0x8d, 0xcd, 0xb0, 0xa9, 0x63, 0x87, 0x4d, 0xa5, 0x2d, 0xe9, 0x69, 0x53, 0x21,
0x55, 0x8c, 0x05, 0x92, 0x0d, 0x58, 0xf0, 0x46, 0x29, 0x3f, 0xc7, 0x1f, 0x47, 0xf1, 0x99, 0x17,
0x0f, 0xc4, 0x5e, 0xe3, 0xf1, 0x3d, 0x57, 0x43, 0x56, 0x60, 0x46, 0x2b, 0x5d, 0x24, 0xe0, 0x45,
0xee, 0xb8, 0xe1, 0x95, 0xcb, 0x54, 0x86, 0x20, 0x64, 0x89, 0xb3, 0x92, 0xfd, 0xbd, 0xf0, 0x9a,
0x85, 0xe8, 0x94, 0x55, 0x71, 0xbb, 0xc6, 0x97, 0x0f, 0xc9, 0x64, 0xec, 0x48, 0x95, 0xcd, 0x38,
0x57, 0xdd, 0xbe, 0x80, 0xfa, 0x27, 0x07, 0x6a, 0xb8, 0x36, 0x5c, 0x0d, 0x08, 0xde, 0xd7, 0x91,
0x53, 0x5c, 0x93, 0x79, 0x37, 0x0f, 0x13, 0x6a, 0xa5, 0xd8, 0x54, 0xf4, 0x84, 0xcc, 0x34, 0x9b,
0x6b, 0xd0, 0x10, 0x25, 0x9d, 0x4e, 0x82, 0x24, 0x19, 0x48, 0xae, 0x42, 0xf5, 0x24, 0x1a, 0x2b,
0xbf, 0x05, 0xd4, 0xc5, 0x41, 0x34, 0x76, 0x11, 0xcf, 0xc6, 0xc3, 0xdb, 0x13, 0xd3, 0x12, 0xd6,
0x28, 0x0f, 0x73, 0x7b, 0xac, 0x9b, 0x35, 0x97, 0x29, 0x87, 0xd2, 0x0d, 0x58, 0x7c, 0x18, 0x0d,
0x98, 0x11, 0xbe, 0x3a, 0x97, 0xcf, 0xe9, 0xcf, 0x3b, 0x50, 0x57, 0xc4, 0xe4, 0x26, 0x54, 0xb9,
0x93, 0x91, 0x3b, 0x01, 0xe8, 0x0b, 0x43, 0x4e, 0xe7, 0x22, 0x05, 0xd7, 0xca, 0x18, 0x55, 0xc8,
0x1c, 0x4e, 0x15, 0x53, 0xc8, 0xfc, 0x29, 0x3d, 0xdc, 0x9c, 0x1b, 0x92, 0x43, 0xe9, 0x77, 0x1c,
0x98, 0xb7, 0xfa, 0xe0, 0x67, 0xc8, 0xc0, 0x4b, 0x52, 0x79, 0x09, 0x23, 0xb7, 0xc7, 0x84, 0xcc,
0x8d, 0xae, 0xd8, 0x01, 0x4d, 0x1d, 0x6a, 0x9b, 0x31, 0x43, 0x6d, 0xb7, 0xa1, 0x91, 0x25, 0x42,
0x55, 0x2d, 0x6d, 0xcb, 0x7b, 0x54, 0x57, 0xa1, 0x19, 0x11, 0x46, 0x6f, 0xa2, 0x20, 0x8a, 0x65,
0xf4, 0x5f, 0x14, 0xe8, 0x7b, 0xd0, 0x34, 0xe8, 0xcd, 0x60, 0x8e, 0x63, 0x05, 0x73, 0x74, 0x9e,
0x40, 0x25, 0xcb, 0x13, 0xa0, 0x7f, 0xe9, 0xc0, 0x3c, 0xe7, 0x41, 0x3f, 0x1c, 0x1e, 0x44, 0x81,
0xdf, 0x9f, 0xe2, 0xde, 0x2b, 0x76, 0x93, 0x3a, 0x43, 0xf1, 0xa2, 0x0d, 0x73, 0xae, 0x57, 0x47,
0x48, 0x29, 0xa2, 0xba, 0xcc, 0x65, 0x98, 0x4b, 0xc0, 0x91, 0x97, 0x48, 0xb1, 0x90, 0xe6, 0xcf,
0x02, 0xb9, 0xa4, 0x71, 0x20, 0xf6, 0x52, 0xd6, 0x1b, 0xf9, 0x41, 0xe0, 0x0b, 0x5a, 0xe1, 0x1c,
0x95, 0x55, 0xf1, 0x3e, 0x07, 0x7e, 0xe2, 0x1d, 0x65, 0x11, 0x6d, 0x5d, 0xa6, 0x7f, 0x5a, 0x81,
0xa6, 0x54, 0xdc, 0xbb, 0x83, 0x21, 0x93, 0xd7, 0x2f, 0xe8, 0x7e, 0x6a, 0x25, 0x63, 0x20, 0xaa,
0xde, 0x72, 0x58, 0x0d, 0x24, 0xbf, 0xe5, 0x33, 0xc5, 0x2d, 0xbf, 0x02, 0x0d, 0xce, 0x7a, 0x6f,
0xa1, 0x67, 0x2c, 0xae, 0x6e, 0x32, 0x40, 0xd5, 0xde, 0xc1, 0xda, 0x5a, 0x56, 0x8b, 0xc0, 0x0b,
0x2f, 0x6b, 0xde, 0x81, 0x96, 0x6c, 0x06, 0xf7, 0x04, 0x75, 0x4a, 0xc6, 0xfc, 0xd6, 0x7e, 0xb9,
0x16, 0xa5, 0xfa, 0xf2, 0x8e, 0xfa, 0xb2, 0x7e, 0xd1, 0x97, 0x8a, 0x92, 0xde, 0xd7, 0x77, 0x60,
0xf7, 0x63, 0x6f, 0x7c, 0xa2, 0xa4, 0xf4, 0x36, 0x2c, 0xfb, 0x61, 0x3f, 0x98, 0x0c, 0x58, 0x6f,
0x12, 0x7a, 0x61, 0x18, 0x4d, 0xc2, 0x3e, 0x53, 0x29, 0x00, 0x65, 0x55, 0x74, 0xa0, 0xb3, 0x92,
0xb0, 0x21, 0xb2, 0x01, 0x35, 0xde, 0x91, 0xb2, 0x0a, 0xe5, 0x22, 0x2c, 0x48, 0xc8, 0x4d, 0xa8,
0xb1, 0xc1, 0x90, 0xa9, 0xd3, 0x22, 0xb1, 0xcf, 0xed, 0x7c, 0x57, 0x5d, 0x41, 0xc0, 0x15, 0x0a,
0x47, 0x73, 0x0a, 0xc5, 0xb6, 0x28, 0xb3, 0xbc, 0xf8, 0x60, 0x40, 0x57, 0x80, 0x3c, 0x14, 0x32,
0x60, 0x86, 0xcf, 0x7f, 0x71, 0x06, 0x9a, 0x06, 0xcc, 0x75, 0xc3, 0x90, 0x0f, 0xb8, 0x37, 0xf0,
0xbd, 0x11, 0x4b, 0x59, 0x2c, 0xf9, 0x3e, 0x87, 0x72, 0x3a, 0xef, 0x74, 0xd8, 0x8b, 0x26, 0x69,
0x6f, 0xc0, 0x86, 0x31, 0x13, 0x46, 0x9e, 0x1b, 0x1d, 0x0b, 0xe5, 0x74, 0x23, 0xef, 0xb9, 0x49,
0x27, 0x38, 0x28, 0x87, 0xaa, 0x60, 0xb8, 0x58, 0xa3, 0x6a, 0x16, 0x0c, 0x17, 0x2b, 0x92, 0xd7,
0x6a, 0xb5, 0x12, 0xad, 0xf6, 0x36, 0xac, 0x09, 0xfd, 0x25, 0x25, 0xbd, 0x97, 0x63, 0xac, 0x73,
0x6a, 0xc9, 0x06, 0xb4, 0xf9, 0x98, 0x95, 0x48, 0x24, 0xfe, 0xd7, 0x45, 0x60, 0xc9, 0x71, 0x0b,
0x38, 0xa7, 0xc5, 0x08, 0x8f, 0x49, 0x2b, 0x2e, 0x07, 0x0b, 0x38, 0xd2, 0x7a, 0xcf, 0x6d, 0xda,
0x86, 0xa4, 0xcd, 0xe1, 0x74, 0x1e, 0x9a, 0x87, 0x69, 0x34, 0x56, 0x9b, 0xb2, 0x00, 0x2d, 0x51,
0x94, 0xa9, 0x18, 0xaf, 0xc0, 0x65, 0xe4, 0xa2, 0xc7, 0xd1, 0x38, 0x0a, 0xa2, 0xe1, 0xf4, 0x70,
0x72, 0x24, 0xd2, 0x73, 0xfd, 0x28, 0xa4, 0x7f, 0xed, 0xc0, 0xb2, 0x55, 0x2b, 0xa3, 0x47, 0x9f,
0x12, 0x42, 0xa0, 0xef, 0xd0, 0x05, 0xe3, 0x2d, 0x19, 0xca, 0x55, 0x10, 0x8a, 0x18, 0xe0, 0x13,
0x79, 0xad, 0xbe, 0x05, 0x8b, 0x6a, 0x64, 0xea, 0x43, 0xc1, 0x85, 0x9d, 0x22, 0x17, 0xca, 0xef,
0x17, 0xe4, 0x07, 0xaa, 0x89, 0x9f, 0x90, 0x97, 0xac, 0x03, 0x9c, 0xa3, 0x8a, 0x43, 0xe8, 0x8b,
0x31, 0xf3, 0x34, 0xa2, 0x46, 0xd0, 0xd7, 0x60, 0x42, 0x7f, 0xcd, 0x01, 0xc8, 0x46, 0x87, 0x57,
0x73, 0xda, 0x40, 0x88, 0x0c, 0x7a, 0xc3, 0x18, 0xbc, 0x0e, 0x2d, 0x7d, 0xa5, 0x93, 0xd9, 0x9c,
0xa6, 0xc2, 0xb8, 0xc3, 0x78, 0x03, 0x16, 0x87, 0x41, 0x74, 0x84, 0x06, 0x1b, 0x73, 0x7b, 0x12,
0x99, 0x90, 0xb2, 0x20, 0xe0, 0x7b, 0x12, 0xcd, 0x0c, 0x54, 0xd5, 0x30, 0x50, 0xf4, 0x1b, 0x15,
0x1d, 0x81, 0xcf, 0xe6, 0x7c, 0xae, 0x94, 0x91, 0x3b, 0x05, 0x75, 0x7a, 0x4e, 0xc0, 0x1b, 0x23,
0x6e, 0x07, 0x17, 0x06, 0x04, 0xde, 0x83, 0x85, 0x58, 0xe8, 0x2b, 0xa5, 0xcc, 0xaa, 0x2f, 0x50,
0x66, 0xf3, 0xb1, 0x65, 0xc5, 0x3e, 0x01, 0x6d, 0x6f, 0x70, 0xca, 0xe2, 0xd4, 0xc7, 0x23, 0x19,
0xba, 0x10, 0x42, 0x05, 0x2f, 0x1a, 0x38, 0x5a, 0xf6, 0x1b, 0xb0, 0x28, 0x93, 0x80, 0x34, 0xa5,
0x4c, 0x89, 0xcd, 0x60, 0x4e, 0x48, 0xff, 0x40, 0x05, 0xfb, 0xed, 0x3d, 0x3c, 0x7f, 0x45, 0xcc,
0xd9, 0x55, 0x72, 0xb3, 0xfb, 0x98, 0x0c, 0xbc, 0x0f, 0xd4, 0xb9, 0x6f, 0xc6, 0xb8, 0x90, 0x1f,
0xc8, 0x8b, 0x12, 0x7b, 0x49, 0xab, 0x2f, 0xb3, 0xa4, 0xf4, 0x7b, 0x0e, 0xcc, 0xed, 0x45, 0xe3,
0x3d, 0x99, 0x9a, 0x80, 0x82, 0xa0, 0xb3, 0xef, 0x54, 0xf1, 0x05, 0x49, 0x0b, 0xa5, 0x96, 0x7b,
0x3e, 0x6f, 0xb9, 0x7f, 0x0a, 0x5e, 0xc1, 0xa8, 0x43, 0x1c, 0x8d, 0xa3, 0x98, 0x0b, 0xa3, 0x17,
0x08, 0x33, 0x1d, 0x85, 0xe9, 0x89, 0x52, 0x63, 0x2f, 0x22, 0xc1, 0xe3, 0x1d, 0x3f, 0x96, 0x08,
0xa7, 0x5b, 0x7a, 0x1a, 0x42, 0xbb, 0x15, 0x2b, 0xe8, 0x67, 0xa0, 0x81, 0xae, 0x32, 0x4e, 0xeb,
0x4d, 0x68, 0x9c, 0x44, 0xe3, 0xde, 0x89, 0x1f, 0xa6, 0x4a, 0xb8, 0x17, 0x32, 0x1f, 0x76, 0x0f,
0x17, 0x44, 0x13, 0xd0, 0xff, 0xac, 0xc1, 0xdc, 0x83, 0xf0, 0x34, 0xf2, 0xfb, 0x78, 0xb1, 0x30,
0x62, 0xa3, 0x48, 0xe5, 0x22, 0xf2, 0xff, 0xc9, 0x15, 0x98, 0xc3, 0xe4, 0x9b, 0xb1, 0x60, 0xda,
0x96, 0xb8, 0x00, 0x94, 0x10, 0x77, 0x12, 0xe2, 0x2c, 0xe5, 0x58, 0x88, 0x8f, 0x81, 0xf0, 0x43,
0x44, 0x6c, 0xa6, 0x0c, 0xcb, 0x52, 0x96, 0xeb, 0x59, 0x33, 0x72, 0x3d, 0x79, 0x5f, 0x32, 0x95,
0x42, 0xdc, 0xb5, 0x8b, 0xbe, 0x24, 0x84, 0x07, 0x9f, 0x98, 0x89, 0xa8, 0x11, 0xba, 0x1c, 0x73,
0xf2, 0xe0, 0x63, 0x82, 0xdc, 0x2d, 0x11, 0x1f, 0x08, 0x1a, 0xa1, 0x84, 0x4d, 0x88, 0xbb, 0x70,
0xf9, 0x24, 0xef, 0x86, 0xe0, 0xfd, 0x1c, 0xcc, 0x35, 0xf5, 0x80, 0x69, 0x85, 0x2a, 0xe6, 0x01,
0x22, 0xad, 0x3a, 0x8f, 0x1b, 0xc7, 0x25, 0x91, 0x27, 0xa5, 0x8e, 0x4b, 0x9c, 0x61, 0xbc, 0x20,
0x38, 0xf2, 0xfa, 0xcf, 0x30, 0x87, 0x1f, 0x43, 0xfd, 0x0d, 0xd7, 0x06, 0x31, 0x21, 0x22, 0xdb,
0x55, 0xbc, 0x2a, 0xad, 0xba, 0x26, 0x44, 0xee, 0x40, 0x13, 0x8f, 0x88, 0x72, 0x5f, 0x17, 0x70,
0x5f, 0xdb, 0xe6, 0x19, 0x12, 0x77, 0xd6, 0x24, 0x32, 0x2f, 0x3d, 0x16, 0xed, 0x4b, 0x0f, 0xa1,
0x3c, 0xe5, 0x5d, 0x51, 0x1b, 0x7b, 0xcb, 0x00, 0x6e, 0x55, 0xe5, 0x82, 0x09, 0x82, 0x25, 0x24,
0xb0, 0x30, 0x72, 0x15, 0xea, 0xfc, 0xf8, 0x32, 0xf6, 0xfc, 0x41, 0x87, 0xe8, 0x53, 0x94, 0xc6,
0x78, 0x1b, 0xea, 0x7f, 0xbc, 0xd3, 0x59, 0xc6, 0x55, 0xb1, 0x30, 0xbe, 0x36, 0xba, 0x8c, 0xc2,
0xb4, 0x22, 0x76, 0xd4, 0x02, 0xc9, 0x5b, 0x18, 0xb1, 0x4f, 0x59, 0x67, 0x15, 0xd3, 0x62, 0x5e,
0x91, 0x73, 0x96, 0x4c, 0xab, 0xfe, 0x1e, 0x72, 0x12, 0x57, 0x50, 0xd2, 0x8f, 0x43, 0xcb, 0x84,
0x49, 0x1d, 0xaa, 0x8f, 0x0e, 0x76, 0x1f, 0xb6, 0x2f, 0x91, 0x26, 0xcc, 0x1d, 0xee, 0x3e, 0x7e,
0xbc, 0xbf, 0xbb, 0xd3, 0x76, 0x68, 0x0a, 0x64, 0x6b, 0x30, 0x90, 0x94, 0xfa, 0xa0, 0x9e, 0xf1,
0xac, 0x63, 0xf1, 0x6c, 0x09, 0xdf, 0x54, 0xca, 0xf9, 0xe6, 0x85, 0xab, 0x4b, 0x77, 0xa1, 0x79,
0x60, 0x64, 0xbf, 0xa3, 0x08, 0xa9, 0xbc, 0x77, 0x29, 0x7a, 0x06, 0x62, 0x0c, 0xa7, 0x62, 0x0e,
0x87, 0xfe, 0xa1, 0x23, 0xb2, 0x84, 0xf5, 0xf0, 0x45, 0xdf, 0x14, 0x5a, 0x3a, 0x9c, 0x92, 0x25,
0x9f, 0x59, 0x18, 0xa7, 0xc1, 0xa1, 0xf4, 0xa2, 0xe3, 0xe3, 0x84, 0xa9, 0x54, 0x11, 0x0b, 0xe3,
0xbc, 0xcf, 0xbd, 0x28, 0xee, 0x91, 0xf8, 0xa2, 0x87, 0x44, 0xa6, 0x8c, 0x14, 0x70, 0xae, 0xc9,
0x63, 0x76, 0xca, 0xe2, 0x44, 0x27, 0xc9, 0xe8, 0xb2, 0xce, 0x91, 0xcb, 0xaf, 0xf2, 0x06, 0xd4,
0x75, 0xbb, 0xb6, 0x92, 0x52, 0x94, 0xba, 0x9e, 0x2b, 0x43, 0x3c, 0x57, 0x58, 0x83, 0x16, 0x8a,
0xb9, 0x58, 0x41, 0x6e, 0x01, 0x39, 0xf6, 0xe3, 0x3c, 0xf9, 0x0c, 0x92, 0x97, 0xd4, 0xd0, 0xa7,
0xb0, 0xac, 0x98, 0xc5, 0x70, 0x9f, 0xec, 0x4d, 0x74, 0x2e, 0x12, 0x91, 0x4a, 0x51, 0x44, 0xe8,
0x7f, 0x39, 0x30, 0x27, 0x77, 0xba, 0xf0, 0x82, 0x42, 0xec, 0xb3, 0x85, 0x91, 0x8e, 0x95, 0x00,
0x8f, 0xf2, 0x24, 0x15, 0x63, 0x41, 0xf5, 0xcd, 0x94, 0xa9, 0x3e, 0x02, 0xd5, 0xb1, 0x97, 0x9e,
0xe0, 0x69, 0xb9, 0xe1, 0xe2, 0xff, 0xa4, 0x2d, 0x62, 0x3b, 0x42, 0xcd, 0x62, 0x5c, 0xa7, 0xec,
0xad, 0x88, 0xb0, 0xe8, 0xc5, 0xb7, 0x22, 0x57, 0xa0, 0x81, 0x03, 0xe8, 0x65, 0xa1, 0x9b, 0x0c,
0xe0, 0x9c, 0x2b, 0x0a, 0x28, 0xbb, 0x32, 0x17, 0x35, 0x43, 0xe8, 0xaa, 0xd8, 0x79, 0xb9, 0x04,
0xfa, 0x46, 0x4d, 0xe6, 0x24, 0x66, 0x70, 0xc6, 0x11, 0x72, 0x00, 0x79, 0x8e, 0x90, 0xa4, 0xae,
0xae, 0xa7, 0x5d, 0xe8, 0xec, 0xb0, 0x80, 0xa5, 0x6c, 0x2b, 0x08, 0xf2, 0xed, 0xbf, 0x02, 0x97,
0x4b, 0xea, 0xa4, 0xc7, 0xfc, 0x05, 0x58, 0xdd, 0x12, 0xf9, 0x5b, 0x3f, 0xaa, 0x9c, 0x04, 0xda,
0x81, 0xb5, 0x7c, 0x93, 0xb2, 0xb3, 0x7b, 0xb0, 0xb4, 0xc3, 0x8e, 0x26, 0xc3, 0x7d, 0x76, 0x9a,
0x75, 0x44, 0xa0, 0x9a, 0x9c, 0x44, 0x67, 0x52, 0x30, 0xf1, 0x7f, 0xf2, 0x2a, 0x40, 0xc0, 0x69,
0x7a, 0xc9, 0x98, 0xf5, 0x55, 0xce, 0x39, 0x22, 0x87, 0x63, 0xd6, 0xa7, 0x6f, 0x03, 0x31, 0xdb,
0x91, 0xeb, 0xc5, 0x2d, 0xdd, 0xe4, 0xa8, 0x97, 0x4c, 0x93, 0x94, 0x8d, 0x54, 0x32, 0xbd, 0x09,
0xd1, 0x1b, 0xd0, 0x3a, 0xf0, 0xa6, 0x2e, 0xfb, 0x9a, 0x7c, 0x38, 0xb3, 0x0e, 0x73, 0x63, 0x6f,
0xca, 0xd5, 0x94, 0x8e, 0x29, 0x61, 0x35, 0xfd, 0xf7, 0x0a, 0xcc, 0x0a, 0x4a, 0xde, 0xea, 0x80,
0x25, 0xa9, 0x1f, 0x22, 0x63, 0xa9, 0x56, 0x0d, 0xa8, 0xc0, 0xca, 0x95, 0x12, 0x56, 0x96, 0xe7,
0x32, 0x95, 0xbf, 0x2b, 0xf9, 0xd5, 0xc2, 0x38, 0x73, 0x65, 0xc9, 0x41, 0x22, 0xa8, 0x91, 0x01,
0xb9, 0xf0, 0x63, 0x66, 0x4f, 0xc5, 0xf8, 0x94, 0x94, 0x4a, 0xce, 0x35, 0xa1, 0x52, 0xab, 0x3d,
0x27, 0x18, 0xbc, 0x60, 0xb5, 0x0b, 0xd6, 0xb9, 0xfe, 0x12, 0xd6, 0x59, 0x1c, 0xd6, 0x5e, 0x64,
0x9d, 0xe1, 0x25, 0xac, 0x33, 0x25, 0xd0, 0xbe, 0xc7, 0x98, 0xcb, 0xb8, 0xff, 0xa7, 0x78, 0xf7,
0x9b, 0x0e, 0xb4, 0x25, 0x17, 0xe9, 0x3a, 0xf2, 0xba, 0xe5, 0xe7, 0x96, 0x66, 0xd9, 0x5e, 0x87,
0x79, 0xf4, 0x3e, 0x75, 0x9c, 0x55, 0x06, 0x85, 0x2d, 0x90, 0xcf, 0x43, 0x5d, 0x86, 0x8d, 0xfc,
0x40, 0x6e, 0x8a, 0x09, 0xa9, 0x50, 0x6d, 0xec, 0xc9, 0x24, 0x19, 0xc7, 0xd5, 0x65, 0xfa, 0x67,
0x0e, 0x2c, 0x19, 0x03, 0x96, 0x5c, 0xf8, 0x1e, 0x28, 0x69, 0x10, 0x41, 0x57, 0x21, 0xb9, 0xeb,
0xb6, 0xd8, 0x64, 0x9f, 0x59, 0xc4, 0xb8, 0x99, 0xde, 0x14, 0x07, 0x98, 0x4c, 0x46, 0x52, 0x89,
0x9a, 0x10, 0x67, 0xa4, 0x33, 0xc6, 0x9e, 0x69, 0x12, 0xa1, 0xc6, 0x2d, 0x0c, 0x33, 0x38, 0xb8,
0xd7, 0xac, 0x89, 0x84, 0x3d, 0xb3, 0x41, 0xfa, 0x77, 0x0e, 0x2c, 0x8b, 0xe3, 0x8f, 0x3c, 0x5c,
0xea, 0x27, 0x10, 0xb3, 0xe2, 0xbc, 0x27, 0x24, 0x72, 0xef, 0x92, 0x2b, 0xcb, 0xe4, 0xd3, 0x2f,
0x79, 0x64, 0xd3, 0x99, 0x3b, 0xe7, 0xec, 0xc5, 0x4c, 0xd9, 0x5e, 0xbc, 0x60, 0xa5, 0xcb, 0x82,
0x8c, 0xb5, 0xd2, 0x20, 0xe3, 0xdd, 0x39, 0xa8, 0x25, 0xfd, 0x68, 0xcc, 0xe8, 0x1a, 0xac, 0xd8,
0x93, 0x93, 0x2a, 0xe8, 0x5b, 0x0e, 0x74, 0xee, 0x89, 0x60, 0xbc, 0x1f, 0x0e, 0xf7, 0xfc, 0x24,
0x8d, 0x62, 0xfd, 0x52, 0xec, 0x2a, 0x40, 0x92, 0x7a, 0x71, 0x2a, 0xf2, 0x33, 0x65, 0x08, 0x30,
0x43, 0xf8, 0x18, 0x59, 0x38, 0x10, 0xb5, 0x62, 0x6f, 0x74, 0xb9, 0xe0, 0x43, 0xc8, 0x03, 0x9a,
0x65, 0x89, 0xdf, 0x10, 0x99, 0x6c, 0xdc, 0x57, 0x60, 0xa7, 0xa8, 0xd7, 0xc5, 0xc9, 0x27, 0x87,
0xd2, 0xbf, 0x75, 0x60, 0x31, 0x1b, 0xe4, 0x2e, 0x07, 0x6d, 0xed, 0x20, 0xcd, 0x6f, 0xa6, 0x1d,
0x54, 0x70, 0xd2, 0xe7, 0xf6, 0x58, 0x8e, 0xcd, 0x40, 0x50, 0x62, 0x65, 0x29, 0x9a, 0x28, 0x07,
0xc7, 0x84, 0x44, 0x5e, 0x0a, 0xf7, 0x04, 0xa4, 0x57, 0x23, 0x4b, 0x98, 0x5e, 0x3b, 0x4a, 0xf1,
0xab, 0x59, 0x71, 0xf4, 0x93, 0x45, 0x65, 0x4a, 0xe7, 0x10, 0x45, 0x53, 0x6a, 0x5e, 0x6c, 0xd4,
0xc5, 0xfa, 0xa8, 0x32, 0xfd, 0x75, 0x07, 0x2e, 0x97, 0x2c, 0xbc, 0x94, 0x9a, 0x1d, 0x58, 0x3a,
0xd6, 0x95, 0x6a, 0x71, 0x84, 0xe8, 0xac, 0xa9, 0x9b, 0x25, 0x7b, 0x41, 0xdc, 0xe2, 0x07, 0xda,
0x2f, 0x12, 0xcb, 0x6d, 0x65, 0x7e, 0x15, 0x2b, 0x36, 0x3e, 0x0b, 0x4d, 0xe3, 0x8d, 0x16, 0x59,
0x87, 0xe5, 0xa7, 0x0f, 0x1e, 0x3f, 0xdc, 0x3d, 0x3c, 0xec, 0x1d, 0x3c, 0xb9, 0xfb, 0xf9, 0xdd,
0x2f, 0xf5, 0xf6, 0xb6, 0x0e, 0xf7, 0xda, 0x97, 0xc8, 0x1a, 0x90, 0x87, 0xbb, 0x87, 0x8f, 0x77,
0x77, 0x2c, 0xdc, 0xb9, 0xf3, 0x1b, 0x33, 0xb0, 0x20, 0x6e, 0x2c, 0xc5, 0x1b, 0x79, 0x16, 0x93,
0xf7, 0x61, 0x4e, 0xfe, 0xc6, 0x01, 0x59, 0x95, 0xc3, 0xb6, 0x7f, 0x55, 0xa1, 0xbb, 0x96, 0x87,
0x25, 0x5f, 0x2e, 0xff, 0xc2, 0xf7, 0xfe, 0xf1, 0xb7, 0x2a, 0xf3, 0xa4, 0xb9, 0x79, 0xfa, 0xd6,
0xe6, 0x90, 0x85, 0x09, 0x6f, 0xe3, 0x67, 0x00, 0xb2, 0xd7, 0xff, 0xa4, 0xa3, 0xfd, 0xc1, 0xdc,
0xcf, 0x1a, 0x74, 0x2f, 0x97, 0xd4, 0xc8, 0x76, 0x2f, 0x63, 0xbb, 0xcb, 0x74, 0x81, 0xb7, 0xeb,
0x87, 0x7e, 0x2a, 0x7e, 0x0a, 0xe0, 0x5d, 0x67, 0x83, 0x0c, 0xa0, 0x65, 0x3e, 0xee, 0x27, 0x2a,
0xf0, 0x54, 0xf2, 0xd3, 0x02, 0xdd, 0x57, 0x4a, 0xeb, 0x54, 0xd4, 0x0d, 0xfb, 0x58, 0xa5, 0x6d,
0xde, 0xc7, 0x04, 0x29, 0xb2, 0x5e, 0x02, 0x58, 0xb0, 0xdf, 0xf0, 0x93, 0x2b, 0x86, 0xca, 0x28,
0xfc, 0x82, 0x40, 0xf7, 0xd5, 0x73, 0x6a, 0x65, 0x5f, 0xaf, 0x62, 0x5f, 0xeb, 0x94, 0xf0, 0xbe,
0xfa, 0x48, 0xa3, 0x7e, 0x41, 0xe0, 0x5d, 0x67, 0xe3, 0xce, 0xbf, 0xbd, 0x06, 0x0d, 0x1d, 0x2a,
0x26, 0x5f, 0x85, 0x79, 0xeb, 0x4a, 0x99, 0xa8, 0x69, 0x94, 0xdd, 0x40, 0x77, 0xaf, 0x94, 0x57,
0xca, 0x8e, 0xaf, 0x62, 0xc7, 0x1d, 0xb2, 0xc6, 0x3b, 0x96, 0x77, 0xb2, 0x9b, 0x78, 0x91, 0x2e,
0xb2, 0x62, 0x9f, 0x89, 0x79, 0x66, 0xd7, 0xc0, 0xd6, 0x3c, 0x0b, 0xd7, 0xc6, 0xd6, 0x3c, 0x8b,
0x77, 0xc7, 0xf4, 0x0a, 0x76, 0xb7, 0x46, 0x56, 0xcc, 0xee, 0x74, 0x08, 0x97, 0x61, 0x2a, 0xb7,
0xf9, 0xe4, 0x9d, 0xbc, 0xaa, 0x19, 0xab, 0xec, 0x29, 0xbc, 0x66, 0x91, 0xe2, 0x7b, 0x78, 0xda,
0xc1, 0xae, 0x08, 0xc1, 0xed, 0x33, 0x5f, 0xbc, 0x93, 0x2f, 0x43, 0x43, 0x3f, 0xd0, 0x24, 0xeb,
0xc6, 0x83, 0x59, 0xf3, 0x41, 0x69, 0xb7, 0x53, 0xac, 0x28, 0x63, 0x0c, 0xb3, 0x65, 0xce, 0x18,
0x4f, 0xa1, 0x69, 0x3c, 0xc2, 0x24, 0x97, 0x75, 0xa0, 0x3f, 0xff, 0xd0, 0xb3, 0xdb, 0x2d, 0xab,
0x92, 0x5d, 0x2c, 0x61, 0x17, 0x4d, 0xd2, 0x40, 0xde, 0x4b, 0x9f, 0x47, 0x09, 0xd9, 0x87, 0x55,
0x79, 0x70, 0x39, 0x62, 0xdf, 0xcf, 0x12, 0x95, 0xfc, 0x02, 0xc0, 0x6d, 0x87, 0xbc, 0x07, 0x75,
0xf5, 0xd6, 0x96, 0xac, 0x95, 0xbf, 0x19, 0xee, 0xae, 0x17, 0x70, 0xa9, 0xd6, 0xbe, 0x04, 0x90,
0xbd, 0xf8, 0xd4, 0x02, 0x5c, 0x78, 0x41, 0xaa, 0x77, 0xa7, 0xf8, 0x3c, 0x94, 0xae, 0xe1, 0x04,
0xdb, 0x04, 0x05, 0x38, 0x64, 0x67, 0xea, 0x71, 0xc3, 0x57, 0xa0, 0x69, 0x3c, 0xfa, 0xd4, 0xcb,
0x57, 0x7c, 0x30, 0xaa, 0x97, 0xaf, 0xe4, 0x8d, 0x28, 0xed, 0x62, 0xeb, 0x2b, 0x74, 0x91, 0xb7,
0x9e, 0xf8, 0xc3, 0x70, 0x24, 0x08, 0xf8, 0x06, 0x9d, 0xc0, 0xbc, 0xf5, 0xb2, 0x53, 0x4b, 0x4f,
0xd9, 0xbb, 0x51, 0x2d, 0x3d, 0xa5, 0x8f, 0x41, 0x15, 0x3b, 0xd3, 0x25, 0xde, 0xcf, 0x29, 0x92,
0x18, 0x3d, 0x7d, 0x00, 0x4d, 0xe3, 0x95, 0xa6, 0x9e, 0x4b, 0xf1, 0x41, 0xa8, 0x9e, 0x4b, 0xd9,
0xa3, 0xce, 0x15, 0xec, 0x63, 0x81, 0x22, 0x2b, 0xe0, 0xdb, 0x00, 0xde, 0xf6, 0x57, 0x61, 0xc1,
0x7e, 0xb7, 0xa9, 0xe5, 0xb2, 0xf4, 0x05, 0xa8, 0x96, 0xcb, 0x73, 0x1e, 0x7b, 0x4a, 0x96, 0xde,
0x58, 0xd6, 0x9d, 0x6c, 0x7e, 0x28, 0x2f, 0x6e, 0x3f, 0x22, 0x5f, 0xe0, 0xca, 0x47, 0x3e, 0xd6,
0x20, 0xeb, 0x06, 0xd7, 0x9a, 0x4f, 0x3a, 0xb4, 0xbc, 0x14, 0xde, 0x75, 0xd8, 0xcc, 0x2c, 0x5e,
0x37, 0xa0, 0x45, 0xc1, 0x47, 0x1b, 0x86, 0x45, 0x31, 0xdf, 0x75, 0x18, 0x16, 0xc5, 0x7a, 0xdb,
0x91, 0xb7, 0x28, 0xa9, 0xcf, 0xdb, 0x08, 0x61, 0x31, 0x97, 0xbe, 0xa4, 0xa5, 0xa2, 0x3c, 0xdf,
0xb3, 0x7b, 0xf5, 0xc5, 0x59, 0x4f, 0xb6, 0xa2, 0x52, 0x0a, 0x6a, 0x53, 0x65, 0xd7, 0xfe, 0x2c,
0xb4, 0xcc, 0xf7, 0x76, 0xc4, 0x14, 0xe5, 0x7c, 0x4f, 0xaf, 0x94, 0xd6, 0xd9, 0x9b, 0x4b, 0x5a,
0x66, 0x37, 0x7c, 0x73, 0xed, 0x07, 0x47, 0x99, 0xd2, 0x2d, 0x7b, 0x67, 0x95, 0x29, 0xdd, 0xd2,
0x57, 0x4a, 0x6a, 0x73, 0xc9, 0xb2, 0x35, 0x17, 0x11, 0x63, 0x27, 0x1f, 0xc0, 0xa2, 0x91, 0x1b,
0x78, 0x38, 0x0d, 0xfb, 0x9a, 0x51, 0x8b, 0x49, 0xe4, 0xdd, 0x32, 0xbf, 0x98, 0xae, 0x63, 0xfb,
0x4b, 0xd4, 0x9a, 0x04, 0x67, 0xd2, 0x6d, 0x68, 0x9a, 0x79, 0x87, 0x2f, 0x68, 0x77, 0xdd, 0xa8,
0x32, 0x73, 0xa0, 0x6f, 0x3b, 0xe4, 0x77, 0x1c, 0x68, 0x59, 0x59, 0x7c, 0xd6, 0x4d, 0x52, 0xae,
0x9d, 0x8e, 0x59, 0x67, 0x36, 0x44, 0x5d, 0x1c, 0xe4, 0xfe, 0xc6, 0xe7, 0xac, 0x45, 0xf8, 0xd0,
0x3a, 0x5f, 0xdd, 0xca, 0xff, 0xd8, 0xc3, 0x47, 0x79, 0x02, 0x33, 0xd1, 0xfe, 0xa3, 0xdb, 0x0e,
0xf9, 0x8e, 0x03, 0x0b, 0x76, 0x54, 0x40, 0x6f, 0x55, 0x69, 0xfc, 0x41, 0x6f, 0xd5, 0x39, 0xa1,
0x84, 0x0f, 0x70, 0x94, 0x8f, 0x37, 0x5c, 0x6b, 0x94, 0xf2, 0x29, 0xda, 0x0f, 0x37, 0x5a, 0xf2,
0xae, 0xf8, 0x79, 0x16, 0x15, 0xaa, 0x22, 0x86, 0x76, 0xcf, 0x6f, 0xaf, 0xf9, 0xdb, 0x24, 0x37,
0x9d, 0xdb, 0x0e, 0xf9, 0x8a, 0xf8, 0xfd, 0x09, 0xf9, 0x2d, 0x72, 0xc9, 0xcb, 0x7e, 0x4f, 0xaf,
0xe3, 0x9c, 0xae, 0xd2, 0xcb, 0xd6, 0x9c, 0xf2, 0x76, 0x73, 0x4b, 0x8c, 0x4e, 0xfe, 0xac, 0x48,
0xa6, 0xf8, 0x0b, 0x3f, 0x35, 0x72, 0xfe, 0x20, 0x47, 0x62, 0x90, 0x92, 0xdc, 0x62, 0xe5, 0x97,
0x6c, 0x86, 0x6e, 0xe0, 0x58, 0xaf, 0xd3, 0xd7, 0xce, 0x1d, 0xeb, 0x26, 0x9e, 0xed, 0xf9, 0x88,
0x0f, 0x00, 0xb2, 0xb0, 0x32, 0xc9, 0x85, 0x35, 0xb5, 0xed, 0x2b, 0x46, 0x9e, 0x6d, 0x79, 0x51,
0xd1, 0x4f, 0xde, 0xe2, 0x97, 0x85, 0x5a, 0x79, 0xa0, 0x02, 0xa2, 0xa6, 0xf3, 0x60, 0xc7, 0x7f,
0x2d, 0xe7, 0x21, 0xdf, 0xbe, 0xa5, 0x54, 0x74, 0x74, 0xf5, 0x09, 0xcc, 0xef, 0x47, 0xd1, 0xb3,
0xc9, 0x58, 0x5f, 0x03, 0xd9, 0x61, 0xb7, 0x3d, 0x2f, 0x39, 0xe9, 0xe6, 0x66, 0x41, 0xaf, 0x61,
0x53, 0x5d, 0xd2, 0x31, 0x9a, 0xda, 0xfc, 0x30, 0x0b, 0x5b, 0x7f, 0x44, 0x3c, 0x58, 0xd2, 0x6e,
0x89, 0x1e, 0x78, 0xd7, 0x6e, 0xc6, 0x0c, 0xb8, 0x16, 0xba, 0xb0, 0x3c, 0x50, 0x35, 0xda, 0xcd,
0x44, 0xb5, 0x79, 0xdb, 0x21, 0x07, 0xd0, 0xda, 0x61, 0xfd, 0x68, 0xc0, 0x64, 0xec, 0x6a, 0x39,
0x1b, 0xb8, 0x0e, 0x7a, 0x75, 0xe7, 0x2d, 0xd0, 0xd6, 0xdf, 0x63, 0x6f, 0x1a, 0xb3, 0xaf, 0x6d,
0x7e, 0x28, 0xa3, 0x62, 0x1f, 0x29, 0xfd, 0xad, 0xc2, 0x86, 0x96, 0xfe, 0xce, 0xc5, 0x19, 0x2d,
0xfd, 0x5d, 0x88, 0x33, 0x5a, 0x4b, 0xad, 0xc2, 0x96, 0x24, 0x80, 0xa5, 0x42, 0x68, 0x92, 0xbc,
0xa6, 0x2c, 0xf0, 0x39, 0x01, 0xcd, 0xee, 0xb5, 0xf3, 0x09, 0xec, 0xde, 0x36, 0xec, 0xde, 0x0e,
0x61, 0x7e, 0x87, 0x89, 0xc5, 0x12, 0xb9, 0x26, 0xb9, 0x37, 0xa8, 0x66, 0x26, 0x4b, 0x5e, 0x81,
0x63, 0x9d, 0x6d, 0xa0, 0x31, 0xd1, 0x83, 0x7c, 0x19, 0x9a, 0xf7, 0x59, 0xaa, 0x92, 0x4b, 0xb4,
0x8b, 0x98, 0xcb, 0x36, 0xe9, 0x96, 0xe4, 0xa6, 0xd8, 0x3c, 0x83, 0xad, 0x6d, 0xb2, 0xc1, 0x90,
0x09, 0xe5, 0xd4, 0xf3, 0x07, 0x1f, 0x91, 0x9f, 0xc6, 0xc6, 0x75, 0x76, 0xdb, 0x9a, 0x91, 0x93,
0x60, 0x36, 0xbe, 0x98, 0xc3, 0xcb, 0x5a, 0x0e, 0xa3, 0x01, 0x33, 0x5c, 0x95, 0x10, 0x9a, 0x46,
0x52, 0xa6, 0x16, 0xa0, 0x62, 0x82, 0xa9, 0x16, 0xa0, 0x92, 0x1c, 0x4e, 0x7a, 0x13, 0xfb, 0xa1,
0xe4, 0x5a, 0xd6, 0x8f, 0xc8, 0xdb, 0xcc, 0x7a, 0xda, 0xfc, 0xd0, 0x1b, 0xa5, 0x1f, 0x91, 0xa7,
0xf8, 0x1e, 0xd5, 0x4c, 0xa0, 0xc9, 0x7c, 0xde, 0x7c, 0xae, 0x8d, 0x5e, 0x2c, 0xa3, 0xca, 0xf6,
0x83, 0x45, 0x57, 0xe8, 0xd1, 0x7c, 0x1a, 0xe0, 0x30, 0x8d, 0xc6, 0x3b, 0x1e, 0x1b, 0x45, 0x61,
0xa6, 0x6b, 0xb3, 0x24, 0x91, 0x4c, 0x7f, 0x19, 0x99, 0x22, 0xe4, 0xa9, 0x71, 0x48, 0xb0, 0xf2,
0x8f, 0x14, 0x73, 0x9d, 0x9b, 0x47, 0xa2, 0x17, 0xa4, 0x24, 0x97, 0xe4, 0xb6, 0x43, 0xb6, 0x00,
0xb2, 0xd8, 0xb4, 0x76, 0xf9, 0x0b, 0x61, 0x6f, 0xad, 0xf6, 0x4a, 0x02, 0xd9, 0x07, 0xd0, 0xc8,
0x82, 0x9d, 0xeb, 0x59, 0x62, 0xad, 0x15, 0x1a, 0xd5, 0x16, 0xbc, 0x10, 0x82, 0xa4, 0x6d, 0x5c,
0x2a, 0x20, 0x75, 0xbe, 0x54, 0x18, 0x57, 0xf4, 0x61, 0x59, 0x0c, 0x50, 0xbb, 0x23, 0x98, 0xf6,
0xa0, 0x66, 0x52, 0x12, 0x06, 0xd4, 0xd2, 0x5c, 0x1a, 0x45, 0xb3, 0xa2, 0x0a, 0x9c, 0x5b, 0x45,
0xca, 0x05, 0x57, 0xcd, 0x23, 0x58, 0x2a, 0x84, 0x79, 0xb4, 0x48, 0x9f, 0x17, 0x79, 0xd3, 0x22,
0x7d, 0x6e, 0x84, 0x88, 0xae, 0x62, 0x97, 0x8b, 0x14, 0xf0, 0xa4, 0x72, 0xe6, 0xa7, 0xfd, 0x93,
0x77, 0x9d, 0x8d, 0xbb, 0x37, 0x3e, 0xf8, 0xf8, 0xd0, 0x4f, 0x4f, 0x26, 0x47, 0xb7, 0xfa, 0xd1,
0x68, 0x33, 0x50, 0x47, 0x7f, 0x99, 0xbc, 0xb4, 0x19, 0x84, 0x83, 0x4d, 0x6c, 0xf9, 0x68, 0x16,
0x7f, 0xe7, 0xf2, 0x93, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x2c, 0x41, 0x1a, 0x19, 0x53,
0x00, 0x00,
}

@ -837,6 +837,13 @@ message SendCoinsRequest {
/// A manual fee rate set in sat/byte that should be used when crafting the transaction.
int64 sat_per_byte = 5;
/**
If set, then the amount field will be ignored, and lnd will attempt to
send all the coins under control of the internal wallet to the specified
address.
*/
bool send_all = 6;
}
message SendCoinsResponse {
/// The transaction ID of the transaction

@ -1288,10 +1288,12 @@
"type": "object",
"properties": {
"chain": {
"type": "string"
"type": "string",
"title": "/ The blockchain the node is on (eg bitcoin, litecoin)"
},
"network": {
"type": "string"
"type": "string",
"title": "/ The network the node is on (eg regtest, testnet, mainnet)"
}
}
},
@ -2782,6 +2784,11 @@
"type": "string",
"format": "int64",
"description": "/ A manual fee rate set in sat/byte that should be used when crafting the transaction."
},
"send_all": {
"type": "boolean",
"format": "boolean",
"description": "*\nIf set, then the amount field will be ignored, and lnd will attempt to\nsend all the coins under control of the internal wallet to the specified\naddress."
}
}
},

@ -180,9 +180,10 @@ func (b *BtcWallet) SignOutputRaw(tx *wire.MsgTx,
// TODO(roasbeef): generate sighash midstate if not present?
amt := signDesc.Output.Value
sig, err := txscript.RawTxInWitnessSignature(tx, signDesc.SigHashes,
signDesc.InputIndex, amt, witnessScript, signDesc.HashType,
privKey)
sig, err := txscript.RawTxInWitnessSignature(
tx, signDesc.SigHashes, signDesc.InputIndex, amt,
witnessScript, signDesc.HashType, privKey,
)
if err != nil {
return nil, err
}
@ -227,8 +228,9 @@ func (b *BtcWallet) ComputeInputScript(tx *wire.MsgTx,
// spend the p2sh output. The sigScript will contain only a
// single push of the p2wkh witness program corresponding to
// the matching public key of this address.
p2wkhAddr, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash,
b.netParams)
p2wkhAddr, err := btcutil.NewAddressWitnessPubKeyHash(
pubKeyHash, b.netParams,
)
if err != nil {
return nil, err
}
@ -244,7 +246,7 @@ func (b *BtcWallet) ComputeInputScript(tx *wire.MsgTx,
return nil, err
}
inputScript.ScriptSig = sigScript
inputScript.SigScript = sigScript
// Otherwise, this is a regular p2wkh output, so we include the
// witness program itself as the subscript to generate the proper
@ -267,7 +269,8 @@ func (b *BtcWallet) ComputeInputScript(tx *wire.MsgTx,
// TODO(roasbeef): adhere to passed HashType
witnessScript, err := txscript.WitnessSignature(tx, signDesc.SigHashes,
signDesc.InputIndex, signDesc.Output.Value, witnessProgram,
signDesc.HashType, privKey, true)
signDesc.HashType, privKey, true,
)
if err != nil {
return nil, err
}

@ -127,7 +127,7 @@ type TransactionSubscription interface {
type WalletController interface {
// FetchInputInfo queries for the WalletController's knowledge of the
// passed outpoint. If the base wallet determines this output is under
// its control, then the original txout should be returned. Otherwise,
// its control, then the original txout should be returned. Otherwise,
// a non-nil error value of ErrNotMine should be returned instead.
FetchInputInfo(prevOut *wire.OutPoint) (*wire.TxOut, error)

@ -50,11 +50,15 @@ func (c *ChannelContribution) toChanConfig() channeldb.ChannelConfig {
}
// InputScript represents any script inputs required to redeem a previous
// output. This struct is used rather than just a witness, or scripSig in
// order to accommodate nested p2sh which utilizes both types of input scripts.
// output. This struct is used rather than just a witness, or scripSig in order
// to accommodate nested p2sh which utilizes both types of input scripts.
type InputScript struct {
Witness [][]byte
ScriptSig []byte
// Witness is the full witness stack required to unlock this output.
Witness wire.TxWitness
// SigScript will only be populated if this is an input script sweeping
// a nested p2sh output.
SigScript []byte
}
// ChannelReservation represents an intent to open a lightning payment channel

@ -438,13 +438,15 @@ func (m *mockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor
"address %v", addresses[0])
}
scriptSig, err := txscript.SignatureScript(tx, signDesc.InputIndex,
signDesc.Output.PkScript, txscript.SigHashAll, privKey, true)
sigScript, err := txscript.SignatureScript(
tx, signDesc.InputIndex, signDesc.Output.PkScript,
txscript.SigHashAll, privKey, true,
)
if err != nil {
return nil, err
}
return &InputScript{ScriptSig: scriptSig}, nil
return &InputScript{SigScript: sigScript}, nil
case txscript.WitnessV0PubKeyHashTy:
privKey := m.findKey(addresses[0].ScriptAddress(), signDesc.SingleTweak,

@ -747,14 +747,15 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
signDesc.Output = info
signDesc.InputIndex = i
inputScript, err := l.Cfg.Signer.ComputeInputScript(fundingTx,
&signDesc)
inputScript, err := l.Cfg.Signer.ComputeInputScript(
fundingTx, &signDesc,
)
if err != nil {
req.err <- err
return
}
txIn.SignatureScript = inputScript.ScriptSig
txIn.SignatureScript = inputScript.SigScript
txIn.Witness = inputScript.Witness
pendingReservation.ourFundingInputScripts = append(
pendingReservation.ourFundingInputScripts,
@ -958,7 +959,7 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
if len(inputScripts) != 0 && len(txin.Witness) == 0 {
// Attach the input scripts so we can verify it below.
txin.Witness = inputScripts[sigIndex].Witness
txin.SignatureScript = inputScripts[sigIndex].ScriptSig
txin.SignatureScript = inputScripts[sigIndex].SigScript
// Fetch the alleged previous output along with the
// pkscript referenced by this input.
@ -1251,12 +1252,22 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
l.limboMtx.Unlock()
}
// WithCoinSelectLock will execute the passed function closure in a
// synchronized manner preventing any coin selection operations from proceeding
// while the closure if executing. This can be seen as the ability to execute a
// function closure under an exclusive coin selection lock.
func (l *LightningWallet) WithCoinSelectLock(f func() error) error {
l.coinSelectMtx.Lock()
defer l.coinSelectMtx.Unlock()
return f()
}
// selectCoinsAndChange performs coin selection in order to obtain witness
// outputs which sum to at least 'numCoins' amount of satoshis. If coin
// selection is successful/possible, then the selected coins are available
// within the passed contribution's inputs. If necessary, a change address will
// also be generated.
// TODO(roasbeef): remove hardcoded fees.
func (l *LightningWallet) selectCoinsAndChange(feeRate SatPerKWeight,
amt btcutil.Amount, minConfs int32,
contribution *ChannelContribution) error {

@ -69,6 +69,16 @@ const (
// broadcast a revoked commitment, but then also immediately attempt to
// go to the second level to claim the HTLC.
HtlcSecondLevelRevoke WitnessType = 9
// WitnessKeyHash is a witness type that allows us to spend a regular
// p2wkh output that's sent to an output which is under complete
// control of the backing wallet.
WitnessKeyHash WitnessType = 10
// NestedWitnessKeyHash is a witness type that allows us to sweep an
// output that sends to a nested P2SH script that pays to a key solely
// under our control. The witness generated needs to include the
NestedWitnessKeyHash WitnessType = 11
)
// Stirng returns a human readable version of the target WitnessType.
@ -110,18 +120,22 @@ func (wt WitnessType) String() string {
}
// WitnessGenerator represents a function which is able to generate the final
// witness for a particular public key script. This function acts as an
// abstraction layer, hiding the details of the underlying script.
// witness for a particular public key script. Additionally, if required, this
// function will also return the sigScript for spending nested P2SH witness
// outputs. This function acts as an abstraction layer, hiding the details of
// the underlying script.
type WitnessGenerator func(tx *wire.MsgTx, hc *txscript.TxSigHashes,
inputIndex int) ([][]byte, error)
inputIndex int) (*InputScript, error)
// GenWitnessFunc will return a WitnessGenerator function that an output
// uses to generate the witness for a sweep transaction.
// GenWitnessFunc will return a WitnessGenerator function that an output uses
// to generate the witness and optionally the sigScript for a sweep
// transaction. The sigScript will be generated if the witness type warrants
// one for spending, such as the NestedWitnessKeyHash witness type.
func (wt WitnessType) GenWitnessFunc(signer Signer,
descriptor *SignDescriptor) WitnessGenerator {
return func(tx *wire.MsgTx, hc *txscript.TxSigHashes,
inputIndex int) ([][]byte, error) {
inputIndex int) (*InputScript, error) {
desc := descriptor
desc.SigHashes = hc
@ -129,34 +143,102 @@ func (wt WitnessType) GenWitnessFunc(signer Signer,
switch wt {
case CommitmentTimeLock:
return CommitSpendTimeout(signer, desc, tx)
witness, err := CommitSpendTimeout(signer, desc, tx)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case CommitmentNoDelay:
return CommitSpendNoDelay(signer, desc, tx)
witness, err := CommitSpendNoDelay(signer, desc, tx)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case CommitmentRevoke:
return CommitSpendRevoke(signer, desc, tx)
witness, err := CommitSpendRevoke(signer, desc, tx)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case HtlcOfferedRevoke:
return ReceiverHtlcSpendRevoke(signer, desc, tx)
witness, err := ReceiverHtlcSpendRevoke(signer, desc, tx)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case HtlcAcceptedRevoke:
return SenderHtlcSpendRevoke(signer, desc, tx)
witness, err := SenderHtlcSpendRevoke(signer, desc, tx)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case HtlcOfferedTimeoutSecondLevel:
return HtlcSecondLevelSpend(signer, desc, tx)
witness, err := HtlcSecondLevelSpend(signer, desc, tx)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case HtlcAcceptedSuccessSecondLevel:
return HtlcSecondLevelSpend(signer, desc, tx)
witness, err := HtlcSecondLevelSpend(signer, desc, tx)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case HtlcOfferedRemoteTimeout:
// We pass in a value of -1 for the timeout, as we
// expect the caller to have already set the lock time
// value.
return receiverHtlcSpendTimeout(signer, desc, tx, -1)
witness, err := receiverHtlcSpendTimeout(signer, desc, tx, -1)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case HtlcSecondLevelRevoke:
return htlcSpendRevoke(signer, desc, tx)
witness, err := htlcSpendRevoke(signer, desc, tx)
if err != nil {
return nil, err
}
return &InputScript{
Witness: witness,
}, nil
case WitnessKeyHash:
fallthrough
case NestedWitnessKeyHash:
return signer.ComputeInputScript(tx, desc)
default:
return nil, fmt.Errorf("unknown witness type: %v", wt)

@ -39,6 +39,7 @@ import (
"github.com/lightningnetwork/lnd/macaroons"
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/signal"
"github.com/lightningnetwork/lnd/sweep"
"github.com/lightningnetwork/lnd/zpay32"
"github.com/tv42/zbase32"
"golang.org/x/net/context"
@ -637,53 +638,7 @@ func (r *rpcServer) sendCoinsOnChain(paymentMap map[string]int64,
}
txHash := tx.TxHash()
return &txHash, err
}
// determineFeePerKw will determine the fee in sat/kw that should be paid given
// an estimator, a confirmation target, and a manual value for sat/byte. A value
// is chosen based on the two free parameters as one, or both of them can be
// zero.
func determineFeePerKw(feeEstimator lnwallet.FeeEstimator, targetConf int32,
feePerByte int64) (lnwallet.SatPerKWeight, error) {
switch {
// If the target number of confirmations is set, then we'll use that to
// consult our fee estimator for an adequate fee.
case targetConf != 0:
feePerKw, err := feeEstimator.EstimateFeePerKW(
uint32(targetConf),
)
if err != nil {
return 0, fmt.Errorf("unable to query fee "+
"estimator: %v", err)
}
return feePerKw, nil
// If a manual sat/byte fee rate is set, then we'll use that directly.
// We'll need to convert it to sat/kw as this is what we use internally.
case feePerByte != 0:
feePerKW := lnwallet.SatPerKVByte(feePerByte * 1000).FeePerKWeight()
if feePerKW < lnwallet.FeePerKwFloor {
rpcsLog.Infof("Manual fee rate input of %d sat/kw is "+
"too low, using %d sat/kw instead", feePerKW,
lnwallet.FeePerKwFloor)
feePerKW = lnwallet.FeePerKwFloor
}
return feePerKW, nil
// Otherwise, we'll attempt a relaxed confirmation target for the
// transaction
default:
feePerKw, err := feeEstimator.EstimateFeePerKW(6)
if err != nil {
return 0, fmt.Errorf("unable to query fee estimator: "+
"%v", err)
}
return feePerKw, nil
}
return &txHash, nil
}
// ListUnspent returns useful information about each unspent output owned by
@ -803,20 +758,100 @@ func (r *rpcServer) SendCoins(ctx context.Context,
// Based on the passed fee related parameters, we'll determine an
// appropriate fee rate for this transaction.
feePerKw, err := determineFeePerKw(
r.server.cc.feeEstimator, in.TargetConf, in.SatPerByte,
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
feePerKw, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw,
},
)
if err != nil {
return nil, err
}
rpcsLog.Infof("[sendcoins] addr=%v, amt=%v, sat/kw=%v", in.Addr,
btcutil.Amount(in.Amount), int64(feePerKw))
rpcsLog.Infof("[sendcoins] addr=%v, amt=%v, sat/kw=%v, sweep_all=%v",
in.Addr, btcutil.Amount(in.Amount), int64(feePerKw),
in.SendAll)
paymentMap := map[string]int64{in.Addr: in.Amount}
txid, err := r.sendCoinsOnChain(paymentMap, feePerKw)
if err != nil {
return nil, err
var txid *chainhash.Hash
wallet := r.server.cc.wallet
// If the send all flag is active, then we'll attempt to sweep all the
// coins in the wallet in a single transaction (if possible),
// otherwise, we'll respect the amount, and attempt a regular 2-output
// send.
if in.SendAll {
// At this point, the amount shouldn't be set since we've been
// instructed to sweep all the coins from the wallet.
if in.Amount != 0 {
return nil, fmt.Errorf("amount set while SendAll is " +
"active")
}
// Additionally, we'll need to convert the sweep address passed
// into a useable struct, and also query for the latest block
// height so we can properly construct the transaction.
sweepAddr, err := btcutil.DecodeAddress(
in.Addr, activeNetParams.Params,
)
if err != nil {
return nil, err
}
_, bestHeight, err := r.server.cc.chainIO.GetBestBlock()
if err != nil {
return nil, err
}
// With the sweeper instance created, we can now generate a
// transaction that will sweep ALL outputs from the wallet in a
// single transaction. This will be generated in a concurrent
// safe manner, so no need to worry about locking.
sweepTxPkg, err := sweep.CraftSweepAllTx(
feePerKw, uint32(bestHeight), sweepAddr, wallet,
wallet.WalletController, wallet.WalletController,
r.server.cc.feeEstimator, r.server.cc.signer,
)
if err != nil {
return nil, err
}
rpcsLog.Debugf("Sweeping all coins from wallet to addr=%v, "+
"with tx=%v", in.Addr, spew.Sdump(sweepTxPkg.SweepTx))
// As our sweep transaction was created, successfully, we'll
// now attempt to publish it, cancelling the sweep pkg to
// return all outputs if it fails.
err = wallet.PublishTransaction(sweepTxPkg.SweepTx)
if err != nil {
sweepTxPkg.CancelSweepAttempt()
return nil, fmt.Errorf("unable to broadcast sweep "+
"transaction: %v", err)
}
sweepTXID := sweepTxPkg.SweepTx.TxHash()
txid = &sweepTXID
} else {
// We'll now construct out payment map, and use the wallet's
// coin selection synchronization method to ensure that no coin
// selection (funding, sweep alls, other sends) can proceed
// while we instruct the wallet to send this transaction.
paymentMap := map[string]int64{in.Addr: in.Amount}
err := wallet.WithCoinSelectLock(func() error {
newTXID, err := r.sendCoinsOnChain(paymentMap, feePerKw)
if err != nil {
return err
}
txid = newTXID
return nil
})
if err != nil {
return nil, err
}
}
rpcsLog.Infof("[sendcoins] spend generated txid: %v", txid.String())
@ -831,8 +866,12 @@ func (r *rpcServer) SendMany(ctx context.Context,
// Based on the passed fee related parameters, we'll determine an
// appropriate fee rate for this transaction.
feePerKw, err := determineFeePerKw(
r.server.cc.feeEstimator, in.TargetConf, in.SatPerByte,
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
feePerKw, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw,
},
)
if err != nil {
return nil, err
@ -841,7 +880,24 @@ func (r *rpcServer) SendMany(ctx context.Context,
rpcsLog.Infof("[sendmany] outputs=%v, sat/kw=%v",
spew.Sdump(in.AddrToAmount), int64(feePerKw))
txid, err := r.sendCoinsOnChain(in.AddrToAmount, feePerKw)
var txid *chainhash.Hash
// We'll attempt to send to the target set of outputs, ensuring that we
// synchronize with any other ongoing coin selection attempts which
// happen to also be concurrently executing.
wallet := r.server.cc.wallet
err = wallet.WithCoinSelectLock(func() error {
sendManyTXID, err := r.sendCoinsOnChain(
in.AddrToAmount, feePerKw,
)
if err != nil {
return err
}
txid = sendManyTXID
return nil
})
if err != nil {
return nil, err
}
@ -1170,8 +1226,12 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
// Based on the passed fee related parameters, we'll determine an
// appropriate fee rate for the funding transaction.
feeRate, err := determineFeePerKw(
r.server.cc.feeEstimator, in.TargetConf, in.SatPerByte,
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
feeRate, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw,
},
)
if err != nil {
return err
@ -1317,8 +1377,12 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
// Based on the passed fee related parameters, we'll determine an
// appropriate fee rate for the funding transaction.
feeRate, err := determineFeePerKw(
r.server.cc.feeEstimator, in.TargetConf, in.SatPerByte,
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
feeRate, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw,
},
)
if err != nil {
return nil, err
@ -1506,8 +1570,14 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
// Based on the passed fee related parameters, we'll determine
// an appropriate fee rate for the cooperative closure
// transaction.
feeRate, err := determineFeePerKw(
r.server.cc.feeEstimator, in.TargetConf, in.SatPerByte,
satPerKw := lnwallet.SatPerKVByte(
in.SatPerByte * 1000,
).FeePerKWeight()
feeRate, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw,
},
)
if err != nil {
return err

@ -608,7 +608,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
}
s.sweeper = sweep.New(&sweep.UtxoSweeperConfig{
Estimator: cc.feeEstimator,
FeeEstimator: cc.feeEstimator,
GenSweepScript: func() ([]byte, error) {
return newSweepPkScript(cc.wallet)
},

@ -1,8 +1,9 @@
package sweep
import (
"github.com/lightningnetwork/lnd/lnwallet"
"sync"
"github.com/lightningnetwork/lnd/lnwallet"
)
// mockFeeEstimator implements a mock fee estimator. It closely resembles
@ -13,6 +14,8 @@ type mockFeeEstimator struct {
relayFee lnwallet.SatPerKWeight
blocksToFee map[uint32]lnwallet.SatPerKWeight
lock sync.Mutex
}
@ -20,8 +23,9 @@ func newMockFeeEstimator(feePerKW,
relayFee lnwallet.SatPerKWeight) *mockFeeEstimator {
return &mockFeeEstimator{
feePerKW: feePerKW,
relayFee: relayFee,
feePerKW: feePerKW,
relayFee: relayFee,
blocksToFee: make(map[uint32]lnwallet.SatPerKWeight),
}
}
@ -41,6 +45,10 @@ func (e *mockFeeEstimator) EstimateFeePerKW(numBlocks uint32) (
e.lock.Lock()
defer e.lock.Unlock()
if fee, ok := e.blocksToFee[numBlocks]; ok {
return fee, nil
}
return e.feePerKW, nil
}

@ -6,7 +6,10 @@ import (
"github.com/lightningnetwork/lnd/lnwallet"
)
// Input contains all data needed to construct a sweep tx input.
// Input represents an abstract UTXO which is to be spent using a sweeping
// transaction. The method provided give the caller all information needed to
// construct a valid input within a sweeping transaction to sweep this
// lingering UTXO.
type Input interface {
// Outpoint returns the reference to the output being spent, used to
// construct the corresponding transaction input.
@ -21,12 +24,14 @@ type Input interface {
// that spends this output.
SignDesc() *lnwallet.SignDescriptor
// BuildWitness returns a valid witness allowing this output to be
// spent, the witness should be attached to the transaction at the
// location determined by the given `txinIdx`.
BuildWitness(signer lnwallet.Signer, txn *wire.MsgTx,
// CraftInputScript returns a valid set of input scripts allowing this
// output to be spent. The returns input scripts should target the
// input at location txIndex within the passed transaction. The input
// scripts generated by this method support spending p2wkh, p2wsh, and
// also nested p2sh outputs.
CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes,
txinIdx int) ([][]byte, error)
txinIdx int) (*lnwallet.InputScript, error)
// BlocksToMaturity returns the relative timelock, as a number of
// blocks, that must be built on top of the confirmation height before
@ -91,12 +96,12 @@ func MakeBaseInput(outpoint *wire.OutPoint, witnessType lnwallet.WitnessType,
}
}
// BuildWitness computes a valid witness that allows us to spend from the
// breached output. It does so by generating the witness generation function,
// which is parameterized primarily by the witness type and sign descriptor.
// The method then returns the witness computed by invoking this function.
func (bi *BaseInput) BuildWitness(signer lnwallet.Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) ([][]byte, error) {
// CraftInputScript returns a valid set of input scripts allowing this output
// to be spent. The returns input scripts should target the input at location
// txIndex within the passed transaction. The input scripts generated by this
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
func (bi *BaseInput) CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) (*lnwallet.InputScript, error) {
witnessFunc := bi.witnessType.GenWitnessFunc(
signer, bi.SignDesc(),
@ -138,20 +143,27 @@ func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
}
}
// BuildWitness computes a valid witness that allows us to spend from the
// breached output. For HtlcSpendInput it will need to make the preimage part
// of the witness.
func (h *HtlcSucceedInput) BuildWitness(signer lnwallet.Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) ([][]byte, error) {
// CraftInputScript returns a valid set of input scripts allowing this output
// to be spent. The returns input scripts should target the input at location
// txIndex within the passed transaction. The input scripts generated by this
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
func (h *HtlcSucceedInput) CraftInputScript(signer lnwallet.Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) (*lnwallet.InputScript, error) {
desc := h.signDesc
desc.SigHashes = hashCache
desc.InputIndex = txinIdx
return lnwallet.SenderHtlcSpendRedeem(
signer, &desc, txn,
h.preimage,
witness, err := lnwallet.SenderHtlcSpendRedeem(
signer, &desc, txn, h.preimage,
)
if err != nil {
return nil, err
}
return &lnwallet.InputScript{
Witness: witness,
}, nil
}
// BlocksToMaturity returns the relative timelock, as a number of blocks, that

@ -85,10 +85,10 @@ type UtxoSweeperConfig struct {
// funds can be swept.
GenSweepScript func() ([]byte, error)
// Estimator is used when crafting sweep transactions to estimate the
// necessary fee relative to the expected size of the sweep
// FeeEstimator is used when crafting sweep transactions to estimate
// the necessary fee relative to the expected size of the sweep
// transaction.
Estimator lnwallet.FeeEstimator
FeeEstimator lnwallet.FeeEstimator
// PublishTransaction facilitates the process of broadcasting a signed
// transaction to the appropriate network.
@ -198,7 +198,7 @@ func (s *UtxoSweeper) Start() error {
// Retrieve relay fee for dust limit calculation. Assume that this will
// not change from here on.
s.relayFeePerKW = s.cfg.Estimator.RelayFeePerKW()
s.relayFeePerKW = s.cfg.FeeEstimator.RelayFeePerKW()
// Register for block epochs to retry sweeping every block.
bestHash, bestHeight, err := s.cfg.ChainIO.GetBestBlock()
@ -407,7 +407,7 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch,
// Retrieve fee estimate for input filtering and final
// tx fee calculation.
satPerKW, err := s.cfg.Estimator.EstimateFeePerKW(
satPerKW, err := s.cfg.FeeEstimator.EstimateFeePerKW(
s.cfg.SweepTxConfTarget,
)
if err != nil {
@ -465,7 +465,7 @@ func (s *UtxoSweeper) scheduleSweep(currentHeight int32) error {
// Retrieve fee estimate for input filtering and final tx fee
// calculation.
satPerKW, err := s.cfg.Estimator.EstimateFeePerKW(
satPerKW, err := s.cfg.FeeEstimator.EstimateFeePerKW(
s.cfg.SweepTxConfTarget,
)
if err != nil {
@ -750,10 +750,10 @@ func (s *UtxoSweeper) waitForSpend(outpoint wire.OutPoint,
// - Make handling re-orgs easier.
// - Thwart future possible fee sniping attempts.
// - Make us blend in with the bitcoind wallet.
func (s *UtxoSweeper) CreateSweepTx(inputs []Input, confTarget uint32,
func (s *UtxoSweeper) CreateSweepTx(inputs []Input, feePref FeePreference,
currentBlockHeight uint32) (*wire.MsgTx, error) {
feePerKw, err := s.cfg.Estimator.EstimateFeePerKW(confTarget)
feePerKw, err := DetermineFeePerKw(s.cfg.FeeEstimator, feePref)
if err != nil {
return nil, err
}

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwallet"
@ -135,7 +136,7 @@ func createSweeperTestContext(t *testing.T) *sweeperTestContext {
outputScriptCount++
return script, nil
},
Estimator: estimator,
FeeEstimator: estimator,
MaxInputsPerTx: testMaxInputsPerTx,
MaxSweepAttempts: testMaxSweepAttempts,
NextAttemptDeltaFunc: func(attempts int) int32 {
@ -376,7 +377,8 @@ func TestNegativeInput(t *testing.T) {
if !testTxIns(&sweepTx1, []*wire.OutPoint{
largeInput.OutPoint(), positiveInput.OutPoint(),
}) {
t.Fatal("Tx does not contain expected inputs")
t.Fatalf("Tx does not contain expected inputs: %v",
spew.Sdump(sweepTx1))
}
ctx.backend.mine()

@ -55,7 +55,7 @@ func generateInputPartitionings(sweepableInputs []Input,
// on the signature length, which is not known yet at this point.
yields := make(map[wire.OutPoint]int64)
for _, input := range sweepableInputs {
size, err := getInputWitnessSizeUpperBound(input)
size, _, err := getInputWitnessSizeUpperBound(input)
if err != nil {
return nil, fmt.Errorf(
"failed adding input weight: %v", err)
@ -125,10 +125,14 @@ func getPositiveYieldInputs(sweepableInputs []Input, maxInputs int,
for idx, input := range sweepableInputs {
// Can ignore error, because it has already been checked when
// calculating the yields.
size, _ := getInputWitnessSizeUpperBound(input)
size, isNestedP2SH, _ := getInputWitnessSizeUpperBound(input)
// Keep a running weight estimate of the input set.
weightEstimate.AddWitnessInput(size)
if isNestedP2SH {
weightEstimate.AddNestedP2WSHInput(size)
} else {
weightEstimate.AddWitnessInput(size)
}
newTotal := total + btcutil.Amount(input.SignDesc().Output.Value)
@ -216,25 +220,29 @@ func createSweepTx(inputs []Input, outputPkScript []byte,
hashCache := txscript.NewTxSigHashes(sweepTx)
// With all the inputs in place, use each output's unique witness
// With all the inputs in place, use each output's unique input script
// function to generate the final witness required for spending.
addWitness := func(idx int, tso Input) error {
witness, err := tso.BuildWitness(
addInputScript := func(idx int, tso Input) error {
inputScript, err := tso.CraftInputScript(
signer, sweepTx, hashCache, idx,
)
if err != nil {
return err
}
sweepTx.TxIn[idx].Witness = witness
sweepTx.TxIn[idx].Witness = inputScript.Witness
if len(inputScript.SigScript) != 0 {
sweepTx.TxIn[idx].SignatureScript = inputScript.SigScript
}
return nil
}
// Finally we'll attach a valid witness to each csv and cltv input
// Finally we'll attach a valid input script to each csv and cltv input
// within the sweeping transaction.
for i, input := range inputs {
if err := addWitness(i, input); err != nil {
if err := addInputScript(i, input); err != nil {
return nil, err
}
}
@ -243,45 +251,54 @@ func createSweepTx(inputs []Input, outputPkScript []byte,
}
// getInputWitnessSizeUpperBound returns the maximum length of the witness for
// the given input if it would be included in a tx.
func getInputWitnessSizeUpperBound(input Input) (int, error) {
// the given input if it would be included in a tx. We also return if the
// output itself is a nested p2sh output, if so then we need to take into
// account the extra sigScript data size.
func getInputWitnessSizeUpperBound(input Input) (int, bool, error) {
switch input.WitnessType() {
// Outputs on a remote commitment transaction that pay directly
// to us.
// Outputs on a remote commitment transaction that pay directly to us.
case lnwallet.WitnessKeyHash:
fallthrough
case lnwallet.CommitmentNoDelay:
return lnwallet.P2WKHWitnessSize, nil
return lnwallet.P2WKHWitnessSize, false, nil
// Outputs on a past commitment transaction that pay directly
// to us.
case lnwallet.CommitmentTimeLock:
return lnwallet.ToLocalTimeoutWitnessSize, nil
return lnwallet.ToLocalTimeoutWitnessSize, false, nil
// Outgoing second layer HTLC's that have confirmed within the
// chain, and the output they produced is now mature enough to
// sweep.
case lnwallet.HtlcOfferedTimeoutSecondLevel:
return lnwallet.ToLocalTimeoutWitnessSize, nil
return lnwallet.ToLocalTimeoutWitnessSize, false, nil
// Incoming second layer HTLC's that have confirmed within the
// chain, and the output they produced is now mature enough to
// sweep.
case lnwallet.HtlcAcceptedSuccessSecondLevel:
return lnwallet.ToLocalTimeoutWitnessSize, nil
return lnwallet.ToLocalTimeoutWitnessSize, false, nil
// An HTLC on the commitment transaction of the remote party,
// that has had its absolute timelock expire.
case lnwallet.HtlcOfferedRemoteTimeout:
return lnwallet.AcceptedHtlcTimeoutWitnessSize, nil
return lnwallet.AcceptedHtlcTimeoutWitnessSize, false, nil
// An HTLC on the commitment transaction of the remote party,
// that can be swept with the preimage.
case lnwallet.HtlcAcceptedRemoteSuccess:
return lnwallet.OfferedHtlcSuccessWitnessSize, nil
return lnwallet.OfferedHtlcSuccessWitnessSize, false, nil
// A nested P2SH input that has a p2wkh witness script. We'll mark this
// as nested P2SH so the caller can estimate the weight properly
// including the sigScript.
case lnwallet.NestedWitnessKeyHash:
return lnwallet.P2WKHWitnessSize, true, nil
}
return 0, fmt.Errorf("unexpected witness type: %v", input.WitnessType())
return 0, false, fmt.Errorf("unexpected witness type: %v",
input.WitnessType())
}
// getWeightEstimate returns a weight estimate for the given inputs.
@ -308,7 +325,10 @@ func getWeightEstimate(inputs []Input) ([]Input, int64, int, int) {
for i := range inputs {
input := inputs[i]
size, err := getInputWitnessSizeUpperBound(input)
// For fee estimation purposes, we'll now attempt to obtain an
// upper bound on the weight this input will add when fully
// populated.
size, isNestedP2SH, err := getInputWitnessSizeUpperBound(input)
if err != nil {
log.Warn(err)
@ -316,7 +336,14 @@ func getWeightEstimate(inputs []Input) ([]Input, int64, int, int) {
// given.
continue
}
weightEstimate.AddWitnessInput(size)
// If this is a nested P2SH input, then we'll need to factor in
// the additional data push within the sigScript.
if isNestedP2SH {
weightEstimate.AddNestedP2WSHInput(size)
} else {
weightEstimate.AddWitnessInput(size)
}
switch input.WitnessType() {
case lnwallet.CommitmentTimeLock,

288
sweep/walletsweep.go Normal file

@ -0,0 +1,288 @@
package sweep
import (
"fmt"
"math"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/lnwallet"
)
const (
// defaultNumBlocksEstimate is the number of blocks that we fall back
// to issuing an estimate for if a fee pre fence doesn't specify an
// explicit conf target or fee rate.
defaultNumBlocksEstimate = 6
)
// FeePreference allows callers to express their time value for inclusion of a
// transaction into a block via either a confirmation target, or a fee rate.
type FeePreference struct {
// ConfTarget if non-zero, signals a fee preference expressed in the
// number of desired blocks between first broadcast, and confirmation.
ConfTarget uint32
// FeeRate if non-zero, signals a fee pre fence expressed in the fee
// rate expressed in sat/kw for a particular transaction.
FeeRate lnwallet.SatPerKWeight
}
// DetermineFeePerKw will determine the fee in sat/kw that should be paid given
// an estimator, a confirmation target, and a manual value for sat/byte. A
// value is chosen based on the two free parameters as one, or both of them can
// be zero.
func DetermineFeePerKw(feeEstimator lnwallet.FeeEstimator,
feePref FeePreference) (lnwallet.SatPerKWeight, error) {
switch {
// If both values are set, then we'll return an error as we require a
// strict directive.
case feePref.FeeRate != 0 && feePref.ConfTarget != 0:
return 0, fmt.Errorf("only FeeRate or ConfTarget should " +
"be set for FeePreferences")
// If the target number of confirmations is set, then we'll use that to
// consult our fee estimator for an adequate fee.
case feePref.ConfTarget != 0:
feePerKw, err := feeEstimator.EstimateFeePerKW(
uint32(feePref.ConfTarget),
)
if err != nil {
return 0, fmt.Errorf("unable to query fee "+
"estimator: %v", err)
}
return feePerKw, nil
// If a manual sat/byte fee rate is set, then we'll use that directly.
// We'll need to convert it to sat/kw as this is what we use
// internally.
case feePref.FeeRate != 0:
feePerKW := feePref.FeeRate
if feePerKW < lnwallet.FeePerKwFloor {
log.Infof("Manual fee rate input of %d sat/kw is "+
"too low, using %d sat/kw instead", feePerKW,
lnwallet.FeePerKwFloor)
feePerKW = lnwallet.FeePerKwFloor
}
return feePerKW, nil
// Otherwise, we'll attempt a relaxed confirmation target for the
// transaction
default:
feePerKw, err := feeEstimator.EstimateFeePerKW(
defaultNumBlocksEstimate,
)
if err != nil {
return 0, fmt.Errorf("unable to query fee estimator: "+
"%v", err)
}
return feePerKw, nil
}
}
// UtxoSource is an interface that allows a caller to access a source of UTXOs
// to use when crafting sweep transactions.
type UtxoSource interface {
// ListUnspentWitness returns all UTXOs from the source that have
// between minConfs and maxConfs number of confirmations.
ListUnspentWitness(minConfs, maxConfs int32) ([]*lnwallet.Utxo, error)
// FetchInputInfo returns the matching output for an outpoint. If the
// outpoint doesn't belong to this UTXO source, then an error should be
// returned.
FetchInputInfo(*wire.OutPoint) (*wire.TxOut, error)
}
// CoinSelectionLocker is an interface that allows the caller to perform an
// operation, which is synchronized with all coin selection attempts. This can
// be used when an operation requires that all coin selection operations cease
// forward progress. Think of this as an exclusive lock on coin selection
// operations.
type CoinSelectionLocker interface {
// WithCoinSelectLock will execute the passed function closure in a
// synchronized manner preventing any coin selection operations from
// proceeding while the closure if executing. This can be seen as the
// ability to execute a function closure under an exclusive coin
// selection lock.
WithCoinSelectLock(func() error) error
}
// OutpointLocker allows a caller to lock/unlock an outpoint. When locked, the
// outpoints shouldn't be used for any sort of channel funding of coin
// selection. Locked outpoints are not expect to be persisted between restarts.
type OutpointLocker interface {
// LockOutpoint locks a target outpoint, rendering it unusable for coin
// selection.
LockOutpoint(o wire.OutPoint)
// UnlockOutpoint unlocks a target outpoint, allowing it to be used for
// coin selection once again.
UnlockOutpoint(o wire.OutPoint)
}
// WalletSweepPackage is a package that gives the caller the ability to sweep
// ALL funds from a wallet in a single transaction. We also package a function
// closure that allows one to abort the operation.
type WalletSweepPackage struct {
// SweepTx is a fully signed, and valid transaction that is broadcast,
// will sweep ALL confirmed coins in the wallet with a single
// transaction.
SweepTx *wire.MsgTx
// CancelSweepAttempt allows the caller to cancel the sweep attempt.
//
// NOTE: If the sweeping transaction isn't or cannot be broadcast, then
// this closure MUST be called, otherwise all selected utxos will be
// unable to be used.
CancelSweepAttempt func()
}
// CraftSweepAllTx attempts to craft a WalletSweepPackage which will allow the
// caller to sweep ALL outputs within the wallet to a single UTXO, as specified
// by the delivery address. The sweep transaction will be crafted with the
// target fee rate, and will use the utxoSource and outpointLocker as sources
// for wallet funds.
func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32,
deliveryAddr btcutil.Address, coinSelectLocker CoinSelectionLocker,
utxoSource UtxoSource, outpointLocker OutpointLocker,
feeEstimator lnwallet.FeeEstimator,
signer lnwallet.Signer) (*WalletSweepPackage, error) {
// TODO(roasbeef): turn off ATPL as well when available?
var allOutputs []*lnwallet.Utxo
// We'll make a function closure up front that allows us to unlock all
// selected outputs to ensure that they become available again in the
// case of an error after the outputs have been locked, but before we
// can actually craft a sweeping transaction.
unlockOutputs := func() {
for _, utxo := range allOutputs {
outpointLocker.UnlockOutpoint(utxo.OutPoint)
}
}
// Next, we'll use the coinSelectLocker to ensure that no coin
// selection takes place while we fetch and lock all outputs the wallet
// knows of. Otherwise, it may be possible for a new funding flow to
// lock an output while we fetch the set of unspent witnesses.
err := coinSelectLocker.WithCoinSelectLock(func() error {
// Now that we can be sure that no other coin selection
// operations are going on, we can grab a clean snapshot of the
// current UTXO state of the wallet.
utxos, err := utxoSource.ListUnspentWitness(
1, math.MaxInt32,
)
if err != nil {
return err
}
// We'll now lock each UTXO to ensure that other callers don't
// attempt to use these UTXOs in transactions while we're
// crafting out sweep all transaction.
for _, utxo := range utxos {
outpointLocker.LockOutpoint(utxo.OutPoint)
}
allOutputs = append(allOutputs, utxos...)
return nil
})
if err != nil {
// If we failed at all, we'll unlock any outputs selected just
// in case we had any lingering outputs.
unlockOutputs()
return nil, fmt.Errorf("unable to fetch+lock wallet "+
"utxos: %v", err)
}
// Now that we've locked all the potential outputs to sweep, we'll
// assemble an input for each of them, so we can hand it off to the
// sweeper to generate and sign a transaction for us.
var inputsToSweep []Input
for _, output := range allOutputs {
// We'll consult the utxoSource for information concerning this
// outpoint, we'll need to properly populate a signDescriptor
// for this output.
outputInfo, err := utxoSource.FetchInputInfo(&output.OutPoint)
if err != nil {
unlockOutputs()
return nil, err
}
// As we'll be signing for outputs under control of the wallet,
// we only need to populate the output value and output script.
// The rest of the items will be populated internally within
// the sweeper via the witness generation function.
signDesc := &lnwallet.SignDescriptor{
Output: outputInfo,
HashType: txscript.SigHashAll,
}
pkScript := outputInfo.PkScript
// Based on the output type, we'll map it to the proper witness
// type so we can generate the set of input scripts needed to
// sweep the output.
var witnessType lnwallet.WitnessType
switch {
// If this is a p2wkh output, then we'll assume it's a witness
// key hash witness type.
case txscript.IsPayToWitnessPubKeyHash(pkScript):
witnessType = lnwallet.WitnessKeyHash
// If this is a p2sh output, then as since it's under control
// of the wallet, we'll assume it's a nested p2sh output.
case txscript.IsPayToScriptHash(pkScript):
witnessType = lnwallet.NestedWitnessKeyHash
// All other output types we count as unknown and will fail to
// sweep.
default:
unlockOutputs()
return nil, fmt.Errorf("unable to sweep coins, "+
"unknown script: %x", pkScript[:])
}
// Now that we've constructed the items required, we'll make an
// input which can be passed to the sweeper for ultimate
// sweeping.
input := MakeBaseInput(&output.OutPoint, witnessType, signDesc, 0)
inputsToSweep = append(inputsToSweep, &input)
}
// Next, we'll convert the delivery addr to a pkScript that we can use
// to create the sweep transaction.
deliveryPkScript, err := txscript.PayToAddrScript(deliveryAddr)
if err != nil {
unlockOutputs()
return nil, err
}
// Finally, we'll ask the sweeper to craft a sweep transaction which
// respects our fee preference and targets all the UTXOs of the wallet.
sweepTx, err := createSweepTx(
inputsToSweep, deliveryPkScript, blockHeight, feeRate, signer,
)
if err != nil {
unlockOutputs()
return nil, err
}
return &WalletSweepPackage{
SweepTx: sweepTx,
CancelSweepAttempt: unlockOutputs,
}, nil
}

409
sweep/walletsweep_test.go Normal file

@ -0,0 +1,409 @@
package sweep
import (
"bytes"
"fmt"
"testing"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/lnwallet"
)
// TestDetermineFeePerKw tests that given a fee preference, the
// DetermineFeePerKw will properly map it to a concrete fee in sat/kw.
func TestDetermineFeePerKw(t *testing.T) {
t.Parallel()
defaultFee := lnwallet.SatPerKWeight(999)
relayFee := lnwallet.SatPerKWeight(300)
feeEstimator := newMockFeeEstimator(defaultFee, relayFee)
// We'll populate two items in the internal map which is used to query
// a fee based on a confirmation target: the default conf target, and
// an arbitrary conf target. We'll ensure below that both of these are
// properly
feeEstimator.blocksToFee[50] = 300
feeEstimator.blocksToFee[defaultNumBlocksEstimate] = 1000
testCases := []struct {
// feePref is the target fee preference for this case.
feePref FeePreference
// fee is the value the DetermineFeePerKw should return given
// the FeePreference above
fee lnwallet.SatPerKWeight
// fail determines if this test case should fail or not.
fail bool
}{
// A fee rate below the fee rate floor should output the floor.
{
feePref: FeePreference{
FeeRate: lnwallet.SatPerKWeight(99),
},
fee: lnwallet.FeePerKwFloor,
},
// A fee rate above the floor, should pass through and return
// the target fee rate.
{
feePref: FeePreference{
FeeRate: 900,
},
fee: 900,
},
// A specified confirmation target should cause the function to
// query the estimator which will return our value specified
// above.
{
feePref: FeePreference{
ConfTarget: 50,
},
fee: 300,
},
// If the caller doesn't specify any values at all, then we
// should query for the default conf target.
{
feePref: FeePreference{},
fee: 1000,
},
// Both conf target and fee rate are set, we should return with
// an error.
{
feePref: FeePreference{
ConfTarget: 50,
FeeRate: 90000,
},
fee: 300,
fail: true,
},
}
for i, testCase := range testCases {
targetFee, err := DetermineFeePerKw(
feeEstimator, testCase.feePref,
)
switch {
case testCase.fail && err != nil:
continue
case testCase.fail && err == nil:
t.Fatalf("expected failure for #%v", i)
case !testCase.fail && err != nil:
t.Fatalf("unable to estimate fee; %v", err)
}
if targetFee != testCase.fee {
t.Fatalf("#%v: wrong fee: expected %v got %v", i,
testCase.fee, targetFee)
}
}
}
type mockUtxoSource struct {
outpoints map[wire.OutPoint]*wire.TxOut
outputs []*lnwallet.Utxo
}
func newMockUtxoSource(utxos []*lnwallet.Utxo) *mockUtxoSource {
m := &mockUtxoSource{
outputs: utxos,
outpoints: make(map[wire.OutPoint]*wire.TxOut),
}
for _, utxo := range utxos {
m.outpoints[utxo.OutPoint] = &wire.TxOut{
Value: int64(utxo.Value),
PkScript: utxo.PkScript,
}
}
return m
}
func (m *mockUtxoSource) ListUnspentWitness(minConfs int32,
maxConfs int32) ([]*lnwallet.Utxo, error) {
return m.outputs, nil
}
func (m *mockUtxoSource) FetchInputInfo(op *wire.OutPoint) (*wire.TxOut, error) {
txOut, ok := m.outpoints[*op]
if !ok {
return nil, fmt.Errorf("no output found")
}
return txOut, nil
}
type mockCoinSelectionLocker struct {
fail bool
}
func (m *mockCoinSelectionLocker) WithCoinSelectLock(f func() error) error {
if err := f(); err != nil {
return err
}
if m.fail {
return fmt.Errorf("kek")
}
return nil
}
type mockOutpointLocker struct {
lockedOutpoints map[wire.OutPoint]struct{}
unlockedOutpoints map[wire.OutPoint]struct{}
}
func newMockOutpointLocker() *mockOutpointLocker {
return &mockOutpointLocker{
lockedOutpoints: make(map[wire.OutPoint]struct{}),
unlockedOutpoints: make(map[wire.OutPoint]struct{}),
}
}
func (m *mockOutpointLocker) LockOutpoint(o wire.OutPoint) {
m.lockedOutpoints[o] = struct{}{}
}
func (m *mockOutpointLocker) UnlockOutpoint(o wire.OutPoint) {
m.unlockedOutpoints[o] = struct{}{}
}
var sweepScript = []byte{
0x0, 0x14, 0x64, 0x3d, 0x8b, 0x15, 0x69, 0x4a, 0x54,
0x7d, 0x57, 0x33, 0x6e, 0x51, 0xdf, 0xfd, 0x38, 0xe3,
0xe, 0x6e, 0xf8, 0xef,
}
var deliveryAddr = func() btcutil.Address {
_, addrs, _, err := txscript.ExtractPkScriptAddrs(
sweepScript, &chaincfg.TestNet3Params,
)
if err != nil {
panic(err)
}
return addrs[0]
}()
var testUtxos = []*lnwallet.Utxo{
{
// A p2wkh output.
PkScript: []byte{
0x0, 0x14, 0x64, 0x3d, 0x8b, 0x15, 0x69, 0x4a, 0x54,
0x7d, 0x57, 0x33, 0x6e, 0x51, 0xdf, 0xfd, 0x38, 0xe3,
0xe, 0x6e, 0xf7, 0xef,
},
Value: 1000,
OutPoint: wire.OutPoint{
Index: 1,
},
},
{
// A np2wkh output.
PkScript: []byte{
0xa9, 0x14, 0x97, 0x17, 0xf7, 0xd1, 0x5f, 0x6f, 0x8b,
0x7, 0xe3, 0x58, 0x43, 0x19, 0xb9, 0x7e, 0xa9, 0x20,
0x18, 0xc3, 0x17, 0xd7, 0x87,
},
Value: 2000,
OutPoint: wire.OutPoint{
Index: 2,
},
},
// A p2wsh output.
{
PkScript: []byte{
0x0, 0x20, 0x70, 0x1a, 0x8d, 0x40, 0x1c, 0x84, 0xfb, 0x13,
0xe6, 0xba, 0xf1, 0x69, 0xd5, 0x96, 0x84, 0xe2, 0x7a, 0xbd,
0x9f, 0xa2, 0x16, 0xc8, 0xbc, 0x5b, 0x9f, 0xc6, 0x3d, 0x62,
0x2f, 0xf8, 0xc5, 0x8c,
},
Value: 3000,
OutPoint: wire.OutPoint{
Index: 3,
},
},
}
func assertUtxosLocked(t *testing.T, utxoLocker *mockOutpointLocker,
utxos []*lnwallet.Utxo) {
t.Helper()
for _, utxo := range utxos {
if _, ok := utxoLocker.lockedOutpoints[utxo.OutPoint]; !ok {
t.Fatalf("utxo %v was never locked", utxo.OutPoint)
}
}
}
func assertNoUtxosUnlocked(t *testing.T, utxoLocker *mockOutpointLocker,
utxos []*lnwallet.Utxo) {
t.Helper()
if len(utxoLocker.unlockedOutpoints) != 0 {
t.Fatalf("outputs have been locked, but shouldn't have been")
}
}
func assertUtxosUnlocked(t *testing.T, utxoLocker *mockOutpointLocker,
utxos []*lnwallet.Utxo) {
t.Helper()
for _, utxo := range utxos {
if _, ok := utxoLocker.unlockedOutpoints[utxo.OutPoint]; !ok {
t.Fatalf("utxo %v was never unlocked", utxo.OutPoint)
}
}
}
func assertUtxosLockedAndUnlocked(t *testing.T, utxoLocker *mockOutpointLocker,
utxos []*lnwallet.Utxo) {
t.Helper()
for _, utxo := range utxos {
if _, ok := utxoLocker.lockedOutpoints[utxo.OutPoint]; !ok {
t.Fatalf("utxo %v was never locked", utxo.OutPoint)
}
if _, ok := utxoLocker.unlockedOutpoints[utxo.OutPoint]; !ok {
t.Fatalf("utxo %v was never unlocked", utxo.OutPoint)
}
}
}
// TestCraftSweepAllTxCoinSelectFail tests that if coin selection fails, then
// we unlock any outputs we may have locked in the passed closure.
func TestCraftSweepAllTxCoinSelectFail(t *testing.T) {
t.Parallel()
utxoSource := newMockUtxoSource(testUtxos)
coinSelectLocker := &mockCoinSelectionLocker{
fail: true,
}
utxoLocker := newMockOutpointLocker()
_, err := CraftSweepAllTx(
0, 100, nil, coinSelectLocker, utxoSource, utxoLocker, nil, nil,
)
// Since we instructed the coin select locker to fail above, we should
// get an error.
if err == nil {
t.Fatalf("sweep tx should have failed: %v", err)
}
// At this point, we'll now verify that all outputs were initially
// locked, and then also unlocked due to the failure.
assertUtxosLockedAndUnlocked(t, utxoLocker, testUtxos)
}
// TestCraftSweepAllTxUnknownWitnessType tests that if one of the inputs we
// encounter is of an unknown witness type, then we fail and unlock any prior
// locked outputs.
func TestCraftSweepAllTxUnknownWitnessType(t *testing.T) {
t.Parallel()
utxoSource := newMockUtxoSource(testUtxos)
coinSelectLocker := &mockCoinSelectionLocker{}
utxoLocker := newMockOutpointLocker()
_, err := CraftSweepAllTx(
0, 100, nil, coinSelectLocker, utxoSource, utxoLocker, nil, nil,
)
// Since passed in a p2wsh output, which is unknown, we should fail to
// map the output to a witness type.
if err == nil {
t.Fatalf("sweep tx should have failed: %v", err)
}
// At this point, we'll now verify that all outputs were initially
// locked, and then also unlocked since we weren't able to find a
// witness type for the last output.
assertUtxosLockedAndUnlocked(t, utxoLocker, testUtxos)
}
// TestCraftSweepAllTx tests that we'll properly lock all available outputs
// within the wallet, and craft a single sweep transaction that pays to the
// target output.
func TestCraftSweepAllTx(t *testing.T) {
t.Parallel()
// First, we'll make a mock signer along with a fee estimator, We'll
// use zero fees to we can assert a precise output value.
signer := &mockSigner{}
feeEstimator := newMockFeeEstimator(0, 0)
// For our UTXO source, we'll pass in all the UTXOs that we know of,
// other than the final one which is of an unknown witness type.
targetUTXOs := testUtxos[:2]
utxoSource := newMockUtxoSource(targetUTXOs)
coinSelectLocker := &mockCoinSelectionLocker{}
utxoLocker := newMockOutpointLocker()
sweepPkg, err := CraftSweepAllTx(
0, 100, deliveryAddr, coinSelectLocker, utxoSource, utxoLocker,
feeEstimator, signer,
)
if err != nil {
t.Fatalf("unable to make sweep tx: %v", err)
}
// At this point, all of the UTXOs that we made above should be locked
// and none of them unlocked.
assertUtxosLocked(t, utxoLocker, testUtxos[:2])
assertNoUtxosUnlocked(t, utxoLocker, testUtxos[:2])
// Now that we have our sweep transaction, we should find that we have
// a UTXO for each input, and also that our final output value is the
// sum of all our inputs.
sweepTx := sweepPkg.SweepTx
if len(sweepTx.TxIn) != len(targetUTXOs) {
t.Fatalf("expected %v utxo, got %v", len(targetUTXOs),
len(sweepTx.TxIn))
}
// We should have a single output that pays to our sweep script
// generated above.
expectedSweepValue := int64(3000)
if len(sweepTx.TxOut) != 1 {
t.Fatalf("should have %v outputs, instead have %v", 1,
len(sweepTx.TxOut))
}
output := sweepTx.TxOut[0]
switch {
case output.Value != expectedSweepValue:
t.Fatalf("expected %v sweep value, instead got %v",
expectedSweepValue, output.Value)
case !bytes.Equal(sweepScript, output.PkScript):
t.Fatalf("expected %x sweep script, instead got %x", sweepScript,
output.PkScript)
}
// If we cancel the sweep attempt, then we should find that all the
// UTXOs within the sweep transaction are now unlocked.
sweepPkg.CancelSweepAttempt()
assertUtxosUnlocked(t, utxoLocker, testUtxos[:2])
}