Skip to content

Commit

Permalink
WIP: Implement gRPC
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenroose committed Mar 29, 2018
1 parent e70a0fe commit d83d4ab
Show file tree
Hide file tree
Showing 10 changed files with 7,097 additions and 191 deletions.
4,101 changes: 4,101 additions & 0 deletions btcrpc/btcrpc.pb.go

Large diffs are not rendered by default.

684 changes: 684 additions & 0 deletions btcrpc/btcrpc.proto

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions btcrpc/generate-protos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

# Generate the protos.
protoc -I/usr/local/include -I. \
-I$GOPATH/src \
--go_out=plugins=grpc:. \
btcrpc.proto

176 changes: 176 additions & 0 deletions btcrpc/rpcutils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package btcrpc

import (
"bytes"
"time"

"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
)

// NewBlockLocatorHash creates a new BlockLocator using the given block hash.
func NewBlockLocatorHash(hash *chainhash.Hash) *BlockLocator {
return &BlockLocator{
Locator: &BlockLocator_Hash{
Hash: hash[:],
},
}
}

// NewBlockLocatorHeight creates a new BlockLocator using the given block height.
func NewBlockLocatorHeight(height int32) *BlockLocator {
return &BlockLocator{
Locator: &BlockLocator_Height{
Height: height,
},
}
}

// GENERAL MESSAGE UTILITIES //

func (i *BlockInfo) Header() *wire.BlockHeader {
if i == nil {
return nil
}

var prevBlockHash chainhash.Hash
if h, _ := chainhash.NewHash(i.PreviousBlock); h != nil {
prevBlockHash = *h
}

var merkleRoot chainhash.Hash
if h, _ := chainhash.NewHash(i.MerkleRoot); h != nil {
merkleRoot = *h
}

return &wire.BlockHeader{
Version: i.Version,
PrevBlock: prevBlockHash,
MerkleRoot: merkleRoot,
Timestamp: time.Unix(i.Time, 0),
Bits: i.Bits,
Nonce: i.Nonce,
}
}

func (t *Transaction) MsgTx() *wire.MsgTx {
if t == nil {
return nil
}

var msgTx wire.MsgTx
buf := bytes.NewBuffer(t.Serialized)
if err := msgTx.Deserialize(buf); err != nil {
return nil
}
return &msgTx
}

func (t *Transaction) UtilTx() *btcutil.Tx {
if t == nil {
return nil
}

tx, _ := btcutil.NewTxFromBytes(t.Serialized)
return tx
}

func (b *Block) MsgBlock() *wire.MsgBlock {
if b == nil {
return nil
}

var txs []*wire.MsgTx
if len(b.Transactions) > 0 {
txs = make([]*wire.MsgTx, len(b.Transactions))
for i, t := range b.Transactions {
txs[i] = t.MsgTx()
}
}

return &wire.MsgBlock{
Header: *b.Info.Header(),
Transactions: txs,
}
}

func (b *Block) UtilBlock() *btcutil.Block {
if b == nil {
return nil
}

return btcutil.NewBlock(b.MsgBlock())
}

// RPC MESSAGE UTILITIES //

func (r *GetRawBlockResponse) GetMsgBlock() *wire.MsgBlock {
if r == nil {
return nil
}

var msgBlock wire.MsgBlock
buf := bytes.NewBuffer(r.Block)
_ = msgBlock.Deserialize(buf)
return &msgBlock
}

func (r *GetRawBlockResponse) GetUtilBlock() *btcutil.Block {
if r == nil {
return nil
}

block, _ := btcutil.NewBlockFromBytes(r.Block)
return block
}

func (r *GetRawMempoolResponse) GetMsgTxs() []*wire.MsgTx {
if r == nil {
return nil
}

txs := make([]*wire.MsgTx, len(r.Transactions))
var buf *bytes.Buffer
for i, encoded := range r.Transactions {
var tx wire.MsgTx
buf = bytes.NewBuffer(encoded)
_ = tx.Deserialize(buf)
txs[i] = &tx
}

return txs
}

func (r *GetRawMempoolResponse) GetUtilTxs() []*btcutil.Tx {
if r == nil {
return nil
}

txs := make([]*btcutil.Tx, len(r.Transactions))
for i, encoded := range r.Transactions {
txs[i], _ = btcutil.NewTxFromBytes(encoded)
}

return txs
}

func (r *GetRawTransactionResponse) GetMsgTx() *wire.MsgTx {
if r == nil {
return nil
}

var tx wire.MsgTx
buf := bytes.NewBuffer(r.Transaction)
_ = tx.Deserialize(buf)
return &tx
}

func (r *GetRawTransactionResponse) GetUtilTx() *btcutil.Tx {
if r == nil {
return nil
}

tx, _ := btcutil.NewTxFromBytes(r.Transaction)
return tx
}
88 changes: 88 additions & 0 deletions grpc-progress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@


All current methods and the new methods that cover them:

- [x] addnode: ConnectPeer
- [x] createrawtransaction: deprecated
- [x] debuglevel: SetDebugLevel
- [x] decoderawtransaction: deprecated
- [x] decodescript: deprecated
- [x] generate: GenerateBlocks
- [x] getaddednodeinfo: GetPeers
- [x] getbestblock: GetBestBlockInfo
- [x] getbestblockhash: GetBestBlockInfo
- [x] getblock: GetBlock
- [ ] **getblockchaininfo: could add to GetNetworkInfo**
- [x] getblockcount: GetBestBlockInfo
- [x] getblockhash: GetBlockInfo
- [x] getblockheader: GetBlockInfo
- [ ] **getblocktemplate**: see below
- [x] getconnectioncount: GetSystemInfo
- [x] getcurrentnet: GetNetworkInfo
- [x] getdifficulty: GetNetworkInfo or GetMiningInfo
- [x] getgenerate: GetGenerate
- [x] gethashespersec: GetHashRate (or GetNetworkInfo or GetMiningInfo for network HR)
- [ ] **getheaders**
- [x] getinfo: GetSystemInfo and GetNetworkInfo
- [x] getmempoolinfo: GetMempoolInfo
- [x] getmininginfo: GetMiningInfo
- [x] getnettotals: GetSystemInfo
- [x] getnetworkhashps: GetNetworkInfo or GetMiningInfo
- [x] getpeerinfo: GetPeers
- [x] getrawmempool: GetMempool and GetRawMempool
- [x] getrawtransaction: GetRawTransactions
- [x] gettxout: just use GetTransaction
- [x] help: deprecated
- [x] node: ConnectPeer, DisconnectPeer, GetPeers
- [x] ping: deprecated
- [ ] **searchrawtransactions: how is this different than rescan?**
- [x] sendrawtransaction: SubmitTransactions
- [x] setgenerate: SetGenerate
- [x] stop: StopDaemon
- [x] submitblock: SubmitBlock
- [x] uptime: GetSystemInfoo
- [x] validateaddress: deprecated
- [ ] **verifychain**: what's the use case of this?
- [x] verifymessage: deprecated
- [x] version: GetSystemInfo

There are WebSocket-only commands:
- [x] loadtxfilter
- [x] notifyblocks: SubscsribeBlocks
- [x] notifynewtransactions: SubscribeTransactions
- [x] notifyreceived: potentially SubscribeTransactions
- [x] notifyspent: potentially SubscribeTransactions
- [x] rescan: RescanTransactions
- [ ] **rescanblocks: why is this useful?**
- [x] session: deprecated
- [x] stopnotifyblocks: SubscribeBlocks
- [x] stopnotifynewtransactions: SubscribeTransaction
- [x] stopnotifyspent: potentially SubscribeTransaction
- [x] stopnotifyreceived: potentially SubscribeTransaction

Additions to the API that did not exist before:
- GetAddressTransactions
- GetAddressUnspentOutputs

These are mentioned in the code as not implemented, but desired:
- estimatefee
- estimatepriority
- getchaintips
- getmempoolentry: have GetRawMempool to get all
- getnetworkinfo: GetNetworkInfo
- getwork
- invalidateblock
- preciousblock
- reconsiderblock

Other TODOs:

- [x] implement listening
- [ ] add GRPC dependenies (waiting for dep PR)
- [ ] correct error handling
- [ ] REST proxy? (cfr lnd)
- [ ] in case it will replace the JSON-RPC interface: find a solution for
getblocktemplate (maybe separate small HTTP server in the mining package
behind `--getblocktemplate <interface>`)
- [ ] update rpcclient
- [ ] update btcctl

0 comments on commit d83d4ab

Please sign in to comment.