// Check against synchronized checkpoint bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev) { if (TestNet()) return true; // Testnet has no checkpoints int nHeight = pindexPrev->nHeight + 1; LOCK(cs_hashSyncCheckpoint); // sync-checkpoint should always be accepted block assert(mapBlockIndex.count(hashSyncCheckpoint)); const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; if (nHeight > pindexSync->nHeight) { // trace back to same height as sync-checkpoint const CBlockIndex* pindex = pindexPrev; while (pindex->nHeight > pindexSync->nHeight) if (!(pindex = pindex->pprev)) return error("CheckSync: pprev null - block index structure failure"); if (pindex->nHeight < pindexSync->nHeight || pindex->GetBlockHash() != hashSyncCheckpoint) return false; // only descendant of sync-checkpoint can pass check } if (nHeight == pindexSync->nHeight && hashBlock != hashSyncCheckpoint) return false; // same height with sync-checkpoint if (nHeight < pindexSync->nHeight && !mapBlockIndex.count(hashBlock)) return false; // lower height than sync-checkpoint return true; }
QString BitcoinUnits::description(int unit) { if(!TestNet() && !RegTest()) { switch(unit) { case DASH: return QString("Dash"); case mDASH: return QString("Milli-Dash (1 / 1,000)"); case uDASH: return QString("Micro-Dash (1 / 1,000,000)"); case duffs: return QString("Ten Nano-Dash (1 / 100,000,000)"); default: return QString("???"); } } else { switch(unit) { case DASH: return QString("TestDashs"); case mDASH: return QString("Milli-TestDash (1 / 1,000)"); case uDASH: return QString("Micro-TestDash (1 / 1,000,000)"); case duffs: return QString("Ten Nano-TestDash (1 / 100,000,000)"); default: return QString("???"); } } }
QString BitcoinUnits::name(int unit) { if(!TestNet() && !RegTest()) { switch(unit) { case DASH: return QString("DASH"); case mDASH: return QString("mDASH"); case uDASH: return QString::fromUtf8("μDASH"); case duffs: return QString::fromUtf8("duffs"); default: return QString("???"); } } else { switch(unit) { case DASH: return QString("tDASH"); case mDASH: return QString("mtDASH"); case uDASH: return QString::fromUtf8("μtDASH"); case duffs: return QString::fromUtf8("tduffs"); default: return QString("???"); } } }
int GetTotalBlocksEstimate() { MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints); if (checkpoints.empty()) return 0; return checkpoints.rbegin()->first; }
CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex) { MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints); BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints) { const uint256& hash = i.second; std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash); if (t != mapBlockIndex.end()) return t->second; } return NULL; }
// Verify sync checkpoint master pubkey and reset sync checkpoint if changed bool CheckCheckpointPubKey() { std::string strPubKey = ""; std::string strMasterPubKey = TestNet() ? CSyncCheckpoint::strTestPubKey : CSyncCheckpoint::strMainPubKey; if (!pblocktree->ReadCheckpointPubKey(strPubKey) || strPubKey != strMasterPubKey) { // write checkpoint master key to db if (!pblocktree->WriteCheckpointPubKey(strMasterPubKey)) return error("CheckCheckpointPubKey() : failed to write new checkpoint master key to db"); if (!ResetSyncCheckpoint()) return error("CheckCheckpointPubKey() : failed to reset sync-checkpoint"); } return true; }
bool ClientModel::isTestNet() const { return TestNet(); }
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { qint64 total = 0; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); std::vector<std::pair<CScript, int64_t> > vecSend; if(recipients.empty()) { return OK; } QSet<QString> setAddress; // Used to detect duplicates int nAddresses = 0; // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... int64_t subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { const payments::Output& out = details.outputs(i); if (out.amount() <= 0) continue; subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, out.amount())); } if (subtotal <= 0) { return InvalidAmount; } total += subtotal; } else { // User-entered bitcoin address / amount: if(!validateAddress(rcp.address)) { return InvalidAddress; } if(rcp.amount <= 0) { return InvalidAmount; } setAddress.insert(rcp.address); ++nAddresses; // stealth std::string sAddr = rcp.address.toStdString(); if (rcp.typeInd == AddressTableModel::AT_Stealth) { if ( (!TestNet() && (chainActive.Height() < BLOCK_STEALTH_START)) || (TestNet() && (chainActive.Height() < 200)) ) { emit message(tr("Send Coins"), tr("Stealth addresses not yet supported"), CClientUIInterface::MSG_ERROR); return InvalidAddress; } CStealthAddress sxAddr; if (sxAddr.SetEncoded(sAddr)) { ec_secret ephem_secret; ec_secret secretShared; ec_point pkSendTo; ec_point ephem_pubkey; if (GenerateRandomSecret(ephem_secret) != 0) { LogPrintf("GenerateRandomSecret failed.\n"); return InvalidAddress; }; if (StealthSecret(ephem_secret, sxAddr.scan_pubkey, sxAddr.spend_pubkey, secretShared, pkSendTo) != 0) { LogPrintf("Could not generate receiving public key.\n"); return InvalidAddress; }; CPubKey cpkTo(pkSendTo); if (!cpkTo.IsValid()) { LogPrintf("Invalid public key generated.\n"); return InvalidAddress; }; CKeyID ckidTo = cpkTo.GetID(); CBitcoinAddress addrTo(ckidTo); if (SecretToPublicKey(ephem_secret, ephem_pubkey) != 0) { LogPrintf("Could not generate ephem public key.\n"); return InvalidAddress; }; if (fDebug) { LogPrintf("Stealth send to generated pubkey %ui: %s\n", pkSendTo.size(), HexStr(pkSendTo).c_str()); LogPrintf("hash %s\n", addrTo.ToString().c_str()); LogPrintf("ephem_pubkey %ui: %s\n", ephem_pubkey.size(), HexStr(ephem_pubkey).c_str()); }; CScript scriptPubKey; scriptPubKey.SetDestination(addrTo.Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); CScript scriptP = CScript() << OP_RETURN << ephem_pubkey; vecSend.push_back(make_pair(scriptP, 0)); continue; }; // else drop through to normal } CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(sAddr).Get()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount)); total += rcp.amount; } } if(setAddress.size() != nAddresses) { return DuplicateAddress; } qint64 nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { transaction.setTransactionFee(nTransactionFee); return SendCoinsReturn(AmountWithFeeExceedsBalance); } { LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); int64_t nFeeRequired = 0; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); CReserveKey *keyChange = transaction.getPossibleKeyChange(); // int nChangePos = -1; bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, /*nChangePos,*/ strFailReason, coinControl); /* std::map<int, std::string>::iterator it; for (it = mapStealthNarr.begin(); it != mapStealthNarr.end(); ++it) { int pos = it->first; if (nChangePos > -1 && it->first >= nChangePos) pos++; char key[64]; if (snprintf(key, sizeof(key), "n_%u", pos) < 1) { printf("CreateStealthTransaction(): Error creating narration key."); continue; }; wtx.mapValue[key] = it->second; }; */ transaction.setTransactionFee(nFeeRequired); if(!fCreated) { if((total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } emit message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } } return SendCoinsReturn(OK); }