Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

from trezor #13

Merged
merged 7 commits into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions bchain/coins/xzc/testdata/packedtxs.hex

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions bchain/coins/xzc/testdata/rawblock.hex

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions bchain/coins/xzc/testdata/txs.hex

Large diffs are not rendered by default.

64 changes: 64 additions & 0 deletions bchain/coins/xzc/zcoinmsgtx.go
Original file line number Diff line number Diff line change
@@ -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
}
43 changes: 38 additions & 5 deletions bchain/coins/xzc/zcoinparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const (
MTPL = 64

SpendTxID = "0000000000000000000000000000000000000000000000000000000000000000"

TransactionQuorumCommitmentType = 6
)

var (
Expand Down Expand Up @@ -125,6 +127,16 @@ func (p *ZcoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
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
func (p *ZcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
reader := bytes.NewReader(b)
Expand Down Expand Up @@ -181,16 +193,37 @@ func (p *ZcoinParser) ParseBlock(b []byte) (*bchain.Block, error) {
txs := make([]bchain.Tx, ntx)

for i := uint64(0); i < ntx; i++ {
tx := wire.MsgTx{}
tx := ZcoinMsgTx{}

err := tx.BtcDecode(reader, 0, wire.WitnessEncoding)
if err != nil {
// read version and seek back
var version uint32 = 0
if err = binary.Read(reader, binary.LittleEndian, &version); err != nil {
return nil, err
}

if _, err = reader.Seek(-4, io.SeekCurrent); err != nil {
return nil, err
}

btx := p.TxFromMsgTx(&tx, false)
txVersion := version & 0xffff
txType := (version >> 16) & 0xffff

p.parseZcoinTx(&btx)
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
}
Expand Down
Loading