美文网首页比特币源码学习笔记
比特币源码阅读(RPC命令-getblock)

比特币源码阅读(RPC命令-getblock)

作者: 坠叶飘香 | 来源:发表于2018-08-13 11:25 被阅读0次

    1.通过hash从mapBlockIndex获得CBlockIndex

    2.通过CBlockIndex得到该区块在文件中的存储位置,读取文件,获得CBlock对象

    3.从CBlockIndex和CBlock获取所需要的值,封装成json对象返回

    src/rpc/blockchain.cpp

    static UniValue getblock(const JSONRPCRequest& request)
    {
      LOCK(cs_main);
    
        std::string strHash = request.params[0].get_str(); //获得参数 hash
        uint256 hash(uint256S(strHash));
    
        int verbosity = 1;
        if (!request.params[1].isNull()) {
            if(request.params[1].isNum())
                verbosity = request.params[1].get_int();
            else
                verbosity = request.params[1].get_bool() ? 1 : 0;
        }
    
        const CBlockIndex* pblockindex = LookupBlockIndex(hash); //第一步
        if (!pblockindex) {
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
        }
    
        const CBlock block = GetBlockChecked(pblockindex); //第二步
    
        if (verbosity <= 0)
        {
            CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
            ssBlock << block;
            std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
            return strHex;
        }
    
        return blockToJSON(block, pblockindex, verbosity >= 2); //第三步
    }
    

    第一步 通过hash从mapBlockIndex获得CBlockIndex

    src/validation.h

    inline CBlockIndex* LookupBlockIndex(const uint256& hash)
    {
        AssertLockHeld(cs_main);
        BlockMap::const_iterator it = mapBlockIndex.find(hash);
        return it == mapBlockIndex.end() ? nullptr : it->second;
    }
    

    第二步 通过CBlockIndex读取文件,获得CBlock对象

    src/rpc/blockchain.cpp

    static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
    {
        CBlock block;
        if (IsBlockPruned(pblockindex)) { //Prune 修剪
            throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
        }
    
        if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) {
            // Block not found on disk. This could be because we have the block
            // header in our index but don't have the block (for example if a
            // non-whitelisted node sends us an unrequested long chain of valid
            // blocks, we add the headers to our index, but don't accept the
            // block).
            throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
        }
    
        return block;
    }
    
    从CBlockIndex构建CDiskBlockPos对象

    src/validation.cpp

    bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
    {
        CDiskBlockPos blockPos;
        {
            LOCK(cs_main);
            blockPos = pindex->GetBlockPos();
        }
    
        if (!ReadBlockFromDisk(block, blockPos, consensusParams))
            return false;
        if (block.GetHash() != pindex->GetBlockHash())
            return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
                    pindex->ToString(), pindex->GetBlockPos().ToString());
        return true;
    }
    
    从文件读取构建CBlock
    bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams)
    {
        block.SetNull();
    
        // Open history file to read
        CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
        if (filein.IsNull())
            return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
    
        // Read block
        try {
            filein >> block; 
        }
        catch (const std::exception& e) {
            return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
        }
    
        // Check the header
        if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) //工作量证明检测
            return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
    
        return true;
    }
    

    相关文章

      网友评论

        本文标题:比特币源码阅读(RPC命令-getblock)

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