rpcserver: add REST workarounds, implement new RPC calls
This commit adds a few workarounds in order to concurrently support the REST proxy as well as the regular gRPC interface. Additionally, concrete support for the following RPC calls has been added: GetTransactions, SubscriptTransactions, SubscribeInvoices, and NewWitnessAddress.
This commit is contained in:
parent
566cd86a1d
commit
7b953c9c61
@ -219,7 +219,7 @@ func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet wire.BitcoinNet)
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the head first.
|
// Write the header first.
|
||||||
n, err := w.Write(hw.Bytes())
|
n, err := w.Write(hw.Bytes())
|
||||||
totalBytes += n
|
totalBytes += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
3
peer.go
3
peer.go
@ -1155,6 +1155,9 @@ func (p *peer) handleUpstreamMsg(state *commitmentState, msg lnwire.Message) {
|
|||||||
p.Disconnect()
|
p.Disconnect()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(roasbeef): add pre-image to DB in order to swipe
|
||||||
|
// repeated r-values
|
||||||
case *lnwire.CommitSignature:
|
case *lnwire.CommitSignature:
|
||||||
// We just received a new update to our local commitment chain,
|
// We just received a new update to our local commitment chain,
|
||||||
// validate this new commitment, closing the link if invalid.
|
// validate this new commitment, closing the link if invalid.
|
||||||
|
146
rpcserver.go
146
rpcserver.go
@ -167,7 +167,22 @@ func (r *rpcServer) NewAddress(ctx context.Context,
|
|||||||
return &lnrpc.NewAddressResponse{Address: addr.String()}, nil
|
return &lnrpc.NewAddressResponse{Address: addr.String()}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewWitnessAddress returns a new native witness address under the control of
|
||||||
|
// the local wallet.
|
||||||
|
func (r *rpcServer) NewWitnessAddress(ctx context.Context,
|
||||||
|
in *lnrpc.NewWitnessAddressRequest) (*lnrpc.NewAddressResponse, error) {
|
||||||
|
|
||||||
|
addr, err := r.server.lnwallet.NewAddress(lnwallet.WitnessPubKey, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rpcsLog.Infof("[newaddress] addr=%v", addr.String())
|
||||||
|
return &lnrpc.NewAddressResponse{Address: addr.String()}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ConnectPeer attempts to establish a connection to a remote peer.
|
// ConnectPeer attempts to establish a connection to a remote peer.
|
||||||
|
// TODO(roasbeef): also return pubkey and/or identity hash?
|
||||||
func (r *rpcServer) ConnectPeer(ctx context.Context,
|
func (r *rpcServer) ConnectPeer(ctx context.Context,
|
||||||
in *lnrpc.ConnectPeerRequest) (*lnrpc.ConnectPeerResponse, error) {
|
in *lnrpc.ConnectPeerRequest) (*lnrpc.ConnectPeerResponse, error) {
|
||||||
|
|
||||||
@ -674,13 +689,29 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
|
|||||||
func (r *rpcServer) LookupInvoice(ctx context.Context,
|
func (r *rpcServer) LookupInvoice(ctx context.Context,
|
||||||
req *lnrpc.PaymentHash) (*lnrpc.Invoice, error) {
|
req *lnrpc.PaymentHash) (*lnrpc.Invoice, error) {
|
||||||
|
|
||||||
if len(req.RHash) != 32 {
|
var (
|
||||||
return nil, fmt.Errorf("payment hash must be exactly "+
|
payHash [32]byte
|
||||||
"32 bytes, is instead %v", len(req.RHash))
|
rHash []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// If the RHash as a raw string was provided, then decode that and use
|
||||||
|
// that directly. Otherwise, we use the raw bytes provided.
|
||||||
|
if req.RHashStr != "" {
|
||||||
|
rHash, err = hex.DecodeString(req.RHashStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rHash = req.RHash
|
||||||
}
|
}
|
||||||
|
|
||||||
var payHash [32]byte
|
// Ensure that the payment hash is *exactly* 32-bytes.
|
||||||
copy(payHash[:], req.RHash)
|
if len(rHash) != 0 && len(rHash) != 32 {
|
||||||
|
return nil, fmt.Errorf("payment hash must be exactly "+
|
||||||
|
"32 bytes, is instead %v", len(rHash))
|
||||||
|
}
|
||||||
|
copy(payHash[:], rHash)
|
||||||
|
|
||||||
rpcsLog.Tracef("[lookupinvoice] searching for invoice %x", payHash[:])
|
rpcsLog.Tracef("[lookupinvoice] searching for invoice %x", payHash[:])
|
||||||
|
|
||||||
@ -731,6 +762,109 @@ func (r *rpcServer) ListInvoices(ctx context.Context,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubscribeInvoices returns a uni-directional stream (sever -> client) for
|
||||||
|
// notifying the client of newly added/settled invoices.
|
||||||
|
func (r *rpcServer) SubscribeInvoices(req *lnrpc.InvoiceSubscription,
|
||||||
|
updateStream lnrpc.Lightning_SubscribeInvoicesServer) error {
|
||||||
|
|
||||||
|
invoiceClient := r.server.invoices.SubscribeNotifications()
|
||||||
|
defer invoiceClient.Cancel()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
// TODO(roasbeef): include newly added invoices?
|
||||||
|
case settledInvoice := <-invoiceClient.SettledInvoices:
|
||||||
|
invoice := &lnrpc.Invoice{
|
||||||
|
Memo: string(settledInvoice.Memo[:]),
|
||||||
|
Receipt: settledInvoice.Receipt[:],
|
||||||
|
RPreimage: settledInvoice.Terms.PaymentPreimage[:],
|
||||||
|
Value: int64(settledInvoice.Terms.Value),
|
||||||
|
Settled: settledInvoice.Terms.Settled,
|
||||||
|
}
|
||||||
|
if err := updateStream.Send(invoice); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case <-r.quit:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubscribeTransactions creates a uni-directional stream (server -> client) in
|
||||||
|
// which any newly discovered transactions relevant to the wallet are sent
|
||||||
|
// over.
|
||||||
|
func (r *rpcServer) SubscribeTransactions(req *lnrpc.GetTransactionsRequest,
|
||||||
|
updateStream lnrpc.Lightning_SubscribeTransactionsServer) error {
|
||||||
|
|
||||||
|
txClient, err := r.server.lnwallet.SubscribeTransactions()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer txClient.Cancel()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case tx := <-txClient.ConfirmedTransactions():
|
||||||
|
detail := &lnrpc.Transaction{
|
||||||
|
TxHash: tx.Hash.String(),
|
||||||
|
Amount: tx.Value.ToBTC(),
|
||||||
|
NumConfirmations: tx.NumConfirmations,
|
||||||
|
BlockHash: tx.BlockHash.String(),
|
||||||
|
TimeStamp: tx.Timestamp,
|
||||||
|
TotalFees: tx.TotalFees,
|
||||||
|
}
|
||||||
|
if err := updateStream.Send(detail); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case tx := <-txClient.UnconfirmedTransactions():
|
||||||
|
detail := &lnrpc.Transaction{
|
||||||
|
TxHash: tx.Hash.String(),
|
||||||
|
Amount: tx.Value.ToBTC(),
|
||||||
|
TimeStamp: tx.Timestamp,
|
||||||
|
TotalFees: tx.TotalFees,
|
||||||
|
}
|
||||||
|
if err := updateStream.Send(detail); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case <-r.quit:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTransactions returns a list of describing all the known transactions
|
||||||
|
// relevant to the wallet.
|
||||||
|
func (r *rpcServer) GetTransactions(context.Context,
|
||||||
|
*lnrpc.GetTransactionsRequest) (*lnrpc.TransactionDetails, error) {
|
||||||
|
|
||||||
|
transactions, err := r.server.lnwallet.ListTransactionDetails()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
txDetails := &lnrpc.TransactionDetails{
|
||||||
|
Transactions: make([]*lnrpc.Transaction, len(transactions)),
|
||||||
|
}
|
||||||
|
for i, tx := range transactions {
|
||||||
|
txDetails.Transactions[i] = &lnrpc.Transaction{
|
||||||
|
TxHash: tx.Hash.String(),
|
||||||
|
Amount: tx.Value.ToBTC(),
|
||||||
|
NumConfirmations: tx.NumConfirmations,
|
||||||
|
BlockHash: tx.BlockHash.String(),
|
||||||
|
TimeStamp: tx.Timestamp,
|
||||||
|
TotalFees: tx.TotalFees,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return txDetails, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShowRoutingTable returns a table-formatted dump of the known routing
|
||||||
|
// topology from the PoV of the source node.
|
||||||
func (r *rpcServer) ShowRoutingTable(ctx context.Context,
|
func (r *rpcServer) ShowRoutingTable(ctx context.Context,
|
||||||
in *lnrpc.ShowRoutingTableRequest) (*lnrpc.ShowRoutingTableResponse, error) {
|
in *lnrpc.ShowRoutingTableRequest) (*lnrpc.ShowRoutingTableResponse, error) {
|
||||||
|
|
||||||
@ -738,7 +872,7 @@ func (r *rpcServer) ShowRoutingTable(ctx context.Context,
|
|||||||
|
|
||||||
rtCopy := r.server.routingMgr.GetRTCopy()
|
rtCopy := r.server.routingMgr.GetRTCopy()
|
||||||
|
|
||||||
channels := make([]*lnrpc.RoutingTableLink, 0)
|
var channels []*lnrpc.RoutingTableLink
|
||||||
for _, channel := range rtCopy.AllChannels() {
|
for _, channel := range rtCopy.AllChannels() {
|
||||||
channels = append(channels,
|
channels = append(channels,
|
||||||
&lnrpc.RoutingTableLink{
|
&lnrpc.RoutingTableLink{
|
||||||
|
@ -48,7 +48,6 @@ type server struct {
|
|||||||
bio lnwallet.BlockChainIO
|
bio lnwallet.BlockChainIO
|
||||||
lnwallet *lnwallet.LightningWallet
|
lnwallet *lnwallet.LightningWallet
|
||||||
|
|
||||||
// TODO(roasbeef): add to constructor
|
|
||||||
fundingMgr *fundingManager
|
fundingMgr *fundingManager
|
||||||
chanDB *channeldb.DB
|
chanDB *channeldb.DB
|
||||||
|
|
||||||
|
@ -134,6 +134,7 @@ out:
|
|||||||
midStageOutputs <- immatureUtxo
|
midStageOutputs <- immatureUtxo
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
// TODO(roasbeef): rename to preschool and kindergarden
|
||||||
case midUtxo := <-midStageOutputs:
|
case midUtxo := <-midStageOutputs:
|
||||||
// The transaction creating the output has been
|
// The transaction creating the output has been
|
||||||
// created, so we move it from early stage to
|
// created, so we move it from early stage to
|
||||||
|
Loading…
Reference in New Issue
Block a user