// // Bootup the masternode, look for a 200000 SPL input and register on the network // void CActiveMasternode::ManageStatus() { std::string errorMessage; if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n"); if(!fMasterNode) return; //need correct adjusted time to send ping bool fIsInitialDownload = IsInitialBlockDownload(); if(fIsInitialDownload) { status = MASTERNODE_SYNC_IN_PROCESS; LogPrintf("CActiveMasternode::ManageStatus() - Sync in progress. Must wait until sync is complete to start masternode.\n"); return; } if(status == MASTERNODE_INPUT_TOO_NEW || status == MASTERNODE_NOT_CAPABLE || status == MASTERNODE_SYNC_IN_PROCESS){ status = MASTERNODE_NOT_PROCESSED; } if(status == MASTERNODE_NOT_PROCESSED) { if(strMasterNodeAddr.empty()) { if(!GetLocal(service)) { notCapableReason = "Can't detect external address. Please use the masternodeaddr configuration option."; status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } } else { service = CService(strMasterNodeAddr, true); } LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString().c_str()); if(!ConnectNode((CAddress)service, service.ToString().c_str())){ notCapableReason = "Could not connect to " + service.ToString(); status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } if(pwalletMain->IsLocked()){ notCapableReason = "Wallet is locked."; status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } // Set defaults status = MASTERNODE_NOT_CAPABLE; notCapableReason = "Unknown. Check debug.log for more information.\n"; // Choose coins to use CPubKey pubKeyCollateralAddress; CKey keyCollateralAddress; if(GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress)) { if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ notCapableReason = "Input must have least " + boost::lexical_cast<string>(MASTERNODE_MIN_CONFIRMATIONS) + " confirmations - " + boost::lexical_cast<string>(GetInputAge(vin)) + " confirmations"; LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason.c_str()); status = MASTERNODE_INPUT_TOO_NEW; return; } LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n"); status = MASTERNODE_IS_CAPABLE; notCapableReason = ""; pwalletMain->LockCoin(vin.prevout); // send to all nodes CPubKey pubKeyMasternode; CKey keyMasternode; if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) { LogPrintf("ActiveMasternode::Dseep() - Error upon calling SetKey: %s\n", errorMessage.c_str()); return; } /* rewards are not supported in simplicity.conf */ CScript rewardAddress = CScript(); int rewardPercentage = 0; if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, rewardAddress, rewardPercentage, errorMessage)) { LogPrintf("CActiveMasternode::ManageStatus() - Error on Register: %s\n", errorMessage.c_str()); } return; } else { notCapableReason = "Could not find suitable coins!"; LogPrintf("CActiveMasternode::ManageStatus() - Could not find suitable coins!\n"); } } //send to all peers if(!Dseep(errorMessage)) { LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s\n", errorMessage.c_str()); } }
bool ClientModel::inInitialBlockDownload() const { return IsInitialBlockDownload(); }
void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) { if (strCommand == "dsee") { //DarkSend Election Entry if(fLiteMode) return; //disable all darksend/masternode related functionality bool fIsInitialDownload = IsInitialBlockDownload(); if(fIsInitialDownload) return; CTxIn vin; CService addr; CPubKey pubkey; CPubKey pubkey2; vector<unsigned char> vchSig; int64_t sigTime; int count; int current; int64_t lastUpdated; int protocolVersion; std::string strMessage; // 70047 and greater vRecv >> vin >> addr >> vchSig >> sigTime >> pubkey >> pubkey2 >> count >> current >> lastUpdated >> protocolVersion; // make sure signature isn't in the future (past is OK) if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("dsee - Signature rejected, too far into the future %s\n", vin.ToString().c_str()); return; } bool isLocal = addr.IsRFC1918() || addr.IsLocal(); //if(Params().MineBlocksOnDemand()) isLocal = false; std::string vchPubKey(pubkey.begin(), pubkey.end()); std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion); if(protocolVersion < MIN_MN_PROTO_VERSION) { LogPrintf("dsee - ignoring outdated masternode %s protocol version %d\n", vin.ToString().c_str(), protocolVersion); return; } CScript pubkeyScript; pubkeyScript =GetScriptForDestination(pubkey.GetID()); if(pubkeyScript.size() != 25) { LogPrintf("dsee - pubkey the wrong size\n"); Misbehaving(pfrom->GetId(), 100); return; } CScript pubkeyScript2; pubkeyScript2 =GetScriptForDestination(pubkey2.GetID()); if(pubkeyScript2.size() != 25) { LogPrintf("dsee - pubkey2 the wrong size\n"); Misbehaving(pfrom->GetId(), 100); return; } std::string errorMessage = ""; if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){ LogPrintf("dsee - Got bad masternode address signature\n"); Misbehaving(pfrom->GetId(), 100); return; } //search existing masternode list, this is where we update existing masternodes with new dsee broadcasts LOCK(cs_masternodes); BOOST_FOREACH(CMasterNode& mn, vecMasternodes) { if(mn.vin.prevout == vin.prevout) { // count == -1 when it's a new entry // e.g. We don't want the entry relayed/time updated when we're syncing the list // mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below, // after that they just need to match if(count == -1 && mn.pubkey == pubkey && !mn.UpdatedWithin(MASTERNODE_MIN_DSEE_SECONDS)){ mn.UpdateLastSeen(); if(mn.now < sigTime){ //take the newest entry LogPrintf("dsee - Got updated entry for %s\n", addr.ToString().c_str()); mn.pubkey2 = pubkey2; mn.now = sigTime; mn.sig = vchSig; mn.protocolVersion = protocolVersion; mn.addr = addr; RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion); } } return; } } // make sure the vout that was signed is related to the transaction that spawned the masternode // - this is expensive, so it's only done once per masternode if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) { LogPrintf("dsee - Got mismatched pubkey and vin\n"); Misbehaving(pfrom->GetId(), 100); return; } if(fDebug) LogPrintf("dsee - Got NEW masternode entry %s\n", addr.ToString().c_str()); // make sure it's still unspent // - this is checked later by .check() in many places and by ThreadCheckDarkSendPool() CValidationState state; CTransaction tx = CTransaction(); CTxOut vout = CTxOut(19999*COIN, darkSendPool.collateralPubKey); tx.vin.push_back(vin); tx.vout.push_back(vout); //if(AcceptableInputs(mempool, state, tx)){ bool* pfMissingInputs = NULL; if(AcceptableInputs(mempool, tx, false, pfMissingInputs)){ if(fDebug) LogPrintf("dsee - Accepted masternode entry %i %i\n", count, current); if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ LogPrintf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS); Misbehaving(pfrom->GetId(), 20); return; } // use this as a peer addrman.Add(CAddress(addr), pfrom->addr, 2*60*60); // add our masternode CMasterNode mn(addr, vin, pubkey, vchSig, sigTime, pubkey2, protocolVersion); mn.UpdateLastSeen(lastUpdated); vecMasternodes.push_back(mn); // if it matches our masternodeprivkey, then we've been remotely activated if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){ activeMasternode.EnableHotColdMasterNode(vin, addr); } if(count == -1 && !isLocal) RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion); } else { LogPrintf("dsee - Rejected masternode entry %s\n", addr.ToString().c_str()); int nDoS = 0; if (state.IsInvalid(nDoS)) { LogPrintf("dsee - %s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(), pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str()); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } } } else if (strCommand == "dseep") { //DarkSend Election Entry Ping
static UniValue getblocktemplate(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getblocktemplate ( TemplateRequest )\n" "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n" "It returns data needed to construct a block to work on.\n" "For full specification, see BIPs 22, 23, 9, and 145:\n" " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n" " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n" "\nArguments:\n" "1. template_request (json object, optional) A json object in the following spec\n" " {\n" " \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n" " \"capabilities\":[ (array, optional) A list of strings\n" " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n" " ,...\n" " ],\n" " \"rules\":[ (array, optional) A list of strings\n" " \"support\" (string) client side supported softfork deployment\n" " ,...\n" " ]\n" " }\n" "\n" "\nResult:\n" "{\n" " \"version\" : n, (numeric) The preferred block version\n" " \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n" " \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n" " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" " ,...\n" " },\n" " \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n" " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" " \"depends\" : [ (array) array of numbers \n" " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" " ],\n" " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" " \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" " }\n" " ,...\n" " ],\n" " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" " \"flags\" : \"xx\" (string) key name is to be ignored, and value included in scriptSig\n" " },\n" " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)\n" " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" " \"target\" : \"xxxx\", (string) The hash target\n" " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"mutable\" : [ (array of string) list of ways the block template may be changed \n" " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" " ,...\n" " ],\n" " \"noncerange\" : \"00000000ffffffff\",(string) A range of valid nonces\n" " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n" " \"sizelimit\" : n, (numeric) limit of block size\n" " \"weightlimit\" : n, (numeric) limit of block weight\n" " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n" " \"bits\" : \"xxxxxxxx\", (string) compressed target of next block\n" " \"height\" : n (numeric) The height of the next block\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblocktemplate", "") + HelpExampleRpc("getblocktemplate", "") ); LOCK(cs_main); std::string strMode = "template"; UniValue lpval = NullUniValue; std::set<std::string> setClientRules; int64_t nMaxVersionPreVB = -1; if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); const UniValue& modeval = find_value(oparam, "mode"); if (modeval.isStr()) strMode = modeval.get_str(); else if (modeval.isNull()) { /* Do nothing */ } else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); lpval = find_value(oparam, "longpollid"); if (strMode == "proposal") { const UniValue& dataval = find_value(oparam, "data"); if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; if (!DecodeHexBlk(block, dataval.get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); uint256 hash = block.GetHash(); const CBlockIndex* pindex = LookupBlockIndex(hash); if (pindex) { if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) return "duplicate"; if (pindex->nStatus & BLOCK_FAILED_MASK) return "duplicate-invalid"; return "duplicate-inconclusive"; } CBlockIndex* const pindexPrev = chainActive.Tip(); // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) return "inconclusive-not-best-prevblk"; CValidationState state; TestBlockValidity(state, Params(), block, pindexPrev, false, true); return BIP22ValidationResult(state); } const UniValue& aClientRules = find_value(oparam, "rules"); if (aClientRules.isArray()) { for (unsigned int i = 0; i < aClientRules.size(); ++i) { const UniValue& v = aClientRules[i]; setClientRules.insert(v.get_str()); } } else { // NOTE: It is important that this NOT be read if versionbits is supported const UniValue& uvMaxVersion = find_value(oparam, "maxversion"); if (uvMaxVersion.isNum()) { nMaxVersionPreVB = uvMaxVersion.get_int64(); } } } if (strMode != "template") throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Feathercoin is not connected!"); if (IsInitialBlockDownload()) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Feathercoin is downloading blocks..."); static unsigned int nTransactionsUpdatedLast; if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions uint256 hashWatchedChain; std::chrono::steady_clock::time_point checktxtime; unsigned int nTransactionsUpdatedLastLP; if (lpval.isStr()) { // Format: <hashBestChain><nTransactionsUpdatedLast> std::string lpstr = lpval.get_str(); hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid"); nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64)); } else { // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier hashWatchedChain = chainActive.Tip()->GetBlockHash(); nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } // Release the wallet and main lock while waiting LEAVE_CRITICAL_SECTION(cs_main); { checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1); WAIT_LOCK(g_best_block_mutex, lock); while (g_best_block == hashWatchedChain && IsRPCRunning()) { if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout) { // Timeout: Check transactions for update if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) break; checktxtime += std::chrono::seconds(10); } } } ENTER_CRITICAL_SECTION(cs_main); if (!IsRPCRunning()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down"); // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners? } const struct VBDeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT]; // If the caller is indicating segwit support, then allow CreateNewBlock() // to select witness transactions, after segwit activates (otherwise // don't). bool fSupportsSegwit = setClientRules.find(segwit_info.name) != setClientRules.end(); // Update block static CBlockIndex* pindexPrev; static int64_t nStart; static std::unique_ptr<CBlockTemplate> pblocktemplate; // Cache whether the last invocation was with segwit support, to avoid returning // a segwit-block to a non-segwit caller. static bool fLastTemplateSupportsSegwit = true; if (pindexPrev != chainActive.Tip() || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5) || fLastTemplateSupportsSegwit != fSupportsSegwit) { // Clear pindexPrev so future calls make a new block, despite any failures from here on pindexPrev = nullptr; // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrevNew = chainActive.Tip(); nStart = GetTime(); fLastTemplateSupportsSegwit = fSupportsSegwit; // Create new block CScript scriptDummy = CScript() << OP_TRUE; pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); // Need to update only after we know CreateNewBlock succeeded pindexPrev = pindexPrevNew; } assert(pindexPrev); CBlock* pblock = &pblocktemplate->block; // pointer for convenience const Consensus::Params& consensusParams = Params().GetConsensus(); // Update nTime UpdateTime(pblock, consensusParams, pindexPrev); pblock->nNonce = 0; // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration const bool fPreSegWit = (ThresholdState::ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache)); UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue transactions(UniValue::VARR); std::map<uint256, int64_t> setTxIndex; int i = 0; for (const auto& it : pblock->vtx) { const CTransaction& tx = *it; uint256 txHash = tx.GetHash(); setTxIndex[txHash] = i++; if (tx.IsCoinBase()) continue; UniValue entry(UniValue::VOBJ); entry.pushKV("data", EncodeHexTx(tx)); entry.pushKV("txid", txHash.GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); UniValue deps(UniValue::VARR); for (const CTxIn &in : tx.vin) { if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } entry.pushKV("depends", deps); int index_in_template = i - 1; entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]); int64_t nTxSigOps = pblocktemplate->vTxSigOpsCost[index_in_template]; if (fPreSegWit) { assert(nTxSigOps % WITNESS_SCALE_FACTOR == 0); nTxSigOps /= WITNESS_SCALE_FACTOR; } entry.pushKV("sigops", nTxSigOps); entry.pushKV("weight", GetTransactionWeight(tx)); transactions.push_back(entry); } UniValue aux(UniValue::VOBJ); aux.pushKV("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); UniValue aMutable(UniValue::VARR); aMutable.push_back("time"); aMutable.push_back("transactions"); aMutable.push_back("prevblock"); UniValue result(UniValue::VOBJ); result.pushKV("capabilities", aCaps); UniValue aRules(UniValue::VARR); UniValue vbavailable(UniValue::VOBJ); for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { Consensus::DeploymentPos pos = Consensus::DeploymentPos(j); ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache); switch (state) { case ThresholdState::DEFINED: case ThresholdState::FAILED: // Not exposed to GBT at all break; case ThresholdState::LOCKED_IN: // Ensure bit is set in block version pblock->nVersion |= VersionBitsMask(consensusParams, pos); // FALL THROUGH to get vbavailable set... case ThresholdState::STARTED: { const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; vbavailable.pushKV(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit); if (setClientRules.find(vbinfo.name) == setClientRules.end()) { if (!vbinfo.gbt_force) { // If the client doesn't support this, don't indicate it in the [default] version pblock->nVersion &= ~VersionBitsMask(consensusParams, pos); } } break; } case ThresholdState::ACTIVE: { // Add to rules only const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; aRules.push_back(gbt_vb_name(pos)); if (setClientRules.find(vbinfo.name) == setClientRules.end()) { // Not supported by the client; make sure it's safe to proceed if (!vbinfo.gbt_force) { // If we do anything other than throw an exception here, be sure version/force isn't sent to old clients throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name)); } } break; } } } result.pushKV("version", pblock->nVersion); result.pushKV("rules", aRules); result.pushKV("vbavailable", vbavailable); result.pushKV("vbrequired", int(0)); if (nMaxVersionPreVB >= 2) { // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here // Because BIP 34 changed how the generation transaction is serialized, we can only use version/force back to v2 blocks // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated aMutable.push_back("version/force"); } result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex()); result.pushKV("transactions", transactions); result.pushKV("coinbaseaux", aux); result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue); result.pushKV("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)); result.pushKV("target", hashTarget.GetHex()); result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1); result.pushKV("mutable", aMutable); result.pushKV("noncerange", "00000000ffffffff"); int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST; int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE; if (fPreSegWit) { assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0); nSigOpLimit /= WITNESS_SCALE_FACTOR; assert(nSizeLimit % WITNESS_SCALE_FACTOR == 0); nSizeLimit /= WITNESS_SCALE_FACTOR; } result.pushKV("sigoplimit", nSigOpLimit); result.pushKV("sizelimit", nSizeLimit); if (!fPreSegWit) { result.pushKV("weightlimit", (int64_t)MAX_BLOCK_WEIGHT); } result.pushKV("curtime", pblock->GetBlockTime()); result.pushKV("bits", strprintf("%08x", pblock->nBits)); result.pushKV("height", (int64_t)(pindexPrev->nHeight+1)); if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) { result.pushKV("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end())); } return result; }
LogPrintf("dsee - Rejected masternode entry %s\n", addr.ToString().c_str()); int nDoS = 0; if (state.IsInvalid(nDoS)) { LogPrintf("dsee - %s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(), pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str()); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } } } else if (strCommand == "dseep") { //DarkSend Election Entry Ping if(fLiteMode) return; //disable all darksend/masternode related functionality bool fIsInitialDownload = IsInitialBlockDownload(); if(fIsInitialDownload) return; CTxIn vin; vector<unsigned char> vchSig; int64_t sigTime; bool stop; vRecv >> vin >> vchSig >> sigTime >> stop; //LogPrintf("dseep - Received: vin: %s sigTime: %lld stop: %s\n", vin.ToString().c_str(), sigTime, stop ? "true" : "false"); if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("dseep - Signature rejected, too far into the future %s\n", vin.ToString().c_str()); return; }
UniValue name_filter (const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 5) throw std::runtime_error ( "name_filter (\"regexp\" (\"maxage\" (\"from\" (\"nb\" (\"stat\")))))\n" "\nScan and list names matching a regular expression.\n" "\nArguments:\n" "1. \"regexp\" (string, optional) filter names with this regexp\n" "2. \"maxage\" (numeric, optional, default=36000) only consider names updated in the last \"maxage\" blocks; 0 means all names\n" "3. \"from\" (numeric, optional, default=0) return from this position onward; index starts at 0\n" "4. \"nb\" (numeric, optional, default=0) return only \"nb\" entries; 0 means all\n" "5. \"stat\" (string, optional) if set to the string \"stat\", print statistics instead of returning the names\n" "\nResult:\n" "[\n" + getNameInfoHelp (" ", ",") + " ...\n" "]\n" "\nExamples:\n" + HelpExampleCli ("name_filter", "\"\" 5") + HelpExampleCli ("name_filter", "\"^id/\"") + HelpExampleCli ("name_filter", "\"^id/\" 36000 0 0 \"stat\"") + HelpExampleRpc ("name_scan", "\"^d/\"") ); if (IsInitialBlockDownload ()) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Namecoin is downloading blocks..."); /* ********************** */ /* Interpret parameters. */ bool haveRegexp(false); boost::xpressive::sregex regexp; int maxage(36000), from(0), nb(0); bool stats(false); if (request.params.size () >= 1) { haveRegexp = true; regexp = boost::xpressive::sregex::compile (request.params[0].get_str ()); } if (request.params.size () >= 2) maxage = request.params[1].get_int (); if (maxage < 0) throw JSONRPCError (RPC_INVALID_PARAMETER, "'maxage' should be non-negative"); if (request.params.size () >= 3) from = request.params[2].get_int (); if (from < 0) throw JSONRPCError (RPC_INVALID_PARAMETER, "'from' should be non-negative"); if (request.params.size () >= 4) nb = request.params[3].get_int (); if (nb < 0) throw JSONRPCError (RPC_INVALID_PARAMETER, "'nb' should be non-negative"); if (request.params.size () >= 5) { if (request.params[4].get_str () != "stat") throw JSONRPCError (RPC_INVALID_PARAMETER, "fifth argument must be the literal string 'stat'"); stats = true; } /* ******************************************* */ /* Iterate over names to build up the result. */ UniValue names(UniValue::VARR); unsigned count(0); LOCK (cs_main); valtype name; CNameData data; std::unique_ptr<CNameIterator> iter(pcoinsTip->IterateNames ()); while (iter->next (name, data)) { const int age = chainActive.Height () - data.getHeight (); assert (age >= 0); if (maxage != 0 && age >= maxage) continue; if (haveRegexp) { const std::string nameStr = ValtypeToString (name); boost::xpressive::smatch matches; if (!boost::xpressive::regex_search (nameStr, matches, regexp)) continue; } if (from > 0) { --from; continue; } assert (from == 0); if (stats) ++count; else names.push_back (getNameInfo (name, data)); if (nb > 0) { --nb; if (nb == 0) break; } } /* ********************************************************** */ /* Return the correct result (take stats mode into account). */ if (stats) { UniValue res(UniValue::VOBJ); res.push_back (Pair ("blocks", chainActive.Height ())); res.push_back (Pair ("count", static_cast<int> (count))); return res; } return names; }
void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) { if(IsInitialBlockDownload()) return; if (strCommand == "mnget") { //Masternode Payments Request Sync if(fLiteMode) return; //disable all Darksend/Masternode related functionality if(pfrom->HasFulfilledRequest("mnget")) { LogPrintf("mnget - peer already asked me for the list\n"); Misbehaving(pfrom->GetId(), 20); return; } pfrom->FulfilledRequest("mnget"); masternodePayments.Sync(pfrom); LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString().c_str()); } else if (strCommand == "mnw") { //Masternode Payments Declare Winner LOCK(cs_masternodepayments); //this is required in litemode CMasternodePaymentWinner winner; vRecv >> winner; if(chainActive.Tip() == NULL) return; CTxDestination address1; ExtractDestination(winner.payee, address1); CBitcoinAddress address2(address1); uint256 hash = winner.GetHash(); if(mapSeenMasternodeVotes.count(hash)) { if(fDebug) LogPrintf("mnw - seen vote %s Addr %s Height %d bestHeight %d\n", hash.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight); return; } if(winner.nBlockHeight < chainActive.Tip()->nHeight - 10 || winner.nBlockHeight > chainActive.Tip()->nHeight+20){ LogPrintf("mnw - winner out of range %s Addr %s Height %d bestHeight %d\n", winner.vin.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight); return; } if(winner.vin.nSequence != std::numeric_limits<unsigned int>::max()){ LogPrintf("mnw - invalid nSequence\n"); Misbehaving(pfrom->GetId(), 100); return; } LogPrintf("mnw - winning vote - Vin %s Addr %s Height %d bestHeight %d\n", winner.vin.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight); if(!masternodePayments.CheckSignature(winner)){ LogPrintf("mnw - invalid signature\n"); Misbehaving(pfrom->GetId(), 100); return; } mapSeenMasternodeVotes.insert(make_pair(hash, winner)); if(masternodePayments.AddWinningMasternode(winner)){ masternodePayments.Relay(winner); } }
// // Bootup the masternode, look for a 500 LDOGE input and register on the network // void CActiveMasternode::ManageStatus() { std::string errorMessage; if(!fMasterNode) return; if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n"); //need correct adjusted time to send ping bool fIsInitialDownload = IsInitialBlockDownload(); if(fIsInitialDownload) { status = MASTERNODE_SYNC_IN_PROCESS; LogPrintf("CActiveMasternode::ManageStatus() - Sync in progress. Must wait until sync is complete to start masternode.\n"); return; } if(status == MASTERNODE_INPUT_TOO_NEW || status == MASTERNODE_NOT_CAPABLE || status == MASTERNODE_SYNC_IN_PROCESS){ status = MASTERNODE_NOT_PROCESSED; } if(status == MASTERNODE_NOT_PROCESSED) { if(strMasterNodeAddr.empty()) { if(!GetLocal(service)) { notCapableReason = "Can't detect external address. Please use the masternodeaddr configuration option."; status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } } else { service = CService(strMasterNodeAddr); } LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString().c_str()); // LDOGENOTE: There is no logical reason to restrict this to a specific port. Its a peer, what difference does it make. /* if(service.GetPort() != 9999) { notCapableReason = "Invalid port: " + boost::lexical_cast<string>(service.GetPort()) + " -only 9999 is supported on mainnet."; status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } */ if(!ConnectNode((CAddress)service, service.ToString().c_str())){ notCapableReason = "Could not connect to " + service.ToString(); status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } if(pwalletMain->IsLocked()){ notCapableReason = "Wallet is locked."; status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } // Set defaults status = MASTERNODE_NOT_CAPABLE; notCapableReason = "Unknown. Check debug.log for more information.\n"; // Choose coins to use CPubKey pubKeyCollateralAddress; CKey keyCollateralAddress; if(GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress)) { if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ LogPrintf("CActiveMasternode::ManageStatus() - Input must have least %d confirmations - %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS, GetInputAge(vin)); status = MASTERNODE_INPUT_TOO_NEW; return; } LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n"); status = MASTERNODE_IS_CAPABLE; notCapableReason = ""; pwalletMain->LockCoin(vin.prevout); // send to all nodes CPubKey pubKeyMasternode; CKey keyMasternode; if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) { LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str()); return; } if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage)) { LogPrintf("CActiveMasternode::ManageStatus() - Error on Register: %s\n", errorMessage.c_str()); } return; } else { LogPrintf("CActiveMasternode::ManageStatus() - Could not find suitable coins!\n"); } } //send to all peers if(!Dseep(errorMessage)) { LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s", errorMessage.c_str()); } }
void CDSNotificationInterface::InitializeCurrentBlockTip() { LOCK(cs_main); UpdatedBlockTip(chainActive.Tip(), NULL, IsInitialBlockDownload()); }