@@ -275,7 +275,12 @@ std::string HelpMessage(HelpMessageMode mode)
275
275
#ifndef WIN32
276
276
strUsage += HelpMessageOpt (" -pid=<file>" , strprintf (_ (" Specify pid file (default: %s)" ), " bitcoind.pid" ));
277
277
#endif
278
- strUsage += HelpMessageOpt (" -reindex" , _ (" Rebuild block chain index from current blk000??.dat files" ) + " " + _ (" on startup" ));
278
+ strUsage += HelpMessageOpt (" -prune=<n>" , _ (" Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex." ) + " " +
279
+ _ (" Warning: Reverting this setting requires re-downloading the entire blockchain." ) + " " +
280
+ _ (" (default: 0 = disable pruning blocks," ) + " " +
281
+ strprintf (_ (" >%u = target size in MiB to use for block files)" ), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024 ));
282
+ strUsage += HelpMessageOpt (" -reindex" , _ (" Rebuild block chain index from current blk000??.dat files" ) + " " + _ (" on startup" ));
283
+
279
284
#if !defined(WIN32)
280
285
strUsage += HelpMessageOpt (" -sysperms" , _ (" Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)" ));
281
286
#endif
@@ -352,7 +357,7 @@ std::string HelpMessage(HelpMessageMode mode)
352
357
strUsage += HelpMessageOpt (" -flushwallet" , strprintf (_ (" Run a thread to flush wallet periodically (default: %u)" ), 1 ));
353
358
strUsage += HelpMessageOpt (" -stopafterblockimport" , strprintf (_ (" Stop running after importing blocks from disk (default: %u)" ), 0 ));
354
359
}
355
- string debugCategories = " addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy" ; // Don't translate these and qt below
360
+ string debugCategories = " addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy, prune " ; // Don't translate these and qt below
356
361
if (mode == HMM_BITCOIN_QT)
357
362
debugCategories += " , qt" ;
358
363
strUsage += HelpMessageOpt (" -debug=<category>" , strprintf (_ (" Output debugging information (default: %u, supplying <category> is optional)" ), 0 ) + " . " +
@@ -458,10 +463,33 @@ struct CImportingNow
458
463
}
459
464
};
460
465
466
+
467
+ // If we're using -prune with -reindex, then delete block files that will be ignored by the
468
+ // reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
469
+ // is missing, and since pruning works by deleting the oldest block file first, just check
470
+ // for block file 0, and if it doesn't exist, delete all the block files in the
471
+ // directory (since they won't be read by the reindex but will take up disk space).
472
+ void DeleteAllBlockFiles ()
473
+ {
474
+ if (boost::filesystem::exists (GetBlockPosFilename (CDiskBlockPos (0 , 0 ), " blk" )))
475
+ return ;
476
+
477
+ LogPrintf (" Removing all blk?????.dat and rev?????.dat files for -reindex with -prune\n " );
478
+ boost::filesystem::path blocksdir = GetDataDir () / " blocks" ;
479
+ for (boost::filesystem::directory_iterator it (blocksdir); it != boost::filesystem::directory_iterator (); it++) {
480
+ if (is_regular_file (*it)) {
481
+ if ((it->path ().filename ().string ().length () == 12 ) &&
482
+ (it->path ().filename ().string ().substr (8 ,4 ) == " .dat" ) &&
483
+ ((it->path ().filename ().string ().substr (0 ,3 ) == " blk" ) ||
484
+ (it->path ().filename ().string ().substr (0 ,3 ) == " rev" )))
485
+ boost::filesystem::remove (it->path ());
486
+ }
487
+ }
488
+ }
489
+
461
490
void ThreadImport (std::vector<boost::filesystem::path> vImportFiles)
462
491
{
463
492
RenameThread (" bitcoin-loadblk" );
464
-
465
493
// -reindex
466
494
if (fReindex ) {
467
495
CImportingNow imp;
@@ -674,6 +702,21 @@ bool AppInit2(boost::thread_group& threadGroup)
674
702
if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
675
703
nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;
676
704
705
+ // if using block pruning, then disable txindex
706
+ // also disable the wallet (for now, until SPV support is implemented in wallet)
707
+ if (GetArg (" -prune" , 0 )) {
708
+ if (GetBoolArg (" -txindex" , false ))
709
+ return InitError (_ (" Prune mode is incompatible with -txindex." ));
710
+ #ifdef ENABLE_WALLET
711
+ if (!GetBoolArg (" -disablewallet" , false )) {
712
+ if (SoftSetBoolArg (" -disablewallet" , true ))
713
+ LogPrintf (" %s : parameter interaction: -prune -> setting -disablewallet=1\n " , __func__);
714
+ else
715
+ return InitError (_ (" Can't run with a wallet in prune mode." ));
716
+ }
717
+ #endif
718
+ }
719
+
677
720
// ********************************************************* Step 3: parameter-to-internal-flags
678
721
679
722
fDebug = !mapMultiArgs[" -debug" ].empty ();
@@ -710,6 +753,21 @@ bool AppInit2(boost::thread_group& threadGroup)
710
753
nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
711
754
712
755
fServer = GetBoolArg (" -server" , false );
756
+
757
+ // block pruning; get the amount of disk space (in MB) to allot for block & undo files
758
+ int64_t nSignedPruneTarget = GetArg (" -prune" , 0 ) * 1024 * 1024 ;
759
+ if (nSignedPruneTarget < 0 ) {
760
+ return InitError (_ (" Prune cannot be configured with a negative value." ));
761
+ }
762
+ nPruneTarget = (uint64_t ) nSignedPruneTarget;
763
+ if (nPruneTarget) {
764
+ if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {
765
+ return InitError (strprintf (_ (" Prune configured below the minimum of %d MB. Please use a higher number." ), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024 ));
766
+ }
767
+ LogPrintf (" Prune configured to target %uMiB on disk for block and undo files.\n " , nPruneTarget / 1024 / 1024 );
768
+ fPruneMode = true ;
769
+ }
770
+
713
771
#ifdef ENABLE_WALLET
714
772
bool fDisableWallet = GetBoolArg (" -disablewallet" , false );
715
773
#endif
@@ -1030,8 +1088,12 @@ bool AppInit2(boost::thread_group& threadGroup)
1030
1088
pcoinscatcher = new CCoinsViewErrorCatcher (pcoinsdbview);
1031
1089
pcoinsTip = new CCoinsViewCache (pcoinscatcher);
1032
1090
1033
- if (fReindex )
1091
+ if (fReindex ) {
1034
1092
pblocktree->WriteReindexing (true );
1093
+ // If we're reindexing in prune mode, wipe away all our block and undo data files
1094
+ if (fPruneMode )
1095
+ DeleteAllBlockFiles ();
1096
+ }
1035
1097
1036
1098
if (!LoadBlockIndex ()) {
1037
1099
strLoadError = _ (" Error loading block database" );
@@ -1055,7 +1117,18 @@ bool AppInit2(boost::thread_group& threadGroup)
1055
1117
break ;
1056
1118
}
1057
1119
1120
+ // Check for changed -prune state. What we are concerned about is a user who has pruned blocks
1121
+ // in the past, but is now trying to run unpruned.
1122
+ if (fHavePruned && !fPruneMode ) {
1123
+ strLoadError = _ (" You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain" );
1124
+ break ;
1125
+ }
1126
+
1058
1127
uiInterface.InitMessage (_ (" Verifying blocks..." ));
1128
+ if (fHavePruned && GetArg (" -checkblocks" , 288 ) > MIN_BLOCKS_TO_KEEP) {
1129
+ LogPrintf (" Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n " ,
1130
+ MIN_BLOCKS_TO_KEEP, GetArg (" -checkblocks" , 288 ));
1131
+ }
1059
1132
if (!CVerifyDB ().VerifyDB (pcoinsdbview, GetArg (" -checklevel" , 3 ),
1060
1133
GetArg (" -checkblocks" , 288 ))) {
1061
1134
strLoadError = _ (" Corrupted block database detected" );
@@ -1106,6 +1179,15 @@ bool AppInit2(boost::thread_group& threadGroup)
1106
1179
mempool.ReadFeeEstimates (est_filein);
1107
1180
fFeeEstimatesInitialized = true ;
1108
1181
1182
+ // if prune mode, unset NODE_NETWORK and prune block files
1183
+ if (fPruneMode ) {
1184
+ LogPrintf (" Unsetting NODE_NETWORK on prune mode\n " );
1185
+ nLocalServices &= ~NODE_NETWORK;
1186
+ if (!fReindex ) {
1187
+ PruneAndFlush ();
1188
+ }
1189
+ }
1190
+
1109
1191
// ********************************************************* Step 8: load wallet
1110
1192
#ifdef ENABLE_WALLET
1111
1193
if (fDisableWallet ) {
0 commit comments