Example #1
0
Value getworkex(const Array& params, bool fHelp)
{
    if (fHelp || params.size() > 2)
        throw runtime_error(
            "getworkex [data, coinbase]\n"
            "If [data, coinbase] is not specified, returns extended work data.\n"
        );

    if (vNodes.empty())
        throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Thepandacoin is not connected!");

    if (IsInitialBlockDownload())
        throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Thepandacoin is downloading blocks...");

    typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
    static mapNewBlock_t mapNewBlock;    // FIXME: thread safety
    static vector<CBlockTemplate*> vNewBlockTemplate;
    static CReserveKey reservekey(pwalletMain);

    if (params.size() == 0)
    {
        // Update block
        static unsigned int nTransactionsUpdatedLast;
        static CBlockIndex* pindexPrev;
        static int64 nStart;
        static CBlockTemplate* pblocktemplate;
        if (pindexPrev != pindexBest ||
            (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
        {
            if (pindexPrev != pindexBest)
            {
                // Deallocate old blocks since they're obsolete now
                mapNewBlock.clear();
                BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
                    delete pblocktemplate;
                vNewBlockTemplate.clear();
            }

            // Clear pindexPrev so future getworks make a new block, despite any failures from here on
            pindexPrev = NULL;

            // Store the pindexBest used before CreateNewBlock, to avoid races
            nTransactionsUpdatedLast = nTransactionsUpdated;
            CBlockIndex* pindexPrevNew = pindexBest;
            nStart = GetTime();

            // Create new block
            pblocktemplate = CreateNewBlockWithKey(*pMiningKey);
            if (!pblocktemplate)
                throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
            vNewBlockTemplate.push_back(pblocktemplate);

            // Need to update only after we know CreateNewBlock succeeded
            pindexPrev = pindexPrevNew;
        }
        CBlock* pblock = &pblocktemplate->block; // pointer for convenience

        // Update nTime
        pblock->UpdateTime(pindexPrev);
        pblock->nNonce = 0;

        // Update nExtraNonce
        static unsigned int nExtraNonce = 0;
        IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);

        // Save
        mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);

        // Pre-build hash buffers
        char pmidstate[32];
        char pdata[128];
        char phash1[64];
        FormatHashBuffers(pblock, pmidstate, pdata, phash1);

        uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();

        CTransaction coinbaseTx = pblock->vtx[0];
        std::vector<uint256> merkle = pblock->GetMerkleBranch(0);

        Object result;
        result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
        result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));

        CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
        ssTx << coinbaseTx;
        result.push_back(Pair("coinbase", HexStr(ssTx.begin(), ssTx.end())));

        Array merkle_arr;

        BOOST_FOREACH(uint256 merkleh, merkle) {
            printf("%s\n", merkleh.ToString().c_str());
            merkle_arr.push_back(HexStr(BEGIN(merkleh), END(merkleh)));
        }

        result.push_back(Pair("merkle", merkle_arr));

        return result;
    }
Example #2
0
Value getworkex(const Array& params, bool fHelp)
{
    if (fHelp || params.size() > 2)
        throw runtime_error(
            "getworkex [data, coinbase]\n"
            "If [data, coinbase] is not specified, returns extended work data.\n"
        );

    if (vNodes.empty())
        throw JSONRPCError(-9, "SSVCoin is not connected!");

    if (IsInitialBlockDownload())
        throw JSONRPCError(-10, "SSVCoin is downloading blocks...");

    typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
    static mapNewBlock_t mapNewBlock;
    static vector<CBlock*> vNewBlock;
    static CReserveKey reservekey(pwalletMain);

    if (params.size() == 0)
    {
        // Update block
        static unsigned int nTransactionsUpdatedLast;
        static CBlockIndex* pindexPrev;
        static int64 nStart;
        static CBlock* pblock;
        if (pindexPrev != pindexBest ||
            (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
        {
            if (pindexPrev != pindexBest)
            {
                // Deallocate old blocks since they're obsolete now
                mapNewBlock.clear();
                BOOST_FOREACH(CBlock* pblock, vNewBlock)
                    delete pblock;
                vNewBlock.clear();
            }
            nTransactionsUpdatedLast = nTransactionsUpdated;
            pindexPrev = pindexBest;
            nStart = GetTime();

            // Create new block
            pblock = CreateNewBlock(pwalletMain);
            if (!pblock)
                throw JSONRPCError(-7, "Out of memory");
            vNewBlock.push_back(pblock);
        }

        // Update nTime
        pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
        pblock->nNonce = 0;

        // Update nExtraNonce
        static unsigned int nExtraNonce = 0;
        IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);

        // Save
        mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);

        // Prebuild hash buffers
        char pmidstate[32];
        char pdata[128];
        char phash1[64];
        FormatHashBuffers(pblock, pmidstate, pdata, phash1);

        uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();

        CTransaction coinbaseTx = pblock->vtx[0];
        std::vector<uint256> merkle = pblock->GetMerkleBranch(0);

        Object result;
        result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
        result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));

        CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
        ssTx << coinbaseTx;
        result.push_back(Pair("coinbase", HexStr(ssTx.begin(), ssTx.end())));

        Array merkle_arr;

        BOOST_FOREACH(uint256 merkleh, merkle) {
            merkle_arr.push_back(HexStr(BEGIN(merkleh), END(merkleh)));
        }

        result.push_back(Pair("merkle", merkle_arr));


        return result;
    }
// TODO: allow to query for future blocks
Value getsubsidy(const Array& params, bool fHelp)
{
    if (fHelp || params.size() > 2) {
        throw runtime_error(
            "getsubsidy [height] [height]\n"
            "If no height is provided, return subsidy of current block.\n"
            "Returns the pow reward for block at height or from one to the other.\n"
            "Biggest height should be no more than the last pow block.");
    }

    Object ret;


#if PROOF_MODEL == PURE_POS
    static const int nLastPoWBlock = GetLastPoWBlock();
#endif

    if (params.size() == 0) {
            struct AMOUNT subsidy = GetPoWSubsidy(pindexBest);
            ret.push_back(Pair("blockvalue", subsidy.nValue));
            ret.push_back(Pair("currency", COLOR_TICKER[subsidy.nColor]));
    }
    else if (params.size() == 1) {

            int nHeight = (int) params[0].get_int();
#if PROOF_MODEL == PURE_POS
            if (nHeight > GetLastPoWBlock() || nHeight < 1)
#else
            if (nHeight > (int) nBestHeight + 1 || nHeight < 1)
#endif
            {
                  throw runtime_error(
                    "getsubsidy [height] [height]\n"
                    "If no height is provided, return subsidy of current block.\n"
                    "Returns the pow reward for block at height or from one to the other.\n"
                    "Biggest height should be no more than the last pow block.");
            }

            CBlockIndex *pindexPrev;

            if (nHeight == (int) nBestHeight + 1)
            {
                 pindexPrev = pindexBest;
            }
            else
            {
                pindexPrev = GetBlockIndexByNumber(nHeight)->pprev;
            }

            struct AMOUNT subsidy = GetPoWSubsidy(pindexPrev);
            ret.push_back(Pair("blockvalue", subsidy.nValue));
            ret.push_back(Pair("currency", COLOR_TICKER[subsidy.nColor]));
    }
    else {
            int p1, p2;
            p1 = params[0].get_int();
            p2 = params[1].get_int();
#if PROOF_MODEL == PURE_POS
            if ((p1 < 1) || (p2 < 1) || (p1 > nLastPoWBlock) || (p2 > nLastPoWBlock)) {
#else
            if ((p1 < 1) || (p2 < 1) || (p1 > (int) nBestHeight) || (p2 > (int) nBestHeight))
            {
#endif
                  throw runtime_error(
                    "getsubsidy [height] [height]\n"
                    "If no height is provided, return subsidy of current block.\n"
                    "Returns the pow reward for block at height or from one to the other.\n"
                    "Biggest height should be no more than the last pow block.");
            }
            int first, last;
            if (p1 > p2) {
                    first = p2;
                    last = p1;
            }
            else {
                    first = p1;
                    last = p2;
            }

           for (int i = first; i <= last; i++) {
              Object obj;
              CBlockIndex *pindex = GetBlockIndexByNumber(i);
              struct AMOUNT subsidy = GetPoWSubsidy(pindex->pprev);
              obj.push_back(Pair("blockvalue", subsidy.nValue));
              obj.push_back(Pair("currency", COLOR_TICKER[subsidy.nColor]));
              ret.push_back(Pair(boost::lexical_cast<string>(i), obj));
           }
    }
    return ret;
}


Value getmininginfo(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getmininginfo\n"
            "Returns an object containing mining-related information.");

    bool hasPoS = (nNumberOfStakingCurrencies > 0);

    uint64_t nWeight = 0;
    if (hasPoS)
    {
        pwalletMain->GetStakeWeight(*pwalletMain, nWeight);
    }

    Object obj, diff, weight;

    obj.push_back(Pair("blocks",        (int)nBestHeight));
    obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize));
    obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx));

    diff.push_back(Pair("proof-of-work",        GetDifficulty()));
    if (hasPoS)
    {
        diff.push_back(Pair("proof-of-stake",       GetDifficulty(GetLastBlockIndex(pindexBest, true))));
        diff.push_back(Pair("search-interval",      (int)nLastCoinStakeSearchInterval));
    }
    obj.push_back(Pair("difficulty",    diff));

    struct AMOUNT subsidy = GetPoWSubsidy(pindexBest);
    obj.push_back(Pair("blockvalue", subsidy.nValue));
    obj.push_back(Pair("currency", COLOR_TICKER[subsidy.nColor]));
    obj.push_back(Pair("netmhashps",     GetPoWMHashPS()));
    if (hasPoS)
    {
         obj.push_back(Pair("netstakeweight", GetPoSKernelPS()));
    }
    obj.push_back(Pair("errors",        GetWarnings("statusbar")));
    obj.push_back(Pair("pooledtx",      (uint64_t)mempool.size()));

    if (hasPoS)
    {
        weight.push_back(Pair("combined",  (uint64_t)nWeight));
        obj.push_back(Pair("stakeweight", weight));

        // IMPORTANT: if you use interest stake, then fix this stuff
        Object stakeObj;
        for (int nStakeColor = 1; nStakeColor < N_COLORS; ++nStakeColor)
        {
              struct AMOUNT subsidy = GetProofOfStakeReward(pindexBest, nStakeColor);
              if (subsidy.nValue > 0)
              {
                     Object mintObj;
                     mintObj.push_back(Pair(COLOR_TICKER[subsidy.nColor], (uint64_t) subsidy.nValue));
                     stakeObj.push_back(Pair(COLOR_TICKER[nStakeColor], mintObj));
              }
        }
        obj.push_back(Pair("stakereward",   stakeObj));
    }
    obj.push_back(Pair("testnet",       fTestNet));
    return obj;
}

Value getstakinginfo(const Array& params, bool fHelp)
{
    if (nNumberOfStakingCurrencies == 0)
    {
        throw runtime_error("No staking currencies.\n");
    }

    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getstakinginfo\n"
            "Returns an object containing staking-related information.");

    int nTargetSpacing = GetTargetSpacing(true, pindexBest->nTime);


    uint64_t nWeight = 0;
    pwalletMain->GetStakeWeight(*pwalletMain, nWeight);

    uint64_t nNetworkWeight = GetPoSKernelPS();
    bool staking = nLastCoinStakeSearchInterval && nWeight;
    int nExpectedTime = staking ? (nTargetSpacing * nNetworkWeight / nWeight) : -1;

    Object obj;

    obj.push_back(Pair("enabled", GetBoolArg("-staking", true)));
    obj.push_back(Pair("staking", staking));
    obj.push_back(Pair("errors", GetWarnings("statusbar")));

    obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
    obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
    obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));

    obj.push_back(Pair("difficulty", GetDifficulty(GetLastBlockIndex(pindexBest, true))));
    obj.push_back(Pair("search-interval", (int)nLastCoinStakeSearchInterval));

    obj.push_back(Pair("weight", (uint64_t)nWeight));
    obj.push_back(Pair("netstakeweight", (uint64_t)nNetworkWeight));

    obj.push_back(Pair("expectedtime", nExpectedTime));

    return obj;
}

Value getworkex(const Array& params, bool fHelp)
{
    if (fHelp || params.size() > 2)
        throw runtime_error(
            "getworkex [data, coinbase]\n"
            "If [data, coinbase] is not specified, returns extended work data.\n"
        );

    if (vNodes.empty())
        throw JSONRPCError(-9, "breakout is not connected!");

    if (IsInitialBlockDownload())
        throw JSONRPCError(-10, "breakout is downloading blocks...");

#if PROOF_MODEL == PURE_POS
    static const int nLastPoWBlock = GetLastPoWBlock();
    if (pindexBest->nHeight >= nLastPoWBlock)
        throw JSONRPCError(RPC_MISC_ERROR, "No more PoW blocks");
#endif

    typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
    static mapNewBlock_t mapNewBlock;
    static vector<CBlock*> vNewBlock;
    static CReserveKey reservekey(pwalletMain);

    if (params.size() == 0)
    {
        // Update block
        static unsigned int nTransactionsUpdatedLast;
        static CBlockIndex* pindexPrev;
        static int64_t nStart;
        static CBlock* pblock;
        if (pindexPrev != pindexBest ||
            (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
        {
            if (pindexPrev != pindexBest)
            {
                // Deallocate old blocks since they're obsolete now
                mapNewBlock.clear();
                BOOST_FOREACH(CBlock* pblock, vNewBlock)
                    delete pblock;
                vNewBlock.clear();
            }
            nTransactionsUpdatedLast = nTransactionsUpdated;
            pindexPrev = pindexBest;
            nStart = GetTime();

            // Create new block
            pblock = CreateNewBlock(pwalletMain);
            if (!pblock)
                throw JSONRPCError(-7, "Out of memory");
            vNewBlock.push_back(pblock);
        }

        // Update nTime
        pblock->nTime = max(pindexPrev->GetPastTimeLimit()+1, GetAdjustedTime());
        pblock->nNonce = 0;

        // Update nExtraNonce
        static unsigned int nExtraNonce = 0;
        IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);

        // Save
        mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);

        // Prebuild hash buffers
        char pmidstate[32];
        char pdata[128];
        char phash1[64];
        FormatHashBuffers(pblock, pmidstate, pdata, phash1);

        uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();

        CTransaction coinbaseTx = pblock->vtx[0];
        std::vector<uint256> merkle = pblock->GetMerkleBranch(0);

        Object result;
        result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
        result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));

        CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
        ssTx << coinbaseTx;
        result.push_back(Pair("coinbase", HexStr(ssTx.begin(), ssTx.end())));

        Array merkle_arr;

        BOOST_FOREACH(uint256 merkleh, merkle) {
            merkle_arr.push_back(HexStr(BEGIN(merkleh), END(merkleh)));
        }

        result.push_back(Pair("merkle", merkle_arr));


        return result;
    }
    else
    {