From f8fbbcfe298d725a8a4eccffea7f0167414902f9 Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Thu, 1 Mar 2018 00:32:40 +0100 Subject: [PATCH] Connect blocks in parallel without getting block header - optimization --- bchain/bitcoinrpc.go | 19 +++++++++++++++++++ blockbook.go | 16 ++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/bchain/bitcoinrpc.go b/bchain/bitcoinrpc.go index 1e874def..28c221c1 100644 --- a/bchain/bitcoinrpc.go +++ b/bchain/bitcoinrpc.go @@ -287,6 +287,25 @@ func (b *BitcoinRPC) GetBlock(hash string) (*Block, error) { return block, nil } +// GetBlockWithoutHeader is an optimization - it does not call GetBlockHeader to get prev, next hashes +// instead it sets to header only block hash and height passed in parameters +func (b *BitcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*Block, error) { + if b.Parser == nil { + return b.GetBlockFull(hash) + } + data, err := b.GetBlockRaw(hash) + if err != nil { + return nil, err + } + block, err := b.Parser.ParseBlock(data) + if err != nil { + return nil, err + } + block.BlockHeader.Hash = hash + block.BlockHeader.Height = height + return block, nil +} + // GetBlockRaw returns block with given hash as bytes. func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) { glog.V(1).Info("rpc: getblock (verbosity=0) ", hash) diff --git a/blockbook.go b/blockbook.go index 63a9fb44..1be2acc5 100644 --- a/blockbook.go +++ b/blockbook.go @@ -480,17 +480,21 @@ func connectBlocksParallel( higher uint32, numWorkers int, ) error { + type hashHeight struct { + hash string + height uint32 + } var err error var wg sync.WaitGroup - hch := make(chan string, numWorkers) + hch := make(chan hashHeight, numWorkers) running := make([]bool, numWorkers) work := func(i int) { defer wg.Done() - for hash := range hch { + for hh := range hch { running[i] = true - block, err := chain.GetBlock(hash) + block, err := chain.GetBlockWithoutHeader(hh.hash, hh.height) if err != nil { - glog.Error("Connect block ", hash, " error ", err) + glog.Error("Connect block ", hh.height, " ", hh.hash, " error ", err) running[i] = false continue } @@ -500,7 +504,7 @@ func connectBlocksParallel( } err = index.ConnectBlock(block) if err != nil { - glog.Error("Connect block ", hash, " error ", err) + glog.Error("Connect block ", hh.height, " ", hh.hash, " error ", err) } running[i] = false } @@ -516,7 +520,7 @@ func connectBlocksParallel( if err != nil { break } - hch <- hash + hch <- hashHeight{hash, h} if h > 0 && h%1000 == 0 { glog.Info("connecting block ", h, " ", hash) }