Skip to content

Commit 9df61b4

Browse files
committed
backend/transactions: add test for tx serialization
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.
1 parent 27ebf6c commit 9df61b4

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

backend/coins/btc/db/transactionsdb/transactionsdb_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package transactionsdb
1616

1717
import (
1818
"encoding/hex"
19+
"encoding/json"
1920
"path"
2021
"reflect"
2122
"testing"
@@ -25,6 +26,7 @@ import (
2526
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/blockchain"
2627
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/types"
2728
"github.com/BitBoxSwiss/bitbox-wallet-app/util/test"
29+
"github.com/btcsuite/btcd/btcutil"
2830
"github.com/btcsuite/btcd/chaincfg/chainhash"
2931
"github.com/btcsuite/btcd/wire"
3032
"github.com/stretchr/testify/require"
@@ -83,6 +85,83 @@ func getRawValue(tx *Tx, bucketKey string, key []byte) []byte {
8385
return tx.tx.Bucket([]byte(bucketKey)).Get(key)
8486
}
8587

88+
// TestTxSerialization checks that Tx marshaling/unmarshaling work with both current and legacy
89+
// chainhash.Hash marshaling methods.
90+
// see https://github.com/btcsuite/btcd/pull/2025.
91+
func TestTxSerialization(t *testing.T) {
92+
db := getDB()
93+
defer func() {
94+
if err := db.Close(); err != nil {
95+
panic(err)
96+
}
97+
}()
98+
dbTx, err := db.Begin(true)
99+
require.NoError(t, err)
100+
defer dbTx.Rollback()
101+
102+
// create a new Tx
103+
amount := btcutil.Amount(123)
104+
tx := &wire.MsgTx{
105+
Version: wire.TxVersion,
106+
TxIn: []*wire.TxIn{
107+
wire.NewTxIn(&wire.OutPoint{Hash: chainhash.HashH(nil), Index: 0}, nil, nil),
108+
},
109+
TxOut: []*wire.TxOut{wire.NewTxOut(int64(amount), []byte("dummyPubKeyScript"))},
110+
LockTime: 0,
111+
}
112+
txHash := tx.TxHash()
113+
114+
dbTx.PutTx(txHash, tx, 999)
115+
116+
retrievedTx, err := dbTx.TxInfo(txHash)
117+
require.NoError(t, err)
118+
require.Equal(t, txHash, retrievedTx.Tx.TxHash())
119+
120+
// Override tx bytes marshaling the prevout hash with legacy method.
121+
transactionsBucket, err := dbTx.(*Tx).tx.CreateBucketIfNotExists([]byte(bucketTransactionsKey))
122+
require.NoError(t, err)
123+
124+
hashBytes := [32]byte(tx.TxIn[0].PreviousOutPoint.Hash.CloneBytes())
125+
legacyMarshalledHash, err := json.Marshal(hashBytes)
126+
require.NoError(t, err)
127+
legacySerializedTx := `{
128+
"Tx": {
129+
"Version": 1,
130+
"TxIn": [
131+
{
132+
"PreviousOutPoint": {
133+
"Hash": ` + string(legacyMarshalledHash) + `,
134+
"Index": 0
135+
},
136+
"SignatureScript": null,
137+
"Witness": null,
138+
"Sequence": 4294967295
139+
}
140+
],
141+
"TxOut": [
142+
{
143+
"Value": 123,
144+
"PkScript": "ZHVtbXlQdWJLZXlTY3JpcHQ="
145+
}
146+
],
147+
"LockTime": 0
148+
},
149+
"Height": 999,
150+
"addresses": {},
151+
"Verified": null,
152+
"ts": null,
153+
"created": "2024-05-08T17:26:36.224472769+02:00"
154+
}`
155+
156+
err = transactionsBucket.Put(txHash[:], []byte(legacySerializedTx))
157+
require.NoError(t, err)
158+
159+
retrievedTx2, err := dbTx.TxInfo(txHash)
160+
require.NoError(t, err)
161+
require.NotNil(t, retrievedTx2)
162+
require.Equal(t, retrievedTx.Tx.TxHash(), retrievedTx2.Tx.TxHash())
163+
}
164+
86165
// TestTxQuick tests the tx related db functions on random data.
87166
func TestTxQuick(t *testing.T) {
88167
testTx(func(tx *Tx) {

0 commit comments

Comments
 (0)