Added ZCashBlockParser

This commit is contained in:
Jakub Matys 2018-03-20 17:28:03 +01:00
parent bad16b1404
commit a9effbe835
7 changed files with 119 additions and 39 deletions

View File

@ -41,8 +41,8 @@ func (p *BitcoinBlockParser) GetUIDFromAddress(address string) ([]byte, error) {
return p.AddressToOutputScript(address) return p.AddressToOutputScript(address)
} }
func (p *BitcoinBlockParser) PackUID(script string) ([]byte, error) { func (p *BitcoinBlockParser) PackUID(str string) ([]byte, error) {
return hex.DecodeString(script) return hex.DecodeString(str)
} }
func (p *BitcoinBlockParser) UnpackUID(buf []byte) string { func (p *BitcoinBlockParser) UnpackUID(buf []byte) string {

View File

@ -24,7 +24,7 @@ type BitcoinRPC struct {
rpcURL string rpcURL string
user string user string
password string password string
Parser *BitcoinBlockParser Parser bchain.BlockChainParser
Testnet bool Testnet bool
Network string Network string
Mempool *bchain.Mempool Mempool *bchain.Mempool
@ -64,26 +64,6 @@ func NewBitcoinRPC(config json.RawMessage, pushHandler func(*bchain.MQMessage),
ParseBlocks: c.Parse, ParseBlocks: c.Parse,
metrics: metrics, 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) mq, err := bchain.NewMQ(c.ZeroMQBinding, pushHandler)
if err != nil { if err != nil {
@ -95,6 +75,35 @@ func NewBitcoinRPC(config json.RawMessage, pushHandler func(*bchain.MQMessage),
return s, nil 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 { func (b *BitcoinRPC) Shutdown() error {
if b.mq != nil { if b.mq != nil {
if err := b.mq.Shutdown(); err != nil { if err := b.mq.Shutdown(); err != nil {
@ -105,10 +114,6 @@ func (b *BitcoinRPC) Shutdown() error {
return nil return nil
} }
func (b *BitcoinRPC) Initialize(mempool *bchain.Mempool) {
b.Mempool = mempool
}
func (b *BitcoinRPC) IsTestnet() bool { func (b *BitcoinRPC) IsTestnet() bool {
return b.Testnet return b.Testnet
} }

View File

@ -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)
}

View File

@ -6,6 +6,8 @@ import (
"blockbook/common" "blockbook/common"
"encoding/json" "encoding/json"
"github.com/btcsuite/btcd/wire"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/juju/errors" "github.com/juju/errors"
) )
@ -25,6 +27,37 @@ func NewZCashRPC(config json.RawMessage, pushHandler func(*bchain.MQMessage), me
return z, nil 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 { type untypedArrayParams struct {
Method string `json:"method"` Method string `json:"method"`
Params []interface{} `json:"params"` Params []interface{} `json:"params"`
@ -145,8 +178,3 @@ func (z *ZCashRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) {
} }
return &res.Result, nil return &res.Result, nil
} }
// GetChainParser returns BlockChainParser
func (z *ZCashRPC) GetChainParser() bchain.BlockChainParser {
return z.Parser
}

View File

@ -27,7 +27,6 @@ type inputOutput struct {
// Mempool is mempool handle. // Mempool is mempool handle.
type Mempool struct { type Mempool struct {
chain BlockChain chain BlockChain
chainParser BlockChainParser
mux sync.Mutex mux sync.Mutex
txToInputOutput map[string]inputOutput txToInputOutput map[string]inputOutput
scriptToTx map[string][]outpoint // TODO rename all occurences scriptToTx map[string][]outpoint // TODO rename all occurences
@ -37,18 +36,19 @@ type Mempool struct {
// NewMempool creates new mempool handler. // NewMempool creates new mempool handler.
func NewMempool(chain BlockChain, metrics *common.Metrics) *Mempool { 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. // GetTransactions returns slice of mempool transactions for given output script.
func (m *Mempool) GetTransactions(address string) ([]string, error) { func (m *Mempool) GetTransactions(address string) ([]string, error) {
m.mux.Lock() m.mux.Lock()
defer m.mux.Unlock() defer m.mux.Unlock()
buf, err := m.chainParser.GetUIDFromAddress(address) parser := m.chain.GetChainParser()
buf, err := parser.GetUIDFromAddress(address)
if err != nil { if err != nil {
return nil, err return nil, err
} }
outid := m.chainParser.UnpackUID(buf) outid := parser.UnpackUID(buf)
outpoints := m.scriptToTx[outid] outpoints := m.scriptToTx[outid]
txs := make([]string, 0, len(outpoints)+len(outpoints)/2) txs := make([]string, 0, len(outpoints)+len(outpoints)/2)
for _, o := range outpoints { 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() m.metrics.MempoolResyncErrors.With(common.Labels{"error": err.Error()}).Inc()
return err return err
} }
parser := m.chain.GetChainParser()
newTxToInputOutput := make(map[string]inputOutput, len(m.txToInputOutput)+1) newTxToInputOutput := make(map[string]inputOutput, len(m.txToInputOutput)+1)
newScriptToTx := make(map[string][]outpoint, len(m.scriptToTx)+1) newScriptToTx := make(map[string][]outpoint, len(m.scriptToTx)+1)
newInputs := make(map[outpoint]string, len(m.inputs)+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)) io.outputs = make([]scriptIndex, 0, len(tx.Vout))
for _, output := range tx.Vout { for _, output := range tx.Vout {
outid := m.chainParser.GetUIDFromVout(&output) outid := parser.GetUIDFromVout(&output)
if outid != "" { if outid != "" {
io.outputs = append(io.outputs, scriptIndex{outid, output.N}) io.outputs = append(io.outputs, scriptIndex{outid, output.N})
} }

View File

@ -87,7 +87,7 @@ func (e *RPCError) Error() string {
type BlockChain interface { type BlockChain interface {
// life-cycle methods // life-cycle methods
Initialize(mempool *Mempool) Initialize(mempool *Mempool) error
Shutdown() error Shutdown() error
// chain info // chain info
IsTestnet() bool IsTestnet() bool

View File

@ -266,7 +266,7 @@ func (d *RocksDB) writeOutputs(wb *gorocksdb.WriteBatch, block *bchain.Block, op
for outid, outpoints := range records { for outid, outpoints := range records {
bOutid, err := d.chainParser.PackUID(outid) bOutid, err := d.chainParser.PackUID(outid)
if err != nil { 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 continue
} }
key, err := packOutputKey(bOutid, block.Height) key, err := packOutputKey(bOutid, block.Height)