From d09333fa2e520cac3e546b77ce2977740fe6565d Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Mon, 19 Mar 2018 15:46:29 +0100 Subject: [PATCH 1/3] WIP: zcash --- bchain/coins/blockchain.go | 8 +- bchain/coins/btc/bitcoinrpc.go | 57 ++++++-------- bchain/coins/zec/zcashrpc.go | 131 ++++++++++++++++++++++++++++++++- bchain/coins/zec/zec.md | 45 +++++++++++ bchain/types.go | 3 +- 5 files changed, 207 insertions(+), 37 deletions(-) create mode 100644 bchain/coins/zec/zec.md diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index d17f26ef..ee7b06bb 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -9,6 +9,7 @@ import ( "fmt" "io/ioutil" "reflect" + "time" "github.com/juju/errors" ) @@ -38,5 +39,10 @@ func NewBlockChain(coin string, configfile string, pushHandler func(*bchain.MQMe if err != nil { return nil, errors.Annotatef(err, "Error parsing file %v", configfile) } - return bcf(config, pushHandler, metrics) + bc, err := bcf(config, pushHandler, metrics) + if err != nil { + return nil, err + } + bc.Initialize(bchain.NewMempool(bc, metrics)) + return bc, nil } diff --git a/bchain/coins/btc/bitcoinrpc.go b/bchain/coins/btc/bitcoinrpc.go index cc4e6c9b..d57c94d2 100644 --- a/bchain/coins/btc/bitcoinrpc.go +++ b/bchain/coins/btc/bitcoinrpc.go @@ -92,8 +92,6 @@ func NewBitcoinRPC(config json.RawMessage, pushHandler func(*bchain.MQMessage), } s.mq = mq - s.Mempool = bchain.NewMempool(s, metrics) - return s, nil } @@ -107,6 +105,10 @@ func (b *BitcoinRPC) Shutdown() error { return nil } +func (b *BitcoinRPC) Initialize(mempool *bchain.Mempool) { + b.Mempool = mempool +} + func (b *BitcoinRPC) IsTestnet() bool { return b.Testnet } @@ -188,12 +190,7 @@ type cmdGetBlockHeader struct { } `json:"params"` } -type resGetBlockHeaderRaw struct { - Error *bchain.RPCError `json:"error"` - Result string `json:"result"` -} - -type resGetBlockHeaderVerbose struct { +type resGetBlockHeader struct { Error *bchain.RPCError `json:"error"` Result bchain.BlockHeader `json:"result"` } @@ -233,12 +230,7 @@ type cmdGetRawTransaction struct { } `json:"params"` } -type resGetRawTransactionRaw struct { - Error *bchain.RPCError `json:"error"` - Result string `json:"result"` -} - -type resGetRawTransactionVerbose struct { +type resGetRawTransaction struct { Error *bchain.RPCError `json:"error"` Result bchain.Tx `json:"result"` } @@ -292,7 +284,7 @@ func (b *BitcoinRPC) GetBestBlockHash() (string, error) { res := resGetBestBlockHash{} req := cmdGetBestBlockHash{Method: "getbestblockhash"} - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return "", err @@ -309,7 +301,7 @@ func (b *BitcoinRPC) GetBestBlockHeight() (uint32, error) { res := resGetBlockCount{} req := cmdGetBlockCount{Method: "getblockcount"} - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return 0, err @@ -326,7 +318,7 @@ func (b *BitcoinRPC) GetBlockChainInfo() (string, error) { res := resGetBlockChainInfo{} req := cmdGetBlockChainInfo{Method: "getblockchaininfo"} - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return "", err @@ -344,7 +336,7 @@ func (b *BitcoinRPC) GetBlockHash(height uint32) (string, error) { res := resGetBlockHash{} req := cmdGetBlockHash{Method: "getblockhash"} req.Params.Height = height - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return "", errors.Annotatef(err, "height %v", height) @@ -359,11 +351,11 @@ func (b *BitcoinRPC) GetBlockHash(height uint32) (string, error) { func (b *BitcoinRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) { glog.V(1).Info("rpc: getblockheader") - res := resGetBlockHeaderVerbose{} + res := resGetBlockHeader{} req := cmdGetBlockHeader{Method: "getblockheader"} req.Params.BlockHash = hash req.Params.Verbose = true - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return nil, errors.Annotatef(err, "hash %v", hash) @@ -402,9 +394,6 @@ func (b *BitcoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) // 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) (*bchain.Block, error) { - if !b.ParseBlocks { - return b.GetBlockFull(hash) - } data, err := b.GetBlockRaw(hash) if err != nil { return nil, err @@ -426,7 +415,7 @@ func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) { req := cmdGetBlock{Method: "getblock"} req.Params.BlockHash = hash req.Params.Verbosity = 0 - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return nil, errors.Annotatef(err, "hash %v", hash) @@ -446,7 +435,7 @@ func (b *BitcoinRPC) GetBlockList(hash string) (*bchain.Block, error) { req := cmdGetBlock{Method: "getblock"} req.Params.BlockHash = hash req.Params.Verbosity = 1 - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return nil, errors.Annotatef(err, "hash %v", hash) @@ -478,7 +467,7 @@ func (b *BitcoinRPC) GetBlockFull(hash string) (*bchain.Block, error) { req := cmdGetBlock{Method: "getblock"} req.Params.BlockHash = hash req.Params.Verbosity = 2 - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return nil, errors.Annotatef(err, "hash %v", hash) @@ -495,7 +484,7 @@ func (b *BitcoinRPC) GetMempool() ([]string, error) { res := resGetMempool{} req := cmdGetMempool{Method: "getrawmempool"} - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return nil, err @@ -510,11 +499,11 @@ func (b *BitcoinRPC) GetMempool() ([]string, error) { func (b *BitcoinRPC) GetTransaction(txid string) (*bchain.Tx, error) { glog.V(1).Info("rpc: getrawtransaction ", txid) - res := resGetRawTransactionVerbose{} + res := resGetRawTransaction{} req := cmdGetRawTransaction{Method: "getrawtransaction"} req.Params.Txid = txid req.Params.Verbose = true - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return nil, errors.Annotatef(err, "txid %v", txid) @@ -553,7 +542,7 @@ func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, e } else { req.Params.EstimateMode = "ECONOMICAL" } - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return 0, err @@ -571,7 +560,7 @@ func (b *BitcoinRPC) SendRawTransaction(tx string) (string, error) { res := resSendRawTransaction{} req := cmdSendRawTransaction{Method: "sendrawtransaction"} req.Params = []string{tx} - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return "", err @@ -590,7 +579,7 @@ func (b *BitcoinRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) Method: "getmempoolentry", Params: []string{txid}, } - err := b.observeRPCLatency(req.Method, func() error { return b.call(&req, &res) }) + err := b.Call(req.Method, &req, &res) if err != nil { return nil, err @@ -601,9 +590,9 @@ func (b *BitcoinRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) return res.Result, nil } -func (b *BitcoinRPC) observeRPCLatency(method string, fn func() error) error { +func (b *BitcoinRPC) Call(method string, req interface{}, res interface{}) error { start := time.Now() - err := fn() + err := b.call(req, res) if err == nil { b.metrics.RPCLatency.With(common.Labels{"method": method}).Observe(float64(time.Since(start)) / 1e6) // in milliseconds } diff --git a/bchain/coins/zec/zcashrpc.go b/bchain/coins/zec/zcashrpc.go index 4f7e38db..90ff6c82 100644 --- a/bchain/coins/zec/zcashrpc.go +++ b/bchain/coins/zec/zcashrpc.go @@ -4,7 +4,10 @@ import ( "blockbook/bchain" "blockbook/bchain/coins/btc" "blockbook/common" - "encoding/json" + "time" + + "github.com/golang/glog" + "github.com/juju/errors" ) type ZCashRPC struct { @@ -21,3 +24,129 @@ func NewZCashRPC(config json.RawMessage, pushHandler func(*bchain.MQMessage), me } return z, nil } + +type untypedArrayParams struct { + Method string `json:"method"` + Params []interface{} `json:"params"` +} + +// getblockhash + +type resGetBlockHash struct { + Error *bchain.RPCError `json:"error"` + Result string `json:"result"` +} + +// getblock + +type resGetBlockThin struct { + Error *bchain.RPCError `json:"error"` + Result bchain.ThinBlock `json:"result"` +} + +// getrawtransaction + +type resGetRawTransaction struct { + Error *bchain.RPCError `json:"error"` + Result bchain.Tx `json:"result"` +} + +// getblockheader + +type resGetBlockHeader struct { + Error *bchain.RPCError `json:"error"` + Result bchain.BlockHeader `json:"result"` +} + +// GetBlock returns block with given hash. +func (z *ZCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { + glog.V(1).Info("rpc: getblock (verbosity=1) ", hash) + + res := resGetBlockThin{} + req := untypedArrayParams{Method: "getblock"} + req.Params = append(req.Params, hash) + req.Params = append(req.Params, true) + err := z.Call(req.Method, &req, &res) + + if err != nil { + return nil, errors.Annotatef(err, "hash %v", hash) + } + if res.Error != nil { + return nil, errors.Annotatef(res.Error, "hash %v", hash) + } + + txs := make([]bchain.Tx, len(res.Result.Txids)) + for i, txid := range res.Result.Txids { + tx, err := z.GetTransaction(txid) + if err != nil { + return nil, err + } + txs[i] = *tx + } + block := &bchain.Block{ + BlockHeader: res.Result.BlockHeader, + Txs: txs, + } + return block, nil +} + +// GetTransaction returns a transaction by the transaction ID. +func (z *ZCashRPC) GetTransaction(txid string) (*bchain.Tx, error) { + glog.V(1).Info("rpc: getrawtransaction ", txid) + + res := resGetRawTransaction{} + req := untypedArrayParams{Method: "getrawtransaction"} + req.Params = append(req.Params, txid) + req.Params = append(req.Params, 1) + err := z.Call(req.Method, &req, &res) + + if err != nil { + return nil, errors.Annotatef(err, "txid %v", txid) + } + if res.Error != nil { + return nil, errors.Annotatef(res.Error, "txid %v", txid) + } + return &res.Result, nil +} + +// GetBlockHash returns hash of block in best-block-chain at given height. +func (z *ZCashRPC) GetBlockHash(height uint32) (string, error) { + glog.V(1).Info("rpc: getblockhash ", height) + + res := resGetBlockHash{} + req := untypedArrayParams{Method: "getblockhash"} + req.Params = append(req.Params, height) + err := z.Call(req.Method, &req, &res) + + if err != nil { + return "", errors.Annotatef(err, "height %v", height) + } + if res.Error != nil { + return "", errors.Annotatef(res.Error, "height %v", height) + } + return res.Result, nil +} + +// GetBlockHeader returns header of block with given hash. +func (z *ZCashRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) { + glog.V(1).Info("rpc: getblockheader") + + res := resGetBlockHeader{} + req := untypedArrayParams{Method: "getblockheader"} + req.Params = append(req.Params, hash) + req.Params = append(req.Params, true) + err := z.Call(req.Method, &req, &res) + + if err != nil { + return nil, errors.Annotatef(err, "hash %v", hash) + } + if res.Error != nil { + return nil, errors.Annotatef(res.Error, "hash %v", hash) + } + return &res.Result, nil +} + +// GetChainParser returns BlockChainParser +func (z *ZCashRPC) GetChainParser() bchain.BlockChainParser { + return z.Parser +} diff --git a/bchain/coins/zec/zec.md b/bchain/coins/zec/zec.md new file mode 100644 index 00000000..f3adeecb --- /dev/null +++ b/bchain/coins/zec/zec.md @@ -0,0 +1,45 @@ +## Zcash Setup +Get Zcash client +``` +wget https://z.cash/downloads/zcash-1.0.15-linux64.tar.gz +tar xzf zcash-1.0.15-linux64.tar.gz +``` + +Run command to download the parameters used to create and verify shielded transactions: +``` +zcash-1.0.15/bin/zcash-fetch-params +``` + +Data are stored in */data/zec* , in folders */data/zec/zcash* for Zcash client data, */data/zec/blockbook* for Blockbook data. + +Create configuration file */data/zec/zcash/zcash.conf* with content +``` +daemon=1 +server=1 +rpcuser=rpc +rpcpassword=rpc +rpcport=8232 +txindex=1 +mainnet=1 +addnode=mainnet.z.cash +``` + +Create script *run-zec-zcashd.sh* that starts the zcashd daemon with increased rpcworkqueue and configured zeromq +``` +#!/bin/bash + +zcash-1.0.15/bin/zcashd -datadir=/data/zec/zcash -rpcworkqueue=32 -zmqpubhashblock=tcp://127.0.0.1:8234 -zmqpubrawblock=tcp://127.0.0.1:8234 -zmqpubhashtx=tcp://127.0.0.1:8234 -zmqpubrawtx=tcp://127.0.0.1:8234 +``` + +Run the *run-zec-zcashd.sh* to get initial import of data. + +Create *run-zec-blockbook.sh* script that starts blockbook +``` +#!/bin/bash +./blockbook -path=/data/zec/blockbook/db -sync -parse -rpcurl=http://127.0.0.1:8232 -httpserver=:8235 -socketio=:8236 -certfile=server/testcert -zeromq=tcp://127.0.0.1:8234 -explorer=https://zec-bitcore1.trezor.io -coin=zec $1 +``` + +To run blockbook with logging to file (run with nohup or daemonize using screen) +``` +./run-zec-blockbook.sh 2> /data/zec/blockbook/blockbook.log +``` diff --git a/bchain/types.go b/bchain/types.go index 8d982021..4d0d5e28 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -86,7 +86,8 @@ func (e *RPCError) Error() string { } type BlockChain interface { - // cleanup + // life-cycle methods + Initialize(mempool *Mempool) Shutdown() error // chain info IsTestnet() bool From bad16b1404459c7104482f8dddf420bac6aa7a22 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Tue, 20 Mar 2018 16:07:05 +0100 Subject: [PATCH 2/3] fixes --- bchain/coins/blockchain.go | 1 - bchain/coins/zec/zcashrpc.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index ee7b06bb..cb93daa2 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -9,7 +9,6 @@ import ( "fmt" "io/ioutil" "reflect" - "time" "github.com/juju/errors" ) diff --git a/bchain/coins/zec/zcashrpc.go b/bchain/coins/zec/zcashrpc.go index 90ff6c82..743cf026 100644 --- a/bchain/coins/zec/zcashrpc.go +++ b/bchain/coins/zec/zcashrpc.go @@ -4,7 +4,7 @@ import ( "blockbook/bchain" "blockbook/bchain/coins/btc" "blockbook/common" - "time" + "encoding/json" "github.com/golang/glog" "github.com/juju/errors" From a9effbe8351f00bede9ca3dbdc8c8210163645ba Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Tue, 20 Mar 2018 17:28:03 +0100 Subject: [PATCH 3/3] Added ZCashBlockParser --- bchain/coins/btc/bitcoinparser.go | 4 +-- bchain/coins/btc/bitcoinrpc.go | 55 +++++++++++++++++-------------- bchain/coins/zec/zcashparser.go | 46 ++++++++++++++++++++++++++ bchain/coins/zec/zcashrpc.go | 38 ++++++++++++++++++--- bchain/mempool.go | 11 ++++--- bchain/types.go | 2 +- db/rocksdb.go | 2 +- 7 files changed, 119 insertions(+), 39 deletions(-) create mode 100644 bchain/coins/zec/zcashparser.go diff --git a/bchain/coins/btc/bitcoinparser.go b/bchain/coins/btc/bitcoinparser.go index 415082a2..692d1170 100644 --- a/bchain/coins/btc/bitcoinparser.go +++ b/bchain/coins/btc/bitcoinparser.go @@ -41,8 +41,8 @@ func (p *BitcoinBlockParser) GetUIDFromAddress(address string) ([]byte, error) { return p.AddressToOutputScript(address) } -func (p *BitcoinBlockParser) PackUID(script string) ([]byte, error) { - return hex.DecodeString(script) +func (p *BitcoinBlockParser) PackUID(str string) ([]byte, error) { + return hex.DecodeString(str) } func (p *BitcoinBlockParser) UnpackUID(buf []byte) string { diff --git a/bchain/coins/btc/bitcoinrpc.go b/bchain/coins/btc/bitcoinrpc.go index d57c94d2..ba4f62d5 100644 --- a/bchain/coins/btc/bitcoinrpc.go +++ b/bchain/coins/btc/bitcoinrpc.go @@ -24,7 +24,7 @@ type BitcoinRPC struct { rpcURL string user string password string - Parser *BitcoinBlockParser + Parser bchain.BlockChainParser Testnet bool Network string Mempool *bchain.Mempool @@ -64,26 +64,6 @@ func NewBitcoinRPC(config json.RawMessage, pushHandler func(*bchain.MQMessage), ParseBlocks: c.Parse, metrics: metrics, } - chainName, err := s.GetBlockChainInfo() - if err != nil { - return nil, err - } - - // always create parser - s.Parser = &BitcoinBlockParser{ - Params: GetChainParams(chainName), - } - - // parameters for getInfo request - if s.Parser.Params.Net == wire.MainNet { - s.Testnet = false - s.Network = "livenet" - } else { - s.Testnet = true - s.Network = "testnet" - } - - glog.Info("rpc: block chain ", s.Parser.Params.Name) mq, err := bchain.NewMQ(c.ZeroMQBinding, pushHandler) if err != nil { @@ -95,6 +75,35 @@ func NewBitcoinRPC(config json.RawMessage, pushHandler func(*bchain.MQMessage), return s, nil } +func (b *BitcoinRPC) Initialize(mempool *bchain.Mempool) error { + b.Mempool = mempool + + chainName, err := b.GetBlockChainInfo() + if err != nil { + return err + } + + params := GetChainParams(chainName) + + // always create parser + b.Parser = &BitcoinBlockParser{ + Params: params, + } + + // parameters for getInfo request + if params.Net == wire.MainNet { + b.Testnet = false + b.Network = "livenet" + } else { + b.Testnet = true + b.Network = "testnet" + } + + glog.Info("rpc: block chain ", params.Name) + + return nil +} + func (b *BitcoinRPC) Shutdown() error { if b.mq != nil { if err := b.mq.Shutdown(); err != nil { @@ -105,10 +114,6 @@ func (b *BitcoinRPC) Shutdown() error { return nil } -func (b *BitcoinRPC) Initialize(mempool *bchain.Mempool) { - b.Mempool = mempool -} - func (b *BitcoinRPC) IsTestnet() bool { return b.Testnet } diff --git a/bchain/coins/zec/zcashparser.go b/bchain/coins/zec/zcashparser.go new file mode 100644 index 00000000..fab2b5ba --- /dev/null +++ b/bchain/coins/zec/zcashparser.go @@ -0,0 +1,46 @@ +package zec + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + + "github.com/btcsuite/btcd/chaincfg" +) + +// bitcoinwire parsing + +type ZCashBlockParser struct { + btc.BitcoinBlockParser +} + +// getChainParams contains network parameters for the main Bitcoin network, +// the regression test Bitcoin network, the test Bitcoin network and +// the simulation test Bitcoin network, in this order +func GetChainParams(chain string) *chaincfg.Params { + switch chain { + case "test": + return &chaincfg.TestNet3Params + case "regtest": + return &chaincfg.RegressionNetParams + } + return &chaincfg.MainNetParams +} + +func (p *ZCashBlockParser) GetUIDFromVout(output *bchain.Vout) string { + if len(output.ScriptPubKey.Addresses) != 1 { + return "" + } + return output.ScriptPubKey.Addresses[0] +} + +func (p *ZCashBlockParser) GetUIDFromAddress(address string) ([]byte, error) { + return p.PackUID(address) +} + +func (p *ZCashBlockParser) PackUID(str string) ([]byte, error) { + return []byte(str), nil +} + +func (p *ZCashBlockParser) UnpackUID(buf []byte) string { + return string(buf) +} diff --git a/bchain/coins/zec/zcashrpc.go b/bchain/coins/zec/zcashrpc.go index 743cf026..5f6dd539 100644 --- a/bchain/coins/zec/zcashrpc.go +++ b/bchain/coins/zec/zcashrpc.go @@ -6,6 +6,8 @@ import ( "blockbook/common" "encoding/json" + "github.com/btcsuite/btcd/wire" + "github.com/golang/glog" "github.com/juju/errors" ) @@ -25,6 +27,37 @@ func NewZCashRPC(config json.RawMessage, pushHandler func(*bchain.MQMessage), me return z, nil } +func (z *ZCashRPC) Initialize(mempool *bchain.Mempool) error { + z.Mempool = mempool + + chainName, err := z.GetBlockChainInfo() + if err != nil { + return err + } + + params := GetChainParams(chainName) + + // always create parser + z.Parser = &ZCashBlockParser{ + btc.BitcoinBlockParser{ + Params: params, + }, + } + + // parameters for getInfo request + if params.Net == wire.MainNet { + z.Testnet = false + z.Network = "livenet" + } else { + z.Testnet = true + z.Network = "testnet" + } + + glog.Info("rpc: block chain ", params.Name) + + return nil +} + type untypedArrayParams struct { Method string `json:"method"` Params []interface{} `json:"params"` @@ -145,8 +178,3 @@ func (z *ZCashRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) { } return &res.Result, nil } - -// GetChainParser returns BlockChainParser -func (z *ZCashRPC) GetChainParser() bchain.BlockChainParser { - return z.Parser -} diff --git a/bchain/mempool.go b/bchain/mempool.go index 37155fda..a37b6c93 100644 --- a/bchain/mempool.go +++ b/bchain/mempool.go @@ -27,7 +27,6 @@ type inputOutput struct { // Mempool is mempool handle. type Mempool struct { chain BlockChain - chainParser BlockChainParser mux sync.Mutex txToInputOutput map[string]inputOutput scriptToTx map[string][]outpoint // TODO rename all occurences @@ -37,18 +36,19 @@ type Mempool struct { // NewMempool creates new mempool handler. func NewMempool(chain BlockChain, metrics *common.Metrics) *Mempool { - return &Mempool{chain: chain, chainParser: chain.GetChainParser(), metrics: metrics} + return &Mempool{chain: chain, metrics: metrics} } // GetTransactions returns slice of mempool transactions for given output script. func (m *Mempool) GetTransactions(address string) ([]string, error) { m.mux.Lock() defer m.mux.Unlock() - buf, err := m.chainParser.GetUIDFromAddress(address) + parser := m.chain.GetChainParser() + buf, err := parser.GetUIDFromAddress(address) if err != nil { return nil, err } - outid := m.chainParser.UnpackUID(buf) + outid := parser.UnpackUID(buf) outpoints := m.scriptToTx[outid] txs := make([]string, 0, len(outpoints)+len(outpoints)/2) for _, o := range outpoints { @@ -86,6 +86,7 @@ func (m *Mempool) Resync(onNewTxAddr func(txid string, addr string)) error { m.metrics.MempoolResyncErrors.With(common.Labels{"error": err.Error()}).Inc() return err } + parser := m.chain.GetChainParser() newTxToInputOutput := make(map[string]inputOutput, len(m.txToInputOutput)+1) newScriptToTx := make(map[string][]outpoint, len(m.scriptToTx)+1) newInputs := make(map[outpoint]string, len(m.inputs)+1) @@ -100,7 +101,7 @@ func (m *Mempool) Resync(onNewTxAddr func(txid string, addr string)) error { } io.outputs = make([]scriptIndex, 0, len(tx.Vout)) for _, output := range tx.Vout { - outid := m.chainParser.GetUIDFromVout(&output) + outid := parser.GetUIDFromVout(&output) if outid != "" { io.outputs = append(io.outputs, scriptIndex{outid, output.N}) } diff --git a/bchain/types.go b/bchain/types.go index 4d0d5e28..6e665364 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -87,7 +87,7 @@ func (e *RPCError) Error() string { type BlockChain interface { // life-cycle methods - Initialize(mempool *Mempool) + Initialize(mempool *Mempool) error Shutdown() error // chain info IsTestnet() bool diff --git a/db/rocksdb.go b/db/rocksdb.go index 43d01260..50ce4438 100644 --- a/db/rocksdb.go +++ b/db/rocksdb.go @@ -266,7 +266,7 @@ func (d *RocksDB) writeOutputs(wb *gorocksdb.WriteBatch, block *bchain.Block, op for outid, outpoints := range records { bOutid, err := d.chainParser.PackUID(outid) if err != nil { - glog.Warningf("rocksdb: packOutputID: %v - %d %s", err, block.Height, outid) + glog.Warningf("rocksdb: packUID: %v - %d %s", err, block.Height, outid) continue } key, err := packOutputKey(bOutid, block.Height)