mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
refactor: move CGoveranceManager code from classes.cpp to governace.cpp
There's only code move, no changes. For review use `git show --color-moved=dimmed-zebra`
This commit is contained in:
parent
350a5ca47c
commit
39f18ab154
@ -94,290 +94,6 @@ CAmount ParsePaymentAmount(const std::string& strAmount)
|
||||
return nAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Governance Object
|
||||
*/
|
||||
|
||||
bool CGovernanceManager::AddNewTrigger(uint256 nHash)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
// IF WE ALREADY HAVE THIS HASH, RETURN
|
||||
if (mapTrigger.count(nHash)) {
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Already have hash, nHash = %s, count = %d, size = %s\n",
|
||||
__func__, nHash.GetHex(), mapTrigger.count(nHash), mapTrigger.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
CSuperblock_sptr pSuperblock;
|
||||
try {
|
||||
auto pSuperblockTmp = std::make_shared<CSuperblock>(*this, nHash);
|
||||
pSuperblock = pSuperblockTmp;
|
||||
} catch (std::exception& e) {
|
||||
LogPrintf("CGovernanceManager::%s -- Error creating superblock: %s\n", __func__, e.what());
|
||||
return false;
|
||||
} catch (...) {
|
||||
LogPrintf("CGovernanceManager::%s -- Unknown Error creating superblock\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
pSuperblock->SetStatus(SeenObjectStatus::Valid);
|
||||
|
||||
mapTrigger.insert(std::make_pair(nHash, pSuperblock));
|
||||
|
||||
return !pSuperblock->IsExpired(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Clean And Remove
|
||||
*
|
||||
*/
|
||||
|
||||
void CGovernanceManager::CleanAndRemoveTriggers()
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
// Remove triggers that are invalid or expired
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- mapTrigger.size() = %d\n", __func__, mapTrigger.size());
|
||||
|
||||
auto it = mapTrigger.begin();
|
||||
while (it != mapTrigger.end()) {
|
||||
bool remove = false;
|
||||
CGovernanceObject* pObj = nullptr;
|
||||
const CSuperblock_sptr& pSuperblock = it->second;
|
||||
if (!pSuperblock) {
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- nullptr superblock\n", __func__);
|
||||
remove = true;
|
||||
} else {
|
||||
pObj = FindGovernanceObject(it->first);
|
||||
if (!pObj || pObj->GetObjectType() != GovernanceObject::TRIGGER) {
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Unknown or non-trigger superblock\n", __func__);
|
||||
pSuperblock->SetStatus(SeenObjectStatus::ErrorInvalid);
|
||||
}
|
||||
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- superblock status = %d\n", __func__, ToUnderlying(pSuperblock->GetStatus()));
|
||||
switch (pSuperblock->GetStatus()) {
|
||||
case SeenObjectStatus::ErrorInvalid:
|
||||
case SeenObjectStatus::Unknown:
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Unknown or invalid trigger found\n", __func__);
|
||||
remove = true;
|
||||
break;
|
||||
case SeenObjectStatus::Valid:
|
||||
case SeenObjectStatus::Executed: {
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Valid trigger found\n", __func__);
|
||||
if (pSuperblock->IsExpired(*this)) {
|
||||
// update corresponding object
|
||||
pObj->SetExpired();
|
||||
remove = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- %smarked for removal\n", __func__, remove ? "" : "NOT ");
|
||||
|
||||
if (remove) {
|
||||
std::string strDataAsPlainString = "nullptr";
|
||||
if (pObj) {
|
||||
strDataAsPlainString = pObj->GetDataAsPlainString();
|
||||
// mark corresponding object for deletion
|
||||
pObj->PrepareDeletion(GetTime<std::chrono::seconds>().count());
|
||||
}
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Removing trigger object %s\n", __func__, strDataAsPlainString);
|
||||
// delete the trigger
|
||||
mapTrigger.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Active Triggers
|
||||
*
|
||||
* - Look through triggers and scan for active ones
|
||||
* - Return the triggers in a list
|
||||
*/
|
||||
|
||||
std::vector<CSuperblock_sptr> CGovernanceManager::GetActiveTriggers() const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
std::vector<CSuperblock_sptr> vecResults;
|
||||
|
||||
// LOOK AT THESE OBJECTS AND COMPILE A VALID LIST OF TRIGGERS
|
||||
for (const auto& pair : mapTrigger) {
|
||||
const CGovernanceObject* pObj = FindConstGovernanceObject(pair.first);
|
||||
if (pObj) {
|
||||
vecResults.push_back(pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
return vecResults;
|
||||
}
|
||||
|
||||
bool CGovernanceManager::IsSuperblockTriggered(const CDeterministicMNList& tip_mn_list, int nBlockHeight)
|
||||
{
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- Start nBlockHeight = %d\n", nBlockHeight);
|
||||
if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOCK(cs);
|
||||
// GET ALL ACTIVE TRIGGERS
|
||||
std::vector<CSuperblock_sptr> vecTriggers = GetActiveTriggers();
|
||||
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- vecTriggers.size() = %d\n", vecTriggers.size());
|
||||
|
||||
for (const auto& pSuperblock : vecTriggers) {
|
||||
if (!pSuperblock) {
|
||||
LogPrintf("IsSuperblockTriggered -- Non-superblock found, continuing\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
CGovernanceObject* pObj = FindGovernanceObject(pSuperblock->GetGovernanceObjHash());
|
||||
if (!pObj) {
|
||||
LogPrintf("IsSuperblockTriggered -- pObj == nullptr, continuing\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- data = %s\n", pObj->GetDataAsPlainString());
|
||||
|
||||
// note : 12.1 - is epoch calculation correct?
|
||||
|
||||
if (nBlockHeight != pSuperblock->GetBlockHeight()) {
|
||||
LogPrint(BCLog::GOBJECT,
|
||||
"IsSuperblockTriggered -- block height doesn't match nBlockHeight = %d, blockStart = %d, "
|
||||
"continuing\n",
|
||||
nBlockHeight, pSuperblock->GetBlockHeight());
|
||||
continue;
|
||||
}
|
||||
|
||||
// MAKE SURE THIS TRIGGER IS ACTIVE VIA FUNDING CACHE FLAG
|
||||
|
||||
pObj->UpdateSentinelVariables(tip_mn_list);
|
||||
|
||||
if (pObj->IsSetCachedFunding()) {
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- fCacheFunding = true, returning true\n");
|
||||
return true;
|
||||
} else {
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- fCacheFunding = false, continuing\n");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CGovernanceManager::GetBestSuperblock(const CDeterministicMNList& tip_mn_list, CSuperblock_sptr& pSuperblockRet,
|
||||
int nBlockHeight) const
|
||||
{
|
||||
if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AssertLockHeld(cs);
|
||||
std::vector<CSuperblock_sptr> vecTriggers = GetActiveTriggers();
|
||||
int nYesCount = 0;
|
||||
|
||||
for (const auto& pSuperblock : vecTriggers) {
|
||||
if (!pSuperblock || nBlockHeight != pSuperblock->GetBlockHeight()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const CGovernanceObject* pObj = FindGovernanceObject(pSuperblock->GetGovernanceObjHash());
|
||||
if (!pObj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// DO WE HAVE A NEW WINNER?
|
||||
|
||||
int nTempYesCount = pObj->GetAbsoluteYesCount(tip_mn_list, VOTE_SIGNAL_FUNDING);
|
||||
if (nTempYesCount > nYesCount) {
|
||||
nYesCount = nTempYesCount;
|
||||
pSuperblockRet = pSuperblock;
|
||||
}
|
||||
}
|
||||
|
||||
return nYesCount > 0;
|
||||
}
|
||||
|
||||
bool CGovernanceManager::GetSuperblockPayments(const CDeterministicMNList& tip_mn_list, int nBlockHeight,
|
||||
std::vector<CTxOut>& voutSuperblockRet)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
// GET THE BEST SUPERBLOCK FOR THIS BLOCK HEIGHT
|
||||
|
||||
CSuperblock_sptr pSuperblock;
|
||||
if (!GetBestSuperblock(tip_mn_list, pSuperblock, nBlockHeight)) {
|
||||
LogPrint(BCLog::GOBJECT, "GetSuperblockPayments -- Can't find superblock for height %d\n", nBlockHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure it's empty, just in case
|
||||
voutSuperblockRet.clear();
|
||||
|
||||
// GET SUPERBLOCK OUTPUTS
|
||||
|
||||
// Superblock payments will be appended to the end of the coinbase vout vector
|
||||
|
||||
// TODO: How many payments can we add before things blow up?
|
||||
// Consider at least following limits:
|
||||
// - max coinbase tx size
|
||||
// - max "budget" available
|
||||
for (int i = 0; i < pSuperblock->CountPayments(); i++) {
|
||||
CGovernancePayment payment;
|
||||
if (pSuperblock->GetPayment(i, payment)) {
|
||||
// SET COINBASE OUTPUT TO SUPERBLOCK SETTING
|
||||
|
||||
CTxOut txout = CTxOut(payment.nAmount, payment.script);
|
||||
voutSuperblockRet.push_back(txout);
|
||||
|
||||
// PRINT NICE LOG OUTPUT FOR SUPERBLOCK PAYMENT
|
||||
|
||||
CTxDestination dest;
|
||||
ExtractDestination(payment.script, dest);
|
||||
|
||||
LogPrint(BCLog::GOBJECT, "GetSuperblockPayments -- NEW Superblock: output %d (addr %s, amount %d.%08d)\n",
|
||||
i, EncodeDestination(dest), payment.nAmount / COIN, payment.nAmount % COIN);
|
||||
} else {
|
||||
LogPrint(BCLog::GOBJECT, "GetSuperblockPayments -- Payment not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGovernanceManager::IsValidSuperblock(const CChain& active_chain, const CDeterministicMNList& tip_mn_list,
|
||||
const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
||||
{
|
||||
// GET BEST SUPERBLOCK, SHOULD MATCH
|
||||
LOCK(cs);
|
||||
|
||||
CSuperblock_sptr pSuperblock;
|
||||
if (GetBestSuperblock(tip_mn_list, pSuperblock, nBlockHeight)) {
|
||||
return pSuperblock->IsValid(*this, active_chain, txNew, nBlockHeight, blockReward);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGovernanceManager::ExecuteBestSuperblock(const CDeterministicMNList& tip_mn_list, int nBlockHeight)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
CSuperblock_sptr pSuperblock;
|
||||
if (GetBestSuperblock(tip_mn_list, pSuperblock, nBlockHeight)) {
|
||||
// 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();
|
||||
ResetVotedFundingTrigger();
|
||||
}
|
||||
}
|
||||
|
||||
CSuperblock::
|
||||
CSuperblock() :
|
||||
nGovObjHash(),
|
||||
|
@ -1634,6 +1634,293 @@ void CGovernanceManager::RemoveInvalidVotes()
|
||||
lastMNListForVotingKeys = std::make_shared<CDeterministicMNList>(tip_mn_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Governance Object
|
||||
*/
|
||||
|
||||
bool CGovernanceManager::AddNewTrigger(uint256 nHash)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
// IF WE ALREADY HAVE THIS HASH, RETURN
|
||||
if (mapTrigger.count(nHash)) {
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Already have hash, nHash = %s, count = %d, size = %s\n",
|
||||
__func__, nHash.GetHex(), mapTrigger.count(nHash), mapTrigger.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
CSuperblock_sptr pSuperblock;
|
||||
try {
|
||||
auto pSuperblockTmp = std::make_shared<CSuperblock>(*this, nHash);
|
||||
pSuperblock = pSuperblockTmp;
|
||||
} catch (std::exception& e) {
|
||||
LogPrintf("CGovernanceManager::%s -- Error creating superblock: %s\n", __func__, e.what());
|
||||
return false;
|
||||
} catch (...) {
|
||||
LogPrintf("CGovernanceManager::%s -- Unknown Error creating superblock\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
pSuperblock->SetStatus(SeenObjectStatus::Valid);
|
||||
|
||||
mapTrigger.insert(std::make_pair(nHash, pSuperblock));
|
||||
|
||||
return !pSuperblock->IsExpired(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Clean And Remove
|
||||
*
|
||||
*/
|
||||
|
||||
void CGovernanceManager::CleanAndRemoveTriggers()
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
// Remove triggers that are invalid or expired
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- mapTrigger.size() = %d\n", __func__, mapTrigger.size());
|
||||
|
||||
auto it = mapTrigger.begin();
|
||||
while (it != mapTrigger.end()) {
|
||||
bool remove = false;
|
||||
CGovernanceObject* pObj = nullptr;
|
||||
const CSuperblock_sptr& pSuperblock = it->second;
|
||||
if (!pSuperblock) {
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- nullptr superblock\n", __func__);
|
||||
remove = true;
|
||||
} else {
|
||||
pObj = FindGovernanceObject(it->first);
|
||||
if (!pObj || pObj->GetObjectType() != GovernanceObject::TRIGGER) {
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Unknown or non-trigger superblock\n", __func__);
|
||||
pSuperblock->SetStatus(SeenObjectStatus::ErrorInvalid);
|
||||
}
|
||||
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- superblock status = %d\n", __func__,
|
||||
ToUnderlying(pSuperblock->GetStatus()));
|
||||
switch (pSuperblock->GetStatus()) {
|
||||
case SeenObjectStatus::ErrorInvalid:
|
||||
case SeenObjectStatus::Unknown:
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Unknown or invalid trigger found\n", __func__);
|
||||
remove = true;
|
||||
break;
|
||||
case SeenObjectStatus::Valid:
|
||||
case SeenObjectStatus::Executed: {
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Valid trigger found\n", __func__);
|
||||
if (pSuperblock->IsExpired(*this)) {
|
||||
// update corresponding object
|
||||
pObj->SetExpired();
|
||||
remove = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- %smarked for removal\n", __func__, remove ? "" : "NOT ");
|
||||
|
||||
if (remove) {
|
||||
std::string strDataAsPlainString = "nullptr";
|
||||
if (pObj) {
|
||||
strDataAsPlainString = pObj->GetDataAsPlainString();
|
||||
// mark corresponding object for deletion
|
||||
pObj->PrepareDeletion(GetTime<std::chrono::seconds>().count());
|
||||
}
|
||||
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- Removing trigger object %s\n", __func__,
|
||||
strDataAsPlainString);
|
||||
// delete the trigger
|
||||
mapTrigger.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Active Triggers
|
||||
*
|
||||
* - Look through triggers and scan for active ones
|
||||
* - Return the triggers in a list
|
||||
*/
|
||||
|
||||
std::vector<CSuperblock_sptr> CGovernanceManager::GetActiveTriggers() const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
std::vector<CSuperblock_sptr> vecResults;
|
||||
|
||||
// LOOK AT THESE OBJECTS AND COMPILE A VALID LIST OF TRIGGERS
|
||||
for (const auto& pair : mapTrigger) {
|
||||
const CGovernanceObject* pObj = FindConstGovernanceObject(pair.first);
|
||||
if (pObj) {
|
||||
vecResults.push_back(pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
return vecResults;
|
||||
}
|
||||
|
||||
bool CGovernanceManager::IsSuperblockTriggered(const CDeterministicMNList& tip_mn_list, int nBlockHeight)
|
||||
{
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- Start nBlockHeight = %d\n", nBlockHeight);
|
||||
if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOCK(cs);
|
||||
// GET ALL ACTIVE TRIGGERS
|
||||
std::vector<CSuperblock_sptr> vecTriggers = GetActiveTriggers();
|
||||
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- vecTriggers.size() = %d\n", vecTriggers.size());
|
||||
|
||||
for (const auto& pSuperblock : vecTriggers) {
|
||||
if (!pSuperblock) {
|
||||
LogPrintf("IsSuperblockTriggered -- Non-superblock found, continuing\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
CGovernanceObject* pObj = FindGovernanceObject(pSuperblock->GetGovernanceObjHash());
|
||||
if (!pObj) {
|
||||
LogPrintf("IsSuperblockTriggered -- pObj == nullptr, continuing\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- data = %s\n", pObj->GetDataAsPlainString());
|
||||
|
||||
// note : 12.1 - is epoch calculation correct?
|
||||
|
||||
if (nBlockHeight != pSuperblock->GetBlockHeight()) {
|
||||
LogPrint(BCLog::GOBJECT, /* Continued */
|
||||
"IsSuperblockTriggered -- block height doesn't match nBlockHeight = %d, blockStart = %d, "
|
||||
"continuing\n",
|
||||
nBlockHeight, pSuperblock->GetBlockHeight());
|
||||
continue;
|
||||
}
|
||||
|
||||
// MAKE SURE THIS TRIGGER IS ACTIVE VIA FUNDING CACHE FLAG
|
||||
|
||||
pObj->UpdateSentinelVariables(tip_mn_list);
|
||||
|
||||
if (pObj->IsSetCachedFunding()) {
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- fCacheFunding = true, returning true\n");
|
||||
return true;
|
||||
} else {
|
||||
LogPrint(BCLog::GOBJECT, "IsSuperblockTriggered -- fCacheFunding = false, continuing\n");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CGovernanceManager::GetBestSuperblock(const CDeterministicMNList& tip_mn_list, CSuperblock_sptr& pSuperblockRet,
|
||||
int nBlockHeight)
|
||||
{
|
||||
if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AssertLockHeld(cs);
|
||||
std::vector<CSuperblock_sptr> vecTriggers = GetActiveTriggers();
|
||||
int nYesCount = 0;
|
||||
|
||||
for (const auto& pSuperblock : vecTriggers) {
|
||||
if (!pSuperblock || nBlockHeight != pSuperblock->GetBlockHeight()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const CGovernanceObject* pObj = FindGovernanceObject(pSuperblock->GetGovernanceObjHash());
|
||||
if (!pObj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// DO WE HAVE A NEW WINNER?
|
||||
|
||||
int nTempYesCount = pObj->GetAbsoluteYesCount(tip_mn_list, VOTE_SIGNAL_FUNDING);
|
||||
if (nTempYesCount > nYesCount) {
|
||||
nYesCount = nTempYesCount;
|
||||
pSuperblockRet = pSuperblock;
|
||||
}
|
||||
}
|
||||
|
||||
return nYesCount > 0;
|
||||
}
|
||||
|
||||
bool CGovernanceManager::GetSuperblockPayments(const CDeterministicMNList& tip_mn_list, int nBlockHeight,
|
||||
std::vector<CTxOut>& voutSuperblockRet)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
// GET THE BEST SUPERBLOCK FOR THIS BLOCK HEIGHT
|
||||
|
||||
CSuperblock_sptr pSuperblock;
|
||||
if (!GetBestSuperblock(tip_mn_list, pSuperblock, nBlockHeight)) {
|
||||
LogPrint(BCLog::GOBJECT, "GetSuperblockPayments -- Can't find superblock for height %d\n", nBlockHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure it's empty, just in case
|
||||
voutSuperblockRet.clear();
|
||||
|
||||
// GET SUPERBLOCK OUTPUTS
|
||||
|
||||
// Superblock payments will be appended to the end of the coinbase vout vector
|
||||
|
||||
// TODO: How many payments can we add before things blow up?
|
||||
// Consider at least following limits:
|
||||
// - max coinbase tx size
|
||||
// - max "budget" available
|
||||
for (int i = 0; i < pSuperblock->CountPayments(); i++) {
|
||||
CGovernancePayment payment;
|
||||
if (pSuperblock->GetPayment(i, payment)) {
|
||||
// SET COINBASE OUTPUT TO SUPERBLOCK SETTING
|
||||
|
||||
CTxOut txout = CTxOut(payment.nAmount, payment.script);
|
||||
voutSuperblockRet.push_back(txout);
|
||||
|
||||
// PRINT NICE LOG OUTPUT FOR SUPERBLOCK PAYMENT
|
||||
|
||||
CTxDestination dest;
|
||||
ExtractDestination(payment.script, dest);
|
||||
|
||||
LogPrint(BCLog::GOBJECT, "GetSuperblockPayments -- NEW Superblock: output %d (addr %s, amount %d.%08d)\n",
|
||||
i, EncodeDestination(dest), payment.nAmount / COIN, payment.nAmount % COIN);
|
||||
} else {
|
||||
LogPrint(BCLog::GOBJECT, "GetSuperblockPayments -- Payment not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGovernanceManager::IsValidSuperblock(const CChain& active_chain, const CDeterministicMNList& tip_mn_list,
|
||||
const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
||||
{
|
||||
// GET BEST SUPERBLOCK, SHOULD MATCH
|
||||
LOCK(cs);
|
||||
|
||||
CSuperblock_sptr pSuperblock;
|
||||
if (GetBestSuperblock(tip_mn_list, pSuperblock, nBlockHeight)) {
|
||||
return pSuperblock->IsValid(*this, active_chain, txNew, nBlockHeight, blockReward);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGovernanceManager::ExecuteBestSuperblock(const CDeterministicMNList& tip_mn_list, int nBlockHeight)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
CSuperblock_sptr pSuperblock;
|
||||
if (GetBestSuperblock(tip_mn_list, pSuperblock, nBlockHeight)) {
|
||||
// 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();
|
||||
ResetVotedFundingTrigger();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool AreSuperblocksEnabled(const CSporkManager& sporkman)
|
||||
{
|
||||
return sporkman.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED);
|
||||
|
Loading…
Reference in New Issue
Block a user