Skip to content

Commit fa2f443

Browse files
committed
New wire protocol for reward script.
Define a new wire protocol version, and for peers that match the version, send the reward script as explicit part of the masternode broadcast messages. Also, if the reward script is not the default value, include it in the signature message of the broadcast (so that the field is authenticated by the collateral signature). Until the protocol version is bumped on the network (which is not yet the case with this commit), masternodes with non-default reward script will not be accepted as valid.
1 parent c94f464 commit fa2f443

File tree

5 files changed

+41
-10
lines changed

5 files changed

+41
-10
lines changed

divi/src/masternode.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <streams.h>
1414
#include <net.h>
1515

16+
#include <sstream>
17+
1618
CAmount CMasternode::GetTierCollateralAmount(const MasternodeTier tier)
1719
{
1820
const auto& collateralMap = Params().MasternodeCollateralMap();
@@ -267,10 +269,28 @@ void CMasternodeBroadcast::Relay() const
267269

268270
std::string CMasternodeBroadcast::getMessageToSign() const
269271
{
270-
std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
271-
std::string vchPubKey2(pubKeyMasternode.begin(), pubKeyMasternode.end());
272+
std::ostringstream message;
273+
274+
message << addr.ToString();
275+
message << sigTime;
276+
message << std::string(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
277+
278+
/* The signature must commit also to the reward script. We do this by
279+
including it in the signed message if and only if it does not match
280+
the collateral address. This makes sure that the signature format
281+
is backwards compatible for situations where we just have the
282+
default reward script. */
283+
if (rewardScript != GetDefaultRewardScript()) {
284+
/* Include a "marker", so that e.g. a zero-length script is different
285+
from the default situation. */
286+
message << "rs";
287+
message << std::string(rewardScript.begin(), rewardScript.end());
288+
}
289+
290+
message << std::string(pubKeyMasternode.begin(), pubKeyMasternode.end());
291+
message << protocolVersion;
272292

273-
return addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion);
293+
return message.str();
274294
}
275295

276296
uint256 CMasternodeBroadcast::GetHash() const

divi/src/masternode.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,14 @@ class CMasternodeBroadcast : public CMasternode
171171
READWRITE(vin);
172172
READWRITE(addr);
173173
READWRITE(pubKeyCollateralAddress);
174-
/* The wire format (for which the serialisation here is relevant)
175-
does not include the reward script yet. */
176-
if (ser_action.ForRead()) {
177-
rewardScript = GetDefaultRewardScript();
178-
} else if (rewardScript != GetDefaultRewardScript()) {
179-
LogPrintf("WARNING: CMasternodeBroadcast - ignoring changed reward script for serialisation of %s\n", vin.prevout.ToString());
174+
if (nVersion >= MN_REWARD_SCRIPT_VERSION) {
175+
READWRITE(rewardScript);
176+
} else {
177+
if (ser_action.ForRead()) {
178+
rewardScript = GetDefaultRewardScript();
179+
} else if (rewardScript != GetDefaultRewardScript()) {
180+
LogPrintf("WARNING: CMasternodeBroadcast - ignoring changed reward script for serialisation of %s\n", vin.prevout.ToString());
181+
}
180182
}
181183
READWRITE(pubKeyMasternode);
182184
READWRITE(signature);

divi/src/masternodeman.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ bool CMasternodeMan::CheckInputsForMasternode(const CMasternodeBroadcast& mnb, i
228228

229229
bool CMasternodeMan::CheckMasternodeBroadcastContext(CMasternodeBroadcast& mnb, int& nDoS)
230230
{
231+
/* Until the protocol is updated, do not allow custom reward scripts. */
232+
if (ActiveProtocol() < MN_REWARD_SCRIPT_VERSION && mnb.rewardScript != mnb.GetDefaultRewardScript()) {
233+
LogPrintf("%s : mnb - reward script does not match collateral address for %s\n", __func__, mnb.vin.prevout.ToString());
234+
return false;
235+
}
236+
231237
// make sure signature isn't in the future (past is OK)
232238
if (mnb.sigTime > GetAdjustedTime() + 60 * 60) {
233239
LogPrintf("%s : mnb - Signature rejected, too far into the future %s\n", __func__, mnb.vin.prevout.hash);

divi/src/version-util.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include <Logging.h>
44

5-
static int version = MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT;
5+
static int version = MN_REWARD_SCRIPT_VERSION;
66
const int& PROTOCOL_VERSION(version);
77

88
void SetProtocolVersion(const int newVersion)

divi/src/version.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ static constexpr int MEMPOOL_GD_VERSION = 60002;
3333
//! "filter*" commands are disabled without NODE_BLOOM after and including this version
3434
static constexpr int NO_BLOOM_VERSION = 70005;
3535

36+
//! include explicit reward script in masternode broadcasts
37+
static constexpr int MN_REWARD_SCRIPT_VERSION = 71000;
38+
3639
/** The current protocol version. Since it can be changed through -protocolversion
3740
* for testing, it is not a constexpr but a real variable. */
3841
extern const int& PROTOCOL_VERSION;

0 commit comments

Comments
 (0)