Skip to content

Commit

Permalink
Refactor masternodebroadcast to serialize/decode/relay multiple mas…
Browse files Browse the repository at this point in the history
…ternodes at once
  • Loading branch information
UdjinM6 committed Mar 17, 2016
1 parent 91b2546 commit c96284a
Showing 1 changed file with 75 additions and 37 deletions.
112 changes: 75 additions & 37 deletions src/rpcmasternode.cpp
Expand Up @@ -610,15 +610,15 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
return obj;
}

bool DecodeHexMnb(CMasternodeBroadcast& mnb, std::string strHexMnb) {
bool DecodeHexVecMnb(std::vector<CMasternodeBroadcast>& vecMnb, std::string strHexMnb) {

if (!IsHex(strHexMnb))
return false;

vector<unsigned char> mnbData(ParseHex(strHexMnb));
CDataStream ssData(mnbData, SER_NETWORK, PROTOCOL_VERSION);
try {
ssData >> mnb;
ssData >> vecMnb;
}
catch (const std::exception&) {
return false;
Expand Down Expand Up @@ -677,6 +677,8 @@ UniValue masternodebroadcast(const UniValue& params, bool fHelp)
bool found = false;

UniValue statusObj(UniValue::VOBJ);
std::vector<CMasternodeBroadcast> vecMnb;

statusObj.push_back(Pair("alias", alias));

BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
Expand All @@ -689,9 +691,10 @@ UniValue masternodebroadcast(const UniValue& params, bool fHelp)

statusObj.push_back(Pair("result", result ? "successful" : "failed"));
if(result) {
CDataStream ssMnb(SER_NETWORK, PROTOCOL_VERSION);
ssMnb << mnb;
statusObj.push_back(Pair("hex", HexStr(ssMnb.begin(), ssMnb.end())));
vecMnb.push_back(mnb);
CDataStream ssVecMnb(SER_NETWORK, PROTOCOL_VERSION);
ssVecMnb << vecMnb;
statusObj.push_back(Pair("hex", HexStr(ssVecMnb.begin(), ssVecMnb.end())));
} else {
statusObj.push_back(Pair("errorMessage", errorMessage));
}
Expand All @@ -700,7 +703,7 @@ UniValue masternodebroadcast(const UniValue& params, bool fHelp)
}

if(!found) {
statusObj.push_back(Pair("result", "failed"));
statusObj.push_back(Pair("result", "not found"));
statusObj.push_back(Pair("errorMessage", "Could not find alias in config. Verify with list-conf."));
}

Expand Down Expand Up @@ -737,6 +740,7 @@ UniValue masternodebroadcast(const UniValue& params, bool fHelp)
int failed = 0;

UniValue resultsObj(UniValue::VOBJ);
std::vector<CMasternodeBroadcast> vecMnb;

BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
std::string errorMessage;
Expand All @@ -752,9 +756,7 @@ UniValue masternodebroadcast(const UniValue& params, bool fHelp)

if(result) {
successful++;
CDataStream ssMnb(SER_NETWORK, PROTOCOL_VERSION);
ssMnb << mnb;
statusObj.push_back(Pair("hex", HexStr(ssMnb.begin(), ssMnb.end())));
vecMnb.push_back(mnb);
} else {
failed++;
statusObj.push_back(Pair("errorMessage", errorMessage));
Expand All @@ -764,9 +766,12 @@ UniValue masternodebroadcast(const UniValue& params, bool fHelp)
}
pwalletMain->Lock();

CDataStream ssVecMnb(SER_NETWORK, PROTOCOL_VERSION);
ssVecMnb << vecMnb;
UniValue returnObj(UniValue::VOBJ);
returnObj.push_back(Pair("overall", strprintf("Successfully created broadcast messages for %d masternodes, failed to create %d, total %d", successful, failed, successful + failed)));
returnObj.push_back(Pair("detail", resultsObj));
returnObj.push_back(Pair("hex", HexStr(ssVecMnb.begin(), ssVecMnb.end())));

return returnObj;
}
Expand All @@ -776,53 +781,86 @@ UniValue masternodebroadcast(const UniValue& params, bool fHelp)
if (params.size() != 2)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'masternodebroadcast decode \"hexstring\"'");

CMasternodeBroadcast mnb;
int successful = 0;
int failed = 0;

std::vector<CMasternodeBroadcast> vecMnb;
UniValue returnObj(UniValue::VOBJ);

if (!DecodeHexMnb(mnb, params[1].get_str()))
if (!DecodeHexVecMnb(vecMnb, params[1].get_str()))
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Masternode broadcast message decode failed");

if(!mnb.VerifySignature())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Masternode broadcast signature verification failed");

UniValue resultObj(UniValue::VOBJ);
BOOST_FOREACH(CMasternodeBroadcast& mnb, vecMnb) {
UniValue resultObj(UniValue::VOBJ);

resultObj.push_back(Pair("vin", mnb.vin.ToString()));
resultObj.push_back(Pair("addr", mnb.addr.ToString()));
resultObj.push_back(Pair("pubkey", CBitcoinAddress(mnb.pubkey.GetID()).ToString()));
resultObj.push_back(Pair("pubkey2", CBitcoinAddress(mnb.pubkey2.GetID()).ToString()));
resultObj.push_back(Pair("vchSig", EncodeBase64(&mnb.vchSig[0], mnb.vchSig.size())));
resultObj.push_back(Pair("sigTime", mnb.sigTime));
resultObj.push_back(Pair("protocolVersion", mnb.protocolVersion));
resultObj.push_back(Pair("nLastDsq", mnb.nLastDsq));
if(mnb.VerifySignature()) {
successful++;
resultObj.push_back(Pair("vin", mnb.vin.ToString()));
resultObj.push_back(Pair("addr", mnb.addr.ToString()));
resultObj.push_back(Pair("pubkey", CBitcoinAddress(mnb.pubkey.GetID()).ToString()));
resultObj.push_back(Pair("pubkey2", CBitcoinAddress(mnb.pubkey2.GetID()).ToString()));
resultObj.push_back(Pair("vchSig", EncodeBase64(&mnb.vchSig[0], mnb.vchSig.size())));
resultObj.push_back(Pair("sigTime", mnb.sigTime));
resultObj.push_back(Pair("protocolVersion", mnb.protocolVersion));
resultObj.push_back(Pair("nLastDsq", mnb.nLastDsq));

UniValue lastPingObj(UniValue::VOBJ);
lastPingObj.push_back(Pair("vin", mnb.lastPing.vin.ToString()));
lastPingObj.push_back(Pair("blockHash", mnb.lastPing.blockHash.ToString()));
lastPingObj.push_back(Pair("sigTime", mnb.lastPing.sigTime));
lastPingObj.push_back(Pair("vchSig", EncodeBase64(&mnb.lastPing.vchSig[0], mnb.lastPing.vchSig.size())));

resultObj.push_back(Pair("lastPing", lastPingObj));
} else {
failed++;
resultObj.push_back(Pair("errorMessage", "Masternode broadcast signature verification failed"));
}

UniValue lastPingObj(UniValue::VOBJ);
lastPingObj.push_back(Pair("vin", mnb.lastPing.vin.ToString()));
lastPingObj.push_back(Pair("blockHash", mnb.lastPing.blockHash.ToString()));
lastPingObj.push_back(Pair("sigTime", mnb.lastPing.sigTime));
lastPingObj.push_back(Pair("vchSig", EncodeBase64(&mnb.lastPing.vchSig[0], mnb.lastPing.vchSig.size())));
returnObj.push_back(Pair(mnb.GetHash().ToString(), resultObj));
}

resultObj.push_back(Pair("lastPing", lastPingObj));
returnObj.push_back(Pair("overall", strprintf("Successfully decoded broadcast messages for %d masternodes, failed to decode %d, total %d", successful, failed, successful + failed)));

return resultObj;
return returnObj;
}

if (strCommand == "relay")
{
if (params.size() != 2)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'masternodebroadcast relay \"hexstring\"'");

CMasternodeBroadcast mnb;
int successful = 0;
int failed = 0;

std::vector<CMasternodeBroadcast> vecMnb;
UniValue returnObj(UniValue::VOBJ);

if (!DecodeHexMnb(mnb, params[1].get_str()))
if (!DecodeHexVecMnb(vecMnb, params[1].get_str()))
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Masternode broadcast message decode failed");

if(!mnb.VerifySignature())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Masternode broadcast signature verification failed");
// verify all signatures first, bailout if any of them broken
BOOST_FOREACH(CMasternodeBroadcast& mnb, vecMnb) {
UniValue resultObj(UniValue::VOBJ);

mnodeman.UpdateMasternodeList(mnb);
mnb.Relay();
resultObj.push_back(Pair("vin", mnb.vin.ToString()));
resultObj.push_back(Pair("addr", mnb.addr.ToString()));

return strprintf("Masternode broadcast sent (service %s, vin %s)", mnb.addr.ToString(), mnb.vin.ToString());
if(mnb.VerifySignature()) {
successful++;
mnodeman.UpdateMasternodeList(mnb);
mnb.Relay();
resultObj.push_back(Pair(mnb.GetHash().ToString(), "successful"));
} else {
failed++;
resultObj.push_back(Pair("errorMessage", "Masternode broadcast signature verification failed"));
}

returnObj.push_back(Pair(mnb.GetHash().ToString(), resultObj));
}

returnObj.push_back(Pair("overall", strprintf("Successfully relayed broadcast messages for %d masternodes, failed to relay %d, total %d", successful, failed, successful + failed)));

return returnObj;
}

return NullUniValue;
Expand Down

0 comments on commit c96284a

Please sign in to comment.