接着上一篇的内容来剖析
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
。
网友评论