Disallow new proposals using legacy serialization (#2722)
* add flag to allow legacy proposal format * add proposal validator ctor flag for legacy format * add test for legacy proposal format disabled
This commit is contained in:
parent
668b84b1e4
commit
fcd3b4fd49
@ -469,7 +469,7 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case GOVERNANCE_OBJECT_PROPOSAL: {
|
case GOVERNANCE_OBJECT_PROPOSAL: {
|
||||||
CProposalValidator validator(GetDataAsHexString());
|
CProposalValidator validator(GetDataAsHexString(), true);
|
||||||
// Note: It's ok to have expired proposals
|
// Note: It's ok to have expired proposals
|
||||||
// they are going to be cleared by CGovernanceManager::UpdateCachesAndClean()
|
// they are going to be cleared by CGovernanceManager::UpdateCachesAndClean()
|
||||||
// TODO: should they be tagged as "expired" to skip vote downloading?
|
// TODO: should they be tagged as "expired" to skip vote downloading?
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
const size_t MAX_DATA_SIZE = 512;
|
const size_t MAX_DATA_SIZE = 512;
|
||||||
const size_t MAX_NAME_SIZE = 40;
|
const size_t MAX_NAME_SIZE = 40;
|
||||||
|
|
||||||
CProposalValidator::CProposalValidator(const std::string& strHexData) :
|
CProposalValidator::CProposalValidator(const std::string& strHexData, bool fAllowLegacyFormat) :
|
||||||
objJSON(UniValue::VOBJ),
|
objJSON(UniValue::VOBJ),
|
||||||
fJSONValid(false),
|
fJSONValid(false),
|
||||||
|
fAllowLegacyFormat(fAllowLegacyFormat),
|
||||||
strErrorMessages()
|
strErrorMessages()
|
||||||
{
|
{
|
||||||
if (!strHexData.empty()) {
|
if (!strHexData.empty()) {
|
||||||
@ -207,9 +208,13 @@ void CProposalValidator::ParseJSONData(const std::string& strJSONData)
|
|||||||
if (obj.isObject()) {
|
if (obj.isObject()) {
|
||||||
objJSON = obj;
|
objJSON = obj;
|
||||||
} else {
|
} else {
|
||||||
std::vector<UniValue> arr1 = obj.getValues();
|
if (fAllowLegacyFormat) {
|
||||||
std::vector<UniValue> arr2 = arr1.at(0).getValues();
|
std::vector<UniValue> arr1 = obj.getValues();
|
||||||
objJSON = arr2.at(1);
|
std::vector<UniValue> arr2 = arr1.at(0).getValues();
|
||||||
|
objJSON = arr2.at(1);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Legacy proposal serialization format not allowed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fJSONValid = true;
|
fJSONValid = true;
|
||||||
|
@ -14,10 +14,11 @@ class CProposalValidator
|
|||||||
private:
|
private:
|
||||||
UniValue objJSON;
|
UniValue objJSON;
|
||||||
bool fJSONValid;
|
bool fJSONValid;
|
||||||
|
bool fAllowLegacyFormat;
|
||||||
std::string strErrorMessages;
|
std::string strErrorMessages;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CProposalValidator(const std::string& strDataHexIn = std::string());
|
CProposalValidator(const std::string& strDataHexIn = std::string(), bool fAllowLegacyFormat = true);
|
||||||
|
|
||||||
bool Validate(bool fCheckExpiration = true);
|
bool Validate(bool fCheckExpiration = true);
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ void CGovernanceManager::UpdateCachesAndClean()
|
|||||||
} else {
|
} else {
|
||||||
// NOTE: triggers are handled via triggerman
|
// NOTE: triggers are handled via triggerman
|
||||||
if (pObj->GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
|
if (pObj->GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
|
||||||
CProposalValidator validator(pObj->GetDataAsHexString());
|
CProposalValidator validator(pObj->GetDataAsHexString(), true);
|
||||||
if (!validator.Validate()) {
|
if (!validator.Validate()) {
|
||||||
LogPrintf("CGovernanceManager::UpdateCachesAndClean -- set for deletion expired obj %s\n", (*it).first.ToString());
|
LogPrintf("CGovernanceManager::UpdateCachesAndClean -- set for deletion expired obj %s\n", (*it).first.ToString());
|
||||||
pObj->fCachedDelete = true;
|
pObj->fCachedDelete = true;
|
||||||
|
@ -102,7 +102,7 @@ UniValue gobject_check(const JSONRPCRequest& request)
|
|||||||
CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strDataHex);
|
CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strDataHex);
|
||||||
|
|
||||||
if (govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
|
if (govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
|
||||||
CProposalValidator validator(strDataHex);
|
CProposalValidator validator(strDataHex, false);
|
||||||
if (!validator.Validate()) {
|
if (!validator.Validate()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ UniValue gobject_prepare(const JSONRPCRequest& request)
|
|||||||
govobj.GetDataAsPlainString(), govobj.GetHash().ToString());
|
govobj.GetDataAsPlainString(), govobj.GetHash().ToString());
|
||||||
|
|
||||||
if (govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
|
if (govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
|
||||||
CProposalValidator validator(strDataHex);
|
CProposalValidator validator(strDataHex, false);
|
||||||
if (!validator.Validate()) {
|
if (!validator.Validate()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ UniValue gobject_submit(const JSONRPCRequest& request)
|
|||||||
<< std::endl; );
|
<< std::endl; );
|
||||||
|
|
||||||
if (govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
|
if (govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
|
||||||
CProposalValidator validator(strDataHex);
|
CProposalValidator validator(strDataHex, false);
|
||||||
if (!validator.Validate()) {
|
if (!validator.Validate()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages());
|
||||||
}
|
}
|
||||||
|
@ -45,13 +45,18 @@ BOOST_AUTO_TEST_CASE(valid_proposals_test)
|
|||||||
|
|
||||||
// legacy format
|
// legacy format
|
||||||
std::string strHexData1 = CreateEncodedProposalObject(objProposal);
|
std::string strHexData1 = CreateEncodedProposalObject(objProposal);
|
||||||
CProposalValidator validator1(strHexData1);
|
CProposalValidator validator1(strHexData1, true);
|
||||||
BOOST_CHECK_MESSAGE(validator1.Validate(false), validator1.GetErrorMessages());
|
BOOST_CHECK_MESSAGE(validator1.Validate(false), validator1.GetErrorMessages());
|
||||||
BOOST_CHECK_MESSAGE(!validator1.Validate(), validator1.GetErrorMessages());
|
BOOST_CHECK_MESSAGE(!validator1.Validate(), validator1.GetErrorMessages());
|
||||||
|
|
||||||
|
// legacy format w/validation flag off
|
||||||
|
CProposalValidator validator0(strHexData1, false);
|
||||||
|
BOOST_CHECK(!validator0.Validate());
|
||||||
|
BOOST_CHECK_EQUAL(validator0.GetErrorMessages(), "Legacy proposal serialization format not allowed;JSON parsing error;");
|
||||||
|
|
||||||
// new format
|
// new format
|
||||||
std::string strHexData2 = HexStr(objProposal.write());
|
std::string strHexData2 = HexStr(objProposal.write());
|
||||||
CProposalValidator validator2(strHexData2);
|
CProposalValidator validator2(strHexData2, false);
|
||||||
BOOST_CHECK_MESSAGE(validator2.Validate(false), validator2.GetErrorMessages());
|
BOOST_CHECK_MESSAGE(validator2.Validate(false), validator2.GetErrorMessages());
|
||||||
BOOST_CHECK_MESSAGE(!validator2.Validate(), validator2.GetErrorMessages());
|
BOOST_CHECK_MESSAGE(!validator2.Validate(), validator2.GetErrorMessages());
|
||||||
}
|
}
|
||||||
@ -69,12 +74,12 @@ BOOST_AUTO_TEST_CASE(invalid_proposals_test)
|
|||||||
|
|
||||||
// legacy format
|
// legacy format
|
||||||
std::string strHexData1 = CreateEncodedProposalObject(objProposal);
|
std::string strHexData1 = CreateEncodedProposalObject(objProposal);
|
||||||
CProposalValidator validator1(strHexData1);
|
CProposalValidator validator1(strHexData1, true);
|
||||||
BOOST_CHECK_MESSAGE(!validator1.Validate(false), validator1.GetErrorMessages());
|
BOOST_CHECK_MESSAGE(!validator1.Validate(false), validator1.GetErrorMessages());
|
||||||
|
|
||||||
// new format
|
// new format
|
||||||
std::string strHexData2 = HexStr(objProposal.write());
|
std::string strHexData2 = HexStr(objProposal.write());
|
||||||
CProposalValidator validator2(strHexData2);
|
CProposalValidator validator2(strHexData2, false);
|
||||||
BOOST_CHECK_MESSAGE(!validator2.Validate(false), validator2.GetErrorMessages());
|
BOOST_CHECK_MESSAGE(!validator2.Validate(false), validator2.GetErrorMessages());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user