@@ -964,6 +964,11 @@ bool GetCoinAge(const CTransaction& tx, const unsigned int nTxTime, uint64_t& nC
964964 return true ;
965965}
966966
967+ bool MoneyRange (CAmount nValueOut)
968+ {
969+ return nValueOut >= 0 && nValueOut <= Params ().MaxMoneyOut ();
970+ }
971+
967972bool CheckTransaction (const CTransaction& tx, CValidationState& state)
968973{
969974 // Basic checks that don't depend on any context
@@ -987,7 +992,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState& state)
987992 if (txout.nValue < 0 )
988993 return state.DoS (100 , error (" CheckTransaction() : txout.nValue negative" ),
989994 REJECT_INVALID, " bad-txns-vout-negative" );
990- if (txout.nValue > MAX_MONEY )
995+ if (txout.nValue > Params (). MaxMoneyOut () )
991996 return state.DoS (100 , error (" CheckTransaction() : txout.nValue too high" ),
992997 REJECT_INVALID, " bad-txns-vout-toolarge" );
993998 nValueOut += txout.nValue ;
@@ -1074,7 +1079,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
10741079 }
10751080
10761081 if (!MoneyRange (nMinFee))
1077- nMinFee = MAX_MONEY ;
1082+ nMinFee = Params (). MaxMoneyOut () ;
10781083 return nMinFee;
10791084}
10801085
@@ -2141,8 +2146,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
21412146 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
21422147 vPos.reserve (block.vtx .size ());
21432148 blockundo.vtxundo .reserve (block.vtx .size () - 1 );
2144- int64_t nValueOut = 0 ;
2145- int64_t nValueIn = 0 ;
2149+ CAmount nValueOut = 0 ;
2150+ CAmount nValueIn = 0 ;
21462151 for (unsigned int i = 0 ; i < block.vtx .size (); i++) {
21472152 const CTransaction& tx = block.vtx [i];
21482153
@@ -2152,7 +2157,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
21522157 return state.DoS (100 , error (" ConnectBlock() : too many sigops" ),
21532158 REJECT_INVALID, " bad-blk-sigops" );
21542159
2155- if (!tx.IsCoinBase ()) {
2160+ if (tx.IsCoinBase ())
2161+ {
2162+ nValueOut += tx.GetValueOut ();
2163+ }
2164+ else
2165+ {
21562166 if (!view.HaveInputs (tx))
21572167 return state.DoS (100 , error (" ConnectBlock() : inputs missing/spent" ),
21582168 REJECT_INVALID, " bad-txns-inputs-missingorspent" );
@@ -2167,15 +2177,19 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
21672177 REJECT_INVALID, " bad-blk-sigops" );
21682178 }
21692179
2170- nFees += view.GetValueIn (tx) - tx.GetValueOut ();
2171- nValueIn += view.GetValueIn (tx);
2180+
2181+ CAmount nTxValueIn = view.GetValueIn (tx);
2182+ CAmount nTxValueOut = tx.GetValueOut ();
2183+ nValueIn += nTxValueIn;
2184+ nValueOut += nTxValueOut;
2185+ if (!tx.IsCoinStake ())
2186+ nFees += nTxValueIn - nTxValueOut;
21722187
21732188 std::vector<CScriptCheck> vChecks;
21742189 if (!CheckInputs (tx, state, view, fScriptChecks , flags, false , nScriptCheckThreads ? &vChecks : NULL ))
21752190 return false ;
21762191 control.Add (vChecks);
21772192 }
2178- nValueOut += tx.GetValueOut ();
21792193
21802194 CTxUndo undoDummy;
21812195 if (i > 0 ) {
@@ -2187,9 +2201,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
21872201 pos.nTxOffset += ::GetSerializeSize (tx, SER_DISK, CLIENT_VERSION);
21882202 }
21892203
2190- // ppcoin: track money supply and mint amount info
2204+ CAmount nMoneySupplyPrev = pindex-> pprev ? pindex-> pprev -> nMoneySupply : 0 ;
21912205 pindex->nMint = nValueOut - nValueIn + nFees;
2192- pindex->nMoneySupply = (pindex->pprev ? pindex->pprev ->nMoneySupply : 0 ) + nValueOut - nValueIn;
2206+ pindex->nMoneySupply = nMoneySupplyPrev + nValueOut - nValueIn;
2207+
2208+ CAmount nExpectedMint = GetBlockValue (pindex->pprev ->nHeight );
2209+ if (pindex->pprev ->nHeight > 4200 && !IsBlockValueValid (block, nExpectedMint, pindex->nMint )) {
2210+ return state.DoS (100 ,
2211+ error (" ConnectBlock() : reward pays too much (actual=%s vs limit=%s)" ,
2212+ FormatMoney (pindex->nMint ), FormatMoney (nExpectedMint)),
2213+ REJECT_INVALID, " bad-cb-amount" );
2214+ }
21932215
21942216 if (!pblocktree->WriteBlockIndex (CDiskBlockIndex (pindex)))
21952217 return error (" Connect() : WriteBlockIndex for pindex failed" );
@@ -2198,13 +2220,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
21982220 nTimeConnect += nTime1 - nTimeStart;
21992221 LogPrint (" bench" , " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n " , (unsigned )block.vtx .size (), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx .size (), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs - 1 ), nTimeConnect * 0.000001 );
22002222
2201- if (!IsInitialBlockDownload () && !IsBlockValueValid (block, GetBlockValue (pindex->pprev ->nHeight ))) {
2202- return state.DoS (100 ,
2203- error (" ConnectBlock() : reward pays too much (actual=%d vs limit=%d)" ,
2204- block.vtx [0 ].GetValueOut (), GetBlockValue (pindex->pprev ->nHeight )),
2205- REJECT_INVALID, " bad-cb-amount" );
2206- }
2207-
22082223 if (!control.Wait ())
22092224 return state.DoS (100 , false );
22102225 int64_t nTime2 = GetTimeMicros ();
@@ -4590,14 +4605,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
45904605 CAddress addrFrom;
45914606 uint64_t nNonce = 1 ;
45924607 vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
4593- if (pfrom->nVersion < ActiveProtocol ()) {
4594- // disconnect from peers older than this proto version
4595- LogPrintf (" peer=%d using obsolete version %i; disconnecting\n " , pfrom->id , pfrom->nVersion );
4596- pfrom->PushMessage (" reject" , strCommand, REJECT_OBSOLETE,
4597- strprintf (" Version must be %d or greater" , ActiveProtocol ()));
4598- pfrom->fDisconnect = true ;
4608+ if (pfrom->DisconnectOldProtocol (ActiveProtocol (), strCommand))
45994609 return false ;
4600- }
46014610
46024611 if (pfrom->nVersion == 10300 )
46034612 pfrom->nVersion = 300 ;
@@ -5094,6 +5103,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
50945103 std::string strError = " invalid header received " + header.GetHash ().ToString ();
50955104 return error (strError.c_str ());
50965105 }
5106+
5107+ // disconnect this node if its old protocol version
5108+ pfrom->DisconnectOldProtocol (ActiveProtocol (), strCommand);
50975109 }
50985110 }
50995111
@@ -5143,6 +5155,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
51435155 TRY_LOCK (cs_main, lockMain);
51445156 if (lockMain) Misbehaving (pfrom->GetId (), nDoS);
51455157 }
5158+
5159+ // disconnect this node if its old protocol version
5160+ pfrom->DisconnectOldProtocol (ActiveProtocol (), strCommand);
51465161 }
51475162 }
51485163
@@ -5376,13 +5391,31 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
53765391 return true ;
53775392}
53785393
5394+ // Note: whenever a protocol update is needed toggle between both implementations (comment out the formerly active one)
5395+ // so we can leave the existing clients untouched (old SPORK will stay on so they don't see even older clients).
5396+ // Those old clients won't react to the changes of the other (new) SPORK because at the time of their implementation
5397+ // it was the one which was commented out
53795398int ActiveProtocol ()
53805399{
5400+
5401+ // SPORK_14 was used for 70710. Leave it 'ON' so they don't see < 70710 nodes. They won't react to SPORK_15
5402+ // messages because it's not in their code
5403+ /*
53815404 if (IsSporkActive(SPORK_14_NEW_PROTOCOL_ENFORCEMENT)) {
53825405 if (chainActive.Tip()->nHeight >= Params().ModifierUpgradeBlock())
53835406 return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT;
53845407 }
53855408
5409+ return MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT;
5410+ */
5411+
5412+
5413+ // SPORK_15 is used for 70910. Nodes < 70910 don't see it and still get their protocol version via SPORK_14 and their
5414+ // own ModifierUpgradeBlock()
5415+
5416+ if (IsSporkActive (SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2))
5417+ return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT;
5418+
53865419 return MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT;
53875420}
53885421
0 commit comments