From c5cc96a52476eededce633bd49ee1110eaa09fb4 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 5 Jul 2016 18:57:08 -0700 Subject: [PATCH] lnd: implement the getinfo RPC call --- fundingmanager.go | 29 +++++++++++++++++++++++++++++ rpcserver.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/fundingmanager.go b/fundingmanager.go index 10ecedcf..55452a48 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -113,6 +113,10 @@ type fundingManager struct { // related to funding workflow from outside peers. fundingMsgs chan interface{} + // queries is a channel which receives requests to query the internal + // state of the funding manager. + queries chan interface{} + // fundingRequests is a channel used to recieve channel initiation // requests from a local sub-system within the daemon. fundingRequests chan *initFundingMsg @@ -129,6 +133,7 @@ func newFundingManager(w *lnwallet.LightningWallet) *fundingManager { wallet: w, fundingMsgs: make(chan interface{}, msgBufferSize), fundingRequests: make(chan *initFundingMsg, msgBufferSize), + queries: make(chan interface{}, 1), quit: make(chan struct{}), } } @@ -164,6 +169,21 @@ func (f *fundingManager) Stop() error { return nil } +type numPendingReq struct { + resp chan uint32 +} + +// NumPendingChannels returns the number of pending channels currently +// progressing through the reservation workflow. +func (f *fundingManager) NumPendingChannels() uint32 { + resp := make(chan uint32, 1) + + req := &numPendingReq{resp} + f.queries <- req + + return <-resp +} + // reservationCoordinator is the primary goroutine tasked with progressing the // funding workflow between the wallet, and any outside peers or local callers. // @@ -187,6 +207,15 @@ out: } case req := <-f.fundingRequests: f.handleInitFundingMsg(req) + case req := <-f.queries: + switch msg := req.(type) { + case *numPendingReq: + var numPending uint32 + for _, peerChannels := range f.activeReservations { + numPending += uint32(len(peerChannels)) + } + msg.resp <- numPending + } case <-f.quit: break out } diff --git a/rpcserver.go b/rpcserver.go index 5a675f63..eea87422 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -245,6 +245,36 @@ func (r *rpcServer) CloseChannel(ctx context.Context, return &lnrpc.CloseChannelResponse{resp}, nil } +// GetInfo serves a request to the "getinfo" RPC call. This call returns +// general information concerning the lightning node including it's LN ID, +// identity address, and information concerning the number of open+pending +// channels. +func (r *rpcServer) GetInfo(ctx context.Context, + in *lnrpc.GetInfoRequest) (*lnrpc.GetInfoResponse, error) { + + var activeChannels uint32 + serverPeers := r.server.Peers() + for _, serverPeer := range serverPeers { + activeChannels += uint32(len(serverPeer.ChannelSnapshots())) + } + + pendingChannels := r.server.fundingMgr.NumPendingChannels() + + idPub := r.server.identityPriv.PubKey().SerializeCompressed() + idAddr, err := btcutil.NewAddressPubKeyHash(btcutil.Hash160(idPub), activeNetParams) + if err != nil { + return nil, err + } + + return &lnrpc.GetInfoResponse{ + LightningId: hex.EncodeToString(r.server.lightningID[:]), + IdentityAddress: idAddr.String(), + NumPendingChannels: pendingChannels, + NumActiveChannels: activeChannels, + NumPeers: uint32(len(serverPeers)), + }, nil +} + // ListPeers returns a verbose listing of all currently active peers. func (r *rpcServer) ListPeers(ctx context.Context, in *lnrpc.ListPeersRequest) (*lnrpc.ListPeersResponse, error) {