bool CMasternodeBroadcast::Create(const COutPoint& outpoint, const CService& service, const CKey& keyCollateralAddressNew, const CPubKey& pubKeyCollateralAddressNew, const CKey& keyMasternodeNew, const CPubKey& pubKeyMasternodeNew, std::string& strErrorRet, CMasternodeBroadcast& mnbRet)
{
    // wait for reindex and/or import to finish
    if (fImporting || fReindex) return false;

    LogPrint(MCLog::MN, "CMasternodeBroadcast::Create -- pubKeyCollateralAddressNew = %s, pubKeyMasternodeNew.GetID() = %s\n",
        EncodeDestination(CScriptID(GetScriptForDestination(WitnessV0KeyHash(pubKeyCollateralAddressNew.GetID())))),
        EncodeDestination(CScriptID(GetScriptForDestination(WitnessV0KeyHash(pubKeyMasternodeNew.GetID())))));

    auto Log = [&strErrorRet, &mnbRet](std::string sErr) -> bool {
        strErrorRet = sErr;
        mnbRet = CMasternodeBroadcast();
        return false;
    };

    CMasternodePing mnp(outpoint);
    if (!mnp.Sign(keyMasternodeNew, pubKeyMasternodeNew))
        return Log(strprintf("Failed to sign ping, masternode=%s", outpoint.ToStringShort()));

    mnbRet = CMasternodeBroadcast(service, outpoint, pubKeyCollateralAddressNew, pubKeyMasternodeNew, PROTOCOL_VERSION);

    if (!mnbRet.IsValidNetAddr())
        return Log(strprintf("Invalid IP address, masternode=%s", outpoint.ToStringShort()));

    mnbRet.lastPing = mnp;
    if (!mnbRet.Sign(keyCollateralAddressNew))
        return Log(strprintf("Failed to sign broadcast, masternode=%s", outpoint.ToStringShort()));

    return true;
}
Beispiel #2
0
Value checkkernel(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "checkkernel [{\"txid\":txid,\"vout\":n},...] [createblocktemplate=false]\n"
            "Check if one of given inputs is a kernel input at the moment.\n"
        );

    RPCTypeCheck(params, list_of(array_type)(bool_type));

    Array inputs = params[0].get_array();
    bool fCreateBlockTemplate = params.size() > 1 ? params[1].get_bool() : false;

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

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

    COutPoint kernel;
    CBlockIndex* pindexPrev = pindexBest;
    unsigned int nBits = GetNextTargetRequired(pindexPrev, true);
    int64_t nTime = GetAdjustedTime();
    nTime &= ~STAKE_TIMESTAMP_MASK;

    BOOST_FOREACH(Value& input, inputs)
    {
        const Object& o = input.get_obj();

        const Value& txid_v = find_value(o, "txid");
        if (txid_v.type() != str_type)
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing txid key");
        string txid = txid_v.get_str();
        if (!IsHex(txid))
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");

        const Value& vout_v = find_value(o, "vout");
        if (vout_v.type() != int_type)
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
        int nOutput = vout_v.get_int();
        if (nOutput < 0)
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");

        COutPoint cInput(uint256(txid), nOutput);
        if (CheckKernel(pindexPrev, nBits, nTime, cInput))
        {
            kernel = cInput;
            break;
        }
    }

    Object result;
    result.push_back(Pair("found", !kernel.IsNull()));

    if (kernel.IsNull())
        return result;

    Object oKernel;
    oKernel.push_back(Pair("txid", kernel.hash.GetHex()));
    oKernel.push_back(Pair("vout", (int64_t)kernel.n));
    oKernel.push_back(Pair("time", nTime));
    result.push_back(Pair("kernel", oKernel));

    if (!fCreateBlockTemplate)
        return result;

    int64_t nFees;
    auto_ptr<CBlock> pblock(CreateNewBlock(*pMiningKey, true, &nFees));

    pblock->nTime = pblock->vtx[0].nTime = nTime;

    CDataStream ss(SER_DISK, PROTOCOL_VERSION);
    ss << *pblock;

    result.push_back(Pair("blocktemplate", HexStr(ss.begin(), ss.end())));
    result.push_back(Pair("blocktemplatefees", nFees));

    CPubKey pubkey;
    if (!pMiningKey->GetReservedKey(pubkey))
        throw JSONRPCError(RPC_MISC_ERROR, "GetReservedKey failed");

    result.push_back(Pair("blocktemplatesignkey", HexStr(pubkey)));

    return result;
}
Beispiel #3
0
std::set<uint256> CGovernanceObject::RemoveInvalidVotes(const COutPoint& mnOutpoint)
{
    LOCK(cs);

    auto it = mapCurrentMNVotes.find(mnOutpoint);
    if (it == mapCurrentMNVotes.end()) {
        // don't even try as we don't have any votes from this MN
        return {};
    }

    auto removedVotes = fileVotes.RemoveInvalidVotes(mnOutpoint, nObjectType == GOVERNANCE_OBJECT_PROPOSAL);
    if (removedVotes.empty()) {
        return {};
    }

    auto nParentHash = GetHash();
    for (auto jt = it->second.mapInstances.begin(); jt != it->second.mapInstances.end(); ) {
        CGovernanceVote tmpVote(mnOutpoint, nParentHash, (vote_signal_enum_t)jt->first, jt->second.eOutcome);
        tmpVote.SetTime(jt->second.nCreationTime);
        if (removedVotes.count(tmpVote.GetHash())) {
            jt = it->second.mapInstances.erase(jt);
        } else {
            ++jt;
        }
    }
    if (it->second.mapInstances.empty()) {
        mapCurrentMNVotes.erase(it);
    }

    if (!removedVotes.empty()) {
        std::string removedStr;
        for (auto& h : removedVotes) {
            removedStr += strprintf("  %s\n", h.ToString());
        }
        LogPrintf("CGovernanceObject::%s -- Removed %d invalid votes for %s from MN %s:\n%s", __func__, removedVotes.size(), nParentHash.ToString(), mnOutpoint.ToString(), removedStr);
        fDirtyCache = true;
    }

    return removedVotes;
}
    void updateMasternode(interfaces::Node& node, const COutPoint& outpoint, int status)
    {
        qDebug() << "MasternodeTablePriv::updateMasternode" + QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status);

        // Find bounds of this masternode in model
        QString strOutpoint = QString::fromStdString(outpoint.ToStringShort());
        QList<MasternodeTableEntry>::iterator lower = qLowerBound(
            cachedMasternodeTable.begin(), cachedMasternodeTable.end(), strOutpoint, outpointEntryLessThan());
        QList<MasternodeTableEntry>::iterator upper = qUpperBound(
            cachedMasternodeTable.begin(), cachedMasternodeTable.end(), strOutpoint, outpointEntryLessThan());
        int lowerIndex = (lower - cachedMasternodeTable.begin());
        int upperIndex = (upper - cachedMasternodeTable.begin());
        bool inModel = (lower != upper);
        switch(status)
        {
        case CT_NEW:
            if(inModel)
            {
                //must be our own one and we are just at a clean start -> try to update
                interfaces::Masternode masternode = node.getMasternode(outpoint);
                lower->txhash = QString::fromStdString(masternode.outpoint.hash.ToString());
                lower->n = masternode.outpoint.n;
                lower->alias = QString::fromStdString(masternode.alias);
                lower->address = QString::fromStdString(masternode.address);
                lower->protocol = masternode.protocol;
                lower->daemon = masternode.daemon;
                lower->sentinel = masternode.sentinel;
                lower->status = QString::fromStdString(masternode.status);
                lower->active = masternode.active;
                lower->lastseen = masternode.last_seen;
                lower->payee = QString::fromStdString(masternode.payee);
                lower->banscore = masternode.banscore;
                parent->emitDataChanged(lowerIndex);
                break;
            }
        {
            // Find masternode on platform
            interfaces::Masternode masternode = node.getMasternode(outpoint);
            if(masternode.outpoint == COutPoint())
            {
                qWarning() << "MasternodeTablePriv::updateMasternode: Warning: Got CT_NEW, but masternode is not on platform: " + QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status);
                break;
            }
            // Added -- insert at the right position
            MasternodeTableEntry::Type addressType = translateMasternodeType(
                        QString::fromStdString(masternode.alias));

            MasternodeTableEntry toInsert =
                    MasternodeTableEntry(
                        addressType,
                        QString::fromStdString(masternode.outpoint.hash.ToString()),
                        masternode.outpoint.n,
                        QString::fromStdString(masternode.alias),
                        QString::fromStdString(masternode.address),
                        masternode.protocol,
                        masternode.daemon,
                        masternode.sentinel,
                        QString::fromStdString(masternode.status),
                        masternode.active,
                        masternode.last_seen,
                        QString::fromStdString(masternode.payee),
                        masternode.banscore);

            parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
            cachedMasternodeTable.insert(lowerIndex, toInsert);
            parent->endInsertRows();
        }
            break;
        case CT_DELETED:
            if(!inModel)
            {
                qWarning() << "MasternodeTablePriv::updateMasternode: Warning: Got CT_DELETED, but masternode is not in model: " + QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status);
                break;
            }
            // Removed -- remove entire masternode from table
            parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
            cachedMasternodeTable.erase(lower, upper);
            parent->endRemoveRows();
            break;
        case CT_UPDATED:
            if(!inModel)
            {
                qWarning() << "MasternodeTablePriv::updateMasternode: Warning: Got CT_UPDATED, but entry is not in model: "+ QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status);
                break;
            }
        {
            // Find masternode on platform
            interfaces::Masternode masternode = node.getMasternode(outpoint);
            //don't remove our own nodes
            if(lower->alias == "" && masternode.outpoint == COutPoint())
            {
                // did we receive a wrong signal? The node got highes priority, delete the entry
                qWarning() << "MasternodeTablePriv::updateMasternode: Warning: Got CT_UPDATED, but masternode is not on platform: " + QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status);
                parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
                cachedMasternodeTable.erase(lower, upper);
                parent->endRemoveRows();
                break;
            }
            MasternodeTableEntry::Type addressType = translateMasternodeType(
                        QString::fromStdString(masternode.alias));
            lower->type = addressType;
            lower->txhash = QString::fromStdString(masternode.outpoint.hash.ToString());
            lower->n = masternode.outpoint.n;
            lower->alias = QString::fromStdString(masternode.alias);
            lower->address = QString::fromStdString(masternode.address);
            lower->protocol = masternode.protocol;
            lower->daemon = masternode.daemon;
            lower->sentinel = masternode.sentinel;
            lower->status = QString::fromStdString(masternode.status);
            lower->active = masternode.active;
            lower->lastseen = masternode.last_seen;
            lower->payee = QString::fromStdString(masternode.payee);
            lower->banscore = masternode.banscore;
            parent->emitDataChanged(lowerIndex);
        }
            break;
        }
    }