Move packing/unpacking of Txid and Block Hash to coin specific code
parent
8a8952d103
commit
a75376706e
|
@ -14,13 +14,12 @@ import (
|
|||
"github.com/btcsuite/btcutil"
|
||||
)
|
||||
|
||||
// bitcoinwire parsing
|
||||
|
||||
type BitcoinBlockParser struct {
|
||||
// BitcoinParser handle
|
||||
type BitcoinParser struct {
|
||||
Params *chaincfg.Params
|
||||
}
|
||||
|
||||
// getChainParams contains network parameters for the main Bitcoin network,
|
||||
// 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 {
|
||||
|
@ -33,18 +32,18 @@ func GetChainParams(chain string) *chaincfg.Params {
|
|||
return &chaincfg.MainNetParams
|
||||
}
|
||||
|
||||
// GetAddrIDFromAddress returns internal address representation of given transaction output
|
||||
func (p *BitcoinBlockParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error) {
|
||||
// GetAddrIDFromVout returns internal address representation of given transaction output
|
||||
func (p *BitcoinParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error) {
|
||||
return hex.DecodeString(output.ScriptPubKey.Hex)
|
||||
}
|
||||
|
||||
// GetAddrIDFromAddress returns internal address representation of given address
|
||||
func (p *BitcoinBlockParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
||||
func (p *BitcoinParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
||||
return p.AddressToOutputScript(address)
|
||||
}
|
||||
|
||||
// AddressToOutputScript converts bitcoin address to ScriptPubKey
|
||||
func (p *BitcoinBlockParser) AddressToOutputScript(address string) ([]byte, error) {
|
||||
func (p *BitcoinParser) AddressToOutputScript(address string) ([]byte, error) {
|
||||
da, err := btcutil.DecodeAddress(address, p.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -57,7 +56,7 @@ func (p *BitcoinBlockParser) AddressToOutputScript(address string) ([]byte, erro
|
|||
}
|
||||
|
||||
// OutputScriptToAddresses converts ScriptPubKey to bitcoin addresses
|
||||
func (p *BitcoinBlockParser) OutputScriptToAddresses(script []byte) ([]string, error) {
|
||||
func (p *BitcoinParser) OutputScriptToAddresses(script []byte) ([]string, error) {
|
||||
_, addresses, _, err := txscript.ExtractPkScriptAddrs(script, p.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -69,7 +68,7 @@ func (p *BitcoinBlockParser) OutputScriptToAddresses(script []byte) ([]string, e
|
|||
return rv, nil
|
||||
}
|
||||
|
||||
func (p *BitcoinBlockParser) txFromMsgTx(t *wire.MsgTx, parseAddresses bool) bchain.Tx {
|
||||
func (p *BitcoinParser) txFromMsgTx(t *wire.MsgTx, parseAddresses bool) bchain.Tx {
|
||||
vin := make([]bchain.Vin, len(t.TxIn))
|
||||
for i, in := range t.TxIn {
|
||||
if blockchain.IsCoinBaseTx(t) {
|
||||
|
@ -123,7 +122,7 @@ func (p *BitcoinBlockParser) txFromMsgTx(t *wire.MsgTx, parseAddresses bool) bch
|
|||
}
|
||||
|
||||
// ParseTx parses byte array containing transaction and returns Tx struct
|
||||
func (p *BitcoinBlockParser) ParseTx(b []byte) (*bchain.Tx, error) {
|
||||
func (p *BitcoinParser) ParseTx(b []byte) (*bchain.Tx, error) {
|
||||
t := wire.MsgTx{}
|
||||
r := bytes.NewReader(b)
|
||||
if err := t.Deserialize(r); err != nil {
|
||||
|
@ -135,7 +134,7 @@ func (p *BitcoinBlockParser) ParseTx(b []byte) (*bchain.Tx, error) {
|
|||
}
|
||||
|
||||
// ParseBlock parses raw block to our Block struct
|
||||
func (p *BitcoinBlockParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
||||
func (p *BitcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
||||
w := wire.MsgBlock{}
|
||||
r := bytes.NewReader(b)
|
||||
|
||||
|
@ -152,7 +151,7 @@ func (p *BitcoinBlockParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
|||
}
|
||||
|
||||
// PackTx packs transaction to byte array
|
||||
func (p *BitcoinBlockParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
|
||||
func (p *BitcoinParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
|
||||
buf := make([]byte, 4+vlq.MaxLen64+len(tx.Hex)/2)
|
||||
binary.BigEndian.PutUint32(buf[0:4], height)
|
||||
vl := vlq.PutInt(buf[4:4+vlq.MaxLen64], blockTime)
|
||||
|
@ -161,7 +160,7 @@ func (p *BitcoinBlockParser) PackTx(tx *bchain.Tx, height uint32, blockTime int6
|
|||
}
|
||||
|
||||
// UnpackTx unpacks transaction from byte array
|
||||
func (p *BitcoinBlockParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
||||
func (p *BitcoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
||||
height := binary.BigEndian.Uint32(buf)
|
||||
bt, l := vlq.Int(buf[4:])
|
||||
tx, err := p.ParseTx(buf[4+l:])
|
||||
|
@ -172,6 +171,32 @@ func (p *BitcoinBlockParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
|||
return tx, height, nil
|
||||
}
|
||||
|
||||
func (p *BitcoinBlockParser) IsUTXOChain() bool {
|
||||
// PackedTxidLen returns length in bytes of packed txid
|
||||
func (p *BitcoinParser) PackedTxidLen() int {
|
||||
return 32
|
||||
}
|
||||
|
||||
// PackTxid packs txid to byte array
|
||||
func (p *BitcoinParser) PackTxid(txid string) ([]byte, error) {
|
||||
return hex.DecodeString(txid)
|
||||
}
|
||||
|
||||
// UnpackTxid unpacks byte array to txid
|
||||
func (p *BitcoinParser) UnpackTxid(buf []byte) (string, error) {
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
// PackBlockHash packs block hash to byte array
|
||||
func (p *BitcoinParser) PackBlockHash(hash string) ([]byte, error) {
|
||||
return hex.DecodeString(hash)
|
||||
}
|
||||
|
||||
// UnpackBlockHash unpacks byte array to block hash
|
||||
func (p *BitcoinParser) UnpackBlockHash(buf []byte) (string, error) {
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
// IsUTXOChain returns true if the block chain is UTXO type, otherwise false
|
||||
func (p *BitcoinParser) IsUTXOChain() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ func TestAddressToOutputScript(t *testing.T) {
|
|||
wantErr: false,
|
||||
},
|
||||
}
|
||||
parser := &BitcoinBlockParser{Params: GetChainParams("main")}
|
||||
parser := &BitcoinParser{Params: GetChainParams("main")}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -94,7 +94,7 @@ func TestOutputScriptToAddresses(t *testing.T) {
|
|||
wantErr: false,
|
||||
},
|
||||
}
|
||||
parser := &BitcoinBlockParser{Params: GetChainParams("main")}
|
||||
parser := &BitcoinParser{Params: GetChainParams("main")}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
b, _ := hex.DecodeString(tt.args.script)
|
||||
|
@ -185,7 +185,7 @@ func Test_PackTx(t *testing.T) {
|
|||
tx bchain.Tx
|
||||
height uint32
|
||||
blockTime int64
|
||||
parser *BitcoinBlockParser
|
||||
parser *BitcoinParser
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -199,7 +199,7 @@ func Test_PackTx(t *testing.T) {
|
|||
tx: testTx1,
|
||||
height: 123456,
|
||||
blockTime: 1519053802,
|
||||
parser: &BitcoinBlockParser{Params: GetChainParams("main")},
|
||||
parser: &BitcoinParser{Params: GetChainParams("main")},
|
||||
},
|
||||
want: testTxPacked1,
|
||||
wantErr: false,
|
||||
|
@ -210,7 +210,7 @@ func Test_PackTx(t *testing.T) {
|
|||
tx: testTx2,
|
||||
height: 510234,
|
||||
blockTime: 1235678901,
|
||||
parser: &BitcoinBlockParser{Params: GetChainParams("test")},
|
||||
parser: &BitcoinParser{Params: GetChainParams("test")},
|
||||
},
|
||||
want: testTxPacked2,
|
||||
wantErr: false,
|
||||
|
@ -234,7 +234,7 @@ func Test_PackTx(t *testing.T) {
|
|||
func Test_UnpackTx(t *testing.T) {
|
||||
type args struct {
|
||||
packedTx string
|
||||
parser *BitcoinBlockParser
|
||||
parser *BitcoinParser
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -247,7 +247,7 @@ func Test_UnpackTx(t *testing.T) {
|
|||
name: "btc-1",
|
||||
args: args{
|
||||
packedTx: testTxPacked1,
|
||||
parser: &BitcoinBlockParser{Params: GetChainParams("main")},
|
||||
parser: &BitcoinParser{Params: GetChainParams("main")},
|
||||
},
|
||||
want: &testTx1,
|
||||
want1: 123456,
|
||||
|
@ -257,7 +257,7 @@ func Test_UnpackTx(t *testing.T) {
|
|||
name: "testnet-1",
|
||||
args: args{
|
||||
packedTx: testTxPacked2,
|
||||
parser: &BitcoinBlockParser{Params: GetChainParams("test")},
|
||||
parser: &BitcoinParser{Params: GetChainParams("test")},
|
||||
},
|
||||
want: &testTx2,
|
||||
want1: 510234,
|
||||
|
|
|
@ -83,7 +83,7 @@ func (b *BitcoinRPC) Initialize() error {
|
|||
params := GetChainParams(chainName)
|
||||
|
||||
// always create parser
|
||||
b.Parser = &BitcoinBlockParser{
|
||||
b.Parser = &BitcoinParser{
|
||||
Params: params,
|
||||
}
|
||||
|
||||
|
|
|
@ -98,9 +98,11 @@ func ethTxToTx(tx *rpcTransaction, blocktime int64, confirmations uint32) (*bcha
|
|||
}, nil
|
||||
}
|
||||
|
||||
// EthereumParser handle
|
||||
type EthereumParser struct {
|
||||
}
|
||||
|
||||
// GetAddrIDFromVout returns internal address representation of given transaction output
|
||||
func (p *EthereumParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error) {
|
||||
if len(output.ScriptPubKey.Addresses) != 1 {
|
||||
return nil, bchain.ErrAddressMissing
|
||||
|
@ -108,6 +110,7 @@ func (p *EthereumParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error)
|
|||
return p.GetAddrIDFromAddress(output.ScriptPubKey.Addresses[0])
|
||||
}
|
||||
|
||||
// GetAddrIDFromAddress returns internal address representation of given address
|
||||
func (p *EthereumParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
||||
// github.com/ethereum/go-ethereum/common.HexToAddress does not handle address errors, using own decoding
|
||||
if len(address) > 1 {
|
||||
|
@ -126,18 +129,22 @@ func (p *EthereumParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
|||
return hex.DecodeString(address)
|
||||
}
|
||||
|
||||
// AddressToOutputScript converts address to ScriptPubKey - currently not implemented
|
||||
func (p *EthereumParser) AddressToOutputScript(address string) ([]byte, error) {
|
||||
return nil, errors.New("AddressToOutputScript: not implemented")
|
||||
}
|
||||
|
||||
// OutputScriptToAddresses converts ScriptPubKey to addresses - currently not implemented
|
||||
func (p *EthereumParser) OutputScriptToAddresses(script []byte) ([]string, error) {
|
||||
return nil, errors.New("OutputScriptToAddresses: not implemented")
|
||||
}
|
||||
|
||||
// ParseTx parses byte array containing transaction and returns Tx struct - currently not implemented
|
||||
func (p *EthereumParser) ParseTx(b []byte) (*bchain.Tx, error) {
|
||||
return nil, errors.New("ParseTx: not implemented")
|
||||
}
|
||||
|
||||
// ParseBlock parses raw block to our Block struct - currently not implemented
|
||||
func (p *EthereumParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
||||
return nil, errors.New("ParseBlock: not implemented")
|
||||
}
|
||||
|
@ -164,6 +171,7 @@ func hexEncodeBig(b []byte) string {
|
|||
return hexutil.EncodeBig(&i)
|
||||
}
|
||||
|
||||
// PackTx packs transaction to byte array
|
||||
func (p *EthereumParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
|
||||
b, err := hex.DecodeString(tx.Hex)
|
||||
if err != nil {
|
||||
|
@ -219,6 +227,7 @@ func (p *EthereumParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) (
|
|||
return proto.Marshal(pt)
|
||||
}
|
||||
|
||||
// UnpackTx unpacks transaction from byte array
|
||||
func (p *EthereumParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
||||
var pt ProtoTransaction
|
||||
err := proto.Unmarshal(buf, &pt)
|
||||
|
@ -247,6 +256,32 @@ func (p *EthereumParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
|||
return tx, pt.BlockNumber, nil
|
||||
}
|
||||
|
||||
// PackedTxidLen returns length in bytes of packed txid
|
||||
func (p *EthereumParser) PackedTxidLen() int {
|
||||
return 32
|
||||
}
|
||||
|
||||
// PackTxid packs txid to byte array
|
||||
func (p *EthereumParser) PackTxid(txid string) ([]byte, error) {
|
||||
return hex.DecodeString(txid)
|
||||
}
|
||||
|
||||
// UnpackTxid unpacks byte array to txid
|
||||
func (p *EthereumParser) UnpackTxid(buf []byte) (string, error) {
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
// PackBlockHash packs block hash to byte array
|
||||
func (p *EthereumParser) PackBlockHash(hash string) ([]byte, error) {
|
||||
return hex.DecodeString(hash)
|
||||
}
|
||||
|
||||
// UnpackBlockHash unpacks byte array to block hash
|
||||
func (p *EthereumParser) UnpackBlockHash(buf []byte) (string, error) {
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
// IsUTXOChain returns true if the block chain is UTXO type, otherwise false
|
||||
func (p *EthereumParser) IsUTXOChain() bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -5,13 +5,15 @@ import (
|
|||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/gob"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type ZCashBlockParser struct{}
|
||||
// ZCashParser handle
|
||||
type ZCashParser struct{}
|
||||
|
||||
// GetAddrIDFromAddress returns internal address representation of given transaction output
|
||||
func (p *ZCashBlockParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error) {
|
||||
// GetAddrIDFromVout returns internal address representation of given transaction output
|
||||
func (p *ZCashParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error) {
|
||||
if len(output.ScriptPubKey.Addresses) != 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -20,13 +22,13 @@ func (p *ZCashBlockParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error
|
|||
}
|
||||
|
||||
// GetAddrIDFromAddress returns internal address representation of given address
|
||||
func (p *ZCashBlockParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
||||
func (p *ZCashParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
||||
hash, _, err := CheckDecode(address)
|
||||
return hash, err
|
||||
}
|
||||
|
||||
// PackTx packs transaction to byte array
|
||||
func (p *ZCashBlockParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
|
||||
func (p *ZCashParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
|
||||
buf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(buf, height)
|
||||
buf, err := encodeTx(buf, tx)
|
||||
|
@ -44,7 +46,7 @@ func encodeTx(b []byte, tx *bchain.Tx) ([]byte, error) {
|
|||
}
|
||||
|
||||
// UnpackTx unpacks transaction from byte array
|
||||
func (p *ZCashBlockParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
||||
func (p *ZCashParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
||||
height := binary.BigEndian.Uint32(buf)
|
||||
tx, err := decodeTx(buf[4:])
|
||||
if err != nil {
|
||||
|
@ -63,22 +65,52 @@ func decodeTx(buf []byte) (*bchain.Tx, error) {
|
|||
return tx, nil
|
||||
}
|
||||
|
||||
func (p *ZCashBlockParser) AddressToOutputScript(address string) ([]byte, error) {
|
||||
// AddressToOutputScript converts address to ScriptPubKey - currently not implemented
|
||||
func (p *ZCashParser) AddressToOutputScript(address string) ([]byte, error) {
|
||||
return nil, errors.New("AddressToOutputScript: not implemented")
|
||||
}
|
||||
|
||||
func (p *ZCashBlockParser) OutputScriptToAddresses(script []byte) ([]string, error) {
|
||||
// OutputScriptToAddresses converts ScriptPubKey to addresses - currently not implemented
|
||||
func (p *ZCashParser) OutputScriptToAddresses(script []byte) ([]string, error) {
|
||||
return nil, errors.New("OutputScriptToAddresses: not implemented")
|
||||
}
|
||||
|
||||
func (p *ZCashBlockParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
||||
// ParseBlock parses raw block to our Block struct - currently not implemented
|
||||
func (p *ZCashParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
||||
return nil, errors.New("ParseBlock: not implemented")
|
||||
}
|
||||
|
||||
func (p *ZCashBlockParser) ParseTx(b []byte) (*bchain.Tx, error) {
|
||||
// ParseTx parses byte array containing transaction and returns Tx struct - currently not implemented
|
||||
func (p *ZCashParser) ParseTx(b []byte) (*bchain.Tx, error) {
|
||||
return nil, errors.New("ParseTx: not implemented")
|
||||
}
|
||||
|
||||
func (p *ZCashBlockParser) IsUTXOChain() bool {
|
||||
// PackedTxidLen returns length in bytes of packed txid
|
||||
func (p *ZCashParser) PackedTxidLen() int {
|
||||
return 32
|
||||
}
|
||||
|
||||
// PackTxid packs txid to byte array
|
||||
func (p *ZCashParser) PackTxid(txid string) ([]byte, error) {
|
||||
return hex.DecodeString(txid)
|
||||
}
|
||||
|
||||
// UnpackTxid unpacks byte array to txid
|
||||
func (p *ZCashParser) UnpackTxid(buf []byte) (string, error) {
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
// PackBlockHash packs block hash to byte array
|
||||
func (p *ZCashParser) PackBlockHash(hash string) ([]byte, error) {
|
||||
return hex.DecodeString(hash)
|
||||
}
|
||||
|
||||
// UnpackBlockHash unpacks byte array to block hash
|
||||
func (p *ZCashParser) UnpackBlockHash(buf []byte) (string, error) {
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
// IsUTXOChain returns true if the block chain is UTXO type, otherwise false
|
||||
func (p *ZCashParser) IsUTXOChain() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ func TestPackTx(t *testing.T) {
|
|||
tx bchain.Tx
|
||||
height uint32
|
||||
blockTime int64
|
||||
parser *ZCashBlockParser
|
||||
parser *ZCashParser
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -101,7 +101,7 @@ func TestPackTx(t *testing.T) {
|
|||
tx: testTx1,
|
||||
height: 292272,
|
||||
blockTime: 1521645728,
|
||||
parser: &ZCashBlockParser{},
|
||||
parser: &ZCashParser{},
|
||||
},
|
||||
want: testTxPacked1,
|
||||
wantErr: false,
|
||||
|
@ -112,7 +112,7 @@ func TestPackTx(t *testing.T) {
|
|||
tx: testTx2,
|
||||
height: 292217,
|
||||
blockTime: 1521637604,
|
||||
parser: &ZCashBlockParser{},
|
||||
parser: &ZCashParser{},
|
||||
},
|
||||
want: testTxPacked2,
|
||||
wantErr: false,
|
||||
|
@ -136,7 +136,7 @@ func TestPackTx(t *testing.T) {
|
|||
func TestUnpackTx(t *testing.T) {
|
||||
type args struct {
|
||||
packedTx string
|
||||
parser *ZCashBlockParser
|
||||
parser *ZCashParser
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -149,7 +149,7 @@ func TestUnpackTx(t *testing.T) {
|
|||
name: "zec-1",
|
||||
args: args{
|
||||
packedTx: testTxPacked1,
|
||||
parser: &ZCashBlockParser{},
|
||||
parser: &ZCashParser{},
|
||||
},
|
||||
want: &testTx1,
|
||||
want1: 292272,
|
||||
|
@ -159,7 +159,7 @@ func TestUnpackTx(t *testing.T) {
|
|||
name: "zec-2",
|
||||
args: args{
|
||||
packedTx: testTxPacked2,
|
||||
parser: &ZCashBlockParser{},
|
||||
parser: &ZCashParser{},
|
||||
},
|
||||
want: &testTx2,
|
||||
want1: 292217,
|
||||
|
|
|
@ -26,7 +26,7 @@ func NewZCashRPC(config json.RawMessage, pushHandler func(bchain.NotificationTyp
|
|||
|
||||
func (z *ZCashRPC) Initialize() error {
|
||||
z.Mempool = bchain.NewUTXOMempool(z)
|
||||
z.Parser = &ZCashBlockParser{}
|
||||
z.Parser = &ZCashParser{}
|
||||
z.Testnet = false
|
||||
z.Network = "livenet"
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ func (e *RPCError) Error() string {
|
|||
return fmt.Sprintf("%d: %s", e.Code, e.Message)
|
||||
}
|
||||
|
||||
// BlockChain defines common interface to block chain daemon
|
||||
type BlockChain interface {
|
||||
// life-cycle methods
|
||||
Initialize() error
|
||||
|
@ -127,6 +128,7 @@ type BlockChain interface {
|
|||
GetChainParser() BlockChainParser
|
||||
}
|
||||
|
||||
// BlockChainParser defines common interface to parsing and conversions of block chain data
|
||||
type BlockChainParser interface {
|
||||
// self description
|
||||
// UTXO chains need "inputs" column in db, that map transactions to transactions that spend them
|
||||
|
@ -139,9 +141,14 @@ type BlockChainParser interface {
|
|||
AddressToOutputScript(address string) ([]byte, error)
|
||||
OutputScriptToAddresses(script []byte) ([]string, error)
|
||||
// transactions
|
||||
PackedTxidLen() int
|
||||
PackTxid(txid string) ([]byte, error)
|
||||
UnpackTxid(buf []byte) (string, error)
|
||||
ParseTx(b []byte) (*Tx, error)
|
||||
PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, error)
|
||||
UnpackTx(buf []byte) (*Tx, uint32, error)
|
||||
// blocks
|
||||
PackBlockHash(hash string) ([]byte, error)
|
||||
UnpackBlockHash(buf []byte) (string, error)
|
||||
ParseBlock(b []byte) (*Block, error)
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ func (d *RocksDB) GetTransactions(address string, lower uint32, higher uint32, f
|
|||
if bytes.Compare(key, kstop) > 0 {
|
||||
break
|
||||
}
|
||||
outpoints, err := unpackOutputValue(val)
|
||||
outpoints, err := d.unpackOutputValue(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ func (d *RocksDB) addAddrIDToRecords(op int, wb *gorocksdb.WriteBatch, records m
|
|||
})
|
||||
if op == opDelete {
|
||||
// remove transactions from cache
|
||||
b, err := packTxid(txid)
|
||||
b, err := d.chainParser.PackTxid(txid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ func (d *RocksDB) writeOutputs(wb *gorocksdb.WriteBatch, block *bchain.Block, op
|
|||
|
||||
switch op {
|
||||
case opInsert:
|
||||
val, err := packOutputValue(outpoints)
|
||||
val, err := d.packOutputValue(outpoints)
|
||||
if err != nil {
|
||||
glog.Warningf("rocksdb: packOutputValue: %v", err)
|
||||
continue
|
||||
|
@ -346,10 +346,10 @@ func packOutputKey(outputScript []byte, height uint32) ([]byte, error) {
|
|||
return buf, nil
|
||||
}
|
||||
|
||||
func packOutputValue(outpoints []outpoint) ([]byte, error) {
|
||||
func (d *RocksDB) packOutputValue(outpoints []outpoint) ([]byte, error) {
|
||||
buf := make([]byte, 0)
|
||||
for _, o := range outpoints {
|
||||
btxid, err := packTxid(o.txid)
|
||||
btxid, err := d.chainParser.PackTxid(o.txid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -360,14 +360,15 @@ func packOutputValue(outpoints []outpoint) ([]byte, error) {
|
|||
return buf, nil
|
||||
}
|
||||
|
||||
func unpackOutputValue(buf []byte) ([]outpoint, error) {
|
||||
func (d *RocksDB) unpackOutputValue(buf []byte) ([]outpoint, error) {
|
||||
txidUnpackedLen := d.chainParser.PackedTxidLen()
|
||||
outpoints := make([]outpoint, 0)
|
||||
for i := 0; i < len(buf); {
|
||||
txid, err := unpackTxid(buf[i : i+txIdUnpackedLen])
|
||||
txid, err := d.chainParser.UnpackTxid(buf[i : i+txidUnpackedLen])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
i += txIdUnpackedLen
|
||||
i += txidUnpackedLen
|
||||
vout, voutLen := unpackVarint(buf[i:])
|
||||
i += voutLen
|
||||
outpoints = append(outpoints, outpoint{
|
||||
|
@ -390,11 +391,11 @@ func (d *RocksDB) writeInputs(
|
|||
if input.Coinbase != "" {
|
||||
continue
|
||||
}
|
||||
key, err := packOutpoint(input.Txid, int32(input.Vout))
|
||||
key, err := d.packOutpoint(input.Txid, int32(input.Vout))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val, err := packOutpoint(tx.Txid, int32(i))
|
||||
val, err := d.packOutpoint(tx.Txid, int32(i))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -409,8 +410,8 @@ func (d *RocksDB) writeInputs(
|
|||
return nil
|
||||
}
|
||||
|
||||
func packOutpoint(txid string, vout int32) ([]byte, error) {
|
||||
btxid, err := packTxid(txid)
|
||||
func (d *RocksDB) packOutpoint(txid string, vout int32) ([]byte, error) {
|
||||
btxid, err := d.chainParser.PackTxid(txid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -421,10 +422,11 @@ func packOutpoint(txid string, vout int32) ([]byte, error) {
|
|||
return buf, nil
|
||||
}
|
||||
|
||||
func unpackOutpoint(buf []byte) (string, int32, int) {
|
||||
txid, _ := unpackTxid(buf[:txIdUnpackedLen])
|
||||
vout, o := unpackVarint(buf[txIdUnpackedLen:])
|
||||
return txid, vout, txIdUnpackedLen + o
|
||||
func (d *RocksDB) unpackOutpoint(buf []byte) (string, int32, int) {
|
||||
txidUnpackedLen := d.chainParser.PackedTxidLen()
|
||||
txid, _ := d.chainParser.UnpackTxid(buf[:txidUnpackedLen])
|
||||
vout, o := unpackVarint(buf[txidUnpackedLen:])
|
||||
return txid, vout, txidUnpackedLen + o
|
||||
}
|
||||
|
||||
// Block index
|
||||
|
@ -435,7 +437,7 @@ func (d *RocksDB) GetBestBlock() (uint32, string, error) {
|
|||
defer it.Close()
|
||||
if it.SeekToLast(); it.Valid() {
|
||||
bestHeight := unpackUint(it.Key().Data())
|
||||
val, err := unpackBlockValue(it.Value().Data())
|
||||
val, err := d.chainParser.UnpackBlockHash(it.Value().Data())
|
||||
if glog.V(1) {
|
||||
glog.Infof("rocksdb: bestblock %d %s", bestHeight, val)
|
||||
}
|
||||
|
@ -452,12 +454,12 @@ func (d *RocksDB) GetBlockHash(height uint32) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
defer val.Free()
|
||||
return unpackBlockValue(val.Data())
|
||||
return d.chainParser.UnpackBlockHash(val.Data())
|
||||
}
|
||||
|
||||
// GetSpentOutput returns output which is spent by input tx
|
||||
func (d *RocksDB) GetSpentOutput(txid string, i int32) (string, int32, error) {
|
||||
b, err := packOutpoint(txid, i)
|
||||
b, err := d.packOutpoint(txid, i)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
|
@ -466,7 +468,7 @@ func (d *RocksDB) GetSpentOutput(txid string, i int32) (string, int32, error) {
|
|||
return "", 0, err
|
||||
}
|
||||
defer val.Free()
|
||||
p, err := unpackOutputValue(val.Data())
|
||||
p, err := d.unpackOutputValue(val.Data())
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
|
@ -488,7 +490,7 @@ func (d *RocksDB) writeHeight(
|
|||
|
||||
switch op {
|
||||
case opInsert:
|
||||
val, err := packBlockValue(block.Hash)
|
||||
val, err := d.chainParser.PackBlockHash(block.Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -551,13 +553,13 @@ func (d *RocksDB) DisconnectBlocksFullScan(lower uint32, higher uint32) error {
|
|||
glog.Info("output ", hex.EncodeToString(outputKeys[i]))
|
||||
}
|
||||
wb.DeleteCF(d.cfh[cfOutputs], outputKeys[i])
|
||||
outpoints, err := unpackOutputValue(outputValues[i])
|
||||
outpoints, err := d.unpackOutputValue(outputValues[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, o := range outpoints {
|
||||
// delete from inputs
|
||||
boutpoint, err := packOutpoint(o.txid, o.vout)
|
||||
boutpoint, err := d.packOutpoint(o.txid, o.vout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -566,7 +568,7 @@ func (d *RocksDB) DisconnectBlocksFullScan(lower uint32, higher uint32) error {
|
|||
}
|
||||
wb.DeleteCF(d.cfh[cfInputs], boutpoint)
|
||||
// delete from txCache
|
||||
b, err := packTxid(o.txid)
|
||||
b, err := d.chainParser.PackTxid(o.txid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -609,7 +611,7 @@ func (d *RocksDB) DatabaseSizeOnDisk() int64 {
|
|||
|
||||
// GetTx returns transaction stored in db and height of the block containing it
|
||||
func (d *RocksDB) GetTx(txid string) (*bchain.Tx, uint32, error) {
|
||||
key, err := packTxid(txid)
|
||||
key, err := d.chainParser.PackTxid(txid)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
@ -627,7 +629,7 @@ func (d *RocksDB) GetTx(txid string) (*bchain.Tx, uint32, error) {
|
|||
|
||||
// PutTx stores transactions in db
|
||||
func (d *RocksDB) PutTx(tx *bchain.Tx, height uint32, blockTime int64) error {
|
||||
key, err := packTxid(tx.Txid)
|
||||
key, err := d.chainParser.PackTxid(tx.Txid)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -640,7 +642,7 @@ func (d *RocksDB) PutTx(tx *bchain.Tx, height uint32, blockTime int64) error {
|
|||
|
||||
// DeleteTx removes transactions from db
|
||||
func (d *RocksDB) DeleteTx(txid string) error {
|
||||
key, err := packTxid(txid)
|
||||
key, err := d.chainParser.PackTxid(txid)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -649,9 +651,6 @@ func (d *RocksDB) DeleteTx(txid string) error {
|
|||
|
||||
// Helpers
|
||||
|
||||
// TODO - this may be coin specific, refactor
|
||||
const txIdUnpackedLen = 32
|
||||
|
||||
var ErrInvalidAddress = errors.New("invalid address")
|
||||
|
||||
func packUint(i uint32) []byte {
|
||||
|
@ -695,19 +694,3 @@ func unpackVarint64(buf []byte) (int64, int) {
|
|||
i, ofs := vlq.Int(buf)
|
||||
return i, ofs
|
||||
}
|
||||
|
||||
func packTxid(txid string) ([]byte, error) {
|
||||
return hex.DecodeString(txid)
|
||||
}
|
||||
|
||||
func unpackTxid(buf []byte) (string, error) {
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
func packBlockValue(hash string) ([]byte, error) {
|
||||
return hex.DecodeString(hash)
|
||||
}
|
||||
|
||||
func unpackBlockValue(buf []byte) (string, error) {
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue