@@ -70,38 +70,45 @@ bool HasAnyRecordOfType(WalletDatabase& db, const std::string& key)
7070 return false ;
7171}
7272
73- BOOST_FIXTURE_TEST_CASE (wallet_load_verif_crypted_key_checksum, TestingSetup)
73+ template <typename ... Args>
74+ SerializeData MakeSerializeData (const Args&... args)
7475{
75- // The test duplicates the db so each case has its own db instance.
76- int NUMBER_OF_TESTS = 4 ;
77- std::vector<std::unique_ptr<WalletDatabase>> dbs;
78- CKey first_key;
79- auto get_db = [](std::vector<std::unique_ptr<WalletDatabase>>& dbs) {
80- std::unique_ptr<WalletDatabase> db = std::move (dbs.back ());
81- dbs.pop_back ();
82- return db;
83- };
84-
85- { // Context setup.
76+ CDataStream s (0 , 0 );
77+ SerializeMany (s, args...);
78+ return {s.begin (), s.end ()};
79+ }
80+
81+
82+ BOOST_FIXTURE_TEST_CASE (wallet_load_ckey, TestingSetup)
83+ {
84+ SerializeData ckey_record_key;
85+ SerializeData ckey_record_value;
86+ std::map<SerializeData, SerializeData> records;
87+
88+ {
89+ // Context setup.
8690 // Create and encrypt legacy wallet
8791 std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , CreateMockableWalletDatabase ()));
8892 LOCK (wallet->cs_wallet );
8993 auto legacy_spkm = wallet->GetOrCreateLegacyScriptPubKeyMan ();
9094 BOOST_CHECK (legacy_spkm->SetupGeneration (true ));
9195
92- // Get the first key in the wallet
96+ // Retrieve a key
9397 CTxDestination dest = *Assert (legacy_spkm->GetNewDestination (OutputType::LEGACY));
9498 CKeyID key_id = GetKeyForDestination (*legacy_spkm, dest);
99+ CKey first_key;
95100 BOOST_CHECK (legacy_spkm->GetKey (key_id, first_key));
96101
97- // Encrypt the wallet and duplicate database
102+ // Encrypt the wallet
98103 BOOST_CHECK (wallet->EncryptWallet (" encrypt" ));
99104 wallet->Flush ();
100105
101- DatabaseOptions options;
102- for (int i=0 ; i < NUMBER_OF_TESTS; i++) {
103- dbs.emplace_back (DuplicateMockDatabase (wallet->GetDatabase ()));
104- }
106+ // Store a copy of all the records
107+ records = GetMockableDatabase (*wallet).m_records ;
108+
109+ // Get the record for the retrieved key
110+ ckey_record_key = MakeSerializeData (DBKeys::CRYPTED_KEY, first_key.GetPubKey ());
111+ ckey_record_value = records.at (ckey_record_key);
105112 }
106113
107114 {
@@ -112,7 +119,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_load_verif_crypted_key_checksum, TestingSetup)
112119 // the records every time that 'CWallet::Unlock' gets called, which is not good.
113120
114121 // Load the wallet and check that is encrypted
115- std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , get_db (dbs )));
122+ std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , CreateMockableWalletDatabase (records )));
116123 BOOST_CHECK_EQUAL (wallet->LoadWallet (), DBErrors::LOAD_OK);
117124 BOOST_CHECK (wallet->IsCrypted ());
118125 BOOST_CHECK (HasAnyRecordOfType (wallet->GetDatabase (), DBKeys::CRYPTED_KEY));
@@ -127,18 +134,12 @@ BOOST_FIXTURE_TEST_CASE(wallet_load_verif_crypted_key_checksum, TestingSetup)
127134 {
128135 // Second test case:
129136 // Verify that loading up a 'ckey' with no checksum triggers a complete re-write of the crypted keys.
130- std::unique_ptr<WalletDatabase> db = get_db (dbs);
131- {
132- std::unique_ptr<DatabaseBatch> batch = db->MakeBatch (false );
133- std::pair<std::vector<unsigned char >, uint256> value;
134- BOOST_CHECK (batch->Read (std::make_pair (DBKeys::CRYPTED_KEY, first_key.GetPubKey ()), value));
135137
136- const auto key = std::make_pair (DBKeys::CRYPTED_KEY, first_key.GetPubKey ());
137- BOOST_CHECK (batch->Write (key, value.first , /* fOverwrite=*/ true ));
138- }
138+ // Cut off the 32 byte checksum from a ckey record
139+ records[ckey_record_key].resize (ckey_record_value.size () - 32 );
139140
140141 // Load the wallet and check that is encrypted
141- std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , std::move (db )));
142+ std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , CreateMockableWalletDatabase (records )));
142143 BOOST_CHECK_EQUAL (wallet->LoadWallet (), DBErrors::LOAD_OK);
143144 BOOST_CHECK (wallet->IsCrypted ());
144145 BOOST_CHECK (HasAnyRecordOfType (wallet->GetDatabase (), DBKeys::CRYPTED_KEY));
@@ -154,35 +155,25 @@ BOOST_FIXTURE_TEST_CASE(wallet_load_verif_crypted_key_checksum, TestingSetup)
154155 {
155156 // Third test case:
156157 // Verify that loading up a 'ckey' with an invalid checksum throws an error.
157- std::unique_ptr<WalletDatabase> db = get_db (dbs);
158- {
159- std::unique_ptr<DatabaseBatch> batch = db->MakeBatch (false );
160- std::vector<unsigned char > crypted_data;
161- BOOST_CHECK (batch->Read (std::make_pair (DBKeys::CRYPTED_KEY, first_key.GetPubKey ()), crypted_data));
162-
163- // Write an invalid checksum
164- std::pair<std::vector<unsigned char >, uint256> value = std::make_pair (crypted_data, uint256::ONE);
165- const auto key = std::make_pair (DBKeys::CRYPTED_KEY, first_key.GetPubKey ());
166- BOOST_CHECK (batch->Write (key, value, /* fOverwrite=*/ true ));
167- }
168-
169- std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , std::move (db)));
158+
159+ // Cut off the 32 byte checksum from a ckey record
160+ records[ckey_record_key].resize (ckey_record_value.size () - 32 );
161+ // Fill in the checksum space with 0s
162+ records[ckey_record_key].resize (ckey_record_value.size ());
163+
164+ std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , CreateMockableWalletDatabase (records)));
170165 BOOST_CHECK_EQUAL (wallet->LoadWallet (), DBErrors::CORRUPT);
171166 }
172167
173168 {
174169 // Fourth test case:
175170 // Verify that loading up a 'ckey' with an invalid pubkey throws an error
176- std::unique_ptr<WalletDatabase> db = get_db (dbs);
177- {
178- CPubKey invalid_key;
179- BOOST_ASSERT (!invalid_key.IsValid ());
180- const auto key = std::make_pair (DBKeys::CRYPTED_KEY, invalid_key);
181- std::pair<std::vector<unsigned char >, uint256> value;
182- BOOST_CHECK (db->MakeBatch (false )->Write (key, value, /* fOverwrite=*/ true ));
183- }
184-
185- std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , std::move (db)));
171+ CPubKey invalid_key;
172+ BOOST_ASSERT (!invalid_key.IsValid ());
173+ SerializeData key = MakeSerializeData (DBKeys::CRYPTED_KEY, invalid_key);
174+ records[key] = ckey_record_value;
175+
176+ std::shared_ptr<CWallet> wallet (new CWallet (m_node.chain .get (), " " , CreateMockableWalletDatabase (records)));
186177 BOOST_CHECK_EQUAL (wallet->LoadWallet (), DBErrors::CORRUPT);
187178 }
188179}
0 commit comments