下面我们来看上一章第二个函数的实现代码,这个函数中包括一系列的if语句,我们一个个来看。
// 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__);
}
if (gArgs.IsArgSet("-whitebind")) {
if (gArgs.SoftSetBoolArg("-listen", true))
LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__);
}
首先是-bind
和-whitebind
参数,这两个参数作用都是将-listen
设为true
,也就是绑定本地的网卡和端口,即使后面设置了-connect
或者-proxy
参数都会监听绑定的地址。另外我们SoftSetBoolArg()
这个函数之前介绍过,首先判断当前参数是否已经设置过,如果已经设置了,那么返回false
;否则就设置对应的值并返回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__);
}
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__); }
-connect
参数是用来只连接信任的节点,而不通过dns种子随机发现网络中的节点,同时默认设置也是不监听端口,也就是不接受其他节点的请求,注意这里和RPC Server不一样,这里是接收网络中其他节点发送的消息,和RPC server使用不同的端口。-proxy
则是设置代理服务器,所有消息都由代理服务器转发,一般设置代理的目的就是为了保护原始IP地址隐私,避免外部的攻击,所以这里默认禁用监听。-upnp
参数全称是Universal Plug and Play
,通用即插即用,是为了实现计算机与智能设备对等网络的连接体系结构,主要目标是希望有任何设备连接到网络时,网络中的设备都能直接使用或者控制它,这里是不希望检测任何upnp
设备。-discover
表示是否希望网络中的其他节点发现自己的地址,如果设置了代理,自然这里应设为false
。
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__);
}
接下来一段表示如果没有设置监听,那么就禁用后面一些参数,因为这些参数都需要开启监听。
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__);
}
这个-externalip
表示指定公有地址,也就是从指定的公有地址同步区块信息以及广播交易信息等等,所有的消息都只发向指定的共有地址,并且不寻找其他的地址。
// 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__);
}
-blocksonly
表示该节点只接受矿工打包成功的区块,不接受未确认的交易,这是在当前节点网络资源有限的情况下减少负载的一种方式(https://github.com/bitcoin-dot-org/bitcoin.org/issues/1544),而-whitelistrelay
表示接受从白名单中的节点转发过来的交易,这个值默认是1
,这里因为设置了只接受打包的区块,所以不会接受任何交易,自然也不会接受转发的交易。
// 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__);
}
最后一个if
语句中-whiltelistforcerelay
表示强制转发从白名单中继过来的交易信息,即使该交易违背了本地的策略,例如小于设置的交易费界限等等。因为是强制转发,所以必须先接收交易信息,-whitelistrelay
就要设置为true
。
分析过程中的主要方法就是结合编译出来的可执行程序运行./bitcoind --help或者 ./bitcoind --help -help-debug
查看每一个命令的帮助信息,基本上都能将对应的命令解释的很清楚,看完之后在看对应的代码就比较容易理解。