int UncompressAndDisplay(const char* filename, int frame_rate)
{

	size_t compressed_block_size;
	size_t uncompressed_block_size;
	unsigned int Frame_number;
	int display_flag = -1;
	unsigned int block_x;
	unsigned int block_y;
	unsigned int block_width;
	unsigned int block_height;

	unsigned char* buf = NULL;
	char* img_data = NULL;
	XImage* img;
	FILE *fp = fopen(filename, "rb");
	if (fp == NULL)
	{
		printf("could not open file: %s !!\n", filename);
		return 0;
	}
	Display* display = XOpenDisplay(NULL); //connect to a local display
	if (NULL == display)
	{
		printf("CaptureDesktop cannot get root window\n");
		return 0;
	}
	Window desktop = RootWindow(display, 0); //refer to root window
	if (desktop == 0)
	{
		printf("CaptureDesktop cannot get root window\n");
		return 0;
	}

	//Retrive the width and the height of the screen
	unsigned int screen_width = DisplayWidth(display, 0);
	unsigned int screen_height = DisplayHeight(display, 0);

	Window window = XCreateSimpleWindow(display, desktop, 0, 0, screen_width,
			screen_height, 1, 0, 0);
	img = XGetImage(display, desktop, 0, 0, screen_width, screen_height, ~0,
	ZPixmap);

	//start reading data from disk
	while (1)
	{
		if (fread(&compressed_block_size, sizeof(size_t), 1, fp) == 0)
		{
			printf("reach the end  or read error !\n");
			return -1;
		}
		if (compressed_block_size == 0)
			continue;
		if ((buf = (unsigned char*) malloc(compressed_block_size)) == NULL)
		{
			printf("no enough memory!\n");
			return -1;
		}
		//读数据
		ReadBlockFromDisk(buf, compressed_block_size, fp, &Frame_number,
				&block_x, &block_y, &block_width, &block_height);

		if ((img_data = (char*) malloc((block_width) * (block_height) * 4))
				== NULL)
		{
			printf("no enough memory!\n");
			return -1;
		}
		//解压缩
		uncompressed_block_size = block_width * block_height * 4;
		if (uncompress((unsigned char*) img_data, &uncompressed_block_size, buf,
				compressed_block_size) != Z_OK)
		{
			printf("uncompress failed!\n");
			return -1;
		}

		if (Frame_number - display_flag == 1)
		{ //用于显示图片 需修改
		  //XSelectInput(display, window, ButtonPressMask | ExposureMask);
			XMapWindow(display, window);
			/*	XEvent ev;
			 bool displayflag = true;
			 while (displayflag)
			 {
			 XNextEvent(display, &ev);
			 switch (ev.type)
			 {
			 case Expose:
			 XPutImage(display, window, DefaultGC(display, 0), img, 0, 0,
			 block_x, block_y, block_width, block_height);
			 break;
			 case ButtonPress:
			 displayflag = false;
			 //XUnmapWindow(display, window);
			 }

			 }*/
			XPutImage(display, window, DefaultGC(display, 0), img, 0, 0, 0, 0,
					screen_width, screen_height);
			display_flag++;

			usleep(1000000.0 / frame_rate);
		}

		PutDatablockToXImage(img, img_data, block_x, block_y, block_width,
				block_height);

	}
	/* 释放内存 */
	XUnmapWindow(display, window);
	fclose(fp);
	XDestroyWindow(display, window);
	XDestroyImage(img);
	XCloseDisplay(display);
	if (buf != NULL || img_data != NULL)
	{
		free(buf);
		free(img_data);
		buf = NULL;
		img_data = NULL;
		fp = NULL;
	}

	return 1;
}
/** Undo the effects of this block (with given index) on the UTXO set represented by coins.
 *  When FAILED is returned, view is left in an indeterminate state. */
DisconnectResult
CViewManager::DisconnectBlock(const CBlock &block, const CBlockIndex *pindex, CCoinsViewCache &view, bool *pfClean)
{
    if (pfClean)
        *pfClean = false;

    bool fClean = true;

    CBlockUndo blockUndo;
    CDiskBlockPos pos = pindex->GetUndoPos();
    if (pos.IsNull())
    {
        ELogFormat("no undo data available");
        return DISCONNECT_FAILED;
    }
    if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
    {
        ELogFormat("failure reading undo data");
        return DISCONNECT_FAILED;
    }

    if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
    {
        ELogFormat("block and undo data inconsistent");
        return DISCONNECT_FAILED;
    }

    // undo transactions in reverse order
    for (int i = block.vtx.size() - 1; i >= 0; i--)
    {
        const CTransaction &tx = *(block.vtx[i]);
        uint256 hash = tx.GetHash();
        bool is_coinbase = tx.IsCoinBase();

        // Check that all outputs are available and match the outputs in the block itself
        // exactly.
        for (size_t o = 0; o < tx.vout.size(); o++)
        {
            if (!tx.vout[o].scriptPubKey.IsUnspendable())
            {
                COutPoint out(hash, o);
                Coin coin;
                bool is_spent = view.SpendCoin(out, &coin);
                if (!is_spent || tx.vout[o] != coin.out || pindex->nHeight != coin.nHeight ||
                    is_coinbase != coin.fCoinBase)
                {
                    fClean = false; // transaction output mismatch
                }
            }
        }

        // restore inputs
        if (i > 0)
        { // not coinbases

            if(tx.IsCoinBase2()){
                continue; //continue
            }
            CTxUndo &txundo = blockUndo.vtxundo[i - 1];
            if (txundo.vprevout.size() != tx.vin.size())
            {
                ELogFormat("transaction and undo data inconsistent");
                return DISCONNECT_FAILED;
            }
            for (unsigned int j = tx.vin.size(); j-- > 0;)
            {
                const COutPoint &out = tx.vin[j].prevout;
                int res = ApplyTxInUndo(std::move(txundo.vprevout[j]), view, out);
                if (res == DISCONNECT_FAILED)
                    return DISCONNECT_FAILED;
                fClean = fClean && res != DISCONNECT_UNCLEAN;
            }
            // At this point, all of txundo.vprevout should have been moved out.
        }
    }

    // move best block pointer to prevout block
    view.SetBestBlock(pindex->pprev->GetBlockHash());

    //sbtc-vm
    GET_CONTRACT_INTERFACE(ifContractObj);
    uint256 hashStateRoot;
    uint256 hashUTXORoot;
    CBlock prevblock;
    if (!ReadBlockFromDisk(prevblock, pindex->pprev, Params().GetConsensus())) {
        //TODO  LogError
        rLogError("ReadBlockFromDisk failed at %d, hash=%s", pindex->pprev->nHeight,
                         pindex->pprev->GetBlockHash().ToString());
    } else {
        if(prevblock.GetVMState(hashStateRoot, hashUTXORoot) == RET_VM_STATE_ERR)
        {
            ILogFormat("GetVMState err");
        }
    }
    ifContractObj->UpdateState(hashStateRoot, hashUTXORoot);
   // ifContractObj->UpdateState(pindex->pprev->hashStateRoot, pindex->pprev->hashUTXORoot);

    GET_CHAIN_INTERFACE(ifChainObj);
    if (pfClean == NULL && ifChainObj->IsLogEvents())
    {
        ifContractObj->DeleteResults(block.vtx);
        ifChainObj->GetBlockTreeDB()->EraseHeightIndex(pindex->nHeight);
    }
    return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
}
Beispiel #3
0
std::string BlockToString(CBlockIndex* pBlock)
{
    if (!pBlock)
        return "";

    CBlock block;
    ReadBlockFromDisk(block, pBlock);

    CAmount Fees = 0;
    CAmount OutVolume = 0;
    CAmount Reward = 0;

    std::string TxLabels[] = {_("Hash"), _("From"), _("Amount"), _("To"), _("Amount")};

    std::string TxContent = table + makeHTMLTableRow(TxLabels, sizeof(TxLabels) / sizeof(std::string));
    for (unsigned int i = 0; i < block.vtx.size(); i++) {
        const CTransaction& tx = block.vtx[i];
        TxContent += TxToRow(tx);

        CAmount In = getTxIn(tx);
        CAmount Out = tx.GetValueOut();
        if (tx.IsCoinBase())
            Reward += Out;
        else if (In < 0)
            Fees = -Params().MaxMoneyOut();
        else {
            Fees += In - Out;
            OutVolume += Out;
        }
    }
    TxContent += "</table>";

    CAmount Generated;
    if (pBlock->nHeight == 0)
        Generated = OutVolume;
    else
        Generated = GetBlockValue(pBlock->nHeight - 1);

    std::string BlockContentCells[] =
        {
            _("Height"), itostr(pBlock->nHeight),
            _("Size"), itostr(GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)),
            _("Number of Transactions"), itostr(block.vtx.size()),
            _("Value Out"), ValueToString(OutVolume),
            _("Fees"), ValueToString(Fees),
            _("Generated"), ValueToString(Generated),
            _("Timestamp"), TimeToString(block.nTime),
            _("Difficulty"), strprintf("%.4f", GetDifficulty(pBlock)),
            _("Bits"), utostr(block.nBits),
            _("Nonce"), utostr(block.nNonce),
            _("Version"), itostr(block.nVersion),
            _("Hash"), "<pre>" + block.GetHash().GetHex() + "</pre>",
            _("Merkle Root"), "<pre>" + block.hashMerkleRoot.GetHex() + "</pre>",
            // _("Hash Whole Block"), "<pre>" + block.hashWholeBlock.GetHex() + "</pre>"
            // _("Miner Signature"), "<pre>" + block.MinerSignature.ToString() + "</pre>"
        };

    std::string BlockContent = makeHTMLTable(BlockContentCells, sizeof(BlockContentCells) / (2 * sizeof(std::string)), 2);

    std::string Content;
    Content += "<h2><a class=\"nav\" href=";
    Content += itostr(pBlock->nHeight - 1);
    Content += ">◄&nbsp;</a>";
    Content += _("Block");
    Content += " ";
    Content += itostr(pBlock->nHeight);
    Content += "<a class=\"nav\" href=";
    Content += itostr(pBlock->nHeight + 1);
    Content += ">&nbsp;►</a></h2>";
    Content += BlockContent;
    Content += "</br>";
    /*
    if (block.nHeight > getThirdHardforkBlock())
    {
        std::vector<std::string> votes[2];
        for (int i = 0; i < 2; i++)
        {
            for (unsigned int j = 0; j < block.vvotes[i].size(); j++)
            {
                votes[i].push_back(block.vvotes[i][j].hash.ToString() + ':' + itostr(block.vvotes[i][j].n));
            }
        }
        Content += "<h3>" + _("Votes +") + "</h3>";
        Content += makeHTMLTable(&votes[1][0], votes[1].size(), 1);
        Content += "</br>";
        Content += "<h3>" + _("Votes -") + "</h3>";
        Content += makeHTMLTable(&votes[0][0], votes[0].size(), 1);
        Content += "</br>";
    }
    */
    Content += "<h2>" + _("Transactions") + "</h2>";
    Content += TxContent;

    return Content;
}
Beispiel #4
0
static bool rest_block(HTTPRequest* req,
                       const std::string& strURIPart,
                       bool showTxDetails)
{
    if (!CheckWarmup(req))
        return false;
    std::string hashStr;
    const RetFormat rf = ParseDataFormat(hashStr, strURIPart);

    uint256 hash;
    if (!ParseHashStr(hashStr, hash))
        return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);

    CBlock block;
    CBlockIndex* pblockindex = nullptr;
    {
        LOCK(cs_main);
        pblockindex = LookupBlockIndex(hash);
        if (!pblockindex) {
            return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
        }

        if (IsBlockPruned(pblockindex))
            return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");

        if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
            return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
    }

    CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
    ssBlock << block;

    switch (rf) {
    case RetFormat::BINARY: {
        std::string binaryBlock = ssBlock.str();
        req->WriteHeader("Content-Type", "application/octet-stream");
        req->WriteReply(HTTP_OK, binaryBlock);
        return true;
    }

    case RetFormat::HEX: {
        std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";
        req->WriteHeader("Content-Type", "text/plain");
        req->WriteReply(HTTP_OK, strHex);
        return true;
    }

    case RetFormat::JSON: {
        UniValue objBlock;
        {
            LOCK(cs_main);
            objBlock = blockToJSON(block, pblockindex, showTxDetails);
        }
        std::string strJSON = objBlock.write() + "\n";
        req->WriteHeader("Content-Type", "application/json");
        req->WriteReply(HTTP_OK, strJSON);
        return true;
    }

    default: {
        return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
    }
    }
}
Beispiel #5
0
UniValue gettxoutproof(const JSONRPCRequest& request)
{
    if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
        throw std::runtime_error(
            "gettxoutproof [\"txid\",...] ( blockhash )\n"
            "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
            "\nNOTE: By default this function only works sometimes. This is when there is an\n"
            "unspent output in the utxo for this transaction. To make it always work,\n"
            "you need to maintain a transaction index, using the -txindex command line option or\n"
            "specify the block in which the transaction is included manually (by blockhash).\n"
            "\nArguments:\n"
            "1. \"txids\"       (string) A json array of txids to filter\n"
            "    [\n"
            "      \"txid\"     (string) A transaction hash\n"
            "      ,...\n"
            "    ]\n"
            "2. \"blockhash\"   (string, optional) If specified, looks for txid in the block with this hash\n"
            "\nResult:\n"
            "\"data\"           (string) A string that is a serialized, hex-encoded data for the proof.\n"
        );

    std::set<uint256> setTxids;
    uint256 oneTxid;
    UniValue txids = request.params[0].get_array();
    for (unsigned int idx = 0; idx < txids.size(); idx++) {
        const UniValue& txid = txids[idx];
        if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
            throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid txid ")+txid.get_str());
        uint256 hash(uint256S(txid.get_str()));
        if (setTxids.count(hash))
            throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ")+txid.get_str());
       setTxids.insert(hash);
       oneTxid = hash;
    }

    LOCK(cs_main);

    CBlockIndex* pblockindex = nullptr;

    uint256 hashBlock;
    if (!request.params[1].isNull())
    {
        hashBlock = uint256S(request.params[1].get_str());
        if (!mapBlockIndex.count(hashBlock))
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
        pblockindex = mapBlockIndex[hashBlock];
    } else {
        // Loop through txids and try to find which block they're in. Exit loop once a block is found.
        for (const auto& tx : setTxids) {
            const Coin& coin = AccessByTxid(*pcoinsTip, tx);
            if (!coin.IsSpent()) {
                pblockindex = chainActive[coin.nHeight];
                break;
            }
        }
    }

    if (pblockindex == nullptr)
    {
        CTransactionRef tx;
        if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull())
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
        if (!mapBlockIndex.count(hashBlock))
            throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
        pblockindex = mapBlockIndex[hashBlock];
    }

    CBlock block;
    if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
        throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");

    unsigned int ntxFound = 0;
    for (const auto& tx : block.vtx)
        if (setTxids.count(tx->GetHash()))
            ntxFound++;
    if (ntxFound != setTxids.size())
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not all transactions found in specified or retrieved block");

    CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
    CMerkleBlock mb(block, setTxids);
    ssMB << mb;
    std::string strHex = HexStr(ssMB.begin(), ssMB.end());
    return strHex;
}