Governance changes (#1029)

* Implemented several governance changes
 - Limit strData size to avoid propagation of very large messages
 - Remove unused CGovernanceObject::SetData method
 - Remove CGovernanceObject::strName field to avoid data redundancy

* Fixed parameter count bug in gobject prepare
This commit is contained in:
Tim Flynn 2016-09-17 15:37:48 -04:00 committed by UdjinM6
parent a29a5345a1
commit fcb985a93f
3 changed files with 22 additions and 90 deletions

View File

@ -359,28 +359,6 @@ void CGovernanceManager::UpdateCachesAndClean()
}
CGovernanceObject *CGovernanceManager::FindGovernanceObject(const std::string &strName)
{
// find the prop with the highest yes count
int nYesCount = -99999;
CGovernanceObject* pGovObj = NULL;
object_m_it it = mapObjects.begin();
while(it != mapObjects.end()) {
int nGovObjYesCount = pGovObj->GetYesCount(VOTE_SIGNAL_FUNDING);
if((*it).second.strName == strName && nGovObjYesCount > nYesCount) {
nYesCount = nGovObjYesCount;
pGovObj = &((*it).second);
}
++it;
}
if(nYesCount == -99999) return NULL;
return pGovObj;
}
CGovernanceObject *CGovernanceManager::FindGovernanceObject(const uint256& nHash)
{
LOCK(cs);
@ -623,7 +601,6 @@ CGovernanceObject::CGovernanceObject()
{
// MAIN OBJECT DATA
strName = "unknown";
nTime = 0;
nObjectType = GOVERNANCE_OBJECT_UNKNOWN;
@ -645,13 +622,12 @@ CGovernanceObject::CGovernanceObject()
LoadData();
}
CGovernanceObject::CGovernanceObject(uint256 nHashParentIn, int nRevisionIn, std::string strNameIn, int64_t nTimeIn, uint256 nCollateralHashIn, std::string strDataIn)
CGovernanceObject::CGovernanceObject(uint256 nHashParentIn, int nRevisionIn, int64_t nTimeIn, uint256 nCollateralHashIn, std::string strDataIn)
{
// MAIN OBJECT DATA
nHashParent = nHashParentIn; //parent object, 0 is root
nRevision = nRevisionIn; //object revision in the system
strName = strNameIn;
nTime = nTimeIn;
nCollateralHash = nCollateralHashIn; //fee-tx
nObjectType = GOVERNANCE_OBJECT_UNKNOWN; // Avoid having an uninitialized variable
@ -677,7 +653,6 @@ CGovernanceObject::CGovernanceObject(const CGovernanceObject& other)
nHashParent = other.nHashParent;
nRevision = other.nRevision;
strName = other.strName;
nTime = other.nTime;
nCollateralHash = other.nCollateralHash;
strData = other.strData;
@ -763,13 +738,12 @@ uint256 CGovernanceObject::GetHash()
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << nHashParent;
ss << nRevision;
ss << strName;
ss << nTime;
ss << strData;
// fee_tx is left out on purpose
uint256 h1 = ss.GetHash();
DBG( printf("CGovernanceObject::GetHash %i %s %li %s\n", nRevision, strName.c_str(), nTime, strData.c_str()); );
DBG( printf("CGovernanceObject::GetHash %i %li %s\n", nRevision, nTime, strData.c_str()); );
return h1;
}
@ -842,30 +816,6 @@ 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)
{
// SET DATA FIELD TO INPUT
if(strDataIn.size() > 512*4)
{
// (assumption) this is equal to pythons len(strData) > 512*4, I think
strError = "Too big.";
return false;
}
strData = strDataIn;
return true;
}
/**
* GetData - Example usage:
* --------------------------------------------------------
@ -915,16 +865,6 @@ bool CGovernanceObject::IsValidLocally(const CBlockIndex* pindex, std::string& s
return true;
}
if(strName.size() > 20) {
strError = "Invalid object name, limit of 20 characters.";
return false;
}
if(strName != SanitizeString(strName)) {
strError = "Invalid object name, unsafe characters found.";
return false;
}
// IF ABSOLUTE NO COUNT (NO-YES VALID VOTES) IS MORE THAN 10% OF THE NETWORK MASTERNODES, OBJ IS INVALID
if(GetAbsoluteNoCount(VOTE_SIGNAL_VALID) > mnodeman.CountEnabled(MSG_GOVERNANCE_PEER_PROTO_VERSION)/10) {
@ -1241,7 +1181,6 @@ void CGovernanceObject::swap(CGovernanceObject& first, CGovernanceObject& second
// by swapping the members of two classes,
// the two classes are effectively swapped
swap(first.strName, second.strName);
swap(first.nHashParent, second.nHashParent);
swap(first.nRevision, second.nRevision);
swap(first.nTime, second.nTime);

View File

@ -29,6 +29,8 @@ class CGovernanceManager;
class CGovernanceObject;
class CGovernanceVote;
static const int MAX_GOVERNANCE_OBJECT_DATA_SIZE = 16 * 1024;
static const int GOVERNANCE_OBJECT_UNKNOWN = 0;
static const int GOVERNANCE_OBJECT_PROPOSAL = 1;
static const int GOVERNANCE_OBJECT_TRIGGER = 2;
@ -135,7 +137,6 @@ public:
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void NewBlock();
CGovernanceObject *FindGovernanceObject(const std::string &strName);
CGovernanceObject *FindGovernanceObject(const uint256& nHash);
std::vector<CGovernanceVote*> GetMatchingVotes(const uint256& nParentHash);
@ -222,7 +223,6 @@ public:
uint256 nHashParent; //parent object, 0 is root
int nRevision; //object revision in the system
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
@ -246,7 +246,7 @@ public:
bool fExpired; // Object is no longer of interest
CGovernanceObject();
CGovernanceObject(uint256 nHashParentIn, int nRevisionIn, std::string strNameIn, int64_t nTime, uint256 nCollateralHashIn, std::string strDataIn);
CGovernanceObject(uint256 nHashParentIn, int nRevisionIn, int64_t nTime, uint256 nCollateralHashIn, std::string strDataIn);
CGovernanceObject(const CGovernanceObject& other);
void swap(CGovernanceObject& first, CGovernanceObject& second); // nothrow
@ -267,7 +267,6 @@ public:
void UpdateSentinelVariables(const CBlockIndex *pCurrentBlockIndex);
int GetObjectType();
int GetObjectSubtype();
std::string GetName() {return strName; }
CAmount GetMinCollateralFee();
@ -300,10 +299,9 @@ public:
READWRITE(nHashParent);
READWRITE(nRevision);
READWRITE(LIMITED_STRING(strName, 64));
READWRITE(nTime);
READWRITE(nCollateralHash);
READWRITE(strData);
READWRITE(LIMITED_STRING(strData, MAX_GOVERNANCE_OBJECT_DATA_SIZE));
READWRITE(nObjectType);
READWRITE(vinMasternode);
READWRITE(vchSig);
@ -315,7 +313,6 @@ private:
// FUNCTIONS FOR DEALING WITH DATA STRING
void LoadData();
bool SetData(std::string& strError, std::string strDataIn);
void GetData(UniValue& objResult);
};

View File

@ -76,8 +76,8 @@ UniValue gobject(const UniValue& params, bool fHelp)
// PREPARE THE GOVERNANCE OBJECT BY CREATING A COLLATERAL TRANSACTION
if(strCommand == "prepare")
{
if (params.size() != 6) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject prepare <parent-hash> <revision> <time> <name> <data-hex>'");
if (params.size() != 5) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject prepare <parent-hash> <revision> <time> <data-hex>'");
}
// ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS
@ -101,12 +101,11 @@ UniValue gobject(const UniValue& params, bool fHelp)
std::string strTime = params[3].get_str();
int nRevision = boost::lexical_cast<int>(strRevision);
int nTime = boost::lexical_cast<int>(strTime);
std::string strName = SanitizeString(params[4].get_str());
std::string strData = params[5].get_str();
std::string strData = params[4].get_str();
// CREATE A NEW COLLATERAL TRANSACTION FOR THIS SPECIFIC OBJECT
CGovernanceObject govobj(hashParent, nRevision, strName, nTime, uint256(), strData);
CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strData);
if(govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Trigger objects need not be prepared (however only masternodes can create them)");
@ -126,8 +125,8 @@ UniValue gobject(const UniValue& params, bool fHelp)
// -- send the tx to the network
pwalletMain->CommitTransaction(wtx, reservekey, NetMsgType::TX);
DBG( cout << "gobject: prepare strName = " << strName
<< ", strData = " << govobj.GetDataAsString()
DBG( cout << "gobject: prepare "
<< " strData = " << govobj.GetDataAsString()
<< ", hash = " << govobj.GetHash().GetHex()
<< ", txidFee = " << wtx.GetHash().GetHex()
<< endl; );
@ -138,8 +137,8 @@ UniValue gobject(const UniValue& params, bool fHelp)
// AFTER COLLATERAL TRANSACTION HAS MATURED USER CAN SUBMIT GOVERNANCE OBJECT TO PROPAGATE NETWORK
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-txid>'");
if ((params.size() < 5) || (params.size() > 6)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject submit <parent-hash> <revision> <time> <data-hex> <fee-txid>'");
}
if(!masternodeSync.IsBlockchainSynced()) {
@ -161,8 +160,8 @@ UniValue gobject(const UniValue& params, bool fHelp)
uint256 txidFee;
if(params.size() == 7) {
txidFee = ParseHashV(params[6], "fee-txid, parameter 6");
if(params.size() == 6) {
txidFee = ParseHashV(params[5], "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)
@ -177,13 +176,12 @@ UniValue gobject(const UniValue& params, bool fHelp)
std::string strTime = params[3].get_str();
int nRevision = boost::lexical_cast<int>(strRevision);
int nTime = boost::lexical_cast<int>(strTime);
std::string strName = SanitizeString(params[4].get_str());
std::string strData = params[5].get_str();
std::string strData = params[4].get_str();
CGovernanceObject govobj(hashParent, nRevision, strName, nTime, txidFee, strData);
CGovernanceObject govobj(hashParent, nRevision, nTime, txidFee, strData);
DBG( cout << "gobject: submit strName = " << strName
<< ", strData = " << govobj.GetDataAsString()
DBG( cout << "gobject: submit "
<< " strData = " << govobj.GetDataAsString()
<< ", hash = " << govobj.GetHash().GetHex()
<< ", txidFee = " << txidFee.GetHex()
<< endl; );
@ -199,7 +197,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
}
}
else {
if(params.size() != 7) {
if(params.size() != 6) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "The fee-txid parameter must be included to submit this type of object");
}
}
@ -546,7 +544,6 @@ UniValue gobject(const UniValue& params, bool fHelp)
if(strShow == "valid" && !pGovObj->fCachedValid) continue;
UniValue bObj(UniValue::VOBJ);
bObj.push_back(Pair("Name", pGovObj->GetName()));
bObj.push_back(Pair("DataHex", pGovObj->GetDataAsHex()));
bObj.push_back(Pair("DataString", pGovObj->GetDataAsString()));
bObj.push_back(Pair("Hash", pGovObj->GetHash().ToString()));
@ -567,7 +564,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
bObj.push_back(Pair("fCachedDelete", pGovObj->fCachedDelete));
bObj.push_back(Pair("fCachedEndorsed", pGovObj->fCachedEndorsed));
objResult.push_back(Pair(pGovObj->GetName(), bObj));
objResult.push_back(Pair(pGovObj->GetHash().ToString(), bObj));
}
return objResult;
@ -593,7 +590,6 @@ UniValue gobject(const UniValue& params, bool fHelp)
// REPORT BASIC OBJECT STATS
UniValue objResult(UniValue::VOBJ);
objResult.push_back(Pair("Name", pGovObj->GetName()));
objResult.push_back(Pair("Hash", pGovObj->GetHash().ToString()));
objResult.push_back(Pair("CollateralHash", pGovObj->nCollateralHash.ToString()));