@@ -17,11 +17,15 @@ package accounts
1717import (
1818 "bytes"
1919 "errors"
20+ "io/ioutil"
21+ "path"
2022 "testing"
2123 "time"
2224
25+ "github.com/btcsuite/btcutil/hdkeychain"
2326 "github.com/digitalbitbox/bitbox-wallet-app/backend/coins/coin"
2427 "github.com/digitalbitbox/bitbox-wallet-app/backend/coins/coin/mocks"
28+ "github.com/digitalbitbox/bitbox-wallet-app/backend/signing"
2529 "github.com/digitalbitbox/bitbox-wallet-app/util/logging"
2630 "github.com/digitalbitbox/bitbox-wallet-app/util/test"
2731 "github.com/stretchr/testify/require"
@@ -38,20 +42,65 @@ func TestBaseAccount(t *testing.T) {
3842 }
3943 panic ("can't reach" )
4044 }
45+
46+ derivationPath , err := signing .NewAbsoluteKeypath ("m/84'/1'/0'" )
47+ require .NoError (t , err )
48+ const xpub = "tpubDCxoQyC5JaGydxN3yprM6sgqgu65LruN3JBm1fnSmGxXR3AcuNwr" +
49+ "E7J2CVaCvuLPJtJNySjshNsYbR96Y7yfEdcywYqWubzUQLVGh2b4mF9"
50+ extendedPublicKey , err := hdkeychain .NewKeyFromString (xpub )
51+ require .NoError (t , err )
52+
4153 const accountIdentifier = "test-account-identifier"
4254 cfg := & AccountConfig {
43- Code : "test" ,
44- Name : "Test" ,
45- DBFolder : test .TstTempDir ("baseaccount_test_dbfolder" ),
46- NotesFolder : test .TstTempDir ("baseaccount_test_notesfolder" ),
47- Keystores : nil ,
48- OnEvent : func (event Event ) { events <- event },
49- RateUpdater : nil ,
50- SigningConfigurations : nil ,
51- GetNotifier : nil ,
55+ Code : "test" ,
56+ Name : "Test" ,
57+ DBFolder : test .TstTempDir ("baseaccount_test_dbfolder" ),
58+ NotesFolder : test .TstTempDir ("baseaccount_test_notesfolder" ),
59+ Keystores : nil ,
60+ OnEvent : func (event Event ) { events <- event },
61+ RateUpdater : nil ,
62+ SigningConfigurations : signing.Configurations {
63+ signing .NewBitcoinConfiguration (signing .ScriptTypeP2PKH , []byte {1 , 2 , 3 , 4 }, derivationPath , extendedPublicKey ),
64+ signing .NewBitcoinConfiguration (signing .ScriptTypeP2WPKH , []byte {1 , 2 , 3 , 4 }, derivationPath , extendedPublicKey ),
65+ signing .NewBitcoinConfiguration (signing .ScriptTypeP2WPKHP2SH , []byte {1 , 2 , 3 , 4 }, derivationPath , extendedPublicKey ),
66+ },
67+ GetNotifier : nil ,
5268 }
69+ // The long ID in the filename is the legacy hash of the configurations above (unified and split).
70+ // This tests notes migration from v4.27.0 to v4.28.0.
71+ require .NoError (t ,
72+ ioutil .WriteFile (
73+ path .Join (cfg .NotesFolder , "account-54b4597c3a5c48177ef2b12c97e0cb30b6fef0b431e7821675b17704c330ce5d-tbtc.json" ),
74+ []byte (`{"transactions": { "legacy-1": "legacy note in unified account" }}` ),
75+ 0666 ,
76+ ),
77+ )
78+ require .NoError (t ,
79+ ioutil .WriteFile (
80+ path .Join (cfg .NotesFolder , "account-989b84ec36f0b84e7926f9f5715e4b59a0592993b1fa4b70836addbcb0cb6e09-tbtc-p2pkh.json" ),
81+ []byte (`{"transactions": { "legacy-2": "legacy note in split account, p2pkh" }}` ),
82+ 0666 ,
83+ ),
84+ )
85+ require .NoError (t ,
86+ ioutil .WriteFile (
87+ path .Join (cfg .NotesFolder , "account-e60b99507ba983d522f15932dbe1214e99de13c56e2bea75ed9c285f7c013117-tbtc-p2wpkh.json" ),
88+ []byte (`{"transactions": { "legacy-3": "legacy note in split account, p2wpkh" }}` ),
89+ 0666 ,
90+ ),
91+ )
92+ require .NoError (t ,
93+ ioutil .WriteFile (
94+ path .Join (cfg .NotesFolder , "account-9e779e0d49e77236f0769e0bab2fd656958d3fd023dce2388525ee66fead88bb-tbtc-p2wpkh-p2sh.json" ),
95+ []byte (`{"transactions": { "legacy-4": "legacy note in split account, p2wpkh-p2sh" }}` ),
96+ 0666 ,
97+ ),
98+ )
5399
54100 mockCoin := & mocks.CoinMock {
101+ CodeFunc : func () coin.Code {
102+ return coin .CodeTBTC
103+ },
55104 SmallestUnitFunc : func () string {
56105 return "satoshi"
57106 },
@@ -103,12 +152,26 @@ func TestBaseAccount(t *testing.T) {
103152 // Was cleared by the previous call.
104153 require .Equal (t , "" , account .GetAndClearProposedTxNote ())
105154
106- notes := account .Notes ()
107- require .NotNil (t , notes )
108-
109155 require .NoError (t , account .SetTxNote ("test-tx-id" , "another test note" ))
110156 require .Equal (t , EventStatusChanged , checkEvent ())
111- require .Equal (t , "another test note" , notes .TxNote ("test-tx-id" ))
157+ require .Equal (t , "another test note" , account .TxNote ("test-tx-id" ))
158+
159+ // Test notes migration from v4.27.0 to v4.28.0
160+ require .Equal (t , "legacy note in unified account" , account .TxNote ("legacy-1" ))
161+ require .Equal (t , "legacy note in split account, p2pkh" , account .TxNote ("legacy-2" ))
162+ require .Equal (t , "legacy note in split account, p2wpkh" , account .TxNote ("legacy-3" ))
163+ require .Equal (t , "legacy note in split account, p2wpkh-p2sh" , account .TxNote ("legacy-4" ))
164+ // Setting a note sets it in the main notes file, and wipes it out in legacy note files.
165+ require .NoError (t , account .SetTxNote ("legacy-1" , "updated legacy note" ))
166+ require .Equal (t , "updated legacy note" , account .TxNote ("legacy-1" ))
167+ contents , err := ioutil .ReadFile (path .Join (cfg .NotesFolder , "account-54b4597c3a5c48177ef2b12c97e0cb30b6fef0b431e7821675b17704c330ce5d-tbtc.json" ))
168+ require .NoError (t , err )
169+ require .JSONEq (t , `{"transactions":{}}` , string (contents ))
170+
171+ // Test that the notes were persisted under the right file name with the right contents.
172+ contents , err = ioutil .ReadFile (path .Join (cfg .NotesFolder , "test-account-identifier.json" ))
173+ require .NoError (t , err )
174+ require .JSONEq (t , `{"transactions":{"legacy-1": "updated legacy note", "test-tx-id": "another test note"}}` , string (contents ))
112175 })
113176
114177 t .Run ("exportCSV" , func (t * testing.T ) {
@@ -122,7 +185,7 @@ func TestBaseAccount(t *testing.T) {
122185
123186 require .Equal (t , header , export (nil ))
124187
125- require .NoError (t , account .notes . SetTxNote ("some-internal-tx-id" , "some note, with a comma" ))
188+ require .NoError (t , account .SetTxNote ("some-internal-tx-id" , "some note, with a comma" ))
126189 fee := coin .NewAmountFromInt64 (101 )
127190 timestamp := time .Date (2020 , 2 , 30 , 16 , 44 , 20 , 0 , time .UTC )
128191 require .Equal (t ,
0 commit comments