美文网首页
比特币源码阅读(四):初始化和启动(3)

比特币源码阅读(四):初始化和启动(3)

作者: 沙漠中的猴 | 来源:发表于2017-11-26 22:48 被阅读0次

接着上一篇的内容来剖析

InitLogging();

// src/init.cpp

void InitLogging()
{
    fPrintToConsole = gArgs.GetBoolArg("-printtoconsole", false);
    fLogTimestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS);
    fLogTimeMicros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS);
    fLogIPs = gArgs.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());
}

从命令行参数中获取以下信息

  • -printtoconsole 输出信息到终端。不写入默认的debug.log文件
  • -logtimestamps 给输出的信息附加时间戳。
  • -logtimemicros 将时间戳精确到微秒。
  • -logips 输出信息附加ip地址

LogPrintf()函数声明在util.h文件中

// src/util.h
#define LogPrintf(...) do { \
    std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \
    try { \
        _log_msg_ = tfm::format(__VA_ARGS__); \
    } catch (tinyformat::format_error &fmterr) { \
        /* Original format string will have newline so don't add one here */ \
        _log_msg_ = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(__VA_ARGS__); \
    } \
    LogPrintStr(_log_msg_); \
} while(0)

我们可以看到LogPrintf函数调用了LogPrintStr函数。

// src/util.cpp
int LogPrintStr(const std::string &str)
{
    int ret = 0; // Returns total number of characters written
    static std::atomic_bool fStartedNewLine(true);

    std::string strTimestamped = LogTimestampStr(str, &fStartedNewLine);

    if (fPrintToConsole)
    {
        // print to console
        ret = fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout);
        fflush(stdout);
    }
    else if (fPrintToDebugLog)
    {
        boost::call_once(&DebugPrintInit, debugPrintInitFlag);
        boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);

        // buffer if we haven't opened the log yet
        if (fileout == nullptr) {
            assert(vMsgsBeforeOpenLog);
            ret = strTimestamped.length();
            vMsgsBeforeOpenLog->push_back(strTimestamped);
        }
        else
        {
            // reopen the log file, if requested
            if (fReopenDebugLog) {
                fReopenDebugLog = false;
                fs::path pathDebug = GetDataDir() / "debug.log";
                if (fsbridge::freopen(pathDebug,"a",fileout) != nullptr)
                    setbuf(fileout, nullptr); // unbuffered
            }

            ret = FileWriteStr(strTimestamped, fileout);
        }
    }
    return ret;
}

该函数先判断fPrintToConsole是否为true,如果为true,则将输出信息打印到终端。之后再判断fPrintToDebugLog是否为true,为true则将输出信息写入debug.log文件中。如果都没有定义,则忽略输出信息。

InitParameterInteraction()

该函数由多个if语句构成,我们将其拆解来看

// src/init.cpp
// when specifying an explicit binding address, you want to listen on it
    // even when -connect or -proxy is specified
    if (gArgs.IsArgSet("-bind")) {
        if (gArgs.SoftSetBoolArg("-listen", true))
            LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__);
    }

如果参数中设置了-bind参数,则将-listen置位true,也就是绑定网卡和端口。即使后面设置了-connect或者-proxy参数仍然会监听绑定的地址和端口。

if (gArgs.IsArgSet("-whitebind")) {
        if (gArgs.SoftSetBoolArg("-listen", true))
            LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__);
    }

如果参数中设置了-whitebind参数,则将-listen置位true,也就是绑定网卡和端口。和上面的判断语句作用相同。

if (gArgs.IsArgSet("-connect")) {
        // when only connecting to trusted nodes, do not seed via DNS, or listen by default
        if (gArgs.SoftSetBoolArg("-dnsseed", false))
            LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__);
        if (gArgs.SoftSetBoolArg("-listen", false))
            LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__);
    }

-connect参数用来指定连接信任的节点,默认不监听端口。也不会按照dnsseed来随机连接节点。

if (gArgs.IsArgSet("-proxy")) {
        // to protect privacy, do not listen by default if a default proxy server is specified
        if (gArgs.SoftSetBoolArg("-listen", false))
            LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
        // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1
        // to listen locally, so don't rely on this happening through -listen below.
        if (gArgs.SoftSetBoolArg("-upnp", false))
            LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__);
        // to protect privacy, do not discover addresses by default
        if (gArgs.SoftSetBoolArg("-discover", false))
            LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__);
    }

-proxy参数是指定代理服务器,所有的数据都会经过代理服务器来转发。一般设置代理服务器是为了隐藏原有IP。所以这里将-listen设置为false。同样也不希望一些upnp设备来控制。-discover参数是不希望网络中的其他节点发现自己。

if (!gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) {
        // do not map ports or try to retrieve public IP when not listening (pointless)
        if (gArgs.SoftSetBoolArg("-upnp", false))
            LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__);
        if (gArgs.SoftSetBoolArg("-discover", false))
            LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
        if (gArgs.SoftSetBoolArg("-listenonion", false))
            LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__);
    }

如果没有设置-listen参数,则将-upnp-discover-listenonion功能置为false,也就是禁用这些功能。

if (gArgs.IsArgSet("-externalip")) {
        // if an explicit public IP is specified, do not try to find others
        if (gArgs.SoftSetBoolArg("-discover", false))
            LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__);
    }

如果指定了公有地址,就不需要再发现其他的地址了。直接与连接的公有地址通信即可。

// disable whitelistrelay in blocksonly mode
    if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
        if (gArgs.SoftSetBoolArg("-whitelistrelay", false))
            LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__);
    }

表示该节点只接受打包过的区块,不接受未打包的交易。这样做可以节省网络资源。whitelistrelay将白名单转发过来的交易,置为false。因为只接收打包成功的区块,所以就不会接收白名单转发过来的交易了。

// Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
    if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
        if (gArgs.SoftSetBoolArg("-whitelistrelay", true))
            LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__);
    }

转发从白名单转发过来的消息,所以需要将whitelistrelay设置为true

相关文章

网友评论

      本文标题:比特币源码阅读(四):初始化和启动(3)

      本文链接:https://www.haomeiwen.com/subject/xuqlbxtx.html