Add RPC to show current total available channel capacity #29 (#35)

This commit adds a new RPC command: `channelbalance` which returns the
sum of all available channel capacity across all open channels. The
total balance is currently returned in units of `satoshis`. Additionally
the `networkHarness` has been modified slightly to allow specifying the
additional "extra" command line parameters when creating the initial
seed nodes. Minor refactoring within the integration tests has been
undertaken in order to increase code re-use across tests.

Closes #29.
This commit is contained in:
andrew.shvv 2016-09-15 22:59:51 +04:00 committed by Olaoluwa Osuntokun
parent 4c01e42670
commit 2788dbeaa8
9 changed files with 415 additions and 239 deletions

1
.gitignore vendored

@ -46,3 +46,4 @@ test_wal/*
*.bin
vendor
*.idea

@ -420,6 +420,26 @@ func walletBalance(ctx *cli.Context) error {
return nil
}
var ChannelBalanceCommand = cli.Command{
Name: "channelbalance",
Description: "returns the sum of the total available channel balance across all open channels",
Action: channelBalance,
}
func channelBalance(ctx *cli.Context) error {
ctxb := context.Background()
client := getClient(ctx)
req := &lnrpc.ChannelBalanceRequest{}
resp, err := client.ChannelBalance(ctxb, req)
if err != nil {
return err
}
printRespJson(resp)
return nil
}
var GetInfoCommand = cli.Command{
Name: "getinfo",
Description: "returns basic information related to the active daemon",

@ -56,6 +56,7 @@ func main() {
CloseChannelCommand,
ListPeersCommand,
WalletBalanceCommand,
ChannelBalanceCommand,
ShellCommand,
GetInfoCommand,
PendingChannelsCommand,

@ -505,7 +505,7 @@ func (f *fundingManager) processFundingSignComplete(msg *lnwire.SingleFundingSig
f.fundingMsgs <- &fundingSignCompleteMsg{msg, peer}
}
// handleFundingSignComplete processes the final message recieved in a single
// handleFundingSignComplete processes the final message received in a single
// funder workflow. Once this message is processed, the funding transaction is
// broadcast. Once the funding transaction reaches a sufficient number of
// confirmations, a message is sent to the responding peer along with an SPV
@ -562,7 +562,7 @@ func (f *fundingManager) handleFundingSignComplete(fmsg *fundingSignCompleteMsg)
fndgLog.Infof("ChannelPoint(%v) with peerID(%v) is now active",
fundingPoint, fmsg.peer.id)
// Now that the channel is open, we need to notifiy a
// Now that the channel is open, we need to notify a
// number of parties of this event.
// First we send the newly opened channel to the source
@ -579,7 +579,7 @@ func (f *fundingManager) handleFundingSignComplete(fmsg *fundingSignCompleteMsg)
fundingOpen := lnwire.NewSingleFundingOpenProof(chanID, spvProof)
fmsg.peer.queueMsg(fundingOpen, nil)
// Register the new link wtith the L3 routing manager
// Register the new link with the L3 routing manager
// so this new channel can be utilized during path
// finding.
chanInfo := openChan.StateSnapshot()

@ -13,6 +13,7 @@ import (
"github.com/roasbeef/btcd/wire"
"github.com/roasbeef/btcrpcclient"
"github.com/roasbeef/btcutil"
"github.com/lightningnetwork/lnd/lnrpc"
)
type lndTestCase func(net *networkHarness, t *testing.T)
@ -27,18 +28,11 @@ func assertTxInBlock(block *btcutil.Block, txid *wire.ShaHash, t *testing.T) {
t.Fatalf("funding tx was not included in block")
}
// testBasicChannelFunding performs a test excercising expected behavior from a
// basic funding workflow. The test creates a new channel between Alice and
// Bob, then immediately closes the channel after asserting some expected post
// conditions. Finally, the chain itelf is checked to ensure the closing
// transaction was mined.
func testBasicChannelFunding(net *networkHarness, t *testing.T) {
ctxb := context.Background()
func getChannelHelpers(ctxb context.Context, net *networkHarness, t *testing.T) (func(*lightningNode,
*lightningNode, btcutil.Amount) *lnrpc.ChannelPoint, func(*lightningNode, *lnrpc.ChannelPoint)) {
// First establish a channel with a capacity of 0.5 BTC between Alice
// and Bob.
chanAmt := btcutil.Amount(btcutil.SatoshiPerBitcoin / 2)
chanOpenUpdate, err := net.OpenChannel(ctxb, net.Alice, net.Bob, chanAmt, 1)
openChannel := func(alice *lightningNode, bob *lightningNode, amount btcutil.Amount) *lnrpc.ChannelPoint {
chanOpenUpdate, err := net.OpenChannel(ctxb, alice, bob, amount, 1)
if err != nil {
t.Fatalf("unable to open channel: %v", err)
}
@ -70,13 +64,16 @@ func testBasicChannelFunding(net *networkHarness, t *testing.T) {
Hash: *fundingTxID,
Index: fundingChanPoint.OutputIndex,
}
err = net.AssertChannelExists(ctxb, net.Alice, &chanPoint)
err = net.AssertChannelExists(ctxb, alice, &chanPoint)
if err != nil {
t.Fatalf("unable to assert channel existence: %v", err)
}
// Initiate a close from Alice's side.
closeUpdates, err := net.CloseChannel(ctxb, net.Alice, fundingChanPoint, false)
return fundingChanPoint
}
closeChannel := func(node *lightningNode, fundingChanPoint *lnrpc.ChannelPoint) {
closeUpdates, err := net.CloseChannel(ctxb, node, fundingChanPoint, false)
if err != nil {
t.Fatalf("unable to clsoe channel: %v", err)
}
@ -84,11 +81,11 @@ func testBasicChannelFunding(net *networkHarness, t *testing.T) {
// Finally, generate a single block, wait for the final close status
// update, then ensure that the closing transaction was included in the
// block.
blockHash, err = net.Miner.Node.Generate(1)
blockHash, err := net.Miner.Node.Generate(1)
if err != nil {
t.Fatalf("unable to generate block: %v", err)
}
block, err = net.Miner.Node.GetBlock(blockHash[0])
block, err := net.Miner.Node.GetBlock(blockHash[0])
if err != nil {
t.Fatalf("unable to get block: %v", err)
}
@ -98,10 +95,67 @@ func testBasicChannelFunding(net *networkHarness, t *testing.T) {
t.Fatalf("error while waiting for channel close: %v", err)
}
assertTxInBlock(block, closingTxid, t)
}
return openChannel, closeChannel
}
// testChannelForceClosure performs a test to excerise the behavior of "force"
// closing a channel or unilterally broadcating the latest local commitment
// testBasicChannelFunding performs a test exercising expected behavior from a
// basic funding workflow. The test creates a new channel between Alice and
// Bob, then immediately closes the channel after asserting some expected post
// conditions. Finally, the chain itself is checked to ensure the closing
// transaction was mined.
func testBasicChannelFunding(net *networkHarness, t *testing.T) {
ctxb := context.Background()
// First establish a channel with a capacity of 0.5 BTC between Alice
// and Bob.
openChannel, closeChannel := getChannelHelpers(ctxb, net, t)
chanAmt := btcutil.Amount(btcutil.SatoshiPerBitcoin / 2)
chanPoint := openChannel(net.Alice, net.Bob, chanAmt)
closeChannel(net.Alice, chanPoint)
}
// testChannelBalance creates a new channel between Alice and Bob, then
// checks channel balance to be equal amount specified while creation of channel.
func testChannelBalance(net *networkHarness, t *testing.T) {
ctxb := context.Background()
checkChannelBalance := func (node lnrpc.LightningClient, amount btcutil.Amount) {
response, err := node.ChannelBalance(ctxb, &lnrpc.ChannelBalanceRequest{})
if err != nil {
t.Fatalf("unable to get channel balance: %v", err)
}
balance := btcutil.Amount(response.Balance)
if balance != amount {
t.Fatalf("channel balance wrong: %v != %v", balance, amount)
}
}
openChannel, closeChannel := getChannelHelpers(ctxb, net, t)
amount := btcutil.Amount(btcutil.SatoshiPerBitcoin / 2)
chanPoint := openChannel(net.Alice, net.Bob, amount)
checkChannelBalance(net.Alice, amount)
// Because we wait for Alice channel open notification it might happen
// that Bob haven't added newly created channel in the list of active
// channels, so lets wait for a second.
time.Sleep(time.Second)
checkChannelBalance(net.Bob, 0)
closeChannel(net.Alice, chanPoint)
}
// testChannelForceClosure performs a test to exercise the behavior of "force"
// closing a channel or unilaterally broadcasting the latest local commitment
// state on-chain. The test creates a new channel between Alice and Bob, then
// force closes the channel after some cursory assertions. Within the test, two
// transactions should be broadcast on-chain, the commitment transaction itself
@ -220,10 +274,12 @@ mempoolPoll:
var lndTestCases = map[string]lndTestCase{
"basic funding flow": testBasicChannelFunding,
"channel force closure": testChannelForceClosure,
"channel balance": testChannelBalance,
}
// TestLightningNetworkDaemon performs a series of integration tests amongst a
// programatically driven network of lnd nodes.
// programmatically driven network of lnd nodes.
func TestLightningNetworkDaemon(t *testing.T) {
var (
btcdHarness *rpctest.Harness
@ -250,7 +306,7 @@ func TestLightningNetworkDaemon(t *testing.T) {
// First create the network harness to gain access to its
// 'OnTxAccepted' call back.
lightningNetwork, err = newNetworkHarness(nil)
lightningNetwork, err = newNetworkHarness()
if err != nil {
t.Fatalf("unable to create lightning network harness: %v", err)
}
@ -260,7 +316,7 @@ func TestLightningNetworkDaemon(t *testing.T) {
OnTxAccepted: lightningNetwork.OnTxAccepted,
}
// First create an intance of the btcd's rpctest.Harness. This will be
// First create an instance of the btcd's rpctest.Harness. This will be
// used to fund the wallets of the nodes within the test network and to
// drive blockchain related events within the network.
btcdHarness, err = rpctest.New(harnessNetParams, handlers, nil)
@ -276,8 +332,10 @@ func TestLightningNetworkDaemon(t *testing.T) {
}
// With the btcd harness created, we can now complete the
// initialization of the network.
if err := lightningNetwork.InitializeSeedNodes(btcdHarness); err != nil {
// initialization of the network. args - list of lnd arguments, example: "--debuglevel=debug"
args := []string{}
if err := lightningNetwork.InitializeSeedNodes(btcdHarness, args); err != nil {
t.Fatalf("unable to initialize seed nodes: %v", err)
}
if err = lightningNetwork.SetUp(); err != nil {

@ -40,6 +40,8 @@ It has these top-level messages:
PendingChannelResponse
WalletBalanceRequest
WalletBalanceResponse
ChannelBalanceRequest
ChannelBalanceResponse
RoutingTableLink
ShowRoutingTableRequest
ShowRoutingTableResponse
@ -119,8 +121,8 @@ func (NewAddressRequest_AddressType) EnumDescriptor() ([]byte, []int) {
type SendRequest struct {
Dest []byte `protobuf:"bytes,1,opt,name=dest,proto3" json:"dest,omitempty"`
Amt int64 `protobuf:"varint,2,opt,name=amt" json:"amt,omitempty"`
PaymentHash []byte `protobuf:"bytes,3,opt,name=payment_hash,proto3" json:"payment_hash,omitempty"`
FastSend bool `protobuf:"varint,4,opt,name=fast_send" json:"fast_send,omitempty"`
PaymentHash []byte `protobuf:"bytes,3,opt,name=payment_hash,json=paymentHash,proto3" json:"payment_hash,omitempty"`
FastSend bool `protobuf:"varint,4,opt,name=fast_send,json=fastSend" json:"fast_send,omitempty"`
}
func (m *SendRequest) Reset() { *m = SendRequest{} }
@ -137,8 +139,8 @@ func (*SendResponse) ProtoMessage() {}
func (*SendResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type ChannelPoint struct {
FundingTxid []byte `protobuf:"bytes,1,opt,name=funding_txid,proto3" json:"funding_txid,omitempty"`
OutputIndex uint32 `protobuf:"varint,2,opt,name=output_index" json:"output_index,omitempty"`
FundingTxid []byte `protobuf:"bytes,1,opt,name=funding_txid,json=fundingTxid,proto3" json:"funding_txid,omitempty"`
OutputIndex uint32 `protobuf:"varint,2,opt,name=output_index,json=outputIndex" json:"output_index,omitempty"`
}
func (m *ChannelPoint) Reset() { *m = ChannelPoint{} }
@ -157,7 +159,7 @@ func (*LightningAddress) ProtoMessage() {}
func (*LightningAddress) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
type SendManyRequest struct {
AddrToAmount map[string]int64 `protobuf:"bytes,1,rep,name=AddrToAmount" json:"AddrToAmount,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
AddrToAmount map[string]int64 `protobuf:"bytes,1,rep,name=AddrToAmount,json=addrToAmount" json:"AddrToAmount,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
}
func (m *SendManyRequest) Reset() { *m = SendManyRequest{} }
@ -235,7 +237,7 @@ func (m *ConnectPeerRequest) GetAddr() *LightningAddress {
}
type ConnectPeerResponse struct {
PeerId int32 `protobuf:"varint,1,opt,name=peer_id" json:"peer_id,omitempty"`
PeerId int32 `protobuf:"varint,1,opt,name=peer_id,json=peerId" json:"peer_id,omitempty"`
}
func (m *ConnectPeerResponse) Reset() { *m = ConnectPeerResponse{} }
@ -246,8 +248,8 @@ func (*ConnectPeerResponse) Descriptor() ([]byte, []int) { return fileDescriptor
type HTLC struct {
Id int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
Amount int64 `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
HashLock []byte `protobuf:"bytes,3,opt,name=hash_lock,proto3" json:"hash_lock,omitempty"`
ToUs bool `protobuf:"varint,4,opt,name=to_us" json:"to_us,omitempty"`
HashLock []byte `protobuf:"bytes,3,opt,name=hash_lock,json=hashLock,proto3" json:"hash_lock,omitempty"`
ToUs bool `protobuf:"varint,4,opt,name=to_us,json=toUs" json:"to_us,omitempty"`
}
func (m *HTLC) Reset() { *m = HTLC{} }
@ -257,14 +259,14 @@ func (*HTLC) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
type ActiveChannel struct {
// TODO(roasbeef): make channel points a string everywhere in rpc?
RemoteId string `protobuf:"bytes,1,opt,name=remote_id" json:"remote_id,omitempty"`
ChannelPoint string `protobuf:"bytes,2,opt,name=channel_point" json:"channel_point,omitempty"`
RemoteId string `protobuf:"bytes,1,opt,name=remote_id,json=remoteId" json:"remote_id,omitempty"`
ChannelPoint string `protobuf:"bytes,2,opt,name=channel_point,json=channelPoint" json:"channel_point,omitempty"`
Capacity int64 `protobuf:"varint,3,opt,name=capacity" json:"capacity,omitempty"`
LocalBalance int64 `protobuf:"varint,4,opt,name=local_balance" json:"local_balance,omitempty"`
RemoteBalance int64 `protobuf:"varint,5,opt,name=remote_balance" json:"remote_balance,omitempty"`
UnsettledBelance int64 `protobuf:"varint,6,opt,name=unsettled_belance" json:"unsettled_belance,omitempty"`
PendingHtlcs []*HTLC `protobuf:"bytes,7,rep,name=pending_htlcs" json:"pending_htlcs,omitempty"`
NumUpdates uint64 `protobuf:"varint,8,opt,name=num_updates" json:"num_updates,omitempty"`
LocalBalance int64 `protobuf:"varint,4,opt,name=local_balance,json=localBalance" json:"local_balance,omitempty"`
RemoteBalance int64 `protobuf:"varint,5,opt,name=remote_balance,json=remoteBalance" json:"remote_balance,omitempty"`
UnsettledBelance int64 `protobuf:"varint,6,opt,name=unsettled_belance,json=unsettledBelance" json:"unsettled_belance,omitempty"`
PendingHtlcs []*HTLC `protobuf:"bytes,7,rep,name=pending_htlcs,json=pendingHtlcs" json:"pending_htlcs,omitempty"`
NumUpdates uint64 `protobuf:"varint,8,opt,name=num_updates,json=numUpdates" json:"num_updates,omitempty"`
}
func (m *ActiveChannel) Reset() { *m = ActiveChannel{} }
@ -280,13 +282,13 @@ func (m *ActiveChannel) GetPendingHtlcs() []*HTLC {
}
type Peer struct {
LightningId string `protobuf:"bytes,1,opt,name=lightning_id" json:"lightning_id,omitempty"`
PeerId int32 `protobuf:"varint,2,opt,name=peer_id" json:"peer_id,omitempty"`
LightningId string `protobuf:"bytes,1,opt,name=lightning_id,json=lightningId" json:"lightning_id,omitempty"`
PeerId int32 `protobuf:"varint,2,opt,name=peer_id,json=peerId" json:"peer_id,omitempty"`
Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"`
BytesSent uint64 `protobuf:"varint,4,opt,name=bytes_sent" json:"bytes_sent,omitempty"`
BytesRecv uint64 `protobuf:"varint,5,opt,name=bytes_recv" json:"bytes_recv,omitempty"`
SatSent int64 `protobuf:"varint,6,opt,name=sat_sent" json:"sat_sent,omitempty"`
SatRecv int64 `protobuf:"varint,7,opt,name=sat_recv" json:"sat_recv,omitempty"`
BytesSent uint64 `protobuf:"varint,4,opt,name=bytes_sent,json=bytesSent" json:"bytes_sent,omitempty"`
BytesRecv uint64 `protobuf:"varint,5,opt,name=bytes_recv,json=bytesRecv" json:"bytes_recv,omitempty"`
SatSent int64 `protobuf:"varint,6,opt,name=sat_sent,json=satSent" json:"sat_sent,omitempty"`
SatRecv int64 `protobuf:"varint,7,opt,name=sat_recv,json=satRecv" json:"sat_recv,omitempty"`
Inbound bool `protobuf:"varint,8,opt,name=inbound" json:"inbound,omitempty"`
// TODO(roasbeef): add pending channels
Channels []*ActiveChannel `protobuf:"bytes,9,rep,name=channels" json:"channels,omitempty"`
@ -337,11 +339,11 @@ func (*GetInfoRequest) ProtoMessage() {}
func (*GetInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
type GetInfoResponse struct {
LightningId string `protobuf:"bytes,1,opt,name=lightning_id" json:"lightning_id,omitempty"`
IdentityAddress string `protobuf:"bytes,2,opt,name=identity_address" json:"identity_address,omitempty"`
NumPendingChannels uint32 `protobuf:"varint,3,opt,name=num_pending_channels" json:"num_pending_channels,omitempty"`
NumActiveChannels uint32 `protobuf:"varint,4,opt,name=num_active_channels" json:"num_active_channels,omitempty"`
NumPeers uint32 `protobuf:"varint,5,opt,name=num_peers" json:"num_peers,omitempty"`
LightningId string `protobuf:"bytes,1,opt,name=lightning_id,json=lightningId" json:"lightning_id,omitempty"`
IdentityAddress string `protobuf:"bytes,2,opt,name=identity_address,json=identityAddress" json:"identity_address,omitempty"`
NumPendingChannels uint32 `protobuf:"varint,3,opt,name=num_pending_channels,json=numPendingChannels" json:"num_pending_channels,omitempty"`
NumActiveChannels uint32 `protobuf:"varint,4,opt,name=num_active_channels,json=numActiveChannels" json:"num_active_channels,omitempty"`
NumPeers uint32 `protobuf:"varint,5,opt,name=num_peers,json=numPeers" json:"num_peers,omitempty"`
}
func (m *GetInfoResponse) Reset() { *m = GetInfoResponse{} }
@ -350,9 +352,9 @@ func (*GetInfoResponse) ProtoMessage() {}
func (*GetInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
type ConfirmationUpdate struct {
BlockSha []byte `protobuf:"bytes,1,opt,name=block_sha,proto3" json:"block_sha,omitempty"`
BlockHeight int32 `protobuf:"varint,2,opt,name=block_height" json:"block_height,omitempty"`
NumConfsLeft uint32 `protobuf:"varint,3,opt,name=num_confs_left" json:"num_confs_left,omitempty"`
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"`
NumConfsLeft uint32 `protobuf:"varint,3,opt,name=num_confs_left,json=numConfsLeft" json:"num_confs_left,omitempty"`
}
func (m *ConfirmationUpdate) Reset() { *m = ConfirmationUpdate{} }
@ -361,7 +363,7 @@ func (*ConfirmationUpdate) ProtoMessage() {}
func (*ConfirmationUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
type ChannelOpenUpdate struct {
ChannelPoint *ChannelPoint `protobuf:"bytes,1,opt,name=channel_point" json:"channel_point,omitempty"`
ChannelPoint *ChannelPoint `protobuf:"bytes,1,opt,name=channel_point,json=channelPoint" json:"channel_point,omitempty"`
}
func (m *ChannelOpenUpdate) Reset() { *m = ChannelOpenUpdate{} }
@ -377,7 +379,7 @@ func (m *ChannelOpenUpdate) GetChannelPoint() *ChannelPoint {
}
type ChannelCloseUpdate struct {
ClosingTxid []byte `protobuf:"bytes,1,opt,name=closing_txid,proto3" json:"closing_txid,omitempty"`
ClosingTxid []byte `protobuf:"bytes,1,opt,name=closing_txid,json=closingTxid,proto3" json:"closing_txid,omitempty"`
Success bool `protobuf:"varint,2,opt,name=success" json:"success,omitempty"`
}
@ -387,8 +389,8 @@ func (*ChannelCloseUpdate) ProtoMessage() {}
func (*ChannelCloseUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
type CloseChannelRequest struct {
ChannelPoint *ChannelPoint `protobuf:"bytes,1,opt,name=channel_point" json:"channel_point,omitempty"`
TimeLimit int64 `protobuf:"varint,2,opt,name=time_limit" json:"time_limit,omitempty"`
ChannelPoint *ChannelPoint `protobuf:"bytes,1,opt,name=channel_point,json=channelPoint" json:"channel_point,omitempty"`
TimeLimit int64 `protobuf:"varint,2,opt,name=time_limit,json=timeLimit" json:"time_limit,omitempty"`
Force bool `protobuf:"varint,3,opt,name=force" json:"force,omitempty"`
}
@ -422,13 +424,13 @@ type isCloseStatusUpdate_Update interface {
}
type CloseStatusUpdate_ClosePending struct {
ClosePending *PendingUpdate `protobuf:"bytes,1,opt,name=close_pending,oneof"`
ClosePending *PendingUpdate `protobuf:"bytes,1,opt,name=close_pending,json=closePending,oneof"`
}
type CloseStatusUpdate_Confirmation struct {
Confirmation *ConfirmationUpdate `protobuf:"bytes,2,opt,name=confirmation,oneof"`
}
type CloseStatusUpdate_ChanClose struct {
ChanClose *ChannelCloseUpdate `protobuf:"bytes,3,opt,name=chan_close,oneof"`
ChanClose *ChannelCloseUpdate `protobuf:"bytes,3,opt,name=chan_close,json=chanClose,oneof"`
}
func (*CloseStatusUpdate_ClosePending) isCloseStatusUpdate_Update() {}
@ -566,12 +568,12 @@ func (*PendingUpdate) ProtoMessage() {}
func (*PendingUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
type OpenChannelRequest struct {
TargetPeerId int32 `protobuf:"varint,1,opt,name=target_peer_id" json:"target_peer_id,omitempty"`
TargetNode []byte `protobuf:"bytes,2,opt,name=target_node,proto3" json:"target_node,omitempty"`
LocalFundingAmount int64 `protobuf:"varint,3,opt,name=local_funding_amount" json:"local_funding_amount,omitempty"`
RemoteFundingAmount int64 `protobuf:"varint,4,opt,name=remote_funding_amount" json:"remote_funding_amount,omitempty"`
CommissionSize int64 `protobuf:"varint,5,opt,name=commission_size" json:"commission_size,omitempty"`
NumConfs uint32 `protobuf:"varint,6,opt,name=num_confs" json:"num_confs,omitempty"`
TargetPeerId int32 `protobuf:"varint,1,opt,name=target_peer_id,json=targetPeerId" json:"target_peer_id,omitempty"`
TargetNode []byte `protobuf:"bytes,2,opt,name=target_node,json=targetNode,proto3" json:"target_node,omitempty"`
LocalFundingAmount int64 `protobuf:"varint,3,opt,name=local_funding_amount,json=localFundingAmount" json:"local_funding_amount,omitempty"`
RemoteFundingAmount int64 `protobuf:"varint,4,opt,name=remote_funding_amount,json=remoteFundingAmount" json:"remote_funding_amount,omitempty"`
CommissionSize int64 `protobuf:"varint,5,opt,name=commission_size,json=commissionSize" json:"commission_size,omitempty"`
NumConfs uint32 `protobuf:"varint,6,opt,name=num_confs,json=numConfs" json:"num_confs,omitempty"`
}
func (m *OpenChannelRequest) Reset() { *m = OpenChannelRequest{} }
@ -597,13 +599,13 @@ type isOpenStatusUpdate_Update interface {
}
type OpenStatusUpdate_ChanPending struct {
ChanPending *PendingUpdate `protobuf:"bytes,1,opt,name=chan_pending,oneof"`
ChanPending *PendingUpdate `protobuf:"bytes,1,opt,name=chan_pending,json=chanPending,oneof"`
}
type OpenStatusUpdate_Confirmation struct {
Confirmation *ConfirmationUpdate `protobuf:"bytes,2,opt,name=confirmation,oneof"`
}
type OpenStatusUpdate_ChanOpen struct {
ChanOpen *ChannelOpenUpdate `protobuf:"bytes,3,opt,name=chan_open,oneof"`
ChanOpen *ChannelOpenUpdate `protobuf:"bytes,3,opt,name=chan_open,json=chanOpen,oneof"`
}
func (*OpenStatusUpdate_ChanPending) isOpenStatusUpdate_Update() {}
@ -741,7 +743,7 @@ func (*PendingChannelRequest) ProtoMessage() {}
func (*PendingChannelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} }
type PendingChannelResponse struct {
PendingChannels []*PendingChannelResponse_PendingChannel `protobuf:"bytes,1,rep,name=pending_channels" json:"pending_channels,omitempty"`
PendingChannels []*PendingChannelResponse_PendingChannel `protobuf:"bytes,1,rep,name=pending_channels,json=pendingChannels" json:"pending_channels,omitempty"`
}
func (m *PendingChannelResponse) Reset() { *m = PendingChannelResponse{} }
@ -757,13 +759,13 @@ func (m *PendingChannelResponse) GetPendingChannels() []*PendingChannelResponse_
}
type PendingChannelResponse_PendingChannel struct {
PeerId int32 `protobuf:"varint,1,opt,name=peer_id" json:"peer_id,omitempty"`
LightningId string `protobuf:"bytes,2,opt,name=lightning_id" json:"lightning_id,omitempty"`
ChannelPoint string `protobuf:"bytes,3,opt,name=channel_point" json:"channel_point,omitempty"`
PeerId int32 `protobuf:"varint,1,opt,name=peer_id,json=peerId" json:"peer_id,omitempty"`
LightningId string `protobuf:"bytes,2,opt,name=lightning_id,json=lightningId" json:"lightning_id,omitempty"`
ChannelPoint string `protobuf:"bytes,3,opt,name=channel_point,json=channelPoint" json:"channel_point,omitempty"`
Capacity int64 `protobuf:"varint,4,opt,name=capacity" json:"capacity,omitempty"`
LocalBalance int64 `protobuf:"varint,5,opt,name=local_balance" json:"local_balance,omitempty"`
RemoteBalance int64 `protobuf:"varint,6,opt,name=remote_balance" json:"remote_balance,omitempty"`
ClosingTxid string `protobuf:"bytes,7,opt,name=closing_txid" json:"closing_txid,omitempty"`
LocalBalance int64 `protobuf:"varint,5,opt,name=local_balance,json=localBalance" json:"local_balance,omitempty"`
RemoteBalance int64 `protobuf:"varint,6,opt,name=remote_balance,json=remoteBalance" json:"remote_balance,omitempty"`
ClosingTxid string `protobuf:"bytes,7,opt,name=closing_txid,json=closingTxid" json:"closing_txid,omitempty"`
Status ChannelStatus `protobuf:"varint,8,opt,name=status,enum=lnrpc.ChannelStatus" json:"status,omitempty"`
}
@ -775,7 +777,7 @@ func (*PendingChannelResponse_PendingChannel) Descriptor() ([]byte, []int) {
}
type WalletBalanceRequest struct {
WitnessOnly bool `protobuf:"varint,1,opt,name=witness_only" json:"witness_only,omitempty"`
WitnessOnly bool `protobuf:"varint,1,opt,name=witness_only,json=witnessOnly" json:"witness_only,omitempty"`
}
func (m *WalletBalanceRequest) Reset() { *m = WalletBalanceRequest{} }
@ -792,6 +794,23 @@ func (m *WalletBalanceResponse) String() string { return proto.Compac
func (*WalletBalanceResponse) ProtoMessage() {}
func (*WalletBalanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} }
type ChannelBalanceRequest struct {
}
func (m *ChannelBalanceRequest) Reset() { *m = ChannelBalanceRequest{} }
func (m *ChannelBalanceRequest) String() string { return proto.CompactTextString(m) }
func (*ChannelBalanceRequest) ProtoMessage() {}
func (*ChannelBalanceRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} }
type ChannelBalanceResponse struct {
Balance int64 `protobuf:"varint,1,opt,name=balance" json:"balance,omitempty"`
}
func (m *ChannelBalanceResponse) Reset() { *m = ChannelBalanceResponse{} }
func (m *ChannelBalanceResponse) String() string { return proto.CompactTextString(m) }
func (*ChannelBalanceResponse) ProtoMessage() {}
func (*ChannelBalanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} }
type RoutingTableLink struct {
Id1 string `protobuf:"bytes,1,opt,name=id1" json:"id1,omitempty"`
Id2 string `protobuf:"bytes,2,opt,name=id2" json:"id2,omitempty"`
@ -803,7 +822,7 @@ type RoutingTableLink struct {
func (m *RoutingTableLink) Reset() { *m = RoutingTableLink{} }
func (m *RoutingTableLink) String() string { return proto.CompactTextString(m) }
func (*RoutingTableLink) ProtoMessage() {}
func (*RoutingTableLink) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} }
func (*RoutingTableLink) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} }
type ShowRoutingTableRequest struct {
}
@ -811,7 +830,7 @@ type ShowRoutingTableRequest struct {
func (m *ShowRoutingTableRequest) Reset() { *m = ShowRoutingTableRequest{} }
func (m *ShowRoutingTableRequest) String() string { return proto.CompactTextString(m) }
func (*ShowRoutingTableRequest) ProtoMessage() {}
func (*ShowRoutingTableRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} }
func (*ShowRoutingTableRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} }
type ShowRoutingTableResponse struct {
Channels []*RoutingTableLink `protobuf:"bytes,1,rep,name=channels" json:"channels,omitempty"`
@ -820,7 +839,7 @@ type ShowRoutingTableResponse struct {
func (m *ShowRoutingTableResponse) Reset() { *m = ShowRoutingTableResponse{} }
func (m *ShowRoutingTableResponse) String() string { return proto.CompactTextString(m) }
func (*ShowRoutingTableResponse) ProtoMessage() {}
func (*ShowRoutingTableResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} }
func (*ShowRoutingTableResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} }
func (m *ShowRoutingTableResponse) GetChannels() []*RoutingTableLink {
if m != nil {
@ -862,6 +881,8 @@ func init() {
proto.RegisterType((*PendingChannelResponse_PendingChannel)(nil), "lnrpc.PendingChannelResponse.PendingChannel")
proto.RegisterType((*WalletBalanceRequest)(nil), "lnrpc.WalletBalanceRequest")
proto.RegisterType((*WalletBalanceResponse)(nil), "lnrpc.WalletBalanceResponse")
proto.RegisterType((*ChannelBalanceRequest)(nil), "lnrpc.ChannelBalanceRequest")
proto.RegisterType((*ChannelBalanceResponse)(nil), "lnrpc.ChannelBalanceResponse")
proto.RegisterType((*RoutingTableLink)(nil), "lnrpc.RoutingTableLink")
proto.RegisterType((*ShowRoutingTableRequest)(nil), "lnrpc.ShowRoutingTableRequest")
proto.RegisterType((*ShowRoutingTableResponse)(nil), "lnrpc.ShowRoutingTableResponse")
@ -881,6 +902,7 @@ const _ = grpc.SupportPackageIsVersion3
type LightningClient interface {
WalletBalance(ctx context.Context, in *WalletBalanceRequest, opts ...grpc.CallOption) (*WalletBalanceResponse, error)
ChannelBalance(ctx context.Context, in *ChannelBalanceRequest, opts ...grpc.CallOption) (*ChannelBalanceResponse, error)
SendMany(ctx context.Context, in *SendManyRequest, opts ...grpc.CallOption) (*SendManyResponse, error)
SendCoins(ctx context.Context, in *SendCoinsRequest, opts ...grpc.CallOption) (*SendCoinsResponse, error)
NewAddress(ctx context.Context, in *NewAddressRequest, opts ...grpc.CallOption) (*NewAddressResponse, error)
@ -911,6 +933,15 @@ func (c *lightningClient) WalletBalance(ctx context.Context, in *WalletBalanceRe
return out, nil
}
func (c *lightningClient) ChannelBalance(ctx context.Context, in *ChannelBalanceRequest, opts ...grpc.CallOption) (*ChannelBalanceResponse, error) {
out := new(ChannelBalanceResponse)
err := grpc.Invoke(ctx, "/lnrpc.Lightning/ChannelBalance", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *lightningClient) SendMany(ctx context.Context, in *SendManyRequest, opts ...grpc.CallOption) (*SendManyResponse, error) {
out := new(SendManyResponse)
err := grpc.Invoke(ctx, "/lnrpc.Lightning/SendMany", in, out, c.cc, opts...)
@ -1082,6 +1113,7 @@ func (c *lightningClient) ShowRoutingTable(ctx context.Context, in *ShowRoutingT
type LightningServer interface {
WalletBalance(context.Context, *WalletBalanceRequest) (*WalletBalanceResponse, error)
ChannelBalance(context.Context, *ChannelBalanceRequest) (*ChannelBalanceResponse, error)
SendMany(context.Context, *SendManyRequest) (*SendManyResponse, error)
SendCoins(context.Context, *SendCoinsRequest) (*SendCoinsResponse, error)
NewAddress(context.Context, *NewAddressRequest) (*NewAddressResponse, error)
@ -1117,6 +1149,24 @@ func _Lightning_WalletBalance_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _Lightning_ChannelBalance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ChannelBalanceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LightningServer).ChannelBalance(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/lnrpc.Lightning/ChannelBalance",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LightningServer).ChannelBalance(ctx, req.(*ChannelBalanceRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Lightning_SendMany_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SendManyRequest)
if err := dec(in); err != nil {
@ -1337,6 +1387,10 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{
MethodName: "WalletBalance",
Handler: _Lightning_WalletBalance_Handler,
},
{
MethodName: "ChannelBalance",
Handler: _Lightning_ChannelBalance_Handler,
},
{
MethodName: "SendMany",
Handler: _Lightning_SendMany_Handler,
@ -1394,101 +1448,122 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 1528 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x57, 0x5b, 0x6f, 0x13, 0xd7,
0x13, 0x67, 0x7d, 0xf7, 0xd8, 0x4e, 0xec, 0x93, 0x9b, 0x63, 0xe0, 0xff, 0xa7, 0x2b, 0x40, 0x29,
0x82, 0x00, 0xa6, 0x0f, 0x08, 0x54, 0xaa, 0x60, 0x52, 0x42, 0x49, 0x93, 0x14, 0x07, 0xa1, 0x3e,
0x6d, 0xd7, 0xbb, 0x27, 0x78, 0xc5, 0x7a, 0xd7, 0xf5, 0x39, 0x26, 0xb8, 0x1f, 0xa0, 0xaf, 0x7d,
0xed, 0x67, 0xa8, 0xaa, 0xaa, 0xdf, 0xa1, 0xea, 0x53, 0xa5, 0x7e, 0xa6, 0xce, 0xb9, 0xac, 0xbd,
0x17, 0x07, 0xa9, 0x0f, 0x7d, 0xb2, 0x76, 0xce, 0x9c, 0xb9, 0xfc, 0x66, 0xce, 0x6f, 0xc6, 0x50,
0x9d, 0x8c, 0x9d, 0xdd, 0xf1, 0x24, 0xe4, 0x21, 0x29, 0xfa, 0x01, 0x7e, 0x98, 0xdf, 0x40, 0xad,
0x4f, 0x03, 0xf7, 0x15, 0xfd, 0x7e, 0x4a, 0x19, 0x27, 0x75, 0x28, 0xb8, 0xf8, 0xdb, 0x36, 0xae,
0x19, 0x3b, 0x75, 0x52, 0x83, 0xbc, 0x3d, 0xe2, 0xed, 0x1c, 0x7e, 0xe4, 0xc9, 0x3a, 0xd4, 0xc7,
0xf6, 0x6c, 0x44, 0x03, 0x6e, 0x0d, 0x6d, 0x36, 0x6c, 0xe7, 0xa5, 0x4a, 0x0b, 0xaa, 0x67, 0x36,
0xe3, 0x16, 0x43, 0x23, 0xed, 0x02, 0x8a, 0x2a, 0xe6, 0x0a, 0xd4, 0x95, 0x49, 0x36, 0x0e, 0x03,
0x46, 0xcd, 0x47, 0x50, 0xef, 0x0d, 0xed, 0x20, 0xa0, 0xfe, 0x49, 0xe8, 0x05, 0x5c, 0x18, 0x3a,
0x9b, 0x06, 0xae, 0x17, 0xbc, 0xb5, 0xf8, 0x07, 0xcf, 0xd5, 0xbe, 0x50, 0x1a, 0x4e, 0xf9, 0x78,
0xca, 0x2d, 0x2f, 0x70, 0xe9, 0x07, 0xe9, 0xb4, 0x61, 0x7e, 0x06, 0xcd, 0x43, 0xef, 0xed, 0x90,
0x07, 0xa8, 0xbd, 0xe7, 0xba, 0x13, 0xca, 0x18, 0x21, 0x00, 0xe3, 0xe9, 0xe0, 0x25, 0x9d, 0x1d,
0x88, 0x30, 0xc4, 0xed, 0xaa, 0x88, 0x7b, 0x18, 0x32, 0x15, 0x6a, 0xd5, 0xfc, 0xd1, 0x80, 0x55,
0x11, 0xc2, 0xd7, 0x76, 0x30, 0x8b, 0x32, 0x7b, 0x02, 0x75, 0x61, 0xe0, 0x34, 0xdc, 0x1b, 0x85,
0xd3, 0x40, 0x64, 0x98, 0xdf, 0xa9, 0x75, 0x77, 0x76, 0x25, 0x0c, 0xbb, 0x29, 0xed, 0xdd, 0xb8,
0xea, 0x7e, 0xc0, 0x27, 0xb3, 0xce, 0x03, 0x68, 0x65, 0x84, 0x02, 0xa0, 0x77, 0x74, 0xa6, 0x63,
0x68, 0x40, 0xf1, 0xbd, 0xed, 0x4f, 0xa9, 0xc2, 0xeb, 0x51, 0xee, 0xa1, 0x61, 0x5e, 0x83, 0xe6,
0xc2, 0xb2, 0x82, 0x43, 0x84, 0x3a, 0x4f, 0xbb, 0x6a, 0xde, 0x53, 0x1a, 0x3d, 0x44, 0x86, 0xc5,
0x8a, 0x60, 0xa3, 0x2b, 0x6d, 0x76, 0x05, 0x4a, 0xb6, 0x0a, 0x59, 0xda, 0x35, 0x3f, 0x81, 0x56,
0xec, 0xc6, 0x52, 0xa3, 0x3f, 0x1b, 0xd0, 0x3a, 0xa2, 0xe7, 0x1a, 0xb0, 0xc8, 0x6c, 0x17, 0x75,
0x66, 0x63, 0x2a, 0x75, 0x56, 0xba, 0xd7, 0x75, 0xe6, 0x19, 0xbd, 0x5d, 0xfd, 0x79, 0x8a, 0xba,
0xe6, 0x31, 0xd4, 0x62, 0x9f, 0x64, 0x0b, 0xd6, 0xde, 0xbc, 0x38, 0x3d, 0xda, 0xef, 0xf7, 0xad,
0x93, 0xd7, 0x4f, 0x5f, 0xee, 0x7f, 0x6b, 0x1d, 0xec, 0xf5, 0x0f, 0x9a, 0x97, 0xc8, 0x26, 0x10,
0x94, 0x9e, 0xee, 0x3f, 0x4b, 0xc8, 0x0d, 0xb2, 0x0a, 0xb5, 0xb8, 0x20, 0x67, 0xde, 0x40, 0xc5,
0x98, 0x47, 0x1d, 0xfe, 0x2a, 0x94, 0x6d, 0x25, 0xd2, 0x19, 0x3c, 0x06, 0xd2, 0x0b, 0xb1, 0x65,
0x1c, 0x7e, 0x42, 0xe9, 0x24, 0xca, 0xe0, 0x46, 0x0c, 0x98, 0x5a, 0x77, 0x4b, 0x67, 0x90, 0x6e,
0x10, 0xf3, 0x26, 0xac, 0x25, 0x2e, 0x2f, 0x9c, 0x8c, 0xf1, 0xdb, 0xd2, 0x30, 0x15, 0xcd, 0x67,
0x50, 0x38, 0x38, 0x3d, 0xec, 0x61, 0x3f, 0xe5, 0xb4, 0x2c, 0x9f, 0x46, 0x5b, 0xf4, 0xb7, 0xe8,
0x76, 0xcb, 0x0f, 0x9d, 0x77, 0xba, 0xe5, 0xb1, 0xce, 0x3c, 0xb4, 0xa6, 0x4c, 0xb7, 0xfb, 0xdf,
0x06, 0x34, 0xf6, 0x1c, 0xee, 0xbd, 0xa7, 0xba, 0xcb, 0xc5, 0x9d, 0x09, 0x1d, 0x85, 0x9c, 0x46,
0xae, 0xaa, 0x64, 0x03, 0x1a, 0x8e, 0x3a, 0xb5, 0xc6, 0xe2, 0x11, 0xa8, 0x46, 0x25, 0x4d, 0xa8,
0x38, 0xf6, 0xd8, 0x76, 0x3c, 0x3e, 0x93, 0xc6, 0xf3, 0x42, 0x11, 0x5d, 0xd9, 0xbe, 0x35, 0xb0,
0x7d, 0x3b, 0x70, 0xa8, 0x74, 0x92, 0x47, 0x7c, 0x57, 0xb4, 0xc9, 0x48, 0x5e, 0x94, 0xf2, 0x6d,
0x68, 0x4d, 0x31, 0x37, 0xce, 0x7d, 0xea, 0x5a, 0x03, 0xaa, 0x8e, 0x4a, 0xf2, 0xc8, 0x84, 0xc6,
0x98, 0xaa, 0x67, 0x36, 0xe4, 0xbe, 0xc3, 0xda, 0x65, 0xd9, 0xf1, 0x35, 0x8d, 0x9a, 0xcc, 0x7c,
0x0d, 0x6a, 0xc1, 0x74, 0x64, 0x4d, 0xc7, 0xae, 0xcd, 0x29, 0x6b, 0x57, 0xf0, 0x62, 0xc1, 0xfc,
0xc3, 0x80, 0x82, 0x00, 0x4e, 0x3c, 0x49, 0x3f, 0xc2, 0x76, 0x91, 0x4a, 0x0c, 0x46, 0x91, 0x44,
0x31, 0x5e, 0xbc, 0xbc, 0xd4, 0x40, 0x40, 0x07, 0x33, 0xb4, 0x27, 0x48, 0x81, 0xcb, 0x04, 0x0a,
0x0b, 0xd9, 0x84, 0x3a, 0xef, 0x65, 0xf0, 0x05, 0x91, 0x3d, 0xb3, 0xb9, 0xd2, 0x52, 0x31, 0x6b,
0x89, 0xd4, 0x29, 0x4b, 0x09, 0x1a, 0xf7, 0x82, 0x01, 0x16, 0xc4, 0x95, 0xd1, 0x55, 0xc8, 0x4d,
0x84, 0x4c, 0x21, 0xc9, 0xda, 0x55, 0x99, 0xd1, 0xba, 0xce, 0x28, 0x51, 0x04, 0x93, 0x08, 0xe6,
0x60, 0xb2, 0x03, 0xa2, 0xce, 0x36, 0xef, 0x42, 0x2b, 0x26, 0xd3, 0x6d, 0xd1, 0x81, 0xa2, 0xc8,
0x87, 0x69, 0x46, 0x88, 0xf0, 0x11, 0x4a, 0x66, 0x13, 0x56, 0x9e, 0x53, 0xfe, 0x22, 0x38, 0x0b,
0x23, 0x13, 0x3f, 0x21, 0xb5, 0xcc, 0x45, 0xda, 0xc2, 0x72, 0x9c, 0xda, 0xd0, 0xf4, 0x5c, 0x4c,
0x0d, 0x6b, 0x6b, 0x45, 0xf8, 0xa8, 0xaa, 0x5f, 0x81, 0x75, 0x81, 0x7a, 0x54, 0x9d, 0x79, 0x3a,
0x02, 0xbd, 0x06, 0xb9, 0x0c, 0x6b, 0xe2, 0xd4, 0x96, 0xd9, 0x2c, 0x0e, 0x0b, 0xf2, 0x10, 0x5b,
0x4b, 0x5d, 0x15, 0x01, 0x17, 0x25, 0x45, 0xbe, 0x96, 0x4f, 0xe5, 0xcc, 0x9b, 0x8c, 0x6c, 0xee,
0x85, 0xc1, 0x6b, 0x59, 0x4b, 0xa1, 0x38, 0x10, 0x3d, 0x6b, 0xb1, 0xa1, 0xbd, 0x60, 0x58, 0x25,
0x1a, 0x52, 0x11, 0xad, 0xae, 0x1e, 0x76, 0x96, 0xb0, 0xe8, 0xa0, 0x09, 0x66, 0xf9, 0xf4, 0x8c,
0xab, 0x30, 0xcc, 0x2f, 0xa0, 0xa5, 0xa1, 0x3c, 0xc6, 0x40, 0xb5, 0xd5, 0x5b, 0xe9, 0x36, 0x56,
0x2f, 0x71, 0x4d, 0x63, 0x16, 0xa7, 0x79, 0xf9, 0x84, 0xd5, 0x77, 0xcf, 0x0f, 0x19, 0xd5, 0x16,
0x30, 0x08, 0x07, 0x3f, 0x53, 0xe4, 0x8f, 0x55, 0x66, 0x53, 0xc7, 0x89, 0x20, 0xaa, 0x98, 0x2e,
0x3e, 0x61, 0x71, 0x4b, 0x5b, 0x88, 0x08, 0xe0, 0x5f, 0xf8, 0x17, 0x1d, 0xc7, 0xbd, 0x11, 0xb5,
0x7c, 0x6f, 0xe4, 0x45, 0xaf, 0x19, 0x9f, 0xee, 0x59, 0x38, 0xc1, 0x27, 0x92, 0x97, 0x5e, 0x7e,
0x47, 0x9e, 0x94, 0x6e, 0xfa, 0xdc, 0xe6, 0x53, 0xa6, 0x43, 0xbc, 0x83, 0x4e, 0x84, 0x30, 0x2a,
0x90, 0x76, 0xb2, 0x3e, 0x6f, 0x0c, 0x29, 0x55, 0xca, 0x07, 0x97, 0xc8, 0x7d, 0xcc, 0x28, 0x86,
0xbf, 0xf4, 0x54, 0xeb, 0x6e, 0x47, 0x21, 0x65, 0x4a, 0x83, 0x57, 0xee, 0x02, 0x88, 0x34, 0x2c,
0xe9, 0x46, 0xc6, 0x12, 0xbb, 0x90, 0xc1, 0xec, 0xe0, 0xd2, 0xd3, 0x0a, 0x94, 0xd4, 0x1b, 0x35,
0xaf, 0x42, 0x23, 0x11, 0x40, 0x82, 0xf9, 0xeb, 0xe6, 0x2f, 0x06, 0x10, 0x51, 0xaf, 0x14, 0x6e,
0x58, 0x64, 0x6e, 0x4f, 0xde, 0x52, 0x6e, 0x25, 0x18, 0x50, 0xbc, 0x7f, 0x2d, 0x0f, 0x42, 0x57,
0x0d, 0xae, 0xba, 0x68, 0x4f, 0x45, 0x41, 0xd1, 0x94, 0xd6, 0x84, 0xa8, 0x08, 0xea, 0x2a, 0x6c,
0x68, 0x26, 0x4a, 0x1d, 0x2b, 0xa2, 0xda, 0x82, 0x55, 0x27, 0x1c, 0x8d, 0x3c, 0xc6, 0x30, 0x61,
0x8b, 0x79, 0x3f, 0x44, 0x4c, 0xa5, 0x3b, 0x57, 0xf6, 0x99, 0x7c, 0xed, 0x0d, 0xf3, 0x57, 0x03,
0x9a, 0x22, 0xd8, 0x04, 0xfa, 0xb7, 0x11, 0x4e, 0x81, 0xcd, 0x7f, 0x06, 0xfe, 0x1d, 0xa8, 0x4a,
0x07, 0x21, 0x7a, 0xd0, 0xd8, 0xb7, 0x93, 0xd8, 0x2f, 0x1a, 0x3e, 0x01, 0xfd, 0xe7, 0xb0, 0xa1,
0xdd, 0xa7, 0xd0, 0xbd, 0x0e, 0x25, 0x26, 0x53, 0xd0, 0xa3, 0x75, 0x3d, 0x69, 0x4e, 0xa5, 0x67,
0xfe, 0x96, 0x83, 0xcd, 0xf4, 0x7d, 0x4d, 0x20, 0x5f, 0x42, 0x33, 0x43, 0x06, 0x8a, 0x8d, 0x6e,
0x27, 0xf3, 0x4e, 0x5d, 0x4c, 0x89, 0x3b, 0x7f, 0x19, 0xb0, 0x92, 0x14, 0x65, 0x86, 0x5e, 0x86,
0xac, 0x72, 0xcb, 0xe7, 0x53, 0x3e, 0x33, 0x9f, 0x0a, 0xcb, 0xe7, 0x53, 0xf1, 0x82, 0xf9, 0x54,
0x8a, 0x96, 0xc6, 0xc4, 0x73, 0x2f, 0x4b, 0xb3, 0x0b, 0xc0, 0x2a, 0x1f, 0x01, 0xec, 0x36, 0xac,
0xbf, 0xb1, 0x7d, 0x9f, 0xf2, 0xa7, 0xca, 0x64, 0x04, 0x37, 0xda, 0x3c, 0xf7, 0x78, 0x80, 0x64,
0x61, 0x85, 0x81, 0xaf, 0xb6, 0xaf, 0x8a, 0xb9, 0x03, 0x1b, 0x29, 0xed, 0xc5, 0xd8, 0x8f, 0x62,
0x12, 0x9a, 0x86, 0xf9, 0x1d, 0x34, 0x5f, 0xe1, 0xaa, 0x89, 0x31, 0x9d, 0xda, 0x03, 0x9f, 0x1e,
0x7a, 0xc1, 0x3b, 0xb1, 0xc8, 0x79, 0xee, 0x7d, 0xcd, 0xdc, 0xf2, 0xa3, 0xbb, 0x18, 0xd1, 0x62,
0x2f, 0xfd, 0x28, 0x28, 0xb8, 0x34, 0x9c, 0x2b, 0x4e, 0x2d, 0x4a, 0x0f, 0xdb, 0xb0, 0xd5, 0x1f,
0x86, 0xe7, 0x71, 0x2f, 0xd1, 0xfc, 0xd8, 0x87, 0x76, 0xf6, 0x48, 0x47, 0xfa, 0x69, 0x6c, 0xb4,
0xa9, 0xf2, 0x47, 0x2b, 0x4e, 0x3a, 0xde, 0x5b, 0x5d, 0x68, 0x24, 0xc0, 0x22, 0x65, 0xc8, 0xef,
0x1d, 0x1e, 0xe2, 0x26, 0x56, 0x83, 0xf2, 0xf1, 0xc9, 0xfe, 0xd1, 0x8b, 0xa3, 0xe7, 0xb8, 0x7e,
0xe1, 0x47, 0xef, 0xf0, 0xb8, 0x2f, 0x3e, 0x72, 0xdd, 0x3f, 0x4b, 0x50, 0x9d, 0xef, 0x4a, 0xe4,
0x2b, 0x68, 0x24, 0xf0, 0x22, 0x97, 0xb5, 0xaf, 0x65, 0x98, 0x77, 0xae, 0x2c, 0x3f, 0xd4, 0x81,
0x3f, 0x86, 0x4a, 0xb4, 0xe6, 0x92, 0xcd, 0xe5, 0x1b, 0x75, 0x67, 0x2b, 0x23, 0xd7, 0x97, 0x9f,
0x40, 0x75, 0xbe, 0xcf, 0x92, 0xb8, 0x56, 0x7c, 0x27, 0xee, 0xb4, 0xb3, 0x07, 0xfa, 0xfe, 0x1e,
0xc0, 0x62, 0xa3, 0x24, 0xed, 0x8b, 0xd6, 0xda, 0xce, 0xf6, 0x92, 0x13, 0x6d, 0xe2, 0x19, 0xd4,
0x62, 0x0b, 0x23, 0x89, 0xd1, 0x47, 0x6a, 0x03, 0xed, 0x74, 0x96, 0x1d, 0x2d, 0x12, 0x99, 0x6f,
0x17, 0x64, 0xb1, 0x9c, 0x26, 0x77, 0x90, 0x79, 0x22, 0xd9, 0x45, 0xe4, 0x21, 0x94, 0xf5, 0x66,
0x41, 0x36, 0xb4, 0x52, 0x72, 0xf9, 0xe8, 0x6c, 0xa6, 0xc5, 0xfa, 0x66, 0x0f, 0x6a, 0x31, 0xd2,
0x9f, 0xc7, 0x9f, 0x1d, 0x04, 0xf3, 0x2a, 0xa4, 0x69, 0xf7, 0x9e, 0x81, 0x24, 0x54, 0x8f, 0x8f,
0x5c, 0x32, 0x4f, 0x35, 0x3b, 0x87, 0xe7, 0x49, 0x64, 0x86, 0x27, 0xda, 0x39, 0x82, 0xd5, 0x24,
0x07, 0x31, 0x72, 0xe5, 0x02, 0x16, 0x53, 0xc6, 0xae, 0x7e, 0x94, 0xe3, 0xc8, 0x23, 0xf5, 0x0f,
0xf5, 0x44, 0xfd, 0xf7, 0x24, 0x24, 0xd6, 0x08, 0x91, 0x85, 0xb5, 0x84, 0x4c, 0xdd, 0xdb, 0x31,
0x30, 0x96, 0x3e, 0xfe, 0xbb, 0x4a, 0xbd, 0x36, 0xf2, 0xbf, 0x48, 0x79, 0xf9, 0x0b, 0xed, 0xfc,
0xff, 0xc2, 0x73, 0x65, 0x78, 0x50, 0x92, 0x7f, 0xa0, 0x1f, 0xfc, 0x13, 0x00, 0x00, 0xff, 0xff,
0x66, 0x9c, 0x09, 0xa8, 0x4d, 0x0f, 0x00, 0x00,
// 1863 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x58, 0x5f, 0x73, 0xd3, 0xca,
0x15, 0xbf, 0xfe, 0x17, 0xdb, 0x47, 0x8e, 0xe3, 0x6c, 0xfe, 0x39, 0xbe, 0xdc, 0x4b, 0x51, 0x69,
0x49, 0x0b, 0x93, 0x01, 0x33, 0xd3, 0x06, 0x98, 0x81, 0x49, 0x42, 0x20, 0x29, 0x26, 0x49, 0xe5,
0x30, 0x4c, 0x9f, 0x54, 0x59, 0xde, 0x60, 0x0d, 0xb2, 0xe4, 0x5a, 0x6b, 0x82, 0x79, 0xee, 0xb4,
0x5f, 0xa0, 0x8f, 0x1d, 0xa6, 0xcf, 0xfd, 0x06, 0xfd, 0x18, 0x7d, 0xea, 0x5b, 0x3f, 0x4b, 0xcf,
0xfe, 0x93, 0x25, 0xd9, 0x01, 0xa6, 0x73, 0x9f, 0xac, 0xfd, 0xed, 0xd9, 0xb3, 0xe7, 0xff, 0x39,
0x6b, 0xa8, 0x8e, 0x47, 0xee, 0xee, 0x68, 0x1c, 0xb2, 0x90, 0x94, 0xfc, 0x00, 0x17, 0x66, 0x04,
0x46, 0x97, 0x06, 0x7d, 0x8b, 0xfe, 0x69, 0x42, 0x23, 0x46, 0x08, 0x14, 0xfb, 0xf8, 0xdb, 0xcc,
0xfd, 0x2c, 0xb7, 0x53, 0xb3, 0xc4, 0x37, 0x69, 0x40, 0xc1, 0x19, 0xb2, 0x66, 0x1e, 0xa1, 0x82,
0xc5, 0x3f, 0xc9, 0x2d, 0xa8, 0x8d, 0x9c, 0xe9, 0x90, 0x06, 0xcc, 0x1e, 0x38, 0xd1, 0xa0, 0x59,
0x10, 0xd4, 0x86, 0xc2, 0x8e, 0x11, 0x22, 0xdf, 0x43, 0xf5, 0xd2, 0x89, 0x98, 0x1d, 0x21, 0xf3,
0x66, 0x11, 0xf7, 0x2b, 0x56, 0x85, 0x03, 0xfc, 0x32, 0xb3, 0x0e, 0x35, 0x79, 0x69, 0x34, 0x0a,
0x83, 0x88, 0x9a, 0x17, 0x50, 0x3b, 0x1c, 0x38, 0x41, 0x40, 0xfd, 0xf3, 0xd0, 0x0b, 0x04, 0xff,
0xcb, 0x49, 0xd0, 0xf7, 0x82, 0x77, 0x36, 0xfb, 0xe8, 0xf5, 0x95, 0x34, 0x86, 0xc2, 0x2e, 0x10,
0xe2, 0x24, 0xe1, 0x84, 0x8d, 0x26, 0xcc, 0xf6, 0x82, 0x3e, 0xfd, 0x28, 0xa4, 0x5b, 0xb6, 0x0c,
0x89, 0x9d, 0x70, 0xc8, 0x7c, 0x01, 0x8d, 0x8e, 0xf7, 0x6e, 0xc0, 0x02, 0x3c, 0xb3, 0xdf, 0xef,
0x8f, 0x69, 0x14, 0x91, 0x1f, 0x01, 0x46, 0x93, 0xde, 0x2b, 0x3a, 0xe5, 0x42, 0x0a, 0xbe, 0x55,
0x2b, 0x81, 0x70, 0xfd, 0x07, 0x61, 0x24, 0x95, 0xad, 0x5a, 0xe2, 0xdb, 0xfc, 0x47, 0x0e, 0x56,
0xb8, 0xb8, 0xaf, 0x9d, 0x60, 0xaa, 0xed, 0xd4, 0x81, 0x1a, 0x67, 0x79, 0x11, 0xee, 0x0f, 0xc3,
0x49, 0xc0, 0xed, 0x55, 0xd8, 0x31, 0xda, 0x3b, 0xbb, 0xc2, 0xa8, 0xbb, 0x19, 0xea, 0xdd, 0x24,
0xe9, 0x51, 0xc0, 0xc6, 0x53, 0xab, 0xe6, 0x24, 0xa0, 0xd6, 0x33, 0x58, 0x9d, 0x23, 0xe1, 0x66,
0x7f, 0x4f, 0xa7, 0x4a, 0x46, 0xfe, 0x49, 0xd6, 0xa1, 0xf4, 0xc1, 0xf1, 0x27, 0x54, 0xb9, 0x42,
0x2e, 0x1e, 0xe7, 0xf7, 0x72, 0xe6, 0x2f, 0xa1, 0x31, 0xbb, 0x53, 0x1a, 0x95, 0xab, 0x12, 0x1b,
0x0f, 0x55, 0xe1, 0xdf, 0xe6, 0x53, 0x49, 0x77, 0x88, 0x56, 0x8e, 0x12, 0x2e, 0xe7, 0xc2, 0x68,
0x3a, 0xfe, 0x4d, 0x36, 0x61, 0xc9, 0x91, 0x8a, 0xc9, 0xab, 0xd4, 0xca, 0xbc, 0x03, 0xab, 0x89,
0xf3, 0x5f, 0xb8, 0xe8, 0x73, 0x0e, 0x56, 0x4f, 0xe9, 0x95, 0x32, 0xbb, 0xbe, 0x6a, 0x0f, 0x29,
0xa7, 0x23, 0x2a, 0x28, 0xeb, 0xed, 0xdb, 0xca, 0x5a, 0x73, 0x74, 0xbb, 0x6a, 0x79, 0x81, 0xb4,
0x96, 0x38, 0x61, 0x9e, 0x81, 0x91, 0x00, 0xc9, 0x16, 0xac, 0xbd, 0x3d, 0xb9, 0x38, 0x3d, 0xea,
0x76, 0xed, 0xf3, 0x37, 0x07, 0xaf, 0x8e, 0xfe, 0x60, 0x1f, 0xef, 0x77, 0x8f, 0x1b, 0xdf, 0xa1,
0xe0, 0x04, 0xd1, 0x8b, 0xa3, 0xe7, 0x29, 0x3c, 0x47, 0x56, 0xc0, 0x48, 0x02, 0x79, 0x73, 0x17,
0x09, 0x13, 0xf7, 0x2a, 0x55, 0x9a, 0x50, 0x76, 0x24, 0xa4, 0xb4, 0xd1, 0x4b, 0x73, 0x1f, 0xc8,
0x61, 0x88, 0x11, 0xea, 0xb2, 0x73, 0x4a, 0xc7, 0x5a, 0xa1, 0xbb, 0x09, 0xdb, 0x19, 0xed, 0x2d,
0xa5, 0x50, 0x36, 0xea, 0xa4, 0x51, 0xf1, 0xca, 0xb5, 0x14, 0x0b, 0x75, 0xe7, 0x16, 0x94, 0x47,
0xb8, 0xb6, 0x95, 0x05, 0x4b, 0xd6, 0x12, 0x5f, 0x9e, 0xf4, 0xcd, 0x3f, 0x42, 0xf1, 0xf8, 0xa2,
0x73, 0x48, 0xea, 0x90, 0x57, 0x7b, 0x05, 0x0b, 0xbf, 0xae, 0x73, 0x0e, 0x4f, 0x39, 0x9e, 0x8d,
0xb6, 0x1f, 0xba, 0xef, 0x55, 0x4a, 0x56, 0x38, 0xd0, 0xc1, 0x35, 0x59, 0x83, 0x12, 0x0b, 0xed,
0x49, 0xa4, 0x72, 0xb1, 0xc8, 0xc2, 0x37, 0x91, 0xf9, 0xaf, 0x3c, 0x2c, 0xef, 0xbb, 0xcc, 0xfb,
0x40, 0x55, 0xfa, 0x71, 0x1e, 0x63, 0x3a, 0x0c, 0x19, 0xb5, 0x63, 0x87, 0x56, 0x24, 0x70, 0xd2,
0x27, 0x3f, 0x87, 0x65, 0x57, 0xd2, 0xd9, 0x23, 0x9e, 0xa7, 0x2a, 0x4b, 0x6a, 0x6e, 0x32, 0x77,
0x5b, 0x50, 0x71, 0x9d, 0x91, 0xe3, 0x7a, 0x6c, 0x2a, 0x84, 0x28, 0x58, 0xf1, 0x9a, 0x33, 0x40,
0xe1, 0x1c, 0xdf, 0xee, 0x39, 0xbe, 0x13, 0xb8, 0x54, 0x08, 0x53, 0xb0, 0x6a, 0x02, 0x3c, 0x90,
0x18, 0xf9, 0x05, 0xd4, 0x95, 0x08, 0x9a, 0xaa, 0x24, 0xa8, 0x96, 0x25, 0xaa, 0xc9, 0xee, 0xc2,
0xea, 0x04, 0xcd, 0xc7, 0x98, 0x4f, 0xfb, 0x76, 0x8f, 0x4a, 0xca, 0x25, 0x41, 0xd9, 0x88, 0x37,
0x0e, 0x24, 0x4e, 0xee, 0xc3, 0xf2, 0x88, 0xca, 0x82, 0x32, 0x60, 0xbe, 0x1b, 0x35, 0xcb, 0x22,
0x5f, 0x0d, 0xe5, 0x30, 0x6e, 0x66, 0xab, 0xa6, 0x28, 0x8e, 0x39, 0x01, 0xb9, 0x09, 0x46, 0x30,
0x19, 0xda, 0x93, 0x51, 0xdf, 0x61, 0x34, 0x6a, 0x56, 0x90, 0x71, 0xd1, 0x02, 0x84, 0xde, 0x48,
0xc4, 0xfc, 0x7b, 0x1e, 0x8a, 0xdc, 0x8f, 0xbc, 0x12, 0xf9, 0xda, 0xe1, 0x33, 0xab, 0x19, 0x31,
0x86, 0x86, 0x4b, 0xb8, 0x38, 0x9f, 0x74, 0x71, 0x32, 0xde, 0x0a, 0xa9, 0x78, 0x23, 0x3f, 0x00,
0xf4, 0xa6, 0x78, 0x0f, 0x2f, 0xa0, 0x4c, 0xd8, 0xa9, 0x68, 0x55, 0x05, 0x82, 0x09, 0xc8, 0x66,
0xdb, 0x63, 0xea, 0x7e, 0x10, 0x06, 0xd2, 0xdb, 0x16, 0x02, 0x64, 0x1b, 0x2a, 0x91, 0xc3, 0xe4,
0x59, 0x69, 0x93, 0x32, 0xae, 0xc5, 0x49, 0xb5, 0x25, 0xce, 0x95, 0xe3, 0x2d, 0x71, 0x0a, 0xa5,
0xf1, 0x82, 0x1e, 0xc6, 0x52, 0x5f, 0xe8, 0x5b, 0xb1, 0xf4, 0x12, 0xed, 0x57, 0x51, 0x4e, 0x8e,
0x9a, 0x55, 0x61, 0xba, 0x75, 0x65, 0xba, 0x54, 0xf8, 0x58, 0x31, 0x95, 0x49, 0x78, 0xf1, 0x8d,
0x44, 0xa4, 0xeb, 0xb4, 0x36, 0x7f, 0x03, 0xab, 0x09, 0x4c, 0x85, 0xff, 0x2d, 0x28, 0x71, 0x63,
0x44, 0xaa, 0x84, 0x6a, 0x97, 0x88, 0x14, 0x91, 0x3b, 0x66, 0x03, 0xea, 0x2f, 0x29, 0x16, 0xf5,
0xcb, 0x50, 0x73, 0xfa, 0x2f, 0x96, 0xe4, 0x18, 0x8a, 0x19, 0x7d, 0xd5, 0x0f, 0xbf, 0x82, 0x86,
0xd7, 0x47, 0x23, 0x60, 0x2c, 0xda, 0xda, 0xee, 0x32, 0x86, 0x57, 0x34, 0xae, 0x1b, 0xc5, 0x7d,
0x58, 0xe7, 0xfe, 0xd7, 0x51, 0x13, 0x6b, 0x5f, 0x10, 0x7d, 0x86, 0xe0, 0xde, 0xb9, 0xdc, 0x52,
0xaa, 0x47, 0x04, 0xd3, 0x9b, 0x9f, 0x70, 0x84, 0x41, 0x66, 0x07, 0x8a, 0xe2, 0xc0, 0x2a, 0x6e,
0xa5, 0x4c, 0x15, 0xf1, 0x54, 0x93, 0x37, 0x70, 0xe5, 0x4b, 0x82, 0xaa, 0x22, 0xd8, 0x72, 0x95,
0x3f, 0x89, 0x72, 0x73, 0xe9, 0x8d, 0x87, 0x0e, 0xf3, 0xc2, 0x40, 0x06, 0x1d, 0x3f, 0xd2, 0xe3,
0xd9, 0x6d, 0x47, 0x03, 0x47, 0x35, 0xc5, 0x8a, 0x00, 0xba, 0x03, 0x87, 0xeb, 0x2f, 0x37, 0x07,
0x94, 0xab, 0xac, 0x22, 0xcd, 0x10, 0xd8, 0xb1, 0x80, 0xc8, 0x6d, 0xa8, 0xf3, 0x2b, 0x5d, 0xe4,
0x1c, 0xd9, 0x3e, 0xbd, 0x64, 0x4a, 0x9d, 0x1a, 0xa2, 0xfc, 0xba, 0xa8, 0x83, 0x98, 0xf9, 0x1a,
0x56, 0x95, 0x90, 0x67, 0xa8, 0xbe, 0xba, 0x7a, 0x2f, 0x9b, 0xfb, 0xb2, 0xe4, 0xad, 0x29, 0x77,
0x25, 0xdb, 0x77, 0xba, 0x20, 0x98, 0xbf, 0x47, 0x55, 0xe4, 0xfa, 0xd0, 0x0f, 0x23, 0xaa, 0xf8,
0xa1, 0xb4, 0x2e, 0x2e, 0xb3, 0x2d, 0x5e, 0x61, 0xa2, 0xc5, 0x63, 0x38, 0x46, 0x13, 0xd7, 0xd5,
0x4e, 0xc2, 0x70, 0x54, 0x4b, 0xf3, 0xcf, 0x39, 0x2c, 0xa5, 0x9c, 0x99, 0x8e, 0xbb, 0xb8, 0xbf,
0xfc, 0x9f, 0x42, 0xf2, 0x7c, 0x62, 0xde, 0x90, 0xda, 0xbe, 0x37, 0xf4, 0x74, 0x5d, 0xad, 0x72,
0xa4, 0xc3, 0x01, 0xde, 0x79, 0x2f, 0xc3, 0x31, 0x16, 0x98, 0x82, 0x10, 0x44, 0x2e, 0xcc, 0xff,
0x60, 0x93, 0x13, 0x62, 0x74, 0x99, 0xc3, 0x26, 0x91, 0xd2, 0xec, 0x09, 0x0a, 0xc1, 0x41, 0x1d,
0x3b, 0x4a, 0x88, 0xf5, 0x38, 0xb0, 0x05, 0x2a, 0x89, 0x8f, 0xbf, 0xb3, 0x84, 0x19, 0xa8, 0x42,
0xc9, 0x33, 0x34, 0x4b, 0xc2, 0xef, 0x42, 0x12, 0xa3, 0xbd, 0xad, 0x15, 0x98, 0x0b, 0x09, 0xc1,
0x20, 0x81, 0x92, 0xc7, 0x00, 0x5c, 0x31, 0x5b, 0x70, 0x15, 0xe2, 0x26, 0x8e, 0xcf, 0xb9, 0x01,
0x8f, 0x57, 0x39, 0xb9, 0x80, 0x0e, 0x2a, 0xb0, 0x24, 0xeb, 0x9d, 0x89, 0x85, 0x3a, 0x25, 0x67,
0xaa, 0xc7, 0xd7, 0x54, 0x8f, 0xff, 0x6b, 0x1e, 0x08, 0x8f, 0x90, 0x8c, 0x13, 0x30, 0xc8, 0x98,
0x33, 0x7e, 0x47, 0x99, 0x9d, 0x6e, 0x6b, 0x35, 0x89, 0x9e, 0xcb, 0xca, 0x87, 0xf5, 0x55, 0x51,
0x05, 0x61, 0x5f, 0x4e, 0x34, 0x35, 0x0b, 0x24, 0x74, 0x8a, 0x08, 0x4f, 0x40, 0xd9, 0x2b, 0xf4,
0x24, 0xa8, 0x7a, 0x9e, 0xec, 0x29, 0x44, 0xec, 0xbd, 0x90, 0x5b, 0x72, 0x6a, 0x22, 0x6d, 0xd8,
0x50, 0x8d, 0x23, 0x73, 0x44, 0x76, 0x99, 0x35, 0xb9, 0x99, 0x3e, 0x73, 0x07, 0x56, 0xdc, 0x70,
0x38, 0xf4, 0xa2, 0x08, 0x8d, 0x67, 0x47, 0xde, 0x27, 0xdd, 0x6d, 0xea, 0x33, 0xb8, 0x8b, 0xa8,
0xce, 0x56, 0x91, 0x3a, 0xa2, 0xa4, 0xca, 0x6c, 0x15, 0x59, 0x63, 0xfe, 0x3b, 0x07, 0x0d, 0x6e,
0x89, 0x54, 0x1c, 0x3c, 0x02, 0x11, 0x62, 0xdf, 0x18, 0x06, 0x06, 0xa7, 0xfd, 0xc9, 0xa2, 0xe0,
0xb7, 0x20, 0xdc, 0x6a, 0x87, 0x78, 0xb9, 0x0a, 0x82, 0x66, 0x3a, 0x08, 0x66, 0xa9, 0x8d, 0x87,
0x45, 0xd9, 0xe6, 0x48, 0x22, 0x04, 0x8e, 0x60, 0x23, 0x5d, 0xe1, 0xb4, 0x7f, 0xef, 0xc1, 0x52,
0x24, 0xf4, 0x54, 0x63, 0xdc, 0x7a, 0x9a, 0xb1, 0xb4, 0x81, 0xa5, 0x68, 0xcc, 0xcf, 0x05, 0xd8,
0xcc, 0xf2, 0x51, 0x05, 0xfb, 0x2d, 0x34, 0xe6, 0xca, 0xab, 0x6c, 0x02, 0xf7, 0xd2, 0x46, 0xca,
0x1c, 0xcc, 0xc2, 0x2b, 0xa3, 0x74, 0x25, 0x6e, 0xfd, 0x33, 0x0f, 0xf5, 0x34, 0xcd, 0xb5, 0x43,
0xd6, 0x5c, 0xd7, 0xc8, 0xcf, 0x77, 0x8d, 0xb9, 0xb1, 0xa7, 0xf0, 0x95, 0xb1, 0xa7, 0xf8, 0xb5,
0xb1, 0xa7, 0xf4, 0x4d, 0x63, 0xcf, 0xd2, 0xa2, 0xb1, 0x27, 0x5b, 0x37, 0xcb, 0x52, 0xde, 0x64,
0xdd, 0x9c, 0x39, 0xa8, 0xf2, 0x0d, 0x0e, 0x7a, 0x04, 0xeb, 0x6f, 0x1d, 0xdf, 0xa7, 0x4c, 0xdd,
0xa0, 0xdd, 0x8c, 0x17, 0x5d, 0x79, 0x2c, 0xc0, 0x72, 0x6b, 0x87, 0x81, 0x2f, 0xdf, 0x21, 0x15,
0xcb, 0x50, 0xd8, 0x19, 0x42, 0xe6, 0x03, 0xd8, 0xc8, 0x1c, 0x9d, 0x8d, 0xd1, 0x5a, 0x09, 0x7e,
0x2c, 0x67, 0xe9, 0xa5, 0xb9, 0x05, 0x1b, 0x4a, 0x8c, 0xf4, 0x75, 0x66, 0x1b, 0x36, 0xb3, 0x1b,
0x8b, 0x99, 0x15, 0x66, 0xcc, 0xfe, 0x82, 0x69, 0x67, 0xe1, 0x8b, 0x8f, 0x2b, 0xee, 0xf4, 0x7c,
0xac, 0xd5, 0xc1, 0x7b, 0xfe, 0x6c, 0xf2, 0xfa, 0x0f, 0xf4, 0xb3, 0x09, 0x3f, 0x25, 0xd2, 0x56,
0x9e, 0xe5, 0x9f, 0xdc, 0x59, 0xfc, 0xa1, 0x98, 0x70, 0x66, 0xbc, 0xfe, 0xa2, 0x23, 0x71, 0xf2,
0xbe, 0x92, 0xcd, 0xb5, 0x24, 0xd4, 0x52, 0x2b, 0x73, 0x1b, 0xb6, 0xba, 0x83, 0xf0, 0x2a, 0x29,
0x8b, 0xd6, 0xeb, 0x0c, 0x9a, 0xf3, 0x5b, 0x4a, 0xb3, 0x87, 0x89, 0xa9, 0x4a, 0x06, 0xbe, 0x7e,
0x41, 0x64, 0xb5, 0x9a, 0x0d, 0x56, 0xbf, 0x6e, 0xc3, 0x72, 0xca, 0x91, 0xa4, 0x0c, 0x85, 0xfd,
0x4e, 0x07, 0xdf, 0x3e, 0x06, 0x94, 0xcf, 0xce, 0x8f, 0x4e, 0x4f, 0x4e, 0x5f, 0xe2, 0x83, 0x07,
0x17, 0x87, 0x9d, 0xb3, 0x2e, 0x5f, 0xe4, 0xdb, 0x7f, 0x2b, 0x43, 0x35, 0x7e, 0x94, 0x90, 0xdf,
0xc1, 0x72, 0xca, 0x6d, 0xe4, 0x7b, 0x75, 0xeb, 0xa2, 0x38, 0x68, 0xdd, 0x58, 0xbc, 0xa9, 0x54,
0x78, 0x0d, 0xf5, 0xb4, 0xdb, 0xc8, 0x8d, 0x74, 0xb4, 0x65, 0xb8, 0xfd, 0x70, 0xcd, 0xae, 0x62,
0xf7, 0x04, 0x2a, 0xfa, 0x1d, 0x4b, 0x36, 0x17, 0x3f, 0xa6, 0x5b, 0x5b, 0x73, 0xb8, 0x3a, 0xfc,
0x14, 0xaa, 0xf1, 0xe3, 0x94, 0x24, 0xa9, 0x92, 0xcf, 0xdd, 0x56, 0x73, 0x7e, 0x43, 0x9d, 0xdf,
0x07, 0x98, 0x3d, 0x09, 0x49, 0xf3, 0xba, 0xd7, 0x69, 0x6b, 0x7b, 0xc1, 0x8e, 0x62, 0xf1, 0x1c,
0x8c, 0xc4, 0x13, 0x8f, 0x24, 0x2a, 0x76, 0xe6, 0xe5, 0xd8, 0x6a, 0x2d, 0xda, 0x9a, 0x29, 0x12,
0xcf, 0xc9, 0x64, 0xf6, 0xa8, 0x4c, 0x4f, 0xd3, 0xb1, 0x22, 0xf3, 0x23, 0xf5, 0x1e, 0x94, 0xd5,
0x70, 0x4c, 0x36, 0x14, 0x51, 0x7a, 0x7e, 0x6e, 0x6d, 0x66, 0x61, 0x75, 0xf2, 0x10, 0x8c, 0x44,
0x47, 0x8f, 0xe5, 0x9f, 0xef, 0xf2, 0xb1, 0x17, 0xb2, 0x6d, 0xef, 0x7e, 0x8e, 0xbc, 0x80, 0x5a,
0x72, 0x38, 0x23, 0xb1, 0xaa, 0xf3, 0x13, 0x5b, 0xac, 0xc4, 0xdc, 0x18, 0x85, 0x7c, 0x4e, 0x61,
0x25, 0x3b, 0x63, 0xdf, 0xb8, 0xa6, 0x31, 0xa4, 0x83, 0xeb, 0x9a, 0x7e, 0xf3, 0x58, 0xfe, 0xd5,
0x75, 0x2e, 0xff, 0xa5, 0x22, 0x24, 0x11, 0x08, 0x9a, 0xc3, 0x5a, 0x0a, 0x93, 0xe7, 0x76, 0x72,
0x28, 0x4b, 0x17, 0x1a, 0xd9, 0x34, 0x26, 0x3f, 0x6a, 0xe2, 0xc5, 0xa9, 0xdf, 0xba, 0x79, 0xed,
0xbe, 0x64, 0xdc, 0x5b, 0x12, 0xff, 0xc4, 0x3d, 0xfc, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc2,
0xc3, 0x5e, 0x39, 0x96, 0x13, 0x00, 0x00,
}

@ -4,6 +4,8 @@ package lnrpc;
service Lightning {
rpc WalletBalance(WalletBalanceRequest) returns (WalletBalanceResponse);
rpc ChannelBalance(ChannelBalanceRequest) returns (ChannelBalanceResponse);
rpc SendMany(SendManyRequest) returns (SendManyResponse);
rpc SendCoins(SendCoinsRequest) returns (SendCoinsResponse);
rpc NewAddress(NewAddressRequest) returns (NewAddressResponse);
@ -222,6 +224,12 @@ message WalletBalanceResponse {
double balance = 1;
}
message ChannelBalanceRequest {
}
message ChannelBalanceResponse {
int64 balance = 1;
}
message RoutingTableLink {
string id1 = 1;
string id2 = 2;

@ -262,14 +262,11 @@ type networkHarness struct {
watchRequests chan *watchRequest
}
// newNetworkHarness creates a new network test harness given an already
// running instance of btcd's rpctest harness. Any extra command line flags
// which should be passed to create lnd instance should be formatted properly
// in the lndArgs slice (--arg=value).
// newNetworkHarness creates a new network test harness.
// TODO(roasbeef): add option to use golang's build library to a binary of the
// current repo. This'll save developers from having to manually `go install`
// within the repo each time before changes.
func newNetworkHarness(lndArgs []string) (*networkHarness, error) {
// within the repo each time before changes
func newNetworkHarness() (*networkHarness, error) {
return &networkHarness{
activeNodes: make(map[int]*lightningNode),
seenTxns: make(chan wire.ShaHash),
@ -277,7 +274,11 @@ func newNetworkHarness(lndArgs []string) (*networkHarness, error) {
}, nil
}
func (n *networkHarness) InitializeSeedNodes(r *rpctest.Harness) error {
// InitializeSeedNodes initialized alice and bob nodes given an already
// running instance of btcd's rpctest harness and extra command line flags,
// which should be formatted properly - "--arg=value".
func (n *networkHarness) InitializeSeedNodes(r *rpctest.Harness, lndArgs []string) error {
nodeConfig := r.RPCConfig()
n.netParams = r.ActiveNet
@ -285,11 +286,11 @@ func (n *networkHarness) InitializeSeedNodes(r *rpctest.Harness) error {
n.rpcConfig = nodeConfig
var err error
n.Alice, err = newLightningNode(&nodeConfig, nil)
n.Alice, err = newLightningNode(&nodeConfig, lndArgs)
if err != nil {
return err
}
n.Bob, err = newLightningNode(&nodeConfig, nil)
n.Bob, err = newLightningNode(&nodeConfig, lndArgs)
if err != nil {
return err
}
@ -511,7 +512,7 @@ func (n *networkHarness) WaitForTxBroadcast(txid wire.ShaHash) {
}
// OpenChannel attemps to open a channel between srcNode and destNode with the
// passed channel funding paramters.
// passed channel funding parameters.
func (n *networkHarness) OpenChannel(ctx context.Context,
srcNode, destNode *lightningNode, amt btcutil.Amount,
numConfs uint32) (lnrpc.Lightning_OpenChannelClient, error) {
@ -521,6 +522,7 @@ func (n *networkHarness) OpenChannel(ctx context.Context,
LocalFundingAmount: int64(amt),
NumConfs: numConfs,
}
respStream, err := srcNode.OpenChannel(ctx, openReq)
if err != nil {
return nil, fmt.Errorf("unable to open channel between "+
@ -634,18 +636,15 @@ func (n *networkHarness) AssertChannelExists(ctx context.Context,
// DumpLogs reads the current logs generated by the passed node, and returns
// the logs as a single string. This function is useful for examining the logs
// of a particular node in the case of a test failure.
// Logs from lightning node being generated with delay - you should
// add time.Sleep() in order to get all logs.
func (n *networkHarness) DumpLogs(node *lightningNode) (string, error) {
logFile := fmt.Sprintf("%v/simnet/lnd.log", node.cfg.LogDir)
f, err := os.Open(logFile)
if err != nil {
return "", err
}
defer f.Close()
logs, err := ioutil.ReadAll(f)
buf, err := ioutil.ReadFile(logFile)
if err != nil {
return "", err
}
return string(logs), nil
return string(buf), nil
}

@ -385,6 +385,20 @@ func (r *rpcServer) WalletBalance(ctx context.Context,
return &lnrpc.WalletBalanceResponse{balance.ToBTC()}, nil
}
func (r *rpcServer) ChannelBalance(ctx context.Context,
in *lnrpc.ChannelBalanceRequest) (*lnrpc.ChannelBalanceResponse, error) {
var balance btcutil.Amount
for _, peer := range r.server.Peers() {
for _, snapshot := range peer.ChannelSnapshots() {
balance += snapshot.LocalBalance
}
}
return &lnrpc.ChannelBalanceResponse{Balance: int64(balance)}, nil
}
// PendingChannels returns a list of all the channels that are currently
// considered "pending". A channel is pending if it has finished the funding
// workflow and is waiting for confirmations for the funding txn, or is in the