// Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "main.h" #include "core.h" #include "db.h" #include "init.h" #include "activemasternode.h" #include "masternodeman.h" #include "masternodeconfig.h" #include "rpcserver.h" #include #include using namespace json_spirit; using namespace std; Value darksend(const Array& params, bool fHelp) { if (fHelp || params.size() == 0) throw runtime_error( "darksend \n" "dashaddress, reset, or auto (AutoDenominate)" " is a real and is rounded to the nearest 0.00000001" + HelpRequiringPassphrase()); if (pwalletMain->IsLocked()) throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); if(params[0].get_str() == "auto"){ if(fMasterNode) return "DarkSend is not supported from masternodes"; darkSendPool.DoAutomaticDenominating(); return "DoAutomaticDenominating"; } if(params[0].get_str() == "reset"){ darkSendPool.SetNull(true); darkSendPool.UnlockCoins(); return "successfully reset darksend"; } if (params.size() != 2) throw runtime_error( "darksend \n" "dashaddress, denominate, or auto (AutoDenominate)" " is a real and is rounded to the nearest 0.00000001" + HelpRequiringPassphrase()); CBitcoinAddress address(params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Dash address"); // Amount int64_t nAmount = AmountFromValue(params[1]); // Wallet comments CWalletTx wtx; string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx, ONLY_DENOMINATED); if (strError != "") throw JSONRPCError(RPC_WALLET_ERROR, strError); return wtx.GetHash().GetHex(); } Value getpoolinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( "getpoolinfo\n" "Returns an object containing anonymous pool-related information."); Object obj; obj.push_back(Pair("current_masternode", mnodeman.GetCurrentMasterNode()->addr.ToString())); obj.push_back(Pair("state", darkSendPool.GetState())); obj.push_back(Pair("entries", darkSendPool.GetEntriesCount())); obj.push_back(Pair("entries_accepted", darkSendPool.GetCountEntriesAccepted())); return obj; } Value masternode(const Array& params, bool fHelp) { string strCommand; if (params.size() >= 1) strCommand = params[0].get_str(); if (fHelp || (strCommand != "start" && strCommand != "start-alias" && strCommand != "start-many" && strCommand != "stop" && strCommand != "stop-alias" && strCommand != "stop-many" && strCommand != "list" && strCommand != "list-conf" && strCommand != "count" && strCommand != "enforce" && strCommand != "debug" && strCommand != "current" && strCommand != "winners" && strCommand != "genkey" && strCommand != "connect" && strCommand != "outputs" && strCommand != "vote-many" && strCommand != "vote")) throw runtime_error( "masternode \"command\"... ( \"passphrase\" )\n" "Set of commands to execute masternode related actions\n" "\nArguments:\n" "1. \"command\" (string or set of strings, required) The command to execute\n" "2. \"passphrase\" (string, optional) The wallet passphrase\n" "\nAvailable commands:\n" " count - Print number of all known masternodes (optional: 'enabled', 'both')\n" " current - Print info on current masternode winner\n" " debug - Print masternode status\n" " genkey - Generate new masternodeprivkey\n" " enforce - Enforce masternode payments\n" " outputs - Print masternode compatible outputs\n" " start - Start masternode configured in dash.conf\n" " start-alias - Start single masternode by assigned alias configured in masternode.conf\n" " start-many - Start all masternodes configured in masternode.conf\n" " stop - Stop masternode configured in dash.conf\n" " stop-alias - Stop single masternode by assigned alias configured in masternode.conf\n" " stop-many - Stop all masternodes configured in masternode.conf\n" " list - Print list of all known masternodes (see masternodelist for more info)\n" " list-conf - Print masternode.conf in JSON format\n" " winners - Print list of masternode winners\n" " vote-many - Vote on a Dash initiative\n" " vote - Vote on a Dash initiative\n" ); if (strCommand == "stop") { if(!fMasterNode) return "you must set masternode=1 in the configuration"; if(pwalletMain->IsLocked()) { SecureString strWalletPass; strWalletPass.reserve(100); if (params.size() == 2){ strWalletPass = params[1].get_str().c_str(); } else { throw runtime_error( "Your wallet is locked, passphrase is required\n"); } if(!pwalletMain->Unlock(strWalletPass)){ return "incorrect passphrase"; } } std::string errorMessage; if(!activeMasternode.StopMasterNode(errorMessage)) { return "stop failed: " + errorMessage; } pwalletMain->Lock(); if(activeMasternode.status == MASTERNODE_STOPPED) return "successfully stopped masternode"; if(activeMasternode.status == MASTERNODE_NOT_CAPABLE) return "not capable masternode"; return "unknown"; } if (strCommand == "stop-alias") { if (params.size() < 2){ throw runtime_error( "command needs at least 2 parameters\n"); } std::string alias = params[1].get_str().c_str(); if(pwalletMain->IsLocked()) { SecureString strWalletPass; strWalletPass.reserve(100); if (params.size() == 3){ strWalletPass = params[2].get_str().c_str(); } else { throw runtime_error( "Your wallet is locked, passphrase is required\n"); } if(!pwalletMain->Unlock(strWalletPass)){ return "incorrect passphrase"; } } bool found = false; Object statusObj; statusObj.push_back(Pair("alias", alias)); BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { if(mne.getAlias() == alias) { found = true; std::string errorMessage; bool result = activeMasternode.StopMasterNode(mne.getIp(), mne.getPrivKey(), errorMessage); statusObj.push_back(Pair("result", result ? "successful" : "failed")); if(!result) { statusObj.push_back(Pair("errorMessage", errorMessage)); } break; } } if(!found) { statusObj.push_back(Pair("result", "failed")); statusObj.push_back(Pair("errorMessage", "could not find alias in config. Verify with list-conf.")); } pwalletMain->Lock(); return statusObj; } if (strCommand == "stop-many") { if(pwalletMain->IsLocked()) { SecureString strWalletPass; strWalletPass.reserve(100); if (params.size() == 2){ strWalletPass = params[1].get_str().c_str(); } else { throw runtime_error( "Your wallet is locked, passphrase is required\n"); } if(!pwalletMain->Unlock(strWalletPass)){ return "incorrect passphrase"; } } int total = 0; int successful = 0; int fail = 0; Object resultsObj; BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { total++; std::string errorMessage; bool result = activeMasternode.StopMasterNode(mne.getIp(), mne.getPrivKey(), errorMessage); Object statusObj; statusObj.push_back(Pair("alias", mne.getAlias())); statusObj.push_back(Pair("result", result ? "successful" : "failed")); if(result) { successful++; } else { fail++; statusObj.push_back(Pair("errorMessage", errorMessage)); } resultsObj.push_back(Pair("status", statusObj)); } pwalletMain->Lock(); Object returnObj; returnObj.push_back(Pair("overall", "Successfully stopped " + boost::lexical_cast(successful) + " masternodes, failed to stop " + boost::lexical_cast(fail) + ", total " + boost::lexical_cast(total))); returnObj.push_back(Pair("detail", resultsObj)); return returnObj; } if (strCommand == "list") { Array newParams(params.size() - 1); std::copy(params.begin() + 1, params.end(), newParams.begin()); return masternodelist(newParams, fHelp); } if (strCommand == "count") { if (params.size() > 2){ throw runtime_error( "too many parameters\n"); } if (params.size() == 2) { if(params[1] == "enabled") return mnodeman.CountEnabled(); if(params[1] == "both") return boost::lexical_cast(mnodeman.CountEnabled()) + " / " + boost::lexical_cast(mnodeman.size()); } return mnodeman.size(); } if (strCommand == "start") { if(!fMasterNode) return "you must set masternode=1 in the configuration"; if(pwalletMain->IsLocked()) { SecureString strWalletPass; strWalletPass.reserve(100); if (params.size() == 2){ strWalletPass = params[1].get_str().c_str(); } else { throw runtime_error( "Your wallet is locked, passphrase is required\n"); } if(!pwalletMain->Unlock(strWalletPass)){ return "incorrect passphrase"; } } if(activeMasternode.status != MASTERNODE_REMOTELY_ENABLED && activeMasternode.status != MASTERNODE_IS_CAPABLE){ activeMasternode.status = MASTERNODE_NOT_PROCESSED; // TODO: consider better way std::string errorMessage; activeMasternode.ManageStatus(); pwalletMain->Lock(); } if(activeMasternode.status == MASTERNODE_REMOTELY_ENABLED) return "masternode started remotely"; if(activeMasternode.status == MASTERNODE_INPUT_TOO_NEW) return "masternode input must have at least 15 confirmations"; if(activeMasternode.status == MASTERNODE_STOPPED) return "masternode is stopped"; if(activeMasternode.status == MASTERNODE_IS_CAPABLE) return "successfully started masternode"; if(activeMasternode.status == MASTERNODE_NOT_CAPABLE) return "not capable masternode: " + activeMasternode.notCapableReason; if(activeMasternode.status == MASTERNODE_SYNC_IN_PROCESS) return "sync in process. Must wait until client is synced to start."; return "unknown"; } if (strCommand == "start-alias") { if (params.size() < 2){ throw runtime_error( "command needs at least 2 parameters\n"); } std::string alias = params[1].get_str().c_str(); if(pwalletMain->IsLocked()) { SecureString strWalletPass; strWalletPass.reserve(100); if (params.size() == 3){ strWalletPass = params[2].get_str().c_str(); } else { throw runtime_error( "Your wallet is locked, passphrase is required\n"); } if(!pwalletMain->Unlock(strWalletPass)){ return "incorrect passphrase"; } } bool found = false; Object statusObj; statusObj.push_back(Pair("alias", alias)); BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { if(mne.getAlias() == alias) { found = true; std::string errorMessage; std::string strDonateAddress = mne.getDonationAddress(); std::string strDonationPercentage = mne.getDonationPercentage(); bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strDonateAddress, strDonationPercentage, errorMessage); statusObj.push_back(Pair("result", result ? "successful" : "failed")); if(!result) { statusObj.push_back(Pair("errorMessage", errorMessage)); } break; } } if(!found) { statusObj.push_back(Pair("result", "failed")); statusObj.push_back(Pair("errorMessage", "could not find alias in config. Verify with list-conf.")); } pwalletMain->Lock(); return statusObj; } if (strCommand == "start-many") { if(pwalletMain->IsLocked()) { SecureString strWalletPass; strWalletPass.reserve(100); if (params.size() == 2){ strWalletPass = params[1].get_str().c_str(); } else { throw runtime_error( "Your wallet is locked, passphrase is required\n"); } if(!pwalletMain->Unlock(strWalletPass)){ return "incorrect passphrase"; } } std::vector mnEntries; mnEntries = masternodeConfig.getEntries(); int total = 0; int successful = 0; int fail = 0; Object resultsObj; BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { total++; std::string errorMessage; std::string strDonateAddress = mne.getDonationAddress(); std::string strDonationPercentage = mne.getDonationPercentage(); bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strDonateAddress, strDonationPercentage, errorMessage); Object statusObj; statusObj.push_back(Pair("alias", mne.getAlias())); statusObj.push_back(Pair("result", result ? "successful" : "failed")); if(result) { successful++; } else { fail++; statusObj.push_back(Pair("errorMessage", errorMessage)); } resultsObj.push_back(Pair("status", statusObj)); } pwalletMain->Lock(); Object returnObj; returnObj.push_back(Pair("overall", "Successfully started " + boost::lexical_cast(successful) + " masternodes, failed to start " + boost::lexical_cast(fail) + ", total " + boost::lexical_cast(total))); returnObj.push_back(Pair("detail", resultsObj)); return returnObj; } if (strCommand == "debug") { if(activeMasternode.status == MASTERNODE_REMOTELY_ENABLED) return "masternode started remotely"; if(activeMasternode.status == MASTERNODE_INPUT_TOO_NEW) return "masternode input must have at least 15 confirmations"; if(activeMasternode.status == MASTERNODE_IS_CAPABLE) return "successfully started masternode"; if(activeMasternode.status == MASTERNODE_STOPPED) return "masternode is stopped"; if(activeMasternode.status == MASTERNODE_NOT_CAPABLE) return "not capable masternode: " + activeMasternode.notCapableReason; if(activeMasternode.status == MASTERNODE_SYNC_IN_PROCESS) return "sync in process. Must wait until client is synced to start."; CTxIn vin = CTxIn(); CPubKey pubkey = CScript(); CKey key; bool found = activeMasternode.GetMasterNodeVin(vin, pubkey, key); if(!found){ return "Missing masternode input, please look at the documentation for instructions on masternode creation"; } else { return "No problems were found"; } } if (strCommand == "create") { return "Not implemented yet, please look at the documentation for instructions on masternode creation"; } if (strCommand == "current") { CMasternode* winner = mnodeman.GetCurrentMasterNode(1); if(winner) { Object obj; CScript pubkey; pubkey.SetDestination(winner->pubkey.GetID()); CTxDestination address1; ExtractDestination(pubkey, address1); CBitcoinAddress address2(address1); obj.push_back(Pair("IP:port", winner->addr.ToString().c_str())); obj.push_back(Pair("protocol", (int64_t)winner->protocolVersion)); obj.push_back(Pair("vin", winner->vin.prevout.hash.ToString().c_str())); obj.push_back(Pair("pubkey", address2.ToString().c_str())); obj.push_back(Pair("lastseen", (int64_t)winner->lastTimeSeen)); obj.push_back(Pair("activeseconds", (int64_t)(winner->lastTimeSeen - winner->sigTime))); return obj; } return "unknown"; } if (strCommand == "genkey") { CKey secret; secret.MakeNewKey(false); return CBitcoinSecret(secret).ToString(); } if (strCommand == "winners") { Object obj; for(int nHeight = chainActive.Tip()->nHeight-10; nHeight < chainActive.Tip()->nHeight+20; nHeight++) { CScript payee; if(masternodePayments.GetBlockPayee(nHeight, payee)){ CTxDestination address1; ExtractDestination(payee, address1); CBitcoinAddress address2(address1); obj.push_back(Pair(boost::lexical_cast(nHeight), address2.ToString().c_str())); } else { obj.push_back(Pair(boost::lexical_cast(nHeight), "")); } } return obj; } if(strCommand == "enforce") { return (uint64_t)enforceMasternodePaymentsTime; } if(strCommand == "connect") { std::string strAddress = ""; if (params.size() == 2){ strAddress = params[1].get_str().c_str(); } else { throw runtime_error( "Masternode address required\n"); } CService addr = CService(strAddress); if(ConnectNode((CAddress)addr, NULL, true)){ return "successfully connected"; } else { return "error connecting"; } } if(strCommand == "list-conf") { std::vector mnEntries; mnEntries = masternodeConfig.getEntries(); Object resultObj; BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { Object mnObj; mnObj.push_back(Pair("alias", mne.getAlias())); mnObj.push_back(Pair("address", mne.getIp())); mnObj.push_back(Pair("privateKey", mne.getPrivKey())); mnObj.push_back(Pair("txHash", mne.getTxHash())); mnObj.push_back(Pair("outputIndex", mne.getOutputIndex())); mnObj.push_back(Pair("donationAddress", mne.getDonationAddress())); mnObj.push_back(Pair("donationPercent", mne.getDonationPercentage())); resultObj.push_back(Pair("masternode", mnObj)); } return resultObj; } if (strCommand == "outputs"){ // Find possible candidates vector possibleCoins = activeMasternode.SelectCoinsMasternode(); Object obj; BOOST_FOREACH(COutput& out, possibleCoins) { obj.push_back(Pair(out.tx->GetHash().ToString().c_str(), boost::lexical_cast(out.i))); } return obj; } if(strCommand == "vote-many") { std::vector mnEntries; mnEntries = masternodeConfig.getEntries(); if (params.size() != 2) throw runtime_error("You can only vote 'yea' or 'nay'"); std::string vote = params[1].get_str().c_str(); if(vote != "yea" && vote != "nay") return "You can only vote 'yea' or 'nay'"; int nVote = 0; if(vote == "yea") nVote = 1; if(vote == "nay") nVote = -1; int success = 0; int failed = 0; Object resultObj; BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { std::string errorMessage; std::vector vchMasterNodeSignature; std::string strMasterNodeSignMessage; CTxIn vin; CPubKey pubKeyCollateralAddress; CKey keyCollateralAddress; CPubKey pubKeyMasternode; CKey keyMasternode; if(!darkSendSigner.SetKey(mne.getPrivKey(), errorMessage, keyMasternode, pubKeyMasternode)){ printf(" Error upon calling SetKey for %s\n", mne.getAlias().c_str()); failed++; continue; } CMasternode* pmn = mnodeman.Find(pubKeyMasternode); if(pmn == NULL) { printf("Can't find masternode by pubkey for %s\n", mne.getAlias().c_str()); failed++; continue; } std::string strMessage = pmn->vin.ToString() + boost::lexical_cast(nVote); if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyMasternode)){ printf(" Error upon calling SignMessage for %s\n", mne.getAlias().c_str()); failed++; continue; } if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchMasterNodeSignature, strMessage, errorMessage)){ printf(" Error upon calling VerifyMessage for %s\n", mne.getAlias().c_str()); failed++; continue; } success++; //send to all peers LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) pnode->PushMessage("mvote", vin, vchMasterNodeSignature, nVote); } return("Voted successfully " + boost::lexical_cast(success) + " time(s) and failed " + boost::lexical_cast(failed) + " time(s)."); } if(strCommand == "vote") { std::vector mnEntries; mnEntries = masternodeConfig.getEntries(); if (params.size() != 2) throw runtime_error("You can only vote 'yea' or 'nay'"); std::string vote = params[1].get_str().c_str(); if(vote != "yea" && vote != "nay") return "You can only vote 'yea' or 'nay'"; int nVote = 0; if(vote == "yea") nVote = 1; if(vote == "nay") nVote = -1; // Choose coins to use CPubKey pubKeyCollateralAddress; CKey keyCollateralAddress; CPubKey pubKeyMasternode; CKey keyMasternode; std::string errorMessage; std::vector vchMasterNodeSignature; std::string strMessage = activeMasternode.vin.ToString() + boost::lexical_cast(nVote); if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) return(" Error upon calling SetKey"); if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyMasternode)) return(" Error upon calling SignMessage"); if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchMasterNodeSignature, strMessage, errorMessage)) return(" Error upon calling VerifyMessage"); //send to all peers LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) pnode->PushMessage("mvote", activeMasternode.vin, vchMasterNodeSignature, nVote); } return Value::null; } Value masternodelist(const Array& params, bool fHelp) { std::string strMode = "status"; std::string strFilter = ""; if (params.size() >= 1) strMode = params[0].get_str(); if (params.size() == 2) strFilter = params[1].get_str(); if (fHelp || (strMode != "status" && strMode != "vin" && strMode != "pubkey" && strMode != "lastseen" && strMode != "activeseconds" && strMode != "rank" && strMode != "protocol" && strMode != "full" && strMode != "votes" && strMode != "donation" && strMode != "pose")) { throw runtime_error( "masternodelist ( \"mode\" \"filter\" )\n" "Get a list of masternodes in different modes\n" "\nArguments:\n" "1. \"mode\" (string, optional/required to use filter, defaults = status) The mode to run list in\n" "2. \"filter\" (string, optional) Filter results. Partial match by IP by default in all modes, additional matches in some modes\n" "\nAvailable modes:\n" " activeseconds - Print number of seconds masternode recognized by the network as enabled\n" " donation - Show donation settings\n" " full - Print info in format 'status protocol pubkey vin lastseen activeseconds' (can be additionally filtered, partial match)\n" " lastseen - Print timestamp of when a masternode was last seen on the network\n" " pose - Print Proof-of-Service score\n" " protocol - Print protocol of a masternode (can be additionally filtered, exact match))\n" " pubkey - Print public key associated with a masternode (can be additionally filtered, partial match)\n" " rank - Print rank of a masternode based on current block\n" " status - Print masternode status: ENABLED / EXPIRED / VIN_SPENT / REMOVE / POS_ERROR (can be additionally filtered, partial match)\n" " vin - Print vin associated with a masternode (can be additionally filtered, partial match)\n" " votes - Print all masternode votes for a Dash initiative (can be additionally filtered, partial match)\n" ); } Object obj; if (strMode == "rank") { std::vector > vMasternodeRanks = mnodeman.GetMasternodeRanks(chainActive.Tip()->nHeight); BOOST_FOREACH(PAIRTYPE(int, CMasternode)& s, vMasternodeRanks) { std::string strAddr = s.second.addr.ToString(); if(strFilter !="" && strAddr.find(strFilter) == string::npos) continue; obj.push_back(Pair(strAddr, s.first)); } } else { std::vector vMasternodes = mnodeman.GetFullMasternodeVector(); BOOST_FOREACH(CMasternode& mn, vMasternodes) { std::string strAddr = mn.addr.ToString(); if (strMode == "activeseconds") { if(strFilter !="" && strAddr.find(strFilter) == string::npos) continue; obj.push_back(Pair(strAddr, (int64_t)(mn.lastTimeSeen - mn.sigTime))); } else if (strMode == "donation") { CTxDestination address1; ExtractDestination(mn.donationAddress, address1); CBitcoinAddress address2(address1); if(strFilter !="" && address2.ToString().find(strFilter) == string::npos && strAddr.find(strFilter) == string::npos) continue; std::string strOut = ""; if(mn.donationPercentage != 0){ strOut = address2.ToString().c_str(); strOut += ":"; strOut += boost::lexical_cast(mn.donationPercentage); } obj.push_back(Pair(strAddr, strOut.c_str())); } else if (strMode == "full") { CScript pubkey; pubkey.SetDestination(mn.pubkey.GetID()); CTxDestination address1; ExtractDestination(pubkey, address1); CBitcoinAddress address2(address1); std::ostringstream addrStream; addrStream << setw(21) << strAddr; std::ostringstream stringStream; stringStream << setw(10) << mn.Status() << " " << mn.protocolVersion << " " << address2.ToString() << " " << mn.vin.prevout.hash.ToString() << " " << mn.lastTimeSeen << " " << setw(8) << (mn.lastTimeSeen - mn.sigTime); std::string output = stringStream.str(); stringStream << " " << strAddr; if(strFilter !="" && stringStream.str().find(strFilter) == string::npos && strAddr.find(strFilter) == string::npos) continue; obj.push_back(Pair(addrStream.str(), output)); } else if (strMode == "lastseen") { if(strFilter !="" && strAddr.find(strFilter) == string::npos) continue; obj.push_back(Pair(strAddr, (int64_t)mn.lastTimeSeen)); } else if (strMode == "protocol") { if(strFilter !="" && strFilter != boost::lexical_cast(mn.protocolVersion) && strAddr.find(strFilter) == string::npos) continue; obj.push_back(Pair(strAddr, (int64_t)mn.protocolVersion)); } else if (strMode == "pubkey") { CScript pubkey; pubkey.SetDestination(mn.pubkey.GetID()); CTxDestination address1; ExtractDestination(pubkey, address1); CBitcoinAddress address2(address1); if(strFilter !="" && address2.ToString().find(strFilter) == string::npos && strAddr.find(strFilter) == string::npos) continue; obj.push_back(Pair(strAddr, address2.ToString().c_str())); } else if (strMode == "pose") { if(strFilter !="" && strAddr.find(strFilter) == string::npos) continue; std::string strOut = boost::lexical_cast(mn.nScanningErrorCount); obj.push_back(Pair(strAddr, strOut.c_str())); } else if(strMode == "status") { std::string strStatus = mn.Status(); if(strFilter !="" && strAddr.find(strFilter) == string::npos && strStatus.find(strFilter) == string::npos) continue; obj.push_back(Pair(strAddr, strStatus.c_str())); } else if (strMode == "vin") { if(strFilter !="" && mn.vin.prevout.hash.ToString().find(strFilter) == string::npos && strAddr.find(strFilter) == string::npos) continue; obj.push_back(Pair(strAddr, mn.vin.prevout.hash.ToString().c_str())); } else if(strMode == "votes"){ std::string strStatus = "ABSTAIN"; //voting lasts 7 days, ignore the last vote if it was older than that if((GetAdjustedTime() - mn.lastVote) < (60*60*8)) { if(mn.nVote == -1) strStatus = "NAY"; if(mn.nVote == 1) strStatus = "YEA"; } if(strFilter !="" && (strAddr.find(strFilter) == string::npos && strStatus.find(strFilter) == string::npos)) continue; obj.push_back(Pair(strAddr, strStatus.c_str())); } } } return obj; }