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

Fix V5 transaction txid (#392) #393

Merged
merged 1 commit into from
May 24, 2022
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
30 changes: 30 additions & 0 deletions common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ type (
Satoshis uint64
Height int
}

// reply to getblock verbose=1 (json includes txid list)
ZcashRpcReplyGetblock1 struct {
Tx []string
}
)

// FirstRPC tests that we can successfully reach zcashd through the RPC
Expand Down Expand Up @@ -271,6 +276,31 @@ func getBlockFromRPC(height int) (*walletrpc.CompactBlock, error) {
return nil, errors.New("received unexpected height block")
}

// `block.ParseFromSlice` correctly parses blocks containing v5 transactions, but
// incorrectly computes the IDs of the v5 transactions. We temporarily paper over this
// bug by fetching the correct txids via a second getblock RPC call.
// https://github.com/zcash/lightwalletd/issues/392
{
params[1] = json.RawMessage("1") // JSON with list of txids
result, rpcErr := RawRequest("getblock", params)
if rpcErr != nil {
return nil, errors.Wrap(rpcErr, "error requesting verbose block")
}
var block1 ZcashRpcReplyGetblock1
err = json.Unmarshal(result, &block1)
if err != nil {
return nil, err
}
for i, t := range block.Transactions() {
txid, err := hex.DecodeString(block1.Tx[i])
if err != nil {
return nil, errors.Wrap(err, "error decoding getblock txid")
}
// convert from big-endian
t.SetTxID(parser.Reverse(txid))
}
}

return block.ToCompact(), nil
}

Expand Down
23 changes: 8 additions & 15 deletions parser/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package parser

import (
"crypto/sha256"
"fmt"

"github.com/pkg/errors"
Expand Down Expand Up @@ -339,29 +338,23 @@ func (p *action) ToCompact() *walletrpc.CompactOrchardAction {
// Transaction encodes a full (zcashd) transaction.
type Transaction struct {
*rawTransaction
rawBytes []byte
cachedTxID []byte // cached for performance
rawBytes []byte
txID []byte // from getblock verbose=1
}

func (tx *Transaction) SetTxID(txid []byte) {
tx.txID = txid
}

// GetDisplayHash returns the transaction hash in big-endian display order.
func (tx *Transaction) GetDisplayHash() []byte {
if tx.cachedTxID != nil {
return tx.cachedTxID
}

// SHA256d
digest := sha256.Sum256(tx.rawBytes)
digest = sha256.Sum256(digest[:])
// Convert to big-endian
tx.cachedTxID = Reverse(digest[:])
return tx.cachedTxID
return Reverse(tx.txID[:])
}

// GetEncodableHash returns the transaction hash in little-endian wire format order.
func (tx *Transaction) GetEncodableHash() []byte {
digest := sha256.Sum256(tx.rawBytes)
digest = sha256.Sum256(digest[:])
return digest[:]
return tx.txID
LarryRuane marked this conversation as resolved.
Show resolved Hide resolved
}

// Bytes returns a full transaction's raw bytes.
Expand Down
7 changes: 3 additions & 4 deletions parser/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package parser

import (
"bytes"
"encoding/hex"
"encoding/json"
"os"
Expand Down Expand Up @@ -85,9 +84,9 @@ func TestV5TransactionParser(t *testing.T) {
if len(rest) != 0 {
t.Fatalf("Test did not consume entire buffer, %d remaining", len(rest))
}
if bytes.Equal(tx.cachedTxID, []byte(txtestdata.Txid)) {
t.Fatal("txid")
}
// Currently, we can't check the txid because we get that from
// zcashd (getblock rpc) rather than computing it ourselves.
LarryRuane marked this conversation as resolved.
Show resolved Hide resolved
// https://github.com/zcash/lightwalletd/issues/392
if tx.version != uint32(txtestdata.Version) {
t.Fatal("version miscompare")
}
Expand Down