Skip to content

Commit

Permalink
Merge pull request #429
Browse files Browse the repository at this point in the history
42579d5 Change 2 to OMNI_PROPERTY_TMSC to improve code readability (thanks dexx7) (zathras-crypto)
c1b65b3 Update test to check disabling the fee cache also (zathras-crypto)
d605a1e Improve the basic tests to cover MetaDEx refunds too (zathras-crypto)
e92cf25 Add refund of all orders on the MetaDEx if it's deactivated (zathras-crypto)
21ef723 Add basic deactivation tests (zathras-crypto)
0ccc5a5 Update comments to note where DeactivateFeature lives (zathras-crypto)
ded344c Add omni_senddeactivation to RPC (zathras-crypto)
0a1dd65 Add interpret_Deactivation() and logicMath_Deactivation() (zathras-crypto)
afbedee Add DeactivateFeature function (zathras-crypto)
9383ab1 Add deactivation transaction type to omnicore.h (zathras-crypto)
2df52d2 Add payload creation for deactivating features (zathras-crypto)
  • Loading branch information
dexX7 committed Nov 15, 2016
2 parents 8af9eae + 42579d5 commit 6568261
Show file tree
Hide file tree
Showing 16 changed files with 619 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/omnicore/activation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* This file contains feature activation utility code.
*
* Note main function 'ActivateFeature()' is consensus breaking and resides in rules.cpp
* Note main functions 'ActivateFeature()' and 'DeactivateFeature()' are consensus breaking and reside in rules.cpp
*/

#include "omnicore/activation.h"
Expand Down
18 changes: 18 additions & 0 deletions src/omnicore/createpayload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,24 @@ std::vector<unsigned char> CreatePayload_MetaDExCancelEcosystem(uint8_t ecosyste
return payload;
}

std::vector<unsigned char> CreatePayload_DeactivateFeature(uint16_t featureId)
{
std::vector<unsigned char> payload;

uint16_t messageVer = 65535;
uint16_t messageType = 65533;

mastercore::swapByteOrder16(messageVer);
mastercore::swapByteOrder16(messageType);
mastercore::swapByteOrder16(featureId);

PUSH_BACK_BYTES(payload, messageVer);
PUSH_BACK_BYTES(payload, messageType);
PUSH_BACK_BYTES(payload, featureId);

return payload;
}

std::vector<unsigned char> CreatePayload_ActivateFeature(uint16_t featureId, uint32_t activationBlock, uint32_t minClientVersion)
{
std::vector<unsigned char> payload;
Expand Down
1 change: 1 addition & 0 deletions src/omnicore/createpayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ std::vector<unsigned char> CreatePayload_MetaDExCancelPrice(uint32_t propertyIdF
std::vector<unsigned char> CreatePayload_MetaDExCancelPair(uint32_t propertyIdForSale, uint32_t propertyIdDesired);
std::vector<unsigned char> CreatePayload_MetaDExCancelEcosystem(uint8_t ecosystem);
std::vector<unsigned char> CreatePayload_OmniCoreAlert(uint16_t alertType, uint32_t expiryValue, const std::string& alertMessage);
std::vector<unsigned char> CreatePayload_DeactivateFeature(uint16_t featureId);
std::vector<unsigned char> CreatePayload_ActivateFeature(uint16_t featureId, uint32_t activationBlock, uint32_t minClientVersion);

#endif // OMNICORE_CREATEPAYLOAD_H
48 changes: 48 additions & 0 deletions src/omnicore/mdex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,54 @@ int mastercore::MetaDEx_CANCEL_EVERYTHING(const uint256& txid, unsigned int bloc
return rc;
}

/**
* Scans the orderbook and removes every all-pair order
*/
int mastercore::MetaDEx_SHUTDOWN_ALLPAIR()
{
int rc = 0;
PrintToLog("%s()\n", __FUNCTION__);
for (md_PropertiesMap::iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) {
md_PricesMap& prices = my_it->second;
for (md_PricesMap::iterator it = prices.begin(); it != prices.end(); ++it) {
md_Set& indexes = it->second;
for (md_Set::iterator it = indexes.begin(); it != indexes.end();) {
if (it->getDesProperty() > OMNI_PROPERTY_TMSC && it->getProperty() > OMNI_PROPERTY_TMSC) { // no OMNI/TOMNI side to the trade
PrintToLog("%s(): REMOVING %s\n", __FUNCTION__, it->ToString());
// move from reserve to balance
assert(update_tally_map(it->getAddr(), it->getProperty(), -it->getAmountRemaining(), METADEX_RESERVE));
assert(update_tally_map(it->getAddr(), it->getProperty(), it->getAmountRemaining(), BALANCE));
indexes.erase(it++);
}
}
}
}
return rc;
}

/**
* Scans the orderbook and removes every order
*/
int mastercore::MetaDEx_SHUTDOWN()
{
int rc = 0;
PrintToLog("%s()\n", __FUNCTION__);
for (md_PropertiesMap::iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) {
md_PricesMap& prices = my_it->second;
for (md_PricesMap::iterator it = prices.begin(); it != prices.end(); ++it) {
md_Set& indexes = it->second;
for (md_Set::iterator it = indexes.begin(); it != indexes.end();) {
PrintToLog("%s(): REMOVING %s\n", __FUNCTION__, it->ToString());
// move from reserve to balance
assert(update_tally_map(it->getAddr(), it->getProperty(), -it->getAmountRemaining(), METADEX_RESERVE));
assert(update_tally_map(it->getAddr(), it->getProperty(), it->getAmountRemaining(), BALANCE));
indexes.erase(it++);
}
}
}
return rc;
}

// searches the metadex maps to see if a trade is still open
// allows search to be optimized if propertyIdForSale is specified
bool mastercore::MetaDEx_isOpen(const uint256& txid, uint32_t propertyIdForSale)
Expand Down
2 changes: 2 additions & 0 deletions src/omnicore/mdex.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ int MetaDEx_ADD(const std::string& sender_addr, uint32_t, int64_t, int block, ui
int MetaDEx_CANCEL_AT_PRICE(const uint256&, uint32_t, const std::string&, uint32_t, int64_t, uint32_t, int64_t);
int MetaDEx_CANCEL_ALL_FOR_PAIR(const uint256&, uint32_t, const std::string&, uint32_t, uint32_t);
int MetaDEx_CANCEL_EVERYTHING(const uint256& txid, uint32_t block, const std::string& sender_addr, unsigned char ecosystem);
int MetaDEx_SHUTDOWN();
int MetaDEx_SHUTDOWN_ALLPAIR();
bool MetaDEx_INSERT(const CMPMetaDEx& objMetaDEx);
void MetaDEx_debug_print(bool bShowPriceLevel = false, bool bDisplay = false);
bool MetaDEx_isOpen(const uint256& txid, uint32_t propertyIdForSale = 0);
Expand Down
53 changes: 27 additions & 26 deletions src/omnicore/omnicore.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,32 +63,33 @@ int const MAX_STATE_HISTORY = 50;

// Transaction types, from the spec
enum TransactionType {
MSC_TYPE_SIMPLE_SEND = 0,
MSC_TYPE_RESTRICTED_SEND = 2,
MSC_TYPE_SEND_TO_OWNERS = 3,
MSC_TYPE_SEND_ALL = 4,
MSC_TYPE_SAVINGS_MARK = 10,
MSC_TYPE_SAVINGS_COMPROMISED = 11,
MSC_TYPE_RATELIMITED_MARK = 12,
MSC_TYPE_AUTOMATIC_DISPENSARY = 15,
MSC_TYPE_TRADE_OFFER = 20,
MSC_TYPE_ACCEPT_OFFER_BTC = 22,
MSC_TYPE_METADEX_TRADE = 25,
MSC_TYPE_METADEX_CANCEL_PRICE = 26,
MSC_TYPE_METADEX_CANCEL_PAIR = 27,
MSC_TYPE_METADEX_CANCEL_ECOSYSTEM = 28,
MSC_TYPE_NOTIFICATION = 31,
MSC_TYPE_OFFER_ACCEPT_A_BET = 40,
MSC_TYPE_CREATE_PROPERTY_FIXED = 50,
MSC_TYPE_CREATE_PROPERTY_VARIABLE = 51,
MSC_TYPE_PROMOTE_PROPERTY = 52,
MSC_TYPE_CLOSE_CROWDSALE = 53,
MSC_TYPE_CREATE_PROPERTY_MANUAL = 54,
MSC_TYPE_GRANT_PROPERTY_TOKENS = 55,
MSC_TYPE_REVOKE_PROPERTY_TOKENS = 56,
MSC_TYPE_CHANGE_ISSUER_ADDRESS = 70,
OMNICORE_MESSAGE_TYPE_ACTIVATION = 65534,
OMNICORE_MESSAGE_TYPE_ALERT = 65535
MSC_TYPE_SIMPLE_SEND = 0,
MSC_TYPE_RESTRICTED_SEND = 2,
MSC_TYPE_SEND_TO_OWNERS = 3,
MSC_TYPE_SEND_ALL = 4,
MSC_TYPE_SAVINGS_MARK = 10,
MSC_TYPE_SAVINGS_COMPROMISED = 11,
MSC_TYPE_RATELIMITED_MARK = 12,
MSC_TYPE_AUTOMATIC_DISPENSARY = 15,
MSC_TYPE_TRADE_OFFER = 20,
MSC_TYPE_ACCEPT_OFFER_BTC = 22,
MSC_TYPE_METADEX_TRADE = 25,
MSC_TYPE_METADEX_CANCEL_PRICE = 26,
MSC_TYPE_METADEX_CANCEL_PAIR = 27,
MSC_TYPE_METADEX_CANCEL_ECOSYSTEM = 28,
MSC_TYPE_NOTIFICATION = 31,
MSC_TYPE_OFFER_ACCEPT_A_BET = 40,
MSC_TYPE_CREATE_PROPERTY_FIXED = 50,
MSC_TYPE_CREATE_PROPERTY_VARIABLE = 51,
MSC_TYPE_PROMOTE_PROPERTY = 52,
MSC_TYPE_CLOSE_CROWDSALE = 53,
MSC_TYPE_CREATE_PROPERTY_MANUAL = 54,
MSC_TYPE_GRANT_PROPERTY_TOKENS = 55,
MSC_TYPE_REVOKE_PROPERTY_TOKENS = 56,
MSC_TYPE_CHANGE_ISSUER_ADDRESS = 70,
OMNICORE_MESSAGE_TYPE_DEACTIVATION = 65533,
OMNICORE_MESSAGE_TYPE_ACTIVATION = 65534,
OMNICORE_MESSAGE_TYPE_ALERT = 65535
};

#define MSC_PROPERTY_TYPE_INDIVISIBLE 1
Expand Down
41 changes: 41 additions & 0 deletions src/omnicore/rpctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,47 @@ Value omni_sendactivation(const Array& params, bool fHelp)
}
}

Value omni_senddeactivation(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 2)
throw runtime_error(
"omni_senddeactivation \"fromaddress\" featureid\n"
"\nDeactivate a protocol feature. For Emergency Use Only.\n"
"\nNote: Omni Core ignores deactivations from unauthorized sources.\n"
"\nArguments:\n"
"1. fromaddress (string, required) the address to send from\n"
"2. featureid (number, required) the identifier of the feature to activate\n"
"\nResult:\n"
"\"hash\" (string) the hex-encoded transaction hash\n"
"\nExamples:\n"
+ HelpExampleCli("omni_senddeactivation", "\"1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P\" 1")
+ HelpExampleRpc("omni_senddeactivation", "\"1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P\", 1")
);

// obtain parameters & info
std::string fromAddress = ParseAddress(params[0]);
uint16_t featureId = params[1].get_uint64();

// create a payload for the transaction
std::vector<unsigned char> payload = CreatePayload_DeactivateFeature(featureId);

// request the wallet build the transaction (and if needed commit it)
uint256 txid;
std::string rawHex;
int result = WalletTxBuilder(fromAddress, "", "", 0, payload, txid, rawHex, autoCommit);

// check error and return the txid (or raw hex depending on autocommit)
if (result != 0) {
throw JSONRPCError(result, error_str(result));
} else {
if (!autoCommit) {
return rawHex;
} else {
return txid.GetHex();
}
}
}

Value omni_sendalert(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 4)
Expand Down
98 changes: 86 additions & 12 deletions src/omnicore/rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ std::vector<TransactionRestriction> CConsensusParams::GetRestrictions() const
// ---------------------------------- ------------- ------- ------------------
{ OMNICORE_MESSAGE_TYPE_ALERT, 0xFFFF, true, MSC_ALERT_BLOCK },
{ OMNICORE_MESSAGE_TYPE_ACTIVATION, 0xFFFF, true, MSC_ALERT_BLOCK },
{ OMNICORE_MESSAGE_TYPE_DEACTIVATION, 0xFFFF, true, MSC_ALERT_BLOCK },

{ MSC_TYPE_SIMPLE_SEND, MP_TX_PKT_V0, false, MSC_SEND_BLOCK },

Expand Down Expand Up @@ -380,51 +381,40 @@ bool ActivateFeature(uint16_t featureId, int activationBlock, uint32_t minClient
}

// check feature is recognized and activation is successful
std::string featureName;
std::string featureName = GetFeatureName(featureId);
bool supported = OMNICORE_VERSION >= minClientVersion;
switch (featureId) {
case FEATURE_CLASS_C:
MutableConsensusParams().NULLDATA_BLOCK = activationBlock;
featureName = "Class C transaction encoding";
break;
case FEATURE_METADEX:
MutableConsensusParams().MSC_METADEX_BLOCK = activationBlock;
featureName = "Distributed Meta Token Exchange";
break;
case FEATURE_BETTING:
MutableConsensusParams().MSC_BET_BLOCK = activationBlock;
featureName = "Bet transactions";
break;
case FEATURE_GRANTEFFECTS:
MutableConsensusParams().GRANTEFFECTS_FEATURE_BLOCK = activationBlock;
featureName = "Remove grant side effects";
break;
case FEATURE_DEXMATH:
MutableConsensusParams().DEXMATH_FEATURE_BLOCK = activationBlock;
featureName = "DEx integer math update";
break;
case FEATURE_SENDALL:
MutableConsensusParams().MSC_SEND_ALL_BLOCK = activationBlock;
featureName = "Send All transactions";
break;
case FEATURE_SPCROWDCROSSOVER:
MutableConsensusParams().SPCROWDCROSSOVER_FEATURE_BLOCK = activationBlock;
featureName = "Disable crowdsale ecosystem crossovers";
break;
case FEATURE_TRADEALLPAIRS:
MutableConsensusParams().TRADEALLPAIRS_FEATURE_BLOCK = activationBlock;
featureName = "Allow trading all pairs on the Distributed Exchange";
break;
case FEATURE_FEES:
MutableConsensusParams().FEES_FEATURE_BLOCK = activationBlock;
featureName = "Fee system (inc 0.05% fee from trades of non-Omni pairs)";
break;
case FEATURE_STOV1:
MutableConsensusParams().MSC_STOV1_BLOCK = activationBlock;
featureName = "Cross-property Send To Owners";
break;
default:
featureName = "Unknown feature";
supported = false;
break;
}
Expand All @@ -443,6 +433,90 @@ bool ActivateFeature(uint16_t featureId, int activationBlock, uint32_t minClient
return true;
}

/**
* Deactivates a feature immediately, authorization has already been validated.
*
* Note: There is no notice period for feature deactivation as:
* # It is reserved for emergency use in the event an exploit is found
* # No client upgrade is required
* # No action is required by users
*/
bool DeactivateFeature(uint16_t featureId, int transactionBlock)
{
PrintToLog("Immediate feature deactivation requested (ID %d)\n", featureId);

if (!IsFeatureActivated(featureId, transactionBlock)) {
PrintToLog("Feature deactivation of ID %d refused as the feature is not yet live\n", featureId);
return false;
}

std::string featureName = GetFeatureName(featureId);
switch (featureId) {
case FEATURE_CLASS_C:
MutableConsensusParams().NULLDATA_BLOCK = 999999;
break;
case FEATURE_METADEX:
MutableConsensusParams().MSC_METADEX_BLOCK = 999999;
break;
case FEATURE_BETTING:
MutableConsensusParams().MSC_BET_BLOCK = 999999;
break;
case FEATURE_GRANTEFFECTS:
MutableConsensusParams().GRANTEFFECTS_FEATURE_BLOCK = 999999;
break;
case FEATURE_DEXMATH:
MutableConsensusParams().DEXMATH_FEATURE_BLOCK = 999999;
break;
case FEATURE_SENDALL:
MutableConsensusParams().MSC_SEND_ALL_BLOCK = 999999;
break;
case FEATURE_SPCROWDCROSSOVER:
MutableConsensusParams().SPCROWDCROSSOVER_FEATURE_BLOCK = 999999;
break;
case FEATURE_TRADEALLPAIRS:
MutableConsensusParams().TRADEALLPAIRS_FEATURE_BLOCK = 999999;
break;
case FEATURE_FEES:
MutableConsensusParams().FEES_FEATURE_BLOCK = 999999;
break;
case FEATURE_STOV1:
MutableConsensusParams().MSC_STOV1_BLOCK = 999999;
break;
default:
return false;
break;
}

PrintToLog("Feature deactivation of ID %d processed. %s has been disabled.\n", featureId, featureName);

std::string alertText = strprintf("An emergency deactivation of feature ID %d (%s) has occurred.", featureId, featureName);
AddAlert("omnicore", ALERT_BLOCK_EXPIRY, transactionBlock + 1024, alertText);
CAlert::Notify(alertText, true);

return true;
}

/**
* Returns the display name of a feature ID
*/
std::string GetFeatureName(uint16_t featureId)
{
switch (featureId) {
case FEATURE_CLASS_C: return "Class C transaction encoding";
case FEATURE_METADEX: return "Distributed Meta Token Exchange";
case FEATURE_BETTING: return "Bet transactions";
case FEATURE_GRANTEFFECTS: return "Remove grant side effects";
case FEATURE_DEXMATH: return "DEx integer math update";
case FEATURE_SENDALL: return "Send All transactions";
case FEATURE_SPCROWDCROSSOVER: return "Disable crowdsale ecosystem crossovers";
case FEATURE_TRADEALLPAIRS: return "Allow trading all pairs on the Distributed Exchange";
case FEATURE_FEES: return "Fee system (inc 0.05% fee from trades of non-Omni pairs)";
case FEATURE_STOV1: return "Cross-property Send To Owners";

default: return "Unknown feature";
}
}

/**
* Checks, whether a feature is activated at the given block.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/omnicore/rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,13 @@ CConsensusParams& MutableConsensusParams();
/** Resets consensus paramters. */
void ResetConsensusParams();


/** Gets the display name for a feature ID */
std::string GetFeatureName(uint16_t featureId);
/** Activates a feature at a specific block height. */
bool ActivateFeature(uint16_t featureId, int activationBlock, uint32_t minClientVersion, int transactionBlock);
/** Deactivates a feature immediately, authorization has already been validated. */
bool DeactivateFeature(uint16_t featureId, int transactionBlock);
/** Checks, whether a feature is activated at the given block. */
bool IsFeatureActivated(uint16_t featureId, int transactionBlock);
/** Checks, if the script type is allowed as input. */
Expand Down
9 changes: 9 additions & 0 deletions src/omnicore/test/create_payload_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,15 @@ BOOST_AUTO_TEST_CASE(payload_change_property_manager)
BOOST_CHECK_EQUAL(HexStr(vch), "000000460000000d");
}

BOOST_AUTO_TEST_CASE(payload_feature_deactivation)
{
// Omni Core feature activation [type 65533, version 65535]
std::vector<unsigned char> vch = CreatePayload_DeactivateFeature(
static_cast<uint16_t>(1)); // feature identifier: 1 (OP_RETURN)

BOOST_CHECK_EQUAL(HexStr(vch), "fffffffd0001");
}

BOOST_AUTO_TEST_CASE(payload_feature_activation)
{
// Omni Core feature activation [type 65534, version 65535]
Expand Down
Loading

0 comments on commit 6568261

Please sign in to comment.