|
9 | 9 | #include <utility> |
10 | 10 | #include <vector> |
11 | 11 |
|
| 12 | +#include "rpc/server.h" |
| 13 | +#include "test/test_bitcoin.h" |
| 14 | +#include "validation.h" |
12 | 15 | #include "wallet/test/wallet_test_fixture.h" |
13 | 16 |
|
14 | 17 | #include <boost/foreach.hpp> |
15 | 18 | #include <boost/test/unit_test.hpp> |
| 19 | +#include <univalue.h> |
| 20 | + |
| 21 | +extern UniValue importmulti(const JSONRPCRequest& request); |
16 | 22 |
|
17 | 23 | // how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles |
18 | 24 | #define RUN_TESTS 100 |
@@ -355,4 +361,58 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) |
355 | 361 | empty_wallet(); |
356 | 362 | } |
357 | 363 |
|
| 364 | +BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) |
| 365 | +{ |
| 366 | + LOCK(cs_main); |
| 367 | + |
| 368 | + // Cap last block file size, and mine new block in a new block file. |
| 369 | + CBlockIndex* oldTip = chainActive.Tip(); |
| 370 | + GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; |
| 371 | + CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); |
| 372 | + CBlockIndex* newTip = chainActive.Tip(); |
| 373 | + |
| 374 | + // Verify ScanForWalletTransactions picks up transactions in both the old |
| 375 | + // and new block files. |
| 376 | + { |
| 377 | + CWallet wallet; |
| 378 | + LOCK(wallet.cs_wallet); |
| 379 | + wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); |
| 380 | + BOOST_CHECK_EQUAL(oldTip, wallet.ScanForWalletTransactions(oldTip)); |
| 381 | + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 100 * COIN); |
| 382 | + } |
| 383 | + |
| 384 | + // Prune the older block file. |
| 385 | + PruneOneBlockFile(oldTip->GetBlockPos().nFile); |
| 386 | + UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); |
| 387 | + |
| 388 | + // Verify ScanForWalletTransactions only picks transactions in the new block |
| 389 | + // file. |
| 390 | + { |
| 391 | + CWallet wallet; |
| 392 | + LOCK(wallet.cs_wallet); |
| 393 | + wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); |
| 394 | + BOOST_CHECK_EQUAL(newTip, wallet.ScanForWalletTransactions(oldTip)); |
| 395 | + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); |
| 396 | + } |
| 397 | + |
| 398 | + { |
| 399 | + CWallet wallet; |
| 400 | + ::pwalletMain = &wallet; |
| 401 | + UniValue key; |
| 402 | + key.setObject(); |
| 403 | + key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(coinbaseKey.GetPubKey()))); |
| 404 | + key.pushKV("timestamp", 0); |
| 405 | + key.pushKV("internal", UniValue(true)); |
| 406 | + UniValue keys; |
| 407 | + keys.setArray(); |
| 408 | + keys.push_back(key); |
| 409 | + JSONRPCRequest request; |
| 410 | + request.params.setArray(); |
| 411 | + request.params.push_back(keys); |
| 412 | + |
| 413 | + UniValue response = importmulti(request); |
| 414 | + BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}}]", newTip->GetBlockTimeMax())); |
| 415 | + } |
| 416 | +} |
| 417 | + |
358 | 418 | BOOST_AUTO_TEST_SUITE_END() |
0 commit comments