比特币源码研读11-程序入口函数解析(10)

这篇已经是源码研读的第十一篇了,一路走来,并不容易,因为比较枯燥,难度也不小,放弃之心时不时便涌上心头。相信我,你并不孤独,你遇到过的问题,前人早有经历,细想下,把基础打好,后面的路就好走的多了。就好像学车一样,一开始的学方向盘,练离合刹车油门,挂挡,你很可能会不耐烦,觉得太简单了,便心不在焉,不放在心上。But, 一旦如此,后面就要在这些简单事情上摔跟头,然后不得不重新回头学起。倒不如一开始就将基本功打好了,后面不仅能少挨教练骂,学起其他项目也会更得心应手。

好了,言归正传,接着上一篇继续分析函数AppInitParameterInteraction剩下的代码。

一、交易池大小限定参数

以下代码中,首先得到mempool的最大值,然后将max mempool参数值乘以 1000000,将单位有 MB 换成 B,最后计算 mempool 的最小值,乘以1000是将单位从 KB转为 B,乘以40代表最小可以容纳40个交易族。

// mempool limits

    int64_t nMempoolSizeMax = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;

    int64_t nMempoolSizeMin = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40;

if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0)));

其中,默认最大交易池常量 DEFAULT_MAX_MEMPOOL_SIZE 定义在policy.h,值为300Mb。

默认最小的交易池常量 DEFAULT_DESCENDANT_SIZE_LIMIT, 101 kb.

/** Default for -maxmempool, maximum megabytes of mempool memory usage */ static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300;

/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */

static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101;

二、交易费增长量

incremental relay fee,即交易费增长量。这里设置的最低费用增长量,主要是为了考虑到交易池的容量限制,取消一些交易费用过低的交易。

// incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool

    // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting.

    if (IsArgSet("-incrementalrelayfee"))

    {

        CAmount n = 0;

        if (!ParseMoney(GetArg("-incrementalrelayfee", ""), n))

            return InitError(AmountErrMsg("incrementalrelayfee", GetArg("-incrementalrelayfee", "")));

        incrementalRelayFee = CFeeRate(n);

    }

当mempool 中的交易数量超过阈值,交易费用阈值就会跟着增加,增加量就是由incrementalrelayfee这个变量决定,默认值为1000聪,即0.00001BTC.

默认值 DEFAULT_INCREMENTAL_RELAY_FEE 同样定义于 policy.h:

/** Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP 125 replacement **/

static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE = 1000;

三、检查脚本线程数

参数-par=0 意味着程序根据机器情况自动检测线程数但同时nScriptCheckThreads==0意味着不使用并发。

// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency

    nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);

    if (nScriptCheckThreads <= 0)

        nScriptCheckThreads += GetNumCores();

    if (nScriptCheckThreads <= 1)

        nScriptCheckThreads = 0;

    else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)

        nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;

定义于validation.h的默认的脚本检查线程数变量值为0, 即程序默认使用自动检测。

/** -par default (number of script-checking threads, 0 = auto) */

static const int DEFAULT_SCRIPTCHECK_THREADS = 0;

还有最大的脚本检查线程数变量值为16,即程序最多启用16个线程对脚本进行检查。


/** Maximum number of script-checking threads allowed */

static const int MAX_SCRIPTCHECK_THREADS = 16;

函数GetNumCores()定义于util.cpp,其中,physical_concurrency()函数返回当前系统的物理内核数量,跟hardware_concurrency()不同,它并不把虚拟内核算进去。

但当BOOST版本小于105600,就得使用hardware_concurrency()代替。


int GetNumCores()

{

#if BOOST_VERSION >= 105600

    return boost::thread::physical_concurrency();

#else // Must fall back to hardware_concurrency, which unfortunately counts virtual cores

    return boost::thread::hardware_concurrency();

#endif

}

四、区块修剪

注释:区块修剪,通过获得当前磁盘空间的大小来分配区块和删除文件.

首先参数"-prune"不能为负数否则报错并退出程序该参数在前面的文章中也说过,其取值有以下三种:

0: 禁止修剪

1: 手动修剪,通过RPC调用pruneblockchain(height) 函数删除旧区块文件

大于等于 550M表示存储区块和 undo 文件的大小至于这个550M哪里来的,下面自有详解。

// block pruning; get the amount of disk space (in MiB) to allot for block & undo files

int64_t nPruneArg = GetArg("-prune", 0);

if (nPruneArg < 0) {

return InitError(_("Prune cannot be configured with a negative value."));

}

nPruneTarget = (uint64_t) nPruneArg * 1024 * 1024; //将nPruneArg转为字节数

if (nPruneArg == 1) {// manual pruning: -prune=1 

LogPrintf("Block pruning enabled. Use RPC call pruneblockchain(height) to manually prune block and undo files.\n");

nPruneTarget = std::numeric_limits::max();

        fPruneMode = true;

} else if (nPruneTarget) {

        if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {

            return InitError(strprintf(_("Prune configured below the minimum of %d MiB.  Please use a higher number."),

MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));

        }

        LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024);

        fPruneMode = true;

    }

其中,validation.h 中的全局变量 MIN_DISK_SPACE_FOR_BLOCK_FILES 为 550M。从注释中可以看出,机器至少需要550M空间来存储区块和 undo 文件。所以为了能让程序正常运行,需要将"-prune"的值设置大于550才行。fPruneMode = true;将修剪模式打开,这将会在后面的程序对区块进行具体修剪的操作中用到。

// Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat)

// At 1MB per block, 288 blocks = 288MB.

// Add 15% for Undo data = 331MB

// Add 20% for Orphan block rate = 397MB

// We want the low water mark after pruning to be at least 397 MB and since we prune in

// full block file chunks, we need the high water mark which triggers the prune to be

// one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB

// Setting the target to > than 550MB will make it likely we can respect the target.

static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;

今天到此为止,下次继续讲解RPC命令注册函数。敬请期待。

区块链研习社源码研读班 Jacky

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容