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; }
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; }
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; } }