(trivial) governance cleanup (#1011)
* trivial governance cleanup: - spaces - names - no "using namespace std;" - few log and rpc messages adjusted - remove unused - use defined types - move few members to private * fixing after code review
This commit is contained in:
parent
1043252d43
commit
f5738c001f
@ -25,9 +25,6 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CNode;
|
||||
|
||||
// DECLARE GLOBAL VARIABLES FOR GOVERNANCE CLASSES
|
||||
CGovernanceTriggerManager triggerman;
|
||||
@ -62,14 +59,14 @@ CAmount ParsePaymentAmount(const std::string& strAmount)
|
||||
if (strAmount.empty()) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "ParsePaymentAmount: Amount is empty";
|
||||
throw runtime_error(ostr.str());
|
||||
throw std::runtime_error(ostr.str());
|
||||
}
|
||||
if(strAmount.size() > 20) {
|
||||
// String is much too long, the functions below impose stricter
|
||||
// requirements
|
||||
std::ostringstream ostr;
|
||||
ostr << "ParsePaymentAmount: Amount string too long";
|
||||
throw runtime_error(ostr.str());
|
||||
throw std::runtime_error(ostr.str());
|
||||
}
|
||||
// Make sure the string makes sense as an amount
|
||||
// Note: No spaces allowed
|
||||
@ -78,22 +75,22 @@ CAmount ParsePaymentAmount(const std::string& strAmount)
|
||||
if (pos != std::string::npos) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "ParsePaymentAmount: Amount string contains invalid character";
|
||||
throw runtime_error(ostr.str());
|
||||
throw std::runtime_error(ostr.str());
|
||||
}
|
||||
|
||||
pos = strAmount.find(".");
|
||||
if (pos == 0) {
|
||||
if (pos == 0) {
|
||||
// JSON doesn't allow values to start with a decimal point
|
||||
std::ostringstream ostr;
|
||||
ostr << "ParsePaymentAmount: Invalid amount string, leading decimal point not allowed";
|
||||
throw runtime_error(ostr.str());
|
||||
throw std::runtime_error(ostr.str());
|
||||
}
|
||||
|
||||
// Make sure there's no more than 1 decimal point
|
||||
if ((pos != std::string::npos) && (strAmount.find(".", pos+1) != std::string::npos)) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "ParsePaymentAmount: Invalid amount string, too many decimal points";
|
||||
throw runtime_error(ostr.str());
|
||||
throw std::runtime_error(ostr.str());
|
||||
}
|
||||
|
||||
// Note this code is taken from AmountFromValue in rpcserver.cpp
|
||||
@ -102,13 +99,13 @@ CAmount ParsePaymentAmount(const std::string& strAmount)
|
||||
nAmount = 0;
|
||||
std::ostringstream ostr;
|
||||
ostr << "ParsePaymentAmount: ParseFixedPoint failed for string: " << strAmount;
|
||||
throw runtime_error(ostr.str());
|
||||
throw std::runtime_error(ostr.str());
|
||||
}
|
||||
if (!MoneyRange(nAmount)) {
|
||||
nAmount = 0;
|
||||
std::ostringstream ostr;
|
||||
ostr << "ParsePaymentAmount: Invalid amount string, value outside of valid money range";
|
||||
throw runtime_error(ostr.str());
|
||||
throw std::runtime_error(ostr.str());
|
||||
}
|
||||
|
||||
DBG( cout << "ParsePaymentAmount Returning true nAmount = " << nAmount << endl; );
|
||||
@ -126,8 +123,8 @@ bool CGovernanceTriggerManager::AddNewTrigger(uint256 nHash)
|
||||
AssertLockHeld(governance.cs);
|
||||
|
||||
// IF WE ALREADY HAVE THIS HASH, RETURN
|
||||
if(mapTrigger.count(nHash)) {
|
||||
DBG(
|
||||
if(mapTrigger.count(nHash)) {
|
||||
DBG(
|
||||
cout << "CGovernanceTriggerManager::AddNewTrigger: Already have hash"
|
||||
<< ", nHash = " << nHash.GetHex()
|
||||
<< ", count = " << mapTrigger.count(nHash)
|
||||
@ -136,28 +133,28 @@ bool CGovernanceTriggerManager::AddNewTrigger(uint256 nHash)
|
||||
return false;
|
||||
}
|
||||
|
||||
CSuperblock_sptr superblock;
|
||||
CSuperblock_sptr pSuperblock;
|
||||
try {
|
||||
CSuperblock_sptr superblockTmp(new CSuperblock(nHash));
|
||||
superblock = superblockTmp;
|
||||
CSuperblock_sptr pSuperblockTmp(new CSuperblock(nHash));
|
||||
pSuperblock = pSuperblockTmp;
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
catch(std::exception& e) {
|
||||
DBG( cout << "CGovernanceTriggerManager::AddNewTrigger Error creating superblock"
|
||||
<< ", e.what() = " << e.what()
|
||||
<< endl; );
|
||||
LogPrintf("CGovernanceTriggerManager::AddNewTrigger: Error creating superblock: %s\n", e.what());
|
||||
LogPrintf("CGovernanceTriggerManager::AddNewTrigger -- Error creating superblock: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
catch(...) {
|
||||
catch(...) {
|
||||
LogPrintf("CGovernanceTriggerManager::AddNewTrigger: Unknown Error creating superblock\n");
|
||||
DBG( cout << "CGovernanceTriggerManager::AddNewTrigger Error creating superblock catchall" << endl; );
|
||||
return false;
|
||||
}
|
||||
|
||||
superblock->SetStatus(SEEN_OBJECT_IS_VALID);
|
||||
pSuperblock->SetStatus(SEEN_OBJECT_IS_VALID);
|
||||
|
||||
DBG( cout << "CGovernanceTriggerManager::AddNewTrigger: Inserting trigger" << endl; );
|
||||
mapTrigger.insert(make_pair(nHash, superblock));
|
||||
mapTrigger.insert(std::make_pair(nHash, pSuperblock));
|
||||
|
||||
DBG( cout << "CGovernanceTriggerManager::AddNewTrigger: End" << endl; );
|
||||
|
||||
@ -176,44 +173,43 @@ void CGovernanceTriggerManager::CleanAndRemove()
|
||||
AssertLockHeld(governance.cs);
|
||||
|
||||
// LOOK AT THESE OBJECTS AND COMPILE A VALID LIST OF TRIGGERS
|
||||
for(trigger_m_it it = mapTrigger.begin(); it != mapTrigger.end(); ++it) {
|
||||
for(trigger_m_it it = mapTrigger.begin(); it != mapTrigger.end(); ++it) {
|
||||
//int nNewStatus = -1;
|
||||
CGovernanceObject* pObj = governance.FindGovernanceObject((*it).first);
|
||||
if(!pObj) {
|
||||
if(!pObj) {
|
||||
continue;
|
||||
}
|
||||
CSuperblock_sptr& superblock = it->second;
|
||||
if(!superblock) {
|
||||
CSuperblock_sptr& pSuperblock = it->second;
|
||||
if(!pSuperblock) {
|
||||
continue;
|
||||
}
|
||||
// IF THIS ISN'T A TRIGGER, WHY ARE WE HERE?
|
||||
if(pObj->GetObjectType() != GOVERNANCE_OBJECT_TRIGGER) {
|
||||
superblock->SetStatus(SEEN_OBJECT_ERROR_INVALID);
|
||||
pSuperblock->SetStatus(SEEN_OBJECT_ERROR_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove triggers that are invalid or already executed
|
||||
DBG( cout << "CGovernanceTriggerManager::CleanAndRemove: mapTrigger.size() = " << mapTrigger.size() << endl; );
|
||||
trigger_m_it it = mapTrigger.begin();
|
||||
while(it != mapTrigger.end()) {
|
||||
while(it != mapTrigger.end()) {
|
||||
bool remove = false;
|
||||
CSuperblock_sptr& superblock = it->second;
|
||||
if(!superblock) {
|
||||
CSuperblock_sptr& pSuperblock = it->second;
|
||||
if(!pSuperblock) {
|
||||
DBG( cout << "CGovernanceTriggerManager::CleanAndRemove: NULL superblock marked for removal " << endl; );
|
||||
remove = true;
|
||||
}
|
||||
else {
|
||||
DBG( cout << "CGovernanceTriggerManager::CleanAndRemove: superblock status = " << superblock->GetStatus() << endl; );
|
||||
switch(superblock->GetStatus()) {
|
||||
} else {
|
||||
DBG( cout << "CGovernanceTriggerManager::CleanAndRemove: superblock status = " << pSuperblock->GetStatus() << endl; );
|
||||
switch(pSuperblock->GetStatus()) {
|
||||
case SEEN_OBJECT_ERROR_INVALID:
|
||||
case SEEN_OBJECT_UNKNOWN:
|
||||
remove = true;
|
||||
break;
|
||||
case SEEN_OBJECT_EXECUTED:
|
||||
{
|
||||
CGovernanceObject* govobj = superblock->GetGovernanceObject();
|
||||
if(govobj) {
|
||||
govobj->fExpired = true;
|
||||
CGovernanceObject* pgovobj = pSuperblock->GetGovernanceObject();
|
||||
if(pgovobj) {
|
||||
pgovobj->fExpired = true;
|
||||
}
|
||||
}
|
||||
remove = true;
|
||||
@ -222,13 +218,13 @@ void CGovernanceTriggerManager::CleanAndRemove()
|
||||
{
|
||||
// Rough approximation: 30 days per month * 576 blocks per day
|
||||
static const int nMonthlyBlocks = 30*576;
|
||||
int nTriggerBlock = superblock->GetBlockStart();
|
||||
int nTriggerBlock = pSuperblock->GetBlockStart();
|
||||
int nExpirationBlock = nTriggerBlock + nMonthlyBlocks;
|
||||
if(governance.GetCachedBlockHeight() > nExpirationBlock) {
|
||||
if(governance.GetCachedBlockHeight() > nExpirationBlock) {
|
||||
remove = true;
|
||||
CGovernanceObject* govobj = superblock->GetGovernanceObject();
|
||||
if(govobj) {
|
||||
govobj->fExpired = true;
|
||||
CGovernanceObject* pgovobj = pSuperblock->GetGovernanceObject();
|
||||
if(pgovobj) {
|
||||
pgovobj->fExpired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -237,15 +233,15 @@ void CGovernanceTriggerManager::CleanAndRemove()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(remove) {
|
||||
DBG(
|
||||
|
||||
if(remove) {
|
||||
DBG(
|
||||
string strdata = "NULL";
|
||||
CGovernanceObject* govobj = superblock->GetGovernanceObject();
|
||||
if(govobj) {
|
||||
strdata = govobj->GetDataAsString();
|
||||
CGovernanceObject* pgovobj = pSuperblock->GetGovernanceObject();
|
||||
if(pgovobj) {
|
||||
strdata = pgovobj->GetDataAsString();
|
||||
}
|
||||
cout << "CGovernanceTriggerManager::CleanAndRemove: Removing object: "
|
||||
cout << "CGovernanceTriggerManager::CleanAndRemove: Removing object: "
|
||||
<< strdata
|
||||
<< endl;
|
||||
);
|
||||
@ -309,36 +305,36 @@ bool CSuperblockManager::IsSuperblockTriggered(int nBlockHeight)
|
||||
|
||||
DBG( cout << "IsSuperblockTriggered Number triggers = " << vecTriggers.size() << endl; );
|
||||
|
||||
BOOST_FOREACH(CSuperblock_sptr superblock, vecTriggers)
|
||||
BOOST_FOREACH(CSuperblock_sptr pSuperblock, vecTriggers)
|
||||
{
|
||||
if(!superblock) {
|
||||
if(!pSuperblock) {
|
||||
DBG( cout << "IsSuperblockTriggered Not a superblock, continuing " << endl; );
|
||||
continue;
|
||||
}
|
||||
|
||||
CGovernanceObject* pObj = superblock->GetGovernanceObject();
|
||||
CGovernanceObject* pObj = pSuperblock->GetGovernanceObject();
|
||||
|
||||
if(!pObj) {
|
||||
if(!pObj) {
|
||||
DBG( cout << "IsSuperblockTriggered pObj is NULL, continuing" << endl; );
|
||||
continue;
|
||||
}
|
||||
|
||||
// note : 12.1 - is epoch calculation correct?
|
||||
|
||||
if(nBlockHeight != superblock->GetBlockStart()) {
|
||||
DBG( cout << "IsSuperblockTriggered Not the target block, continuing"
|
||||
if(nBlockHeight != pSuperblock->GetBlockStart()) {
|
||||
DBG( cout << "IsSuperblockTriggered Not the target block, continuing"
|
||||
<< ", nBlockHeight = " << nBlockHeight
|
||||
<< ", superblock->GetBlockStart() = " << superblock->GetBlockStart()
|
||||
<< ", superblock->GetBlockStart() = " << pSuperblock->GetBlockStart()
|
||||
<< endl; );
|
||||
continue;
|
||||
}
|
||||
|
||||
// MAKE SURE THIS TRIGGER IS ACTIVE VIA FUNDING CACHE FLAG
|
||||
|
||||
if(pObj->fCachedFunding) {
|
||||
if(pObj->fCachedFunding) {
|
||||
DBG( cout << "IsSuperblockTriggered returning true" << endl; );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG( cout << "IsSuperblockTriggered No fCachedFunding, continuing" << endl; );
|
||||
}
|
||||
@ -348,7 +344,7 @@ bool CSuperblockManager::IsSuperblockTriggered(int nBlockHeight)
|
||||
}
|
||||
|
||||
|
||||
bool CSuperblockManager::GetBestSuperblock(CSuperblock_sptr& pBlock, int nBlockHeight)
|
||||
bool CSuperblockManager::GetBestSuperblock(CSuperblock_sptr& pSuperblockRet, int nBlockHeight)
|
||||
{
|
||||
if(!CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
||||
return false;
|
||||
@ -358,20 +354,20 @@ bool CSuperblockManager::GetBestSuperblock(CSuperblock_sptr& pBlock, int nBlockH
|
||||
std::vector<CSuperblock_sptr> vecTriggers = triggerman.GetActiveTriggers();
|
||||
int nYesCount = 0;
|
||||
|
||||
BOOST_FOREACH(CSuperblock_sptr superblock, vecTriggers) {
|
||||
if(!superblock) {
|
||||
BOOST_FOREACH(CSuperblock_sptr pSuperblock, vecTriggers) {
|
||||
if(!pSuperblock) {
|
||||
DBG( cout << "GetBestSuperblock Not a superblock, continuing" << endl; );
|
||||
continue;
|
||||
}
|
||||
|
||||
CGovernanceObject* pObj = superblock->GetGovernanceObject();
|
||||
CGovernanceObject* pObj = pSuperblock->GetGovernanceObject();
|
||||
|
||||
if(!pObj) {
|
||||
if(!pObj) {
|
||||
DBG( cout << "GetBestSuperblock pObj is NULL, continuing" << endl; );
|
||||
continue;
|
||||
}
|
||||
|
||||
if(nBlockHeight != superblock->GetBlockStart()) {
|
||||
if(nBlockHeight != pSuperblock->GetBlockStart()) {
|
||||
DBG( cout << "GetBestSuperblock Not the target block, continuing" << endl; );
|
||||
continue;
|
||||
}
|
||||
@ -380,10 +376,10 @@ bool CSuperblockManager::GetBestSuperblock(CSuperblock_sptr& pBlock, int nBlockH
|
||||
|
||||
int nTempYesCount = pObj->GetAbsoluteYesCount(VOTE_SIGNAL_FUNDING);
|
||||
DBG( cout << "GetBestSuperblock nTempYesCount = " << nTempYesCount << endl; );
|
||||
if(nTempYesCount > nYesCount) {
|
||||
if(nTempYesCount > nYesCount) {
|
||||
nYesCount = nTempYesCount;
|
||||
pBlock = superblock;
|
||||
DBG( cout << "GetBestSuperblock Valid superblock found, pBlock set" << endl; );
|
||||
pSuperblockRet = pSuperblock;
|
||||
DBG( cout << "GetBestSuperblock Valid superblock found, pSuperblock set" << endl; );
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,9 +400,9 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl
|
||||
|
||||
// GET THE BEST SUPERBLOCK FOR THIS BLOCK HEIGHT
|
||||
|
||||
CSuperblock_sptr pBlock;
|
||||
if(!CSuperblockManager::GetBestSuperblock(pBlock, nBlockHeight)) {
|
||||
LogPrint("superblock", "CSuperblockManager::CreateSuperblock: Can't find superblock for height %d\n", nBlockHeight);
|
||||
CSuperblock_sptr pSuperblock;
|
||||
if(!CSuperblockManager::GetBestSuperblock(pSuperblock, nBlockHeight)) {
|
||||
LogPrint("superblock", "CSuperblockManager::CreateSuperblock -- Can't find superblock for height %d\n", nBlockHeight);
|
||||
DBG( cout << "CSuperblockManager::CreateSuperblock Failed to get superblock for height, returning" << endl; );
|
||||
return;
|
||||
}
|
||||
@ -417,16 +413,16 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl
|
||||
// CONFIGURE SUPERBLOCK OUTPUTS
|
||||
|
||||
// Superblock payments are appended to the end of the coinbase vout vector
|
||||
DBG( cout << "CSuperblockManager::CreateSuperblock Number payments: " << pBlock->CountPayments() << endl; );
|
||||
DBG( cout << "CSuperblockManager::CreateSuperblock Number payments: " << pSuperblock->CountPayments() << endl; );
|
||||
|
||||
// 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 < pBlock->CountPayments(); i++) {
|
||||
for(int i = 0; i < pSuperblock->CountPayments(); i++) {
|
||||
CGovernancePayment payment;
|
||||
DBG( cout << "CSuperblockManager::CreateSuperblock i = " << i << endl; );
|
||||
if(pBlock->GetPayment(i, payment)) {
|
||||
if(pSuperblock->GetPayment(i, payment)) {
|
||||
DBG( cout << "CSuperblockManager::CreateSuperblock Payment found " << endl; );
|
||||
// SET COINBASE OUTPUT TO SUPERBLOCK SETTING
|
||||
|
||||
@ -445,9 +441,8 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl
|
||||
DBG( cout << "CSuperblockManager::CreateSuperblock Before LogPrintf call, nAmount = " << payment.nAmount << endl; );
|
||||
LogPrintf("NEW Superblock : output %d (addr %s, amount %d)\n", i, address2.ToString(), payment.nAmount);
|
||||
DBG( cout << "CSuperblockManager::CreateSuperblock After LogPrintf call " << endl; );
|
||||
pBlock->SetExecuted();
|
||||
}
|
||||
else {
|
||||
pSuperblock->SetExecuted();
|
||||
} else {
|
||||
DBG( cout << "CSuperblockManager::CreateSuperblock Payment not found " << endl; );
|
||||
}
|
||||
}
|
||||
@ -484,26 +479,26 @@ CSuperblock(uint256& nHash)
|
||||
vecPayments()
|
||||
{
|
||||
DBG( cout << "CSuperblock Constructor Start" << endl; );
|
||||
|
||||
|
||||
CGovernanceObject* pGovObj = GetGovernanceObject();
|
||||
|
||||
|
||||
if(!pGovObj) {
|
||||
DBG( cout << "CSuperblock Constructor pGovObjIn is NULL, returning" << endl; );
|
||||
throw runtime_error("CSuperblock: Failed to find Governance Object");
|
||||
throw std::runtime_error("CSuperblock: Failed to find Governance Object");
|
||||
}
|
||||
|
||||
|
||||
DBG( cout << "CSuperblock Constructor pGovObj : "
|
||||
<< pGovObj->GetDataAsString()
|
||||
<< ", nObjectType = " << pGovObj->nObjectType
|
||||
<< endl; );
|
||||
|
||||
|
||||
if (pGovObj->GetObjectType() != GOVERNANCE_OBJECT_TRIGGER) {
|
||||
DBG( cout << "CSuperblock Constructor pHoObj not a trigger, returning" << endl; );
|
||||
throw runtime_error("CSuperblock: Governance Object not a trigger");
|
||||
throw std::runtime_error("CSuperblock: Governance Object not a trigger");
|
||||
}
|
||||
|
||||
UniValue obj = pGovObj->GetJSONObject();
|
||||
|
||||
|
||||
// FIRST WE GET THE START EPOCH, THE DATE WHICH THE PAYMENT SHALL OCCUR
|
||||
nEpochStart = obj["event_block_height"].get_int();
|
||||
|
||||
@ -511,7 +506,7 @@ CSuperblock(uint256& nHash)
|
||||
std::string strAddresses = obj["payment_addresses"].get_str();
|
||||
std::string strAmounts = obj["payment_amounts"].get_str();
|
||||
ParsePaymentSchedule(strAddresses, strAmounts);
|
||||
|
||||
|
||||
DBG( cout << "CSuperblock Constructor End" << endl; );
|
||||
}
|
||||
|
||||
@ -571,21 +566,21 @@ void CSuperblock::ParsePaymentSchedule(std::string& strPaymentAddresses, std::st
|
||||
|
||||
// LOOP THROUGH THE ADDRESSES/AMOUNTS AND CREATE PAYMENTS
|
||||
/*
|
||||
ADDRESSES = [ADDR1|2|3|4|5\6]
|
||||
AMOUNTS = [AMOUNT1|2|3|4|5\6]
|
||||
ADDRESSES = [ADDR1|2|3|4|5|6]
|
||||
AMOUNTS = [AMOUNT1|2|3|4|5|6]
|
||||
*/
|
||||
|
||||
DBG( cout << "CSuperblock::ParsePaymentSchedule vecParsed1.size() = " << vecParsed1.size() << endl; );
|
||||
|
||||
for (int i = 0; i < (int)vecParsed1.size(); i++) {
|
||||
CBitcoinAddress address(vecParsed1[i]);
|
||||
if (!address.IsValid()) {
|
||||
if (!address.IsValid()) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "CSuperblock::ParsePaymentSchedule Invalid Dash Address : " << vecParsed1[i];
|
||||
throw std::runtime_error(ostr.str());
|
||||
}
|
||||
|
||||
DBG( cout << "CSuperblock::ParsePaymentSchedule i = " << i
|
||||
DBG( cout << "CSuperblock::ParsePaymentSchedule i = " << i
|
||||
<< ", vecParsed2[i] = " << vecParsed2[i]
|
||||
<< endl; );
|
||||
|
||||
@ -645,7 +640,7 @@ bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount b
|
||||
|
||||
std::string strPayeesPossible = "";
|
||||
|
||||
// CONFIGURE SUPERBLOCK OUTPUTS
|
||||
// CONFIGURE SUPERBLOCK OUTPUTS
|
||||
|
||||
int nOutputs = txNew.vout.size();
|
||||
int nPayments = CountPayments();
|
||||
@ -719,17 +714,17 @@ std::string CSuperblockManager::GetRequiredPaymentsString(int nBlockHeight)
|
||||
|
||||
// GET BEST SUPERBLOCK
|
||||
|
||||
CSuperblock_sptr pBlock;
|
||||
if(!CSuperblockManager::GetBestSuperblock(pBlock, nBlockHeight)) {
|
||||
LogPrint("superblock", "CSuperblockManager::CreateSuperblock: Can't find superblock for height %d\n", nBlockHeight);
|
||||
CSuperblock_sptr pSuperblock;
|
||||
if(!GetBestSuperblock(pSuperblock, nBlockHeight)) {
|
||||
LogPrint("superblock", "CSuperblockManager::GetRequiredPaymentsString -- Can't find superblock for height %d\n", nBlockHeight);
|
||||
return "error";
|
||||
}
|
||||
|
||||
// LOOP THROUGH SUPERBLOCK PAYMENTS, CONFIGURE OUTPUT STRING
|
||||
// LOOP THROUGH SUPERBLOCK PAYMENTS, CONFIGURE OUTPUT STRING
|
||||
|
||||
for(int i = 0; i < pBlock->CountPayments(); i++) {
|
||||
for(int i = 0; i < pSuperblock->CountPayments(); i++) {
|
||||
CGovernancePayment payment;
|
||||
if(pBlock->GetPayment(i, payment)) {
|
||||
if(pSuperblock->GetPayment(i, payment)) {
|
||||
// PRINT NICE LOG OUTPUT FOR SUPERBLOCK PAYMENT
|
||||
|
||||
CTxDestination address1;
|
||||
|
@ -19,16 +19,15 @@
|
||||
#include "init.h"
|
||||
#include "governance.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define TRIGGER_UNKNOWN -1
|
||||
#define TRIGGER_SUPERBLOCK 1000
|
||||
|
||||
class CSuperblock;
|
||||
class CGovernanceTrigger;
|
||||
class CGovernanceTriggerManager;
|
||||
class CSuperblockManager;
|
||||
|
||||
static const int TRIGGER_UNKNOWN = -1;
|
||||
static const int TRIGGER_SUPERBLOCK = 1000;
|
||||
|
||||
typedef boost::shared_ptr<CSuperblock> CSuperblock_sptr;
|
||||
|
||||
// DECLARE GLOBAL VARIABLES FOR GOVERNANCE CLASSES
|
||||
@ -44,35 +43,24 @@ std::vector<std::string> SplitBy(std::string strCommand, std::string strDelimit)
|
||||
* - After triggers are activated and executed, they can be removed
|
||||
*/
|
||||
|
||||
CAmount ParsePaymentAmount(const std::string& strAmount);
|
||||
|
||||
class CGovernanceTriggerManager
|
||||
{
|
||||
friend class CSuperblockManager;
|
||||
friend class CGovernanceManager;
|
||||
|
||||
public: // Typedefs
|
||||
private:
|
||||
typedef std::map<uint256, CSuperblock_sptr> trigger_m_t;
|
||||
|
||||
typedef trigger_m_t::iterator trigger_m_it;
|
||||
|
||||
typedef trigger_m_t::const_iterator trigger_m_cit;
|
||||
|
||||
private:
|
||||
trigger_m_t mapTrigger;
|
||||
|
||||
public:
|
||||
CGovernanceTriggerManager()
|
||||
: mapTrigger()
|
||||
{}
|
||||
|
||||
private:
|
||||
std::vector<CSuperblock_sptr> GetActiveTriggers();
|
||||
|
||||
bool AddNewTrigger(uint256 nHash);
|
||||
|
||||
void CleanAndRemove();
|
||||
|
||||
public:
|
||||
CGovernanceTriggerManager() : mapTrigger() {}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -84,7 +72,7 @@ private:
|
||||
class CSuperblockManager
|
||||
{
|
||||
private:
|
||||
static bool GetBestSuperblock(CSuperblock_sptr& pBlock, int nBlockHeight);
|
||||
static bool GetBestSuperblock(CSuperblock_sptr& pSuperblockRet, int nBlockHeight);
|
||||
|
||||
public:
|
||||
|
||||
@ -103,28 +91,18 @@ public:
|
||||
|
||||
class CGovernancePayment
|
||||
{
|
||||
private:
|
||||
bool fValid;
|
||||
|
||||
public:
|
||||
CScript script;
|
||||
CAmount nAmount;
|
||||
bool fValid;
|
||||
|
||||
CGovernancePayment()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
script = CScript();
|
||||
nAmount = 0;
|
||||
fValid = false;
|
||||
}
|
||||
|
||||
bool IsValid()
|
||||
{
|
||||
return fValid;
|
||||
}
|
||||
|
||||
CGovernancePayment(CBitcoinAddress addrIn, CAmount nAmountIn)
|
||||
{
|
||||
try
|
||||
@ -136,6 +114,15 @@ public:
|
||||
SetNull(); //set fValid to false
|
||||
}
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
script = CScript();
|
||||
nAmount = 0;
|
||||
fValid = false;
|
||||
}
|
||||
|
||||
bool IsValid() { return fValid; }
|
||||
};
|
||||
|
||||
|
||||
@ -143,25 +130,21 @@ public:
|
||||
* Trigger : Superblock
|
||||
*
|
||||
* - Create payments on the network
|
||||
*
|
||||
* object structure:
|
||||
* {
|
||||
* "governance_object_id" : last_id,
|
||||
* "type" : govtypes.trigger,
|
||||
* "subtype" : "superblock",
|
||||
* "superblock_name" : superblock_name,
|
||||
* "start_epoch" : start_epoch,
|
||||
* "payment_addresses" : "addr1|addr2|addr3",
|
||||
* "payment_amounts" : "amount1|amount2|amount3"
|
||||
* }
|
||||
*/
|
||||
|
||||
class CSuperblock : public CGovernanceObject
|
||||
{
|
||||
|
||||
/*
|
||||
|
||||
object structure:
|
||||
{
|
||||
"governance_object_id" : last_id,
|
||||
"type" : govtypes.trigger,
|
||||
"subtype" : "superblock",
|
||||
"superblock_name" : superblock_name,
|
||||
"start_epoch" : start_epoch,
|
||||
"payment_addresses" : "addr1|addr2|addr3",
|
||||
"payment_amounts" : "amount1|amount2|amount3"
|
||||
}
|
||||
*/
|
||||
|
||||
private:
|
||||
uint256 nGovObjHash;
|
||||
|
||||
|
@ -193,7 +193,7 @@ vote_signal_enum_t CGovernanceVoting::ConvertVoteSignal(std::string strVoteSigna
|
||||
|
||||
// convert custom sentinel outcomes to integer and store
|
||||
try {
|
||||
int i = boost::lexical_cast<int>(strVoteSignal);
|
||||
int i = boost::lexical_cast<int>(strVoteSignal);
|
||||
if(i < VOTE_SIGNAL_CUSTOM1 || i > VOTE_SIGNAL_CUSTOM20) {
|
||||
eSignal = VOTE_SIGNAL_NONE;
|
||||
}
|
||||
@ -203,8 +203,8 @@ vote_signal_enum_t CGovernanceVoting::ConvertVoteSignal(std::string strVoteSigna
|
||||
}
|
||||
catch(std::exception const & e)
|
||||
{
|
||||
ostringstream ostr;
|
||||
ostr << "CGovernanceVote::ConvertVoteSignal: error : " << e.what() << endl;
|
||||
std::ostringstream ostr;
|
||||
ostr << "CGovernanceVote::ConvertVoteSignal: error : " << e.what() << std::endl;
|
||||
LogPrintf(ostr.str().c_str());
|
||||
}
|
||||
|
||||
@ -265,28 +265,28 @@ bool CGovernanceVote::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
|
||||
bool CGovernanceVote::IsValid(bool fSignatureCheck)
|
||||
{
|
||||
if(nTime > GetTime() + (60*60)){
|
||||
LogPrint("gobject", "CGovernanceVote::IsValid() - vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", GetHash().ToString(), nTime, GetTime() + (60*60));
|
||||
LogPrint("gobject", "CGovernanceVote::IsValid -- vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", GetHash().ToString(), nTime, GetTime() + (60*60));
|
||||
return false;
|
||||
}
|
||||
|
||||
// support up to 50 actions (implemented in sentinel)
|
||||
if(nVoteSignal > 50)
|
||||
{
|
||||
LogPrint("gobject", "CGovernanceVote::IsValid() - Client attempted to vote on invalid action(%d) - %s\n", nVoteSignal, GetHash().ToString());
|
||||
LogPrint("gobject", "CGovernanceVote::IsValid -- Client attempted to vote on invalid signal(%d) - %s\n", nVoteSignal, GetHash().ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0=none, 1=yes, 2=no, 3=abstain. Beyond that reject votes
|
||||
if(nVoteOutcome > 3)
|
||||
{
|
||||
LogPrint("gobject", "CGovernanceVote::IsValid() - Client attempted to vote on invalid outcome(%d) - %s\n", nVoteSignal, GetHash().ToString());
|
||||
return false;
|
||||
LogPrint("gobject", "CGovernanceVote::IsValid -- Client attempted to vote on invalid outcome(%d) - %s\n", nVoteSignal, GetHash().ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
CMasternode* pmn = mnodeman.Find(vinMasternode);
|
||||
if(pmn == NULL)
|
||||
{
|
||||
LogPrint("gobject", "CGovernanceVote::IsValid() - Unknown Masternode - %s\n", vinMasternode.ToString());
|
||||
LogPrint("gobject", "CGovernanceVote::IsValid -- Unknown Masternode - %s\n", vinMasternode.prevout.ToStringShort());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ enum vote_signal_enum_t {
|
||||
VOTE_SIGNAL_NOOP9 = 13,
|
||||
VOTE_SIGNAL_NOOP10 = 14,
|
||||
VOTE_SIGNAL_NOOP11 = 15,
|
||||
VOTE_SIGNAL_CUSTOM1 = 16, // SENTINEL CUSTOM ACTIONS
|
||||
VOTE_SIGNAL_CUSTOM1 = 16, // SENTINEL CUSTOM ACTIONS
|
||||
VOTE_SIGNAL_CUSTOM2 = 17, // 16-35
|
||||
VOTE_SIGNAL_CUSTOM3 = 18,
|
||||
VOTE_SIGNAL_CUSTOM4 = 19,
|
||||
@ -157,25 +157,25 @@ public:
|
||||
*
|
||||
* GET HASH WITH DETERMINISTIC VALUE OF MASTERNODE-VIN/PARENT-HASH/VOTE-SIGNAL
|
||||
*
|
||||
* This hash collides with previous masternode votes when they update their votes on governance objects.
|
||||
* With 12.1 there's various types of votes (funding, valid, delete, etc), so this is the deterministic hash
|
||||
* This hash collides with previous masternode votes when they update their votes on governance objects.
|
||||
* With 12.1 there's various types of votes (funding, valid, delete, etc), so this is the deterministic hash
|
||||
* that will collide with the previous vote and allow the system to update.
|
||||
*
|
||||
*
|
||||
* --
|
||||
*
|
||||
* We do not include an outcome, because that can change when a masternode updates their vote from yes to no
|
||||
* on funding a specific project for example.
|
||||
* on funding a specific project for example.
|
||||
* We do not include a time because it will be updated each time the vote is updated, changing the hash
|
||||
*/
|
||||
uint256 GetTypeHash() const
|
||||
{
|
||||
{
|
||||
// CALCULATE HOW TO STORE VOTE IN governance.mapVotes
|
||||
|
||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||
ss << vinMasternode;
|
||||
ss << nParentHash;
|
||||
ss << nVoteSignal;
|
||||
// -- no outcome
|
||||
// -- no outcome
|
||||
// -- timeless
|
||||
return ss.GetHash();
|
||||
}
|
||||
@ -195,7 +195,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* 12.1.1 - CGovernanceVoteManager
|
||||
* -------------------------------
|
||||
*
|
||||
@ -206,7 +206,7 @@ public:
|
||||
- load serialized files from filesystem if needed
|
||||
- calc answer
|
||||
- return result
|
||||
|
||||
|
||||
CacheUnused():
|
||||
- Cache votes if lastused > 12h/24/48/etc
|
||||
|
||||
|
@ -20,9 +20,6 @@
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <univalue.h>
|
||||
|
||||
class CNode;
|
||||
class CBudgetVote;
|
||||
|
||||
CGovernanceManager governance;
|
||||
|
||||
std::map<uint256, int64_t> mapAskedForGovernanceObject;
|
||||
@ -43,40 +40,30 @@ CGovernanceManager::CGovernanceManager()
|
||||
{}
|
||||
|
||||
// Accessors for thread-safe access to maps
|
||||
bool CGovernanceManager::HaveObjectForHash(uint256 nHash) {
|
||||
bool CGovernanceManager::HaveObjectForHash(uint256 nHash) {
|
||||
LOCK(cs);
|
||||
return (mapObjects.count(nHash) == 1);
|
||||
}
|
||||
|
||||
bool CGovernanceManager::HaveVoteForHash(uint256 nHash) {
|
||||
bool CGovernanceManager::HaveVoteForHash(uint256 nHash) {
|
||||
LOCK(cs);
|
||||
return (mapVotesByHash.count(nHash) == 1);
|
||||
}
|
||||
|
||||
// int CGovernanceManager::GetVoteCountByHash(uint256 nHash) {
|
||||
// int count = 0;
|
||||
// LOCK(cs);
|
||||
// count_m_cit it = mapVotesByHash.find(nHash);
|
||||
// if (it != mapVotesByHash.end()) {
|
||||
// count = it->second;
|
||||
// }
|
||||
// return count;
|
||||
// }
|
||||
|
||||
bool CGovernanceManager::SerializeObjectForHash(uint256 nHash, CDataStream& ss) {
|
||||
bool CGovernanceManager::SerializeObjectForHash(uint256 nHash, CDataStream& ss) {
|
||||
LOCK(cs);
|
||||
object_m_it it = mapObjects.find(nHash);
|
||||
if (it == mapObjects.end()) {
|
||||
if (it == mapObjects.end()) {
|
||||
return false;
|
||||
}
|
||||
ss << it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGovernanceManager::SerializeVoteForHash(uint256 nHash, CDataStream& ss) {
|
||||
bool CGovernanceManager::SerializeVoteForHash(uint256 nHash, CDataStream& ss) {
|
||||
LOCK(cs);
|
||||
vote_m_it it = mapVotesByHash.find(nHash);
|
||||
if (it == mapVotesByHash.end()) {
|
||||
if (it == mapVotesByHash.end()) {
|
||||
return false;
|
||||
}
|
||||
ss << it->second;
|
||||
@ -115,7 +102,9 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
||||
if (strCommand == NetMsgType::MNGOVERNANCESYNC)
|
||||
{
|
||||
|
||||
// ignore such request until we are fully synced
|
||||
// Ignore such requests until we are fully synced.
|
||||
// We could start processing this after masternode list is synced
|
||||
// but this is a heavy one so it's better to finish sync first.
|
||||
if (!masternodeSync.IsSynced()) return;
|
||||
|
||||
uint256 nProp;
|
||||
@ -135,10 +124,9 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
||||
}
|
||||
}
|
||||
|
||||
// ask for a specific govobj and it's votes
|
||||
Sync(pfrom, nProp);
|
||||
LogPrint("gobject", "syncing governance objects to our peer at %s\n", pfrom->addr.ToString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
// A NEW GOVERNANCE OBJECT HAS ARRIVED
|
||||
@ -167,14 +155,14 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
||||
return;
|
||||
}
|
||||
|
||||
// CHECK OBJECT AGAINST LOCAL BLOCKCHAIN
|
||||
// CHECK OBJECT AGAINST LOCAL BLOCKCHAIN
|
||||
|
||||
if(!govobj.IsValidLocally(pCurrentBlockIndex, strError, true)) {
|
||||
mapSeenGovernanceObjects.insert(make_pair(govobj.GetHash(), SEEN_OBJECT_ERROR_INVALID));
|
||||
mapSeenGovernanceObjects.insert(std::make_pair(govobj.GetHash(), SEEN_OBJECT_ERROR_INVALID));
|
||||
LogPrintf("Governance object is invalid - %s\n", strError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// UPDATE CACHED VARIABLES FOR THIS OBJECT AND ADD IT TO OUR MANANGED DATA
|
||||
|
||||
{
|
||||
@ -230,10 +218,10 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
||||
if(masternodeSync.IsSynced()) Misbehaving(pfrom->GetId(), 20);
|
||||
// it could just be a non-synced masternode
|
||||
mnodeman.AskForMN(pfrom, vote.GetVinMasternode());
|
||||
mapSeenVotes.insert(make_pair(vote.GetHash(), SEEN_OBJECT_ERROR_INVALID));
|
||||
mapSeenVotes.insert(std::make_pair(vote.GetHash(), SEEN_OBJECT_ERROR_INVALID));
|
||||
return;
|
||||
} else {
|
||||
mapSeenVotes.insert(make_pair(vote.GetHash(), SEEN_OBJECT_IS_VALID));
|
||||
mapSeenVotes.insert(std::make_pair(vote.GetHash(), SEEN_OBJECT_IS_VALID));
|
||||
}
|
||||
|
||||
// IF EVERYTHING CHECKS OUT, UPDATE THE GOVERNANCE MANAGER
|
||||
@ -255,7 +243,7 @@ void CGovernanceManager::CheckOrphanVotes()
|
||||
LOCK(cs);
|
||||
|
||||
std::string strError = "";
|
||||
std::map<uint256, CGovernanceVote>::iterator it1 = mapOrphanVotes.begin();
|
||||
vote_m_it it1 = mapOrphanVotes.begin();
|
||||
while(it1 != mapOrphanVotes.end()){
|
||||
if(AddOrUpdateVote(((*it1).second), NULL, strError)){
|
||||
LogPrintf("CGovernanceManager::CheckOrphanVotes - Governance object is known, activating and removing orphan vote\n");
|
||||
@ -288,9 +276,7 @@ bool CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj)
|
||||
}
|
||||
|
||||
// INSERT INTO OUR GOVERNANCE OBJECT MEMORY
|
||||
{
|
||||
mapObjects.insert(make_pair(govobj.GetHash(), govobj));
|
||||
}
|
||||
mapObjects.insert(std::make_pair(govobj.GetHash(), govobj));
|
||||
|
||||
// SHOULD WE ADD THIS OBJECT TO ANY OTHER MANANGERS?
|
||||
|
||||
@ -323,39 +309,36 @@ void CGovernanceManager::UpdateCachesAndClean()
|
||||
|
||||
// UPDATE CACHE FOR EACH OBJECT THAT IS FLAGGED DIRTYCACHE=TRUE
|
||||
|
||||
std::map<uint256, CGovernanceObject>::iterator it = mapObjects.begin();
|
||||
object_m_it it = mapObjects.begin();
|
||||
|
||||
std::map<uint256, int> mapDirtyObjects;
|
||||
count_m_t mapDirtyObjects;
|
||||
|
||||
// Clean up any expired or invalid triggers
|
||||
triggerman.CleanAndRemove();
|
||||
|
||||
while(it != mapObjects.end())
|
||||
{
|
||||
{
|
||||
CGovernanceObject* pObj = &((*it).second);
|
||||
|
||||
if(!pObj) {
|
||||
if(!pObj) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
// IF CACHE IS NOT DIRTY, WHY DO THIS?
|
||||
if(pObj->fDirtyCache) {
|
||||
mapDirtyObjects.insert(make_pair((*it).first, 1));
|
||||
|
||||
if(pObj->fDirtyCache) {
|
||||
mapDirtyObjects.insert(std::make_pair((*it).first, 1));
|
||||
|
||||
// UPDATE LOCAL VALIDITY AGAINST CRYPTO DATA
|
||||
|
||||
pObj->UpdateLocalValidity(pCurrentBlockIndex);
|
||||
|
||||
|
||||
// UPDATE SENTINEL SIGNALING VARIABLES
|
||||
|
||||
pObj->UpdateSentinelVariables(pCurrentBlockIndex);
|
||||
}
|
||||
|
||||
// IF DELETE=TRUE, THEN CLEAN THE MESS UP!
|
||||
|
||||
if(pObj->fCachedDelete || pObj->fExpired)
|
||||
{
|
||||
if(pObj->fCachedDelete || pObj->fExpired) {
|
||||
LogPrintf("UpdateCachesAndClean --- erase obj %s\n", (*it).first.ToString());
|
||||
mapObjects.erase(it++);
|
||||
} else {
|
||||
@ -388,10 +371,10 @@ CGovernanceObject *CGovernanceManager::FindGovernanceObject(const std::string &s
|
||||
int nYesCount = -99999;
|
||||
CGovernanceObject* pGovObj = NULL;
|
||||
|
||||
std::map<uint256, CGovernanceObject>::iterator it = mapObjects.begin();
|
||||
while(it != mapObjects.end()){
|
||||
object_m_it it = mapObjects.begin();
|
||||
while(it != mapObjects.end()) {
|
||||
int nGovObjYesCount = pGovObj->GetYesCount(VOTE_SIGNAL_FUNDING);
|
||||
if((*it).second.strName == strName && nGovObjYesCount > nYesCount){
|
||||
if((*it).second.strName == strName && nGovObjYesCount > nYesCount) {
|
||||
nYesCount = nGovObjYesCount;
|
||||
pGovObj = &((*it).second);
|
||||
}
|
||||
@ -419,13 +402,12 @@ std::vector<CGovernanceVote*> CGovernanceManager::GetMatchingVotes(const uint256
|
||||
|
||||
// LOOP THROUGH ALL VOTES AND FIND THOSE MATCHING USER HASH
|
||||
|
||||
std::map<uint256, CGovernanceVote>::iterator it2 = mapVotesByHash.begin();
|
||||
while(it2 != mapVotesByHash.end()){
|
||||
if((*it2).second.GetParentHash() == nParentHash)
|
||||
{
|
||||
vote_m_it it2 = mapVotesByHash.begin();
|
||||
while(it2 != mapVotesByHash.end()) {
|
||||
if((*it2).second.GetParentHash() == nParentHash) {
|
||||
vecResult.push_back(&(*it2).second);
|
||||
}
|
||||
*it2++;
|
||||
++it2;
|
||||
}
|
||||
|
||||
return vecResult;
|
||||
@ -437,7 +419,7 @@ std::vector<CGovernanceObject*> CGovernanceManager::GetAllNewerThan(int64_t nMor
|
||||
|
||||
std::vector<CGovernanceObject*> vGovObjs;
|
||||
|
||||
std::map<uint256, CGovernanceObject>::iterator it = mapObjects.begin();
|
||||
object_m_it it = mapObjects.begin();
|
||||
while(it != mapObjects.end())
|
||||
{
|
||||
// IF THIS OBJECT IS OLDER THAN TIME, CONTINUE
|
||||
@ -465,9 +447,9 @@ std::vector<CGovernanceObject*> CGovernanceManager::GetAllNewerThan(int64_t nMor
|
||||
//
|
||||
struct sortProposalsByVotes {
|
||||
bool operator()(const std::pair<CGovernanceObject*, int> &left, const std::pair<CGovernanceObject*, int> &right) {
|
||||
if( left.second != right.second)
|
||||
return (left.second > right.second);
|
||||
return (UintToArith256(left.first->nCollateralHash) > UintToArith256(right.first->nCollateralHash));
|
||||
if (left.second != right.second)
|
||||
return (left.second > right.second);
|
||||
return (UintToArith256(left.first->nCollateralHash) > UintToArith256(right.first->nCollateralHash));
|
||||
}
|
||||
};
|
||||
|
||||
@ -509,11 +491,11 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
|
||||
|
||||
{
|
||||
LOCK(cs);
|
||||
std::map<uint256, CGovernanceObject>::iterator it1 = mapObjects.begin();
|
||||
object_m_it it1 = mapObjects.begin();
|
||||
while(it1 != mapObjects.end()) {
|
||||
uint256 h = (*it1).first;
|
||||
|
||||
if((*it1).second.fCachedValid && ((nProp == uint256() || (h == nProp)))){
|
||||
if((*it1).second.fCachedValid && (nProp == uint256() || h == nProp)) {
|
||||
// Push the inventory budget proposal message over to the other client
|
||||
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT, h));
|
||||
nInvCount++;
|
||||
@ -523,7 +505,7 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
|
||||
|
||||
// SYNC OUR GOVERNANCE OBJECT VOTES WITH THEIR GOVERNANCE OBJECT VOTES
|
||||
|
||||
std::map<uint256, CGovernanceVote>::iterator it2 = mapVotesByHash.begin();
|
||||
vote_m_it it2 = mapVotesByHash.begin();
|
||||
while(it2 != mapVotesByHash.end()) {
|
||||
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT_VOTE, (*it2).first));
|
||||
nInvCount++;
|
||||
@ -553,15 +535,15 @@ bool CGovernanceManager::AddOrUpdateVote(const CGovernanceVote& vote, CNode* pfr
|
||||
LOCK(cs);
|
||||
if(!mapObjects.count(vote.GetParentHash())) {
|
||||
if(pfrom) {
|
||||
// only ask for missing items after our syncing process is complete --
|
||||
// only ask for missing items after our syncing process is complete --
|
||||
// otherwise we'll think a full sync succeeded when they return a result
|
||||
if(!masternodeSync.IsSynced()) return false;
|
||||
|
||||
|
||||
// ADD THE VOTE AS AN ORPHAN, TO BE USED UPON RECEIVAL OF THE PARENT OBJECT
|
||||
|
||||
|
||||
LogPrintf("CGovernanceManager::AddOrUpdateVote - Unknown object %d, asking for source\n", vote.GetParentHash().ToString());
|
||||
mapOrphanVotes[vote.GetParentHash()] = vote;
|
||||
|
||||
|
||||
// ASK FOR THIS VOTES PARENT SPECIFICALLY FROM THIS USER (THEY SHOULD HAVE IT, NO?)
|
||||
|
||||
if(!mapAskedForGovernanceObject.count(vote.GetParentHash())){
|
||||
@ -577,14 +559,14 @@ bool CGovernanceManager::AddOrUpdateVote(const CGovernanceVote& vote, CNode* pfr
|
||||
}
|
||||
|
||||
// Need to keep this out of the locked section
|
||||
if(syncparent) {
|
||||
if(syncparent) {
|
||||
pfrom->PushMessage(NetMsgType::MNGOVERNANCESYNC, votehash);
|
||||
}
|
||||
|
||||
// Reestablish lock
|
||||
LOCK(cs);
|
||||
// GET DETERMINISTIC HASH WHICH COLLIDES ON MASTERNODE-VIN/GOVOBJ-HASH/VOTE-SIGNAL
|
||||
|
||||
|
||||
uint256 nTypeHash = vote.GetTypeHash();
|
||||
uint256 nHash = vote.GetHash();
|
||||
|
||||
@ -606,7 +588,7 @@ bool CGovernanceManager::AddOrUpdateVote(const CGovernanceVote& vote, CNode* pfr
|
||||
|
||||
// UPDATE TO NEWEST VOTE
|
||||
{
|
||||
mapVotesByHash[nHash] = vote;
|
||||
mapVotesByHash[nHash] = vote;
|
||||
mapVotesByType[nTypeHash] = vote;
|
||||
}
|
||||
|
||||
@ -628,12 +610,12 @@ bool CGovernanceManager::MasternodeRateCheck(const CPubKey& pubkey)
|
||||
{
|
||||
LOCK(cs);
|
||||
count_m_it it = mapLastMasternodeTrigger.find(pubkey.GetHash());
|
||||
if(it == mapLastMasternodeTrigger.end()) {
|
||||
if(it == mapLastMasternodeTrigger.end()) {
|
||||
return true;
|
||||
}
|
||||
// Allow 1 trigger per mn per cycle, with a small fudge factor
|
||||
int mindiff = Params().GetConsensus().nSuperblockCycle - Params().GetConsensus().nSuperblockCycle / 10;
|
||||
if((nCachedBlockHeight - it->second) > mindiff) {
|
||||
if((nCachedBlockHeight - it->second) > mindiff) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -651,7 +633,7 @@ CGovernanceObject::CGovernanceObject()
|
||||
nHashParent = uint256(); //parent object, 0 is root
|
||||
nRevision = 0; //object revision in the system
|
||||
nCollateralHash = uint256(); //fee-tx
|
||||
|
||||
|
||||
// CACHING FOR VARIOUS FLAGS
|
||||
|
||||
fCachedFunding = false;
|
||||
@ -675,7 +657,7 @@ CGovernanceObject::CGovernanceObject(uint256 nHashParentIn, int nRevisionIn, std
|
||||
strName = strNameIn;
|
||||
nTime = nTimeIn;
|
||||
nCollateralHash = nCollateralHashIn; //fee-tx
|
||||
nObjectType = GOVERNANCE_OBJECT_UNKNOWN; // Avoid having an uninitialized variable
|
||||
nObjectType = GOVERNANCE_OBJECT_UNKNOWN; // Avoid having an uninitialized variable
|
||||
strData = strDataIn;
|
||||
|
||||
// CACHING FOR VARIOUS FLAGS
|
||||
@ -801,7 +783,7 @@ uint256 CGovernanceObject::GetHash()
|
||||
UniValue CGovernanceObject::GetJSONObject()
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
if(strData.empty()) {
|
||||
if(strData.empty()) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -818,9 +800,9 @@ UniValue CGovernanceObject::GetJSONObject()
|
||||
/**
|
||||
* LoadData
|
||||
* --------------------------------------------------------
|
||||
*
|
||||
* Attempt to load data from strData
|
||||
*
|
||||
*
|
||||
* Attempt to load data from strData
|
||||
*
|
||||
*/
|
||||
|
||||
void CGovernanceObject::LoadData()
|
||||
@ -828,7 +810,7 @@ void CGovernanceObject::LoadData()
|
||||
// todo : 12.1 - resolved
|
||||
//return;
|
||||
|
||||
if(strData.empty()) {
|
||||
if(strData.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -836,15 +818,15 @@ void CGovernanceObject::LoadData()
|
||||
// ATTEMPT TO LOAD JSON STRING FROM STRDATA
|
||||
UniValue objResult(UniValue::VOBJ);
|
||||
GetData(objResult);
|
||||
|
||||
|
||||
DBG( cout << "CGovernanceObject::LoadData strData = "
|
||||
<< GetDataAsString()
|
||||
<< endl; );
|
||||
|
||||
|
||||
UniValue obj = GetJSONObject();
|
||||
nObjectType = obj["type"].get_int();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
catch(std::exception& e) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "CGovernanceObject::LoadData Error parsing JSON"
|
||||
<< ", e.what() = " << e.what();
|
||||
@ -852,7 +834,7 @@ void CGovernanceObject::LoadData()
|
||||
LogPrintf( ostr.str().c_str() );
|
||||
return;
|
||||
}
|
||||
catch(...) {
|
||||
catch(...) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "CGovernanceObject::LoadData Unknown Error parsing JSON";
|
||||
DBG( cout << ostr.str() << endl; );
|
||||
@ -864,10 +846,10 @@ void CGovernanceObject::LoadData()
|
||||
/**
|
||||
* SetData - Example usage:
|
||||
* --------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* Data must be stored as an encoded hex/json string.
|
||||
* Other than the above requirement gov objects are data-agnostic.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
bool CGovernanceObject::SetData(std::string& strError, std::string strDataIn)
|
||||
@ -876,7 +858,7 @@ bool CGovernanceObject::SetData(std::string& strError, std::string strDataIn)
|
||||
|
||||
if(strDataIn.size() > 512*4)
|
||||
{
|
||||
// (assumption) this is equal to pythons len(strData) > 512*4, I think
|
||||
// (assumption) this is equal to pythons len(strData) > 512*4, I think
|
||||
strError = "Too big.";
|
||||
return false;
|
||||
}
|
||||
@ -888,9 +870,9 @@ bool CGovernanceObject::SetData(std::string& strError, std::string strDataIn)
|
||||
/**
|
||||
* GetData - Example usage:
|
||||
* --------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* Decode governance object data into UniValue(VOBJ)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
void CGovernanceObject::GetData(UniValue& objResult)
|
||||
@ -904,7 +886,7 @@ void CGovernanceObject::GetData(UniValue& objResult)
|
||||
/**
|
||||
* GetData - As
|
||||
* --------------------------------------------------------
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
std::string CGovernanceObject::GetDataAsHex()
|
||||
@ -914,8 +896,8 @@ std::string CGovernanceObject::GetDataAsHex()
|
||||
|
||||
std::string CGovernanceObject::GetDataAsString()
|
||||
{
|
||||
vector<unsigned char> v = ParseHex(strData);
|
||||
string s(v.begin(), v.end());
|
||||
std::vector<unsigned char> v = ParseHex(strData);
|
||||
std::string s(v.begin(), v.end());
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -1006,7 +988,7 @@ CAmount CGovernanceObject::GetMinCollateralFee()
|
||||
{
|
||||
CAmount nMinFee = 0;
|
||||
// Only 1 type has a fee for the moment but switch statement allows for future object types
|
||||
switch(nObjectType) {
|
||||
switch(nObjectType) {
|
||||
case GOVERNANCE_OBJECT_PROPOSAL:
|
||||
nMinFee = GOVERNANCE_PROPOSAL_FEE_TX;
|
||||
break;
|
||||
@ -1029,18 +1011,18 @@ bool CGovernanceObject::IsCollateralValid(std::string& strError)
|
||||
try {
|
||||
nMinFee = GetMinCollateralFee();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
catch(std::exception& e) {
|
||||
strError = e.what();
|
||||
LogPrintf("CGovernanceObject::IsCollateralValid ERROR An exception occurred - %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint256 nExpectedHash = GetHash();
|
||||
|
||||
CTransaction txCollateral;
|
||||
uint256 nBlockHash;
|
||||
|
||||
// RETRIEVE TRANSACTION IN QUESTION
|
||||
// RETRIEVE TRANSACTION IN QUESTION
|
||||
|
||||
if(!GetTransaction(nCollateralHash, txCollateral, Params().GetConsensus(), nBlockHash, true)){
|
||||
strError = strprintf("Can't find collateral tx %s", txCollateral.ToString());
|
||||
@ -1068,7 +1050,7 @@ bool CGovernanceObject::IsCollateralValid(std::string& strError)
|
||||
|
||||
bool foundOpReturn = false;
|
||||
BOOST_FOREACH(const CTxOut o, txCollateral.vout) {
|
||||
DBG( cout << "IsCollateralValid txout : " << o.ToString()
|
||||
DBG( cout << "IsCollateralValid txout : " << o.ToString()
|
||||
<< ", o.nValue = " << o.nValue
|
||||
<< ", o.scriptPubKey = " << ScriptToAsmStr( o.scriptPubKey, false )
|
||||
<< endl; );
|
||||
@ -1114,7 +1096,7 @@ bool CGovernanceObject::IsCollateralValid(std::string& strError)
|
||||
LogPrintf ("CGovernanceObject::IsCollateralValid - %s - %d confirmations\n", strError, nConfirmationsIn);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1160,7 +1142,7 @@ std::string CGovernanceManager::ToString() const
|
||||
info << "Governance Objects: " << (int)mapObjects.size() <<
|
||||
", Seen Budgets: " << (int)mapSeenGovernanceObjects.size() <<
|
||||
", Seen Budget Votes: " << (int)mapSeenVotes.size() <<
|
||||
", VoteByHash Count: " << (int)mapVotesByHash.size() <<
|
||||
", VoteByHash Count: " << (int)mapVotesByHash.size() <<
|
||||
", VoteByType Count: " << (int)mapVotesByType.size();
|
||||
|
||||
return info.str();
|
||||
@ -1170,7 +1152,7 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex *pindex)
|
||||
{
|
||||
// Note this gets called from ActivateBestChain without cs_main being held
|
||||
// so it should be safe to lock our mutex here without risking a deadlock
|
||||
// On the other hand it should be safe for us to access pindex without holding a lock
|
||||
// On the other hand it should be safe for us to access pindex without holding a lock
|
||||
// on cs_main because the CBlockIndex objects are dynamically allocated and
|
||||
// presumably never deleted.
|
||||
LOCK(cs);
|
||||
@ -1187,7 +1169,7 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex *pindex)
|
||||
int CGovernanceManager::CountMatchingVotes(CGovernanceObject& govobj, vote_signal_enum_t eVoteSignalIn, vote_outcome_enum_t eVoteOutcomeIn)
|
||||
{
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Count matching votes and return
|
||||
*
|
||||
*/
|
||||
@ -1219,7 +1201,7 @@ void CGovernanceObject::UpdateSentinelVariables(const CBlockIndex *pCurrentBlock
|
||||
// CALCULATE THE MINUMUM VOTE COUNT REQUIRED FOR FULL SIGNAL
|
||||
|
||||
// todo - 12.1 - should be set to `10` after governance vote compression is implemented
|
||||
int nAbsVoteReq = max(Params().GetConsensus().nGovernanceMinQuorum, nMnCount / 10);
|
||||
int nAbsVoteReq = std::max(Params().GetConsensus().nGovernanceMinQuorum, nMnCount / 10);
|
||||
// todo - 12.1 - Temporarily set to 1 for testing - reverted
|
||||
//nAbsVoteReq = 1;
|
||||
|
||||
@ -1230,7 +1212,7 @@ void CGovernanceObject::UpdateSentinelVariables(const CBlockIndex *pCurrentBlock
|
||||
fCachedDelete = false;
|
||||
fCachedEndorsed = false;
|
||||
fDirtyCache = false;
|
||||
|
||||
|
||||
// SET SENTINEL FLAGS TO TRUE IF MIMIMUM SUPPORT LEVELS ARE REACHED
|
||||
// ARE ANY OF THESE FLAGS CURRENTLY ACTIVATED?
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2014-2016 The Dash Core developers
|
||||
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef GOVERANCE_H
|
||||
#define GOVERANCE_H
|
||||
|
||||
@ -25,25 +25,19 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
class CGovernanceManager;
|
||||
class CGovernanceObject;
|
||||
class CGovernanceVote;
|
||||
|
||||
static const int GOVERNANCE_OBJECT_UNKNOWN = 0;
|
||||
static const int GOVERNANCE_OBJECT_PROPOSAL = 1;
|
||||
static const int GOVERNANCE_OBJECT_TRIGGER = 2;
|
||||
|
||||
class CGovernanceManager;
|
||||
class CGovernanceObject;
|
||||
class CGovernanceVote;
|
||||
class CNode;
|
||||
|
||||
static const CAmount GOVERNANCE_PROPOSAL_FEE_TX = (0.33*COIN);
|
||||
|
||||
static const int64_t GOVERNANCE_FEE_CONFIRMATIONS = 6;
|
||||
static const int64_t GOVERNANCE_UPDATE_MIN = 60*60;
|
||||
|
||||
extern std::map<uint256, int64_t> mapAskedForGovernanceObject;
|
||||
extern CGovernanceManager governance;
|
||||
|
||||
// FOR SEEN MAP ARRAYS - GOVERNANCE OBJECTS AND VOTES
|
||||
static const int SEEN_OBJECT_IS_VALID = 0;
|
||||
static const int SEEN_OBJECT_ERROR_INVALID = 1;
|
||||
@ -51,7 +45,8 @@ static const int SEEN_OBJECT_ERROR_IMMATURE = 2;
|
||||
static const int SEEN_OBJECT_EXECUTED = 3; //used for triggers
|
||||
static const int SEEN_OBJECT_UNKNOWN = 4; // the default
|
||||
|
||||
|
||||
extern std::map<uint256, int64_t> mapAskedForGovernanceObject;
|
||||
extern CGovernanceManager governance;
|
||||
|
||||
//
|
||||
// Governance Manager : Contains all proposals for the budget
|
||||
@ -99,7 +94,6 @@ private:
|
||||
// keep track of the scanning errors
|
||||
object_m_t mapObjects;
|
||||
|
||||
// note: move to private for better encapsulation
|
||||
count_m_t mapSeenGovernanceObjects;
|
||||
count_m_t mapSeenVotes;
|
||||
vote_m_t mapOrphanVotes;
|
||||
@ -114,10 +108,11 @@ private:
|
||||
public:
|
||||
// critical section to protect the inner data structures
|
||||
mutable CCriticalSection cs;
|
||||
|
||||
|
||||
CGovernanceManager();
|
||||
|
||||
void ClearSeen() {
|
||||
void ClearSeen()
|
||||
{
|
||||
LOCK(cs);
|
||||
mapSeenGovernanceObjects.clear();
|
||||
mapSeenVotes.clear();
|
||||
@ -128,8 +123,6 @@ public:
|
||||
return mapSeenGovernanceObjects.size() + mapSeenVotes.size();
|
||||
}
|
||||
|
||||
int sizeProposals() {return (int)mapObjects.size();}
|
||||
|
||||
void Sync(CNode* node, uint256 nProp);
|
||||
void SyncParentObjectByVote(CNode* pfrom, const CGovernanceVote& vote);
|
||||
|
||||
@ -155,7 +148,8 @@ public:
|
||||
|
||||
void CheckOrphanVotes();
|
||||
|
||||
void Clear(){
|
||||
void Clear()
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
LogPrint("gobject", "Governance object manager was cleared\n");
|
||||
@ -167,7 +161,7 @@ public:
|
||||
mapVotesByHash.clear();
|
||||
mapLastMasternodeTrigger.clear();
|
||||
}
|
||||
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
@ -185,8 +179,8 @@ public:
|
||||
}
|
||||
|
||||
void UpdatedBlockTip(const CBlockIndex *pindex);
|
||||
int64_t GetLastDiffTime() {return nTimeLastDiff;}
|
||||
void UpdateLastDiffTime(int64_t nTimeIn) {nTimeLastDiff=nTimeIn;}
|
||||
int64_t GetLastDiffTime() { return nTimeLastDiff; }
|
||||
void UpdateLastDiffTime(int64_t nTimeIn) { nTimeLastDiff = nTimeIn; }
|
||||
|
||||
int GetCachedBlockHeight() { return nCachedBlockHeight; }
|
||||
|
||||
@ -195,8 +189,6 @@ public:
|
||||
|
||||
bool HaveVoteForHash(uint256 nHash);
|
||||
|
||||
// int GetVoteCountByHash(uint256 nHash);
|
||||
|
||||
bool SerializeObjectForHash(uint256 nHash, CDataStream& ss);
|
||||
|
||||
bool SerializeVoteForHash(uint256 nHash, CDataStream& ss);
|
||||
@ -224,13 +216,13 @@ public:
|
||||
|
||||
uint256 nHashParent; //parent object, 0 is root
|
||||
int nRevision; //object revision in the system
|
||||
std::string strName; //org name, username, prop name, etc.
|
||||
std::string strName; //org name, username, prop name, etc.
|
||||
int64_t nTime; //time this object was created
|
||||
uint256 nCollateralHash; //fee-tx
|
||||
std::string strData; // Data field - can be used for anything
|
||||
int nObjectType;
|
||||
|
||||
bool fCachedLocalValidity; // is valid by blockchain
|
||||
bool fCachedLocalValidity; // is valid by blockchain
|
||||
std::string strLocalValidityError;
|
||||
|
||||
// Masternode info for signed objects
|
||||
@ -287,7 +279,7 @@ public:
|
||||
int GetNoCount(vote_signal_enum_t eVoteSignalIn);
|
||||
int GetAbstainCount(vote_signal_enum_t eVoteSignalIn);
|
||||
|
||||
// FUNCTIONS FOR DEALING WITH DATA STRING
|
||||
// FUNCTIONS FOR DEALING WITH DATA STRING
|
||||
|
||||
std::string GetDataAsHex();
|
||||
std::string GetDataAsString();
|
||||
@ -316,7 +308,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
// FUNCTIONS FOR DEALING WITH DATA STRING
|
||||
// FUNCTIONS FOR DEALING WITH DATA STRING
|
||||
|
||||
void LoadData();
|
||||
bool SetData(std::string& strError, std::string strDataIn);
|
||||
|
@ -30,32 +30,32 @@ using namespace std;
|
||||
|
||||
UniValue gobject(const UniValue& params, bool fHelp)
|
||||
{
|
||||
string strCommand;
|
||||
std::string strCommand;
|
||||
if (params.size() >= 1)
|
||||
strCommand = params[0].get_str();
|
||||
|
||||
if (fHelp ||
|
||||
(strCommand != "vote-many" && strCommand != "vote-conf" && strCommand != "vote-alias" && strCommand != "prepare" && strCommand != "submit" &&
|
||||
strCommand != "vote" && strCommand != "get" && strCommand != "getvotes" && strCommand != "list" && strCommand != "diff" && strCommand != "deserialize"))
|
||||
throw runtime_error(
|
||||
throw std::runtime_error(
|
||||
"gobject \"command\"...\n"
|
||||
"Manage governance objects\n"
|
||||
"\nAvailable commands:\n"
|
||||
" prepare - Prepare govobj by signing and creating tx\n"
|
||||
" submit - Submit govobj to network\n"
|
||||
" get - Get govobj by hash\n"
|
||||
" getvotes - Get votes for a govobj hash\n"
|
||||
" list - List all govobjs\n"
|
||||
" prepare - Prepare governance object by signing and creating tx\n"
|
||||
" submit - Submit governance object to network\n"
|
||||
" get - Get governance object by hash\n"
|
||||
" getvotes - Get votes for a governance object hash\n"
|
||||
" list - List all governance objects\n"
|
||||
" diff - List differences since last diff\n"
|
||||
" vote-many - Vote on a governance object by all masternodes (using masternode.conf setup)\n"
|
||||
" vote-alias - Vote on a governance object by masternode alias (using masternode.conf setup)\n"
|
||||
" vote-conf - Vote on a governance object by masternode configured in dash.conf\n"
|
||||
" vote-alias - Vote on a governance object by masternode alias\n"
|
||||
" vote-many - Vote on a governance object by all masternodes (using masternode.conf setup)\n"
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
------ Example Governance Item ------
|
||||
|
||||
------ Example Governance Item ------
|
||||
|
||||
gobject submit 6e622bb41bad1fb18e7f23ae96770aeb33129e18bd9efe790522488e580a0a03 0 1 1464292854 "beer-reimbursement" 5b5b22636f6e7472616374222c207b2270726f6a6563745f6e616d65223a20225c22626565722d7265696d62757273656d656e745c22222c20227061796d656e745f61646472657373223a20225c225879324c4b4a4a64655178657948726e34744744514238626a6876464564615576375c22222c2022656e645f64617465223a202231343936333030343030222c20226465736372697074696f6e5f75726c223a20225c227777772e646173687768616c652e6f72672f702f626565722d7265696d62757273656d656e745c22222c2022636f6e74726163745f75726c223a20225c22626565722d7265696d62757273656d656e742e636f6d2f3030312e7064665c22222c20227061796d656e745f616d6f756e74223a20223233342e323334323232222c2022676f7665726e616e63655f6f626a6563745f6964223a2037342c202273746172745f64617465223a202231343833323534303030227d5d5d1
|
||||
*/
|
||||
|
||||
@ -64,8 +64,8 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
{
|
||||
std::string strHex = params[1].get_str();
|
||||
|
||||
vector<unsigned char> v = ParseHex(strHex);
|
||||
string s(v.begin(), v.end());
|
||||
std::vector<unsigned char> v = ParseHex(strHex);
|
||||
std::string s(v.begin(), v.end());
|
||||
|
||||
UniValue u(UniValue::VOBJ);
|
||||
u.read(s);
|
||||
@ -90,10 +90,10 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
uint256 hashParent;
|
||||
|
||||
// -- attach to root node (root node doesn't really exist, but has a hash of zero)
|
||||
if(params[1].get_str() == "0") {
|
||||
if(params[1].get_str() == "0") {
|
||||
hashParent = uint256();
|
||||
} else {
|
||||
hashParent = ParseHashV(params[1], "fee-tx hash, parameter 1");
|
||||
hashParent = ParseHashV(params[1], "fee-txid, parameter 1");
|
||||
}
|
||||
|
||||
std::string strRevision = params[2].get_str();
|
||||
@ -102,7 +102,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
int nTime = boost::lexical_cast<int>(strTime);
|
||||
std::string strName = SanitizeString(params[4].get_str());
|
||||
std::string strData = params[5].get_str();
|
||||
|
||||
|
||||
// CREATE A NEW COLLATERAL TRANSACTION FOR THIS SPECIFIC OBJECT
|
||||
|
||||
CGovernanceObject govobj(hashParent, nRevision, strName, nTime, uint256(), strData);
|
||||
@ -113,9 +113,9 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
|
||||
CWalletTx wtx;
|
||||
if(!pwalletMain->GetBudgetSystemCollateralTX(wtx, govobj.GetHash(), govobj.GetMinCollateralFee(), false)) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Error making collateral transaction for govobj. Please check your wallet balance and make sure your wallet is unlocked.");
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Error making collateral transaction for governance object. Please check your wallet balance and make sure your wallet is unlocked.");
|
||||
}
|
||||
|
||||
|
||||
// -- make our change address
|
||||
CReserveKey reservekey(pwalletMain);
|
||||
// -- send the tx to the network
|
||||
@ -124,7 +124,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
DBG( cout << "gobject: prepare strName = " << strName
|
||||
<< ", strData = " << govobj.GetDataAsString()
|
||||
<< ", hash = " << govobj.GetHash().GetHex()
|
||||
<< ", fee_tx = " << wtx.GetHash().GetHex()
|
||||
<< ", txidFee = " << wtx.GetHash().GetHex()
|
||||
<< endl; );
|
||||
|
||||
return wtx.GetHash().ToString();
|
||||
@ -134,7 +134,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
if(strCommand == "submit")
|
||||
{
|
||||
if ((params.size() < 6) || (params.size() > 7)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject submit <parent-hash> <revision> <time> <name> <data-hex> <fee-tx>'");
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject submit <parent-hash> <revision> <time> <name> <data-hex> <fee-txid>'");
|
||||
}
|
||||
|
||||
if(!masternodeSync.IsBlockchainSynced()) {
|
||||
@ -149,7 +149,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
<< ", mnFound = " << mnFound << endl; );
|
||||
|
||||
if((params.size() == 6) && (!mnFound)) {
|
||||
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Non-masternodes must include fee-tx parameter.");
|
||||
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Non-masternodes must include fee-txid parameter.");
|
||||
}
|
||||
|
||||
// ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS
|
||||
@ -157,10 +157,10 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
LOCK(cs_main);
|
||||
CBlockIndex* pindex = chainActive.Tip();
|
||||
|
||||
uint256 fee_tx;
|
||||
uint256 txidFee;
|
||||
|
||||
if(params.size() == 7) {
|
||||
fee_tx = ParseHashV(params[6], "fee-tx hash, parameter 6");
|
||||
txidFee = ParseHashV(params[6], "fee-txid, parameter 6");
|
||||
}
|
||||
uint256 hashParent;
|
||||
if(params[1].get_str() == "0") { // attach to root node (root node doesn't really exist, but has a hash of zero)
|
||||
@ -178,12 +178,12 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
std::string strName = SanitizeString(params[4].get_str());
|
||||
std::string strData = params[5].get_str();
|
||||
|
||||
CGovernanceObject govobj(hashParent, nRevision, strName, nTime, fee_tx, strData);
|
||||
CGovernanceObject govobj(hashParent, nRevision, strName, nTime, txidFee, strData);
|
||||
|
||||
DBG( cout << "gobject: submit strName = " << strName
|
||||
<< ", strData = " << govobj.GetDataAsString()
|
||||
<< ", hash = " << govobj.GetHash().GetHex()
|
||||
<< ", fee_tx = " << fee_tx.GetHex()
|
||||
<< ", txidFee = " << txidFee.GetHex()
|
||||
<< endl; );
|
||||
|
||||
// Attempt to sign triggers if we are a MN
|
||||
@ -220,14 +220,14 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
std::string strVote;
|
||||
|
||||
hash = ParseHashV(params[1], "Object hash");
|
||||
std::string strVoteAction = params[2].get_str();
|
||||
std::string strVoteSignal = params[2].get_str();
|
||||
std::string strVoteOutcome = params[3].get_str();
|
||||
|
||||
vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteAction);
|
||||
|
||||
vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
|
||||
if(eVoteSignal == VOTE_SIGNAL_NONE) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||
"Invalid vote signal. Please using one of the following: "
|
||||
"(funding|valid|delete|endorsed) OR `custom sentinel code` ");
|
||||
"(funding|valid|delete|endorsed) OR `custom sentinel code` ");
|
||||
}
|
||||
|
||||
vote_outcome_enum_t eVoteOutcome = CGovernanceVoting::ConvertVoteOutcome(strVoteOutcome);
|
||||
@ -240,7 +240,6 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
|
||||
UniValue resultsObj(UniValue::VOBJ);
|
||||
|
||||
std::string errorMessage;
|
||||
std::vector<unsigned char> vchMasterNodeSignature;
|
||||
std::string strMasterNodeSignMessage;
|
||||
|
||||
@ -300,11 +299,11 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
std::string strVote;
|
||||
|
||||
hash = ParseHashV(params[1], "Object hash");
|
||||
std::string strVoteAction = params[2].get_str();
|
||||
std::string strVoteSignal = params[2].get_str();
|
||||
std::string strVoteOutcome = params[3].get_str();
|
||||
|
||||
|
||||
vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteAction);
|
||||
vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
|
||||
if(eVoteSignal == VOTE_SIGNAL_NONE) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||
"Invalid vote signal. Please using one of the following: "
|
||||
@ -325,7 +324,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
UniValue resultsObj(UniValue::VOBJ);
|
||||
|
||||
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
|
||||
std::string errorMessage;
|
||||
std::string strError;
|
||||
std::vector<unsigned char> vchMasterNodeSignature;
|
||||
std::string strMasterNodeSignMessage;
|
||||
|
||||
@ -339,7 +338,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
if(!darkSendSigner.GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)){
|
||||
failed++;
|
||||
statusObj.push_back(Pair("result", "failed"));
|
||||
statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly: " + errorMessage));
|
||||
statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly"));
|
||||
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
|
||||
continue;
|
||||
}
|
||||
@ -363,7 +362,6 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string strError = "";
|
||||
if(governance.AddOrUpdateVote(vote, NULL, strError)) {
|
||||
governance.AddSeenVote(vote.GetHash(), SEEN_OBJECT_IS_VALID);
|
||||
vote.Relay();
|
||||
@ -398,17 +396,17 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
// COLLECT NEEDED PARAMETRS FROM USER
|
||||
|
||||
hash = ParseHashV(params[1], "Object hash");
|
||||
std::string strVoteAction = params[2].get_str();
|
||||
std::string strVoteSignal = params[2].get_str();
|
||||
std::string strVoteOutcome = params[3].get_str();
|
||||
std::string strAlias = params[4].get_str();
|
||||
|
||||
|
||||
// CONVERT NAMED SIGNAL/ACTION AND CONVERT
|
||||
|
||||
vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteAction);
|
||||
vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
|
||||
if(eVoteSignal == VOTE_SIGNAL_NONE) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||
"Invalid vote signal. Please using one of the following: "
|
||||
"(funding|valid|delete|endorsed) OR `custom sentinel code` ");
|
||||
"(funding|valid|delete|endorsed) OR `custom sentinel code` ");
|
||||
}
|
||||
|
||||
vote_outcome_enum_t eVoteOutcome = CGovernanceVoting::ConvertVoteOutcome(strVoteOutcome);
|
||||
@ -432,7 +430,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
if( strAlias != mne.getAlias()) continue;
|
||||
|
||||
// INIT OUR NEEDED VARIABLES TO EXECUTE THE VOTE
|
||||
std::string errorMessage;
|
||||
std::string strError;
|
||||
std::vector<unsigned char> vchMasterNodeSignature;
|
||||
std::string strMasterNodeSignMessage;
|
||||
|
||||
@ -456,8 +454,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
// SEARCH FOR THIS MASTERNODE ON THE NETWORK, THE NODE MUST BE ACTIVE TO VOTE
|
||||
|
||||
CMasternode* pmn = mnodeman.Find(pubKeyMasternode);
|
||||
if(pmn == NULL)
|
||||
{
|
||||
if(pmn == NULL) {
|
||||
failed++;
|
||||
statusObj.push_back(Pair("result", "failed"));
|
||||
statusObj.push_back(Pair("errorMessage", "Masternode must be publically available on network to vote. Masternode not found."));
|
||||
@ -478,7 +475,6 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
|
||||
// UPDATE LOCAL DATABASE WITH NEW OBJECT SETTINGS
|
||||
|
||||
std::string strError = "";
|
||||
if(governance.AddOrUpdateVote(vote, NULL, strError)) {
|
||||
governance.AddSeenVote(vote.GetHash(), SEEN_OBJECT_IS_VALID);
|
||||
vote.Relay();
|
||||
@ -586,7 +582,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
CGovernanceObject* pGovObj = governance.FindGovernanceObject(hash);
|
||||
|
||||
if(pGovObj == NULL)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown govobj");
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown governance object");
|
||||
|
||||
// REPORT BASIC OBJECT STATS
|
||||
|
||||
@ -602,7 +598,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
objFundingResult.push_back(Pair("AbsoluteYesCount", (int64_t)pGovObj->GetYesCount(VOTE_SIGNAL_FUNDING)-(int64_t)pGovObj->GetNoCount(VOTE_SIGNAL_FUNDING)));
|
||||
objFundingResult.push_back(Pair("YesCount", (int64_t)pGovObj->GetYesCount(VOTE_SIGNAL_FUNDING)));
|
||||
objFundingResult.push_back(Pair("NoCount", (int64_t)pGovObj->GetNoCount(VOTE_SIGNAL_FUNDING)));
|
||||
objFundingResult.push_back(Pair("AbstainCount", (int64_t)pGovObj->GetAbstainCount(VOTE_SIGNAL_FUNDING)));
|
||||
objFundingResult.push_back(Pair("AbstainCount", (int64_t)pGovObj->GetAbstainCount(VOTE_SIGNAL_FUNDING)));
|
||||
objResult.push_back(Pair("FundingResult", objFundingResult));
|
||||
|
||||
// -- VALIDITY VOTING RESULTS
|
||||
@ -610,7 +606,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
objValid.push_back(Pair("AbsoluteYesCount", (int64_t)pGovObj->GetYesCount(VOTE_SIGNAL_VALID)-(int64_t)pGovObj->GetNoCount(VOTE_SIGNAL_VALID)));
|
||||
objValid.push_back(Pair("YesCount", (int64_t)pGovObj->GetYesCount(VOTE_SIGNAL_VALID)));
|
||||
objValid.push_back(Pair("NoCount", (int64_t)pGovObj->GetNoCount(VOTE_SIGNAL_VALID)));
|
||||
objValid.push_back(Pair("AbstainCount", (int64_t)pGovObj->GetAbstainCount(VOTE_SIGNAL_VALID)));
|
||||
objValid.push_back(Pair("AbstainCount", (int64_t)pGovObj->GetAbstainCount(VOTE_SIGNAL_VALID)));
|
||||
objResult.push_back(Pair("ValidResult", objValid));
|
||||
|
||||
// -- DELETION CRITERION VOTING RESULTS
|
||||
@ -618,18 +614,18 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
objDelete.push_back(Pair("AbsoluteYesCount", (int64_t)pGovObj->GetYesCount(VOTE_SIGNAL_DELETE)-(int64_t)pGovObj->GetNoCount(VOTE_SIGNAL_DELETE)));
|
||||
objDelete.push_back(Pair("YesCount", (int64_t)pGovObj->GetYesCount(VOTE_SIGNAL_DELETE)));
|
||||
objDelete.push_back(Pair("NoCount", (int64_t)pGovObj->GetNoCount(VOTE_SIGNAL_DELETE)));
|
||||
objDelete.push_back(Pair("AbstainCount", (int64_t)pGovObj->GetAbstainCount(VOTE_SIGNAL_DELETE)));
|
||||
objDelete.push_back(Pair("AbstainCount", (int64_t)pGovObj->GetAbstainCount(VOTE_SIGNAL_DELETE)));
|
||||
objResult.push_back(Pair("DeleteResult", objDelete));
|
||||
|
||||
// -- ENDORSED VIA MASTERNODE-ELECTED BOARD
|
||||
// -- ENDORSED VIA MASTERNODE-ELECTED BOARD
|
||||
UniValue objEndorsed(UniValue::VOBJ);
|
||||
objEndorsed.push_back(Pair("AbsoluteYesCount", (int64_t)pGovObj->GetYesCount(VOTE_SIGNAL_ENDORSED)-(int64_t)pGovObj->GetNoCount(VOTE_SIGNAL_ENDORSED)));
|
||||
objEndorsed.push_back(Pair("YesCount", (int64_t)pGovObj->GetYesCount(VOTE_SIGNAL_ENDORSED)));
|
||||
objEndorsed.push_back(Pair("NoCount", (int64_t)pGovObj->GetNoCount(VOTE_SIGNAL_ENDORSED)));
|
||||
objEndorsed.push_back(Pair("AbstainCount", (int64_t)pGovObj->GetAbstainCount(VOTE_SIGNAL_ENDORSED)));
|
||||
objEndorsed.push_back(Pair("AbstainCount", (int64_t)pGovObj->GetAbstainCount(VOTE_SIGNAL_ENDORSED)));
|
||||
objResult.push_back(Pair("EndorsedResult", objEndorsed));
|
||||
|
||||
// --
|
||||
// --
|
||||
std::string strError = "";
|
||||
objResult.push_back(Pair("fLocalValidity", pGovObj->IsValidLocally(chainActive.Tip(), strError, false)));
|
||||
objResult.push_back(Pair("fCachedValid", pGovObj->fCachedValid));
|
||||
@ -641,16 +637,16 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
if(strCommand == "getvotes")
|
||||
{
|
||||
if (params.size() != 2)
|
||||
throw runtime_error(
|
||||
throw std::runtime_error(
|
||||
"Correct usage is 'gobject getvotes <governance-hash>'"
|
||||
);
|
||||
|
||||
// COLLECT PARAMETERS FROM USER
|
||||
|
||||
|
||||
uint256 hash = ParseHashV(params[1], "Governance hash");
|
||||
|
||||
|
||||
// FIND OBJECT USER IS LOOKING FOR
|
||||
|
||||
|
||||
LOCK(governance.cs);
|
||||
|
||||
CGovernanceObject* pGovObj = governance.FindGovernanceObject(hash);
|
||||
@ -662,8 +658,8 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
// REPORT RESULTS TO USER
|
||||
|
||||
UniValue bResult(UniValue::VOBJ);
|
||||
|
||||
// GET MATCHING VOTES BY HASH, THEN SHOW USERS VOTE INFORMATION
|
||||
|
||||
// GET MATCHING VOTES BY HASH, THEN SHOW USERS VOTE INFORMATION
|
||||
|
||||
std::vector<CGovernanceVote*> vecVotes = governance.GetMatchingVotes(hash);
|
||||
BOOST_FOREACH(CGovernanceVote* pVote, vecVotes) {
|
||||
@ -679,7 +675,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
||||
UniValue voteraw(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 6)
|
||||
throw runtime_error(
|
||||
throw std::runtime_error(
|
||||
"voteraw <masternode-tx-hash> <masternode-tx-index> <governance-hash> <vote-signal> [yes|no|abstain] <time> <vote-sig>\n"
|
||||
"Compile and relay a governance vote with provided external signature instead of signing vote internally\n"
|
||||
);
|
||||
@ -694,9 +690,9 @@ UniValue voteraw(const UniValue& params, bool fHelp)
|
||||
|
||||
vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
|
||||
if(eVoteSignal == VOTE_SIGNAL_NONE) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||
"Invalid vote signal. Please using one of the following: "
|
||||
"(funding|valid|delete|endorsed) OR `custom sentinel code` ");
|
||||
"(funding|valid|delete|endorsed) OR `custom sentinel code` ");
|
||||
}
|
||||
|
||||
vote_outcome_enum_t eVoteOutcome = CGovernanceVoting::ConvertVoteOutcome(strVoteOutcome);
|
||||
@ -707,7 +703,7 @@ UniValue voteraw(const UniValue& params, bool fHelp)
|
||||
int64_t nTime = params[5].get_int64();
|
||||
std::string strSig = params[6].get_str();
|
||||
bool fInvalid = false;
|
||||
vector<unsigned char> vchSig = DecodeBase64(strSig.c_str(), &fInvalid);
|
||||
std::vector<unsigned char> vchSig = DecodeBase64(strSig.c_str(), &fInvalid);
|
||||
|
||||
if (fInvalid) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
|
||||
@ -740,7 +736,7 @@ UniValue voteraw(const UniValue& params, bool fHelp)
|
||||
UniValue getgovernanceinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0) {
|
||||
throw runtime_error(
|
||||
throw std::runtime_error(
|
||||
"getgovernanceinfo\n"
|
||||
"Returns an object containing governance parameters.\n"
|
||||
"\nResult:\n"
|
||||
@ -792,7 +788,7 @@ UniValue getgovernanceinfo(const UniValue& params, bool fHelp)
|
||||
UniValue getsuperblockbudget(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1) {
|
||||
throw runtime_error(
|
||||
throw std::runtime_error(
|
||||
"getsuperblockbudget index\n"
|
||||
"\nReturns the absolute minimum number of votes needed to trigger a governance action.\n"
|
||||
"\nArguments:\n"
|
||||
|
Loading…
Reference in New Issue
Block a user