Merge branch 'master' into master

This commit is contained in:
Johan T. Halseth 2018-02-21 13:54:26 +01:00 committed by GitHub
commit 31ec79e7ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 848 additions and 510 deletions

View File

@ -1,7 +1,7 @@
language: go
go:
- 1.8.5
- 1.9.2
- 1.9.4
- "1.10"
sudo: required
install:
- sudo add-apt-repository -y ppa:bitcoin/bitcoin -y

View File

@ -5,7 +5,6 @@ import (
"encoding/binary"
"errors"
"io"
"strings"
"sync"
"sync/atomic"
@ -580,7 +579,7 @@ secondLevelCheck:
if err != nil {
brarLog.Errorf("unable to broadcast "+
"justice tx: %v", err)
if strings.Contains(err.Error(), "already been spent") {
if err == lnwallet.ErrDoubleSpend {
brarLog.Infof("Attempting to transfer HTLC revocations " +
"to the second level")
finalTx = nil

View File

@ -1116,7 +1116,7 @@ func testReorgConf(miner *rpctest.Harness, notifier chainntnfs.ChainNotifier,
}
if nodeHeight1 != nodeHeight2 {
t.Fatalf("expected both miners to be on the same height",
t.Fatalf("expected both miners to be on the same height: %v vs %v",
nodeHeight1, nodeHeight2)
}
@ -1190,7 +1190,7 @@ func testReorgConf(miner *rpctest.Harness, notifier chainntnfs.ChainNotifier,
}
if nodeHeight1 != nodeHeight2 {
t.Fatalf("expected both miners to be on the same height",
t.Fatalf("expected both miners to be on the same height: %v vs %v",
nodeHeight1, nodeHeight2)
}

View File

@ -2,7 +2,6 @@ package main
import (
"fmt"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/channeldb"
@ -439,19 +438,7 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b
return spew.Sdump(closeTx)
}))
if err := c.cfg.broadcastTx(closeTx); err != nil {
// TODO(halseth): add relevant error types to the
// WalletController interface as this is quite fragile.
switch {
case strings.Contains(err.Error(), "already exists"):
fallthrough
case strings.Contains(err.Error(), "already have"):
peerLog.Debugf("channel close tx from "+
"ChannelPoint(%v) already exist, "+
"probably broadcast by peer: %v",
c.chanPoint, err)
default:
return nil, false, err
}
return nil, false, err
}
// Clear out the current channel state, marking the channel as

View File

@ -388,15 +388,9 @@ var openChannelCommand = cli.Command{
of the funding output is returned.
One can manually set the fee to be used for the funding transaction via either
the --conf_target or --sat_per_byte arguments. This is optional.
NOTE: peer_id and node_key are mutually exclusive, only one should be used, not both.`,
the --conf_target or --sat_per_byte arguments. This is optional.`,
ArgsUsage: "node-key local-amt push-amt",
Flags: []cli.Flag{
cli.IntFlag{
Name: "peer_id",
Usage: "the relative id of the peer to open a channel with",
},
cli.StringFlag{
Name: "node_key",
Usage: "the identity public key of the target node/peer " +
@ -463,11 +457,6 @@ func openChannel(ctx *cli.Context) error {
return nil
}
if ctx.IsSet("peer_id") && ctx.IsSet("node_key") {
return fmt.Errorf("both peer_id and lightning_id cannot be set " +
"at the same time, only one can be specified")
}
req := &lnrpc.OpenChannelRequest{
TargetConf: int32(ctx.Int64("conf_target")),
SatPerByte: ctx.Int64("sat_per_byte"),
@ -475,8 +464,6 @@ func openChannel(ctx *cli.Context) error {
}
switch {
case ctx.IsSet("peer_id"):
req.TargetPeerId = int32(ctx.Int("peer_id"))
case ctx.IsSet("node_key"):
nodePubHex, err := hex.DecodeString(ctx.String("node_key"))
if err != nil {

View File

@ -449,7 +449,6 @@ func (c *ChannelArbitrator) stateStep(bestHeight uint32, bestHash *chainhash.Has
// At this point, we'll now broadcast the commitment
// transaction itself.
if err := c.cfg.PublishTx(closeTx); err != nil {
// TODO(roasbeef): need to check for errors (duplicate)
log.Errorf("ChannelArbitrator(%v): unable to broadcast "+
"close tx: %v", c.cfg.ChanPoint, err)
return StateError, closeTx, err

View File

@ -582,7 +582,6 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
//
// TODO(roasbeef): after changing sighashes send to tx bundler
if err := h.PublishTx(h.htlcResolution.SignedSuccessTx); err != nil {
// TODO(roasbeef): detect double spends
return nil, err
}

View File

@ -123,7 +123,6 @@ alice$ lncli listpeers
"peers": [
{
"pub_key": "0343bc80b914aebf8e50eb0b8e445fc79b9e6e8e5e018fa8c5f85c7d429c117b38",
"peer_id": 1,
"address": "172.19.0.4:9735",
"bytes_sent": "357",
"bytes_recv": "357",
@ -141,7 +140,6 @@ bob$ lncli listpeers
"peers": [
{
"pub_key": "03d0cd35b761f789983f3cfe82c68170cd1c3266b39220c24f7dd72ef4be0883eb",
"peer_id": 1,
"address": "172.19.0.3:51932",
"bytes_sent": "357",
"bytes_recv": "357",

View File

@ -7,14 +7,16 @@
* **Go:** `lnd` is written in Go. To install, run one of the following commands:
**Note**: The minimum version of Go supported is Go 1.8.
**Note**: The minimum version of Go supported is Go 1.8. We recommend that
users use the latest version of Go, which at the time of writing is
[`1.10`](https://blog.golang.org/go1.10).
On Linux:
```
sudo apt-get install golang-1.8-go
sudo apt-get install golang-1.10-go
```
> Note that golang-1.8-go puts binaries in /usr/lib/go-1.8/bin. If you want them on your PATH, you need to make that change yourself.
> Note that golang-1.10-go puts binaries in /usr/lib/go-1.8/bin. If you want them on your PATH, you need to make that change yourself.
On Mac OS X
```

View File

@ -823,7 +823,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
// We'll also reject any requests to create channels until we're fully
// synced to the network as we won't be able to properly validate the
// confirmation of the funding transaction.
isSynced, err := f.cfg.Wallet.IsSynced()
isSynced, _, err := f.cfg.Wallet.IsSynced()
if err != nil {
fndgLog.Errorf("unable to query wallet: %v", err)
return

View File

@ -434,7 +434,6 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
// Create a funding request and start the workflow.
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPeerID: int32(1),
targetPubkey: bob.privKey.PubKey(),
chainHash: *activeNetParams.GenesisHash,
localFundingAmt: localFundingAmt,

6
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: 63c0706e71ebdd4664e6a452bf58035571a8799b24e517ea0d8aa2fb8dd94155
updated: 2018-02-08T15:26:31.423935935-08:00
hash: ccd5caad2b8fa46f76338964fe06f5d6a35b9ed36dd5df8da0748e3e3ab99e6a
updated: 2018-02-19T17:31:51.88595122-08:00
imports:
- name: github.com/aead/chacha20
version: d31a916ded42d1640b9d89a26f8abd53cc96790c
@ -90,7 +90,7 @@ imports:
subpackages:
- internal/socket
- name: github.com/roasbeef/btcd
version: 9978b939c33973be19b932fa7b936079bb7ba38d
version: e6807bc4dd5ddbb95b4ab163f6dd61e4ad79463a
subpackages:
- addrmgr
- blockchain

View File

@ -15,7 +15,7 @@ import:
- proto
- package: github.com/howeyc/gopass
- package: github.com/roasbeef/btcd
version: 9978b939c33973be19b932fa7b936079bb7ba38d
version: e6807bc4dd5ddbb95b4ab163f6dd61e4ad79463a
subpackages:
- blockchain
- btcec

2
lnd.go
View File

@ -490,7 +490,7 @@ func lndMain() error {
"start_height=%v", bestHeight)
for {
synced, err := activeChainControl.wallet.IsSynced()
synced, _, err := activeChainControl.wallet.IsSynced()
if err != nil {
return err
}

View File

@ -832,8 +832,6 @@ func (m *ConnectPeerRequest) GetPerm() bool {
}
type ConnectPeerResponse struct {
// / The id of the newly connected peer
PeerId int32 `protobuf:"varint,1,opt,name=peer_id" json:"peer_id,omitempty"`
}
func (m *ConnectPeerResponse) Reset() { *m = ConnectPeerResponse{} }
@ -841,13 +839,6 @@ func (m *ConnectPeerResponse) String() string { return proto.CompactT
func (*ConnectPeerResponse) ProtoMessage() {}
func (*ConnectPeerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
func (m *ConnectPeerResponse) GetPeerId() int32 {
if m != nil {
return m.PeerId
}
return 0
}
type DisconnectPeerRequest struct {
// / The pubkey of the node to disconnect from
PubKey string `protobuf:"bytes,1,opt,name=pub_key" json:"pub_key,omitempty"`
@ -1113,8 +1104,6 @@ func (m *ListChannelsResponse) GetChannels() []*ActiveChannel {
type Peer struct {
// / The identity pubkey of the peer
PubKey string `protobuf:"bytes,1,opt,name=pub_key" json:"pub_key,omitempty"`
// / The peer's id from the local point of view
PeerId int32 `protobuf:"varint,2,opt,name=peer_id" json:"peer_id,omitempty"`
// / Network address of the peer; eg `127.0.0.1:10011`
Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"`
// / Bytes of data transmitted to this peer
@ -1143,13 +1132,6 @@ func (m *Peer) GetPubKey() string {
return ""
}
func (m *Peer) GetPeerId() int32 {
if m != nil {
return m.PeerId
}
return 0
}
func (m *Peer) GetAddress() string {
if m != nil {
return m.Address
@ -1255,6 +1237,8 @@ type GetInfoResponse struct {
Chains []string `protobuf:"bytes,11,rep,name=chains" json:"chains,omitempty"`
// / The URIs of the current node.
Uris []string `protobuf:"bytes,12,rep,name=uris" json:"uris,omitempty"`
// / Timestamp of the block best known to the wallet
BestHeaderTimestamp int64 `protobuf:"varint,13,opt,name=best_header_timestamp" json:"best_header_timestamp,omitempty"`
}
func (m *GetInfoResponse) Reset() { *m = GetInfoResponse{} }
@ -1339,6 +1323,13 @@ func (m *GetInfoResponse) GetUris() []string {
return nil
}
func (m *GetInfoResponse) GetBestHeaderTimestamp() int64 {
if m != nil {
return m.BestHeaderTimestamp
}
return 0
}
type ConfirmationUpdate struct {
BlockSha []byte `protobuf:"bytes,1,opt,name=block_sha,json=blockSha,proto3" json:"block_sha,omitempty"`
BlockHeight int32 `protobuf:"varint,2,opt,name=block_height,json=blockHeight" json:"block_height,omitempty"`
@ -1635,8 +1626,6 @@ func (m *PendingUpdate) GetOutputIndex() uint32 {
}
type OpenChannelRequest struct {
// / The peer_id of the node to open a channel with
TargetPeerId int32 `protobuf:"varint,1,opt,name=target_peer_id" json:"target_peer_id,omitempty"`
// / The pubkey of the node to open a channel with
NodePubkey []byte `protobuf:"bytes,2,opt,name=node_pubkey,proto3" json:"node_pubkey,omitempty"`
// / The hex encoded pubkey of the node to open a channel with
@ -1660,13 +1649,6 @@ func (m *OpenChannelRequest) String() string { return proto.CompactTe
func (*OpenChannelRequest) ProtoMessage() {}
func (*OpenChannelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} }
func (m *OpenChannelRequest) GetTargetPeerId() int32 {
if m != nil {
return m.TargetPeerId
}
return 0
}
func (m *OpenChannelRequest) GetNodePubkey() []byte {
if m != nil {
return m.NodePubkey
@ -5740,314 +5722,314 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 4940 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3b, 0x4d, 0x73, 0x1c, 0x49,
0x56, 0xae, 0x56, 0xb7, 0xa4, 0x7e, 0xfd, 0x21, 0x29, 0x25, 0x4b, 0xed, 0x1e, 0xaf, 0xd7, 0x93,
0x4c, 0xcc, 0x08, 0x33, 0x58, 0xb6, 0x96, 0x1d, 0x66, 0xc7, 0xc0, 0x86, 0x6d, 0x79, 0xac, 0xd9,
0xd5, 0x78, 0xb4, 0x25, 0x7b, 0x07, 0x76, 0x02, 0x9a, 0x52, 0x77, 0xaa, 0x55, 0xeb, 0xea, 0xaa,
0x9e, 0xaa, 0x6c, 0xc9, 0xbd, 0xc6, 0x11, 0x7c, 0x05, 0x11, 0x44, 0x40, 0x70, 0x80, 0x08, 0x62,
0x89, 0x58, 0x0e, 0x70, 0x81, 0x03, 0xbf, 0x60, 0x23, 0xf8, 0x01, 0x1b, 0x41, 0x70, 0xd8, 0x13,
0x01, 0x17, 0x02, 0x4e, 0x70, 0x24, 0xb8, 0x70, 0x22, 0x5e, 0x7e, 0x55, 0x66, 0x55, 0xc9, 0xf6,
0xb0, 0xc0, 0xad, 0xf3, 0xe5, 0xab, 0x97, 0x99, 0x2f, 0x5f, 0xbe, 0xef, 0x86, 0x66, 0x3a, 0x1d,
0xde, 0x9c, 0xa6, 0x09, 0x4f, 0x48, 0x23, 0x8a, 0xd3, 0xe9, 0xb0, 0x7f, 0x75, 0x9c, 0x24, 0xe3,
0x88, 0xed, 0x04, 0xd3, 0x70, 0x27, 0x88, 0xe3, 0x84, 0x07, 0x3c, 0x4c, 0xe2, 0x4c, 0x22, 0xd1,
0xdb, 0xb0, 0x7e, 0x3f, 0x65, 0x01, 0x67, 0x9f, 0x06, 0x51, 0xc4, 0xb8, 0xcf, 0x3e, 0x9f, 0xb1,
0x8c, 0x93, 0x3e, 0x2c, 0x4f, 0x83, 0x2c, 0x3b, 0x4f, 0xd2, 0x51, 0xcf, 0xbb, 0xee, 0x6d, 0xb7,
0x7d, 0x33, 0xa6, 0x9b, 0xb0, 0xe1, 0x7e, 0x92, 0x4d, 0x93, 0x38, 0x63, 0x48, 0xea, 0x49, 0x1c,
0x25, 0xc3, 0xa7, 0x5f, 0x88, 0x94, 0xfb, 0x89, 0x22, 0xf5, 0xfd, 0x1a, 0xb4, 0x1e, 0xa7, 0x41,
0x9c, 0x05, 0x43, 0xdc, 0x2c, 0xe9, 0xc1, 0x12, 0x7f, 0x36, 0x38, 0x0d, 0xb2, 0x53, 0x41, 0xa2,
0xe9, 0xeb, 0x21, 0xd9, 0x84, 0xc5, 0x60, 0x92, 0xcc, 0x62, 0xde, 0xab, 0x5d, 0xf7, 0xb6, 0x17,
0x7c, 0x35, 0x22, 0xef, 0xc2, 0x5a, 0x3c, 0x9b, 0x0c, 0x86, 0x49, 0x7c, 0x12, 0xa6, 0x13, 0x79,
0xe4, 0xde, 0xc2, 0x75, 0x6f, 0xbb, 0xe1, 0x97, 0x27, 0xc8, 0x35, 0x80, 0x63, 0xdc, 0x86, 0x5c,
0xa2, 0x2e, 0x96, 0xb0, 0x20, 0x84, 0x42, 0x5b, 0x8d, 0x58, 0x38, 0x3e, 0xe5, 0xbd, 0x86, 0x20,
0xe4, 0xc0, 0x90, 0x06, 0x0f, 0x27, 0x6c, 0x90, 0xf1, 0x60, 0x32, 0xed, 0x2d, 0x8a, 0xdd, 0x58,
0x10, 0x31, 0x9f, 0xf0, 0x20, 0x1a, 0x9c, 0x30, 0x96, 0xf5, 0x96, 0xd4, 0xbc, 0x81, 0x90, 0xb7,
0xa1, 0x3b, 0x62, 0x19, 0x1f, 0x04, 0xa3, 0x51, 0xca, 0xb2, 0x8c, 0x65, 0xbd, 0xe5, 0xeb, 0x0b,
0xdb, 0x4d, 0xbf, 0x00, 0xa5, 0x3d, 0xd8, 0x7c, 0xc8, 0xb8, 0xc5, 0x9d, 0x4c, 0x71, 0x9a, 0x1e,
0x00, 0xb1, 0xc0, 0x7b, 0x8c, 0x07, 0x61, 0x94, 0x91, 0xf7, 0xa0, 0xcd, 0x2d, 0xe4, 0x9e, 0x77,
0x7d, 0x61, 0xbb, 0xb5, 0x4b, 0x6e, 0x0a, 0xe9, 0xb8, 0x69, 0x7d, 0xe0, 0x3b, 0x78, 0xf4, 0xbf,
0x3c, 0x68, 0x1d, 0xb1, 0x78, 0xa4, 0xef, 0x91, 0x40, 0x1d, 0x77, 0xa2, 0xee, 0x50, 0xfc, 0x26,
0x5f, 0x86, 0x96, 0xd8, 0x5d, 0xc6, 0xd3, 0x30, 0x1e, 0x8b, 0x2b, 0x68, 0xfa, 0x80, 0xa0, 0x23,
0x01, 0x21, 0xab, 0xb0, 0x10, 0x4c, 0xb8, 0x60, 0xfc, 0x82, 0x8f, 0x3f, 0xc9, 0x9b, 0xd0, 0x9e,
0x06, 0xf3, 0x09, 0x8b, 0x79, 0xce, 0xec, 0xb6, 0xdf, 0x52, 0xb0, 0x7d, 0xe4, 0xf6, 0x4d, 0x58,
0xb7, 0x51, 0x34, 0xf5, 0x86, 0xa0, 0xbe, 0x66, 0x61, 0xaa, 0x45, 0xde, 0x81, 0x15, 0x8d, 0x9f,
0xca, 0xcd, 0x0a, 0xf6, 0x37, 0xfd, 0xae, 0x02, 0xeb, 0x23, 0x6c, 0xc3, 0xea, 0x49, 0x18, 0x07,
0xd1, 0x60, 0x18, 0xf1, 0xb3, 0xc1, 0x88, 0x45, 0x3c, 0x10, 0x17, 0xd1, 0xf0, 0xbb, 0x02, 0x7e,
0x3f, 0xe2, 0x67, 0x7b, 0x08, 0xa5, 0x7f, 0xe2, 0x41, 0x5b, 0x1e, 0x5e, 0x4a, 0x24, 0x79, 0x0b,
0x3a, 0x7a, 0x0d, 0x96, 0xa6, 0x49, 0xaa, 0xe4, 0xd0, 0x05, 0x92, 0x1b, 0xb0, 0xaa, 0x01, 0xd3,
0x94, 0x85, 0x93, 0x60, 0xcc, 0x04, 0x53, 0xda, 0x7e, 0x09, 0x4e, 0x76, 0x73, 0x8a, 0x69, 0x32,
0xe3, 0x4c, 0x30, 0xa9, 0xb5, 0xdb, 0x56, 0x17, 0xe3, 0x23, 0xcc, 0x77, 0x51, 0xe8, 0x5f, 0x78,
0xd0, 0xbe, 0x7f, 0x1a, 0xc4, 0x31, 0x8b, 0x0e, 0x93, 0x30, 0xe6, 0xe4, 0x16, 0x90, 0x93, 0x59,
0x3c, 0x0a, 0xe3, 0xf1, 0x80, 0x3f, 0x0b, 0x47, 0x83, 0xe3, 0x39, 0x67, 0x99, 0xbc, 0xa2, 0xfd,
0x4b, 0x7e, 0xc5, 0x1c, 0x79, 0x17, 0x56, 0x1d, 0x68, 0xc6, 0x53, 0x79, 0x6f, 0xfb, 0x97, 0xfc,
0xd2, 0x0c, 0x0a, 0x7e, 0x32, 0xe3, 0xd3, 0x19, 0x1f, 0x84, 0xf1, 0x88, 0x3d, 0x13, 0x7b, 0xec,
0xf8, 0x0e, 0xec, 0x5e, 0x17, 0xda, 0xf6, 0x77, 0xf4, 0x97, 0x60, 0xf5, 0x00, 0x5f, 0x44, 0x1c,
0xc6, 0xe3, 0xbb, 0x52, 0x6c, 0xf1, 0x99, 0x4e, 0x67, 0xc7, 0x4f, 0xd9, 0x5c, 0xf1, 0x4d, 0x8d,
0x50, 0xa8, 0x4e, 0x93, 0x8c, 0x2b, 0xc9, 0x11, 0xbf, 0xe9, 0xbf, 0x78, 0xb0, 0x82, 0xbc, 0xff,
0x38, 0x88, 0xe7, 0xfa, 0xe6, 0x0e, 0xa0, 0x8d, 0xa4, 0x1e, 0x27, 0x77, 0xe5, 0x63, 0x97, 0x42,
0xbc, 0xad, 0x78, 0x55, 0xc0, 0xbe, 0x69, 0xa3, 0x3e, 0x88, 0x79, 0x3a, 0xf7, 0x9d, 0xaf, 0x51,
0x6c, 0x79, 0x90, 0x8e, 0x19, 0x17, 0x6a, 0x40, 0xa9, 0x05, 0x90, 0xa0, 0xfb, 0x49, 0x7c, 0x42,
0xae, 0x43, 0x3b, 0x0b, 0xf8, 0x60, 0xca, 0x52, 0xc1, 0x35, 0x21, 0x7a, 0x0b, 0x3e, 0x64, 0x01,
0x3f, 0x64, 0xe9, 0xbd, 0x39, 0x67, 0xfd, 0xaf, 0xc3, 0x5a, 0x69, 0x15, 0x94, 0xf6, 0xfc, 0x88,
0xf8, 0x93, 0x6c, 0x40, 0xe3, 0x2c, 0x88, 0x66, 0x4c, 0x69, 0x27, 0x39, 0xf8, 0xa0, 0xf6, 0xbe,
0x47, 0xdf, 0x86, 0xd5, 0x7c, 0xdb, 0x4a, 0xc8, 0x08, 0xd4, 0x91, 0x83, 0x8a, 0x80, 0xf8, 0x4d,
0x7f, 0xcb, 0x93, 0x88, 0xf7, 0x93, 0xd0, 0xbc, 0x74, 0x44, 0x44, 0x85, 0xa0, 0x11, 0xf1, 0xf7,
0x85, 0x9a, 0xf0, 0x27, 0x3f, 0x2c, 0x7d, 0x07, 0xd6, 0xac, 0x2d, 0xbc, 0x64, 0xb3, 0x7f, 0xee,
0xc1, 0xda, 0x23, 0x76, 0xae, 0x6e, 0x5d, 0xef, 0xf6, 0x7d, 0xa8, 0xf3, 0xf9, 0x94, 0x09, 0xcc,
0xee, 0xee, 0x5b, 0xea, 0xd2, 0x4a, 0x78, 0x37, 0xd5, 0xf0, 0xf1, 0x7c, 0xca, 0x7c, 0xf1, 0x05,
0xfd, 0x04, 0x5a, 0x16, 0x90, 0x6c, 0xc1, 0xfa, 0xa7, 0x1f, 0x3d, 0x7e, 0xf4, 0xe0, 0xe8, 0x68,
0x70, 0xf8, 0xe4, 0xde, 0x37, 0x1f, 0xfc, 0xca, 0x60, 0xff, 0xee, 0xd1, 0xfe, 0xea, 0x25, 0xb2,
0x09, 0xe4, 0xd1, 0x83, 0xa3, 0xc7, 0x0f, 0xf6, 0x1c, 0xb8, 0x47, 0x56, 0xa0, 0x65, 0x03, 0x6a,
0xb4, 0x0f, 0xbd, 0x47, 0xec, 0xfc, 0xd3, 0x90, 0xc7, 0x2c, 0xcb, 0xdc, 0xe5, 0xe9, 0x4d, 0x20,
0xf6, 0x9e, 0xd4, 0x31, 0x7b, 0xb0, 0xa4, 0x74, 0xaf, 0x36, 0x3d, 0x6a, 0x48, 0xdf, 0x06, 0x72,
0x14, 0x8e, 0xe3, 0x8f, 0x59, 0x96, 0x05, 0x63, 0xa6, 0x0f, 0xbb, 0x0a, 0x0b, 0x93, 0x6c, 0xac,
0xb4, 0x24, 0xfe, 0xa4, 0x5f, 0x81, 0x75, 0x07, 0x4f, 0x11, 0xbe, 0x0a, 0xcd, 0x2c, 0x1c, 0xc7,
0x01, 0x9f, 0xa5, 0x4c, 0x91, 0xce, 0x01, 0xf4, 0x43, 0xd8, 0xf8, 0x36, 0x4b, 0xc3, 0x93, 0xf9,
0xab, 0xc8, 0xbb, 0x74, 0x6a, 0x45, 0x3a, 0x0f, 0xe0, 0x72, 0x81, 0x8e, 0x5a, 0x5e, 0x4a, 0xa6,
0xba, 0xbf, 0x65, 0x5f, 0x0e, 0xac, 0x77, 0x5a, 0xb3, 0xdf, 0x29, 0x7d, 0x02, 0xe4, 0x7e, 0x12,
0xc7, 0x6c, 0xc8, 0x0f, 0x19, 0x4b, 0xf5, 0x66, 0x7e, 0xc6, 0x12, 0xc3, 0xd6, 0xee, 0x96, 0xba,
0xd8, 0xe2, 0xe3, 0x57, 0xf2, 0x49, 0xa0, 0x3e, 0x65, 0xe9, 0x44, 0x10, 0x5e, 0xf6, 0xc5, 0x6f,
0xba, 0x03, 0xeb, 0x0e, 0xd9, 0x9c, 0xe7, 0x53, 0xc6, 0xd2, 0x81, 0xda, 0x5d, 0xc3, 0xd7, 0x43,
0x7a, 0x1b, 0x2e, 0xef, 0x85, 0xd9, 0xb0, 0xbc, 0x15, 0xfc, 0x64, 0x76, 0x3c, 0xc8, 0x9f, 0x9f,
0x1e, 0xa2, 0xbd, 0x2c, 0x7e, 0xa2, 0xbc, 0x8c, 0xdf, 0xf3, 0xa0, 0xbe, 0xff, 0xf8, 0xe0, 0x3e,
0xba, 0x28, 0x61, 0x3c, 0x4c, 0x26, 0x68, 0x65, 0x24, 0x3b, 0xcc, 0xf8, 0xc2, 0x67, 0x75, 0x15,
0x9a, 0xc2, 0x38, 0xa1, 0x0b, 0x20, 0x1e, 0x55, 0xdb, 0xcf, 0x01, 0xe8, 0x7e, 0xb0, 0x67, 0xd3,
0x30, 0x15, 0xfe, 0x85, 0xf6, 0x1a, 0xea, 0x42, 0x79, 0x96, 0x27, 0xe8, 0xbf, 0xd5, 0xa1, 0x73,
0x77, 0xc8, 0xc3, 0x33, 0xa6, 0x94, 0xbb, 0x58, 0x55, 0x00, 0xd4, 0x7e, 0xd4, 0x08, 0xcd, 0x50,
0xca, 0x26, 0x09, 0x67, 0x03, 0xe7, 0x9a, 0x5c, 0x20, 0x62, 0x0d, 0x25, 0xa1, 0xc1, 0x14, 0xcd,
0x84, 0xd8, 0x5f, 0xd3, 0x77, 0x81, 0xc8, 0x32, 0x04, 0x20, 0x97, 0x71, 0x67, 0x75, 0x5f, 0x0f,
0x91, 0x1f, 0xc3, 0x60, 0x1a, 0x0c, 0x43, 0x3e, 0x57, 0xda, 0xc0, 0x8c, 0x91, 0x76, 0x94, 0x0c,
0x83, 0x68, 0x70, 0x1c, 0x44, 0x41, 0x3c, 0x64, 0xca, 0xd3, 0x71, 0x81, 0xe8, 0xcc, 0xa8, 0x2d,
0x69, 0x34, 0xe9, 0xf0, 0x14, 0xa0, 0xe8, 0x14, 0x0d, 0x93, 0xc9, 0x24, 0xe4, 0xe8, 0x03, 0xf5,
0x96, 0xa5, 0xe6, 0xc9, 0x21, 0xe2, 0x24, 0x72, 0x74, 0x2e, 0x79, 0xd8, 0x94, 0xab, 0x39, 0x40,
0xa4, 0x72, 0xc2, 0x98, 0xd0, 0x60, 0x4f, 0xcf, 0x7b, 0x20, 0xa9, 0xe4, 0x10, 0xbc, 0x8d, 0x59,
0x9c, 0x31, 0xce, 0x23, 0x36, 0x32, 0x1b, 0x6a, 0x09, 0xb4, 0xf2, 0x04, 0xb9, 0x05, 0xeb, 0xd2,
0x2d, 0xcb, 0x02, 0x9e, 0x64, 0xa7, 0x61, 0x36, 0xc8, 0x58, 0xcc, 0x7b, 0x6d, 0x81, 0x5f, 0x35,
0x45, 0xde, 0x87, 0xad, 0x02, 0x38, 0x65, 0x43, 0x16, 0x9e, 0xb1, 0x51, 0xaf, 0x23, 0xbe, 0xba,
0x68, 0x9a, 0x5c, 0x87, 0x16, 0x7a, 0xa3, 0xb3, 0xe9, 0x28, 0x40, 0xc3, 0xdd, 0x15, 0xf7, 0x60,
0x83, 0xc8, 0x6d, 0xe8, 0x4c, 0x99, 0xb4, 0xae, 0xa7, 0x3c, 0x1a, 0x66, 0xbd, 0x15, 0x61, 0xfa,
0x5a, 0xea, 0xb1, 0xa1, 0xfc, 0xfa, 0x2e, 0x06, 0x8a, 0xe6, 0x30, 0x13, 0xfe, 0x4d, 0x30, 0xef,
0xad, 0x0a, 0xa1, 0xcb, 0x01, 0xf4, 0x32, 0xac, 0x1f, 0x84, 0x19, 0x57, 0x92, 0x66, 0xb4, 0xdf,
0x3e, 0x6c, 0xb8, 0x60, 0xf5, 0x16, 0x6f, 0xc1, 0xb2, 0x12, 0x9b, 0xac, 0xd7, 0x12, 0x4b, 0x6f,
0xa8, 0xa5, 0x1d, 0x89, 0xf5, 0x0d, 0x16, 0xfd, 0xdd, 0x1a, 0xd4, 0xf1, 0x9d, 0x5d, 0xfc, 0x26,
0xed, 0x07, 0x5e, 0x73, 0x1e, 0xb8, 0xad, 0x6e, 0x17, 0x1c, 0x75, 0x2b, 0x7c, 0x74, 0xf4, 0x60,
0xe4, 0x6d, 0x48, 0x89, 0xb5, 0x20, 0xf9, 0x7c, 0xca, 0x86, 0x67, 0x42, 0x6c, 0xcd, 0x3c, 0x42,
0x50, 0xa8, 0xd1, 0xcc, 0x89, 0xaf, 0xa5, 0xcc, 0x9a, 0xb1, 0x9e, 0x13, 0x5f, 0x2e, 0xe5, 0x73,
0xe2, 0xbb, 0x1e, 0x2c, 0x85, 0xf1, 0x71, 0x32, 0x8b, 0x47, 0x42, 0x3e, 0x97, 0x7d, 0x3d, 0x44,
0x3e, 0x4f, 0x85, 0xd7, 0x13, 0x4e, 0x98, 0x12, 0xcc, 0x1c, 0x40, 0x09, 0xba, 0x41, 0x99, 0xd0,
0x38, 0x86, 0xc9, 0xef, 0xc1, 0x9a, 0x05, 0x53, 0x1c, 0x7e, 0x13, 0x1a, 0x78, 0x7a, 0xed, 0x99,
0xeb, 0x9b, 0x15, 0xaa, 0x4a, 0xce, 0xd0, 0x55, 0xe8, 0x3e, 0x64, 0xfc, 0xa3, 0xf8, 0x24, 0xd1,
0x94, 0x7e, 0x7f, 0x01, 0x56, 0x0c, 0x48, 0x11, 0xda, 0x86, 0x95, 0x70, 0xc4, 0x62, 0x1e, 0xf2,
0xf9, 0xc0, 0xf1, 0xb6, 0x8a, 0x60, 0x54, 0xfe, 0x41, 0x14, 0x06, 0x99, 0x52, 0x1f, 0x72, 0x40,
0x76, 0x61, 0x03, 0x25, 0x4f, 0x0b, 0x93, 0xb9, 0x76, 0xe9, 0xf4, 0x55, 0xce, 0xe1, 0x63, 0x41,
0xb8, 0x54, 0x4f, 0xf9, 0x27, 0x52, 0xd5, 0x55, 0x4d, 0x21, 0xd7, 0x24, 0x25, 0x3c, 0x72, 0x43,
0x4a, 0xa7, 0x01, 0x94, 0x22, 0xad, 0x45, 0xe9, 0x70, 0x16, 0x23, 0x2d, 0x2b, 0x5a, 0x5b, 0x2e,
0x45, 0x6b, 0xdb, 0xb0, 0x92, 0xcd, 0xe3, 0x21, 0x1b, 0x0d, 0x78, 0x82, 0xeb, 0x86, 0xb1, 0xb8,
0x9d, 0x65, 0xbf, 0x08, 0x16, 0x71, 0x25, 0xcb, 0x78, 0xcc, 0xb8, 0xd0, 0x1a, 0xcb, 0xbe, 0x1e,
0xa2, 0x02, 0x16, 0x28, 0x52, 0xe8, 0x9b, 0xbe, 0x1a, 0xa1, 0x15, 0x9b, 0xa5, 0x61, 0xd6, 0x6b,
0x0b, 0xa8, 0xf8, 0x4d, 0xbf, 0x27, 0x8c, 0xa3, 0x09, 0x27, 0x9f, 0x88, 0x97, 0x4b, 0xde, 0x80,
0xa6, 0xdc, 0x53, 0x76, 0x1a, 0xe8, 0xc0, 0x57, 0x00, 0x8e, 0x4e, 0x03, 0x8c, 0x82, 0x9c, 0x63,
0xca, 0x57, 0xd0, 0x12, 0xb0, 0x7d, 0x79, 0xca, 0xb7, 0xa0, 0xab, 0x03, 0xd5, 0x6c, 0x10, 0xb1,
0x13, 0xae, 0x9d, 0xef, 0x78, 0x36, 0xc1, 0xe5, 0xb2, 0x03, 0x76, 0xc2, 0xe9, 0x23, 0x58, 0x53,
0x2f, 0xf0, 0x93, 0x29, 0xd3, 0x4b, 0x7f, 0xad, 0xa8, 0xff, 0xa5, 0x81, 0x5e, 0x57, 0x92, 0x65,
0x47, 0x10, 0x05, 0xa3, 0x40, 0x7d, 0x20, 0x6a, 0xfa, 0x7e, 0x94, 0x64, 0x4c, 0x11, 0xa4, 0xd0,
0x1e, 0x46, 0x49, 0xa6, 0x5d, 0x7c, 0x75, 0x1c, 0x07, 0x86, 0xbc, 0xcc, 0x66, 0xc3, 0x21, 0xbe,
0x5c, 0x69, 0xe2, 0xf5, 0x90, 0xfe, 0x95, 0x07, 0xeb, 0x82, 0x9a, 0xd6, 0x15, 0xc6, 0x2f, 0x7c,
0xfd, 0x6d, 0xb6, 0x87, 0x76, 0xd8, 0xb3, 0x01, 0x8d, 0x93, 0x24, 0x1d, 0x32, 0xb5, 0x92, 0x1c,
0x7c, 0x71, 0x4f, 0xb7, 0x5e, 0xf2, 0x74, 0xff, 0xc1, 0x83, 0x35, 0xb1, 0xd5, 0x23, 0x1e, 0xf0,
0x59, 0xa6, 0x8e, 0xff, 0x0b, 0xd0, 0xc1, 0xa3, 0x32, 0x2d, 0xfe, 0x6a, 0xa3, 0x1b, 0xe6, 0xa5,
0x0a, 0xa8, 0x44, 0xde, 0xbf, 0xe4, 0xbb, 0xc8, 0xe4, 0xeb, 0xd0, 0xb6, 0xb3, 0x0d, 0x62, 0xcf,
0xad, 0xdd, 0x2b, 0xfa, 0x94, 0x25, 0xc9, 0xd9, 0xbf, 0xe4, 0x3b, 0x1f, 0x90, 0x3b, 0x00, 0xc2,
0x32, 0x0b, 0xb2, 0x2a, 0x4c, 0xbc, 0xe2, 0x32, 0xc9, 0xba, 0xac, 0xfd, 0x4b, 0xbe, 0x85, 0x7e,
0x6f, 0x19, 0x16, 0xa5, 0x29, 0xa1, 0x0f, 0xa1, 0xe3, 0xec, 0xd4, 0xf1, 0xe0, 0xdb, 0xd2, 0x83,
0x2f, 0x05, 0x7c, 0xb5, 0x72, 0xc0, 0x47, 0xff, 0xb9, 0x06, 0x04, 0xa5, 0xad, 0x70, 0x9d, 0x6f,
0x43, 0x57, 0xb1, 0xdf, 0x75, 0xde, 0x0a, 0x50, 0x61, 0xf3, 0x92, 0x91, 0xe3, 0xc1, 0xb4, 0x7d,
0x1b, 0x44, 0x6e, 0x02, 0xb1, 0x86, 0x3a, 0xfe, 0x97, 0xf6, 0xa0, 0x62, 0x06, 0x15, 0x97, 0x74,
0x3f, 0x74, 0x1c, 0xaa, 0x3c, 0x36, 0x79, 0xbf, 0x95, 0x73, 0x22, 0x2d, 0x35, 0xcb, 0x4e, 0xd1,
0x26, 0x6b, 0x1f, 0x47, 0x8f, 0x8b, 0x82, 0xb4, 0xf8, 0x4a, 0x41, 0x5a, 0x2a, 0x0a, 0x92, 0xb0,
0x70, 0x69, 0x78, 0x16, 0x70, 0xa6, 0xad, 0x86, 0x1a, 0xa2, 0x4b, 0x33, 0x09, 0x63, 0x61, 0xaa,
0x07, 0x13, 0x5c, 0x5d, 0xb9, 0x34, 0x0e, 0x90, 0xfe, 0xd8, 0x83, 0x55, 0xe4, 0xb1, 0x23, 0x87,
0x1f, 0x80, 0x78, 0x06, 0xaf, 0x29, 0x86, 0x0e, 0xee, 0x4f, 0x2e, 0x85, 0xef, 0x43, 0x53, 0x10,
0x4c, 0xa6, 0x2c, 0x56, 0x42, 0xd8, 0x73, 0x85, 0x30, 0xd7, 0x40, 0xfb, 0x97, 0xfc, 0x1c, 0xd9,
0x12, 0xc1, 0xbf, 0xf7, 0xa0, 0xa5, 0xb6, 0xf9, 0x3f, 0x76, 0xbc, 0xfb, 0xb0, 0x8c, 0xd2, 0x68,
0xf9, 0xb5, 0x66, 0x8c, 0x9a, 0x7f, 0x82, 0x71, 0x0f, 0x9a, 0x3a, 0xc7, 0xe9, 0x2e, 0x82, 0xd1,
0x6e, 0x09, 0x65, 0x9b, 0x0d, 0x78, 0x18, 0x0d, 0xf4, 0xac, 0x4a, 0xec, 0x55, 0x4d, 0xa1, 0xce,
0xc9, 0x78, 0x30, 0x66, 0xca, 0x24, 0xc9, 0x01, 0x46, 0x17, 0xea, 0x40, 0x45, 0x87, 0xea, 0x47,
0x00, 0x5b, 0xa5, 0x29, 0xe3, 0x54, 0x29, 0x3f, 0x32, 0x0a, 0x27, 0xc7, 0x89, 0x71, 0x49, 0x3d,
0xdb, 0xc5, 0x74, 0xa6, 0xc8, 0x18, 0x2e, 0x6b, 0xdb, 0x8b, 0x3c, 0xcd, 0x2d, 0x6d, 0x4d, 0x38,
0x0d, 0xb7, 0x5d, 0x19, 0x28, 0x2e, 0xa8, 0xe1, 0xf6, 0xab, 0xad, 0xa6, 0x47, 0x4e, 0xa1, 0x67,
0x8c, 0xbc, 0x52, 0xef, 0x96, 0x23, 0x80, 0x6b, 0xbd, 0xfb, 0x8a, 0xb5, 0x84, 0x2e, 0x1a, 0xe9,
0x65, 0x2e, 0xa4, 0x46, 0xe6, 0x70, 0x4d, 0xcf, 0x09, 0xfd, 0x5d, 0x5e, 0xaf, 0xfe, 0x5a, 0x67,
0xfb, 0x10, 0x3f, 0x76, 0x17, 0x7d, 0x05, 0xe1, 0xfe, 0x8f, 0x3c, 0xe8, 0xba, 0xe4, 0x50, 0x74,
0x54, 0x6c, 0xa2, 0x15, 0x8c, 0x76, 0x9e, 0x0a, 0xe0, 0x72, 0x74, 0x55, 0xab, 0x8a, 0xae, 0xec,
0x18, 0x6a, 0xe1, 0x55, 0x31, 0x54, 0xfd, 0xf5, 0x62, 0xa8, 0x46, 0x55, 0x0c, 0xd5, 0xff, 0x4f,
0x0f, 0x48, 0xf9, 0x7e, 0xc9, 0x43, 0x19, 0xde, 0xc5, 0x2c, 0x52, 0x7a, 0xe2, 0x67, 0x5f, 0x4f,
0x46, 0x34, 0x0f, 0xf5, 0xd7, 0x28, 0xac, 0xb6, 0x22, 0xb0, 0x5d, 0x96, 0x8e, 0x5f, 0x35, 0x55,
0x88, 0xea, 0xea, 0xaf, 0x8e, 0xea, 0x1a, 0xaf, 0x8e, 0xea, 0x16, 0x8b, 0x51, 0x5d, 0xff, 0x37,
0xa0, 0xe3, 0xdc, 0xfa, 0xff, 0xde, 0x89, 0x8b, 0xee, 0x8e, 0xbc, 0x60, 0x07, 0xd6, 0xff, 0xf7,
0x1a, 0x90, 0xb2, 0xe4, 0xfd, 0xbf, 0xee, 0x41, 0xc8, 0x91, 0xa3, 0x40, 0x16, 0x94, 0x1c, 0x39,
0xaa, 0xe3, 0xff, 0x52, 0x29, 0xbe, 0x0b, 0x6b, 0x29, 0x1b, 0x26, 0x67, 0x2c, 0xb5, 0x22, 0x6b,
0x79, 0x55, 0xe5, 0x09, 0x74, 0xf8, 0xdc, 0x58, 0x76, 0xd9, 0xa9, 0x45, 0x58, 0x96, 0xa1, 0x10,
0xd2, 0xd2, 0xaf, 0xc1, 0x86, 0x2c, 0x11, 0xdd, 0x93, 0xa4, 0xb4, 0xcf, 0xf1, 0x26, 0xb4, 0xcf,
0x65, 0x32, 0x6f, 0x90, 0xc4, 0xd1, 0x5c, 0x19, 0x91, 0x96, 0x82, 0x7d, 0x12, 0x47, 0x73, 0xfa,
0x03, 0x0f, 0x2e, 0x17, 0xbe, 0xcd, 0x73, 0xfa, 0x52, 0xd5, 0xba, 0xfa, 0xd7, 0x05, 0xe2, 0x11,
0x95, 0x8c, 0x5b, 0x47, 0x94, 0x26, 0xa9, 0x3c, 0x81, 0x2c, 0x9c, 0xc5, 0x65, 0x7c, 0x79, 0x31,
0x55, 0x53, 0x74, 0x0b, 0x2e, 0xab, 0xcb, 0x77, 0xcf, 0x46, 0x77, 0x61, 0xb3, 0x38, 0x91, 0xe7,
0xc7, 0xdc, 0x2d, 0xeb, 0x21, 0xfd, 0x35, 0x20, 0xdf, 0x9a, 0xb1, 0x74, 0x2e, 0xaa, 0x07, 0x26,
0x01, 0xbb, 0x55, 0x0c, 0xc4, 0x17, 0xa7, 0xb3, 0xe3, 0x6f, 0xb2, 0xb9, 0x2e, 0xcf, 0xd4, 0xf2,
0xf2, 0xcc, 0x97, 0x00, 0x30, 0xea, 0x10, 0xe5, 0x06, 0x5d, 0x30, 0xc3, 0xf0, 0x4c, 0x12, 0xa4,
0x77, 0x60, 0xdd, 0xa1, 0x6f, 0x38, 0xb9, 0xa8, 0xbe, 0x90, 0x31, 0xac, 0x5b, 0xc4, 0x50, 0x73,
0xf4, 0x4f, 0x3d, 0x58, 0xd8, 0x4f, 0xa6, 0x76, 0xe2, 0xc9, 0x73, 0x13, 0x4f, 0x4a, 0xb5, 0x0e,
0x8c, 0xe6, 0xac, 0x29, 0xc5, 0x60, 0x03, 0x51, 0x31, 0x06, 0x13, 0x8e, 0x51, 0xdc, 0x49, 0x92,
0x9e, 0x07, 0xe9, 0x48, 0xb1, 0xb7, 0x00, 0xc5, 0xd3, 0xe5, 0xfa, 0x07, 0x7f, 0xa2, 0x4f, 0x21,
0xb2, 0x6f, 0x73, 0x15, 0x78, 0xaa, 0x11, 0xfd, 0x23, 0x0f, 0x1a, 0x62, 0xaf, 0xf8, 0x58, 0xe4,
0xf5, 0x8b, 0xca, 0x9d, 0x48, 0xee, 0x79, 0xf2, 0xb1, 0x14, 0xc0, 0x85, 0x7a, 0x5e, 0xad, 0x54,
0xcf, 0xbb, 0x0a, 0x4d, 0x39, 0xca, 0x0b, 0x60, 0x39, 0x80, 0x5c, 0x83, 0xfa, 0x69, 0x32, 0xd5,
0x26, 0x0e, 0x74, 0x36, 0x27, 0x99, 0xfa, 0x02, 0x4e, 0x6f, 0xc0, 0xca, 0xa3, 0x64, 0xc4, 0xac,
0x90, 0xff, 0xc2, 0x5b, 0xa4, 0xbf, 0xe9, 0xc1, 0xb2, 0x46, 0x26, 0xdb, 0x50, 0x47, 0x4b, 0x55,
0xf0, 0x0d, 0x4d, 0x4e, 0x16, 0xf1, 0x7c, 0x81, 0x81, 0x1a, 0x46, 0x04, 0x98, 0xb9, 0x27, 0xa1,
0xc3, 0xcb, 0xdc, 0x46, 0xa3, 0x4f, 0x2f, 0xf6, 0x5c, 0xb0, 0x65, 0x05, 0x28, 0xfd, 0x6b, 0x0f,
0x3a, 0xce, 0x1a, 0xe8, 0xe5, 0x47, 0x41, 0xc6, 0x55, 0x1e, 0x4b, 0x31, 0xd1, 0x06, 0xd9, 0xe9,
0xa1, 0x9a, 0x9b, 0x1e, 0x32, 0xe9, 0x89, 0x05, 0x3b, 0x3d, 0x71, 0x0b, 0x9a, 0x79, 0x6d, 0xb4,
0xee, 0x68, 0x0e, 0x5c, 0x51, 0x67, 0x9b, 0x73, 0x24, 0xa4, 0x33, 0x4c, 0xa2, 0x24, 0x55, 0xa5,
0x43, 0x39, 0xa0, 0x77, 0xa0, 0x65, 0xe1, 0xe3, 0x36, 0x62, 0xc6, 0xcf, 0x93, 0xf4, 0xa9, 0xce,
0x52, 0xa9, 0xa1, 0xa9, 0xb2, 0xd4, 0xf2, 0x2a, 0x0b, 0xfd, 0x1b, 0x0f, 0x3a, 0x28, 0x29, 0x61,
0x3c, 0x3e, 0x4c, 0xa2, 0x70, 0x38, 0x17, 0x12, 0xa3, 0x85, 0x42, 0xd5, 0x14, 0xb5, 0xc4, 0xb8,
0x60, 0x74, 0x09, 0xb4, 0x93, 0xaf, 0xe4, 0xc5, 0x8c, 0x51, 0xf2, 0xd1, 0xb4, 0x1d, 0x07, 0x19,
0x93, 0x51, 0x81, 0x52, 0xe5, 0x0e, 0x10, 0xb5, 0x0b, 0x02, 0xd2, 0x80, 0xb3, 0xc1, 0x24, 0x8c,
0xa2, 0x50, 0xe2, 0x4a, 0x09, 0xaf, 0x9a, 0xa2, 0x3f, 0xac, 0x41, 0x4b, 0x69, 0x91, 0x07, 0xa3,
0xb1, 0x4c, 0xb8, 0x2a, 0x3f, 0xc5, 0x3c, 0x3f, 0x0b, 0xa2, 0xe7, 0x1d, 0xcf, 0xc6, 0x82, 0x14,
0xaf, 0x75, 0xa1, 0x7c, 0xad, 0x57, 0xa1, 0x89, 0xe2, 0x75, 0x5b, 0xb8, 0x50, 0xb2, 0x94, 0x9e,
0x03, 0xf4, 0xec, 0xae, 0x98, 0x6d, 0xe4, 0xb3, 0x02, 0xe0, 0x38, 0x4d, 0x8b, 0x05, 0xa7, 0xe9,
0x7d, 0x68, 0x2b, 0x32, 0x82, 0xef, 0x22, 0xe6, 0xca, 0x05, 0xdc, 0xb9, 0x13, 0xdf, 0xc1, 0xd4,
0x5f, 0xee, 0xea, 0x2f, 0x97, 0x5f, 0xf5, 0xa5, 0xc6, 0xa4, 0x97, 0x61, 0x5d, 0x31, 0xef, 0x61,
0x1a, 0x4c, 0x4f, 0xb5, 0x66, 0x1e, 0x99, 0x2a, 0xac, 0x00, 0x93, 0x1b, 0xd0, 0xc0, 0xcf, 0xb4,
0xf6, 0xab, 0x7e, 0x74, 0x12, 0x85, 0x6c, 0x43, 0x83, 0x8d, 0xc6, 0x4c, 0x3b, 0xee, 0xc4, 0x0d,
0xa1, 0xf0, 0x8e, 0x7c, 0x89, 0x80, 0x2a, 0x00, 0xa1, 0x05, 0x15, 0xe0, 0x6a, 0xce, 0x45, 0x1c,
0x7e, 0x34, 0xa2, 0x1b, 0x40, 0x1e, 0x49, 0xa9, 0xb5, 0x93, 0x84, 0xbf, 0xb3, 0x00, 0x2d, 0x0b,
0x8c, 0xaf, 0x79, 0x8c, 0x1b, 0x1e, 0x8c, 0xc2, 0x60, 0xc2, 0x38, 0x4b, 0x95, 0xa4, 0x16, 0xa0,
0x42, 0xc1, 0x9e, 0x8d, 0x07, 0xc9, 0x8c, 0x0f, 0x46, 0x6c, 0x9c, 0x32, 0x69, 0xef, 0x3c, 0xbf,
0x00, 0x45, 0xbc, 0x49, 0xf0, 0xcc, 0xc6, 0x93, 0xf2, 0x50, 0x80, 0xea, 0x94, 0x9f, 0xe4, 0x51,
0x3d, 0x4f, 0xf9, 0x49, 0x8e, 0x14, 0xf5, 0x50, 0xa3, 0x42, 0x0f, 0xbd, 0x07, 0x9b, 0x52, 0xe3,
0xa8, 0xb7, 0x39, 0x28, 0x88, 0xc9, 0x05, 0xb3, 0xe4, 0x06, 0xac, 0xe2, 0x9e, 0xb5, 0x80, 0x67,
0xe1, 0xf7, 0x64, 0xb0, 0xee, 0xf9, 0x25, 0x38, 0xe2, 0xe2, 0x73, 0x74, 0x70, 0x65, 0x45, 0xa2,
0x04, 0x17, 0xb8, 0xc1, 0x33, 0x17, 0xb7, 0xa9, 0x70, 0x0b, 0x70, 0xda, 0x81, 0xd6, 0x11, 0x4f,
0xa6, 0xfa, 0x52, 0xba, 0xd0, 0x96, 0x43, 0x55, 0x85, 0x7a, 0x03, 0xae, 0x08, 0x29, 0x7a, 0x9c,
0x4c, 0x93, 0x28, 0x19, 0xcf, 0x8f, 0x66, 0xc7, 0xd9, 0x30, 0x0d, 0xa7, 0xe8, 0x50, 0xd3, 0xbf,
0xf3, 0x60, 0xdd, 0x99, 0x55, 0x99, 0x80, 0x9f, 0x93, 0x22, 0x6d, 0x0a, 0x07, 0x52, 0xf0, 0xd6,
0x2c, 0x75, 0x28, 0x11, 0x65, 0x5e, 0xe5, 0x89, 0xaa, 0x25, 0xdc, 0x85, 0x15, 0xbd, 0x33, 0xfd,
0xa1, 0x94, 0xc2, 0x5e, 0x59, 0x0a, 0xd5, 0xf7, 0x5d, 0xf5, 0x81, 0x26, 0xf1, 0x8b, 0xd2, 0x2d,
0x65, 0x23, 0x71, 0x46, 0x1d, 0x12, 0xf6, 0xf5, 0xf7, 0xb6, 0x2f, 0xac, 0x77, 0x30, 0x34, 0xc0,
0x8c, 0xfe, 0x81, 0x07, 0x90, 0xef, 0x0e, 0x05, 0x23, 0x57, 0xe9, 0x9e, 0x48, 0xa9, 0x5a, 0xea,
0xfb, 0x4d, 0x68, 0x9b, 0xc4, 0x75, 0x6e, 0x25, 0x5a, 0x1a, 0x86, 0x0e, 0xcc, 0x3b, 0xb0, 0x32,
0x8e, 0x92, 0x63, 0x61, 0x73, 0x45, 0xc1, 0x33, 0x53, 0xb5, 0xb8, 0xae, 0x04, 0x7f, 0xa8, 0xa0,
0xb9, 0x49, 0xa9, 0x5b, 0x26, 0x85, 0xfe, 0x61, 0xcd, 0xa4, 0x4f, 0xf3, 0x33, 0x5f, 0xf8, 0xca,
0xc8, 0x6e, 0x49, 0x39, 0x5e, 0x90, 0xad, 0x14, 0xc9, 0x8f, 0xc3, 0x57, 0xc6, 0x81, 0x77, 0xa0,
0x9b, 0x4a, 0xed, 0xa3, 0x55, 0x53, 0xfd, 0x25, 0xaa, 0xa9, 0x93, 0x3a, 0x76, 0xe7, 0xa7, 0x61,
0x35, 0x18, 0x9d, 0xb1, 0x94, 0x87, 0x22, 0x20, 0x10, 0x46, 0x5f, 0x2a, 0xd4, 0x15, 0x0b, 0x2e,
0x6c, 0xf1, 0x3b, 0xb0, 0xa2, 0xea, 0x9f, 0x06, 0x53, 0x35, 0xc8, 0xe4, 0x60, 0x44, 0xa4, 0x7f,
0xa9, 0x33, 0xb5, 0xee, 0x1d, 0x5e, 0xcc, 0x11, 0xfb, 0x74, 0xb5, 0xc2, 0xe9, 0x7e, 0x4a, 0x65,
0x4d, 0x47, 0x3a, 0xea, 0x50, 0xf9, 0x6b, 0x09, 0x54, 0x59, 0x6e, 0x97, 0xa5, 0xf5, 0xd7, 0x61,
0x29, 0xfd, 0xc1, 0x02, 0x2c, 0x7d, 0x14, 0x9f, 0x25, 0xe1, 0x50, 0xe4, 0x30, 0x27, 0x6c, 0x92,
0xe8, 0x2e, 0x04, 0xfc, 0x8d, 0x16, 0x5d, 0x14, 0xd8, 0xa6, 0x5c, 0x25, 0x17, 0xf5, 0x10, 0xad,
0x5b, 0x9a, 0x77, 0xe6, 0x48, 0x49, 0xb1, 0x20, 0xe8, 0x1f, 0xa6, 0x76, 0x5b, 0x92, 0x1a, 0xe5,
0x6d, 0x1c, 0x0d, 0xab, 0x8d, 0x43, 0x64, 0xbc, 0x65, 0xed, 0x50, 0xb0, 0x73, 0xd9, 0xd7, 0x43,
0xe1, 0xc7, 0xa6, 0x4c, 0xc6, 0xc4, 0xc2, 0x4e, 0x2e, 0x29, 0x3f, 0xd6, 0x06, 0xa2, 0x2d, 0x95,
0x1f, 0x48, 0x1c, 0xa9, 0x6b, 0x6c, 0x10, 0xfa, 0x16, 0xc5, 0xce, 0xa6, 0xa6, 0xbc, 0xe2, 0x02,
0x18, 0x15, 0xd2, 0x88, 0x19, 0xbd, 0x21, 0xcf, 0x00, 0xb2, 0xf3, 0xa8, 0x08, 0xb7, 0xbc, 0x60,
0x59, 0x03, 0x55, 0x23, 0xe1, 0x83, 0x04, 0x51, 0x74, 0x1c, 0x0c, 0x9f, 0x8a, 0x7e, 0x33, 0x51,
0xf2, 0x6c, 0xfa, 0x2e, 0x10, 0x77, 0x2d, 0xda, 0xa7, 0x14, 0x89, 0x8e, 0x2c, 0x59, 0x5a, 0x20,
0xfa, 0x6d, 0x20, 0x77, 0x47, 0x23, 0x75, 0x43, 0x26, 0x46, 0xc8, 0x79, 0xeb, 0x39, 0xbc, 0xad,
0x38, 0x63, 0xad, 0xf2, 0x8c, 0xf4, 0x01, 0xb4, 0x0e, 0xad, 0x36, 0x31, 0x71, 0x99, 0xba, 0x41,
0x4c, 0x09, 0x80, 0x05, 0xb1, 0x16, 0xac, 0xd9, 0x0b, 0xd2, 0x9f, 0x07, 0x72, 0x10, 0x66, 0xdc,
0xec, 0xcf, 0x44, 0x92, 0x26, 0x21, 0x66, 0x45, 0x92, 0x0a, 0x26, 0x22, 0xc9, 0xbb, 0xb2, 0x72,
0x5a, 0x3c, 0xd8, 0x0d, 0x58, 0x0e, 0x25, 0x48, 0xeb, 0xe1, 0xae, 0x12, 0x60, 0x8d, 0x69, 0xe6,
0xd1, 0xa1, 0x50, 0x40, 0x47, 0xcd, 0xff, 0xd0, 0x83, 0x25, 0x75, 0x34, 0x34, 0x87, 0x4e, 0x83,
0x9c, 0x3c, 0x98, 0x03, 0xab, 0x6e, 0x2b, 0x2a, 0x4b, 0xdd, 0x42, 0x95, 0xd4, 0x11, 0xa8, 0x4f,
0x03, 0x7e, 0x2a, 0x3c, 0xe8, 0xa6, 0x2f, 0x7e, 0xeb, 0x48, 0xa9, 0x91, 0x47, 0x4a, 0x55, 0x9d,
0x6c, 0x52, 0x67, 0x94, 0xe0, 0xba, 0xa2, 0xac, 0x0e, 0x60, 0x12, 0xa0, 0xf7, 0x64, 0x45, 0x39,
0x07, 0xe7, 0xfc, 0x52, 0x24, 0x8a, 0xfc, 0x52, 0xa8, 0xbe, 0x99, 0xa7, 0x7d, 0xe8, 0xed, 0xb1,
0x88, 0x71, 0x76, 0x37, 0x8a, 0x8a, 0xf4, 0xdf, 0x80, 0x2b, 0x15, 0x73, 0xca, 0xaa, 0x7e, 0x08,
0x6b, 0x7b, 0xec, 0x78, 0x36, 0x3e, 0x60, 0x67, 0x79, 0x85, 0x82, 0x40, 0x3d, 0x3b, 0x4d, 0xce,
0xd5, 0xdd, 0x8a, 0xdf, 0x18, 0xf0, 0x46, 0x88, 0x33, 0xc8, 0xa6, 0x6c, 0xa8, 0xfb, 0x67, 0x04,
0xe4, 0x68, 0xca, 0x86, 0xf4, 0x3d, 0x20, 0x36, 0x1d, 0x75, 0x04, 0x7c, 0xb9, 0xb3, 0xe3, 0x41,
0x36, 0xcf, 0x38, 0x9b, 0xe8, 0xc6, 0x20, 0x1b, 0x44, 0xdf, 0x81, 0xf6, 0x61, 0x30, 0xf7, 0xd9,
0xe7, 0xaa, 0x47, 0x11, 0x83, 0xb7, 0x60, 0x8e, 0xa2, 0x6c, 0x82, 0x37, 0x31, 0x4d, 0xff, 0xb6,
0x06, 0x8b, 0x12, 0x13, 0xa9, 0x8e, 0x58, 0xc6, 0xc3, 0x58, 0x66, 0xe8, 0x15, 0x55, 0x0b, 0x54,
0x92, 0x8d, 0x5a, 0x85, 0x6c, 0x28, 0x77, 0x4a, 0xf7, 0x1a, 0x28, 0x21, 0x70, 0x60, 0x22, 0x36,
0x0d, 0x27, 0x4c, 0xb6, 0xaa, 0xd6, 0x55, 0x6c, 0xaa, 0x01, 0x85, 0x28, 0x39, 0xd7, 0x0f, 0x72,
0x7f, 0x5a, 0x68, 0x95, 0x38, 0xd8, 0xa0, 0x4a, 0x2d, 0xb4, 0x24, 0xa5, 0xa6, 0xa4, 0x85, 0x4a,
0xda, 0x66, 0xf9, 0x35, 0xb4, 0x8d, 0xf4, 0xb1, 0x1c, 0x6d, 0x43, 0x60, 0xf5, 0x43, 0xc6, 0x7c,
0x36, 0x4d, 0x52, 0xdd, 0xe8, 0x49, 0xbf, 0xef, 0xc1, 0xaa, 0xb2, 0x1e, 0x66, 0x8e, 0xbc, 0xe9,
0x98, 0x1a, 0xaf, 0x2a, 0x69, 0xfb, 0x16, 0x74, 0x44, 0xb0, 0x85, 0x91, 0x94, 0x88, 0xac, 0x54,
0xfe, 0xc1, 0x01, 0xe2, 0x9e, 0x74, 0x1a, 0x72, 0x12, 0x46, 0x8a, 0xc1, 0x36, 0x08, 0xcd, 0xa2,
0x0e, 0xc6, 0x04, 0x7b, 0x3d, 0xdf, 0x8c, 0xe9, 0x21, 0xac, 0x59, 0xfb, 0x55, 0x02, 0x75, 0x07,
0x74, 0x81, 0x53, 0xa6, 0x13, 0xe4, 0xbb, 0xd8, 0x72, 0x0d, 0x61, 0xfe, 0x99, 0x83, 0x4c, 0xff,
0xd1, 0x83, 0x75, 0xe9, 0x14, 0x28, 0x97, 0xcb, 0xf4, 0x44, 0x2d, 0x4a, 0x2f, 0x48, 0x0a, 0xfc,
0xfe, 0x25, 0x5f, 0x8d, 0xc9, 0x57, 0x5f, 0xd3, 0x91, 0x31, 0xb5, 0xc4, 0x0b, 0xd8, 0xb3, 0x50,
0xc5, 0x9e, 0x97, 0x1c, 0xbe, 0x2a, 0x58, 0x6e, 0x54, 0x06, 0xcb, 0xf7, 0x96, 0xa0, 0x91, 0x0d,
0x93, 0x29, 0xa3, 0x9b, 0xb0, 0xe1, 0x1e, 0x4e, 0xb2, 0x6c, 0xf7, 0x9f, 0x3c, 0xe8, 0xca, 0xbc,
0x9e, 0x6c, 0x21, 0x67, 0x29, 0xc1, 0xb8, 0xcc, 0xea, 0x4c, 0x27, 0xc6, 0x2d, 0x2d, 0x77, 0xb8,
0xf7, 0xdf, 0xa8, 0x9c, 0xd3, 0x3e, 0xf9, 0x6f, 0xff, 0xf8, 0x5f, 0xff, 0xb8, 0x76, 0x99, 0xae,
0xee, 0x9c, 0xdd, 0xde, 0x11, 0xea, 0x93, 0x9d, 0x0b, 0x8c, 0x0f, 0xbc, 0x1b, 0xb8, 0x8a, 0xdd,
0xb4, 0x6e, 0x56, 0xa9, 0x68, 0x7e, 0x37, 0xab, 0x54, 0x76, 0xb9, 0x3b, 0xab, 0xcc, 0x04, 0x86,
0x59, 0x65, 0xf7, 0x3f, 0xfa, 0xd0, 0x34, 0x01, 0x24, 0xf9, 0x2e, 0x74, 0x9c, 0x1c, 0x26, 0xd1,
0x84, 0xab, 0xb2, 0xa2, 0xfd, 0xab, 0xd5, 0x93, 0x6a, 0xd9, 0x6b, 0x62, 0xd9, 0x1e, 0xd9, 0xc4,
0x65, 0x55, 0xe2, 0x70, 0x47, 0x24, 0x77, 0x65, 0x53, 0xc4, 0x53, 0xe8, 0xba, 0x79, 0x47, 0x72,
0xd5, 0x15, 0x8d, 0xc2, 0x6a, 0x5f, 0xba, 0x60, 0x56, 0x2d, 0x77, 0x55, 0x2c, 0xb7, 0x49, 0x36,
0xec, 0xe5, 0x4c, 0x60, 0xc7, 0x44, 0x1b, 0x8b, 0xdd, 0xcd, 0x4e, 0x34, 0xbd, 0xea, 0x2e, 0xf7,
0xfe, 0x95, 0x72, 0xe7, 0xba, 0x6a, 0x75, 0xa7, 0x3d, 0xb1, 0x14, 0x21, 0x82, 0xa1, 0x76, 0x33,
0x3b, 0xf9, 0x0c, 0x9a, 0xa6, 0x83, 0x95, 0x6c, 0x59, 0x6d, 0xc3, 0x76, 0x5b, 0x6d, 0xbf, 0x57,
0x9e, 0xa8, 0xba, 0x2a, 0x9b, 0x32, 0x0a, 0xc4, 0x01, 0x5c, 0x56, 0xd6, 0xfc, 0x98, 0x7d, 0x91,
0x93, 0x54, 0xf4, 0xe0, 0xdf, 0xf2, 0xc8, 0x1d, 0x58, 0xd6, 0x8d, 0xc1, 0x64, 0xb3, 0xba, 0xc1,
0xb9, 0xbf, 0x55, 0x82, 0x2b, 0x3d, 0x72, 0x17, 0x20, 0xef, 0x61, 0x25, 0xbd, 0x8b, 0x5a, 0x6d,
0x0d, 0x13, 0x2b, 0x1a, 0x5e, 0xc7, 0xa2, 0x85, 0xd7, 0x6d, 0x91, 0x25, 0x5f, 0xce, 0xf1, 0x2b,
0x9b, 0x67, 0x5f, 0x42, 0x90, 0x6e, 0x0a, 0xde, 0xad, 0x92, 0x2e, 0xf2, 0x2e, 0x66, 0xe7, 0xba,
0xa1, 0x6b, 0x0f, 0x5a, 0x56, 0x5f, 0x2c, 0xd1, 0x14, 0xca, 0x3d, 0xb5, 0xfd, 0x7e, 0xd5, 0x94,
0xda, 0xee, 0x37, 0xa0, 0xe3, 0x34, 0xb8, 0x9a, 0x97, 0x51, 0xd5, 0x3e, 0x6b, 0x5e, 0x46, 0x75,
0x4f, 0xec, 0x77, 0xa0, 0x65, 0xb5, 0xa3, 0x12, 0xab, 0x38, 0x5e, 0x68, 0x37, 0x35, 0x3b, 0xaa,
0xe8, 0x5e, 0xa5, 0x1b, 0xe2, 0xbc, 0x5d, 0xda, 0xc4, 0xf3, 0x8a, 0xae, 0x26, 0x14, 0x92, 0xef,
0x42, 0xd7, 0x6d, 0x43, 0x35, 0xaf, 0xaa, 0xb2, 0xa1, 0xd5, 0xbc, 0xaa, 0x0b, 0x7a, 0x57, 0x95,
0x40, 0xde, 0x58, 0x37, 0x8b, 0xec, 0x3c, 0x57, 0xe9, 0xd3, 0x17, 0xe4, 0x5b, 0xa8, 0x3a, 0x54,
0x9b, 0x19, 0xc9, 0xdb, 0x72, 0xdd, 0x66, 0x34, 0x23, 0xed, 0xa5, 0x8e, 0x34, 0xba, 0x26, 0x88,
0xb7, 0x48, 0x7e, 0x02, 0xf2, 0x31, 0x2c, 0xa9, 0x76, 0x33, 0x72, 0x39, 0x97, 0x6a, 0x2b, 0xd9,
0xd4, 0xdf, 0x2c, 0x82, 0x15, 0xb1, 0x75, 0x41, 0xac, 0x43, 0x5a, 0x48, 0x6c, 0xcc, 0x78, 0x88,
0x34, 0x62, 0x58, 0x29, 0x14, 0xc4, 0xcc, 0x63, 0xa9, 0x2e, 0xa7, 0xf7, 0xaf, 0xbd, 0xbc, 0x8e,
0xe6, 0xaa, 0x19, 0xad, 0x5e, 0x76, 0x74, 0xf7, 0xc3, 0xaf, 0x42, 0xdb, 0xee, 0x6e, 0x34, 0x3a,
0xbb, 0xa2, 0x13, 0xd2, 0xe8, 0xec, 0xaa, 0x76, 0x48, 0x7d, 0xb9, 0xa4, 0x6d, 0x2f, 0x43, 0xbe,
0x03, 0x2b, 0x56, 0xe9, 0xf5, 0x68, 0x1e, 0x0f, 0x8d, 0xf0, 0x94, 0x1b, 0x65, 0xfa, 0x55, 0x96,
0x96, 0x6e, 0x09, 0xc2, 0x6b, 0xd4, 0x21, 0x8c, 0x82, 0x73, 0x1f, 0x5a, 0x76, 0x59, 0xf7, 0x25,
0x74, 0xb7, 0xac, 0x29, 0xbb, 0x6f, 0xe4, 0x96, 0x47, 0xfe, 0xcc, 0x83, 0xb6, 0xdd, 0x82, 0x45,
0x9c, 0x8c, 0x4d, 0x81, 0x4e, 0xcf, 0x9e, 0xb3, 0x09, 0x51, 0x5f, 0x6c, 0xf2, 0xe0, 0xc6, 0x37,
0x1c, 0x26, 0x3f, 0x77, 0x9c, 0xa8, 0x9b, 0xc5, 0x3f, 0x91, 0xbc, 0x28, 0x22, 0xd8, 0xcd, 0x44,
0x2f, 0x6e, 0x79, 0xe4, 0x03, 0xf9, 0x47, 0x23, 0x1d, 0x00, 0x11, 0x4b, 0xb9, 0x15, 0x59, 0x66,
0xff, 0x27, 0x67, 0xdb, 0xbb, 0xe5, 0x91, 0x5f, 0x97, 0xff, 0x15, 0x51, 0xdf, 0x0a, 0xce, 0xbf,
0xee, 0xf7, 0xf4, 0x2d, 0x71, 0x9a, 0x6b, 0xf4, 0x8a, 0x73, 0x9a, 0xa2, 0x76, 0x3f, 0x04, 0xc8,
0xa3, 0x59, 0x52, 0x08, 0xed, 0x8c, 0xde, 0x2b, 0x07, 0xbc, 0xee, 0x8d, 0xea, 0x08, 0x10, 0x29,
0x7e, 0x26, 0x85, 0x51, 0xe1, 0x67, 0xe6, 0x4a, 0xcb, 0x51, 0x69, 0xbf, 0x5f, 0x35, 0x55, 0x25,
0x8a, 0x9a, 0x3e, 0x79, 0x02, 0x9d, 0x83, 0x24, 0x79, 0x3a, 0x9b, 0x9a, 0x0c, 0x89, 0x1b, 0x5c,
0x61, 0xe8, 0xdc, 0x2f, 0x9c, 0x82, 0x5e, 0x17, 0xa4, 0xfa, 0xa4, 0x67, 0x91, 0xda, 0x79, 0x9e,
0xc7, 0xd2, 0x2f, 0x48, 0x00, 0x6b, 0xc6, 0xc6, 0x99, 0x8d, 0xf7, 0x5d, 0x32, 0x76, 0x48, 0x5b,
0x5a, 0xc2, 0xf1, 0x3a, 0xf4, 0x6e, 0x77, 0x32, 0x4d, 0xf3, 0x96, 0x47, 0x0e, 0xa1, 0xbd, 0xc7,
0x86, 0xc9, 0x88, 0xa9, 0x70, 0x68, 0x3d, 0xdf, 0xb8, 0x89, 0xa3, 0xfa, 0x1d, 0x07, 0xe8, 0xbe,
0xfa, 0x69, 0x30, 0x4f, 0xd9, 0xe7, 0x3b, 0xcf, 0x55, 0xa0, 0xf5, 0x42, 0xbf, 0x7a, 0x1d, 0x1c,
0x3a, 0xaf, 0xbe, 0x10, 0x4d, 0x3a, 0xaf, 0xbe, 0x14, 0x4d, 0x3a, 0xac, 0xd6, 0xc1, 0x29, 0x89,
0x30, 0xc6, 0x2c, 0x04, 0xa0, 0xc6, 0x52, 0x5e, 0x14, 0xb6, 0xf6, 0xaf, 0x5f, 0x8c, 0xe0, 0xae,
0x76, 0xc3, 0x5d, 0xed, 0x08, 0x3a, 0x7b, 0x4c, 0x32, 0x4b, 0x56, 0x1d, 0xfa, 0xae, 0x1a, 0xb1,
0x2b, 0x14, 0x45, 0x15, 0x23, 0xe6, 0x5c, 0xb5, 0x2e, 0x52, 0xfe, 0xe4, 0x33, 0x68, 0x3d, 0x64,
0x5c, 0x97, 0x19, 0x8c, 0xbf, 0x51, 0xa8, 0x3b, 0xf4, 0x2b, 0xaa, 0x14, 0xae, 0xcc, 0x08, 0x6a,
0x3b, 0x6c, 0x34, 0x66, 0xf2, 0xb1, 0x0f, 0xc2, 0xd1, 0x0b, 0xf2, 0xcb, 0x82, 0xb8, 0xa9, 0x4c,
0x6e, 0x5a, 0xd9, 0x69, 0x9b, 0xf8, 0x4a, 0x01, 0x5e, 0x45, 0x39, 0x4e, 0x46, 0xcc, 0x32, 0x70,
0x31, 0xb4, 0xac, 0x32, 0xb4, 0x79, 0x40, 0xe5, 0xd2, 0xb7, 0x79, 0x40, 0x15, 0x55, 0x6b, 0xba,
0x2d, 0xd6, 0xa1, 0xe4, 0x7a, 0xbe, 0x8e, 0xac, 0x54, 0xe7, 0x2b, 0xed, 0x3c, 0x0f, 0x26, 0xfc,
0x05, 0xf9, 0x54, 0xf4, 0x5f, 0xdb, 0xa5, 0x94, 0xdc, 0xdf, 0x29, 0x56, 0x5d, 0x0c, 0xb3, 0xac,
0x29, 0xd7, 0x07, 0x92, 0x4b, 0x09, 0x3b, 0xf8, 0x55, 0x80, 0x23, 0x9e, 0x4c, 0xf7, 0x02, 0x36,
0x49, 0xe2, 0x5c, 0x73, 0xe5, 0xe5, 0x82, 0x5c, 0x73, 0x59, 0x35, 0x03, 0xf2, 0xa9, 0xe5, 0x71,
0x3a, 0x95, 0x28, 0x2d, 0x5c, 0x17, 0x56, 0x14, 0x0c, 0x43, 0x2a, 0xaa, 0x0a, 0xb7, 0x3c, 0xf4,
0x1f, 0xf3, 0x74, 0x87, 0xf1, 0x1f, 0x4b, 0x99, 0x14, 0xa3, 0xf6, 0x2a, 0x72, 0x23, 0x87, 0xd0,
0xcc, 0x63, 0x6e, 0x6d, 0x92, 0x8a, 0x11, 0xba, 0xb1, 0x31, 0xa5, 0x50, 0x98, 0xae, 0x0a, 0x56,
0x01, 0x59, 0x46, 0x56, 0x89, 0x4a, 0x7a, 0x08, 0xeb, 0x72, 0x83, 0xc6, 0x60, 0x8a, 0x04, 0xb8,
0x3e, 0x49, 0x45, 0xe8, 0x6b, 0x5e, 0x73, 0x55, 0xe4, 0x48, 0xaf, 0x88, 0x15, 0xd6, 0x69, 0x57,
0xeb, 0x7d, 0x99, 0x7c, 0xff, 0xc0, 0xbb, 0x71, 0xbc, 0x28, 0xfe, 0x15, 0xfd, 0x95, 0xff, 0x0e,
0x00, 0x00, 0xff, 0xff, 0xdf, 0xa6, 0x48, 0x8e, 0x47, 0x3d, 0x00, 0x00,
// 4934 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7b, 0xcd, 0x6f, 0x24, 0x49,
0x56, 0x78, 0x67, 0xb9, 0xfc, 0x51, 0xaf, 0x3e, 0x6c, 0x87, 0xdd, 0x76, 0x75, 0x4d, 0x6f, 0x6f,
0x4f, 0xfe, 0x46, 0x33, 0xfe, 0x35, 0x43, 0xbb, 0xc7, 0xbb, 0x3b, 0xcc, 0x4e, 0x03, 0xab, 0xfe,
0x9a, 0xf6, 0xec, 0x7a, 0x7a, 0xbc, 0xe9, 0xee, 0x1d, 0xd8, 0x11, 0x14, 0xe9, 0xaa, 0x70, 0x39,
0xb7, 0xb3, 0x32, 0x73, 0x32, 0xb3, 0xec, 0xae, 0x1d, 0x5a, 0xe2, 0x43, 0xe2, 0x04, 0xe2, 0x00,
0x12, 0x5a, 0xa4, 0xe5, 0x00, 0x17, 0x38, 0xf0, 0x07, 0xa0, 0x95, 0xe0, 0xbe, 0x12, 0xe2, 0xb0,
0x27, 0x04, 0x37, 0x38, 0x2d, 0x47, 0xc4, 0x85, 0x13, 0x7a, 0x2f, 0x3e, 0x32, 0x22, 0x33, 0xdd,
0xdd, 0xc3, 0x02, 0xb7, 0x8a, 0x17, 0x2f, 0x5f, 0x44, 0xbc, 0x78, 0xf1, 0xbe, 0x0b, 0x5a, 0x69,
0x32, 0xba, 0x99, 0xa4, 0x71, 0x1e, 0xb3, 0xc5, 0x30, 0x4a, 0x93, 0xd1, 0xe0, 0xea, 0x24, 0x8e,
0x27, 0x21, 0xdf, 0xf5, 0x93, 0x60, 0xd7, 0x8f, 0xa2, 0x38, 0xf7, 0xf3, 0x20, 0x8e, 0x32, 0x81,
0xe4, 0xbe, 0x03, 0x1b, 0xf7, 0x52, 0xee, 0xe7, 0xfc, 0x13, 0x3f, 0x0c, 0x79, 0xee, 0xf1, 0xcf,
0x66, 0x3c, 0xcb, 0xd9, 0x00, 0x56, 0x12, 0x3f, 0xcb, 0xce, 0xe3, 0x74, 0xdc, 0x77, 0xae, 0x3b,
0x3b, 0x1d, 0x4f, 0x8f, 0xdd, 0x2d, 0xd8, 0xb4, 0x3f, 0xc9, 0x92, 0x38, 0xca, 0x38, 0x92, 0x7a,
0x12, 0x85, 0xf1, 0xe8, 0xe9, 0x17, 0x22, 0x65, 0x7f, 0x22, 0x49, 0xfd, 0xa0, 0x01, 0xed, 0xc7,
0xa9, 0x1f, 0x65, 0xfe, 0x08, 0x37, 0xcb, 0xfa, 0xb0, 0x9c, 0x3f, 0x1b, 0x9e, 0xfa, 0xd9, 0x29,
0x91, 0x68, 0x79, 0x6a, 0xc8, 0xb6, 0x60, 0xc9, 0x9f, 0xc6, 0xb3, 0x28, 0xef, 0x37, 0xae, 0x3b,
0x3b, 0x0b, 0x9e, 0x1c, 0xb1, 0xb7, 0x61, 0x3d, 0x9a, 0x4d, 0x87, 0xa3, 0x38, 0x3a, 0x09, 0xd2,
0xa9, 0x38, 0x72, 0x7f, 0xe1, 0xba, 0xb3, 0xb3, 0xe8, 0x55, 0x27, 0xd8, 0x35, 0x80, 0x63, 0xdc,
0x86, 0x58, 0xa2, 0x49, 0x4b, 0x18, 0x10, 0xe6, 0x42, 0x47, 0x8e, 0x78, 0x30, 0x39, 0xcd, 0xfb,
0x8b, 0x44, 0xc8, 0x82, 0x21, 0x8d, 0x3c, 0x98, 0xf2, 0x61, 0x96, 0xfb, 0xd3, 0xa4, 0xbf, 0x44,
0xbb, 0x31, 0x20, 0x34, 0x1f, 0xe7, 0x7e, 0x38, 0x3c, 0xe1, 0x3c, 0xeb, 0x2f, 0xcb, 0x79, 0x0d,
0x61, 0x6f, 0x42, 0x6f, 0xcc, 0xb3, 0x7c, 0xe8, 0x8f, 0xc7, 0x29, 0xcf, 0x32, 0x9e, 0xf5, 0x57,
0xae, 0x2f, 0xec, 0xb4, 0xbc, 0x12, 0xd4, 0xed, 0xc3, 0xd6, 0x43, 0x9e, 0x1b, 0xdc, 0xc9, 0x24,
0xa7, 0xdd, 0x03, 0x60, 0x06, 0xf8, 0x3e, 0xcf, 0xfd, 0x20, 0xcc, 0xd8, 0xbb, 0xd0, 0xc9, 0x0d,
0xe4, 0xbe, 0x73, 0x7d, 0x61, 0xa7, 0xbd, 0xc7, 0x6e, 0x92, 0x74, 0xdc, 0x34, 0x3e, 0xf0, 0x2c,
0x3c, 0xf7, 0x3f, 0x1d, 0x68, 0x1f, 0xf1, 0x68, 0xac, 0xee, 0x91, 0x41, 0x13, 0x77, 0x22, 0xef,
0x90, 0x7e, 0xb3, 0x2f, 0x43, 0x9b, 0x76, 0x97, 0xe5, 0x69, 0x10, 0x4d, 0xe8, 0x0a, 0x5a, 0x1e,
0x20, 0xe8, 0x88, 0x20, 0x6c, 0x0d, 0x16, 0xfc, 0x69, 0x4e, 0x8c, 0x5f, 0xf0, 0xf0, 0x27, 0x7b,
0x1d, 0x3a, 0x89, 0x3f, 0x9f, 0xf2, 0x28, 0x2f, 0x98, 0xdd, 0xf1, 0xda, 0x12, 0xb6, 0x8f, 0xdc,
0xbe, 0x09, 0x1b, 0x26, 0x8a, 0xa2, 0xbe, 0x48, 0xd4, 0xd7, 0x0d, 0x4c, 0xb9, 0xc8, 0x5b, 0xb0,
0xaa, 0xf0, 0x53, 0xb1, 0x59, 0x62, 0x7f, 0xcb, 0xeb, 0x49, 0xb0, 0x3a, 0xc2, 0x0e, 0xac, 0x9d,
0x04, 0x91, 0x1f, 0x0e, 0x47, 0x61, 0x7e, 0x36, 0x1c, 0xf3, 0x30, 0xf7, 0xe9, 0x22, 0x16, 0xbd,
0x1e, 0xc1, 0xef, 0x85, 0xf9, 0xd9, 0x7d, 0x84, 0xba, 0x7f, 0xec, 0x40, 0x47, 0x1c, 0x5e, 0x48,
0x24, 0x7b, 0x03, 0xba, 0x6a, 0x0d, 0x9e, 0xa6, 0x71, 0x2a, 0xe5, 0xd0, 0x06, 0xb2, 0x1b, 0xb0,
0xa6, 0x00, 0x49, 0xca, 0x83, 0xa9, 0x3f, 0xe1, 0xc4, 0x94, 0x8e, 0x57, 0x81, 0xb3, 0xbd, 0x82,
0x62, 0x1a, 0xcf, 0x72, 0x4e, 0x4c, 0x6a, 0xef, 0x75, 0xe4, 0xc5, 0x78, 0x08, 0xf3, 0x6c, 0x14,
0xf7, 0xcf, 0x1d, 0xe8, 0xdc, 0x3b, 0xf5, 0xa3, 0x88, 0x87, 0x87, 0x71, 0x10, 0xe5, 0xec, 0x16,
0xb0, 0x93, 0x59, 0x34, 0x0e, 0xa2, 0xc9, 0x30, 0x7f, 0x16, 0x8c, 0x87, 0xc7, 0xf3, 0x9c, 0x67,
0xe2, 0x8a, 0xf6, 0x2f, 0x79, 0x35, 0x73, 0xec, 0x6d, 0x58, 0xb3, 0xa0, 0x59, 0x9e, 0x8a, 0x7b,
0xdb, 0xbf, 0xe4, 0x55, 0x66, 0x50, 0xf0, 0xe3, 0x59, 0x9e, 0xcc, 0xf2, 0x61, 0x10, 0x8d, 0xf9,
0x33, 0xda, 0x63, 0xd7, 0xb3, 0x60, 0x77, 0x7b, 0xd0, 0x31, 0xbf, 0x73, 0x7f, 0x19, 0xd6, 0x0e,
0xf0, 0x45, 0x44, 0x41, 0x34, 0xb9, 0x23, 0xc4, 0x16, 0x9f, 0x69, 0x32, 0x3b, 0x7e, 0xca, 0xe7,
0x92, 0x6f, 0x72, 0x84, 0x42, 0x75, 0x1a, 0x67, 0xb9, 0x94, 0x1c, 0xfa, 0xed, 0xfe, 0x8b, 0x03,
0xab, 0xc8, 0xfb, 0x8f, 0xfc, 0x68, 0xae, 0x6e, 0xee, 0x00, 0x3a, 0x48, 0xea, 0x71, 0x7c, 0x47,
0x3c, 0x76, 0x21, 0xc4, 0x3b, 0x92, 0x57, 0x25, 0xec, 0x9b, 0x26, 0xea, 0x83, 0x28, 0x4f, 0xe7,
0x9e, 0xf5, 0x35, 0x8a, 0x6d, 0xee, 0xa7, 0x13, 0x9e, 0x93, 0x1a, 0x90, 0x6a, 0x01, 0x04, 0xe8,
0x5e, 0x1c, 0x9d, 0xb0, 0xeb, 0xd0, 0xc9, 0xfc, 0x7c, 0x98, 0xf0, 0x94, 0xb8, 0x46, 0xa2, 0xb7,
0xe0, 0x41, 0xe6, 0xe7, 0x87, 0x3c, 0xbd, 0x3b, 0xcf, 0xf9, 0xe0, 0x1b, 0xb0, 0x5e, 0x59, 0x05,
0xa5, 0xbd, 0x38, 0x22, 0xfe, 0x64, 0x9b, 0xb0, 0x78, 0xe6, 0x87, 0x33, 0x2e, 0xb5, 0x93, 0x18,
0xbc, 0xdf, 0x78, 0xcf, 0x71, 0xdf, 0x84, 0xb5, 0x62, 0xdb, 0x52, 0xc8, 0x18, 0x34, 0x91, 0x83,
0x92, 0x00, 0xfd, 0x76, 0x7f, 0xdb, 0x11, 0x88, 0xf7, 0xe2, 0x40, 0xbf, 0x74, 0x44, 0x44, 0x85,
0xa0, 0x10, 0xf1, 0xf7, 0x85, 0x9a, 0xf0, 0x67, 0x3f, 0xac, 0xfb, 0x16, 0xac, 0x1b, 0x5b, 0x78,
0xc1, 0x66, 0xff, 0xcc, 0x81, 0xf5, 0x47, 0xfc, 0x5c, 0xde, 0xba, 0xda, 0xed, 0x7b, 0xd0, 0xcc,
0xe7, 0x09, 0x27, 0xcc, 0xde, 0xde, 0x1b, 0xf2, 0xd2, 0x2a, 0x78, 0x37, 0xe5, 0xf0, 0xf1, 0x3c,
0xe1, 0x1e, 0x7d, 0xe1, 0x7e, 0x0c, 0x6d, 0x03, 0xc8, 0xb6, 0x61, 0xe3, 0x93, 0x0f, 0x1f, 0x3f,
0x7a, 0x70, 0x74, 0x34, 0x3c, 0x7c, 0x72, 0xf7, 0x5b, 0x0f, 0x7e, 0x75, 0xb8, 0x7f, 0xe7, 0x68,
0x7f, 0xed, 0x12, 0xdb, 0x02, 0xf6, 0xe8, 0xc1, 0xd1, 0xe3, 0x07, 0xf7, 0x2d, 0xb8, 0xc3, 0x56,
0xa1, 0x6d, 0x02, 0x1a, 0xee, 0x00, 0xfa, 0x8f, 0xf8, 0xf9, 0x27, 0x41, 0x1e, 0xf1, 0x2c, 0xb3,
0x97, 0x77, 0x6f, 0x02, 0x33, 0xf7, 0x24, 0x8f, 0xd9, 0x87, 0x65, 0xa9, 0x7b, 0x95, 0xe9, 0x91,
0x43, 0xf7, 0x4d, 0x60, 0x47, 0xc1, 0x24, 0xfa, 0x88, 0x67, 0x99, 0x3f, 0xe1, 0xea, 0xb0, 0x6b,
0xb0, 0x30, 0xcd, 0x26, 0x52, 0x4b, 0xe2, 0x4f, 0xf7, 0x2b, 0xb0, 0x61, 0xe1, 0x49, 0xc2, 0x57,
0xa1, 0x95, 0x05, 0x93, 0xc8, 0xcf, 0x67, 0x29, 0x97, 0xa4, 0x0b, 0x80, 0xfb, 0x01, 0x6c, 0x7e,
0x87, 0xa7, 0xc1, 0xc9, 0xfc, 0x65, 0xe4, 0x6d, 0x3a, 0x8d, 0x32, 0x9d, 0x07, 0x70, 0xb9, 0x44,
0x47, 0x2e, 0x2f, 0x24, 0x53, 0xde, 0xdf, 0x8a, 0x27, 0x06, 0xc6, 0x3b, 0x6d, 0x98, 0xef, 0xd4,
0x7d, 0x02, 0xec, 0x5e, 0x1c, 0x45, 0x7c, 0x94, 0x1f, 0x72, 0x9e, 0xaa, 0xcd, 0xfc, 0x9c, 0x21,
0x86, 0xed, 0xbd, 0x6d, 0x79, 0xb1, 0xe5, 0xc7, 0x2f, 0xe5, 0x93, 0x41, 0x33, 0xe1, 0xe9, 0x94,
0x08, 0xaf, 0x78, 0xf4, 0xdb, 0xbd, 0x0c, 0x1b, 0x16, 0x59, 0xed, 0x49, 0x5c, 0xbe, 0x1f, 0x64,
0xa3, 0xea, 0x82, 0x7d, 0x58, 0x4e, 0x66, 0xc7, 0xc3, 0xe2, 0x91, 0xa9, 0x21, 0x5a, 0xc5, 0xf2,
0x27, 0x92, 0xd8, 0xef, 0x39, 0xd0, 0xdc, 0x7f, 0x7c, 0x70, 0x0f, 0x1d, 0x91, 0x20, 0x1a, 0xc5,
0x53, 0xb4, 0x25, 0xe2, 0xd0, 0x7a, 0x7c, 0xe1, 0xe3, 0xb9, 0x0a, 0x2d, 0x32, 0x41, 0x68, 0xe8,
0xe9, 0xe9, 0x74, 0xbc, 0x02, 0x80, 0x4e, 0x06, 0x7f, 0x96, 0x04, 0x29, 0x79, 0x11, 0xca, 0x37,
0x68, 0x92, 0x8a, 0xac, 0x4e, 0xb8, 0x3f, 0x6d, 0x42, 0xf7, 0xce, 0x28, 0x0f, 0xce, 0xb8, 0x54,
0xe1, 0xb4, 0x2a, 0x01, 0xe4, 0x7e, 0xe4, 0x08, 0x8d, 0x4d, 0xca, 0xa7, 0x71, 0xce, 0x87, 0xd6,
0x65, 0xd8, 0x40, 0xc4, 0x1a, 0x09, 0x42, 0xc3, 0x04, 0x8d, 0x01, 0xed, 0xaf, 0xe5, 0xd9, 0x40,
0x64, 0x19, 0x02, 0x86, 0xc1, 0x98, 0x76, 0xd6, 0xf4, 0xd4, 0x10, 0xf9, 0x31, 0xf2, 0x13, 0x7f,
0x14, 0xe4, 0x73, 0xf9, 0xe6, 0xf5, 0x18, 0x69, 0x87, 0xf1, 0xc8, 0x0f, 0x87, 0xc7, 0x7e, 0xe8,
0x47, 0x23, 0x2e, 0xfd, 0x19, 0x1b, 0x88, 0x2e, 0x8b, 0xdc, 0x92, 0x42, 0x13, 0x6e, 0x4d, 0x09,
0x8a, 0xae, 0xcf, 0x28, 0x9e, 0x4e, 0x83, 0x1c, 0x3d, 0x9d, 0xfe, 0x8a, 0xd0, 0x2f, 0x05, 0x84,
0x4e, 0x22, 0x46, 0xe7, 0x82, 0x87, 0x2d, 0xb1, 0x9a, 0x05, 0x44, 0x2a, 0x27, 0x9c, 0x93, 0x9e,
0x7a, 0x7a, 0xde, 0x07, 0x41, 0xa5, 0x80, 0xe0, 0x6d, 0xcc, 0xa2, 0x8c, 0xe7, 0x79, 0xc8, 0xc7,
0x7a, 0x43, 0x6d, 0x42, 0xab, 0x4e, 0xb0, 0x5b, 0xb0, 0x21, 0x9c, 0xaf, 0xcc, 0xcf, 0xe3, 0xec,
0x34, 0xc8, 0x86, 0x19, 0x8f, 0xf2, 0x7e, 0x87, 0xf0, 0xeb, 0xa6, 0xd8, 0x7b, 0xb0, 0x5d, 0x02,
0xa7, 0x7c, 0xc4, 0x83, 0x33, 0x3e, 0xee, 0x77, 0xe9, 0xab, 0x8b, 0xa6, 0xd9, 0x75, 0x68, 0xa3,
0xcf, 0x39, 0x4b, 0xc6, 0x3e, 0x9a, 0xe7, 0x1e, 0xdd, 0x83, 0x09, 0x62, 0xef, 0x40, 0x37, 0xe1,
0xc2, 0x86, 0x9e, 0xe6, 0xe1, 0x28, 0xeb, 0xaf, 0x92, 0x81, 0x6b, 0xcb, 0x27, 0x85, 0xf2, 0xeb,
0xd9, 0x18, 0x28, 0x9a, 0xa3, 0x8c, 0xbc, 0x18, 0x7f, 0xde, 0x5f, 0x23, 0xa1, 0x2b, 0x00, 0xf8,
0xb2, 0x0e, 0x82, 0x2c, 0x97, 0x92, 0xa6, 0x75, 0xdc, 0x3e, 0x6c, 0xda, 0x60, 0xa9, 0x0d, 0x6e,
0xc1, 0x8a, 0x14, 0x9b, 0xac, 0xdf, 0xa6, 0xa5, 0x37, 0xe5, 0xd2, 0x96, 0xc4, 0x7a, 0x1a, 0xcb,
0xfd, 0xa9, 0x03, 0x4d, 0x7c, 0x67, 0x17, 0xbf, 0x49, 0x53, 0x75, 0x2e, 0x58, 0xaa, 0x93, 0xfc,
0x6d, 0xf4, 0x46, 0x04, 0xcf, 0x85, 0x5c, 0x1a, 0x90, 0x62, 0x3e, 0xe5, 0xa3, 0x33, 0x12, 0x4e,
0x3d, 0x8f, 0x10, 0x14, 0x5d, 0x34, 0x59, 0xf4, 0xb5, 0x90, 0x4c, 0x3d, 0x56, 0x73, 0xf4, 0xe5,
0x72, 0x31, 0x47, 0xdf, 0xf5, 0x61, 0x39, 0x88, 0x8e, 0xe3, 0x59, 0x34, 0x26, 0x29, 0x5c, 0xf1,
0xd4, 0x10, 0xb9, 0x99, 0x90, 0x07, 0x13, 0x4c, 0xb9, 0x14, 0xbf, 0x02, 0xe0, 0x32, 0x74, 0x69,
0x32, 0xd2, 0x2b, 0x9a, 0x95, 0xef, 0xc2, 0xba, 0x01, 0x93, 0x7c, 0x7c, 0x1d, 0x16, 0x13, 0x04,
0x48, 0x07, 0x45, 0xdd, 0x1f, 0x29, 0x24, 0x31, 0xe3, 0xae, 0x41, 0xef, 0x21, 0xcf, 0x3f, 0x8c,
0x4e, 0x62, 0x45, 0xe9, 0xef, 0x16, 0x60, 0x55, 0x83, 0x24, 0xa1, 0x1d, 0x58, 0x0d, 0xc6, 0x3c,
0xca, 0x83, 0x7c, 0x3e, 0xb4, 0x3c, 0xa7, 0x32, 0x18, 0x15, 0xb9, 0x1f, 0x06, 0x7e, 0x26, 0x95,
0x84, 0x18, 0xb0, 0x3d, 0xd8, 0x44, 0xf9, 0x52, 0x22, 0xa3, 0x2f, 0x57, 0x38, 0x70, 0xb5, 0x73,
0xf8, 0x24, 0x10, 0x2e, 0x94, 0x50, 0xf1, 0x89, 0x50, 0x68, 0x75, 0x53, 0xc8, 0x35, 0x41, 0x09,
0x8f, 0xbc, 0x28, 0x64, 0x50, 0x03, 0x2a, 0x51, 0xd3, 0x92, 0x70, 0x1e, 0xcb, 0x51, 0x93, 0x11,
0x79, 0xad, 0x54, 0x22, 0xaf, 0x1d, 0x58, 0xcd, 0xe6, 0xd1, 0x88, 0x8f, 0x87, 0x79, 0x8c, 0xeb,
0x06, 0x11, 0xdd, 0xce, 0x8a, 0x57, 0x06, 0x53, 0x8c, 0xc8, 0xb3, 0x3c, 0xe2, 0x39, 0xe9, 0x86,
0x15, 0x4f, 0x0d, 0x51, 0xcd, 0x12, 0x8a, 0x10, 0xed, 0x96, 0x27, 0x47, 0x68, 0x91, 0x66, 0x69,
0x90, 0xf5, 0x3b, 0x04, 0xa5, 0xdf, 0xec, 0xab, 0x70, 0xf9, 0x18, 0x23, 0x9a, 0x53, 0xee, 0x8f,
0x79, 0x4a, 0xb7, 0x2f, 0x02, 0x3a, 0xf1, 0xc4, 0xeb, 0x27, 0xdd, 0xef, 0x93, 0x79, 0xd4, 0x01,
0xe5, 0x13, 0x7a, 0xd5, 0xec, 0x35, 0x68, 0x89, 0x93, 0x64, 0xa7, 0xbe, 0x0a, 0x7d, 0x09, 0x70,
0x74, 0xea, 0x63, 0x1c, 0x64, 0x31, 0xa7, 0x41, 0x7e, 0x59, 0x9b, 0x60, 0xfb, 0x82, 0x37, 0x6f,
0x40, 0x4f, 0x85, 0xaa, 0xd9, 0x30, 0xe4, 0x27, 0xb9, 0x72, 0xbf, 0xa3, 0xd9, 0x14, 0x97, 0xcb,
0x0e, 0xf8, 0x49, 0xee, 0x3e, 0x82, 0x75, 0xf9, 0x3a, 0x3f, 0x4e, 0xb8, 0x5a, 0xfa, 0xeb, 0x65,
0xdb, 0x20, 0x4c, 0xf4, 0x86, 0x94, 0x47, 0x33, 0x86, 0x28, 0x19, 0x0c, 0xd7, 0x03, 0x26, 0xa7,
0xef, 0x85, 0x71, 0xc6, 0x25, 0x41, 0x17, 0x3a, 0xa3, 0x30, 0xce, 0x94, 0x93, 0x2f, 0x8f, 0x63,
0xc1, 0xf0, 0x06, 0xb2, 0xd9, 0x68, 0x84, 0xef, 0x5d, 0x18, 0x79, 0x35, 0x74, 0xff, 0xd2, 0x81,
0x0d, 0xa2, 0xa6, 0xf4, 0x88, 0xf6, 0x0c, 0x5f, 0x7d, 0x9b, 0x9d, 0x91, 0x19, 0xf8, 0x6c, 0xc2,
0xe2, 0x49, 0x9c, 0x8e, 0xb8, 0x5c, 0x49, 0x0c, 0xbe, 0xb8, 0xaf, 0xdb, 0xac, 0xf8, 0xba, 0xff,
0xe8, 0xc0, 0x3a, 0x6d, 0xf5, 0x28, 0xf7, 0xf3, 0x59, 0x26, 0x8f, 0xff, 0x8b, 0xd0, 0xc5, 0xa3,
0x72, 0xf5, 0x68, 0xe4, 0x46, 0x37, 0xf5, 0xfb, 0x26, 0xa8, 0x40, 0xde, 0xbf, 0xe4, 0xd9, 0xc8,
0xec, 0x1b, 0xd0, 0x31, 0xf3, 0x0d, 0xb4, 0xe7, 0xf6, 0xde, 0x15, 0x75, 0xca, 0x8a, 0xe4, 0xec,
0x5f, 0xf2, 0xac, 0x0f, 0xd8, 0x6d, 0x00, 0xb2, 0xda, 0x44, 0x56, 0x06, 0x8a, 0x57, 0x6c, 0x26,
0x19, 0x97, 0xb5, 0x7f, 0xc9, 0x33, 0xd0, 0xef, 0xae, 0xc0, 0x92, 0x30, 0x33, 0xee, 0x43, 0xe8,
0x5a, 0x3b, 0xb5, 0x7c, 0xf8, 0x8e, 0xf0, 0xe1, 0x2b, 0x21, 0x5f, 0xa3, 0x1a, 0xf2, 0xb9, 0x7f,
0xd3, 0x00, 0x86, 0xd2, 0x56, 0xba, 0x4e, 0xb4, 0x73, 0xf1, 0xd8, 0xf2, 0x5a, 0x3a, 0x9e, 0x09,
0x62, 0x37, 0x81, 0x19, 0x43, 0x15, 0xd9, 0x0b, 0xeb, 0x50, 0x33, 0x83, 0x6a, 0x4c, 0xb8, 0x1c,
0x2a, 0xc2, 0x94, 0x5e, 0x9a, 0xb8, 0xb7, 0xda, 0x39, 0x4a, 0x38, 0xcd, 0xb2, 0x53, 0xb4, 0xc3,
0xca, 0xaf, 0x51, 0xe3, 0xb2, 0x80, 0x2c, 0xbd, 0x54, 0x40, 0x96, 0xcb, 0x02, 0x42, 0xf6, 0x2e,
0x0d, 0xce, 0xfc, 0x9c, 0x2b, 0x1b, 0x22, 0x87, 0xe8, 0xc6, 0x4c, 0x83, 0x88, 0xcc, 0xf3, 0x70,
0x8a, 0xab, 0x4b, 0x37, 0xc6, 0x02, 0xba, 0x3f, 0x71, 0x60, 0x0d, 0x79, 0x67, 0xc9, 0xd7, 0xfb,
0x40, 0xe2, 0xfd, 0x8a, 0xe2, 0x65, 0xe1, 0xfe, 0xec, 0xd2, 0xf5, 0x1e, 0xb4, 0x88, 0x60, 0x9c,
0xf0, 0x48, 0x0a, 0x57, 0xdf, 0x16, 0xae, 0x42, 0xb3, 0xec, 0x5f, 0xf2, 0x0a, 0x64, 0x43, 0xb4,
0xfe, 0xc1, 0x81, 0xb6, 0xdc, 0xe6, 0x7f, 0xdb, 0xd9, 0x1e, 0xc0, 0x0a, 0x4a, 0x99, 0xe1, 0xcb,
0xea, 0x31, 0xda, 0x81, 0x29, 0x46, 0x34, 0x68, 0xf8, 0x2c, 0x47, 0xbb, 0x0c, 0x46, 0x2b, 0x46,
0x4a, 0x34, 0x1b, 0xe6, 0x41, 0x38, 0x54, 0xb3, 0x32, 0x65, 0x57, 0x37, 0x85, 0xba, 0x24, 0xcb,
0xfd, 0x09, 0x97, 0x06, 0x4a, 0x0c, 0x30, 0xa2, 0x90, 0x07, 0x2a, 0x3b, 0x51, 0x3f, 0x06, 0xd8,
0xae, 0x4c, 0x69, 0x47, 0x4a, 0xfa, 0x8e, 0x61, 0x30, 0x3d, 0x8e, 0xb5, 0x1b, 0xea, 0x98, 0x6e,
0xa5, 0x35, 0xc5, 0x26, 0x70, 0x59, 0x59, 0x62, 0xe4, 0x69, 0x61, 0x77, 0x1b, 0xe4, 0x42, 0xbc,
0x63, 0xcb, 0x40, 0x79, 0x41, 0x05, 0x37, 0x5f, 0x63, 0x3d, 0x3d, 0x76, 0x0a, 0x7d, 0x6d, 0xf2,
0xa5, 0xda, 0x36, 0xdc, 0x02, 0x5c, 0xeb, 0xed, 0x97, 0xac, 0x45, 0x3a, 0x66, 0xac, 0x96, 0xb9,
0x90, 0x1a, 0x9b, 0xc3, 0x35, 0x35, 0x47, 0x7a, 0xb9, 0xba, 0x5e, 0xf3, 0x95, 0xce, 0xf6, 0x01,
0x7e, 0x6c, 0x2f, 0xfa, 0x12, 0xc2, 0x83, 0x1f, 0x3b, 0xd0, 0xb3, 0xc9, 0xa1, 0xe8, 0xc8, 0x78,
0x44, 0x29, 0x18, 0xe5, 0x4a, 0x95, 0xc0, 0xd5, 0x88, 0xaa, 0x51, 0x17, 0x51, 0x99, 0x71, 0xd3,
0xc2, 0xcb, 0xe2, 0xa6, 0xe6, 0xab, 0xc5, 0x4d, 0x8b, 0x75, 0x71, 0xd3, 0xe0, 0x3f, 0x1c, 0x60,
0xd5, 0xfb, 0x65, 0x0f, 0x45, 0x48, 0x17, 0xf1, 0x50, 0xea, 0x89, 0x9f, 0x7f, 0x35, 0x19, 0x51,
0x3c, 0x54, 0x5f, 0xa3, 0xb0, 0x9a, 0x8a, 0xc0, 0x74, 0x45, 0xba, 0x5e, 0xdd, 0x54, 0x29, 0x92,
0x6b, 0xbe, 0x3c, 0x92, 0x5b, 0x7c, 0x79, 0x24, 0xb7, 0x54, 0x8e, 0xe4, 0x06, 0xbf, 0x09, 0x5d,
0xeb, 0xd6, 0xff, 0xe7, 0x4e, 0x5c, 0x76, 0x63, 0xc4, 0x05, 0x5b, 0xb0, 0xc1, 0xbf, 0x35, 0x80,
0x55, 0x25, 0xef, 0xff, 0x74, 0x0f, 0x24, 0x47, 0x96, 0x02, 0x59, 0x90, 0x72, 0x64, 0xa9, 0x8e,
0xff, 0x4d, 0xa5, 0xf8, 0x36, 0xac, 0xa7, 0x7c, 0x14, 0x9f, 0xf1, 0xd4, 0x88, 0xa6, 0xc5, 0x55,
0x55, 0x27, 0xd0, 0x91, 0xb3, 0xe3, 0xd7, 0x15, 0xab, 0xca, 0x60, 0x58, 0x86, 0x52, 0x18, 0xeb,
0x7e, 0x1d, 0x36, 0x45, 0xf1, 0xe7, 0xae, 0x20, 0xa5, 0x7c, 0x89, 0xd7, 0xa1, 0x73, 0x2e, 0xd2,
0x74, 0xc3, 0x38, 0x0a, 0xe7, 0xd2, 0x88, 0xb4, 0x25, 0xec, 0xe3, 0x28, 0x9c, 0xbb, 0x3f, 0x74,
0xe0, 0x72, 0xe9, 0xdb, 0x22, 0x5b, 0x2f, 0x54, 0xad, 0xad, 0x7f, 0x6d, 0x20, 0x1e, 0x51, 0xca,
0xb8, 0x71, 0x44, 0x61, 0x92, 0xaa, 0x13, 0xc8, 0xc2, 0x59, 0x54, 0xc5, 0x17, 0x17, 0x53, 0x37,
0xe5, 0x6e, 0xc3, 0x65, 0x79, 0xf9, 0xf6, 0xd9, 0xdc, 0x3d, 0xd8, 0x2a, 0x4f, 0x14, 0xd9, 0x46,
0x7b, 0xcb, 0x6a, 0xe8, 0xfe, 0x3a, 0xb0, 0x6f, 0xcf, 0x78, 0x3a, 0xa7, 0xba, 0x80, 0x4e, 0xad,
0x6e, 0x97, 0x83, 0xef, 0xa5, 0x64, 0x76, 0xfc, 0x2d, 0x3e, 0x57, 0x85, 0x97, 0x46, 0x51, 0x78,
0xf9, 0x12, 0x00, 0x46, 0x13, 0x54, 0x48, 0x50, 0xa5, 0x30, 0x0c, 0xd6, 0x04, 0x41, 0xf7, 0x36,
0x6c, 0x58, 0xf4, 0x35, 0x27, 0x97, 0xe4, 0x17, 0x22, 0xa2, 0xb5, 0xcb, 0x13, 0x72, 0xce, 0xfd,
0x13, 0x07, 0x16, 0xf6, 0xe3, 0xc4, 0x4c, 0x36, 0x39, 0x76, 0xb2, 0x49, 0xaa, 0xd6, 0xa1, 0xd6,
0x9c, 0x0d, 0xa9, 0x18, 0x4c, 0x20, 0x2a, 0x46, 0x7f, 0x9a, 0x63, 0x4c, 0x77, 0x12, 0xa7, 0xe7,
0x7e, 0x3a, 0x96, 0xec, 0x2d, 0x41, 0xf1, 0x74, 0x85, 0xfe, 0xc1, 0x9f, 0xe8, 0x53, 0x50, 0xc6,
0x6d, 0x2e, 0xc3, 0x50, 0x39, 0x72, 0xff, 0xd0, 0x81, 0x45, 0xda, 0x2b, 0x3e, 0x16, 0x71, 0xfd,
0x54, 0x93, 0xa3, 0x84, 0x9e, 0x23, 0x1e, 0x4b, 0x09, 0x5c, 0xaa, 0xd4, 0x35, 0x2a, 0x95, 0xba,
0xab, 0xd0, 0x12, 0xa3, 0xa2, 0xb4, 0x55, 0x00, 0xd8, 0x35, 0x68, 0x9e, 0xc6, 0x89, 0x32, 0x71,
0xa0, 0x32, 0x38, 0x71, 0xe2, 0x11, 0xdc, 0xbd, 0x01, 0xab, 0x8f, 0xe2, 0x31, 0x37, 0x12, 0x00,
0x17, 0xde, 0xa2, 0xfb, 0x5b, 0x0e, 0xac, 0x28, 0x64, 0xb6, 0x03, 0x4d, 0xb4, 0x54, 0x25, 0xdf,
0x50, 0x67, 0x5b, 0x11, 0xcf, 0x23, 0x0c, 0xd4, 0x30, 0x14, 0x38, 0x16, 0x9e, 0x84, 0x0a, 0x1b,
0x0b, 0x1b, 0xfd, 0x26, 0xf4, 0xc4, 0x9e, 0x4b, 0xb6, 0xac, 0x04, 0x75, 0xff, 0xca, 0x81, 0xae,
0xb5, 0x06, 0x7a, 0xf9, 0xa1, 0x9f, 0xe5, 0x32, 0x77, 0x25, 0x99, 0x68, 0x82, 0xcc, 0x94, 0x50,
0xc3, 0x4e, 0x09, 0xe9, 0x64, 0xc5, 0x82, 0x99, 0xac, 0xb8, 0x05, 0xad, 0xa2, 0xea, 0xd9, 0xb4,
0x34, 0x07, 0xae, 0xa8, 0xf2, 0xc8, 0x05, 0x12, 0xd2, 0x19, 0xc5, 0x61, 0x9c, 0xca, 0xa2, 0xa0,
0x18, 0xb8, 0xb7, 0xa1, 0x6d, 0xe0, 0xe3, 0x36, 0x22, 0x9e, 0x9f, 0xc7, 0xe9, 0x53, 0x95, 0x99,
0x92, 0x43, 0x5d, 0x3f, 0x69, 0x14, 0xf5, 0x13, 0xf7, 0xaf, 0x1d, 0xe8, 0xa2, 0xa4, 0x04, 0xd1,
0xe4, 0x30, 0x0e, 0x83, 0xd1, 0x9c, 0x24, 0x46, 0x09, 0x85, 0xac, 0x16, 0x2a, 0x89, 0xb1, 0xc1,
0xe8, 0x12, 0x28, 0x27, 0x5f, 0xca, 0x8b, 0x1e, 0xa3, 0xe4, 0xa3, 0x69, 0x3b, 0xf6, 0x33, 0x2e,
0xa2, 0x02, 0xa9, 0xca, 0x2d, 0x20, 0x6a, 0x17, 0x04, 0xa4, 0x7e, 0xce, 0x87, 0xd3, 0x20, 0x0c,
0x03, 0x81, 0x2b, 0x24, 0xbc, 0x6e, 0xca, 0xfd, 0x51, 0x03, 0xda, 0x52, 0x8b, 0x3c, 0x18, 0x4f,
0x44, 0x92, 0x55, 0xfa, 0x29, 0xfa, 0xf9, 0x19, 0x10, 0x35, 0x6f, 0x79, 0x36, 0x06, 0xa4, 0x7c,
0xad, 0x0b, 0xd5, 0x6b, 0xbd, 0x0a, 0x2d, 0x14, 0xaf, 0x77, 0xc8, 0x85, 0x12, 0x45, 0xf2, 0x02,
0xa0, 0x66, 0xf7, 0x68, 0x76, 0xb1, 0x98, 0x25, 0x80, 0xe5, 0x34, 0x2d, 0x95, 0x9c, 0xa6, 0xf7,
0xa0, 0x23, 0xc9, 0x10, 0xdf, 0x29, 0xe6, 0x2a, 0x04, 0xdc, 0xba, 0x13, 0xcf, 0xc2, 0x54, 0x5f,
0xee, 0xa9, 0x2f, 0x57, 0x5e, 0xf6, 0xa5, 0xc2, 0xa4, 0xca, 0x83, 0xe0, 0xcd, 0xc3, 0xd4, 0x4f,
0x4e, 0x95, 0x66, 0x1e, 0xeb, 0xfa, 0x2a, 0x81, 0xd9, 0x0d, 0x58, 0xc4, 0xcf, 0x94, 0xf6, 0xab,
0x7f, 0x74, 0x02, 0x85, 0xed, 0xc0, 0x22, 0x1f, 0x4f, 0xb8, 0x72, 0xdc, 0x99, 0x1d, 0x42, 0xe1,
0x1d, 0x79, 0x02, 0x01, 0x55, 0x00, 0x42, 0x4b, 0x2a, 0xc0, 0xd6, 0x9c, 0x4b, 0x38, 0xfc, 0x70,
0xec, 0x6e, 0x02, 0x7b, 0x24, 0xa4, 0xd6, 0x4c, 0x19, 0xfe, 0xee, 0x02, 0xb4, 0x0d, 0x30, 0xbe,
0xe6, 0x09, 0x6e, 0x78, 0x38, 0x0e, 0xfc, 0x29, 0xcf, 0x79, 0x2a, 0x25, 0xb5, 0x04, 0x25, 0x05,
0x7b, 0x36, 0x19, 0xc6, 0xb3, 0x7c, 0x38, 0xe6, 0x93, 0x94, 0x0b, 0x7b, 0xe7, 0x78, 0x25, 0x28,
0xe2, 0x4d, 0xfd, 0x67, 0x26, 0x9e, 0x90, 0x87, 0x12, 0x54, 0x25, 0x00, 0x05, 0x8f, 0x9a, 0x45,
0x02, 0x50, 0x70, 0xa4, 0xac, 0x87, 0x16, 0x6b, 0xf4, 0xd0, 0xbb, 0xb0, 0x25, 0x34, 0x8e, 0x7c,
0x9b, 0xc3, 0x92, 0x98, 0x5c, 0x30, 0xcb, 0x6e, 0xc0, 0x1a, 0xee, 0x59, 0x09, 0x78, 0x16, 0x7c,
0x5f, 0x04, 0xeb, 0x8e, 0x57, 0x81, 0x23, 0x2e, 0x3e, 0x47, 0x0b, 0x57, 0x54, 0x21, 0x2a, 0x70,
0xc2, 0xf5, 0x9f, 0xd9, 0xb8, 0x2d, 0x89, 0x5b, 0x82, 0xbb, 0x5d, 0x68, 0x1f, 0xe5, 0x71, 0xa2,
0x2e, 0xa5, 0x07, 0x1d, 0x31, 0x94, 0x95, 0xa7, 0xd7, 0xe0, 0x0a, 0x49, 0xd1, 0xe3, 0x38, 0x89,
0xc3, 0x78, 0x32, 0x3f, 0x9a, 0x1d, 0x67, 0xa3, 0x34, 0x48, 0xd0, 0xa1, 0x76, 0xff, 0xde, 0x81,
0x0d, 0x6b, 0x56, 0x66, 0x02, 0xbe, 0x2a, 0x44, 0x5a, 0x17, 0x0b, 0x84, 0xe0, 0xad, 0x1b, 0xea,
0x50, 0x20, 0x8a, 0xbc, 0xca, 0x13, 0x59, 0x3f, 0xb8, 0x03, 0xab, 0x6a, 0x67, 0xea, 0x43, 0x21,
0x85, 0xfd, 0xaa, 0x14, 0xca, 0xef, 0x7b, 0xf2, 0x03, 0x45, 0xe2, 0x97, 0x84, 0x5b, 0xca, 0xc7,
0x74, 0x46, 0x15, 0x12, 0x0e, 0xd4, 0xf7, 0xa6, 0x2f, 0xac, 0x76, 0x30, 0xd2, 0xc0, 0xcc, 0xfd,
0x7d, 0x07, 0xa0, 0xd8, 0x1d, 0x0a, 0x46, 0xa1, 0xd2, 0x1d, 0x4a, 0xb0, 0x1a, 0xea, 0xfb, 0x75,
0xe8, 0xe8, 0x34, 0x76, 0x61, 0x25, 0xda, 0x0a, 0x86, 0x0e, 0xcc, 0x5b, 0xb0, 0x3a, 0x09, 0xe3,
0x63, 0xb2, 0xb9, 0x54, 0xca, 0xcc, 0x64, 0xfd, 0xad, 0x27, 0xc0, 0x1f, 0x48, 0x68, 0x61, 0x52,
0x9a, 0x86, 0x49, 0x71, 0xff, 0xa0, 0xa1, 0xd3, 0xa2, 0xc5, 0x99, 0x2f, 0x7c, 0x65, 0x6c, 0xaf,
0xa2, 0x1c, 0x2f, 0xc8, 0x42, 0x52, 0xf2, 0xe3, 0xf0, 0xa5, 0x71, 0xe0, 0x6d, 0xe8, 0xa5, 0x42,
0xfb, 0x28, 0xd5, 0xd4, 0x7c, 0x81, 0x6a, 0xea, 0xa6, 0x96, 0xdd, 0xf9, 0xff, 0xb0, 0xe6, 0x8f,
0xcf, 0x78, 0x9a, 0x07, 0x14, 0x10, 0x90, 0xd1, 0x17, 0x0a, 0x75, 0xd5, 0x80, 0x93, 0x2d, 0x7e,
0x0b, 0x56, 0x65, 0xcd, 0x53, 0x63, 0xca, 0xd6, 0x97, 0x02, 0x8c, 0x88, 0xee, 0x5f, 0xa8, 0x0c,
0xac, 0x7d, 0x87, 0x17, 0x73, 0xc4, 0x3c, 0x5d, 0xa3, 0x74, 0xba, 0xff, 0x27, 0xb3, 0xa1, 0x63,
0x15, 0x75, 0xc8, 0xbc, 0xb4, 0x00, 0xca, 0xec, 0xb5, 0xcd, 0xd2, 0xe6, 0xab, 0xb0, 0xd4, 0xfd,
0xe1, 0x02, 0x2c, 0x7f, 0x18, 0x9d, 0xc5, 0xc1, 0x88, 0x72, 0x93, 0x53, 0x3e, 0x8d, 0x55, 0x7f,
0x01, 0xfe, 0x46, 0x8b, 0x4e, 0x45, 0xb5, 0x24, 0x97, 0xc9, 0x45, 0x35, 0x44, 0xeb, 0x96, 0x16,
0x3d, 0x37, 0x42, 0x52, 0x0c, 0x08, 0xfa, 0x87, 0xa9, 0xd9, 0x70, 0x24, 0x47, 0x45, 0x83, 0xc6,
0xa2, 0xd1, 0xa0, 0x41, 0x99, 0x6c, 0x51, 0x2f, 0x24, 0x76, 0xae, 0x78, 0x6a, 0x48, 0x7e, 0x6c,
0xca, 0x45, 0x4c, 0x4c, 0x76, 0x72, 0x59, 0xfa, 0xb1, 0x26, 0x10, 0x6d, 0xa9, 0xf8, 0x40, 0xe0,
0x08, 0x5d, 0x63, 0x82, 0xd0, 0xb7, 0x28, 0xf7, 0x2c, 0xb5, 0xc4, 0x15, 0x97, 0xc0, 0xa8, 0x90,
0xc6, 0x5c, 0xeb, 0x0d, 0x71, 0x06, 0x10, 0x3d, 0x45, 0x65, 0xb8, 0xe1, 0x05, 0x8b, 0xba, 0xa7,
0x1c, 0x91, 0x0f, 0xe2, 0x87, 0xe1, 0xb1, 0x3f, 0x7a, 0x4a, 0x9d, 0x64, 0x54, 0xe6, 0x6c, 0x79,
0x36, 0x10, 0x77, 0x4d, 0x8d, 0x51, 0x92, 0x44, 0x57, 0x94, 0x29, 0x0d, 0x90, 0xfb, 0x1d, 0x60,
0x77, 0xc6, 0x63, 0x79, 0x43, 0x3a, 0x46, 0x28, 0x78, 0xeb, 0x58, 0xbc, 0xad, 0x39, 0x63, 0xa3,
0xf6, 0x8c, 0xee, 0x03, 0x68, 0x1f, 0x1a, 0x0d, 0x60, 0x74, 0x99, 0xaa, 0xf5, 0x4b, 0x0a, 0x80,
0x01, 0x31, 0x16, 0x6c, 0x98, 0x0b, 0xba, 0xbf, 0x00, 0xec, 0x20, 0xc8, 0x72, 0xbd, 0x3f, 0x1d,
0x49, 0xea, 0x84, 0x98, 0x11, 0x49, 0x4a, 0x18, 0x45, 0x92, 0x77, 0x44, 0xb5, 0xb4, 0x7c, 0xb0,
0x1b, 0xb0, 0x12, 0x08, 0x90, 0xd2, 0xc3, 0x3d, 0x29, 0xc0, 0x0a, 0x53, 0xcf, 0xa3, 0x43, 0x21,
0x81, 0x96, 0x9a, 0xff, 0x91, 0x03, 0xcb, 0xf2, 0x68, 0x68, 0x0e, 0xad, 0xd6, 0x37, 0x71, 0x30,
0x0b, 0x56, 0xdf, 0x30, 0x54, 0x95, 0xba, 0x85, 0x3a, 0xa9, 0x63, 0xd0, 0x4c, 0xfc, 0xfc, 0x94,
0x3c, 0xe8, 0x96, 0x47, 0xbf, 0x55, 0xa4, 0xb4, 0x58, 0x44, 0x4a, 0x75, 0x3d, 0x6a, 0x42, 0x67,
0x54, 0xe0, 0xaa, 0x8a, 0x2c, 0x0f, 0xa0, 0x13, 0xa0, 0x77, 0x45, 0x15, 0xb9, 0x00, 0x17, 0xfc,
0x92, 0x24, 0xca, 0xfc, 0x92, 0xa8, 0x9e, 0x9e, 0x77, 0x07, 0xd0, 0xbf, 0xcf, 0x43, 0x9e, 0xf3,
0x3b, 0x61, 0x58, 0xa6, 0xff, 0x1a, 0x5c, 0xa9, 0x99, 0x93, 0x56, 0xf5, 0x03, 0x58, 0xbf, 0xcf,
0x8f, 0x67, 0x93, 0x03, 0x7e, 0x56, 0x54, 0x1e, 0x18, 0x34, 0xb3, 0xd3, 0xf8, 0x5c, 0xde, 0x2d,
0xfd, 0xc6, 0x80, 0x37, 0x44, 0x9c, 0x61, 0x96, 0xf0, 0x91, 0xea, 0x8c, 0x21, 0xc8, 0x51, 0xc2,
0x47, 0xee, 0xbb, 0xc0, 0x4c, 0x3a, 0xf2, 0x08, 0xf8, 0x72, 0x67, 0xc7, 0xc3, 0x6c, 0x9e, 0xe5,
0x7c, 0xaa, 0x5a, 0x7e, 0x4c, 0x90, 0xfb, 0x16, 0x74, 0x0e, 0xfd, 0xb9, 0xc7, 0x3f, 0x93, 0xdd,
0x87, 0x18, 0xbc, 0xf9, 0x73, 0x14, 0x65, 0x1d, 0xbc, 0xd1, 0xb4, 0xfb, 0xb7, 0x0d, 0x58, 0x12,
0x98, 0x48, 0x75, 0xcc, 0xb3, 0x3c, 0x88, 0x44, 0x86, 0x5e, 0x52, 0x35, 0x40, 0x15, 0xd9, 0x68,
0xd4, 0xc8, 0x86, 0x74, 0xa7, 0x54, 0x7f, 0x81, 0x14, 0x02, 0x0b, 0x46, 0xb1, 0xa9, 0xae, 0x59,
0x36, 0x65, 0x6c, 0xaa, 0x00, 0xa5, 0x28, 0xb9, 0xd0, 0x0f, 0x62, 0x7f, 0x4a, 0x68, 0xa5, 0x38,
0x98, 0xa0, 0x5a, 0x2d, 0xb4, 0x2c, 0xa4, 0xa6, 0xa2, 0x85, 0x2a, 0xda, 0x66, 0xe5, 0x15, 0xb4,
0x8d, 0xf0, 0xb1, 0x2c, 0x6d, 0xc3, 0x60, 0xed, 0x03, 0xce, 0x3d, 0x9e, 0xc4, 0xa9, 0x6a, 0xe1,
0x74, 0x7f, 0xe0, 0xc0, 0x9a, 0xb4, 0x1e, 0x7a, 0x8e, 0xbd, 0x6e, 0x99, 0x1a, 0xa7, 0x2e, 0x69,
0xfb, 0x06, 0x74, 0x29, 0xd8, 0xc2, 0x48, 0x8a, 0x22, 0x2b, 0x99, 0x7f, 0xb0, 0x80, 0xb8, 0x27,
0x95, 0x86, 0x9c, 0x06, 0xa1, 0x64, 0xb0, 0x09, 0x42, 0xb3, 0xa8, 0x82, 0x31, 0x62, 0xaf, 0xe3,
0xe9, 0xb1, 0x7b, 0x08, 0xeb, 0xc6, 0x7e, 0xa5, 0x40, 0xdd, 0x06, 0x55, 0xb8, 0x14, 0xe9, 0x04,
0xf1, 0x2e, 0xb6, 0x6d, 0x43, 0x58, 0x7c, 0x66, 0x21, 0xbb, 0xff, 0xe4, 0xc0, 0x86, 0x70, 0x0a,
0xa4, 0xcb, 0xa5, 0xfb, 0xa0, 0x96, 0x84, 0x17, 0x24, 0x04, 0x7e, 0xff, 0x92, 0x27, 0xc7, 0xec,
0x6b, 0xaf, 0xe8, 0xc8, 0xe8, 0x1a, 0xe1, 0x05, 0xec, 0x59, 0xa8, 0x63, 0xcf, 0x0b, 0x0e, 0x5f,
0x17, 0x2c, 0x2f, 0xd6, 0x06, 0xcb, 0x77, 0x97, 0x61, 0x31, 0x1b, 0xc5, 0x09, 0x77, 0xb7, 0x60,
0xd3, 0x3e, 0x9c, 0x60, 0xd9, 0xde, 0x3f, 0x3b, 0xd0, 0x13, 0x79, 0x3d, 0xd1, 0x1c, 0xce, 0x53,
0x86, 0x71, 0x99, 0xd1, 0x73, 0xce, 0xb4, 0x5b, 0x5a, 0xed, 0x5d, 0x1f, 0xbc, 0x56, 0x3b, 0xa7,
0x7c, 0xf2, 0xdf, 0xf9, 0xc9, 0xbf, 0xfe, 0x51, 0xe3, 0xb2, 0xbb, 0xb6, 0x7b, 0xf6, 0xce, 0x2e,
0xa9, 0x4f, 0x7e, 0x4e, 0x18, 0xef, 0x3b, 0x37, 0x70, 0x15, 0xb3, 0x1d, 0x5d, 0xaf, 0x52, 0xd3,
0xd6, 0xae, 0x57, 0xa9, 0xed, 0x5f, 0xb7, 0x56, 0x99, 0x11, 0x86, 0x5e, 0x65, 0xef, 0xdf, 0x07,
0xd0, 0xd2, 0x01, 0x24, 0xfb, 0x1e, 0x74, 0xad, 0x1c, 0x26, 0x53, 0x84, 0xeb, 0xb2, 0xa2, 0x83,
0xab, 0xf5, 0x93, 0x72, 0xd9, 0x6b, 0xb4, 0x6c, 0x9f, 0x6d, 0xe1, 0xb2, 0x32, 0x71, 0xb8, 0x4b,
0xc9, 0x5d, 0xd1, 0x22, 0xf1, 0x14, 0x7a, 0x76, 0xde, 0x91, 0x5d, 0xb5, 0x45, 0xa3, 0xb4, 0xda,
0x97, 0x2e, 0x98, 0x95, 0xcb, 0x5d, 0xa5, 0xe5, 0xb6, 0xd8, 0xa6, 0xb9, 0x9c, 0x0e, 0xec, 0x38,
0x35, 0xb5, 0x98, 0x7d, 0xea, 0x4c, 0xd1, 0xab, 0xef, 0x5f, 0x1f, 0x5c, 0xa9, 0xf6, 0xa4, 0xcb,
0x26, 0x76, 0xb7, 0x4f, 0x4b, 0x31, 0x46, 0x0c, 0x35, 0xdb, 0xd4, 0xd9, 0xa7, 0xd0, 0xd2, 0xbd,
0xa9, 0x6c, 0xdb, 0x68, 0x08, 0x36, 0x1b, 0x66, 0x07, 0xfd, 0xea, 0x44, 0xdd, 0x55, 0x99, 0x94,
0x51, 0x20, 0x0e, 0xe0, 0xb2, 0xb4, 0xe6, 0xc7, 0xfc, 0x8b, 0x9c, 0xa4, 0xa6, 0xbb, 0xfe, 0x96,
0xc3, 0x6e, 0xc3, 0x8a, 0x6a, 0xf9, 0x65, 0x5b, 0xf5, 0xad, 0xcb, 0x83, 0xed, 0x0a, 0x5c, 0xea,
0x91, 0x3b, 0x00, 0x45, 0x77, 0x2a, 0xeb, 0x5f, 0xd4, 0x44, 0xab, 0x99, 0x58, 0xd3, 0xca, 0x3a,
0xa1, 0xe6, 0x5c, 0xbb, 0xf9, 0x95, 0x7d, 0xb9, 0xc0, 0xaf, 0x6d, 0x8b, 0x7d, 0x01, 0x41, 0x77,
0x8b, 0x78, 0xb7, 0xc6, 0x7a, 0xc8, 0xbb, 0x88, 0x9f, 0xab, 0xf6, 0xae, 0xfb, 0xd0, 0x36, 0x3a,
0x5e, 0x99, 0xa2, 0x50, 0xed, 0x96, 0x1d, 0x0c, 0xea, 0xa6, 0xe4, 0x76, 0xbf, 0x09, 0x5d, 0xab,
0x75, 0x55, 0xbf, 0x8c, 0xba, 0xc6, 0x58, 0xfd, 0x32, 0xea, 0xbb, 0x5d, 0xbf, 0x0b, 0x6d, 0xa3,
0xd1, 0x94, 0x19, 0xc5, 0xf1, 0x52, 0x8b, 0xa9, 0xde, 0x51, 0x5d, 0x5f, 0xea, 0x26, 0x9d, 0xb7,
0xe7, 0xb6, 0xf0, 0xbc, 0xd4, 0xe3, 0x84, 0x42, 0xf2, 0x3d, 0xe8, 0xd9, 0xad, 0xa7, 0xfa, 0x55,
0xd5, 0x36, 0xb1, 0xea, 0x57, 0x75, 0x41, 0xbf, 0xaa, 0x14, 0xc8, 0x1b, 0x1b, 0x7a, 0x91, 0xdd,
0xcf, 0x65, 0xfa, 0xf4, 0x39, 0xfb, 0x36, 0xaa, 0x0e, 0xd9, 0x74, 0xc6, 0x8a, 0x86, 0x5b, 0xbb,
0x35, 0x4d, 0x4b, 0x7b, 0xa5, 0x3f, 0xcd, 0x5d, 0x27, 0xe2, 0x6d, 0x56, 0x9c, 0x80, 0x7d, 0x04,
0xcb, 0xb2, 0xf9, 0x8c, 0x5d, 0x2e, 0xa4, 0xda, 0x48, 0x36, 0x0d, 0xb6, 0xca, 0x60, 0x49, 0x6c,
0x83, 0x88, 0x75, 0x59, 0x1b, 0x89, 0x4d, 0x78, 0x1e, 0x20, 0x8d, 0x08, 0x56, 0x4b, 0x05, 0x31,
0xfd, 0x58, 0xea, 0xcb, 0xe9, 0x83, 0x6b, 0x2f, 0xae, 0xa3, 0xd9, 0x6a, 0x46, 0xa9, 0x97, 0x5d,
0xd5, 0xfd, 0xf0, 0x6b, 0xd0, 0x31, 0x3b, 0x1a, 0xb5, 0xce, 0xae, 0xe9, 0x7e, 0xd4, 0x3a, 0xbb,
0xae, 0x05, 0x52, 0x5d, 0x2e, 0xeb, 0x98, 0xcb, 0xb0, 0xef, 0xc2, 0xaa, 0x51, 0x7a, 0x3d, 0x9a,
0x47, 0x23, 0x2d, 0x3c, 0xd5, 0x06, 0x98, 0x41, 0x9d, 0xa5, 0x75, 0xb7, 0x89, 0xf0, 0xba, 0x6b,
0x11, 0x46, 0xc1, 0xb9, 0x07, 0x6d, 0xb3, 0xac, 0xfb, 0x02, 0xba, 0xdb, 0xc6, 0x94, 0xd9, 0x37,
0x72, 0xcb, 0x61, 0x7f, 0xea, 0x40, 0xc7, 0x6c, 0xad, 0x62, 0x56, 0xc6, 0xa6, 0x44, 0xa7, 0x6f,
0xce, 0x99, 0x84, 0x5c, 0x8f, 0x36, 0x79, 0x70, 0xe3, 0x9b, 0x16, 0x93, 0x3f, 0xb7, 0x9c, 0xa8,
0x9b, 0xe5, 0xbf, 0x87, 0x3c, 0x2f, 0x23, 0x98, 0x4d, 0x42, 0xcf, 0x6f, 0x39, 0xec, 0x7d, 0xf1,
0x17, 0x22, 0x15, 0x00, 0x31, 0x43, 0xb9, 0x95, 0x59, 0x66, 0xfe, 0xdb, 0x66, 0xc7, 0xb9, 0xe5,
0xb0, 0xdf, 0x10, 0xff, 0x02, 0x91, 0xdf, 0x12, 0xe7, 0x5f, 0xf5, 0x7b, 0xf7, 0x0d, 0x3a, 0xcd,
0x35, 0xf7, 0x8a, 0x75, 0x9a, 0xb2, 0x76, 0x3f, 0x04, 0x28, 0xa2, 0x59, 0x56, 0x0a, 0xed, 0xb4,
0xde, 0xab, 0x06, 0xbc, 0xf6, 0x8d, 0xaa, 0x08, 0x10, 0x29, 0x7e, 0x2a, 0x84, 0x51, 0xe2, 0x67,
0xfa, 0x4a, 0xab, 0x51, 0xe9, 0x60, 0x50, 0x37, 0x55, 0x27, 0x8a, 0x8a, 0x3e, 0x7b, 0x02, 0xdd,
0x83, 0x38, 0x7e, 0x3a, 0x4b, 0x74, 0x86, 0xc4, 0x0e, 0xae, 0x30, 0x74, 0x1e, 0x94, 0x4e, 0xe1,
0x5e, 0x27, 0x52, 0x03, 0xd6, 0x37, 0x48, 0xed, 0x7e, 0x5e, 0xc4, 0xd2, 0xcf, 0x99, 0x0f, 0xeb,
0xda, 0xc6, 0xe9, 0x8d, 0x0f, 0x6c, 0x32, 0x66, 0x48, 0x5b, 0x59, 0xc2, 0xf2, 0x3a, 0xd4, 0x6e,
0x77, 0x33, 0x45, 0xf3, 0x96, 0xc3, 0x0e, 0xa1, 0x73, 0x9f, 0x8f, 0xe2, 0x31, 0x97, 0xe1, 0xd0,
0x46, 0xb1, 0x71, 0x1d, 0x47, 0x0d, 0xba, 0x16, 0xd0, 0x7e, 0xf5, 0x89, 0x3f, 0x4f, 0xf9, 0x67,
0xbb, 0x9f, 0xcb, 0x40, 0xeb, 0xb9, 0x7a, 0xf5, 0x2a, 0x38, 0xb4, 0x5e, 0x7d, 0x29, 0x9a, 0xb4,
0x5e, 0x7d, 0x25, 0x9a, 0xb4, 0x58, 0xad, 0x82, 0x53, 0x16, 0x62, 0x8c, 0x59, 0x0a, 0x40, 0xb5,
0xa5, 0xbc, 0x28, 0x6c, 0x1d, 0x5c, 0xbf, 0x18, 0xc1, 0x5e, 0xed, 0x86, 0xbd, 0xda, 0x11, 0x74,
0xef, 0x73, 0xc1, 0x2c, 0x51, 0x75, 0x18, 0xd8, 0x6a, 0xc4, 0xac, 0x50, 0x94, 0x55, 0x0c, 0xcd,
0xd9, 0x6a, 0x9d, 0x52, 0xfe, 0xec, 0x53, 0x68, 0x3f, 0xe4, 0xb9, 0x2a, 0x33, 0x68, 0x7f, 0xa3,
0x54, 0x77, 0x18, 0xd4, 0x54, 0x29, 0x6c, 0x99, 0x21, 0x6a, 0xbb, 0x7c, 0x3c, 0xe1, 0xe2, 0xb1,
0x0f, 0x83, 0xf1, 0x73, 0xf6, 0x2b, 0x44, 0x5c, 0x57, 0x26, 0xb7, 0x8c, 0xec, 0xb4, 0x49, 0x7c,
0xb5, 0x04, 0xaf, 0xa3, 0x1c, 0xc5, 0x63, 0x6e, 0x18, 0xb8, 0x08, 0xda, 0x46, 0x19, 0x5a, 0x3f,
0xa0, 0x6a, 0xe9, 0x5b, 0x3f, 0xa0, 0x9a, 0xaa, 0xb5, 0xbb, 0x43, 0xeb, 0xb8, 0xec, 0x7a, 0xb1,
0x8e, 0xa8, 0x54, 0x17, 0x2b, 0xed, 0x7e, 0xee, 0x4f, 0xf3, 0xe7, 0xec, 0x13, 0xea, 0xc6, 0x36,
0x4b, 0x29, 0x85, 0xbf, 0x53, 0xae, 0xba, 0x68, 0x66, 0x19, 0x53, 0xb6, 0x0f, 0x24, 0x96, 0x22,
0x3b, 0xf8, 0x35, 0x80, 0xa3, 0x3c, 0x4e, 0xee, 0xfb, 0x7c, 0x1a, 0x47, 0x85, 0xe6, 0x2a, 0xca,
0x05, 0x85, 0xe6, 0x32, 0x6a, 0x06, 0xec, 0x13, 0xc3, 0xe3, 0xb4, 0x2a, 0x51, 0x4a, 0xb8, 0x2e,
0xac, 0x28, 0x68, 0x86, 0xd4, 0x54, 0x15, 0x6e, 0x39, 0xe8, 0x3f, 0x16, 0xe9, 0x0e, 0xed, 0x3f,
0x56, 0x32, 0x29, 0x5a, 0xed, 0xd5, 0xe4, 0x46, 0x0e, 0xa1, 0x55, 0xc4, 0xdc, 0xca, 0x24, 0x95,
0x23, 0x74, 0x6d, 0x63, 0x2a, 0xa1, 0xb0, 0xbb, 0x46, 0xac, 0x02, 0xb6, 0x82, 0xac, 0xa2, 0x4a,
0x7a, 0x00, 0x1b, 0x62, 0x83, 0xda, 0x60, 0x52, 0x02, 0x5c, 0x9d, 0xa4, 0x26, 0xf4, 0xd5, 0xaf,
0xb9, 0x2e, 0x72, 0x74, 0xaf, 0xd0, 0x0a, 0x1b, 0x6e, 0x4f, 0xe9, 0x7d, 0x91, 0x7c, 0x7f, 0xdf,
0xb9, 0x71, 0xbc, 0x44, 0xff, 0x77, 0xfe, 0xca, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x23,
0xfe, 0x34, 0x21, 0x3d, 0x00, 0x00,
}

View File

@ -630,8 +630,6 @@ message ConnectPeerRequest {
bool perm = 2;
}
message ConnectPeerResponse {
/// The id of the newly connected peer
int32 peer_id = 1 [json_name = "peer_id"];
}
message DisconnectPeerRequest {
@ -738,9 +736,6 @@ message Peer {
/// The identity pubkey of the peer
string pub_key = 1 [json_name = "pub_key"];
/// The peer's id from the local point of view
int32 peer_id = 2 [json_name = "peer_id"];
/// Network address of the peer; eg `127.0.0.1:10011`
string address = 3 [json_name = "address"];
@ -806,6 +801,9 @@ message GetInfoResponse {
/// The URIs of the current node.
repeated string uris = 12 [json_name = "uris"];
/// Timestamp of the block best known to the wallet
int64 best_header_timestamp = 13 [ json_name = "best_header_timestamp" ];
}
message ConfirmationUpdate {
@ -858,9 +856,6 @@ message PendingUpdate {
message OpenChannelRequest {
/// The peer_id of the node to open a channel with
int32 target_peer_id = 1 [json_name = "target_peer_id"];
/// The pubkey of the node to open a channel with
bytes node_pubkey = 2 [json_name = "node_pubkey"];

View File

@ -1127,14 +1127,7 @@
}
},
"lnrpcConnectPeerResponse": {
"type": "object",
"properties": {
"peer_id": {
"type": "integer",
"format": "int32",
"title": "/ The id of the newly connected peer"
}
}
"type": "object"
},
"lnrpcCreateWalletRequest": {
"type": "object",
@ -1232,6 +1225,11 @@
"type": "string"
},
"description": "/ The URIs of the current node."
},
"best_header_timestamp": {
"type": "string",
"format": "int64",
"title": "/ Timestamp of the block best known to the wallet"
}
}
},
@ -1559,11 +1557,6 @@
"lnrpcOpenChannelRequest": {
"type": "object",
"properties": {
"target_peer_id": {
"type": "integer",
"format": "int32",
"title": "/ The peer_id of the node to open a channel with"
},
"node_pubkey": {
"type": "string",
"format": "byte",
@ -1697,11 +1690,6 @@
"type": "string",
"title": "/ The identity pubkey of the peer"
},
"peer_id": {
"type": "integer",
"format": "int32",
"title": "/ The peer's id from the local point of view"
},
"address": {
"type": "string",
"title": "/ Network address of the peer; eg `127.0.0.1:10011`"
@ -2024,7 +2012,7 @@
"amount": {
"type": "string",
"format": "int64",
"title": "/ The transaction amount, denominated in satoshis"
"title": "/ The transaction ammount, denominated in satoshis"
},
"num_confirmations": {
"type": "integer",

View File

@ -5,6 +5,7 @@ import (
"encoding/hex"
"fmt"
"math"
"strings"
"sync"
"time"
@ -399,9 +400,93 @@ func (b *BtcWallet) ListUnspentWitness(minConfs int32) ([]*lnwallet.Utxo, error)
}
// PublishTransaction performs cursory validation (dust checks, etc), then
// finally broadcasts the passed transaction to the Bitcoin network.
// finally broadcasts the passed transaction to the Bitcoin network. If
// publishing the transaction fails, an error describing the reason is
// returned (currently ErrDoubleSpend). If the transaction is already
// published to the network (either in the mempool or chain) no error
// will be returned.
func (b *BtcWallet) PublishTransaction(tx *wire.MsgTx) error {
return b.wallet.PublishTransaction(tx)
if err := b.wallet.PublishTransaction(tx); err != nil {
switch b.chain.(type) {
case *chain.RPCClient:
if strings.Contains(err.Error(), "already have") {
// Transaction was already in the mempool, do
// not treat as an error. We do this to mimic
// the behaviour of bitcoind, which will not
// return an error if a transaction in the
// mempool is sent again using the
// sendrawtransaction RPC call.
return nil
}
if strings.Contains(err.Error(), "already exists") {
// Transaction was already mined, we don't
// consider this an error.
return nil
}
if strings.Contains(err.Error(), "already spent") {
// Output was already spent.
return lnwallet.ErrDoubleSpend
}
if strings.Contains(err.Error(), "already been spent") {
// Output was already spent.
return lnwallet.ErrDoubleSpend
}
if strings.Contains(err.Error(), "orphan transaction") {
// Transaction is spending either output that
// is missing or already spent.
return lnwallet.ErrDoubleSpend
}
case *chain.BitcoindClient:
if strings.Contains(err.Error(), "txn-already-in-mempool") {
// Transaction in mempool, treat as non-error.
return nil
}
if strings.Contains(err.Error(), "txn-already-known") {
// Transaction in mempool, treat as non-error.
return nil
}
if strings.Contains(err.Error(), "already in block") {
// Transaction was already mined, we don't
// consider this an error.
return nil
}
if strings.Contains(err.Error(), "txn-mempool-conflict") {
// Output was spent by other transaction
// already in the mempool.
return lnwallet.ErrDoubleSpend
}
if strings.Contains(err.Error(), "insufficient fee") {
// RBF enabled transaction did not have enough fee.
return lnwallet.ErrDoubleSpend
}
if strings.Contains(err.Error(), "Missing inputs") {
// Transaction is spending either output that
// is missing or already spent.
return lnwallet.ErrDoubleSpend
}
case *chain.NeutrinoClient:
if strings.Contains(err.Error(), "already have") {
// Transaction was already in the mempool, do
// not treat as an error.
return nil
}
if strings.Contains(err.Error(), "already exists") {
// Transaction was already mined, we don't
// consider this an error.
return nil
}
if strings.Contains(err.Error(), "already spent") {
// Output was already spent.
return lnwallet.ErrDoubleSpend
}
default:
}
return err
}
return nil
}
// extractBalanceDelta extracts the net balance delta from the PoV of the
@ -667,27 +752,32 @@ func (b *BtcWallet) SubscribeTransactions() (lnwallet.TransactionSubscription, e
// it has fully synced to the current best block in the main chain.
//
// This is a part of the WalletController interface.
func (b *BtcWallet) IsSynced() (bool, error) {
// Grab the best chain state the wallet is currently aware of.
func (b *BtcWallet) IsSynced() (bool, int64, error) {
// Grab the best chain state the wallet is currently aware of. We'll
// also grab the timestamp of the best block to return for determining
// sync progress.
syncState := b.wallet.Manager.SyncedTo()
walletBestHeader, err := b.chain.GetBlockHeader(&syncState.Hash)
if err != nil {
return false, 0, err
}
var (
bestHash *chainhash.Hash
bestHeight int32
err error
)
// Next, query the chain backend to grab the info about the tip of the
// main chain.
bestHash, bestHeight, err = b.cfg.ChainSource.GetBestBlock()
if err != nil {
return false, err
return false, 0, err
}
// If the wallet hasn't yet fully synced to the node's best chain tip,
// then we're not yet fully synced.
if syncState.Height < bestHeight {
return false, nil
return false, walletBestHeader.Timestamp.Unix(), nil
}
// If the wallet is on par with the current best chain tip, then we
@ -696,11 +786,11 @@ func (b *BtcWallet) IsSynced() (bool, error) {
// order to make a guess based on the current time stamp.
blockHeader, err := b.cfg.ChainSource.GetBlockHeader(bestHash)
if err != nil {
return false, err
return false, 0, err
}
// If the timestamp no the best header is more than 2 hours in the
// past, then we're not yet synced.
minus24Hours := time.Now().Add(-2 * time.Hour)
return !blockHeader.Timestamp.Before(minus24Hours), nil
return !blockHeader.Timestamp.Before(minus24Hours), walletBestHeader.Timestamp.Unix(), nil
}

View File

@ -35,6 +35,11 @@ const (
PubKeyHash
)
// ErrDoubleSpend is returned from PublishTransaction in case the
// tx being published is spending an output spent by a conflicting
// transaction.
var ErrDoubleSpend = errors.New("Transaction rejected: output already spent")
// Utxo is an unspent output denoted by its outpoint, and output value of the
// original output.
type Utxo struct {
@ -183,6 +188,11 @@ type WalletController interface {
// PublishTransaction performs cursory validation (dust checks, etc),
// then finally broadcasts the passed transaction to the Bitcoin network.
// If the transaction is rejected because it is conflicting with an
// already known transaction, ErrDoubleSpend is returned. If the
// transaction is already known (published already), no error will be
// returned. Other error returned depends on the currently active chain
// backend.
PublishTransaction(tx *wire.MsgTx) error
// SubscribeTransactions returns a TransactionSubscription client which
@ -198,7 +208,9 @@ type WalletController interface {
// IsSynced returns a boolean indicating if from the PoV of the wallet,
// it has fully synced to the current best block in the main chain.
IsSynced() (bool, error)
// It also returns an int64 indicating the timestamp of the best block
// known to the wallet, expressed in Unix epoch time
IsSynced() (bool, int64, error)
// Start initializes the wallet, making any necessary connections,
// starting up required goroutines etc.

View File

@ -211,7 +211,7 @@ func loadTestCredits(miner *rpctest.Harness, w *lnwallet.LightningWallet,
}
select {
case <-timeout:
synced, err := w.IsSynced()
synced, _, err := w.IsSynced()
if err != nil {
return err
}
@ -1114,6 +1114,326 @@ func testTransactionSubscriptions(miner *rpctest.Harness,
}
}
// testPublishTransaction checks that PublishTransaction returns the
// expected error types in case the transaction being published
// conflicts with the current mempool or chain.
func testPublishTransaction(r *rpctest.Harness,
alice, _ *lnwallet.LightningWallet, t *testing.T) {
// mineAndAssert mines a block and ensures the passed TX
// is part of that block.
mineAndAssert := func(tx *wire.MsgTx) error {
blockHashes, err := r.Node.Generate(1)
if err != nil {
return fmt.Errorf("unable to generate block: %v", err)
}
block, err := r.Node.GetBlock(blockHashes[0])
if err != nil {
return fmt.Errorf("unable to find block: %v", err)
}
if len(block.Transactions) != 2 {
return fmt.Errorf("expected 2 txs in block, got %d",
len(block.Transactions))
}
blockTx := block.Transactions[1]
if blockTx.TxHash() != tx.TxHash() {
return fmt.Errorf("incorrect transaction was mined")
}
// Sleep for a second before returning, to make sure the
// block has propagated.
time.Sleep(1 * time.Second)
return nil
}
// Generate a pubkey, and pay-to-addr script.
pubKey, err := alice.NewRawKey()
if err != nil {
t.Fatalf("unable to obtain public key: %v", err)
}
pubkeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
keyAddr, err := btcutil.NewAddressWitnessPubKeyHash(pubkeyHash,
&chaincfg.RegressionNetParams)
if err != nil {
t.Fatalf("unable to create addr: %v", err)
}
keyScript, err := txscript.PayToAddrScript(keyAddr)
if err != nil {
t.Fatalf("unable to generate script: %v", err)
}
// txFromOutput takes a tx, and creates a new tx that spends
// the output from this tx, to an address derived from payToPubKey.
// NB: assumes that the output from tx is paid to pubKey.
txFromOutput := func(tx *wire.MsgTx, payToPubKey *btcec.PublicKey,
txFee btcutil.Amount) *wire.MsgTx {
// Create a script to pay to.
payToPubkeyHash := btcutil.Hash160(payToPubKey.SerializeCompressed())
payToKeyAddr, err := btcutil.NewAddressWitnessPubKeyHash(payToPubkeyHash,
&chaincfg.RegressionNetParams)
if err != nil {
t.Fatalf("unable to create addr: %v", err)
}
payToScript, err := txscript.PayToAddrScript(payToKeyAddr)
if err != nil {
t.Fatalf("unable to generate script: %v", err)
}
// We assume the output was paid to the keyScript made earlier.
var outputIndex uint32
if len(tx.TxOut) == 1 || bytes.Equal(tx.TxOut[0].PkScript, keyScript) {
outputIndex = 0
} else {
outputIndex = 1
}
outputValue := tx.TxOut[outputIndex].Value
// With the index located, we can create a transaction spending
// the referenced output.
tx1 := wire.NewMsgTx(2)
tx1.AddTxIn(&wire.TxIn{
PreviousOutPoint: wire.OutPoint{
Hash: tx.TxHash(),
Index: outputIndex,
},
// We don't support RBF, so set sequence to max.
Sequence: wire.MaxTxInSequenceNum,
})
tx1.AddTxOut(&wire.TxOut{
Value: outputValue - int64(txFee),
PkScript: payToScript,
})
// Now we can populate the sign descriptor which we'll use to
// generate the signature.
signDesc := &lnwallet.SignDescriptor{
PubKey: pubKey,
WitnessScript: keyScript,
Output: tx.TxOut[outputIndex],
HashType: txscript.SigHashAll,
SigHashes: txscript.NewTxSigHashes(tx1),
InputIndex: 0, // Has only one input.
}
// With the descriptor created, we use it to generate a
// signature, then manually create a valid witness stack we'll
// use for signing.
spendSig, err := alice.Cfg.Signer.SignOutputRaw(tx1, signDesc)
if err != nil {
t.Fatalf("unable to generate signature: %v", err)
}
witness := make([][]byte, 2)
witness[0] = append(spendSig, byte(txscript.SigHashAll))
witness[1] = pubKey.SerializeCompressed()
tx1.TxIn[0].Witness = witness
// Finally, attempt to validate the completed transaction. This
// should succeed if the wallet was able to properly generate
// the proper private key.
vm, err := txscript.NewEngine(keyScript,
tx1, 0, txscript.StandardVerifyFlags, nil,
nil, outputValue)
if err != nil {
t.Fatalf("unable to create engine: %v", err)
}
if err := vm.Execute(); err != nil {
t.Fatalf("spend is invalid: %v", err)
}
return tx1
}
// newTx sends coins from Alice's wallet, mines this transaction,
// and creates a new, unconfirmed tx that spends this output to
// pubKey.
newTx := func() *wire.MsgTx {
// With the script fully assembled, instruct the wallet to fund
// the output with a newly created transaction.
newOutput := &wire.TxOut{
Value: btcutil.SatoshiPerBitcoin,
PkScript: keyScript,
}
txid, err := alice.SendOutputs([]*wire.TxOut{newOutput}, 10)
if err != nil {
t.Fatalf("unable to create output: %v", err)
}
// Query for the transaction generated above so we can located
// the index of our output.
err = waitForMempoolTx(r, txid)
if err != nil {
t.Fatalf("tx not relayed to miner: %v", err)
}
tx, err := r.Node.GetRawTransaction(txid)
if err != nil {
t.Fatalf("unable to query for tx: %v", err)
}
if err := mineAndAssert(tx.MsgTx()); err != nil {
t.Fatalf("unable to mine tx: %v", err)
}
txFee := btcutil.Amount(0.1 * btcutil.SatoshiPerBitcoin)
tx1 := txFromOutput(tx.MsgTx(), pubKey, txFee)
return tx1
}
// We will first check that publishing a transaction already
// in the mempool does NOT return an error. Create the tx.
tx1 := newTx()
// Publish the transaction.
if err := alice.PublishTransaction(tx1); err != nil {
t.Fatalf("unable to publish: %v", err)
}
txid1 := tx1.TxHash()
err = waitForMempoolTx(r, &txid1)
if err != nil {
t.Fatalf("tx not relayed to miner: %v", err)
}
// Publish the exact same transaction again. This should
// not return an error, even though the transaction is
// already in the mempool.
if err := alice.PublishTransaction(tx1); err != nil {
t.Fatalf("unable to publish: %v", err)
}
// Mine the transaction.
if _, err := r.Node.Generate(1); err != nil {
t.Fatalf("unable to generate block: %v", err)
}
// We'll now test that we don't get an error if we try
// to publish a transaction that is already mined.
//
// Create a new transaction. We must do this to properly
// test the reject messages from our peers. They might
// only send us a reject message for a given tx once,
// so we create a new to make sure it is not just
// immediately rejected.
tx2 := newTx()
// Publish this tx.
if err := alice.PublishTransaction(tx2); err != nil {
t.Fatalf("unable to publish: %v", err)
}
txid2 := tx2.TxHash()
err = waitForMempoolTx(r, &txid2)
if err != nil {
t.Fatalf("tx not relayed to miner: %v", err)
}
// Mine the transaction.
if err := mineAndAssert(tx2); err != nil {
t.Fatalf("unable to mine tx: %v", err)
}
// Publish the transaction again. It is already mined,
// and we don't expect this to return an error.
if err := alice.PublishTransaction(tx2); err != nil {
t.Fatalf("unable to publish: %v", err)
}
// Now we'll try to double spend an output with a different
// transaction. Create a new tx and publish it. This is
// the output we'll try to double spend.
tx3 := newTx()
if err := alice.PublishTransaction(tx3); err != nil {
t.Fatalf("unable to publish: %v", err)
}
txid3 := tx3.TxHash()
err = waitForMempoolTx(r, &txid3)
if err != nil {
t.Fatalf("tx not relayed to miner: %v", err)
}
// Mine the transaction.
if err := mineAndAssert(tx3); err != nil {
t.Fatalf("unable to mine tx: %v", err)
}
// Now we create a transaction that spends the output
// from the tx just mined. This should be accepted
// into the mempool.
txFee := btcutil.Amount(0.05 * btcutil.SatoshiPerBitcoin)
tx4 := txFromOutput(tx3, pubKey, txFee)
if err := alice.PublishTransaction(tx4); err != nil {
t.Fatalf("unable to publish: %v", err)
}
txid4 := tx4.TxHash()
err = waitForMempoolTx(r, &txid4)
if err != nil {
t.Fatalf("tx not relayed to miner: %v", err)
}
// Create a new key we'll pay to, to ensure we create
// a unique transaction.
pubKey2, err := alice.NewRawKey()
if err != nil {
t.Fatalf("unable to obtain public key: %v", err)
}
// Create a new transaction that spends the output from
// tx3, and that pays to a different address. We expect
// this to be rejected because it is a double spend.
tx5 := txFromOutput(tx3, pubKey2, txFee)
if err := alice.PublishTransaction(tx5); err != lnwallet.ErrDoubleSpend {
t.Fatalf("expected ErrDoubleSpend, got: %v", err)
}
// Create another transaction that spends the same output,
// but has a higher fee. We expect also this tx to be
// rejected, since the sequence number of tx3 is set to Max,
// indicating it is not replacable.
pubKey3, err := alice.NewRawKey()
if err != nil {
t.Fatalf("unable to obtain public key: %v", err)
}
tx6 := txFromOutput(tx3, pubKey3, 3*txFee)
// Expect rejection.
if err := alice.PublishTransaction(tx6); err != lnwallet.ErrDoubleSpend {
t.Fatalf("expected ErrDoubleSpend, got: %v", err)
}
// At last we try to spend an output already spent by a
// confirmed transaction.
// TODO(halseth): we currently skip this test for neutrino,
// as the backing btcd node will consider the tx being an
// orphan, and will accept it. Should look into if this is
// the behavior also for bitcoind, and update test
// accordingly.
if alice.BackEnd() != "neutrino" {
// Mine the tx spending tx3.
if err := mineAndAssert(tx4); err != nil {
t.Fatalf("unable to mine tx: %v", err)
}
// Create another tx spending tx3.
pubKey4, err := alice.NewRawKey()
if err != nil {
t.Fatalf("unable to obtain public key: %v", err)
}
tx7 := txFromOutput(tx3, pubKey4, txFee)
// Expect rejection.
if err := alice.PublishTransaction(tx7); err != lnwallet.ErrDoubleSpend {
t.Fatalf("expected ErrDoubleSpend, got: %v", err)
}
}
// TODO(halseth): test replaceable transactions when btcd
// gets RBF support.
}
func testSignOutputUsingTweaks(r *rpctest.Harness,
alice, _ *lnwallet.LightningWallet, t *testing.T) {
@ -1469,6 +1789,10 @@ var walletTests = []walletTestCase{
name: "transaction details",
test: testListTransactionDetails,
},
{
name: "publish transaction",
test: testPublishTransaction,
},
{
name: "signed with tweaked pubkeys",
test: testSignOutputUsingTweaks,
@ -1562,7 +1886,7 @@ func waitForWalletSync(r *rpctest.Harness, w *lnwallet.LightningWallet) error {
}
// Check for synchronization.
synced, err = w.IsSynced()
synced, _, err = w.IsSynced()
if err != nil {
return err
}

View File

@ -5,7 +5,6 @@ import (
"crypto/sha256"
"fmt"
"net"
"strings"
"sync"
"sync/atomic"
@ -1114,12 +1113,9 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
// Broadcast the finalized funding transaction to the network.
if err := l.PublishTransaction(fundingTx); err != nil {
// TODO(roasbeef): need to make this into a concrete error
if !strings.Contains(err.Error(), "already have") {
msg.err <- err
msg.completeChan <- nil
return
}
msg.err <- err
msg.completeChan <- nil
return
}
msg.completeChan <- res.partialState

View File

@ -262,8 +262,8 @@ func (m *mockWalletController) PublishTransaction(tx *wire.MsgTx) error {
func (*mockWalletController) SubscribeTransactions() (lnwallet.TransactionSubscription, error) {
return nil, nil
}
func (*mockWalletController) IsSynced() (bool, error) {
return true, nil
func (*mockWalletController) IsSynced() (bool, int64, error) {
return true, int64(0), nil
}
func (*mockWalletController) Start() error {
return nil

10
peer.go
View File

@ -106,7 +106,6 @@ type peer struct {
pubKeyBytes [33]byte
inbound bool
id int32
// This mutex protects all the stats below it.
sync.RWMutex
@ -179,7 +178,6 @@ func newPeer(conn net.Conn, connReq *connmgr.ConnReq, server *server,
conn: conn,
addr: addr,
id: atomic.AddInt32(&numNodes, 1),
inbound: inbound,
connReq: connReq,
@ -276,7 +274,7 @@ func (p *peer) Start() error {
// registering them with the switch and launching the necessary
// goroutines required to operate them.
peerLog.Debugf("Loaded %v active channels from database with "+
"peerID(%v)", len(activeChans), p.id)
"NodeKey(%x)", len(activeChans), p.PubKey())
if err := p.loadActiveChannels(activeChans); err != nil {
return fmt.Errorf("unable to load channels: %v", err)
}
@ -310,7 +308,7 @@ func (p *peer) loadActiveChannels(chans []*channeldb.OpenChannel) error {
p.activeChannels[chanID] = lnChan
p.activeChanMtx.Unlock()
peerLog.Infof("peerID(%v) loading ChannelPoint(%v)", p.id, chanPoint)
peerLog.Infof("NodeKey(%x) loading ChannelPoint(%v)", p.PubKey(), chanPoint)
// Skip adding any permanently irreconcilable channels to the
// htlcswitch.
@ -1247,7 +1245,7 @@ out:
p.activeChanMtx.Unlock()
peerLog.Infof("New channel active ChannelPoint(%v) "+
"with peerId(%v)", chanPoint, p.id)
"with NodeKey(%x)", chanPoint, p.PubKey())
// Next, we'll assemble a ChannelLink along with the
// necessary items it needs to function.
@ -1304,7 +1302,7 @@ out:
// local payments and also passively forward payments.
if err := p.server.htlcSwitch.AddLink(link); err != nil {
peerLog.Errorf("can't register new channel "+
"link(%v) with peerId(%v)", chanPoint, p.id)
"link(%v) with NodeKey(%x)", chanPoint, p.PubKey())
}
close(newChanReq.done)

View File

@ -93,7 +93,7 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey,
// TODO(halseth): make configurable?
minHtlc := lnwire.NewMSatFromSatoshis(1)
updateStream, errChan := c.server.OpenChannel(-1, target, amt, 0,
updateStream, errChan := c.server.OpenChannel(target, amt, 0,
minHtlc, feePerWeight, false)
select {

View File

@ -668,8 +668,8 @@ func (r *rpcServer) DisconnectPeer(ctx context.Context,
func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
updateStream lnrpc.Lightning_OpenChannelServer) error {
rpcsLog.Tracef("[openchannel] request to peerid(%v) "+
"allocation(us=%v, them=%v)", in.TargetPeerId,
rpcsLog.Tracef("[openchannel] request to NodeKey(%v) "+
"allocation(us=%v, them=%v)", in.NodePubkeyString,
in.LocalFundingAmount, in.PushSat)
if !r.server.Started() {
@ -720,24 +720,26 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
// TODO(roasbeef): also return channel ID?
// If the node key is set, then we'll parse the raw bytes into a pubkey
// object so we can easily manipulate it. If this isn't set, then we
// expected the TargetPeerId to be set accordingly.
if len(in.NodePubkey) != 0 {
nodePubKey, err = btcec.ParsePubKey(in.NodePubkey, btcec.S256())
if err != nil {
return err
}
// Making a channel to ourselves wouldn't be of any use, so we
// explicitly disallow them.
if nodePubKey.IsEqual(r.server.identityPriv.PubKey()) {
return fmt.Errorf("cannot open channel to self")
}
nodePubKeyBytes = nodePubKey.SerializeCompressed()
// Ensure that the NodePubKey is set before attempting to use it
if len(in.NodePubkey) == 0 {
return fmt.Errorf("NodePubKey is not set")
}
// Parse the raw bytes of the node key into a pubkey object so we
// can easily manipulate it.
nodePubKey, err = btcec.ParsePubKey(in.NodePubkey, btcec.S256())
if err != nil {
return err
}
// Making a channel to ourselves wouldn't be of any use, so we
// explicitly disallow them.
if nodePubKey.IsEqual(r.server.identityPriv.PubKey()) {
return fmt.Errorf("cannot open channel to self")
}
nodePubKeyBytes = nodePubKey.SerializeCompressed()
// Based on the passed fee related parameters, we'll determine an
// appropriate fee rate for the funding transaction.
feePerByte, err := determineFeePerByte(
@ -754,7 +756,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
// open a new channel. A stream is returned in place, this stream will
// be used to consume updates of the state of the pending channel.
updateChan, errChan := r.server.OpenChannel(
in.TargetPeerId, nodePubKey, localFundingAmt,
nodePubKey, localFundingAmt,
lnwire.NewMSatFromSatoshis(remoteInitialBalance),
minHtlc, feePerByte, in.Private,
)
@ -764,9 +766,8 @@ out:
for {
select {
case err := <-errChan:
rpcsLog.Errorf("unable to open channel to "+
"identityPub(%x) nor peerID(%v): %v",
nodePubKeyBytes, in.TargetPeerId, err)
rpcsLog.Errorf("unable to open channel to NodeKey(%x): %v",
nodePubKeyBytes, err)
return err
case fundingUpdate := <-updateChan:
rpcsLog.Tracef("[openchannel] sending update: %v",
@ -802,8 +803,8 @@ out:
}
}
rpcsLog.Tracef("[openchannel] success peerid(%v), ChannelPoint(%v)",
in.TargetPeerId, outpoint)
rpcsLog.Tracef("[openchannel] success NodeKey(%x), ChannelPoint(%v)",
nodePubKeyBytes, outpoint)
return nil
}
@ -814,8 +815,8 @@ out:
func (r *rpcServer) OpenChannelSync(ctx context.Context,
in *lnrpc.OpenChannelRequest) (*lnrpc.ChannelPoint, error) {
rpcsLog.Tracef("[openchannel] request to peerid(%v) "+
"allocation(us=%v, them=%v)", in.TargetPeerId,
rpcsLog.Tracef("[openchannel] request to NodeKey(%v) "+
"allocation(us=%v, them=%v)", in.NodePubkeyString,
in.LocalFundingAmount, in.PushSat)
// We don't allow new channels to be open while the server is still
@ -828,7 +829,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
// Creation of channels before the wallet syncs up is currently
// disallowed.
isSynced, err := r.server.cc.wallet.IsSynced()
isSynced, _, err := r.server.cc.wallet.IsSynced()
if err != nil {
return nil, err
}
@ -874,7 +875,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
int64(feePerByte))
updateChan, errChan := r.server.OpenChannel(
in.TargetPeerId, nodepubKey, localFundingAmt,
nodepubKey, localFundingAmt,
lnwire.NewMSatFromSatoshis(remoteInitialBalance),
minHtlc, feePerByte, in.Private,
)
@ -882,9 +883,8 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
select {
// If an error occurs them immediately return the error to the client.
case err := <-errChan:
rpcsLog.Errorf("unable to open channel to "+
"identityPub(%x) nor peerID(%v): %v",
nodepubKey, in.TargetPeerId, err)
rpcsLog.Errorf("unable to open channel to NodeKey(%x): %v",
nodepubKey, err)
return nil, err
// Otherwise, wait for the first channel update. The first update sent
@ -1166,7 +1166,7 @@ func (r *rpcServer) GetInfo(ctx context.Context,
return nil, fmt.Errorf("unable to get best block info: %v", err)
}
isSynced, err := r.server.cc.wallet.IsSynced()
isSynced, bestHeaderTimestamp, err := r.server.cc.wallet.IsSynced()
if err != nil {
return nil, fmt.Errorf("unable to sync PoV of the wallet "+
"with current best block in the main chain: %v", err)
@ -1192,17 +1192,18 @@ func (r *rpcServer) GetInfo(ctx context.Context,
// TODO(roasbeef): add synced height n stuff
return &lnrpc.GetInfoResponse{
IdentityPubkey: encodedIDPub,
NumPendingChannels: nPendingChannels,
NumActiveChannels: activeChannels,
NumPeers: uint32(len(serverPeers)),
BlockHeight: uint32(bestHeight),
BlockHash: bestHash.String(),
SyncedToChain: isSynced,
Testnet: activeNetParams.Params == &chaincfg.TestNet3Params,
Chains: activeChains,
Uris: uris,
Alias: nodeAnn.Alias.String(),
IdentityPubkey: encodedIDPub,
NumPendingChannels: nPendingChannels,
NumActiveChannels: activeChannels,
NumPeers: uint32(len(serverPeers)),
BlockHeight: uint32(bestHeight),
BlockHash: bestHash.String(),
SyncedToChain: isSynced,
Testnet: activeNetParams.Params == &chaincfg.TestNet3Params,
Chains: activeChains,
Uris: uris,
Alias: nodeAnn.Alias.String(),
BestHeaderTimestamp: int64(bestHeaderTimestamp),
}, nil
}
@ -1237,7 +1238,6 @@ func (r *rpcServer) ListPeers(ctx context.Context,
nodePub := serverPeer.addr.IdentityKey.SerializeCompressed()
peer := &lnrpc.Peer{
PubKey: hex.EncodeToString(nodePub),
PeerId: serverPeer.id,
Address: serverPeer.conn.RemoteAddr().String(),
Inbound: !serverPeer.inbound, // Flip for display
BytesRecv: atomic.LoadUint64(&serverPeer.bytesReceived),

View File

@ -75,7 +75,6 @@ type server struct {
lightningID [32]byte
mu sync.RWMutex
peersByID map[int32]*peer
peersByPub map[string]*peer
inboundPeers map[string]*peer
@ -173,7 +172,6 @@ func newServer(listenAddrs []string, chanDB *channeldb.DB, cc *chainControl,
persistentConnReqs: make(map[string][]*connmgr.ConnReq),
ignorePeerTermination: make(map[*peer]struct{}),
peersByID: make(map[int32]*peer),
peersByPub: make(map[string]*peer),
inboundPeers: make(map[string]*peer),
outboundPeers: make(map[string]*peer),
@ -1575,7 +1573,6 @@ func (s *server) addPeer(p *peer) {
pubStr := string(p.addr.IdentityKey.SerializeCompressed())
s.peersByID[p.id] = p
s.peersByPub[pubStr] = p
if p.inbound {
@ -1632,7 +1629,6 @@ func (s *server) removePeer(p *peer) {
pubStr := string(p.addr.IdentityKey.SerializeCompressed())
delete(s.peersByID, p.id)
delete(s.peersByPub, pubStr)
if p.inbound {
@ -1646,7 +1642,6 @@ func (s *server) removePeer(p *peer) {
// initiation of a channel funding workflow to the peer with either the
// specified relative peer ID, or a global lightning ID.
type openChanReq struct {
targetPeerID int32
targetPubkey *btcec.PublicKey
chainHash chainhash.Hash
@ -1778,10 +1773,10 @@ func (s *server) DisconnectPeer(pubKey *btcec.PublicKey) error {
}
// OpenChannel sends a request to the server to open a channel to the specified
// peer identified by ID with the passed channel funding parameters.
// peer identified by nodeKey with the passed channel funding parameters.
//
// NOTE: This function is safe for concurrent access.
func (s *server) OpenChannel(peerID int32, nodeKey *btcec.PublicKey,
func (s *server) OpenChannel(nodeKey *btcec.PublicKey,
localAmt btcutil.Amount, pushAmt lnwire.MilliSatoshi,
minHtlc lnwire.MilliSatoshi,
fundingFeePerByte btcutil.Amount,
@ -1806,16 +1801,13 @@ func (s *server) OpenChannel(peerID int32, nodeKey *btcec.PublicKey,
// First attempt to locate the target peer to open a channel with, if
// we're unable to locate the peer then this request will fail.
s.mu.RLock()
if peer, ok := s.peersByID[peerID]; ok {
targetPeer = peer
} else if peer, ok := s.peersByPub[string(pubKeyBytes)]; ok {
if peer, ok := s.peersByPub[string(pubKeyBytes)]; ok {
targetPeer = peer
}
s.mu.RUnlock()
if targetPeer == nil {
errChan <- fmt.Errorf("unable to find peer nodeID(%x), "+
"peerID(%v)", pubKeyBytes, peerID)
errChan <- fmt.Errorf("unable to find peer NodeKey(%x)", pubKeyBytes)
return updateChan, errChan
}
@ -1839,7 +1831,6 @@ func (s *server) OpenChannel(peerID int32, nodeKey *btcec.PublicKey,
// instead of blocking on this request which is exported as a
// synchronous request to the outside world.
req := &openChanReq{
targetPeerID: peerID,
targetPubkey: nodeKey,
chainHash: *activeNetParams.GenesisHash,
localFundingAmt: localAmt,
@ -1865,8 +1856,8 @@ func (s *server) Peers() []*peer {
s.mu.RLock()
defer s.mu.RUnlock()
peers := make([]*peer, 0, len(s.peersByID))
for _, peer := range s.peersByID {
peers := make([]*peer, 0, len(s.peersByPub))
for _, peer := range s.peersByPub {
peers = append(peers, peer)
}

View File

@ -5,7 +5,6 @@ import (
"encoding/binary"
"fmt"
"io"
"strings"
"sync"
"sync/atomic"
@ -1125,9 +1124,7 @@ func (u *utxoNursery) sweepMatureOutputs(classHeight uint32, finalTx *wire.MsgTx
// With the sweep transaction fully signed, broadcast the transaction
// to the network. Additionally, we can stop tracking these outputs as
// they've just been swept.
// TODO(conner): handle concrete error types returned from publication
err := u.cfg.PublishTransaction(finalTx)
if err != nil && !strings.Contains(err.Error(), "TX rejected:") {
if err := u.cfg.PublishTransaction(finalTx); err != nil {
utxnLog.Errorf("unable to broadcast sweep tx: %v, %v",
err, spew.Sdump(finalTx))
return err
@ -1233,14 +1230,9 @@ func (u *utxoNursery) sweepCribOutput(classHeight uint32, baby *babyOutput) erro
// We'll now broadcast the HTLC transaction, then wait for it to be
// confirmed before transitioning it to kindergarten.
//
// TODO(conner): handle concrete error types returned from publication
err := u.cfg.PublishTransaction(baby.timeoutTx)
if err != nil &&
!strings.Contains(err.Error(), "TX rejected:") {
if err := u.cfg.PublishTransaction(baby.timeoutTx); err != nil {
utxnLog.Errorf("Unable to broadcast baby tx: "+
"%v, %v", err,
spew.Sdump(baby.timeoutTx))
"%v, %v", err, spew.Sdump(baby.timeoutTx))
return err
}