lnrpc: add cursory REST support to the RPC server

This commit adds a REST interface to the existing gRPC server by
employing a simple http proxy auto-generated from the existing protobuf
files. Currently full-support for any streaming RPC’s are currently
untested. In addition to auto-generating a REST proxy server, a
swagger.json is also generated which allows for gRPC-like native
objects with higher-level clients, and also for auto-generated
documentation.

Due to limitations with accepting raw byte strings as parameters, some
RPC’s have been modified to take both raw-bytes and string arguments.
Additionally a new RPC has been added ‘NewWitnessAddress’ since the
proxy doesn’t currently support enum-based arguments.

Currently the proxy server is embedded within the daemon as an active
HTTP server, however we may want to package the proxy server as a
separate binary in the future. Similarly, we may want to add additional
configuration information which controls the optional inclusion of the
REST proxy.

Atm, just like the current gRPC interface, the REST API is fully
unauthenticated. Before moving to an initial alpha release after making
the necessary changes to meet the spec drafted in Milan, authentication
of the RPC interfaces will be addressed.
This commit is contained in:
Olaoluwa Osuntokun
2016-10-15 14:38:47 -07:00
parent bea555e61d
commit 566cd86a1d
8 changed files with 2667 additions and 293 deletions

28
lnd.go
View File

@@ -1,6 +1,7 @@
package main
import (
"context"
"encoding/hex"
"fmt"
"io/ioutil"
@@ -14,11 +15,13 @@ import (
"google.golang.org/grpc"
proxy "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/lightningnetwork/lnd/chainntnfs/btcdnotify"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
"github.com/roasbeef/btcrpcclient"
)
@@ -175,8 +178,9 @@ func lndMain() error {
grpcServer := grpc.NewServer(opts...)
lnrpc.RegisterLightningServer(grpcServer, server.rpcServer)
// Finally, start the grpc server listening for HTTP/2 connections.
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", loadedConfig.RPCPort))
// Next, Start the grpc server listening for HTTP/2 connections.
grpcEndpoint := fmt.Sprintf("localhost:%d", loadedConfig.RPCPort)
lis, err := net.Listen("tcp", grpcEndpoint)
if err != nil {
fmt.Printf("failed to listen: %v", err)
return err
@@ -186,6 +190,26 @@ func lndMain() error {
grpcServer.Serve(lis)
}()
// Finally, start the REST proxy for our gRPC server above.
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := proxy.NewServeMux()
swaggerPattern := proxy.MustPattern(proxy.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "swagger"}, ""))
// TODO(roasbeef): accept path to swagger file as command-line option
mux.Handle("GET", swaggerPattern, func(w http.ResponseWriter, r *http.Request, p map[string]string) {
http.ServeFile(w, r, "lnrpc/rpc.swagger.json")
})
proxyOpts := []grpc.DialOption{grpc.WithInsecure()}
err = lnrpc.RegisterLightningHandlerFromEndpoint(ctx, mux, grpcEndpoint, proxyOpts)
if err != nil {
return err
}
go func() {
rpcsLog.Infof("gRPC proxy started")
http.ListenAndServe(":8080", mux)
}()
// Wait for shutdown signal from either a graceful server stop or from
// the interrupt handler.
<-shutdownChannel