13 #include <boost/algorithm/string.hpp> 14 #include <boost/foreach.hpp> 23 std::vector<std::string>
SplitBy(std::string strCommand, std::string strDelimit)
25 std::vector<std::string> vParts;
26 boost::split(vParts, strCommand, boost::is_any_of(strDelimit));
28 for(
int q=0; q<(int)vParts.size(); q++) {
29 if(strDelimit.find(vParts[q]) != std::string::npos) {
30 vParts.erase(vParts.begin()+q);
40 DBG( cout <<
"ParsePaymentAmount Start: strAmount = " << strAmount << endl; );
43 if (strAmount.empty()) {
44 std::ostringstream ostr;
45 ostr <<
"ParsePaymentAmount: Amount is empty";
46 throw std::runtime_error(ostr.str());
48 if(strAmount.size() > 20) {
51 std::ostringstream ostr;
52 ostr <<
"ParsePaymentAmount: Amount string too long";
53 throw std::runtime_error(ostr.str());
58 size_t pos = strAmount.find_first_not_of(
"0123456789.");
59 if (pos != std::string::npos) {
60 std::ostringstream ostr;
61 ostr <<
"ParsePaymentAmount: Amount string contains invalid character";
62 throw std::runtime_error(ostr.str());
65 pos = strAmount.find(
".");
68 std::ostringstream ostr;
69 ostr <<
"ParsePaymentAmount: Invalid amount string, leading decimal point not allowed";
70 throw std::runtime_error(ostr.str());
74 if ((pos != std::string::npos) && (strAmount.find(
".", pos+1) != std::string::npos)) {
75 std::ostringstream ostr;
76 ostr <<
"ParsePaymentAmount: Invalid amount string, too many decimal points";
77 throw std::runtime_error(ostr.str());
84 std::ostringstream ostr;
85 ostr <<
"ParsePaymentAmount: ParseFixedPoint failed for string: " << strAmount;
86 throw std::runtime_error(ostr.str());
90 std::ostringstream ostr;
91 ostr <<
"ParsePaymentAmount: Invalid amount string, value outside of valid money range";
92 throw std::runtime_error(ostr.str());
95 DBG( cout <<
"ParsePaymentAmount Returning true nAmount = " << nAmount << endl; );
106 DBG( cout <<
"CGovernanceTriggerManager::AddNewTrigger: Start" << endl; );
112 cout <<
"CGovernanceTriggerManager::AddNewTrigger: Already have hash" 113 <<
", nHash = " << nHash.
GetHex()
115 <<
", mapTrigger.size() = " <<
mapTrigger.size()
123 pSuperblock = pSuperblockTmp;
125 catch(std::exception& e) {
126 DBG( cout <<
"CGovernanceTriggerManager::AddNewTrigger Error creating superblock" 127 <<
", e.what() = " << e.what()
129 LogPrintf(
"CGovernanceTriggerManager::AddNewTrigger -- Error creating superblock: %s\n", e.what());
133 LogPrintf(
"CGovernanceTriggerManager::AddNewTrigger: Unknown Error creating superblock\n");
134 DBG( cout <<
"CGovernanceTriggerManager::AddNewTrigger Error creating superblock catchall" << endl; );
140 DBG( cout <<
"CGovernanceTriggerManager::AddNewTrigger: Inserting trigger" << endl; );
141 mapTrigger.insert(std::make_pair(nHash, pSuperblock));
143 DBG( cout <<
"CGovernanceTriggerManager::AddNewTrigger: End" << endl; );
156 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- Start\n");
157 DBG( cout <<
"CGovernanceTriggerManager::CleanAndRemove: Start" << endl; );
178 DBG( cout <<
"CGovernanceTriggerManager::CleanAndRemove: mapTrigger.size() = " <<
mapTrigger.size() << endl; );
179 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- mapTrigger.size() = %d\n",
mapTrigger.size());
185 DBG( cout <<
"CGovernanceTriggerManager::CleanAndRemove: NULL superblock marked for removal " << endl; );
186 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- NULL superblock marked for removal\n");
189 DBG( cout <<
"CGovernanceTriggerManager::CleanAndRemove: superblock status = " << pSuperblock->GetStatus() << endl; );
190 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- superblock status = %d\n", pSuperblock->GetStatus());
191 switch(pSuperblock->GetStatus()) {
194 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- Unknown or invalid trigger found\n");
200 int nTriggerBlock = pSuperblock->GetBlockStart();
203 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- nTriggerBlock = %d, nExpirationBlock = %d\n", nTriggerBlock, nExpirationBlock);
205 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- Outdated trigger found\n");
209 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- Expiring outdated object: %s\n", pgovobj->
GetHash().
ToString());
223 string strdata =
"NULL";
228 cout <<
"CGovernanceTriggerManager::CleanAndRemove: Removing object: " 232 LogPrint(
"gobject",
"CGovernanceTriggerManager::CleanAndRemove -- Removing trigger object\n");
240 DBG( cout <<
"CGovernanceTriggerManager::CleanAndRemove: End" << endl; );
253 std::vector<CSuperblock_sptr> vecResults;
255 DBG( cout <<
"GetActiveTriggers: mapTrigger.size() = " <<
mapTrigger.size() << endl; );
264 DBG( cout <<
"GetActiveTriggers: pObj->GetDataAsString() = " << pObj->
GetDataAsString() << endl; );
265 vecResults.push_back(it->second);
270 DBG( cout <<
"GetActiveTriggers: vecResults.size() = " << vecResults.size() << endl; );
283 LogPrint(
"gobject",
"CSuperblockManager::IsSuperblockTriggered -- Start nBlockHeight = %d\n", nBlockHeight);
292 LogPrint(
"gobject",
"CSuperblockManager::IsSuperblockTriggered -- vecTriggers.size() = %d\n", vecTriggers.size());
294 DBG( cout <<
"IsSuperblockTriggered Number triggers = " << vecTriggers.size() << endl; );
299 LogPrintf(
"CSuperblockManager::IsSuperblockTriggered -- Non-superblock found, continuing\n");
300 DBG( cout <<
"IsSuperblockTriggered Not a superblock, continuing " << endl; );
307 LogPrintf(
"CSuperblockManager::IsSuperblockTriggered -- pObj == NULL, continuing\n");
308 DBG( cout <<
"IsSuperblockTriggered pObj is NULL, continuing" << endl; );
316 if(nBlockHeight != pSuperblock->GetBlockStart()) {
317 LogPrint(
"gobject",
"CSuperblockManager::IsSuperblockTriggered -- block height doesn't match nBlockHeight = %d, blockStart = %d, continuing\n",
319 pSuperblock->GetBlockStart());
320 DBG( cout <<
"IsSuperblockTriggered Not the target block, continuing" 321 <<
", nBlockHeight = " << nBlockHeight
322 <<
", superblock->GetBlockStart() = " << pSuperblock->GetBlockStart()
332 LogPrint(
"gobject",
"CSuperblockManager::IsSuperblockTriggered -- fCacheFunding = true, returning true\n");
333 DBG( cout <<
"IsSuperblockTriggered returning true" << endl; );
337 LogPrint(
"gobject",
"CSuperblockManager::IsSuperblockTriggered -- fCacheFunding = false, continuing\n");
338 DBG( cout <<
"IsSuperblockTriggered No fCachedFunding, continuing" << endl; );
358 DBG( cout <<
"GetBestSuperblock Not a superblock, continuing" << endl; );
365 DBG( cout <<
"GetBestSuperblock pObj is NULL, continuing" << endl; );
369 if(nBlockHeight != pSuperblock->GetBlockStart()) {
370 DBG( cout <<
"GetBestSuperblock Not the target block, continuing" << endl; );
377 DBG( cout <<
"GetBestSuperblock nTempYesCount = " << nTempYesCount << endl; );
378 if(nTempYesCount > nYesCount) {
379 nYesCount = nTempYesCount;
380 pSuperblockRet = pSuperblock;
381 DBG( cout <<
"GetBestSuperblock Valid superblock found, pSuperblock set" << endl; );
385 return nYesCount > 0;
396 DBG( cout <<
"CSuperblockManager::CreateSuperblock Start" << endl; );
404 LogPrint(
"gobject",
"CSuperblockManager::CreateSuperblock -- Can't find superblock for height %d\n", nBlockHeight);
405 DBG( cout <<
"CSuperblockManager::CreateSuperblock Failed to get superblock for height, returning" << endl; );
410 voutSuperblockRet.clear();
415 DBG( cout <<
"CSuperblockManager::CreateSuperblock Number payments: " << pSuperblock->CountPayments() << endl; );
421 for(
int i = 0; i < pSuperblock->CountPayments(); i++) {
423 DBG( cout <<
"CSuperblockManager::CreateSuperblock i = " << i << endl; );
424 if(pSuperblock->GetPayment(i, payment)) {
425 DBG( cout <<
"CSuperblockManager::CreateSuperblock Payment found " << endl; );
429 txNewRet.
vout.push_back(txout);
430 voutSuperblockRet.push_back(txout);
440 DBG( cout <<
"CSuperblockManager::CreateSuperblock Before LogPrintf call, nAmount = " << payment.
nAmount << endl; );
442 DBG( cout <<
"CSuperblockManager::CreateSuperblock After LogPrintf call " << endl; );
444 DBG( cout <<
"CSuperblockManager::CreateSuperblock Payment not found " << endl; );
448 DBG( cout <<
"CSuperblockManager::CreateSuperblock End" << endl; );
458 return pSuperblock->IsValid(txNew, nBlockHeight, blockReward);
474 : nGovObjHash(nHash),
479 DBG( cout <<
"CSuperblock Constructor Start" << endl; );
484 DBG( cout <<
"CSuperblock Constructor pGovObjIn is NULL, returning" << endl; );
485 throw std::runtime_error(
"CSuperblock: Failed to find Governance Object");
488 DBG( cout <<
"CSuperblock Constructor pGovObj : " 489 << pGovObj->GetDataAsString()
490 <<
", nObjectType = " << pGovObj->GetObjectType()
494 DBG( cout <<
"CSuperblock Constructor pHoObj not a trigger, returning" << endl; );
495 throw std::runtime_error(
"CSuperblock: Governance Object not a trigger");
498 UniValue obj = pGovObj->GetJSONObject();
504 std::string strAddresses = obj[
"payment_addresses"].
get_str();
505 std::string strAmounts = obj[
"payment_amounts"].
get_str();
508 LogPrint(
"gobject",
"CSuperblock -- nEpochStart = %d, strAddresses = %s, strAmounts = %s, vecPayments.size() = %d\n",
511 DBG( cout <<
"CSuperblock Constructor End" << endl; );
540 LogPrint(
"gobject",
"CSuperblock::GetPaymentsLimit -- Valid superblock height %d, payments max %lld\n", nBlockHeight, nPaymentsLimit);
542 return nPaymentsLimit;
549 std::vector<std::string> vecParsed1;
550 std::vector<std::string> vecParsed2;
551 vecParsed1 =
SplitBy(strPaymentAddresses,
"|");
552 vecParsed2 =
SplitBy(strPaymentAmounts,
"|");
556 if (vecParsed1.size() != vecParsed2.size()) {
557 std::ostringstream ostr;
558 ostr <<
"CSuperblock::ParsePaymentSchedule -- Mismatched payments and amounts";
560 throw std::runtime_error(ostr.str());
563 if (vecParsed1.size() == 0) {
564 std::ostringstream ostr;
565 ostr <<
"CSuperblock::ParsePaymentSchedule -- Error no payments";
567 throw std::runtime_error(ostr.str());
576 DBG( cout <<
"CSuperblock::ParsePaymentSchedule vecParsed1.size() = " << vecParsed1.size() << endl; );
578 for (
int i = 0; i < (int)vecParsed1.size(); i++) {
581 std::ostringstream ostr;
582 ostr <<
"CSuperblock::ParsePaymentSchedule -- Invalid Dash Address : " << vecParsed1[i];
584 throw std::runtime_error(ostr.str());
587 DBG( cout <<
"CSuperblock::ParsePaymentSchedule i = " << i
588 <<
", vecParsed2[i] = " << vecParsed2[i]
593 DBG( cout <<
"CSuperblock::ParsePaymentSchedule: " 594 <<
"amount string = " << vecParsed2[i]
595 <<
", nAmount = " << nAmount
599 if(payment.IsValid()) {
604 std::ostringstream ostr;
605 ostr <<
"CSuperblock::ParsePaymentSchedule -- Invalid payment found: address = " << address.
ToString()
606 <<
", amount = " << nAmount;
608 throw std::runtime_error(ostr.str());
615 if((nPaymentIndex<0) || (nPaymentIndex >= (
int)
vecPayments.size())) {
625 CAmount nPaymentsTotalAmount = 0;
628 for(
int i = 0; i < nPayments; i++) {
632 return nPaymentsTotalAmount;
649 LogPrintf(
"CSuperblock::IsValid -- ERROR: Block invalid, incorrect block height\n");
653 std::string strPayeesPossible =
"";
657 int nOutputs = txNew.
vout.size();
659 int nMinerPayments = nOutputs - nPayments;
661 LogPrint(
"gobject",
"CSuperblock::IsValid nOutputs = %d, nPayments = %d, strData = %s\n",
667 if(nMinerPayments < 0) {
671 LogPrintf(
"CSuperblock::IsValid -- ERROR: Block invalid, too few superblock payments\n");
678 if(nPaymentsTotalAmount > nPaymentsLimit) {
679 LogPrintf(
"CSuperblock::IsValid -- ERROR: Block invalid, payments limit exceeded: payments %lld, limit %lld\n", nPaymentsTotalAmount, nPaymentsLimit);
685 if(nBlockValue > blockReward + nPaymentsTotalAmount) {
686 LogPrintf(
"CSuperblock::IsValid -- ERROR: Block invalid, block value limit exceeded: block %lld, limit %lld\n", nBlockValue, blockReward + nPaymentsTotalAmount);
691 for(
int i = 0; i < nPayments; i++) {
695 LogPrintf(
"CSuperblock::IsValid -- WARNING: Failed to find payment: %d of %d total payments\n", i, nPayments);
699 bool fPaymentMatch =
false;
701 for (
int j = nVoutIndex; j < nOutputs; j++) {
703 fPaymentMatch = ((payment.
script == txNew.
vout[j].scriptPubKey) &&
718 LogPrintf(
"CSuperblock::IsValid -- ERROR: Block invalid: %d payment %d to %s not found\n", i, payment.
nAmount, address2.
ToString());
736 std::string ret =
"Unknown";
742 LogPrint(
"gobject",
"CSuperblockManager::GetRequiredPaymentsString -- Can't find superblock for height %d\n", nBlockHeight);
748 for(
int i = 0; i < pSuperblock->CountPayments(); i++) {
750 if(pSuperblock->GetPayment(i, payment)) {
759 if(ret !=
"Unknown") {
void UpdateSentinelVariables()
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
int nSuperblockStartBlock
CAmount ParsePaymentAmount(const std::string &strAmount)
static std::string GetRequiredPaymentsString(int nBlockHeight)
static const int GOVERNANCE_TRIGGER_EXPIRATION_BLOCKS
const Consensus::Params & GetConsensus() const
bool fPowAllowMinDifficultyBlocks
bool MoneyRange(const CAmount &nValue)
CGovernanceObject * FindGovernanceObject(const uint256 &nHash)
CGovernanceObject * GetGovernanceObject()
static bool IsSuperblockTriggered(int nBlockHeight)
static const int SEEN_OBJECT_ERROR_INVALID
CAmount GetValueOut() const
bool IsValid(const CTransaction &txNew, int nBlockHeight, CAmount blockReward)
bool fExpired
Object is no longer of interest.
CAmount GetPaymentsTotalAmount()
uint32_t GetCompact(bool fNegative=false) const
std::vector< CSuperblock_sptr > GetActiveTriggers()
bool GetPayment(int nPaymentIndex, CGovernancePayment &paymentRet)
arith_uint256 UintToArith256(const uint256 &a)
std::string ToString() const
static bool IsValid(const CTransaction &txNew, int nBlockHeight, CAmount blockReward)
#define AssertLockHeld(cs)
CGovernanceTriggerManager triggerman
static bool GetBestSuperblock(CSuperblock_sptr &pSuperblockRet, int nBlockHeight)
static int LogPrint(const char *category, const char *format)
int64_t nDeletionTime
time this object was marked for deletion
bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
std::string GetDataAsHex()
static const int GOVERNANCE_OBJECT_TRIGGER
std::string GetDataAsString()
static const int SEEN_OBJECT_IS_VALID
std::string ToString() const
static CAmount GetPaymentsLimit(int nBlockHeight)
static const int SEEN_OBJECT_EXECUTED
static const int SEEN_OBJECT_UNKNOWN
std::vector< CTxOut > vout
void ParsePaymentSchedule(std::string &strPaymentAddresses, std::string &strPaymentAmounts)
bool AddNewTrigger(uint256 nHash)
bool IsSetCachedFunding() const
const CChainParams & Params()
int GetAbsoluteYesCount(vote_signal_enum_t eVoteSignalIn) const
int64_t GetAdjustedTime()
int GetCachedBlockHeight()
std::string GetHex() const
const std::vector< CTxOut > vout
virtual uint256 GetHash()=0
CGovernanceManager governance
std::vector< CGovernancePayment > vecPayments
CAmount GetBlockSubsidy(int nPrevBits, int nPrevHeight, const Consensus::Params &consensusParams, bool fSuperblockPartOnly)
boost::shared_ptr< CSuperblock > CSuperblock_sptr
static bool IsValidBlockHeight(int nBlockHeight)
std::vector< std::string > SplitBy(std::string strCommand, std::string strDelimit)
trigger_m_t::iterator trigger_m_it
static void CreateSuperblock(CMutableTransaction &txNewRet, int nBlockHeight, std::vector< CTxOut > &voutSuperblockRet)
int GetObjectType() const
std::string get_str() const