Move packing/unpacking of Txid and Block Hash to coin specific code

indexv1
Martin Boehm 2018-04-08 11:24:29 +02:00
parent 8a8952d103
commit a75376706e
9 changed files with 170 additions and 88 deletions

View File

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

View File

@ -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,

View File

@ -83,7 +83,7 @@ func (b *BitcoinRPC) Initialize() error {
params := GetChainParams(chainName)
// always create parser
b.Parser = &BitcoinBlockParser{
b.Parser = &BitcoinParser{
Params: params,
}

View File

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

View File

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

View File

@ -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,

View File

@ -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"

View File

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

View File

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