1212#include " omnicore/utilsbitcoin.h"
1313#include " omnicore/version.h"
1414
15+ #include " alert.h"
1516#include " chainparams.h"
17+ #include " main.h"
1618#include " script/standard.h"
1719#include " uint256.h"
20+ #include " ui_interface.h"
1821
1922#include < openssl/sha.h>
2023
@@ -28,7 +31,12 @@ namespace mastercore
2831/* *
2932 * Pending activations
3033 */
31- std::vector<PendingActivation> PendingActivations;
34+ std::vector<FeatureActivation> PendingActivations;
35+
36+ /* *
37+ * Completed activations
38+ */
39+ std::vector<FeatureActivation> CompletedActivations;
3240
3341/* *
3442 * Returns a mapping of transaction types, and the blocks at which they are enabled.
@@ -318,18 +326,90 @@ bool IsAllowedOutputType(int whichType, int nBlock)
318326}
319327
320328/* *
321- * Adds a pending activation to the PendingActivations vector.
329+ * Adds a feature activation to the PendingActivations vector.
322330 *
323331 */
324332void AddPendingActivation (uint16_t featureId, int activationBlock, uint32_t minClientVersion, const std::string& featureName)
325333{
326- PendingActivation pa;
327- pa.featureId = featureId;
328- pa.activationBlock = activationBlock;
329- pa.minClientVersion = minClientVersion;
330- pa.featureName = featureName;
334+ FeatureActivation featureActivation;
331335
332- PendingActivations.push_back (pa);
336+ featureActivation.featureId = featureId;
337+ featureActivation.featureName = featureName;
338+ featureActivation.activationBlock = activationBlock;
339+ featureActivation.minClientVersion = minClientVersion;
340+
341+ PendingActivations.push_back (featureActivation);
342+ }
343+
344+ /* *
345+ * Deletes a pending activation from the PendingActivations vector. Deletion is not supported on the CompletedActivations vector.
346+ *
347+ */
348+ void DeletePendingActivation (uint16_t featureId)
349+ {
350+ for (std::vector<FeatureActivation>::iterator it = PendingActivations.begin (); it != PendingActivations.end (); ) {
351+ if ((*it).featureId == featureId) {
352+ it = PendingActivations.erase (it);
353+ } else {
354+ it++;
355+ }
356+ }
357+ }
358+
359+ /* *
360+ * Checks if any activations went live in the block
361+ *
362+ */
363+ void CheckLiveActivations (int blockHeight)
364+ {
365+ std::vector<FeatureActivation> PendingActivations = GetPendingActivations ();
366+ for (std::vector<FeatureActivation>::iterator it = PendingActivations.begin (); it != PendingActivations.end (); ++it) {
367+ if ((*it).activationBlock > blockHeight) continue ;
368+ FeatureActivation LiveActivation = *it;
369+ if (OMNICORE_VERSION < LiveActivation.minClientVersion ) {
370+ std::string msgText = strprintf (" Shutting down due to unsupported feature activation (%d: %s)" , LiveActivation.featureId , LiveActivation.featureName );
371+ PrintToLog (msgText);
372+ PrintToConsole (msgText);
373+ if (!GetBoolArg (" -overrideforcedshutdown" , false )) {
374+ AbortNode (msgText, msgText);
375+ }
376+ }
377+ PendingActivationCompleted (LiveActivation.featureId );
378+ uiInterface.OmniStateChanged ();
379+ }
380+ }
381+
382+ /* *
383+ * Moves an activation from PendingActivations to CompletedActivations when it is activated
384+ *
385+ */
386+ void PendingActivationCompleted (uint16_t featureId)
387+ {
388+ for (std::vector<FeatureActivation>::iterator it = PendingActivations.begin (); it != PendingActivations.end (); ) {
389+ if ((*it).featureId == featureId) {
390+ FeatureActivation completedActivation = *it;
391+ CompletedActivations.push_back (completedActivation);
392+ it = PendingActivations.erase (it);
393+ } else {
394+ it++;
395+ }
396+ }
397+ }
398+
399+ /* *
400+ * Returns the vector of pending activations.
401+ */
402+ std::vector<FeatureActivation> GetPendingActivations ()
403+ {
404+ return PendingActivations;
405+ }
406+
407+ /* *
408+ * Returns the vector of completed activations.
409+ */
410+ std::vector<FeatureActivation> GetCompletedActivations ()
411+ {
412+ return CompletedActivations;
333413}
334414
335415/* *
@@ -428,13 +508,14 @@ bool ActivateFeature(uint16_t featureId, int activationBlock, uint32_t minClient
428508 break ;
429509 }
430510 PrintToLog (" Feature activation of ID %d processed. %s will be enabled at block %d.\n " , featureId, featureName, activationBlock);
511+ DeletePendingActivation (featureId); // if this feature id was previously scheduled for activation, delete the stale pending object
431512 AddPendingActivation (featureId, activationBlock, minClientVersion, featureName);
432- AddAlert (" omnicore" , ALERT_BLOCK_EXPIRY, activationBlock, strprintf (" Feature %d ('%s') will go live at block %d" , featureId, featureName, activationBlock));
433513 if (!supported) {
434514 PrintToLog (" WARNING!!! AS OF BLOCK %d THIS CLIENT WILL BE OUT OF CONSENSUS AND WILL AUTOMATICALLY SHUTDOWN.\n " , activationBlock);
435- AddAlert (" omnicore" , ALERT_FEATURE_UNSUPPORTED, activationBlock,
436- strprintf (" Your client must be updated and will shutdown at block %d "
437- " (unsupported feature %d ('%s') activated)\n " , activationBlock, featureId, featureName));
515+ std::string alertText = strprintf (" Your client must be updated and will shutdown at block %d (unsupported feature %d ('%s') activated)\n " ,
516+ activationBlock, featureId, featureName);
517+ AddAlert (" omnicore" , ALERT_BLOCK_EXPIRY, activationBlock, alertText);
518+ CAlert::Notify (alertText, true );
438519 }
439520 return true ;
440521}
0 commit comments