Update Zcoin transaction parser and bump binary version (#466)
This commit is contained in:
parent
2fb1e779c0
commit
79907e7aa5
6
bchain/coins/xzc/testdata/packedtxs.hex
vendored
6
bchain/coins/xzc/testdata/packedtxs.hex
vendored
File diff suppressed because one or more lines are too long
1
bchain/coins/xzc/testdata/rawblock.hex
vendored
1
bchain/coins/xzc/testdata/rawblock.hex
vendored
File diff suppressed because one or more lines are too long
2
bchain/coins/xzc/testdata/txs.hex
vendored
2
bchain/coins/xzc/testdata/txs.hex
vendored
File diff suppressed because one or more lines are too long
64
bchain/coins/xzc/zcoinmsgtx.go
Normal file
64
bchain/coins/xzc/zcoinmsgtx.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package xzc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/martinboehm/btcd/chaincfg/chainhash"
|
||||||
|
"github.com/martinboehm/btcd/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ZcoinMsgTx encapsulate zcoin tx and extra
|
||||||
|
type ZcoinMsgTx struct {
|
||||||
|
wire.MsgTx
|
||||||
|
Extra []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// TxHash calculate hash of transaction
|
||||||
|
func (msg *ZcoinMsgTx) TxHash() chainhash.Hash {
|
||||||
|
extraSize := uint64(len(msg.Extra))
|
||||||
|
sizeOfExtraSize := 0
|
||||||
|
if extraSize != 0 {
|
||||||
|
sizeOfExtraSize = wire.VarIntSerializeSize(extraSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Original payload
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0,
|
||||||
|
msg.SerializeSizeStripped()+sizeOfExtraSize+len(msg.Extra)))
|
||||||
|
_ = msg.SerializeNoWitness(buf)
|
||||||
|
|
||||||
|
// Extra payload
|
||||||
|
if extraSize != 0 {
|
||||||
|
wire.WriteVarInt(buf, 0, extraSize)
|
||||||
|
buf.Write(msg.Extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
return chainhash.DoubleHashH(buf.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// XzcDecode to decode bitcoin tx and extra
|
||||||
|
func (msg *ZcoinMsgTx) XzcDecode(r io.Reader, pver uint32, enc wire.MessageEncoding) error {
|
||||||
|
if err := msg.MsgTx.BtcDecode(r, pver, enc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// extra
|
||||||
|
version := uint32(msg.Version)
|
||||||
|
txVersion := version & 0xffff
|
||||||
|
txType := (version >> 16) & 0xffff
|
||||||
|
if txVersion == 3 && txType != 0 {
|
||||||
|
|
||||||
|
extraSize, err := wire.ReadVarInt(r, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Extra = make([]byte, extraSize)
|
||||||
|
_, err = io.ReadFull(r, msg.Extra[:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -28,6 +28,8 @@ const (
|
|||||||
MTPL = 64
|
MTPL = 64
|
||||||
|
|
||||||
SpendTxID = "0000000000000000000000000000000000000000000000000000000000000000"
|
SpendTxID = "0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
|
||||||
|
TransactionQuorumCommitmentType = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -125,6 +127,16 @@ func (p *ZcoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
|||||||
return p.BaseParser.UnpackTx(buf)
|
return p.BaseParser.UnpackTx(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TxFromZcoinMsgTx converts bitcoin wire Tx to bchain.Tx
|
||||||
|
func (p *ZcoinParser) TxFromZcoinMsgTx(t *ZcoinMsgTx, parseAddresses bool) bchain.Tx {
|
||||||
|
btx := p.TxFromMsgTx(&t.MsgTx, parseAddresses)
|
||||||
|
|
||||||
|
// NOTE: wire.MsgTx.TxHash() doesn't include extra
|
||||||
|
btx.Txid = t.TxHash().String()
|
||||||
|
|
||||||
|
return btx
|
||||||
|
}
|
||||||
|
|
||||||
// ParseBlock parses raw block to our Block struct
|
// ParseBlock parses raw block to our Block struct
|
||||||
func (p *ZcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
func (p *ZcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
||||||
reader := bytes.NewReader(b)
|
reader := bytes.NewReader(b)
|
||||||
@ -181,16 +193,37 @@ func (p *ZcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
|
|||||||
txs := make([]bchain.Tx, ntx)
|
txs := make([]bchain.Tx, ntx)
|
||||||
|
|
||||||
for i := uint64(0); i < ntx; i++ {
|
for i := uint64(0); i < ntx; i++ {
|
||||||
tx := wire.MsgTx{}
|
tx := ZcoinMsgTx{}
|
||||||
|
|
||||||
err := tx.BtcDecode(reader, 0, wire.WitnessEncoding)
|
// read version and seek back
|
||||||
if err != nil {
|
var version uint32 = 0
|
||||||
|
if err = binary.Read(reader, binary.LittleEndian, &version); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
btx := p.TxFromMsgTx(&tx, false)
|
if _, err = reader.Seek(-4, io.SeekCurrent); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
p.parseZcoinTx(&btx)
|
txVersion := version & 0xffff
|
||||||
|
txType := (version >> 16) & 0xffff
|
||||||
|
|
||||||
|
enc := wire.WitnessEncoding
|
||||||
|
|
||||||
|
// transaction quorum commitment could not be parsed with witness flag
|
||||||
|
if txVersion == 3 && txType == TransactionQuorumCommitmentType {
|
||||||
|
enc = wire.BaseEncoding
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = tx.XzcDecode(reader, 0, enc); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
btx := p.TxFromZcoinMsgTx(&tx, false)
|
||||||
|
|
||||||
|
if err = p.parseZcoinTx(&btx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
txs[i] = btx
|
txs[i] = btx
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,16 +13,18 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/martinboehm/btcd/wire"
|
||||||
"github.com/martinboehm/btcutil/chaincfg"
|
"github.com/martinboehm/btcutil/chaincfg"
|
||||||
"github.com/trezor/blockbook/bchain"
|
"github.com/trezor/blockbook/bchain"
|
||||||
"github.com/trezor/blockbook/bchain/coins/btc"
|
"github.com/trezor/blockbook/bchain/coins/btc"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testTx1, testTx2, testTx3, testTx4 bchain.Tx
|
testTx1, testTx2, testTx3, testTx4, testTx5, testTx6 bchain.Tx
|
||||||
testTxPacked1, testTxPacked2, testTxPacked3, testTxPacked4 string
|
rawTestTx1, rawTestTx2, rawTestTx3, rawTestTx4, rawTestTx5, rawTestTx6 string
|
||||||
rawBlock1, rawBlock2 string
|
testTxPacked1, testTxPacked2, testTxPacked3, testTxPacked4, testTxPacked5, testTxPacked6 string
|
||||||
jsonTx json.RawMessage
|
rawBlock1, rawBlock2, rawBlock3 string
|
||||||
|
jsonTx json.RawMessage
|
||||||
)
|
)
|
||||||
|
|
||||||
func readHexs(path string) []string {
|
func readHexs(path string) []string {
|
||||||
@ -39,12 +41,15 @@ func init() {
|
|||||||
rawBlocks := readHexs("./testdata/rawblock.hex")
|
rawBlocks := readHexs("./testdata/rawblock.hex")
|
||||||
rawBlock1 = rawBlocks[0]
|
rawBlock1 = rawBlocks[0]
|
||||||
rawBlock2 = rawBlocks[1]
|
rawBlock2 = rawBlocks[1]
|
||||||
|
rawBlock3 = rawBlocks[2]
|
||||||
|
|
||||||
hextxs := readHexs("./testdata/txs.hex")
|
hextxs := readHexs("./testdata/txs.hex")
|
||||||
rawTestTx1 := hextxs[0]
|
rawTestTx1 = hextxs[0]
|
||||||
rawTestTx2 := hextxs[1]
|
rawTestTx2 = hextxs[1]
|
||||||
rawTestTx3 := hextxs[2]
|
rawTestTx3 = hextxs[2]
|
||||||
rawTestTx4 := hextxs[3]
|
rawTestTx4 = hextxs[3]
|
||||||
|
rawTestTx5 = hextxs[4]
|
||||||
|
rawTestTx6 = hextxs[5]
|
||||||
|
|
||||||
rawSpendHex := readHexs("./testdata/rawspend.hex")[0]
|
rawSpendHex := readHexs("./testdata/rawspend.hex")[0]
|
||||||
|
|
||||||
@ -59,13 +64,15 @@ func init() {
|
|||||||
testTxPacked2 = testTxPackeds[1]
|
testTxPacked2 = testTxPackeds[1]
|
||||||
testTxPacked3 = testTxPackeds[2]
|
testTxPacked3 = testTxPackeds[2]
|
||||||
testTxPacked4 = testTxPackeds[3]
|
testTxPacked4 = testTxPackeds[3]
|
||||||
|
testTxPacked5 = testTxPackeds[4]
|
||||||
|
testTxPacked6 = testTxPackeds[5]
|
||||||
|
|
||||||
testTx1 = bchain.Tx{
|
testTx1 = bchain.Tx{
|
||||||
Hex: rawTestTx1,
|
Hex: rawTestTx1,
|
||||||
Blocktime: 1533980594,
|
Blocktime: 1533980594,
|
||||||
Time: 1533980594,
|
Time: 1533980594,
|
||||||
Txid: "9d9e759dd970d86df9e105a7d4f671543bc16a03b6c5d2b48895f2a00aa7dd23",
|
Txid: "9d9e759dd970d86df9e105a7d4f671543bc16a03b6c5d2b48895f2a00aa7dd23",
|
||||||
LockTime: 0,
|
LockTime: 99688,
|
||||||
Vin: []bchain.Vin{
|
Vin: []bchain.Vin{
|
||||||
{
|
{
|
||||||
ScriptSig: bchain.ScriptSig{
|
ScriptSig: bchain.ScriptSig{
|
||||||
@ -78,14 +85,14 @@ func init() {
|
|||||||
},
|
},
|
||||||
Vout: []bchain.Vout{
|
Vout: []bchain.Vout{
|
||||||
{
|
{
|
||||||
ValueSat: *big.NewInt(18188266638),
|
ValueSat: *big.NewInt(100000000),
|
||||||
N: 0,
|
N: 0,
|
||||||
ScriptPubKey: bchain.ScriptPubKey{
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
Hex: "c10280004c80f767f3ee79953c67a7ed386dcccf1243619eb4bbbe414a3982dd94a83c1b69ac52d6ab3b653a3e05c4e4516c8dfe1e58ada40461bc5835a4a0d0387a51c29ac11b72ae25bbcdef745f50ad08f08b3e9bc2c31a35444398a490e65ac090e9f341f1abdebe47e57e8237ac25d098e951b4164a35caea29f30acb50b12e4425df28",
|
Hex: "c10280004c80f767f3ee79953c67a7ed386dcccf1243619eb4bbbe414a3982dd94a83c1b69ac52d6ab3b653a3e05c4e4516c8dfe1e58ada40461bc5835a4a0d0387a51c29ac11b72ae25bbcdef745f50ad08f08b3e9bc2c31a35444398a490e65ac090e9f341f1abdebe47e57e8237ac25d098e951b4164a35caea29f30acb50b12e4425df28",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ValueSat: *big.NewInt(18188266638),
|
ValueSat: *big.NewInt(871824000),
|
||||||
N: 1,
|
N: 1,
|
||||||
ScriptPubKey: bchain.ScriptPubKey{
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
Hex: "76a914c963f917c7f23cb4243e079db33107571b87690588ac",
|
Hex: "76a914c963f917c7f23cb4243e079db33107571b87690588ac",
|
||||||
@ -105,9 +112,7 @@ func init() {
|
|||||||
LockTime: 0,
|
LockTime: 0,
|
||||||
Vin: []bchain.Vin{
|
Vin: []bchain.Vin{
|
||||||
{
|
{
|
||||||
ScriptSig: bchain.ScriptSig{
|
Coinbase: rawSpendHex,
|
||||||
Hex: rawSpendHex,
|
|
||||||
},
|
|
||||||
Txid: "0000000000000000000000000000000000000000000000000000000000000000",
|
Txid: "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
Vout: 4294967295,
|
Vout: 4294967295,
|
||||||
Sequence: 2,
|
Sequence: 2,
|
||||||
@ -226,7 +231,7 @@ func init() {
|
|||||||
ScriptPubKey: bchain.ScriptPubKey{
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
Hex: "76a914ff71b0c9c2a90c6164a50a2fb523eb54a8a6b55088ac",
|
Hex: "76a914ff71b0c9c2a90c6164a50a2fb523eb54a8a6b55088ac",
|
||||||
Addresses: []string{
|
Addresses: []string{
|
||||||
"a1HwTdCmQV3NspP2QqCGpehoFpi8NY4Zg3",
|
"aQ18FBVFtnueucZKeVg4srhmzbpAeb1KoN",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -250,6 +255,103 @@ func init() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// TODO: test segwit
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
testTx5 = bchain.Tx{
|
||||||
|
Hex: rawTestTx5,
|
||||||
|
Blocktime: 1591752749,
|
||||||
|
Time: 1591752749,
|
||||||
|
Txid: "8d1f32f35c32d2c127a7400dc1ec52049fbf0b8bcdf284cfaa3da59b6169a22d",
|
||||||
|
LockTime: 0,
|
||||||
|
Vin: []bchain.Vin{},
|
||||||
|
Vout: []bchain.Vout{},
|
||||||
|
}
|
||||||
|
|
||||||
|
testTx6 = bchain.Tx{
|
||||||
|
Hex: rawTestTx6,
|
||||||
|
Blocktime: 1591762049,
|
||||||
|
Time: 1591762049,
|
||||||
|
Txid: "e5767d3606230a65f150837a6f28b4f0e4c2702a683045df3883d57702739c61",
|
||||||
|
LockTime: 0,
|
||||||
|
Vin: []bchain.Vin{
|
||||||
|
{
|
||||||
|
Coinbase: "02b4140101",
|
||||||
|
Sequence: 4294967295,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Vout: []bchain.Vout{
|
||||||
|
{
|
||||||
|
ValueSat: *big.NewInt(1400000000),
|
||||||
|
N: 0,
|
||||||
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
|
Hex: "2103fb09a216761d5e7f248294970c2370f7f84ce1ad564b8e7096b1e19116af1d52ac",
|
||||||
|
Addresses: []string{
|
||||||
|
"TAn9Ghkp31myXRgejCj11wWVHT14Lsj349",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ValueSat: *big.NewInt(50000000),
|
||||||
|
N: 1,
|
||||||
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
|
Hex: "76a914296134d2415bf1f2b518b3f673816d7e603b160088ac",
|
||||||
|
Addresses: []string{
|
||||||
|
"TDk19wPKYq91i18qmY6U9FeTdTxwPeSveo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ValueSat: *big.NewInt(50000000),
|
||||||
|
N: 2,
|
||||||
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
|
Hex: "76a914e1e1dc06a889c1b6d3eb00eef7a96f6a7cfb884888ac",
|
||||||
|
Addresses: []string{
|
||||||
|
"TWZZcDGkNixTAMtRBqzZkkMHbq1G6vUTk5",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ValueSat: *big.NewInt(50000000),
|
||||||
|
N: 3,
|
||||||
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
|
Hex: "76a914ab03ecfddee6330497be894d16c29ae341c123aa88ac",
|
||||||
|
Addresses: []string{
|
||||||
|
"TRZTFdNCKCKbLMQV8cZDkQN9Vwuuq4gDzT",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ValueSat: *big.NewInt(150000000),
|
||||||
|
N: 4,
|
||||||
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
|
Hex: "76a9144281a58a1d5b2d3285e00cb45a8492debbdad4c588ac",
|
||||||
|
Addresses: []string{
|
||||||
|
"TG2ruj59E5b1u9G3F7HQVs6pCcVDBxrQve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ValueSat: *big.NewInt(50000000),
|
||||||
|
N: 5,
|
||||||
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
|
Hex: "76a9141fd264c0bb53bd9fef18e2248ddf1383d6e811ae88ac",
|
||||||
|
Addresses: []string{
|
||||||
|
"TCsTzQZKVn4fao8jDmB9zQBk9YQNEZ3XfS",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ValueSat: *big.NewInt(750000000),
|
||||||
|
N: 6,
|
||||||
|
ScriptPubKey: bchain.ScriptPubKey{
|
||||||
|
Hex: "76a91471a3892d164ffa3829078bf9ad5f114a3908ce5588ac",
|
||||||
|
Addresses: []string{
|
||||||
|
"TLL5GQULX4uBfz7yXL6VcZyvzdKVv1RGxm",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -474,6 +576,28 @@ func TestPackTx(t *testing.T) {
|
|||||||
want: testTxPacked4,
|
want: testTxPacked4,
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "xzc-quorum-commitment-tx",
|
||||||
|
args: args{
|
||||||
|
tx: testTx5,
|
||||||
|
height: 5268,
|
||||||
|
blockTime: 1591752749,
|
||||||
|
parser: NewZcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: testTxPacked5,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "xzc-special-coinbase-tx",
|
||||||
|
args: args{
|
||||||
|
tx: testTx6,
|
||||||
|
height: 5300,
|
||||||
|
blockTime: 1591762049,
|
||||||
|
parser: NewZcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: testTxPacked6,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@ -545,6 +669,26 @@ func TestUnpackTx(t *testing.T) {
|
|||||||
want1: 100001,
|
want1: 100001,
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "xzc-special-tx",
|
||||||
|
args: args{
|
||||||
|
packedTx: testTxPacked5,
|
||||||
|
parser: NewZcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: &testTx5,
|
||||||
|
want1: 5268,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "xzc-special-coinbase-tx",
|
||||||
|
args: args{
|
||||||
|
packedTx: testTxPacked6,
|
||||||
|
parser: NewZcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: &testTx6,
|
||||||
|
want1: 5300,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@ -609,6 +753,21 @@ func TestParseBlock(t *testing.T) {
|
|||||||
wantTxs: 4,
|
wantTxs: 4,
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "special-tx-block",
|
||||||
|
args: args{
|
||||||
|
rawBlock: rawBlock3,
|
||||||
|
parser: NewZcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: &bchain.Block{
|
||||||
|
BlockHeader: bchain.BlockHeader{
|
||||||
|
Size: 200062,
|
||||||
|
Time: 1591752749,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantTxs: 3,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -632,3 +791,191 @@ func TestParseBlock(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecodeTransaction(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
enc wire.MessageEncoding
|
||||||
|
rawTransaction string
|
||||||
|
parser *ZcoinParser
|
||||||
|
privacyType byte // 0 as non privacy
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bchain.Tx
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "normal-transaction",
|
||||||
|
args: args{
|
||||||
|
enc: wire.WitnessEncoding,
|
||||||
|
rawTransaction: rawTestTx1,
|
||||||
|
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: testTx1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "coinbase-zcoinspend",
|
||||||
|
args: args{
|
||||||
|
enc: wire.WitnessEncoding,
|
||||||
|
rawTransaction: rawTestTx2,
|
||||||
|
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||||
|
privacyType: OpSigmaSpend,
|
||||||
|
},
|
||||||
|
want: testTx2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "normal-transaction-2",
|
||||||
|
args: args{
|
||||||
|
enc: wire.WitnessEncoding,
|
||||||
|
rawTransaction: rawTestTx3,
|
||||||
|
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: testTx3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "coinbase-transaction",
|
||||||
|
args: args{
|
||||||
|
enc: wire.WitnessEncoding,
|
||||||
|
rawTransaction: rawTestTx4,
|
||||||
|
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: testTx4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "quorum-commitment-transaction",
|
||||||
|
args: args{
|
||||||
|
enc: wire.BaseEncoding,
|
||||||
|
rawTransaction: rawTestTx5,
|
||||||
|
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: testTx5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "quorum-commitment-transaction-witness",
|
||||||
|
args: args{
|
||||||
|
enc: wire.WitnessEncoding,
|
||||||
|
rawTransaction: rawTestTx5,
|
||||||
|
parser: NewZcoinParser(GetChainParams("main"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "special-coinbase",
|
||||||
|
args: args{
|
||||||
|
enc: wire.WitnessEncoding,
|
||||||
|
rawTransaction: rawTestTx6,
|
||||||
|
parser: NewZcoinParser(GetChainParams("test"), &btc.Configuration{}),
|
||||||
|
},
|
||||||
|
want: testTx6,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
b, _ := hex.DecodeString(tt.args.rawTransaction)
|
||||||
|
r := bytes.NewReader(b)
|
||||||
|
|
||||||
|
msg := ZcoinMsgTx{}
|
||||||
|
err := msg.XzcDecode(r, 0, tt.args.enc)
|
||||||
|
|
||||||
|
if tt.wantErr {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Want error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := tt.args.parser.TxFromZcoinMsgTx(&msg, true)
|
||||||
|
if pErr := tt.args.parser.parseZcoinTx(&got); pErr != nil {
|
||||||
|
t.Fatal(pErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Len() != 0 {
|
||||||
|
t.Errorf("Expected EOF but there are remaining %d bytes to read", r.Len())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(got.Vin) != len(tt.want.Vin) {
|
||||||
|
t.Errorf("Check vin size, got %v, want %v", len(got.Vin), len(tt.want.Vin))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i != len(got.Vin); i++ {
|
||||||
|
if !reflect.DeepEqual(got.Vin[i].Addresses, tt.want.Vin[i].Addresses) {
|
||||||
|
t.Errorf("Check Addresses at input %d, got %v, want %v",
|
||||||
|
i, got.Vin[i].Addresses, tt.want.Vin[i].Addresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got.Vin[i].Coinbase, tt.want.Vin[i].Coinbase) {
|
||||||
|
t.Errorf("Check Coinbase at input %d, got %v, want %v",
|
||||||
|
i, got.Vin[i].Coinbase, tt.want.Vin[i].Coinbase)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got.Vin[i].ScriptSig, tt.want.Vin[i].ScriptSig) {
|
||||||
|
t.Errorf("Check ScriptSig at input %d, got %v, want %v",
|
||||||
|
i, got.Vin[i].ScriptSig, tt.want.Vin[i].ScriptSig)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got.Vin[i].Sequence, tt.want.Vin[i].Sequence) {
|
||||||
|
t.Errorf("Check Sequence at input %d, got %v, want %v",
|
||||||
|
i, got.Vin[i].Sequence, tt.want.Vin[i].Sequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.args.privacyType == 0 && !reflect.DeepEqual(got.Vin[i].Txid, tt.want.Vin[i].Txid) {
|
||||||
|
t.Errorf("Check Txid at input %d, got %v, want %v",
|
||||||
|
i, got.Vin[i].Txid, tt.want.Vin[i].Txid)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.args.privacyType == 0 && !reflect.DeepEqual(got.Vin[i].Vout, tt.want.Vin[i].Vout) {
|
||||||
|
t.Errorf("Check Vout at input %d, got %v, want %v",
|
||||||
|
i, got.Vin[i].Vout, tt.want.Vin[i].Vout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(got.Vout) != len(tt.want.Vout) {
|
||||||
|
t.Errorf("Check vout size, got %v, want %v", len(got.Vout), len(tt.want.Vout))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i != len(got.Vout); i++ {
|
||||||
|
if !reflect.DeepEqual(got.Vout[i].JsonValue, tt.want.Vout[i].JsonValue) {
|
||||||
|
t.Errorf("Check JsonValue at output %d, got %v, want %v",
|
||||||
|
i, got.Vout[i].JsonValue, tt.want.Vout[i].JsonValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got.Vout[i].N, tt.want.Vout[i].N) {
|
||||||
|
t.Errorf("Check N at output %d, got %v, want %v",
|
||||||
|
i, got.Vout[i].N, tt.want.Vout[i].N)
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty addresses and null should be the same
|
||||||
|
if !((len(got.Vout[i].ScriptPubKey.Addresses) == 0 && len(got.Vout[i].ScriptPubKey.Addresses) == len(tt.want.Vout[i].ScriptPubKey.Addresses)) ||
|
||||||
|
reflect.DeepEqual(got.Vout[i].ScriptPubKey.Addresses, tt.want.Vout[i].ScriptPubKey.Addresses)) {
|
||||||
|
t.Errorf("Check ScriptPubKey.Addresses at output %d, got %v, want %v",
|
||||||
|
i, got.Vout[i].ScriptPubKey.Addresses, tt.want.Vout[i].ScriptPubKey.Addresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got.Vout[i].ScriptPubKey.Hex, tt.want.Vout[i].ScriptPubKey.Hex) {
|
||||||
|
t.Errorf("Check ScriptPubKey.Hex at output %d, got %v, want %v",
|
||||||
|
i, got.Vout[i].ScriptPubKey.Hex, tt.want.Vout[i].ScriptPubKey.Hex)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got.Vout[i].ValueSat, tt.want.Vout[i].ValueSat) {
|
||||||
|
t.Errorf("Check ValueSat at output %d, got %v, want %v",
|
||||||
|
i, got.Vout[i].ValueSat, tt.want.Vout[i].ValueSat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if got.LockTime != tt.want.LockTime {
|
||||||
|
t.Errorf("Check LockTime, got %v, want %v", got.LockTime, tt.want.LockTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got.Txid != tt.want.Txid {
|
||||||
|
t.Errorf("Check TxId, got %v, want %v", got.Txid, tt.want.Txid)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -22,24 +22,70 @@
|
|||||||
"package_name": "backend-zcoin",
|
"package_name": "backend-zcoin",
|
||||||
"package_revision": "satoshilabs-1",
|
"package_revision": "satoshilabs-1",
|
||||||
"system_user": "zcoin",
|
"system_user": "zcoin",
|
||||||
"version": "0.13.8.8",
|
"version": "0.14.0.4",
|
||||||
"binary_url": "https://github.com/zcoinofficial/zcoin/releases/download/v0.13.8.8/zcoin-0.13.8.8-linux64.tar.gz",
|
"binary_url": "https://github.com/zcoinofficial/zcoin/releases/download/v0.14.0.4/zcoin-0.14.0.4-linux64.tar.gz",
|
||||||
"verification_type": "sha256",
|
"verification_type": "sha256",
|
||||||
"verification_source": "badab4c7e42cb7ce567c1e02a700b52f7ea3f55780e4e180b89596ad940f7189",
|
"verification_source": "d060c76fe5fc0fe2527485035e984413881c4a845f65c4c9e71cc298b227a816",
|
||||||
"extract_command": "tar -C backend --strip 1 -xf",
|
"extract_command": "tar -C backend --strip 1 -xf",
|
||||||
"exclude_files": [
|
"exclude_files": [
|
||||||
"bin/tor",
|
"bin/tor",
|
||||||
"bin/tor-gencert",
|
"bin/tor-gencert",
|
||||||
"bin/tor-print-ed-signing-cert",
|
|
||||||
"bin/torify",
|
"bin/torify",
|
||||||
|
"bin/tor-print-ed-signing-cert",
|
||||||
"bin/tor-resolve",
|
"bin/tor-resolve",
|
||||||
"bin/zcoin-qt",
|
"bin/zcoin-qt",
|
||||||
"bin/zcoin-tx",
|
"bin/zcoin-tx",
|
||||||
"etc/tor/torrc.sample",
|
"etc/tor/torrc.sample",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/cmake/relic-config.cmake",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/aggregationinfo.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/bls.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/chaincode.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/extendedprivatekey.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/extendedpublickey.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/privatekey.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/publickey.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/signature.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/test-utils.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/chiabls/util.hpp",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/low/relic_bn_low.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/low/relic_dv_low.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/low/relic_fb_low.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/low/relic_fp_low.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/low/relic_fpx_low.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_arch.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_bc.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_bench.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_bn.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_conf.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_core.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_cp.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_dv.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_eb.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_ec.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_ed.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_ep.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_epx.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_err.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_fb.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_fbx.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_fp.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_fpx.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_label.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_md.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_pc.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_pool.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_pp.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_rand.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_test.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_trace.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_types.h",
|
||||||
|
"home/ubuntu/build/zcoin/depends/x86_64-linux-gnu/include/relic_util.h",
|
||||||
"include/bitcoinconsensus.h",
|
"include/bitcoinconsensus.h",
|
||||||
"lib/libbitcoinconsensus.so",
|
"lib/libbitcoinconsensus.so",
|
||||||
"lib/libbitcoinconsensus.so.0",
|
"lib/libbitcoinconsensus.so.0",
|
||||||
"lib/libbitcoinconsensus.so.0.0.0",
|
"lib/libbitcoinconsensus.so.0.0.0",
|
||||||
|
"README.md",
|
||||||
"share/tor/geoip",
|
"share/tor/geoip",
|
||||||
"share/tor/geoip6"
|
"share/tor/geoip6"
|
||||||
],
|
],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user