Skip to content

Commit 33bf875

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 d541388 commit 33bf875

File tree

4 files changed

+44
-13
lines changed

4 files changed

+44
-13
lines changed

divi/qa/rpc-tests/mnoperation.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,9 @@ def start_masternodes (self):
185185
assert_equal (lst[1]["tier"], "SILVER")
186186
for i in range (2):
187187
assert_equal (lst[i]["status"], "ENABLED")
188-
assert_equal (lst[i]["addr"],
189-
self.nodes[i + 1].getmasternodestatus ()["addr"])
188+
n = self.nodes[i + 1]
189+
for key in ["addr", "rewardscript"]:
190+
assert_equal (lst[i][key], n.getmasternodestatus ()[key])
190191
assert_equal (lst[i]["txhash"], self.cfg[i].txid)
191192
assert_equal (lst[i]["outidx"], self.cfg[i].vout)
192193

divi/src/masternode.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <utiltime.h>
2020

2121

22+
#include <sstream>
23+
2224
// keep track of the scanning errors I've seen
2325
std::map<uint256, int> mapSeenMasternodeScanningErrors;
2426
extern CChain chainActive;
@@ -817,6 +819,12 @@ bool CMasternodeBroadcastFactory::Create(
817819

818820
bool CMasternodeBroadcast::CheckAndUpdate(int& nDos)
819821
{
822+
/* Until the protocol is updated, do not allow custom reward scripts. */
823+
if (ActiveProtocol() < MN_REWARD_SCRIPT_VERSION && rewardScript != GetDefaultRewardScript()) {
824+
LogPrintf("%s : mnb - reward script does not match collateral address for %s\n", __func__, vin.prevout.ToString());
825+
return false;
826+
}
827+
820828
// make sure signature isn't in the future (past is OK)
821829
if (sigTime > GetAdjustedTime() + 60 * 60) {
822830
LogPrintf("%s : mnb - Signature rejected, too far into the future %s\n", __func__, vin.prevout.hash.ToString());
@@ -970,10 +978,28 @@ void CMasternodeBroadcast::Relay() const
970978

971979
std::string CMasternodeBroadcast::getMessageToSign() const
972980
{
973-
std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
974-
std::string vchPubKey2(pubKeyMasternode.begin(), pubKeyMasternode.end());
981+
std::ostringstream message;
982+
983+
message << addr.ToString();
984+
message << sigTime;
985+
message << std::string(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
986+
987+
/* The signature must commit also to the reward script. We do this by
988+
including it in the signed message if and only if it does not match
989+
the collateral address. This makes sure that the signature format
990+
is backwards compatible for situations where we just have the
991+
default reward script. */
992+
if (rewardScript != GetDefaultRewardScript()) {
993+
/* Include a "marker", so that e.g. a zero-length script is different
994+
from the default situation. */
995+
message << "rs";
996+
message << std::string(rewardScript.begin(), rewardScript.end());
997+
}
998+
999+
message << std::string(pubKeyMasternode.begin(), pubKeyMasternode.end());
1000+
message << protocolVersion;
9751001

976-
return addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion);
1002+
return message.str();
9771003
}
9781004

9791005
bool CMasternodeBroadcast::Sign(CKey& keyCollateralAddress, bool updateTimeBeforeSigning)

divi/src/masternode.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,14 @@ class CMasternodeBroadcast : public CMasternode
289289
READWRITE(vin);
290290
READWRITE(addr);
291291
READWRITE(pubKeyCollateralAddress);
292-
/* The wire format (for which the serialisation here is relevant)
293-
does not include the reward script yet. */
294-
if (ser_action.ForRead()) {
295-
rewardScript = GetDefaultRewardScript();
296-
} else if (rewardScript != GetDefaultRewardScript()) {
297-
LogPrintf("WARNING: CMasternodeBroadcast - ignoring changed reward script for serialisation of %s\n", vin.prevout.ToString());
292+
if (nVersion >= MN_REWARD_SCRIPT_VERSION) {
293+
READWRITE(rewardScript);
294+
} else {
295+
if (ser_action.ForRead()) {
296+
rewardScript = GetDefaultRewardScript();
297+
} else if (rewardScript != GetDefaultRewardScript()) {
298+
LogPrintf("WARNING: CMasternodeBroadcast - ignoring changed reward script for serialisation of %s\n", vin.prevout.ToString());
299+
}
298300
}
299301
READWRITE(pubKeyMasternode);
300302
READWRITE(sig);

divi/src/version.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
* network protocol versioning
1212
*/
1313

14-
static const int PROTOCOL_VERSION = 70915;
15-
1614
//! initial proto version, to be increased after version/verack negotiation
1715
static const int INIT_PROTO_VERSION = 209;
1816

@@ -35,5 +33,9 @@ static const int MEMPOOL_GD_VERSION = 60002;
3533
//! "filter*" commands are disabled without NODE_BLOOM after and including this version
3634
static const int NO_BLOOM_VERSION = 70005;
3735

36+
//! include explicit reward script in masternode broadcasts
37+
static constexpr int MN_REWARD_SCRIPT_VERSION = 71000;
38+
39+
static constexpr int PROTOCOL_VERSION = MN_REWARD_SCRIPT_VERSION;
3840

3941
#endif // BITCOIN_VERSION_H

0 commit comments

Comments
 (0)