Add base for ZCash support

This commit is contained in:
Martin Boehm 2018-03-08 19:39:21 +01:00
parent 9d0547f608
commit 23b795ccc7
3 changed files with 48 additions and 24 deletions

View File

@ -3,6 +3,7 @@ package coins
import ( import (
"blockbook/bchain" "blockbook/bchain"
"blockbook/bchain/coins/btc" "blockbook/bchain/coins/btc"
"blockbook/bchain/coins/zec"
"fmt" "fmt"
"reflect" "reflect"
"time" "time"
@ -16,6 +17,7 @@ var blockChainFactories = make(map[string]blockChainFactory)
func init() { func init() {
blockChainFactories["btc"] = btc.NewBitcoinRPC blockChainFactories["btc"] = btc.NewBitcoinRPC
blockChainFactories["zec"] = zec.NewZCashRPC
} }
// NewBlockChain creates bchain.BlockChain of type defined by parameter coin // NewBlockChain creates bchain.BlockChain of type defined by parameter coin

View File

@ -23,11 +23,11 @@ type BitcoinRPC struct {
rpcURL string rpcURL string
user string user string
password string password string
parser *BitcoinBlockParser Parser *BitcoinBlockParser
testnet bool Testnet bool
network string Network string
mempool *bchain.Mempool Mempool *bchain.Mempool
parseBlocks bool ParseBlocks bool
} }
// NewBitcoinRPC returns new BitcoinRPC instance. // NewBitcoinRPC returns new BitcoinRPC instance.
@ -42,7 +42,7 @@ func NewBitcoinRPC(url string, user string, password string, timeout time.Durati
rpcURL: url, rpcURL: url,
user: user, user: user,
password: password, password: password,
parseBlocks: parse, ParseBlocks: parse,
} }
chainName, err := s.GetBlockChainInfo() chainName, err := s.GetBlockChainInfo()
if err != nil { if err != nil {
@ -50,31 +50,31 @@ func NewBitcoinRPC(url string, user string, password string, timeout time.Durati
} }
// always create parser // always create parser
s.parser = &BitcoinBlockParser{ s.Parser = &BitcoinBlockParser{
Params: GetChainParams(chainName), Params: GetChainParams(chainName),
} }
// parameters for getInfo request // parameters for getInfo request
if s.parser.Params.Net == wire.MainNet { if s.Parser.Params.Net == wire.MainNet {
s.testnet = false s.Testnet = false
s.network = "livenet" s.Network = "livenet"
} else { } else {
s.testnet = true s.Testnet = true
s.network = "testnet" s.Network = "testnet"
} }
s.mempool = bchain.NewMempool(s) s.Mempool = bchain.NewMempool(s)
glog.Info("rpc: block chain ", s.parser.Params.Name) glog.Info("rpc: block chain ", s.Parser.Params.Name)
return s, nil return s, nil
} }
func (b *BitcoinRPC) IsTestnet() bool { func (b *BitcoinRPC) IsTestnet() bool {
return b.testnet return b.Testnet
} }
func (b *BitcoinRPC) GetNetworkName() string { func (b *BitcoinRPC) GetNetworkName() string {
return b.network return b.Network
} }
// getblockhash // getblockhash
@ -338,7 +338,7 @@ func (b *BitcoinRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) {
// GetBlock returns block with given hash. // GetBlock returns block with given hash.
func (b *BitcoinRPC) GetBlock(hash string) (*bchain.Block, error) { func (b *BitcoinRPC) GetBlock(hash string) (*bchain.Block, error) {
if !b.parseBlocks { if !b.ParseBlocks {
return b.GetBlockFull(hash) return b.GetBlockFull(hash)
} }
header, err := b.GetBlockHeader(hash) header, err := b.GetBlockHeader(hash)
@ -349,7 +349,7 @@ func (b *BitcoinRPC) GetBlock(hash string) (*bchain.Block, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
block, err := b.parser.ParseBlock(data) block, err := b.Parser.ParseBlock(data)
if err != nil { if err != nil {
return nil, errors.Annotatef(err, "hash %v", hash) return nil, errors.Annotatef(err, "hash %v", hash)
} }
@ -360,14 +360,14 @@ func (b *BitcoinRPC) GetBlock(hash string) (*bchain.Block, error) {
// GetBlockWithoutHeader is an optimization - it does not call GetBlockHeader to get prev, next hashes // 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 // instead it sets to header only block hash and height passed in parameters
func (b *BitcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) { func (b *BitcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) {
if !b.parseBlocks { if !b.ParseBlocks {
return b.GetBlockFull(hash) return b.GetBlockFull(hash)
} }
data, err := b.GetBlockRaw(hash) data, err := b.GetBlockRaw(hash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
block, err := b.parser.ParseBlock(data) block, err := b.Parser.ParseBlock(data)
if err != nil { if err != nil {
return nil, errors.Annotatef(err, "%v %v", height, hash) return nil, errors.Annotatef(err, "%v %v", height, hash)
} }
@ -486,17 +486,17 @@ func (b *BitcoinRPC) GetTransaction(txid string) (*bchain.Tx, error) {
// ResyncMempool gets mempool transactions and maps output scripts to transactions. // ResyncMempool gets mempool transactions and maps output scripts to transactions.
// ResyncMempool is not reentrant, it should be called from a single thread. // ResyncMempool is not reentrant, it should be called from a single thread.
func (b *BitcoinRPC) ResyncMempool(onNewTxAddr func(txid string, addr string)) error { func (b *BitcoinRPC) ResyncMempool(onNewTxAddr func(txid string, addr string)) error {
return b.mempool.Resync(onNewTxAddr) return b.Mempool.Resync(onNewTxAddr)
} }
// GetMempoolTransactions returns slice of mempool transactions for given output script. // GetMempoolTransactions returns slice of mempool transactions for given output script.
func (b *BitcoinRPC) GetMempoolTransactions(outputScript []byte) ([]string, error) { func (b *BitcoinRPC) GetMempoolTransactions(outputScript []byte) ([]string, error) {
return b.mempool.GetTransactions(outputScript) return b.Mempool.GetTransactions(outputScript)
} }
// GetMempoolSpentOutput returns transaction in mempool which spends given outpoint // GetMempoolSpentOutput returns transaction in mempool which spends given outpoint
func (b *BitcoinRPC) GetMempoolSpentOutput(outputTxid string, vout uint32) string { func (b *BitcoinRPC) GetMempoolSpentOutput(outputTxid string, vout uint32) string {
return b.mempool.GetSpentOutput(outputTxid, vout) return b.Mempool.GetSpentOutput(outputTxid, vout)
} }
// EstimateSmartFee returns fee estimation. // EstimateSmartFee returns fee estimation.
@ -586,5 +586,5 @@ func (b *BitcoinRPC) call(req interface{}, res interface{}) error {
// GetChainParser returns BlockChainParser // GetChainParser returns BlockChainParser
func (b *BitcoinRPC) GetChainParser() bchain.BlockChainParser { func (b *BitcoinRPC) GetChainParser() bchain.BlockChainParser {
return b.parser return b.Parser
} }

View File

@ -0,0 +1,22 @@
package zec
import (
"blockbook/bchain"
"blockbook/bchain/coins/btc"
"time"
)
type ZCashRPC struct {
*btc.BitcoinRPC
}
func NewZCashRPC(url string, user string, password string, timeout time.Duration, parse bool) (bchain.BlockChain, error) {
b, err := btc.NewBitcoinRPC(url, user, password, timeout, parse)
if err != nil {
return nil, err
}
z := &ZCashRPC{
BitcoinRPC: b.(*btc.BitcoinRPC),
}
return z, nil
}