2023-01-12 22:26:21 +01:00
|
|
|
// Copyright (c) 2014-2022 The Dash Core developers
|
2016-08-17 09:08:25 +02:00
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2021-10-01 21:19:08 +02:00
|
|
|
#include <governance/classes.h>
|
2021-04-23 00:32:03 +02:00
|
|
|
|
2021-10-25 15:55:34 +02:00
|
|
|
#include <chainparams.h>
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <core_io.h>
|
2021-04-23 00:32:03 +02:00
|
|
|
#include <governance/governance.h>
|
|
|
|
#include <key_io.h>
|
|
|
|
#include <primitives/transaction.h>
|
|
|
|
#include <script/standard.h>
|
|
|
|
#include <timedata.h>
|
2021-06-27 08:33:13 +02:00
|
|
|
#include <util/strencodings.h>
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <validation.h>
|
2023-04-16 19:09:37 +02:00
|
|
|
#include <util/underlying.h>
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-12-20 14:27:59 +01:00
|
|
|
#include <univalue.h>
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
// DECLARE GLOBAL VARIABLES FOR GOVERNANCE CLASSES
|
|
|
|
CGovernanceTriggerManager triggerman;
|
|
|
|
|
|
|
|
// SPLIT UP STRING BY DELIMITER
|
2018-02-12 13:49:00 +01:00
|
|
|
std::vector<std::string> SplitBy(const std::string& strCommand, const std::string& strDelimit)
|
2016-08-17 09:08:25 +02:00
|
|
|
{
|
2023-01-03 09:58:11 +01:00
|
|
|
std::vector<std::string> vParts = SplitString(strCommand, strDelimit);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
for (int q = 0; q < (int)vParts.size(); q++) {
|
|
|
|
if (strDelimit.find(vParts[q]) != std::string::npos) {
|
|
|
|
vParts.erase(vParts.begin() + q);
|
2016-08-17 09:08:25 +02:00
|
|
|
--q;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
return vParts;
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
CAmount ParsePaymentAmount(const std::string& strAmount)
|
|
|
|
{
|
|
|
|
CAmount nAmount = 0;
|
|
|
|
if (strAmount.empty()) {
|
|
|
|
std::ostringstream ostr;
|
|
|
|
ostr << "ParsePaymentAmount: Amount is empty";
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
2018-09-28 09:56:17 +02:00
|
|
|
if (strAmount.size() > 20) {
|
2016-08-17 09:08:25 +02:00
|
|
|
// String is much too long, the functions below impose stricter
|
|
|
|
// requirements
|
|
|
|
std::ostringstream ostr;
|
|
|
|
ostr << "ParsePaymentAmount: Amount string too long";
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
// Make sure the string makes sense as an amount
|
|
|
|
// Note: No spaces allowed
|
|
|
|
// Also note: No scientific notation
|
|
|
|
size_t pos = strAmount.find_first_not_of("0123456789.");
|
|
|
|
if (pos != std::string::npos) {
|
|
|
|
std::ostringstream ostr;
|
|
|
|
ostr << "ParsePaymentAmount: Amount string contains invalid character";
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
2021-06-06 23:35:29 +02:00
|
|
|
pos = strAmount.find('.');
|
2016-09-12 09:40:00 +02:00
|
|
|
if (pos == 0) {
|
2016-08-17 09:08:25 +02:00
|
|
|
// JSON doesn't allow values to start with a decimal point
|
|
|
|
std::ostringstream ostr;
|
|
|
|
ostr << "ParsePaymentAmount: Invalid amount string, leading decimal point not allowed";
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure there's no more than 1 decimal point
|
2021-06-06 23:35:29 +02:00
|
|
|
if ((pos != std::string::npos) && (strAmount.find('.', pos + 1) != std::string::npos)) {
|
2016-08-17 09:08:25 +02:00
|
|
|
std::ostringstream ostr;
|
|
|
|
ostr << "ParsePaymentAmount: Invalid amount string, too many decimal points";
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Note this code is taken from AmountFromValue in rpcserver.cpp
|
|
|
|
// which is used for parsing the amounts in createrawtransaction.
|
|
|
|
if (!ParseFixedPoint(strAmount, 8, &nAmount)) {
|
|
|
|
nAmount = 0;
|
|
|
|
std::ostringstream ostr;
|
|
|
|
ostr << "ParsePaymentAmount: ParseFixedPoint failed for string: " << strAmount;
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
if (!MoneyRange(nAmount)) {
|
|
|
|
nAmount = 0;
|
|
|
|
std::ostringstream ostr;
|
|
|
|
ostr << "ParsePaymentAmount: Invalid amount string, value outside of valid money range";
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return nAmount;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add Governance Object
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool CGovernanceTriggerManager::AddNewTrigger(uint256 nHash)
|
|
|
|
{
|
2022-08-26 23:52:53 +02:00
|
|
|
AssertLockHeld(governance->cs);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
// IF WE ALREADY HAVE THIS HASH, RETURN
|
2018-09-28 09:56:17 +02:00
|
|
|
if (mapTrigger.count(nHash)) {
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::AddNewTrigger -- Already have hash, nHash = %s, count = %d, size = %s\n",
|
2019-03-25 07:15:32 +01:00
|
|
|
nHash.GetHex(), mapTrigger.count(nHash), mapTrigger.size());
|
2016-08-17 09:08:25 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-09-12 09:40:00 +02:00
|
|
|
CSuperblock_sptr pSuperblock;
|
2018-09-28 09:56:17 +02:00
|
|
|
try {
|
2021-06-26 15:09:09 +02:00
|
|
|
auto pSuperblockTmp = std::make_shared<CSuperblock>(nHash);
|
2016-09-12 09:40:00 +02:00
|
|
|
pSuperblock = pSuperblockTmp;
|
2018-09-28 09:56:17 +02:00
|
|
|
} catch (std::exception& e) {
|
2016-09-12 09:40:00 +02:00
|
|
|
LogPrintf("CGovernanceTriggerManager::AddNewTrigger -- Error creating superblock: %s\n", e.what());
|
2016-08-17 09:08:25 +02:00
|
|
|
return false;
|
2018-09-28 09:56:17 +02:00
|
|
|
} catch (...) {
|
2016-08-17 09:08:25 +02:00
|
|
|
LogPrintf("CGovernanceTriggerManager::AddNewTrigger: Unknown Error creating superblock\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-04-16 19:09:37 +02:00
|
|
|
pSuperblock->SetStatus(SeenObjectStatus::Valid);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-09-12 09:40:00 +02:00
|
|
|
mapTrigger.insert(std::make_pair(nHash, pSuperblock));
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Clean And Remove
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
void CGovernanceTriggerManager::CleanAndRemove()
|
|
|
|
{
|
2022-08-26 23:52:53 +02:00
|
|
|
AssertLockHeld(governance->cs);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2018-02-12 19:35:10 +01:00
|
|
|
// Remove triggers that are invalid or expired
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::CleanAndRemove -- mapTrigger.size() = %d\n", mapTrigger.size());
|
2018-06-06 17:56:33 +02:00
|
|
|
|
2021-01-26 04:31:31 +01:00
|
|
|
auto it = mapTrigger.begin();
|
2018-09-28 09:56:17 +02:00
|
|
|
while (it != mapTrigger.end()) {
|
2016-08-17 09:08:25 +02:00
|
|
|
bool remove = false;
|
2018-06-06 17:56:33 +02:00
|
|
|
CGovernanceObject* pObj = nullptr;
|
2021-06-26 15:09:09 +02:00
|
|
|
const CSuperblock_sptr& pSuperblock = it->second;
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!pSuperblock) {
|
2019-08-23 20:03:05 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::CleanAndRemove -- nullptr superblock\n");
|
2016-08-17 09:08:25 +02:00
|
|
|
remove = true;
|
2016-09-12 09:40:00 +02:00
|
|
|
} else {
|
2022-08-26 23:52:53 +02:00
|
|
|
pObj = governance->FindGovernanceObject(it->first);
|
2023-04-16 19:09:37 +02:00
|
|
|
if (!pObj || pObj->GetObjectType() != GovernanceObject::TRIGGER) {
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::CleanAndRemove -- Unknown or non-trigger superblock\n");
|
2023-04-16 19:09:37 +02:00
|
|
|
pSuperblock->SetStatus(SeenObjectStatus::ErrorInvalid);
|
2018-06-06 17:56:33 +02:00
|
|
|
}
|
|
|
|
|
2023-04-16 19:09:37 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::CleanAndRemove -- superblock status = %d\n", ToUnderlying(pSuperblock->GetStatus()));
|
2018-09-28 09:56:17 +02:00
|
|
|
switch (pSuperblock->GetStatus()) {
|
2023-04-16 19:09:37 +02:00
|
|
|
case SeenObjectStatus::ErrorInvalid:
|
|
|
|
case SeenObjectStatus::Unknown:
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::CleanAndRemove -- Unknown or invalid trigger found\n");
|
2016-08-17 09:08:25 +02:00
|
|
|
remove = true;
|
|
|
|
break;
|
2023-04-16 19:09:37 +02:00
|
|
|
case SeenObjectStatus::Valid:
|
|
|
|
case SeenObjectStatus::Executed: {
|
2019-08-23 20:03:05 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::CleanAndRemove -- Valid trigger found\n");
|
2022-08-26 23:52:53 +02:00
|
|
|
if (pSuperblock->IsExpired(*governance)) {
|
2019-08-23 20:03:05 +02:00
|
|
|
// update corresponding object
|
|
|
|
pObj->SetExpired();
|
|
|
|
remove = true;
|
|
|
|
}
|
2016-08-17 09:08:25 +02:00
|
|
|
break;
|
2019-08-23 20:03:05 +02:00
|
|
|
}
|
2016-08-17 09:08:25 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::CleanAndRemove -- %smarked for removal\n", remove ? "" : "NOT ");
|
2016-09-12 09:40:00 +02:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (remove) {
|
2019-08-06 05:08:33 +02:00
|
|
|
std::string strDataAsPlainString = "nullptr";
|
2019-03-25 07:15:32 +01:00
|
|
|
if (pObj) {
|
|
|
|
strDataAsPlainString = pObj->GetDataAsPlainString();
|
2019-08-23 20:03:05 +02:00
|
|
|
// mark corresponding object for deletion
|
|
|
|
pObj->PrepareDeletion(GetAdjustedTime());
|
2019-03-25 07:15:32 +01:00
|
|
|
}
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CGovernanceTriggerManager::CleanAndRemove -- Removing trigger object %s\n", strDataAsPlainString);
|
2018-06-06 17:56:33 +02:00
|
|
|
// delete the trigger
|
2016-08-17 09:08:25 +02:00
|
|
|
mapTrigger.erase(it++);
|
2018-09-28 09:56:17 +02:00
|
|
|
} else {
|
2016-08-17 09:08:25 +02:00
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get Active Triggers
|
|
|
|
*
|
|
|
|
* - Look through triggers and scan for active ones
|
|
|
|
* - Return the triggers in a list
|
|
|
|
*/
|
|
|
|
|
|
|
|
std::vector<CSuperblock_sptr> CGovernanceTriggerManager::GetActiveTriggers()
|
|
|
|
{
|
2022-08-26 23:52:53 +02:00
|
|
|
AssertLockHeld(governance->cs);
|
2016-08-17 09:08:25 +02:00
|
|
|
std::vector<CSuperblock_sptr> vecResults;
|
|
|
|
|
|
|
|
// LOOK AT THESE OBJECTS AND COMPILE A VALID LIST OF TRIGGERS
|
2018-07-12 11:07:51 +02:00
|
|
|
for (const auto& pair : mapTrigger) {
|
2022-08-26 23:52:53 +02:00
|
|
|
const CGovernanceObject* pObj = governance->FindGovernanceObject(pair.first);
|
2018-09-28 09:56:17 +02:00
|
|
|
if (pObj) {
|
2018-07-12 11:07:51 +02:00
|
|
|
vecResults.push_back(pair.second);
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return vecResults;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is Superblock Triggered
|
|
|
|
*
|
2021-07-17 21:15:21 +02:00
|
|
|
* - Does this block have a non-executed and activated trigger?
|
2016-08-17 09:08:25 +02:00
|
|
|
*/
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
bool CSuperblockManager::IsSuperblockTriggered(CGovernanceManager& governanceManager, int nBlockHeight)
|
2016-08-17 09:08:25 +02:00
|
|
|
{
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::IsSuperblockTriggered -- Start nBlockHeight = %d\n", nBlockHeight);
|
2016-08-22 03:41:40 +02:00
|
|
|
if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
2016-08-17 09:08:25 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
LOCK(governanceManager.cs);
|
2016-08-17 09:08:25 +02:00
|
|
|
// GET ALL ACTIVE TRIGGERS
|
|
|
|
std::vector<CSuperblock_sptr> vecTriggers = triggerman.GetActiveTriggers();
|
|
|
|
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::IsSuperblockTriggered -- vecTriggers.size() = %d\n", vecTriggers.size());
|
2016-10-17 20:54:28 +02:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
for (const auto& pSuperblock : vecTriggers) {
|
|
|
|
if (!pSuperblock) {
|
2016-10-17 20:54:28 +02:00
|
|
|
LogPrintf("CSuperblockManager::IsSuperblockTriggered -- Non-superblock found, continuing\n");
|
2016-08-17 09:08:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
CGovernanceObject* pObj = pSuperblock->GetGovernanceObject(governanceManager);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!pObj) {
|
2018-07-12 11:08:43 +02:00
|
|
|
LogPrintf("CSuperblockManager::IsSuperblockTriggered -- pObj == nullptr, continuing\n");
|
2016-08-17 09:08:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::IsSuperblockTriggered -- data = %s\n", pObj->GetDataAsPlainString());
|
2016-10-17 20:54:28 +02:00
|
|
|
|
2016-08-17 09:08:25 +02:00
|
|
|
// note : 12.1 - is epoch calculation correct?
|
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (nBlockHeight != pSuperblock->GetBlockHeight()) {
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::IsSuperblockTriggered -- block height doesn't match nBlockHeight = %d, blockStart = %d, continuing\n",
|
2018-09-28 09:56:17 +02:00
|
|
|
nBlockHeight,
|
|
|
|
pSuperblock->GetBlockHeight());
|
2016-08-17 09:08:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// MAKE SURE THIS TRIGGER IS ACTIVE VIA FUNDING CACHE FLAG
|
|
|
|
|
2016-12-11 07:17:38 +01:00
|
|
|
pObj->UpdateSentinelVariables();
|
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (pObj->IsSetCachedFunding()) {
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::IsSuperblockTriggered -- fCacheFunding = true, returning true\n");
|
2016-08-17 09:08:25 +02:00
|
|
|
return true;
|
2018-09-28 09:56:17 +02:00
|
|
|
} else {
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::IsSuperblockTriggered -- fCacheFunding = false, continuing\n");
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
bool CSuperblockManager::GetBestSuperblock(CGovernanceManager& governanceManager, CSuperblock_sptr& pSuperblockRet, int nBlockHeight)
|
2016-08-17 09:08:25 +02:00
|
|
|
{
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
2016-08-22 03:41:40 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
AssertLockHeld(governanceManager.cs);
|
2016-08-17 09:08:25 +02:00
|
|
|
std::vector<CSuperblock_sptr> vecTriggers = triggerman.GetActiveTriggers();
|
|
|
|
int nYesCount = 0;
|
|
|
|
|
2018-02-06 12:09:33 +01:00
|
|
|
for (const auto& pSuperblock : vecTriggers) {
|
2019-03-25 07:15:32 +01:00
|
|
|
if (!pSuperblock || nBlockHeight != pSuperblock->GetBlockHeight()) {
|
2016-08-17 09:08:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
const CGovernanceObject* pObj = pSuperblock->GetGovernanceObject(governanceManager);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!pObj) {
|
2016-08-17 09:08:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// DO WE HAVE A NEW WINNER?
|
|
|
|
|
|
|
|
int nTempYesCount = pObj->GetAbsoluteYesCount(VOTE_SIGNAL_FUNDING);
|
2018-09-28 09:56:17 +02:00
|
|
|
if (nTempYesCount > nYesCount) {
|
2016-08-17 09:08:25 +02:00
|
|
|
nYesCount = nTempYesCount;
|
2016-09-12 09:40:00 +02:00
|
|
|
pSuperblockRet = pSuperblock;
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nYesCount > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-08-12 17:27:09 +02:00
|
|
|
* Get Superblock Payments
|
2016-08-17 09:08:25 +02:00
|
|
|
*
|
2018-08-12 17:27:09 +02:00
|
|
|
* - Returns payments for superblock
|
2016-08-17 09:08:25 +02:00
|
|
|
*/
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
bool CSuperblockManager::GetSuperblockPayments(CGovernanceManager& governanceManager, int nBlockHeight, std::vector<CTxOut>& voutSuperblockRet)
|
2016-08-17 09:08:25 +02:00
|
|
|
{
|
2022-08-26 23:52:53 +02:00
|
|
|
LOCK(governanceManager.cs);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
// GET THE BEST SUPERBLOCK FOR THIS BLOCK HEIGHT
|
|
|
|
|
2016-09-12 09:40:00 +02:00
|
|
|
CSuperblock_sptr pSuperblock;
|
2022-08-26 23:52:53 +02:00
|
|
|
if (!CSuperblockManager::GetBestSuperblock(governanceManager, pSuperblock, nBlockHeight)) {
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::GetSuperblockPayments -- Can't find superblock for height %d\n", nBlockHeight);
|
2018-08-12 17:27:09 +02:00
|
|
|
return false;
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
2016-08-28 12:11:36 +02:00
|
|
|
// make sure it's empty, just in case
|
|
|
|
voutSuperblockRet.clear();
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2018-08-12 17:27:09 +02:00
|
|
|
// GET SUPERBLOCK OUTPUTS
|
2016-08-19 13:53:49 +02:00
|
|
|
|
2018-08-12 17:27:09 +02:00
|
|
|
// Superblock payments will be appended to the end of the coinbase vout vector
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-08-22 03:41:40 +02:00
|
|
|
// TODO: How many payments can we add before things blow up?
|
|
|
|
// Consider at least following limits:
|
|
|
|
// - max coinbase tx size
|
|
|
|
// - max "budget" available
|
2018-09-28 09:56:17 +02:00
|
|
|
for (int i = 0; i < pSuperblock->CountPayments(); i++) {
|
2016-08-17 09:08:25 +02:00
|
|
|
CGovernancePayment payment;
|
2018-09-28 09:56:17 +02:00
|
|
|
if (pSuperblock->GetPayment(i, payment)) {
|
2016-08-17 09:08:25 +02:00
|
|
|
// SET COINBASE OUTPUT TO SUPERBLOCK SETTING
|
|
|
|
|
2016-08-28 12:11:36 +02:00
|
|
|
CTxOut txout = CTxOut(payment.nAmount, payment.script);
|
|
|
|
voutSuperblockRet.push_back(txout);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
// PRINT NICE LOG OUTPUT FOR SUPERBLOCK PAYMENT
|
|
|
|
|
Merge #11117: Prepare for non-Base58 addresses (#3294)
* Merge #11117: Prepare for non-Base58 addresses
864cd2787 Move CBitcoinAddress to base58.cpp (Pieter Wuille)
5c8ff0d44 Introduce wrappers around CBitcoinAddress (Pieter Wuille)
Pull request description:
This patch removes the need for the intermediary Base58 type `CBitcoinAddress`, by providing {`Encode`,`Decode`,`IsValid`}`Destination` functions that directly operate on the conversion between `std::string`s and `CTxDestination`.
As a side, it also fixes a number of indentation issues, and removes probably several unnecessary implicit `CTxDestination`<->`CBitcoinAddress` conversions.
This change is far from complete. In follow-ups I'd like to:
* Split off the specific address and key encoding logic from base58.h, and move it to a address.h or so.
* Replace `CTxDestination` with a non-`boost::variant` version (which can be more efficient as `boost::variant` allocates everything on the heap, and remove the need for `boost::get<...>` and `IsValidDestination` calls everywhere).
* Do the same for `CBitcoinSecret`, `CBitcoinExtKey`, and `CBitcoinExtPubKey`.
However, I've tried to keep this patch to be minimally invasive, but still enough to support non-Base58 addresses. Perhaps a smaller patch is possible to hack Bech32 support into `CBitcoinAddress`, but I would consider that a move in the wrong direction.
Tree-SHA512: c2c77ffb57caeadf2429b1c2562ce60e8c7be8aa9f8e51b591f354b6b441162625b2efe14c023a1ae485cf2ed417263afa35c892891dfaa7844e7fbabccab85e
* CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* fix CBitcoinAddress GetKeyID check
Signed-off-by: Pasta <pasta@dashboost.org>
* fix providertx.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* hopefully fix governance-classes.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-validators.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-classes.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* fix governance-classes.h
Signed-off-by: Pasta <pasta@dashboost.org>
* DecodeTransaction -> DecodeDestination, fix governance-validators.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* More fixes for 3294
* Move GetIndexKey into rpc/misc.cpp near getAddressesFromParams
No need to have it in base58.cpp anymore as this is only used in getAddressesFromParams
Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Alexander Block <ablock84@gmail.com>
2020-01-22 11:35:04 +01:00
|
|
|
CTxDestination dest;
|
|
|
|
ExtractDestination(payment.script, dest);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
// TODO: PRINT NICE N.N DASH OUTPUT
|
|
|
|
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::GetSuperblockPayments -- NEW Superblock: output %d (addr %s, amount %lld)\n",
|
Merge #11117: Prepare for non-Base58 addresses (#3294)
* Merge #11117: Prepare for non-Base58 addresses
864cd2787 Move CBitcoinAddress to base58.cpp (Pieter Wuille)
5c8ff0d44 Introduce wrappers around CBitcoinAddress (Pieter Wuille)
Pull request description:
This patch removes the need for the intermediary Base58 type `CBitcoinAddress`, by providing {`Encode`,`Decode`,`IsValid`}`Destination` functions that directly operate on the conversion between `std::string`s and `CTxDestination`.
As a side, it also fixes a number of indentation issues, and removes probably several unnecessary implicit `CTxDestination`<->`CBitcoinAddress` conversions.
This change is far from complete. In follow-ups I'd like to:
* Split off the specific address and key encoding logic from base58.h, and move it to a address.h or so.
* Replace `CTxDestination` with a non-`boost::variant` version (which can be more efficient as `boost::variant` allocates everything on the heap, and remove the need for `boost::get<...>` and `IsValidDestination` calls everywhere).
* Do the same for `CBitcoinSecret`, `CBitcoinExtKey`, and `CBitcoinExtPubKey`.
However, I've tried to keep this patch to be minimally invasive, but still enough to support non-Base58 addresses. Perhaps a smaller patch is possible to hack Bech32 support into `CBitcoinAddress`, but I would consider that a move in the wrong direction.
Tree-SHA512: c2c77ffb57caeadf2429b1c2562ce60e8c7be8aa9f8e51b591f354b6b441162625b2efe14c023a1ae485cf2ed417263afa35c892891dfaa7844e7fbabccab85e
* CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* fix CBitcoinAddress GetKeyID check
Signed-off-by: Pasta <pasta@dashboost.org>
* fix providertx.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* hopefully fix governance-classes.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-validators.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-classes.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* fix governance-classes.h
Signed-off-by: Pasta <pasta@dashboost.org>
* DecodeTransaction -> DecodeDestination, fix governance-validators.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* More fixes for 3294
* Move GetIndexKey into rpc/misc.cpp near getAddressesFromParams
No need to have it in base58.cpp anymore as this is only used in getAddressesFromParams
Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Alexander Block <ablock84@gmail.com>
2020-01-22 11:35:04 +01:00
|
|
|
i, EncodeDestination(dest), payment.nAmount);
|
2016-09-12 09:40:00 +02:00
|
|
|
} else {
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblockManager::GetSuperblockPayments -- Payment not found\n");
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-12 17:27:09 +02:00
|
|
|
return true;
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
bool CSuperblockManager::IsValid(CGovernanceManager& governanceManager, const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
2016-08-17 09:08:25 +02:00
|
|
|
{
|
|
|
|
// GET BEST SUPERBLOCK, SHOULD MATCH
|
2022-08-26 23:52:53 +02:00
|
|
|
LOCK(governanceManager.cs);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-08-22 03:41:40 +02:00
|
|
|
CSuperblock_sptr pSuperblock;
|
2022-08-26 23:52:53 +02:00
|
|
|
if (CSuperblockManager::GetBestSuperblock(governanceManager, pSuperblock, nBlockHeight)) {
|
2016-08-22 03:41:40 +02:00
|
|
|
return pSuperblock->IsValid(txNew, nBlockHeight, blockReward);
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
void CSuperblockManager::ExecuteBestSuperblock(CGovernanceManager& governanceManager, int nBlockHeight)
|
2018-02-12 19:35:10 +01:00
|
|
|
{
|
2022-08-26 23:52:53 +02:00
|
|
|
LOCK(governanceManager.cs);
|
2018-02-12 19:35:10 +01:00
|
|
|
|
|
|
|
CSuperblock_sptr pSuperblock;
|
2022-08-26 23:52:53 +02:00
|
|
|
if (GetBestSuperblock(governanceManager, pSuperblock, nBlockHeight)) {
|
2018-02-12 19:35:10 +01:00
|
|
|
// All checks are done in CSuperblock::IsValid via IsBlockValueValid and IsBlockPayeeValid,
|
|
|
|
// tip wouldn't be updated if anything was wrong. Mark this trigger as executed.
|
|
|
|
pSuperblock->SetExecuted();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-17 09:08:25 +02:00
|
|
|
CSuperblock::
|
2018-09-28 09:56:17 +02:00
|
|
|
CSuperblock() :
|
|
|
|
nGovObjHash(),
|
|
|
|
nBlockHeight(0),
|
2023-04-16 19:09:37 +02:00
|
|
|
nStatus(SeenObjectStatus::Unknown),
|
2018-09-28 09:56:17 +02:00
|
|
|
vecPayments()
|
|
|
|
{
|
|
|
|
}
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
CSuperblock::
|
2018-09-28 09:56:17 +02:00
|
|
|
CSuperblock(uint256& nHash) :
|
|
|
|
nGovObjHash(nHash),
|
|
|
|
nBlockHeight(0),
|
2023-04-16 19:09:37 +02:00
|
|
|
nStatus(SeenObjectStatus::Unknown),
|
2018-09-28 09:56:17 +02:00
|
|
|
vecPayments()
|
2016-08-17 09:08:25 +02:00
|
|
|
{
|
2022-08-26 23:52:53 +02:00
|
|
|
CGovernanceObject* pGovObj = GetGovernanceObject(*governance);
|
2016-09-12 09:40:00 +02:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!pGovObj) {
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error("CSuperblock: Failed to find Governance Object");
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
2016-09-12 09:40:00 +02:00
|
|
|
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblock -- Constructor pGovObj: %s, nObjectType = %d\n",
|
2023-04-16 19:09:37 +02:00
|
|
|
pGovObj->GetDataAsPlainString(), ToUnderlying(pGovObj->GetObjectType()));
|
2016-09-12 09:40:00 +02:00
|
|
|
|
2023-04-16 19:09:37 +02:00
|
|
|
if (pGovObj->GetObjectType() != GovernanceObject::TRIGGER) {
|
2016-09-12 09:40:00 +02:00
|
|
|
throw std::runtime_error("CSuperblock: Governance Object not a trigger");
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
UniValue obj = pGovObj->GetJSONObject();
|
2016-09-12 09:40:00 +02:00
|
|
|
|
2023-04-16 19:09:37 +02:00
|
|
|
if (obj["type"].get_int() != ToUnderlying(GovernanceObject::TRIGGER)) {
|
2020-12-21 22:22:57 +01:00
|
|
|
throw std::runtime_error("CSuperblock: invalid data type");
|
|
|
|
}
|
|
|
|
|
2018-02-12 13:46:01 +01:00
|
|
|
// FIRST WE GET THE START HEIGHT, THE BLOCK HEIGHT AT WHICH THE PAYMENT SHALL OCCUR
|
|
|
|
nBlockHeight = obj["event_block_height"].get_int();
|
2016-08-29 00:08:27 +02:00
|
|
|
|
2016-08-17 09:08:25 +02:00
|
|
|
// NEXT WE GET THE PAYMENT INFORMATION AND RECONSTRUCT THE PAYMENT VECTOR
|
|
|
|
std::string strAddresses = obj["payment_addresses"].get_str();
|
|
|
|
std::string strAmounts = obj["payment_amounts"].get_str();
|
|
|
|
ParsePaymentSchedule(strAddresses, strAmounts);
|
2016-09-12 09:40:00 +02:00
|
|
|
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblock -- nBlockHeight = %d, strAddresses = %s, strAmounts = %s, vecPayments.size() = %d\n",
|
2018-09-28 09:56:17 +02:00
|
|
|
nBlockHeight, strAddresses, strAmounts, vecPayments.size());
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
CGovernanceObject* CSuperblock::GetGovernanceObject(CGovernanceManager& governanceManager)
|
2021-04-23 00:32:03 +02:00
|
|
|
{
|
2022-08-26 23:52:53 +02:00
|
|
|
AssertLockHeld(governanceManager.cs);
|
|
|
|
CGovernanceObject* pObj = governanceManager.FindGovernanceObject(nGovObjHash);
|
2021-04-23 00:32:03 +02:00
|
|
|
return pObj;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-22 03:41:40 +02:00
|
|
|
/**
|
|
|
|
* Is Valid Superblock Height
|
|
|
|
*
|
|
|
|
* - See if a block at this height can be a superblock
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool CSuperblock::IsValidBlockHeight(int nBlockHeight)
|
|
|
|
{
|
|
|
|
// SUPERBLOCKS CAN HAPPEN ONLY after hardfork and only ONCE PER CYCLE
|
|
|
|
return nBlockHeight >= Params().GetConsensus().nSuperblockStartBlock &&
|
2018-09-28 09:56:17 +02:00
|
|
|
((nBlockHeight % Params().GetConsensus().nSuperblockCycle) == 0);
|
2016-08-22 03:41:40 +02:00
|
|
|
}
|
|
|
|
|
2018-02-12 13:46:55 +01:00
|
|
|
void CSuperblock::GetNearestSuperblocksHeights(int nBlockHeight, int& nLastSuperblockRet, int& nNextSuperblockRet)
|
|
|
|
{
|
|
|
|
const Consensus::Params& consensusParams = Params().GetConsensus();
|
|
|
|
int nSuperblockStartBlock = consensusParams.nSuperblockStartBlock;
|
|
|
|
int nSuperblockCycle = consensusParams.nSuperblockCycle;
|
|
|
|
|
|
|
|
// Get first superblock
|
|
|
|
int nFirstSuperblockOffset = (nSuperblockCycle - nSuperblockStartBlock % nSuperblockCycle) % nSuperblockCycle;
|
|
|
|
int nFirstSuperblock = nSuperblockStartBlock + nFirstSuperblockOffset;
|
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (nBlockHeight < nFirstSuperblock) {
|
2018-02-12 13:46:55 +01:00
|
|
|
nLastSuperblockRet = 0;
|
|
|
|
nNextSuperblockRet = nFirstSuperblock;
|
|
|
|
} else {
|
|
|
|
nLastSuperblockRet = nBlockHeight - nBlockHeight % nSuperblockCycle;
|
|
|
|
nNextSuperblockRet = nLastSuperblockRet + nSuperblockCycle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-22 03:41:40 +02:00
|
|
|
CAmount CSuperblock::GetPaymentsLimit(int nBlockHeight)
|
|
|
|
{
|
|
|
|
const Consensus::Params& consensusParams = Params().GetConsensus();
|
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!IsValidBlockHeight(nBlockHeight)) {
|
2016-08-22 03:41:40 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// min subsidy for high diff networks and vice versa
|
|
|
|
int nBits = consensusParams.fPowAllowMinDifficultyBlocks ? UintToArith256(consensusParams.powLimit).GetCompact() : 1;
|
|
|
|
// some part of all blocks issued during the cycle goes to superblock, see GetBlockSubsidy
|
2017-09-03 15:31:14 +02:00
|
|
|
CAmount nSuperblockPartOfSubsidy = GetBlockSubsidy(nBits, nBlockHeight - 1, consensusParams, true);
|
2016-08-22 03:41:40 +02:00
|
|
|
CAmount nPaymentsLimit = nSuperblockPartOfSubsidy * consensusParams.nSuperblockCycle;
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblock::GetPaymentsLimit -- Valid superblock height %d, payments max %lld\n", nBlockHeight, nPaymentsLimit);
|
2016-08-22 03:41:40 +02:00
|
|
|
|
|
|
|
return nPaymentsLimit;
|
|
|
|
}
|
|
|
|
|
2018-02-12 13:49:00 +01:00
|
|
|
void CSuperblock::ParsePaymentSchedule(const std::string& strPaymentAddresses, const std::string& strPaymentAmounts)
|
2016-08-17 09:08:25 +02:00
|
|
|
{
|
|
|
|
// SPLIT UP ADDR/AMOUNT STRINGS AND PUT IN VECTORS
|
|
|
|
|
|
|
|
std::vector<std::string> vecParsed1;
|
|
|
|
std::vector<std::string> vecParsed2;
|
|
|
|
vecParsed1 = SplitBy(strPaymentAddresses, "|");
|
|
|
|
vecParsed2 = SplitBy(strPaymentAmounts, "|");
|
|
|
|
|
2021-07-17 21:15:21 +02:00
|
|
|
// IF THESE DON'T MATCH, SOMETHING IS WRONG
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
if (vecParsed1.size() != vecParsed2.size()) {
|
|
|
|
std::ostringstream ostr;
|
2016-10-17 20:54:28 +02:00
|
|
|
ostr << "CSuperblock::ParsePaymentSchedule -- Mismatched payments and amounts";
|
|
|
|
LogPrintf("%s\n", ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
|
|
|
}
|
|
|
|
|
2021-06-06 23:35:29 +02:00
|
|
|
if (vecParsed1.empty()) {
|
2016-08-17 09:08:25 +02:00
|
|
|
std::ostringstream ostr;
|
2016-10-17 20:54:28 +02:00
|
|
|
ostr << "CSuperblock::ParsePaymentSchedule -- Error no payments";
|
|
|
|
LogPrintf("%s\n", ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
// LOOP THROUGH THE ADDRESSES/AMOUNTS AND CREATE PAYMENTS
|
|
|
|
/*
|
2016-09-12 09:40:00 +02:00
|
|
|
ADDRESSES = [ADDR1|2|3|4|5|6]
|
|
|
|
AMOUNTS = [AMOUNT1|2|3|4|5|6]
|
2016-08-17 09:08:25 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)vecParsed1.size(); i++) {
|
Merge #11117: Prepare for non-Base58 addresses (#3294)
* Merge #11117: Prepare for non-Base58 addresses
864cd2787 Move CBitcoinAddress to base58.cpp (Pieter Wuille)
5c8ff0d44 Introduce wrappers around CBitcoinAddress (Pieter Wuille)
Pull request description:
This patch removes the need for the intermediary Base58 type `CBitcoinAddress`, by providing {`Encode`,`Decode`,`IsValid`}`Destination` functions that directly operate on the conversion between `std::string`s and `CTxDestination`.
As a side, it also fixes a number of indentation issues, and removes probably several unnecessary implicit `CTxDestination`<->`CBitcoinAddress` conversions.
This change is far from complete. In follow-ups I'd like to:
* Split off the specific address and key encoding logic from base58.h, and move it to a address.h or so.
* Replace `CTxDestination` with a non-`boost::variant` version (which can be more efficient as `boost::variant` allocates everything on the heap, and remove the need for `boost::get<...>` and `IsValidDestination` calls everywhere).
* Do the same for `CBitcoinSecret`, `CBitcoinExtKey`, and `CBitcoinExtPubKey`.
However, I've tried to keep this patch to be minimally invasive, but still enough to support non-Base58 addresses. Perhaps a smaller patch is possible to hack Bech32 support into `CBitcoinAddress`, but I would consider that a move in the wrong direction.
Tree-SHA512: c2c77ffb57caeadf2429b1c2562ce60e8c7be8aa9f8e51b591f354b6b441162625b2efe14c023a1ae485cf2ed417263afa35c892891dfaa7844e7fbabccab85e
* CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* fix CBitcoinAddress GetKeyID check
Signed-off-by: Pasta <pasta@dashboost.org>
* fix providertx.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* hopefully fix governance-classes.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-validators.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-classes.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* fix governance-classes.h
Signed-off-by: Pasta <pasta@dashboost.org>
* DecodeTransaction -> DecodeDestination, fix governance-validators.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* More fixes for 3294
* Move GetIndexKey into rpc/misc.cpp near getAddressesFromParams
No need to have it in base58.cpp anymore as this is only used in getAddressesFromParams
Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Alexander Block <ablock84@gmail.com>
2020-01-22 11:35:04 +01:00
|
|
|
CTxDestination dest = DecodeDestination(vecParsed1[i]);
|
|
|
|
if (!IsValidDestination(dest)) {
|
2016-08-17 09:08:25 +02:00
|
|
|
std::ostringstream ostr;
|
2018-09-28 09:56:17 +02:00
|
|
|
ostr << "CSuperblock::ParsePaymentSchedule -- Invalid Dash Address : " << vecParsed1[i];
|
2016-10-17 20:54:28 +02:00
|
|
|
LogPrintf("%s\n", ostr.str());
|
2016-08-17 09:08:25 +02:00
|
|
|
throw std::runtime_error(ostr.str());
|
|
|
|
}
|
2022-08-17 15:45:04 +02:00
|
|
|
|
2016-08-17 09:08:25 +02:00
|
|
|
CAmount nAmount = ParsePaymentAmount(vecParsed2[i]);
|
|
|
|
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblock::ParsePaymentSchedule -- i = %d, amount string = %s, nAmount = %lld\n", i, vecParsed2[i], nAmount);
|
2016-08-17 09:08:25 +02:00
|
|
|
|
Merge #11117: Prepare for non-Base58 addresses (#3294)
* Merge #11117: Prepare for non-Base58 addresses
864cd2787 Move CBitcoinAddress to base58.cpp (Pieter Wuille)
5c8ff0d44 Introduce wrappers around CBitcoinAddress (Pieter Wuille)
Pull request description:
This patch removes the need for the intermediary Base58 type `CBitcoinAddress`, by providing {`Encode`,`Decode`,`IsValid`}`Destination` functions that directly operate on the conversion between `std::string`s and `CTxDestination`.
As a side, it also fixes a number of indentation issues, and removes probably several unnecessary implicit `CTxDestination`<->`CBitcoinAddress` conversions.
This change is far from complete. In follow-ups I'd like to:
* Split off the specific address and key encoding logic from base58.h, and move it to a address.h or so.
* Replace `CTxDestination` with a non-`boost::variant` version (which can be more efficient as `boost::variant` allocates everything on the heap, and remove the need for `boost::get<...>` and `IsValidDestination` calls everywhere).
* Do the same for `CBitcoinSecret`, `CBitcoinExtKey`, and `CBitcoinExtPubKey`.
However, I've tried to keep this patch to be minimally invasive, but still enough to support non-Base58 addresses. Perhaps a smaller patch is possible to hack Bech32 support into `CBitcoinAddress`, but I would consider that a move in the wrong direction.
Tree-SHA512: c2c77ffb57caeadf2429b1c2562ce60e8c7be8aa9f8e51b591f354b6b441162625b2efe14c023a1ae485cf2ed417263afa35c892891dfaa7844e7fbabccab85e
* CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* fix CBitcoinAddress GetKeyID check
Signed-off-by: Pasta <pasta@dashboost.org>
* fix providertx.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* hopefully fix governance-classes.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-validators.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-classes.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* fix governance-classes.h
Signed-off-by: Pasta <pasta@dashboost.org>
* DecodeTransaction -> DecodeDestination, fix governance-validators.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* More fixes for 3294
* Move GetIndexKey into rpc/misc.cpp near getAddressesFromParams
No need to have it in base58.cpp anymore as this is only used in getAddressesFromParams
Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Alexander Block <ablock84@gmail.com>
2020-01-22 11:35:04 +01:00
|
|
|
CGovernancePayment payment(dest, nAmount);
|
2018-09-28 09:56:17 +02:00
|
|
|
if (payment.IsValid()) {
|
2016-08-17 09:08:25 +02:00
|
|
|
vecPayments.push_back(payment);
|
2018-09-28 09:56:17 +02:00
|
|
|
} else {
|
2016-10-17 20:54:28 +02:00
|
|
|
vecPayments.clear();
|
|
|
|
std::ostringstream ostr;
|
Merge #11117: Prepare for non-Base58 addresses (#3294)
* Merge #11117: Prepare for non-Base58 addresses
864cd2787 Move CBitcoinAddress to base58.cpp (Pieter Wuille)
5c8ff0d44 Introduce wrappers around CBitcoinAddress (Pieter Wuille)
Pull request description:
This patch removes the need for the intermediary Base58 type `CBitcoinAddress`, by providing {`Encode`,`Decode`,`IsValid`}`Destination` functions that directly operate on the conversion between `std::string`s and `CTxDestination`.
As a side, it also fixes a number of indentation issues, and removes probably several unnecessary implicit `CTxDestination`<->`CBitcoinAddress` conversions.
This change is far from complete. In follow-ups I'd like to:
* Split off the specific address and key encoding logic from base58.h, and move it to a address.h or so.
* Replace `CTxDestination` with a non-`boost::variant` version (which can be more efficient as `boost::variant` allocates everything on the heap, and remove the need for `boost::get<...>` and `IsValidDestination` calls everywhere).
* Do the same for `CBitcoinSecret`, `CBitcoinExtKey`, and `CBitcoinExtPubKey`.
However, I've tried to keep this patch to be minimally invasive, but still enough to support non-Base58 addresses. Perhaps a smaller patch is possible to hack Bech32 support into `CBitcoinAddress`, but I would consider that a move in the wrong direction.
Tree-SHA512: c2c77ffb57caeadf2429b1c2562ce60e8c7be8aa9f8e51b591f354b6b441162625b2efe14c023a1ae485cf2ed417263afa35c892891dfaa7844e7fbabccab85e
* CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* fix CBitcoinAddress GetKeyID check
Signed-off-by: Pasta <pasta@dashboost.org>
* fix providertx.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* hopefully fix governance-classes.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-validators.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-classes.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* fix governance-classes.h
Signed-off-by: Pasta <pasta@dashboost.org>
* DecodeTransaction -> DecodeDestination, fix governance-validators.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* More fixes for 3294
* Move GetIndexKey into rpc/misc.cpp near getAddressesFromParams
No need to have it in base58.cpp anymore as this is only used in getAddressesFromParams
Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Alexander Block <ablock84@gmail.com>
2020-01-22 11:35:04 +01:00
|
|
|
ostr << "CSuperblock::ParsePaymentSchedule -- Invalid payment found: address = " << EncodeDestination(dest)
|
2016-10-17 20:54:28 +02:00
|
|
|
<< ", amount = " << nAmount;
|
|
|
|
LogPrintf("%s\n", ostr.str());
|
|
|
|
throw std::runtime_error(ostr.str());
|
|
|
|
}
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-22 03:41:40 +02:00
|
|
|
bool CSuperblock::GetPayment(int nPaymentIndex, CGovernancePayment& paymentRet)
|
|
|
|
{
|
2018-09-28 09:56:17 +02:00
|
|
|
if ((nPaymentIndex < 0) || (nPaymentIndex >= (int)vecPayments.size())) {
|
2016-08-22 03:41:40 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
paymentRet = vecPayments[nPaymentIndex];
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
CAmount CSuperblock::GetPaymentsTotalAmount()
|
|
|
|
{
|
|
|
|
CAmount nPaymentsTotalAmount = 0;
|
|
|
|
int nPayments = CountPayments();
|
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
for (int i = 0; i < nPayments; i++) {
|
2016-08-22 03:41:40 +02:00
|
|
|
nPaymentsTotalAmount += vecPayments[i].nAmount;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nPaymentsTotalAmount;
|
|
|
|
}
|
2016-08-17 09:08:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Is Transaction Valid
|
|
|
|
*
|
|
|
|
* - Does this transaction match the superblock?
|
|
|
|
*/
|
|
|
|
|
2016-08-22 03:41:40 +02:00
|
|
|
bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
2016-08-17 09:08:25 +02:00
|
|
|
{
|
|
|
|
// TODO : LOCK(cs);
|
|
|
|
// No reason for a lock here now since this method only accesses data
|
|
|
|
// internal to *this and since CSuperblock's are accessed only through
|
|
|
|
// shared pointers there's no way our object can get deleted while this
|
|
|
|
// code is running.
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!IsValidBlockHeight(nBlockHeight)) {
|
2016-08-22 03:41:40 +02:00
|
|
|
LogPrintf("CSuperblock::IsValid -- ERROR: Block invalid, incorrect block height\n");
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-09-12 09:40:00 +02:00
|
|
|
// CONFIGURE SUPERBLOCK OUTPUTS
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-08-19 13:53:49 +02:00
|
|
|
int nOutputs = txNew.vout.size();
|
|
|
|
int nPayments = CountPayments();
|
2018-08-12 17:27:09 +02:00
|
|
|
int nMinerAndMasternodePayments = nOutputs - nPayments;
|
2016-08-19 13:53:49 +02:00
|
|
|
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblock::IsValid -- nOutputs = %d, nPayments = %d, GetDataAsHexString = %s\n",
|
2022-08-26 23:52:53 +02:00
|
|
|
nOutputs, nPayments, GetGovernanceObject(*governance)->GetDataAsHexString());
|
2016-10-17 20:54:28 +02:00
|
|
|
|
2016-08-19 13:53:49 +02:00
|
|
|
// We require an exact match (including order) between the expected
|
2016-12-06 18:26:44 +01:00
|
|
|
// superblock payments and the payments actually in the block.
|
2016-08-19 13:53:49 +02:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (nMinerAndMasternodePayments < 0) {
|
2016-08-19 13:53:49 +02:00
|
|
|
// This means the block cannot have all the superblock payments
|
|
|
|
// so it is not valid.
|
2016-08-22 03:41:40 +02:00
|
|
|
// TODO: could that be that we just hit coinbase size limit?
|
|
|
|
LogPrintf("CSuperblock::IsValid -- ERROR: Block invalid, too few superblock payments\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// payments should not exceed limit
|
|
|
|
CAmount nPaymentsTotalAmount = GetPaymentsTotalAmount();
|
|
|
|
CAmount nPaymentsLimit = GetPaymentsLimit(nBlockHeight);
|
2018-09-28 09:56:17 +02:00
|
|
|
if (nPaymentsTotalAmount > nPaymentsLimit) {
|
2016-08-22 03:41:40 +02:00
|
|
|
LogPrintf("CSuperblock::IsValid -- ERROR: Block invalid, payments limit exceeded: payments %lld, limit %lld\n", nPaymentsTotalAmount, nPaymentsLimit);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-12 17:27:09 +02:00
|
|
|
// miner and masternodes should not get more than they would usually get
|
2016-08-22 03:41:40 +02:00
|
|
|
CAmount nBlockValue = txNew.GetValueOut();
|
2018-09-28 09:56:17 +02:00
|
|
|
if (nBlockValue > blockReward + nPaymentsTotalAmount) {
|
2016-08-22 03:41:40 +02:00
|
|
|
LogPrintf("CSuperblock::IsValid -- ERROR: Block invalid, block value limit exceeded: block %lld, limit %lld\n", nBlockValue, blockReward + nPaymentsTotalAmount);
|
2016-08-19 13:53:49 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-12-06 18:26:44 +01:00
|
|
|
int nVoutIndex = 0;
|
2018-09-28 09:56:17 +02:00
|
|
|
for (int i = 0; i < nPayments; i++) {
|
2016-08-17 09:08:25 +02:00
|
|
|
CGovernancePayment payment;
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!GetPayment(i, payment)) {
|
2016-08-19 13:53:49 +02:00
|
|
|
// This shouldn't happen so log a warning
|
2016-08-22 03:41:40 +02:00
|
|
|
LogPrintf("CSuperblock::IsValid -- WARNING: Failed to find payment: %d of %d total payments\n", i, nPayments);
|
2016-08-19 13:53:49 +02:00
|
|
|
continue;
|
|
|
|
}
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-12-06 18:26:44 +01:00
|
|
|
bool fPaymentMatch = false;
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-12-06 18:26:44 +01:00
|
|
|
for (int j = nVoutIndex; j < nOutputs; j++) {
|
|
|
|
// Find superblock payment
|
|
|
|
fPaymentMatch = ((payment.script == txNew.vout[j].scriptPubKey) &&
|
|
|
|
(payment.nAmount == txNew.vout[j].nValue));
|
|
|
|
|
|
|
|
if (fPaymentMatch) {
|
|
|
|
nVoutIndex = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
if (!fPaymentMatch) {
|
2016-12-06 18:26:44 +01:00
|
|
|
// Superblock payment not found!
|
2016-08-17 09:08:25 +02:00
|
|
|
|
Merge #11117: Prepare for non-Base58 addresses (#3294)
* Merge #11117: Prepare for non-Base58 addresses
864cd2787 Move CBitcoinAddress to base58.cpp (Pieter Wuille)
5c8ff0d44 Introduce wrappers around CBitcoinAddress (Pieter Wuille)
Pull request description:
This patch removes the need for the intermediary Base58 type `CBitcoinAddress`, by providing {`Encode`,`Decode`,`IsValid`}`Destination` functions that directly operate on the conversion between `std::string`s and `CTxDestination`.
As a side, it also fixes a number of indentation issues, and removes probably several unnecessary implicit `CTxDestination`<->`CBitcoinAddress` conversions.
This change is far from complete. In follow-ups I'd like to:
* Split off the specific address and key encoding logic from base58.h, and move it to a address.h or so.
* Replace `CTxDestination` with a non-`boost::variant` version (which can be more efficient as `boost::variant` allocates everything on the heap, and remove the need for `boost::get<...>` and `IsValidDestination` calls everywhere).
* Do the same for `CBitcoinSecret`, `CBitcoinExtKey`, and `CBitcoinExtPubKey`.
However, I've tried to keep this patch to be minimally invasive, but still enough to support non-Base58 addresses. Perhaps a smaller patch is possible to hack Bech32 support into `CBitcoinAddress`, but I would consider that a move in the wrong direction.
Tree-SHA512: c2c77ffb57caeadf2429b1c2562ce60e8c7be8aa9f8e51b591f354b6b441162625b2efe14c023a1ae485cf2ed417263afa35c892891dfaa7844e7fbabccab85e
* CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* more CBitcoinAddress -> EncodeDestination in providertx.h
Signed-off-by: Pasta <pasta@dashboost.org>
* fix CBitcoinAddress GetKeyID check
Signed-off-by: Pasta <pasta@dashboost.org>
* fix providertx.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* hopefully fix governance-classes.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-validators.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* partially fix governance-classes.cpp, unable to resolve "address.IsScript()"
Signed-off-by: Pasta <pasta@dashboost.org>
* fix governance-classes.h
Signed-off-by: Pasta <pasta@dashboost.org>
* DecodeTransaction -> DecodeDestination, fix governance-validators.cpp
Signed-off-by: Pasta <pasta@dashboost.org>
* More fixes for 3294
* Move GetIndexKey into rpc/misc.cpp near getAddressesFromParams
No need to have it in base58.cpp anymore as this is only used in getAddressesFromParams
Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Alexander Block <ablock84@gmail.com>
2020-01-22 11:35:04 +01:00
|
|
|
CTxDestination dest;
|
|
|
|
ExtractDestination(payment.script, dest);
|
|
|
|
LogPrintf("CSuperblock::IsValid -- ERROR: Block invalid: %d payment %d to %s not found\n", i, payment.nAmount, EncodeDestination(dest));
|
2016-08-17 09:08:25 +02:00
|
|
|
|
2016-08-19 13:53:49 +02:00
|
|
|
return false;
|
2016-08-17 09:08:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
bool CSuperblock::IsExpired(const CGovernanceManager& governanceManager) const
|
2018-02-12 19:35:10 +01:00
|
|
|
{
|
2021-01-26 04:31:31 +01:00
|
|
|
int nExpirationBlocks;
|
2023-03-23 16:06:06 +01:00
|
|
|
// Executed triggers are kept for another superblock cycle (approximately 1 month for mainnet).
|
|
|
|
// Other valid triggers are kept for ~1 day only (for mainnet, but no longer than a superblock cycle for other networks).
|
|
|
|
// Everything else is pruned after ~1h (for mainnet, but no longer than a superblock cycle for other networks).
|
2018-02-12 19:35:10 +01:00
|
|
|
switch (nStatus) {
|
2023-04-16 19:09:37 +02:00
|
|
|
case SeenObjectStatus::Executed:
|
2018-09-28 09:56:17 +02:00
|
|
|
nExpirationBlocks = Params().GetConsensus().nSuperblockCycle;
|
|
|
|
break;
|
2023-04-16 19:09:37 +02:00
|
|
|
case SeenObjectStatus::Valid:
|
2023-03-23 16:06:06 +01:00
|
|
|
nExpirationBlocks = std::min(576, Params().GetConsensus().nSuperblockCycle);
|
2018-09-28 09:56:17 +02:00
|
|
|
break;
|
|
|
|
default:
|
2023-03-23 16:06:06 +01:00
|
|
|
nExpirationBlocks = std::min(24, Params().GetConsensus().nSuperblockCycle);
|
2018-09-28 09:56:17 +02:00
|
|
|
break;
|
2018-02-12 19:35:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int nExpirationBlock = nBlockHeight + nExpirationBlocks;
|
|
|
|
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblock::IsExpired -- nBlockHeight = %d, nExpirationBlock = %d\n", nBlockHeight, nExpirationBlock);
|
2018-02-12 19:35:10 +01:00
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
if (governanceManager.GetCachedBlockHeight() > nExpirationBlock) {
|
2019-05-22 23:51:39 +02:00
|
|
|
LogPrint(BCLog::GOBJECT, "CSuperblock::IsExpired -- Outdated trigger found\n");
|
2019-08-23 20:03:05 +02:00
|
|
|
return true;
|
2018-02-12 19:35:10 +01:00
|
|
|
}
|
|
|
|
|
2019-08-23 20:03:05 +02:00
|
|
|
return false;
|
2018-02-12 19:35:10 +01:00
|
|
|
}
|
2021-04-23 00:32:03 +02:00
|
|
|
|
|
|
|
CGovernancePayment::CGovernancePayment(const CTxDestination& destIn, CAmount nAmountIn) :
|
|
|
|
fValid(false),
|
|
|
|
script(),
|
|
|
|
nAmount(0)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
script = GetScriptForDestination(destIn);
|
|
|
|
nAmount = nAmountIn;
|
|
|
|
fValid = true;
|
|
|
|
} catch (std::exception& e) {
|
|
|
|
LogPrintf("CGovernancePayment Payment not valid: destIn = %s, nAmountIn = %d, what = %s\n",
|
|
|
|
EncodeDestination(destIn), nAmountIn, e.what());
|
|
|
|
} catch (...) {
|
|
|
|
LogPrintf("CGovernancePayment Payment not valid: destIn = %s, nAmountIn = %d\n",
|
|
|
|
EncodeDestination(destIn), nAmountIn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|