From fd4073e5444f033aecb190c7ecc4cda7ddb3cc9f Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Wed, 13 Sep 2017 00:36:08 +0200 Subject: [PATCH] getblock verbosity --- bitcoinrpc.go | 57 ++++++++++++++++++++++++++++++++++++++------------- blockbook.go | 34 ++++++++++-------------------- types.go | 6 +++++- 3 files changed, 59 insertions(+), 38 deletions(-) diff --git a/bitcoinrpc.go b/bitcoinrpc.go index 5617175a..489d7457 100644 --- a/bitcoinrpc.go +++ b/bitcoinrpc.go @@ -70,16 +70,21 @@ type cmdGetBlock struct { Method string `json:"method"` Params struct { BlockHash string `json:"blockhash"` - Verbose bool `json:"verbose"` + Verbosity int `json:"verbosity"` } `json:"params"` } -type resGetBlock struct { +type resGetBlockRaw struct { Error *RPCError `json:"error"` Result string `json:"result"` } -type resGetBlockVerbose struct { +type resGetBlockThin struct { + Error *RPCError `json:"error"` + Result ThinBlock `json:"result"` +} + +type resGetBlockFull struct { Error *RPCError `json:"error"` Result Block `json:"result"` } @@ -180,7 +185,7 @@ func (b *BitcoinRPC) GetBlockHeader(hash string) (*BlockHeader, error) { // GetBlock returns block with given hash. func (b *BitcoinRPC) GetBlock(hash string) (*Block, error) { if b.Parser == nil { - return b.GetBlockVerbose(hash) + return b.GetBlockFull(hash) } header, err := b.GetBlockHeader(hash) if err != nil { @@ -200,12 +205,12 @@ func (b *BitcoinRPC) GetBlock(hash string) (*Block, error) { // GetBlockRaw returns block with given hash as bytes. func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) { - log.Printf("rpc: getblock (verbose=false) %v", hash) + log.Printf("rpc: getblock (verbosity=0) %v", hash) - res := resGetBlock{} + res := resGetBlockRaw{} req := cmdGetBlock{Method: "getblock"} req.Params.BlockHash = hash - req.Params.Verbose = false + req.Params.Verbosity = 0 err := b.call(&req, &res) if err != nil { @@ -217,15 +222,15 @@ func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) { return hex.DecodeString(res.Result) } -// GetBlockVerbose returns block with given hash by downloading block +// GetBlockList returns block with given hash by downloading block // transactions one by one. -func (b *BitcoinRPC) GetBlockVerbose(hash string) (*Block, error) { - log.Printf("rpc: getblock (verbose=true) %v", hash) +func (b *BitcoinRPC) GetBlockList(hash string) (*Block, error) { + log.Printf("rpc: getblock (verbosity=1) %v", hash) - res := resGetBlockVerbose{} + res := resGetBlockThin{} req := cmdGetBlock{Method: "getblock"} req.Params.BlockHash = hash - req.Params.Verbose = true + req.Params.Verbosity = 1 err := b.call(&req, &res) if err != nil { @@ -235,12 +240,36 @@ func (b *BitcoinRPC) GetBlockVerbose(hash string) (*Block, error) { return nil, res.Error } - for _, txid := range res.Result.Txids { + txs := make([]Tx, len(res.Result.Txids)) + for i, txid := range res.Result.Txids { tx, err := b.GetTransaction(txid) if err != nil { return nil, err } - res.Result.Txs = append(res.Result.Txs, tx) + txs[i] = *tx + } + block := &Block{ + BlockHeader: res.Result.BlockHeader, + Txs: txs, + } + return block, nil +} + +// GetBlockFull returns block with given hash. +func (b *BitcoinRPC) GetBlockFull(hash string) (*Block, error) { + log.Printf("rpc: getblock (verbosity=2) %v", hash) + + res := resGetBlockFull{} + req := cmdGetBlock{Method: "getblock"} + req.Params.BlockHash = hash + req.Params.Verbosity = 2 + err := b.call(&req, &res) + + if err != nil { + return nil, err + } + if res.Error != nil { + return nil, res.Error } return &res.Result, nil } diff --git a/blockbook.go b/blockbook.go index 83a317ff..bd302451 100644 --- a/blockbook.go +++ b/blockbook.go @@ -42,7 +42,8 @@ type Indexer interface { func (b *Block) GetAllAddresses(outpoints Outpoints) (map[string][]string, error) { addrs := make(map[string][]string, 0) // Address to a list of txids. - for _, tx := range b.Txs { + for i, _ := range b.Txs { + tx := &b.Txs[i] ta, err := b.GetTxAddresses(outpoints, tx) if err != nil { return nil, err @@ -92,9 +93,9 @@ func (b *Block) GetTxAddresses(outpoints Outpoints, tx *Tx) (map[string]struct{} func (b *Block) GetAddress(txid string, vout uint32) (string, error) { var t *Tx - for _, tx := range b.Txs { - if tx.Txid == txid { - t = tx + for i, _ := range b.Txs { + if b.Txs[i].Txid == txid { + t = &b.Txs[i] break } } @@ -122,8 +123,6 @@ func (o *Vout) GetAddress() string { } var ( - chain = flag.String("chain", "mainnet", "none | mainnet | regtest | testnet3 | simnet") - rpcURL = flag.String("rpcurl", "http://localhost:8332", "url of bitcoin RPC service") rpcUser = flag.String("rpcuser", "rpc", "rpc username") rpcPass = flag.String("rpcpass", "rpc", "rpc password") @@ -153,23 +152,18 @@ func main() { timeout := time.Duration(*rpcTimeout) * time.Second rpc := NewBitcoinRPC(*rpcURL, *rpcUser, *rpcPass, timeout) - if *chain != "none" { - for _, p := range GetChainParams() { - if p.Name == *chain { - rpc.Parser = &BitcoinBlockParser{Params: p} - } - } - if rpc.Parser == nil { - log.Fatal("unknown chain") - } - } - db, err := NewRocksDB(*dbPath) if err != nil { log.Fatal(err) } defer db.Close() + if *resync { + if err := resyncIndex(rpc, db, db); err != nil { + log.Fatal(err) + } + } + if *blockHeight >= 0 { if *blockUntil < 0 { *blockUntil = *blockHeight @@ -188,12 +182,6 @@ func main() { } } } - - if *resync { - if err := resyncIndex(rpc, db, db); err != nil { - log.Fatal(err) - } - } } func printResult(txids []string) error { diff --git a/types.go b/types.go index 030e64fb..e051ff2f 100644 --- a/types.go +++ b/types.go @@ -39,9 +39,13 @@ type Tx struct { } type Block struct { + BlockHeader + Txs []Tx `json:"tx"` +} + +type ThinBlock struct { BlockHeader Txids []string `json:"tx"` - Txs []*Tx `json:"_"` } type BlockHeader struct {