比特币源码研读之七

源码研读系列从第4期开始到现在已有3期在介绍参数处理部分,可见这部分内容对于比特币后台进程来说是很重要的,因为其运行的状态是根据用户输入的参数来决定的,所以这部分的介绍相对会多些,我将在本期完成该部分源码的研读。话不多说,我们继续参数处理剩余部分源码的研读。

《比特币源码研读之七》

本文主要涉及的源码文件包括:

src/bitcond.cpp、src/util.h、src/util.cpp、src/init.h、src/init.cpp

一、RPC命令行判断

RPC为远程过程调用,其在后台进程中RPC调用方式的参数正确设置形式如下:

bitcoind -daemon //后台运行

bitcoind -stop//停止daemon进程

以下为RPC命令行参数设置正确性判断过程:

// Command-line RPC

bool fCommandLine = false;

for (int i = 1; i < argc; i++)

if (!IsSwitchChar(argv[i][0]) &&!boost::algorithm::istarts_with(argv[i], “bitcoin:”))

fCommandLine= true;

if(fCommandLine)

{

fprintf(stderr, “Error: There is no RPC client functionality inbitcoind anymore. Use the bitcoin-cli utility instead.\n”);

exit(EXIT_FAILURE);

}

上述代码对输入的参数逐个判断,首先通过IsSwitchCahr函数(src/util.h)判断参数是否有’-‘或’/’,并且不包含’bitcoin:’,bitcoin:URI是用于转账的,所以应该排除这种情况:bitcoin://1F2EUzKR1XsLRCtEnsnpDQZ13XJgS6P3ZK?amount=0.001&message=donation,如果出现上述情况则在终端中输出错误提示信息,并且退出程序。其显示效果如图所示。

《比特币源码研读之七》

通过其输出信息我们可以知道,对于不含’-‘或’/’的参数和bitcoin:URI只能在bitcoin-cli客户端工具中使用,bitcoind中是无法处理的,会导致程序异常退出。

参考文章:http://blog.sina.com.cn/s/blog_14ed0b9990102wp7p.html

二、服务参数设置

服务参数设置代码实现是通过SoftSetBoolArg(“-server”, true);完成的。其注释如下:

// -server defaults to true for bitcoindbut not for the GUI so do this here

通过该注释我们可以知道bitcoind默认是服务端,其参数-server是true,但是对于GUI(即图形界面程序)则不然,需要显示设置,因此在此处添加该行代码。该函数的实现代码以及其调用的函数均在src/util.cpp中,其代码实现也比较简单,具体如下:

bool SoftSetBoolArg(const std::string&strArg, bool fValue)

{

if (fValue)

return SoftSetArg(strArg, std::string(“1”));

else

return SoftSetArg(strArg, std::string(“0”));

}

bool SoftSetArg(const std::string&strArg, const std::string& strValue)

{

LOCK(cs_args);

if (mapArgs.count(strArg))

return false;

mapArgs[strArg] = strValue;

return true;

}

其实现思路为:首先判断mapArgs(该参数的解释在第4篇研读分析中)中是否存在server参数,如果存在则无需设置,不存在则根据SoftSetBoolArg传入的fValue进行设置相应值。具体服务参数设置就这么简单,大家只要看了之前的源码研读分析文章,该函数的解读很容易理解。

三、初始化日志

《比特币源码研读之七》

接下来我们将进入日志打印内容基础框架设置部分,在该部分主要对日志打印的内容根据参数进行解析,确定后续运行过程中需打印的信息,其具体实现代码也很简单,具体如下:

Src/init.cpp

//日志打印

void InitLogging()

{

fPrintToConsole = GetBoolArg(“-printtoconsole”, false);

fLogTimestamps =GetBoolArg(“-logtimestamps”, DEFAULT_LOGTIMESTAMPS);

fLogTimeMicros = GetBoolArg(“-logtimemicros”,DEFAULT_LOGTIMEMICROS);

fLogIPs = GetBoolArg(“-logips”, DEFAULT_LOGIPS);

LogPrintf(“\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n”);

LogPrintf(“Bitcoin version %s\n”, FormatFullVersion());

}

日志文件的默认位置为我们设置的数据目录中,其名称为debug.log,在ubuntu系统中其默认目录位置为~/.bitcoin。

《比特币源码研读之七》

我们接下来逐个分析其参数含义:

(1)printtoconsole

日志信息是否发送跟踪/调试信息到控制台而不是debug.log文件。我们看到其默认为false,即不打印至控制台或终端上,反之则打印。

(2)logtimestamps

该参数的含义为在日志中打印时间戳,该参数的默认值定义为静态常量DEFAULT_LOGTIMESTAMPS,该常量在src/util.h中定义,与该常量一起定义的还有本函数中使用到的另两个常量,这3个常量分别给作为函数中3个参数的默认值,其分别是:

static const bool DEFAULT_LOGTIMEMICROS = false;//按微秒格式打印日志时间

static const bool DEFAULT_LOGIPS= false; //日志打印中包含IP地址

static const bool DEFAULT_LOGTIMESTAMPS = true;//打印日志时间戳

通过名字我们可以很明显看出它们的对应关系。分别为:

Logtimestamps ——-> DEFAULT_LOGTIMESTAMPS

fLogTimeMicros ——-> DEFAULT_LOGTIMEMICROS

DEFAULT_LOGIPS——-> DEFAULT_LOGIPS

从DEFAULT_LOGTIMESTAMPS的定义可以看出,日志打印中是默认打印时间戳的。

(3)logtimemicros

从DEFAULT_LOGTIMEMICROS的定义可以看出,日志打印中日志时间是按微秒格式打印的。

(4)DEFAULT_LOGIPS

从DEFAULT_LOGIPS的定义可以看出,日志打印中是默认不打印IP地址的。

在ubuntu系统中打开~/.bitcoin下的日志文件debug.log,我们可以看到其具体的日志打印输出内容如图所示。

《比特币源码研读之七》

到此我们完成了AppInit函数中集中处理传入参数的源码,在这个参数解析过程中,我知道了区块链的3个链,那就是第6篇中讲到的私有链、测试链以及公有链;知道了比特币帮助信息输出的代码实现方法;知道了参数存储变量mapArgs与_mapMultiArgs。当然还有很多小的知识点,这里就不一一列举了,相信通过后续的源码研读我将会收获更多,也欢迎更多的朋友一起加入源码研读行动,更多地了解比特币!

作者:区块链研习社比特币源码研读班 菜菜子

以下是广告:

我们区块链研习社已创建“区块链研习社币圈交流”小密圈”,在小密圈中,我们将带领大家一起学习区块链的原理与投资,还将提供区块链基本原理解答、交易所注册与交易操作、ICO交易与操作、投资分析、风险分析等内容。

目前入圈价格初始定价50元,50人调整一次价格,每次调整幅度为50元!

《比特币源码研读之七》

    原文作者:菜菜子_forest
    原文地址: https://www.jianshu.com/p/5858f9ca0a33
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞