Skip to content

Commit

Permalink
backend/transactions: add test for tx serialization
Browse files Browse the repository at this point in the history
Recent btcd updates changed the way hashes are serialized. We proposed a
fix (see btcsuite/btcd#2025) to restore backward
compatibility.

This commit adds a specific test case to ensure that the newer and the
legacy serialization methods work.
  • Loading branch information
Beerosagos committed May 9, 2024
1 parent 7f33634 commit 0833165
Showing 1 changed file with 91 additions and 0 deletions.
91 changes: 91 additions & 0 deletions backend/coins/btc/db/transactionsdb/transactionsdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ package transactionsdb

import (
"encoding/hex"
"encoding/json"
"path"
"reflect"
"testing"
"testing/quick"
"time"

"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/addresses"
addressesTest "github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/addresses/test"
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/blockchain"
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/types"
"github.com/digitalbitbox/bitbox-wallet-app/util/test"
Expand Down Expand Up @@ -83,6 +87,93 @@ func getRawValue(tx *Tx, bucketKey string, key []byte) []byte {
return tx.tx.Bucket([]byte(bucketKey)).Get(key)
}

// TestTxSerialization checks that Tx marshaling/unmarshaling work with both current and legacy
// chainhash.Hash marshaling methods.
// see https://github.com/btcsuite/btcd/pull/2025.
func TestTxSerialization(t *testing.T) {
db := getDB()
defer func() {
if err := db.Close(); err != nil {
panic(err)
}
}()
dbTx, err := db.Begin(true)
if err != nil {
panic(err)
}
defer dbTx.Rollback()

// create a new Tx
_, addressChain := addressesTest.NewAddressChain(
func(address *addresses.AccountAddress) (bool, error) {
return false, nil
},
)
addresses, err := addressChain.EnsureAddresses()
require.NoError(t, err)
address := addresses[0]
amount := btcutil.Amount(123)
tx := &wire.MsgTx{
Version: wire.TxVersion,
TxIn: []*wire.TxIn{
wire.NewTxIn(&wire.OutPoint{Hash: chainhash.HashH(nil), Index: 0}, nil, nil),
},
TxOut: []*wire.TxOut{wire.NewTxOut(int64(amount), address.PubkeyScript())},
LockTime: 0,
}
txHash := tx.TxHash()

dbTx.PutTx(txHash, tx, 999)

retrievedTx, err := dbTx.TxInfo(txHash)
require.NoError(t, err)
require.Equal(t, txHash, retrievedTx.Tx.TxHash())

// Override tx bytes marshaling the prevout hash with legacy method.
transactionsBucket, err := dbTx.(*Tx).tx.CreateBucketIfNotExists([]byte(bucketTransactionsKey))
require.NoError(t, err)

hashBytes := [32]byte(tx.TxIn[0].PreviousOutPoint.Hash.CloneBytes())
legacyMarshalledHash, err := json.Marshal(hashBytes)
require.NoError(t, err)
legacySerializedTx := `{
"Tx": {
"Version": 1,
"TxIn": [
{
"PreviousOutPoint": {
"Hash": ` + string(legacyMarshalledHash) + `,
"Index": 0
},
"SignatureScript": null,
"Witness": null,
"Sequence": 4294967295
}
],
"TxOut": [
{
"Value": 123,
"PkScript": "dqkU+tJNI2oRHKW1g4q4XbLEvaq3w76IrA=="
}
],
"LockTime": 0
},
"Height": 999,
"addresses": {},
"Verified": null,
"ts": null,
"created": "2024-05-08T17:26:36.224472769+02:00"
}`

err = transactionsBucket.Put(txHash[:], []byte(legacySerializedTx))
require.NoError(t, err)

retrievedTx2, err := dbTx.TxInfo(txHash)
require.NoError(t, err)
require.NotNil(t, retrievedTx2)
require.Equal(t, retrievedTx.Tx.TxHash(), retrievedTx2.Tx.TxHash())
}

// TestTxQuick tests the tx related db functions on random data.
func TestTxQuick(t *testing.T) {
testTx(func(tx *Tx) {
Expand Down

0 comments on commit 0833165

Please sign in to comment.