Bit-Currency source resolution (21)-Executable program-Bitcoind

Source: Internet
Author: User
Tags nets
0x00 Summary

After the analysis of the previous 20 chapters, we are getting closer to the core function of Bitcoin, which is its consensus, transaction processing, and so on. Although the front is basically doing some initialization of the work, but these work for the overall operation of the bitcoin is essential, and as before the signal processing, concurrency and so on are worth learning part, this chapter mainly introduces the step in the Appinitmain 6, the code is a little bit longer so it is segmented into small sections for analysis. 0x01 appinitmain Step 6:network initialization

    Step 6:network Initialization
    //Note that we Absolutely cannot open any actual connections
    //until the very end (' Start node ') as the Utxo/block state
    /n OT yet setup and may-being set up twice if we
    //need to reindex later.

    ASSERT (!g_connman);
    G_connman = std::unique_ptr<cconnman> (New Cconnman (Getrand (Std::numeric_limits<uint64_t>::max ()), Getrand (Std::numeric_limits<uint64_t>::max ()));
    cconnman& Connman = *g_connman;

    Peerlogic.reset (New Peerlogicvalidation (&connman));
    Registervalidationinterface (Peerlogic.get ());
    Registernodesignals (Getnodesignals ());

Look at the first comment, which suggests that the actual network connection will only be made at the last start node, which means that this paragraph is set for some parameters and does not actually open the connection because the state of the block has not been configured and, if the index is set back, Then the state of the block will be set two times. peerlogicvalidation

Look at the code, first of all, to ensure that the G_connman is empty, the previous code also often see the assertion statement, which is a good habit to ensure that the variable in the specified range, while easy to debug. Next, you create a Cconnman object that sets the parameters for the connection, and then creates a variable of the peerlogicvalidation type, which is implemented as follows,

Class Peerlogicvalidation:public Cvalidationinterface {
private:
    cconnman* Connman;

Public:
    Explicit peerlogicvalidation (cconnman* connmanin);

    void blockconnected (const std::shared_ptr<const cblock>& pblock, const cblockindex* pindexconnected, const std::vector<ctransactionref>& vtxconflicted) override;
    void Updatedblocktip (const cblockindex *pindexnew, const cblockindex *pindexfork, bool finitialdownload) override;
    void blockchecked (const cblock& block, Const cvalidationstate& State) override;
    void Newpowvalidblock (const cblockindex *pindex, const std::shared_ptr<const cblock>& pblock) override;

As you can probably see from the names of these functions, this class implements how the nodes are handled when a new block is generated, and the implementation of these functions is parsed later when called. Message processing signals between registered nodes

void Registervalidationinterface (cvalidationinterface* pwalletin) {g_signals.m_internals->
    Updatedblocktip.connect (Boost::bind (&cvalidationinterface::updatedblocktip, PwalletIn, _1, _2, _3)); G_signals.m_internals->transactionaddedtomempool.connect (boost::bind &cvalidationinterface::
    Transactionaddedtomempool, Pwalletin, _1)); G_signals.m_internals->blockconnected.connect (Boost::bind (&cvalidationinterface::blockconnected,
    Pwalletin, _1, _2, _3)); G_signals.m_internals->blockdisconnected.connect (Boost::bind (&cvalidationinterface::blockdisconnected,
    Pwalletin, _1)); G_signals.m_internals->setbestchain.connect (Boost::bind (&cvalidationinterface::setbestchain, PwalletIn, _
    1));
    G_signals.m_internals->inventory.connect (Boost::bind (&cvalidationinterface::inventory, PwalletIn, _1)); G_signals.m_internals->broadcast.connect (Boost::bind (&cvalidationinterface::resendwallettransactions,
    Pwalletin, _1, _2)); G_signals.m_Internals->blockchecked.connect (Boost::bind (&cvalidationinterface::blockchecked, PwalletIn, _1, _2)); G_signals.m_internals->newpowvalidblock.connect (Boost::bind (&cvalidationinterface::newpowvalidblock,
Pwalletin, _1, _2)); }
Registering node signals
void Registernodesignals (cnodesignals& nodesignals)
{
    NodeSignals.ProcessMessages.connect (& ProcessMessages);
    NodeSignals.SendMessages.connect (&sendmessages);
    NodeSignals.InitializeNode.connect (&initializenode);
    NodeSignals.FinalizeNode.connect (&finalizenode);
}

Here is a sign to register several nodes to process and send messages. Add User Agent comments

    Sanitize comments per BIP-0014, format user agent and check total size
    std::vector<std::string> uacomments;
  for (const std::string& Cmt:gArgs.GetArgs ("-uacomment")) {
        if (CMT!= sanitizestring (CMT, Safe_chars_ua_ COMMENT)) return
            Initerror (strprintf (_ ("User Agent COMMENT (%s) contains unsafe characters."), CMT));
        Uacomments.push_back (CMT);
    Strsubversion = Formatsubversion (Client_name, client_version, uacomments);
    if (Strsubversion.size () > Max_subversion_length) {return
        Initerror strprintf (_ ("Total LENGTH of network Version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. "),
            strsubversion.size (), max_subversion_length));
    

-uacomment: Adds a comment to the user agent string.

First, the user's annotation information to the agent is saved to the uacomments, and the Client_name, Client_version and uacomments are followed by/client_name:client_version (COMMENTS1; comments2; ...) /format, and finally determine whether the formatted string exceeds the maximum length limit, which is defined as 256 in the Src/net.h max_subversion_length. Set Network Range

    if (Gargs.isargset ("-onlynet")) {
        std::set<enum network> nets;
        for (const std::string& Snet:gArgs.GetArgs ("-onlynet")) {
            enum Network net = parsenetwork (SNET);
            if (net = = net_unroutable) return
                Initerror (strprintf (_ ("Unknown Network specified in-onlynet: '%s '"), snet));
            Nets.insert (NET);
        }
        for (int n = 0; n < net_max n++) {
            enum network NET = (enum network) n;
            if (!nets.count (net))
                setlimited (NET);
        }
    }

-onlynet: Connect only the nodes in a particular network, net_unroutable,net_ipv4,net_ipv6,net_tor,net_internal several values.

First look at the definition of network,

Enum network
{
    net_unroutable = 0,
    net_ipv4,
    Net_ipv6,
    net_tor,
    net_internal,

    Net_max ,
};

Several networks are defined, and-onlynet limits the scope of the connection to one or several networks. Proxy Settings

    Check for host lookup allowed before parsing the any network related parameters fnamelookup = Gargs.getboolarg ("-dn

    S ", default_name_lookup);
    BOOL Proxyrandomize = Gargs.getboolarg ("-proxyrandomize", default_proxyrandomize); -proxy sets a proxy for all outgoing network traffic//-noproxy (or-proxy=0) as as as "the empty string can be u
    Sed to don't set a proxy, this is the default std::string Proxyarg = Gargs.getarg ("-proxy", "");
    Setlimited (Net_tor);
        if (Proxyarg!= "" && proxyarg!= "0") {cservice proxyaddr; if (!  Lookup (Proxyarg.c_str (), Proxyaddr, 9050, Fnamelookup)) {return Initerror (strprintf (_) ("Invalid-proxy address
        or hostname: '%s '), Proxyarg);
        } Proxytype addrproxy = Proxytype (proxyaddr, proxyrandomize); if (!addrproxy.isvalid ()) Return Initerror (strprintf (_ ("Invalid-proxy address or hostname: '%s '), Proxyarg)"

        ;
        SetProxy (Net_ipv4, addrproxy); SetprOxy (Net_ipv6, Addrproxy);
        SetProxy (Net_tor, addrproxy);
        Setnameproxy (Addrproxy); Setlimited (Net_tor, false); By default,-proxy sets onion as reachable, unless-noonion later}

-DNS: DNS resolution is allowed, default is 1.

-proxyrandomize: A certificate is issued randomly for each agent connection, and defaults to 1.

-proxy: Set up a proxy for all traffic on the network, NULL by default.

First check two parameters, then disable onion routing via setlimited (Net_tor). Then check if the agent is not empty, then according to the proxy domain DNS query, check the corresponding IP and check the legality of the agent, then for IPV4, IPV6 and Tor set up agents. Finally disable Tor, because it is disabled first, so here to enable, in fact, this setting does not matter, the following will be based on the-onion parameters of the corresponding settings. Set Onion Routing

    -onion can is used to set only a proxy for. onion, or override normal proxy for. Onion addresses//-noonion (o r-onion=0) disables connecting to. Onion entirely/A empty string is used to not override the Onion proxy (in whic
    H case it defaults to-proxy set above, or none) std::string Onionarg = Gargs.getarg ("-onion", ""); if (Onionarg!= "") {if (Onionarg = "0") {//Handle-noonion/-onion=0 setlimited (Net_tor);
            Set onions as unreachable} else {Cservice onionproxy; if (! Lookup (Onionarg.c_str (), Onionproxy, 9050, Fnamelookup)) {return Initerror (strprintf (_ ("invalid-onion ad
            Dress or hostname: '%s '), Onionarg));
            } Proxytype addronion = Proxytype (Onionproxy, proxyrandomize); if (!addronion.isvalid ()) Return Initerror (strprintf (_ ("Invalid-onion address or hostname: '%s '), Oniona
            RG));
        SetProxy (Net_tor, addronion);    Setlimited (Net_tor, false); }
    }

If-onion!= "" &&!= "0" is similar to the setup agent, first parse the domain name and enable onion routing. Set External IP

    2:parameter Interactions For more information about
    Flisten = Gargs.getboolarg ("-listen", default_l Isten);
    Fdiscover = Gargs.getboolarg ("-discover", true);
    Frelaytxes =!gargs.getboolarg ("-blocksonly", default_blocksonly);

    for (const std::string& StrAddr:gArgs.GetArgs ("-externalip")) {
        cservice addrlocal;
        if (Lookup (Straddr.c_str (), addrlocal, Getlistenport (), fnamelookup) && addrlocal.isvalid ())
            addlocal ( Addrlocal, local_manual);
        else return
            Initerror (resolveerrmsg ("Externalip", straddr));
    }

-listen: Accepts a connection request from an address.

-discover: Discover the IP address you have.

-blocksonly: Let the node enter blocksonly mode.

-externalip: Specify a public address.

The previous two parameters are better understood, so what is the blocksonly mode? According to Https://bitcointalk.org/index.php?topic=1377345.0 's explanation,

Bitcoin Core 0.12 introduced a new blocksonly setting. When set to blocksonly a node behaves normally but sends and receives no lose transactions; Instead it handles only complete blocks. There are many applications for nodes where only confirmed transactions are interesting, and a node which still a ND forwards blocks still contributes to network health–less-perhaps, than one that relays transactions:but it also Umes fewer to begin with. A additional downside they don ' t get the latency advantages of signature ' caching since every transaction they-is Tota Lly new to Them–this isn ' t something miners should use.

How much less bandwidth does the blocksonly use in practice? I recently measured this using two techniques:once by instrumenting a node to measure bandwidth used for blocks vs all OT Her traffic, and again by repeatedly running into both for a and modes of the hosts total monitoring network; Both modes gave effectively the same result.

How are the the savings? Blocksonly reduced the node ' s bandwidth usage by 88%.

In short, the node does not receive a temporary transaction and only accepts blocks that have been identified.

Next, for the specified external IP, first query the corresponding IP (the specified can be a domain name, or convert the string IP to Cservice), and then add the specified IP to the maplocalhost by ADDLOCAL, which maintains all the local IP. ZMQ

#if enable_zmq
    pzmqnotificationinterface = Czmqnotificationinterface::create ();

    if (pzmqnotificationinterface) {
        registervalidationinterface (pzmqnotificationinterface);
    }
#endif
    uint64_t nmaxoutboundlimit = 0;//unlimited unless-maxuploadtarget is set
    uint64_t Nmaxoutboundtimeframe = Max_upload_timeframe;

    if (Gargs.isargset ("-maxuploadtarget")) {
        nmaxoutboundlimit = Gargs.getarg ("-maxuploadtarget", DEFAULT_MAX_ Upload_target) *1024*1024;
    }

-maxuploadtarget: Set the maximum upload speed, in MB, the default value is 0, which means there is no limit.

First, through a macro definition to indicate whether to enable ZMQ, the introduction of ZMQ, reference https://www.cnblogs.com/rainbowzc/p/3357594.html, in simple terms, ZMQ encapsulated network communications, Message Queuing, thread scheduling and other functions, Provides a concise API to the upper layer, which enables High-performance network communication by loading library files and invoking API functions. The Registervalidationinterface function is described earlier in this chapter, which registers a number of signals for block processing. The following-maxuploadtarget parameters are then used to set the maximum upload speed.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.