diff --git a/backend/coins/btc/transactions/transactions_test.go b/backend/coins/btc/transactions/transactions_test.go index eeb00ff88f..6e933979b6 100644 --- a/backend/coins/btc/transactions/transactions_test.go +++ b/backend/coins/btc/transactions/transactions_test.go @@ -15,6 +15,7 @@ package transactions_test import ( + "encoding/json" "os" "testing" @@ -190,6 +191,39 @@ func (s *transactionsSuite) TestUpdateAddressHistorySingleTxReceive() { require.Equal(s.T(), expectedHeight, transactions[0].Height) } +// 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 (s *transactionsSuite) TestTxSerialization() { + // create a new Tx + addresses, err := s.addressChain.EnsureAddresses() + require.NoError(s.T(), err) + address := addresses[0] + expectedAmount := btcutil.Amount(123) + tx1 := newTx(chainhash.HashH(nil), 0, address, expectedAmount) + + // marshal & unmarshal transaction with current method. + tx1Serialized, err := json.Marshal(tx1) + require.NoError(s.T(), err) + s.log.Print("Tx marshaled: " + string(tx1Serialized)) + var tx2 *wire.MsgTx + err = json.Unmarshal(tx1Serialized, &tx2) + require.NoError(s.T(), err) + + // marshal prevout hash with legacy method. + hashBytes := [32]byte(tx1.TxIn[0].PreviousOutPoint.Hash.CloneBytes()) + legacyMarshalledHash, err := json.Marshal(hashBytes) + require.NoError(s.T(), err) + + // build a serialized tx string which is identical to the previous tx, except for the prevout hash and unmarshal it. + tx2serialized := "{\"Version\":1,\"TxIn\":[{\"PreviousOutPoint\":{\"Hash\":" + string(legacyMarshalledHash) + ",\"Index\":0},\"SignatureScript\":null,\"Witness\":null,\"Sequence\":4294967295}],\"TxOut\":[{\"Value\":123,\"PkScript\":\"dqkU+tJNI2oRHKW1g4q4XbLEvaq3w76IrA==\"}],\"LockTime\":0}" + err = json.Unmarshal([]byte(tx2serialized), &tx2) + require.NoError(s.T(), err) + + // check prevout hashes. + require.Equal(s.T(), tx1.TxIn[0].PreviousOutPoint.Hash.String(), tx2.TxIn[0].PreviousOutPoint.Hash.String()) +} + // TestSpendableOutputs checks that the utxo set is correct. Only confirmed (or unconfirmed outputs // we own) outputs can be spent. func (s *transactionsSuite) TestSpendableOutputs() {