diff --git a/src/governance-classes.cpp b/src/governance-classes.cpp index bd0afe5b7a152..fef027debe9d6 100644 --- a/src/governance-classes.cpp +++ b/src/governance-classes.cpp @@ -204,13 +204,13 @@ void CGovernanceTriggerManager::CleanAndRemove() if(remove) { DBG( - string strdata = "NULL"; + string strDataAsPlainString = "NULL"; CGovernanceObject* pgovobj = pSuperblock->GetGovernanceObject(); if(pgovobj) { - strdata = pgovobj->GetDataAsString(); + strDataAsPlainString = pgovobj->GetDataAsPlainString(); } cout << "CGovernanceTriggerManager::CleanAndRemove: Removing object: " - << strdata + << strDataAsPlainString << endl; ); LogPrint("gobject", "CGovernanceTriggerManager::CleanAndRemove -- Removing trigger object\n"); @@ -245,7 +245,7 @@ std::vector CGovernanceTriggerManager::GetActiveTriggers() CGovernanceObject* pObj = governance.FindGovernanceObject((*it).first); if(pObj) { - DBG( cout << "GetActiveTriggers: pObj->GetDataAsString() = " << pObj->GetDataAsString() << endl; ); + DBG( cout << "GetActiveTriggers: pObj->GetDataAsPlainString() = " << pObj->GetDataAsPlainString() << endl; ); vecResults.push_back(it->second); } ++it; @@ -293,7 +293,7 @@ bool CSuperblockManager::IsSuperblockTriggered(int nBlockHeight) continue; } - LogPrint("gobject", "CSuperblockManager::IsSuperblockTriggered -- data = %s\n", pObj->GetDataAsString()); + LogPrint("gobject", "CSuperblockManager::IsSuperblockTriggered -- data = %s\n", pObj->GetDataAsPlainString()); // note : 12.1 - is epoch calculation correct? @@ -482,7 +482,7 @@ CSuperblock(uint256& nHash) } DBG( cout << "CSuperblock Constructor pGovObj : " - << pGovObj->GetDataAsString() + << pGovObj->GetDataAsPlainString() << ", nObjectType = " << pGovObj->GetObjectType() << endl; ); @@ -673,8 +673,8 @@ bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount b int nPayments = CountPayments(); int nMinerPayments = nOutputs - nPayments; - LogPrint("gobject", "CSuperblock::IsValid nOutputs = %d, nPayments = %d, strData = %s\n", - nOutputs, nPayments, GetGovernanceObject()->GetDataAsHex()); + LogPrint("gobject", "CSuperblock::IsValid nOutputs = %d, nPayments = %d, GetDataAsHexString = %s\n", + nOutputs, nPayments, GetGovernanceObject()->GetDataAsHexString()); // We require an exact match (including order) between the expected // superblock payments and the payments actually in the block. diff --git a/src/governance-object.cpp b/src/governance-object.cpp index 293db033f73a5..78eea95c35f1d 100644 --- a/src/governance-object.cpp +++ b/src/governance-object.cpp @@ -23,7 +23,7 @@ CGovernanceObject::CGovernanceObject() nTime(0), nDeletionTime(0), nCollateralHash(), - strData(), + vchData(), masternodeOutpoint(), vchSig(), fCachedLocalValidity(false), @@ -39,11 +39,11 @@ CGovernanceObject::CGovernanceObject() cmmapOrphanVotes(), fileVotes() { - // PARSE JSON DATA STORAGE (STRDATA) + // PARSE JSON DATA STORAGE (VCHDATA) LoadData(); } -CGovernanceObject::CGovernanceObject(const uint256& nHashParentIn, int nRevisionIn, int64_t nTimeIn, const uint256& nCollateralHashIn, const std::string& strDataIn) +CGovernanceObject::CGovernanceObject(const uint256& nHashParentIn, int nRevisionIn, int64_t nTimeIn, const uint256& nCollateralHashIn, const std::string& strDataHexIn) : cs(), nObjectType(GOVERNANCE_OBJECT_UNKNOWN), nHashParent(nHashParentIn), @@ -51,7 +51,7 @@ CGovernanceObject::CGovernanceObject(const uint256& nHashParentIn, int nRevision nTime(nTimeIn), nDeletionTime(0), nCollateralHash(nCollateralHashIn), - strData(strDataIn), + vchData(ParseHex(strDataHexIn)), masternodeOutpoint(), vchSig(), fCachedLocalValidity(false), @@ -67,7 +67,7 @@ CGovernanceObject::CGovernanceObject(const uint256& nHashParentIn, int nRevision cmmapOrphanVotes(), fileVotes() { - // PARSE JSON DATA STORAGE (STRDATA) + // PARSE JSON DATA STORAGE (VCHDATA) LoadData(); } @@ -79,7 +79,7 @@ CGovernanceObject::CGovernanceObject(const CGovernanceObject& other) nTime(other.nTime), nDeletionTime(other.nDeletionTime), nCollateralHash(other.nCollateralHash), - strData(other.strData), + vchData(other.vchData), masternodeOutpoint(other.masternodeOutpoint), vchSig(other.vchSig), fCachedLocalValidity(other.fCachedLocalValidity), @@ -217,7 +217,7 @@ std::string CGovernanceObject::GetSignatureMessage() const std::string strMessage = nHashParent.ToString() + "|" + boost::lexical_cast(nRevision) + "|" + boost::lexical_cast(nTime) + "|" + - strData + "|" + + GetDataAsHexString() + "|" + masternodeOutpoint.ToStringShort() + "|" + nCollateralHash.ToString(); @@ -276,25 +276,25 @@ uint256 CGovernanceObject::GetHash() const ss << nHashParent; ss << nRevision; ss << nTime; - ss << strData; + ss << GetDataAsHexString(); ss << masternodeOutpoint << uint8_t{} << 0xffffffff; ss << vchSig; // fee_tx is left out on purpose - DBG( printf("CGovernanceObject::GetHash %i %li %s\n", nRevision, nTime, strData.c_str()); ); + DBG( printf("CGovernanceObject::GetHash %i %li %s\n", nRevision, nTime, GetDataAsHexString().c_str()); ); return ss.GetHash(); } /** - Return the actual object from the strData JSON structure. + Return the actual object from the vchData JSON structure. Returns an empty object on error. */ UniValue CGovernanceObject::GetJSONObject() { UniValue obj(UniValue::VOBJ); - if(strData.empty()) { + if(vchData.empty()) { return obj; } @@ -312,7 +312,7 @@ UniValue CGovernanceObject::GetJSONObject() * LoadData * -------------------------------------------------------- * -* Attempt to load data from strData +* Attempt to load data from vchData * */ @@ -321,17 +321,17 @@ void CGovernanceObject::LoadData() // todo : 12.1 - resolved //return; - if(strData.empty()) { + if(vchData.empty()) { return; } try { - // ATTEMPT TO LOAD JSON STRING FROM STRDATA + // ATTEMPT TO LOAD JSON STRING FROM VCHDATA UniValue objResult(UniValue::VOBJ); GetData(objResult); - DBG( cout << "CGovernanceObject::LoadData strData = " - << GetDataAsString() + DBG( cout << "CGovernanceObject::LoadData GetDataAsPlainString = " + << GetDataAsPlainString() << endl; ); UniValue obj = GetJSONObject(); @@ -367,7 +367,7 @@ void CGovernanceObject::LoadData() void CGovernanceObject::GetData(UniValue& objResult) { UniValue o(UniValue::VOBJ); - std::string s = GetDataAsString(); + std::string s = GetDataAsPlainString(); o.read(s); objResult = o; } @@ -378,17 +378,14 @@ void CGovernanceObject::GetData(UniValue& objResult) * */ -std::string CGovernanceObject::GetDataAsHex() +std::string CGovernanceObject::GetDataAsHexString() const { - return strData; + return HexStr(vchData); } -std::string CGovernanceObject::GetDataAsString() +std::string CGovernanceObject::GetDataAsPlainString() const { - std::vector v = ParseHex(strData); - std::string s(v.begin(), v.end()); - - return s; + return std::string(vchData.begin(), vchData.end()); } void CGovernanceObject::UpdateLocalValidity() @@ -421,6 +418,10 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast case GOVERNANCE_OBJECT_PROPOSAL: case GOVERNANCE_OBJECT_TRIGGER: case GOVERNANCE_OBJECT_WATCHDOG: + if (vchData.size() > MAX_GOVERNANCE_OBJECT_DATA_SIZE) { + strError = strprintf("Invalid object size %d", vchData.size()); + return false; + } break; default: strError = strprintf("Invalid object type %d", nObjectType); @@ -704,7 +705,7 @@ void CGovernanceObject::swap(CGovernanceObject& first, CGovernanceObject& second swap(first.nTime, second.nTime); swap(first.nDeletionTime, second.nDeletionTime); swap(first.nCollateralHash, second.nCollateralHash); - swap(first.strData, second.strData); + swap(first.vchData, second.vchData); swap(first.nObjectType, second.nObjectType); // swap all cached valid flags diff --git a/src/governance-object.h b/src/governance-object.h index 98e1ee0bb67d4..ffbc9a4889a74 100644 --- a/src/governance-object.h +++ b/src/governance-object.h @@ -15,6 +15,7 @@ #include "net.h" #include "sync.h" #include "util.h" +#include "utilstrencodings.h" #include @@ -145,7 +146,7 @@ class CGovernanceObject uint256 nCollateralHash; /// Data field - can be used for anything - std::string strData; + std::vector vchData; /// Masternode info for signed objects COutPoint masternodeOutpoint; @@ -190,7 +191,7 @@ class CGovernanceObject public: CGovernanceObject(); - CGovernanceObject(const uint256& nHashParentIn, int nRevisionIn, int64_t nTime, const uint256& nCollateralHashIn, const std::string& strDataIn); + CGovernanceObject(const uint256& nHashParentIn, int nRevisionIn, int64_t nTime, const uint256& nCollateralHashIn, const std::string& strDataHexIn); CGovernanceObject(const CGovernanceObject& other); @@ -293,8 +294,8 @@ class CGovernanceObject // FUNCTIONS FOR DEALING WITH DATA STRING - std::string GetDataAsHex(); - std::string GetDataAsString(); + std::string GetDataAsHexString() const; + std::string GetDataAsPlainString() const; // SERIALIZER @@ -309,7 +310,20 @@ class CGovernanceObject READWRITE(nRevision); READWRITE(nTime); READWRITE(nCollateralHash); - READWRITE(LIMITED_STRING(strData, MAX_GOVERNANCE_OBJECT_DATA_SIZE)); + if (nVersion == 70208) { + // converting from/to old format + std::string strDataHex; + if (ser_action.ForRead()) { + READWRITE(LIMITED_STRING(strDataHex, MAX_GOVERNANCE_OBJECT_DATA_SIZE)); + vchData = ParseHex(strDataHex); + } else { + strDataHex = HexStr(vchData); + READWRITE(LIMITED_STRING(strDataHex, MAX_GOVERNANCE_OBJECT_DATA_SIZE)); + } + } else { + // using new format directly + READWRITE(vchData); + } READWRITE(nObjectType); if (nVersion == 70208) { // converting from/to old format diff --git a/src/governance-validators.cpp b/src/governance-validators.cpp index 1c6a946e15b9b..d36abdbfacd3e 100644 --- a/src/governance-validators.cpp +++ b/src/governance-validators.cpp @@ -10,7 +10,7 @@ #include CProposalValidator::CProposalValidator(const std::string& strDataHexIn) - : strData(), + : strDataHex(), objJSON(UniValue::VOBJ), fJSONValid(false), strErrorMessages() @@ -22,7 +22,7 @@ CProposalValidator::CProposalValidator(const std::string& strDataHexIn) void CProposalValidator::Clear() { - strData = std::string(); + strDataHex = std::string(); objJSON = UniValue(UniValue::VOBJ); fJSONValid = false; strErrorMessages = std::string(); @@ -31,7 +31,7 @@ void CProposalValidator::Clear() void CProposalValidator::SetHexData(const std::string& strDataHexIn) { std::vector v = ParseHex(strDataHexIn); - strData = std::string(v.begin(), v.end()); + strDataHex = std::string(v.begin(), v.end()); ParseJSONData(); } @@ -195,13 +195,13 @@ void CProposalValidator::ParseJSONData() { fJSONValid = false; - if(strData.empty()) { + if(strDataHex.empty()) { return; } try { UniValue obj(UniValue::VOBJ); - obj.read(strData); + obj.read(strDataHex); std::vector arr1 = obj.getValues(); std::vector arr2 = arr1.at(0).getValues(); objJSON = arr2.at(1); diff --git a/src/governance-validators.h b/src/governance-validators.h index 6e57c21dd24de..5445eb6e75665 100644 --- a/src/governance-validators.h +++ b/src/governance-validators.h @@ -50,7 +50,7 @@ class CProposalValidator { static bool CheckURL(const std::string& strURLIn); private: - std::string strData; + std::string strDataHex; UniValue objJSON; diff --git a/src/governance.cpp b/src/governance.cpp index b9003e83ced5e..ddcc84e5a4b02 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -348,8 +348,8 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CConnman // SHOULD WE ADD THIS OBJECT TO ANY OTHER MANANGERS? - DBG( cout << "CGovernanceManager::AddGovernanceObject Before trigger block, strData = " - << govobj.GetDataAsString() + DBG( cout << "CGovernanceManager::AddGovernanceObject Before trigger block, GetDataAsPlainString = " + << govobj.GetDataAsPlainString() << ", nObjectType = " << govobj.nObjectType << endl; ); diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index ecd060309c7a9..e0e1c06db9aaa 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -100,12 +100,12 @@ UniValue gobject(const JSONRPCRequest& request) int nRevision = 1; int64_t nTime = GetAdjustedTime(); - std::string strData = request.params[1].get_str(); + std::string strDataHex = request.params[1].get_str(); - CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strData); + CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strDataHex); if(govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) { - CProposalValidator validator(strData); + CProposalValidator validator(strDataHex); if(!validator.Validate()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages()); } @@ -144,14 +144,14 @@ UniValue gobject(const JSONRPCRequest& request) std::string strTime = request.params[3].get_str(); int nRevision = atoi(strRevision); int64_t nTime = atoi64(strTime); - std::string strData = request.params[4].get_str(); + std::string strDataHex = request.params[4].get_str(); // CREATE A NEW COLLATERAL TRANSACTION FOR THIS SPECIFIC OBJECT - CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strData); + CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strDataHex); if(govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) { - CProposalValidator validator(strData); + CProposalValidator validator(strDataHex); if(!validator.Validate()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages()); } @@ -183,7 +183,7 @@ UniValue gobject(const JSONRPCRequest& request) } DBG( cout << "gobject: prepare " - << " strData = " << govobj.GetDataAsString() + << " GetDataAsPlainString = " << govobj.GetDataAsPlainString() << ", hash = " << govobj.GetHash().GetHex() << ", txidFee = " << wtx.GetHash().GetHex() << endl; ); @@ -230,18 +230,18 @@ UniValue gobject(const JSONRPCRequest& request) std::string strTime = request.params[3].get_str(); int nRevision = atoi(strRevision); int64_t nTime = atoi64(strTime); - std::string strData = request.params[4].get_str(); + std::string strDataHex = request.params[4].get_str(); - CGovernanceObject govobj(hashParent, nRevision, nTime, txidFee, strData); + CGovernanceObject govobj(hashParent, nRevision, nTime, txidFee, strDataHex); DBG( cout << "gobject: submit " - << " strData = " << govobj.GetDataAsString() + << " GetDataAsPlainString = " << govobj.GetDataAsPlainString() << ", hash = " << govobj.GetHash().GetHex() << ", txidFee = " << txidFee.GetHex() << endl; ); if(govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) { - CProposalValidator validator(strData); + CProposalValidator validator(strDataHex); if(!validator.Validate()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages()); } @@ -655,8 +655,8 @@ UniValue gobject(const JSONRPCRequest& request) if(strType == "watchdogs" && pGovObj->GetObjectType() != GOVERNANCE_OBJECT_WATCHDOG) continue; UniValue bObj(UniValue::VOBJ); - bObj.push_back(Pair("DataHex", pGovObj->GetDataAsHex())); - bObj.push_back(Pair("DataString", pGovObj->GetDataAsString())); + bObj.push_back(Pair("DataHex", pGovObj->GetDataAsHexString())); + bObj.push_back(Pair("DataString", pGovObj->GetDataAsPlainString())); bObj.push_back(Pair("Hash", pGovObj->GetHash().ToString())); bObj.push_back(Pair("CollateralHash", pGovObj->GetCollateralHash().ToString())); bObj.push_back(Pair("ObjectType", pGovObj->GetObjectType())); @@ -707,8 +707,8 @@ UniValue gobject(const JSONRPCRequest& request) // REPORT BASIC OBJECT STATS UniValue objResult(UniValue::VOBJ); - objResult.push_back(Pair("DataHex", pGovObj->GetDataAsHex())); - objResult.push_back(Pair("DataString", pGovObj->GetDataAsString())); + objResult.push_back(Pair("DataHex", pGovObj->GetDataAsHexString())); + objResult.push_back(Pair("DataString", pGovObj->GetDataAsPlainString())); objResult.push_back(Pair("Hash", pGovObj->GetHash().ToString())); objResult.push_back(Pair("CollateralHash", pGovObj->GetCollateralHash().ToString())); objResult.push_back(Pair("ObjectType", pGovObj->GetObjectType()));