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