Cleanup/maintenance (#830)

* remove instance references inside own class

* better logging

* remove unused

* fix tabs/spaces

* bitcoin->dash

* fix README.md
This commit is contained in:
UdjinM6 2016-05-30 10:22:30 +04:00 committed by Holger Schinzel
parent f5e3042b7a
commit 4d55bc9666
14 changed files with 41 additions and 1394 deletions

View File

@ -1,6 +1,8 @@
Dash Core staging tree 0.12
Dash Core staging tree 0.12.1
===============================
`master:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=master)](https://travis-ci.org/dashpay/dash) `v0.12.0.x:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=v0.12.0.x)](https://travis-ci.org/dashpay/dash/branches) `v0.12.1.x:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=v0.12.1.x)](https://travis-ci.org/dashpay/dash/branches)
https://www.dash.org
@ -72,4 +74,4 @@ Translations are periodically pulled from Transifex and merged into the git repo
**Important**: We do not accept translation changes as GitHub pull requests because the next
pull from Transifex would automatically overwrite them again.
Translators should also follow the [forum](https://dashtalk.org/forums/dash-worldwide-collaboration.88/).
Translators should also follow the [forum](https://www.dash.org/forum/topic/dash-worldwide-collaboration.88/).

View File

@ -385,7 +385,7 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
return;
}
darkSendPool.CompletedTransaction(error, errorID);
CompletedTransaction(error, errorID);
}
}
@ -1445,6 +1445,14 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
if(nBalanceNeedsDenominated > nValueIn) nBalanceNeedsDenominated = nValueIn;
LogPrint("privatesend", "%s -- SelectCoinsDark -- (%f - (%f + %f - %f = %f) ) = %f\n", __func__,
(float)nBalanceNeedsAnonymized/COIN,
(float)pwalletMain->GetDenominatedBalance(true)/COIN,
(float)pwalletMain->GetDenominatedBalance()/COIN,
(float)pwalletMain->GetAnonymizedBalance()/COIN,
(float)nOnlyDenominatedBalance/COIN,
(float)nBalanceNeedsDenominated/COIN);
if(nBalanceNeedsDenominated < nLowestDenom) return false; // most likely we just waiting for denoms to confirm
if(!fDryRun) return CreateDenominated(nBalanceNeedsDenominated);
@ -1461,6 +1469,13 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
nOnlyDenominatedBalance = pwalletMain->GetDenominatedBalance(true) + pwalletMain->GetDenominatedBalance() - pwalletMain->GetAnonymizedBalance();
nBalanceNeedsDenominated = nBalanceNeedsAnonymized - nOnlyDenominatedBalance;
LogPrint("privatesend", "%s -- 'nBalanceNeedsDenominated > nOnlyDenominatedBalance' (%f - (%f + %f - %f = %f) ) = %f\n", __func__,
(float)nBalanceNeedsAnonymized/COIN,
(float)pwalletMain->GetDenominatedBalance(true)/COIN,
(float)pwalletMain->GetDenominatedBalance()/COIN,
(float)pwalletMain->GetAnonymizedBalance()/COIN,
(float)nOnlyDenominatedBalance/COIN,
(float)nBalanceNeedsDenominated/COIN);
//check if we have should create more denominated inputs
if(nBalanceNeedsDenominated > nOnlyDenominatedBalance) return CreateDenominated(nBalanceNeedsDenominated);

View File

@ -191,8 +191,6 @@ void Interrupt(boost::thread_group& threadGroup)
/** Preparing steps before shutting down or restarting the wallet */
void PrepareShutdown()
{
LogPrintf("1 %s\n", governance.ToString());
fRequestShutdown = true; // Needed when we shutdown the wallet
fRestartRequested = true; // Needed when we restart the wallet
LogPrintf("%s: In progress...\n", __func__);
@ -201,8 +199,6 @@ void PrepareShutdown()
if (!lockShutdown)
return;
LogPrintf("2 %s\n", governance.ToString());
/// Note: Shutdown() must be able to handle cases in which AppInit2() failed part of the way,
/// for example if the data directory was found to be locked.
/// Be sure that anything that writes files or flushes caches only does this if the respective

View File

@ -1450,17 +1450,17 @@ int64_t GetTotalCoinEstimate(int nHeight)
/* these values are taken from the block explorer */
if(nHeight > 5076) nTotalCoins += 2021642;
if(nHeight > 17000) nTotalCoins += 3267692-2021642;
if(nHeight > 34000) nTotalCoins += 3688775-3267692;
if(nHeight > 68000) nTotalCoins += 4277615-3688775;
if(nHeight > 34000) nTotalCoins += 3688775-3267692;
if(nHeight > 68000) nTotalCoins += 4277615-3688775;
if(nHeight > 68000*2) {
nTotalCoins += 4649913.99999995-4277615;
nTotalCoins += 4649913.99999995-4277615;
} else {
return nTotalCoins;
}
//5.383754730451325 per block average after this
nTotalCoins += ((nHeight-68000*2)*((5382104.64334133-4649913.99999995)/(68000*2)));
nTotalCoins += ((nHeight-68000*2)*((5382104.64334133-4649913.99999995)/(68000*2)));
// TODO: this should include the 7.1% decline too
return nTotalCoins;
@ -4565,7 +4565,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
}
}
if (!pushed && inv.type == MSG_DSTX) {
if (!pushed && inv.type == MSG_DSTX) {
if(mapDarksendBroadcastTxes.count(inv.hash)){
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);

File diff suppressed because it is too large Load Diff

View File

@ -21,167 +21,6 @@ CCriticalSection cs_vecPayments;
CCriticalSection cs_mapMasternodeBlocks;
CCriticalSection cs_mapMasternodePayeeVotes;
//
// CMasternodePaymentDB
//
CMasternodePaymentDB::CMasternodePaymentDB()
{
pathDB = GetDataDir() / "mnpayments.dat";
strMagicMessage = "MasternodePayments";
}
bool CMasternodePaymentDB::Write(const CMasternodePayments& objToSave)
{
int64_t nStart = GetTimeMillis();
// serialize, checksum data up to that point, then append checksum
CDataStream ssObj(SER_DISK, CLIENT_VERSION);
ssObj << strMagicMessage; // masternode cache file specific magic message
ssObj << FLATDATA(Params().MessageStart()); // network specific magic number
ssObj << objToSave;
uint256 hash = Hash(ssObj.begin(), ssObj.end());
ssObj << hash;
// open output file, and associate with CAutoFile
FILE *file = fopen(pathDB.string().c_str(), "wb");
CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
return error("%s : Failed to open file %s", __func__, pathDB.string());
// Write and commit header, data
try {
fileout << ssObj;
}
catch (std::exception &e) {
return error("%s : Serialize or I/O error - %s", __func__, e.what());
}
fileout.fclose();
LogPrintf("Written info to mnpayments.dat %dms\n", GetTimeMillis() - nStart);
return true;
}
CMasternodePaymentDB::ReadResult CMasternodePaymentDB::Read(CMasternodePayments& objToLoad, bool fDryRun)
{
int64_t nStart = GetTimeMillis();
// open input file, and associate with CAutoFile
FILE *file = fopen(pathDB.string().c_str(), "rb");
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
{
error("%s : Failed to open file %s", __func__, pathDB.string());
return FileError;
}
// use file size to size memory buffer
int fileSize = boost::filesystem::file_size(pathDB);
int dataSize = fileSize - sizeof(uint256);
// Don't try to resize to a negative number if file is small
if (dataSize < 0)
dataSize = 0;
vector<unsigned char> vchData;
vchData.resize(dataSize);
uint256 hashIn;
// read data and checksum from file
try {
filein.read((char *)&vchData[0], dataSize);
filein >> hashIn;
}
catch (std::exception &e) {
error("%s : Deserialize or I/O error - %s", __func__, e.what());
return HashReadError;
}
filein.fclose();
CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION);
// verify stored checksum matches input data
uint256 hashTmp = Hash(ssObj.begin(), ssObj.end());
if (hashIn != hashTmp)
{
error("%s : Checksum mismatch, data corrupted", __func__);
return IncorrectHash;
}
unsigned char pchMsgTmp[4];
std::string strMagicMessageTmp;
try {
// de-serialize file header (masternode cache file specific magic message) and ..
ssObj >> strMagicMessageTmp;
// ... verify the message matches predefined one
if (strMagicMessage != strMagicMessageTmp)
{
error("%s : Invalid masternode payement cache magic message", __func__);
return IncorrectMagicMessage;
}
// de-serialize file header (network specific magic number) and ..
ssObj >> FLATDATA(pchMsgTmp);
// ... verify the network matches ours
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
{
error("%s : Invalid network magic number", __func__);
return IncorrectMagicNumber;
}
// de-serialize data into CMasternodePayments object
ssObj >> objToLoad;
}
catch (std::exception &e) {
objToLoad.Clear();
error("%s : Deserialize or I/O error - %s", __func__, e.what());
return IncorrectFormat;
}
LogPrintf("Loaded info from mnpayments.dat %dms\n", GetTimeMillis() - nStart);
LogPrintf(" %s\n", objToLoad.ToString());
if(!fDryRun) {
LogPrintf("Masternode payments manager - cleaning....\n");
objToLoad.CheckAndRemove();
LogPrintf("Masternode payments manager - result:\n");
LogPrintf(" %s\n", objToLoad.ToString());
}
return Ok;
}
void DumpMasternodePayments()
{
int64_t nStart = GetTimeMillis();
CMasternodePaymentDB paymentdb;
CMasternodePayments tempPayments;
LogPrintf("Verifying mnpayments.dat format...\n");
CMasternodePaymentDB::ReadResult readResult = paymentdb.Read(tempPayments, true);
// there was an error and it was not an error on file opening => do not proceed
if (readResult == CMasternodePaymentDB::FileError)
LogPrintf("Missing budgets file - mnpayments.dat, will try to recreate\n");
else if (readResult != CMasternodePaymentDB::Ok)
{
LogPrintf("Error reading mnpayments.dat: ");
if(readResult == CMasternodePaymentDB::IncorrectFormat)
LogPrintf("magic is ok but data has invalid format, will try to recreate\n");
else
{
LogPrintf("file format is unknown or invalid, please fix it manually\n");
return;
}
}
LogPrintf("Writting info to mnpayments.dat...\n");
paymentdb.Write(mnpayments);
LogPrintf("Budget dump finished %dms\n", GetTimeMillis() - nStart);
}
bool IsBlockValueValid(const CBlock& block, CAmount nExpectedValue){
int nHeight = 0;
@ -369,7 +208,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
}
pfrom->FulfilledRequest(NetMsgType::MNWINNERSSYNC);
mnpayments.Sync(pfrom, nCountNeeded);
Sync(pfrom, nCountNeeded);
LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString());
}
else if (strCommand == NetMsgType::MNWINNER) { //Masternode Payments Declare Winner
@ -381,7 +220,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
if(!pCurrentBlockIndex) return;
if(mnpayments.mapMasternodePayeeVotes.count(winner.GetHash())){
if(mapMasternodePayeeVotes.count(winner.GetHash())){
LogPrint("mnpayments", "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString(), pCurrentBlockIndex->nHeight);
masternodeSync.AddedMasternodeWinner(winner.GetHash());
return;
@ -399,7 +238,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
return;
}
if(!mnpayments.CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)){
if(!CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)){
LogPrintf("mnw - masternode already voted - %s\n", winner.vinMasternode.prevout.ToStringShort());
return;
}
@ -418,7 +257,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString(), winner.nBlockHeight, pCurrentBlockIndex->nHeight, winner.vinMasternode.prevout.ToStringShort());
if(mnpayments.AddWinningMasternode(winner)){
if(AddWinningMasternode(winner)){
winner.Relay();
masternodeSync.AddedMasternodeWinner(winner.GetHash());
}
@ -622,6 +461,7 @@ void CMasternodePayments::CheckAndRemove()
++it;
}
}
LogPrintf("CMasternodePayments::CleanPaymentList() - %s mapSeenSyncMNW %lld\n", ToString(), masternodeSync.mapSeenSyncMNW.size());
}
bool CMasternodePaymentWinner::IsValid(CNode* pnode, std::string& strError)

View File

@ -36,31 +36,6 @@ std::string GetRequiredPaymentsString(int nBlockHeight);
bool IsBlockValueValid(const CBlock& block, CAmount nExpectedValue);
void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees);
void DumpMasternodePayments();
/** Save Masternode Payment Data (mnpayments.dat)
*/
class CMasternodePaymentDB
{
private:
boost::filesystem::path pathDB;
std::string strMagicMessage;
public:
enum ReadResult {
Ok,
FileError,
HashReadError,
IncorrectHash,
IncorrectMagicMessage,
IncorrectMagicNumber,
IncorrectFormat
};
CMasternodePaymentDB();
bool Write(const CMasternodePayments &objToSave);
ReadResult Read(CMasternodePayments& objToLoad, bool fDryRun = false);
};
class CMasternodePayee
{
public:

View File

@ -128,7 +128,7 @@ CMasternode::CMasternode(const CMasternodeBroadcast& mnb)
//
bool CMasternode::UpdateFromNewBroadcast(CMasternodeBroadcast& mnb)
{
if(mnb.sigTime > sigTime) {
if(mnb.sigTime > sigTime) {
pubkey2 = mnb.pubkey2;
sigTime = mnb.sigTime;
vchSig = mnb.vchSig;
@ -679,7 +679,7 @@ bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled, bool fChec
return true;
}
LogPrint("masternode", "CMasternodePing::CheckAndUpdate - New Ping - %s - %s - %lli\n", GetHash().ToString(), blockHash.ToString(), sigTime);
LogPrint("masternode", "CMasternodePing::CheckAndUpdate - New Ping %s - %s %s %d\n", vin.ToString(), GetHash().ToString(), blockHash.ToString(), sigTime);
// see if we have this Masternode
CMasternode* pmn = mnodeman.Find(vin);

View File

@ -44,137 +44,6 @@ struct CompareScoreMN
}
};
//
// CMasternodeDB
//
CMasternodeDB::CMasternodeDB()
{
pathMN = GetDataDir() / "mncache.dat";
strMagicMessage = "MasternodeCache";
}
bool CMasternodeDB::Write(const CMasternodeMan& mnodemanToSave)
{
int64_t nStart = GetTimeMillis();
// serialize, checksum data up to that point, then append checksum
CDataStream ssMasternodes(SER_DISK, CLIENT_VERSION);
ssMasternodes << strMagicMessage; // masternode cache file specific magic message
ssMasternodes << FLATDATA(Params().MessageStart()); // network specific magic number
ssMasternodes << mnodemanToSave;
uint256 hash = Hash(ssMasternodes.begin(), ssMasternodes.end());
ssMasternodes << hash;
// open output file, and associate with CAutoFile
FILE *file = fopen(pathMN.string().c_str(), "wb");
CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
return error("%s : Failed to open file %s", __func__, pathMN.string());
// Write and commit header, data
try {
fileout << ssMasternodes;
}
catch (std::exception &e) {
return error("%s : Serialize or I/O error - %s", __func__, e.what());
}
// FileCommit(fileout);
fileout.fclose();
LogPrintf("Written info to mncache.dat %dms\n", GetTimeMillis() - nStart);
LogPrintf(" %s\n", mnodemanToSave.ToString());
return true;
}
CMasternodeDB::ReadResult CMasternodeDB::Read(CMasternodeMan& mnodemanToLoad, bool fDryRun)
{
int64_t nStart = GetTimeMillis();
// open input file, and associate with CAutoFile
FILE *file = fopen(pathMN.string().c_str(), "rb");
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
{
error("%s : Failed to open file %s", __func__, pathMN.string());
return FileError;
}
// use file size to size memory buffer
int fileSize = boost::filesystem::file_size(pathMN);
int dataSize = fileSize - sizeof(uint256);
// Don't try to resize to a negative number if file is small
if (dataSize < 0)
dataSize = 0;
vector<unsigned char> vchData;
vchData.resize(dataSize);
uint256 hashIn;
// read data and checksum from file
try {
filein.read((char *)&vchData[0], dataSize);
filein >> hashIn;
}
catch (std::exception &e) {
error("%s : Deserialize or I/O error - %s", __func__, e.what());
return HashReadError;
}
filein.fclose();
CDataStream ssMasternodes(vchData, SER_DISK, CLIENT_VERSION);
// verify stored checksum matches input data
uint256 hashTmp = Hash(ssMasternodes.begin(), ssMasternodes.end());
if (hashIn != hashTmp)
{
error("%s : Checksum mismatch, data corrupted", __func__);
return IncorrectHash;
}
unsigned char pchMsgTmp[4];
std::string strMagicMessageTmp;
try {
// de-serialize file header (masternode cache file specific magic message) and ..
ssMasternodes >> strMagicMessageTmp;
// ... verify the message matches predefined one
if (strMagicMessage != strMagicMessageTmp)
{
error("%s : Invalid masternode cache magic message", __func__);
return IncorrectMagicMessage;
}
// de-serialize file header (network specific magic number) and ..
ssMasternodes >> FLATDATA(pchMsgTmp);
// ... verify the network matches ours
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
{
error("%s : Invalid network magic number", __func__);
return IncorrectMagicNumber;
}
// de-serialize data into CMasternodeMan object
ssMasternodes >> mnodemanToLoad;
}
catch (std::exception &e) {
mnodemanToLoad.Clear();
error("%s : Deserialize or I/O error - %s", __func__, e.what());
return IncorrectFormat;
}
LogPrintf("Loaded info from mncache.dat %dms\n", GetTimeMillis() - nStart);
LogPrintf(" %s\n", mnodemanToLoad.ToString());
if(!fDryRun) {
LogPrintf("Masternode manager - cleaning....\n");
mnodemanToLoad.CheckAndRemove(true);
LogPrintf("Masternode manager - result:\n");
LogPrintf(" %s\n", mnodemanToLoad.ToString());
}
return Ok;
}
CMasternodeMan::CMasternodeMan() {
nDsqCount = 0;
}
@ -225,6 +94,8 @@ void CMasternodeMan::Check()
void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval)
{
LogPrintf("CMasternodeMan::CheckAndRemove\n");
Check();
LOCK(cs);
@ -235,7 +106,7 @@ void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval)
if((*it).activeState == CMasternode::MASTERNODE_REMOVE ||
(*it).activeState == CMasternode::MASTERNODE_VIN_SPENT ||
(forceExpiredRemoval && (*it).activeState == CMasternode::MASTERNODE_EXPIRED)) {
LogPrint("masternode", "CMasternodeMan::CheckAndRemove - Removing inactive Masternode %s - %i now\n", (*it).addr.ToString(), size() - 1);
LogPrint("masternode", "CMasternodeMan::CheckAndRemove - Removing %s Masternode %s - %i now\n", (*it).Status(), (*it).addr.ToString(), size() - 1);
//erase all of the broadcasts we've seen from this vin
// -- if we missed a few pings and the node was removed, this will allow is to get it back without them
@ -746,8 +617,8 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
if(mn.addr.IsRFC1918() || mn.addr.IsLocal()) continue; //local network
if(mn.IsEnabled()) {
LogPrint("masternode", "dseg - Sending Masternode entry - %s \n", mn.addr.ToString());
if(vin == CTxIn() || vin == mn.vin){
LogPrint("masternode", "dseg - Sending Masternode entry - %s \n", mn.addr.ToString());
CMasternodeBroadcast mnb = CMasternodeBroadcast(mn);
uint256 hash = mnb.GetHash();
pfrom->PushInventory(CInv(MSG_MASTERNODE_ANNOUNCE, hash));

View File

@ -21,29 +21,6 @@ using namespace std;
class CMasternodeMan;
extern CMasternodeMan mnodeman;
/** Access to the MN database (mncache.dat)
*/
class CMasternodeDB
{
private:
boost::filesystem::path pathMN;
std::string strMagicMessage;
public:
enum ReadResult {
Ok,
FileError,
HashReadError,
IncorrectHash,
IncorrectMagicMessage,
IncorrectMagicNumber,
IncorrectFormat
};
CMasternodeDB();
bool Write(const CMasternodeMan &mnodemanToSave);
ReadResult Read(CMasternodeMan& mnodemanToLoad, bool fDryRun = false);
};
class CMasternodeMan
{
private:

View File

@ -233,7 +233,7 @@ CInv::CInv(const std::string& strType, const uint256& hashIn)
}
}
if (i == ARRAYLEN(ppszTypeName))
LogPrint("net", "CInv::CInv(string, uint256) : unknown type '%s'", strType);
LogPrint("net", "CInv::CInv(string, uint256) : unknown type '%s'\n", strType);
hash = hashIn;
}
@ -250,7 +250,7 @@ bool CInv::IsKnownType() const
const char* CInv::GetCommand() const
{
if (!IsKnownType())
LogPrint("net", "CInv::GetCommand() : type=%d unknown type", type);
LogPrint("net", "CInv::GetCommand() : type=%d unknown type\n", type);
return ppszTypeName[type];
}

View File

@ -474,8 +474,8 @@ void RPCConsole::setClientModel(ClientModel *model)
autoCompleter = new QCompleter(wordList, this);
ui->lineEdit->setCompleter(autoCompleter);
// clear the lineEdit after activating from QCompleter
connect(autoCompleter, SIGNAL(activated(const QString&)), ui->lineEdit, SLOT(clear()), Qt::QueuedConnection);
// clear the lineEdit after activating from QCompleter
connect(autoCompleter, SIGNAL(activated(const QString&)), ui->lineEdit, SLOT(clear()), Qt::QueuedConnection);
}
}

View File

@ -324,9 +324,6 @@ UniValue masternode(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "You can't use this command until masternode list is synced");
}
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
mnEntries = masternodeConfig.getEntries();
int successful = 0;
int failed = 0;
@ -378,9 +375,6 @@ UniValue masternode(const UniValue& params, bool fHelp)
if(strCommand == "list-conf")
{
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
mnEntries = masternodeConfig.getEntries();
UniValue resultObj(UniValue::VOBJ);
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {

View File

@ -2531,7 +2531,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
const UniValue& input = inputs[idx];
CBitcoinAddress address(input.get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str());
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Dash address: ")+input.get_str());
if (setAddress.count(address))
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str());
setAddress.insert(address);