主程序初始化

2024-04-27 23:38
文章标签 初始化 主程序

本文主要是介绍主程序初始化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

比特币源码分析(三) - 主程序初始化

 

https://blog.csdn.net/yzpbright/article/details/81165546

本文是以一个整体的角度分析程序初始化过程中所做的操作,整个初始化过程如果要分开来细讲可以写好几篇,后面一系列文章会具体展开分析关键逻辑的源码。

主程序的入口函数main()在bitcoind.cpp文件中:

int main(int argc, char* argv[])
{SetupEnvironment();// Connect bitcoind signal handlersnoui_connect();return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

一步一步分析下。
一、SetupEnvironment() ,设置运行环境
二、noui_connect(),连接bitcoind信号处理器
三、AppInit(argc, argv), 应用初始化,这里有大量的初始化操作,接下来一步一步分析下这个函数的源码:

1.解析运行输入的参数,保存在 mapArgs 这个map容器中

    // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()gArgs.ParseParameters(argc, argv);
  • 1
  • 2

2.处理查询帮助信息和版本信息的命令

    // Process help and version before taking care about datadirif (gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") ||  gArgs.IsArgSet("-help") || gArgs.IsArgSet("-version")){std::string strUsage = strprintf(_("%s Daemon"), _(PACKAGE_NAME)) + " " + _("version") + " " + FormatFullVersion() + "\n";if (gArgs.IsArgSet("-version")){strUsage += FormatParagraph(LicenseInfo());}else{strUsage += "\n" + _("Usage:") + "\n" +"  bitcoind [options]                     " + strprintf(_("Start %s Daemon"), _(PACKAGE_NAME)) + "\n";strUsage += "\n" + HelpMessage(HMM_BITCOIND);}fprintf(stdout, "%s", strUsage.c_str());return true;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

3.检查应用的数据目录

        if (!fs::is_directory(GetDataDir(false))){fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str());return false;}
  • 1
  • 2
  • 3
  • 4
  • 5

4.读取配置文件

        try{gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));} catch (const std::exception& e) {fprintf(stderr,"Error reading configuration file: %s\n", e.what());return false;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

5.检查判断是主网还是测试网络,并设置区块链的全局参数

        // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)try {SelectParams(ChainNameFromCommandLine());} catch (const std::exception& e) {fprintf(stderr, "Error: %s\n", e.what());return false;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

6.设置server标识为true,即启用RPC服务

        // -server defaults to true for bitcoind but not for the GUI so do this heregArgs.SoftSetBoolArg("-server", true);
  • 1
  • 2

7.初始化日志

        // Set this early so that parameter interactions go to consoleInitLogging();       
  • 1
  • 2

8.初始化参数交互,即根据规则将一些设置的参数转化为设置其他参数

       InitParameterInteraction();
  • 1

8.建立Bitcoin Core的基础上下文环境

        if (!AppInitBasicSetup()){// InitError will have been called with detailed error, which ends up on consolereturn false;}
  • 1
  • 2
  • 3
  • 4
  • 5

9.初始化参数交互,根据设置的参数做一些逻辑条件判断,根据情况显示相应的警告信息或者异常信息,也会有相关计算,将结果存储在内部变量中

        if (!AppInitParameterInteraction()){// InitError will have been called with detailed error, which ends up on consolereturn false;}
  • 1
  • 2
  • 3
  • 4
  • 5

10.完整性检查

        if (!AppInitSanityChecks()){// InitError will have been called with detailed error, which ends up on consolereturn false;}
  • 1
  • 2
  • 3
  • 4
  • 5

11.判断是否需要在后台运行(Daemonize)

        if (gArgs.GetBoolArg("-daemon", false)){#if HAVE_DECL_DAEMONfprintf(stdout, "Bitcoin server starting\n");// Daemonizeif (daemon(1, 0)) { // don't chdir (1), do close FDs (0)fprintf(stderr, "Error: daemon() failed: %s\n", strerror(errno));return false;}#elsefprintf(stderr, "Error: -daemon is not supported on this operating system\n");return false;#endif // HAVE_DECL_DAEMON}       

12.锁住Bitcoin Core数据目录

        // Lock data directory after daemonizationif (!AppInitLockDataDirectory()){// If locking the data directory failed, exit immediatelyreturn false;}

13.Bitcoin Core的主要初始化工作

        fRet = AppInitMain();
  • 1

14.监结束程序的请求,若有结束程序的请求,则完成结束程序的相关操作

    if (!fRet){Interrupt();} else {WaitForShutdown();}Shutdown();

P2P网络相关

CConnman
该类在src/net.h中声明,在src/net.cpp中实现。

class CConnman
{
public:

    enum NumConnections {
        CONNECTIONS_NONE = 0,
        CONNECTIONS_IN = (1U << 0),
        CONNECTIONS_OUT = (1U << 1),
        CONNECTIONS_ALL = (CONNECTIONS_IN | CONNECTIONS_OUT),
    };

    struct Options
    {
        ServiceFlags nLocalServices = NODE_NONE;
        int nMaxConnections = 0;
        int nMaxOutbound = 0;
        int nMaxAddnode = 0;
        int nMaxFeeler = 0;
        int nBestHeight = 0;
        CClientUIInterface* uiInterface = nullptr;
        NetEventsInterface* m_msgproc = nullptr;
        unsigned int nSendBufferMaxSize = 0;
        unsigned int nReceiveFloodSize = 0;
        uint64_t nMaxOutboundTimeframe = 0;
        uint64_t nMaxOutboundLimit = 0;
        std::vector<std::string> vSeedNodes;
        std::vector<CSubNet> vWhitelistedRange;
        std::vector<CService> vBinds, vWhiteBinds;
        bool m_use_addrman_outgoing = true;
        std::vector<std::string> m_specified_outgoing;
        std::vector<std::string> m_added_nodes;
    };

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32

该类是网络连接管理类,比较庞大,负责节点的启动、结束,推送消息,接收其他节点的连接等。

PeerLogicValidation
该类多重继承了两个接口类:CValidationInterface, 和 NetEventsInterface 。
CValidationInterface,主要是通知交易和区块相关的状态的改变。
NetEventsInterface,主要是处理从其他节点接收到的消息,发送消息,

/**
 * Interface for message handling
 */
class NetEventsInterface
{
public:
    virtual bool ProcessMessages(CNode* pnode, std::atomic<bool>& interrupt) = 0;
    virtual bool SendMessages(CNode* pnode, std::atomic<bool>& interrupt) = 0;
    virtual void InitializeNode(CNode* pnode) = 0;
    virtual void FinalizeNode(NodeId id, bool& update_connection_time) = 0;
};

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

除此之外,该类新增了几个方法,用于处理过期信息和剔除多余的对等节点

    void ConsiderEviction(CNode *pto, int64_t time_in_seconds);
    void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams);
    void EvictExtraOutboundPeers(int64_t time_in_seconds);
 

 

这篇关于主程序初始化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/941802

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

@postconstruct初始化的操作

从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion);@PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法 。写法有如下两种方式: @PostConstruct Public void someMethod() {}

spring和tomcat初始化的类和注解

1.InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。 spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用 实

LabVIEW环境中等待FPGA模块初始化完成

这个程序使用的是LabVIEW环境中的FPGA模块和I/O模块初始化功能,主要实现等待FAM(Field-Programmable Gate Array Module,FPGA模块)的初始化完成,并处理初始化过程中的错误。让我们逐步分析各部分的功能: 1. Wait for FAM Initialization框架 此程序框架用于等待I/O模块成功初始化。如果在5秒钟内模块没有完成配

dp(背包问题) 恰好、至少、至多初始化

状态表示的初始化(一般情况) f[i][j] i:前i件物品 体积至少为j 枚举体积时可以是负数(体积为负数时等价于体积为0) max f[i][j] = {-0x3f} f[i][0] = 0min f[i][j] = { 0x3f} f[i][0] = 0cnt f[0][0] = 1 体积至多为j 枚举体积时不能是负数 max f[i][j] = 0min f[i][j]

Windows11上使用WSL2,提示:系统尚未使用systemd作为初始化系统(PID 1)启动

前言 略 报错信息 System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down 解决方法 使用如下命令 # windows终端,执行如下命令wsl --update# 登录ubuntu系统,执行如下命令s

WapApp初始化样式表

@charset "utf-8";/* 样式初始化--------------------------------------------------*/body {margin: 0;padding: 0;background-color: #f6f6f6;font: normal 67.5% Helvetica, Arial, sans-serif;min-width: 240px;}*

Spark Core源码精读计划7 | Spark执行环境的初始化

推荐阅读 《Spark源码精度计划 | SparkConf》 《Spark Core源码精读计划 | SparkContext组件初始化》 《Spark Core源码精读计划3 | SparkContext辅助属性及后初始化》 《Spark Core源码精读计划4 | SparkContext提供的其他功能》 《Spark Core源码精读计划5 | 事件总线及ListenerBus》 《Spa

Spark Core源码精读计划3 | SparkContext辅助属性及后初始化

推荐阅读 《关于MQ面试的几件小事 | 消息队列的用途、优缺点、技术选型》         《关于MQ面试的几件小事 | 如何保证消息队列高可用和幂等》 《关于MQ面试的几件小事 | 如何保证消息不丢失》 《关于MQ面试的几件小事 | 如何保证消息按顺序执行》 《关于MQ面试的几件小事 | 消息积压在消息队列里怎么办》 《关于Redis的几件小事 | 使用目的与问题及线程模型》 《关于Red