diff --git a/src/Makefile.am b/src/Makefile.am index 151e1a346..f75156bb6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -215,7 +215,7 @@ obj/build.h: FORCE @$(MKDIR_P) $(builddir)/obj @$(top_srcdir)/share/genbuild.sh "$(abs_top_builddir)/src/obj/build.h" \ "$(abs_top_srcdir)" -libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h +omnicore/libbitcoin_server_a-version.$(OBJEXT): obj/build.h # build info # server: shared between bitcoind and bitcoin-qt libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) diff --git a/src/omnicore/activation.cpp b/src/omnicore/activation.cpp index acd0f37a5..d84613cd6 100644 --- a/src/omnicore/activation.cpp +++ b/src/omnicore/activation.cpp @@ -8,6 +8,7 @@ #include "omnicore/activation.h" #include "omnicore/log.h" +#include "omnicore/utilsbitcoin.h" #include "omnicore/version.h" #include "validation.h" //NOTE: after-> main.h @@ -88,12 +89,9 @@ void CheckLiveActivations(int blockHeight) if (OMNICORE_VERSION < liveActivation.minClientVersion) { std::string msgText = strprintf("Shutting down due to unsupported feature activation (%d: %s)", liveActivation.featureId, liveActivation.featureName); PrintToLog(msgText); - PrintToConsole(msgText); - // if (!GetBoolArg("-overrideforcedshutdown", false)) { - // boost::filesystem::path persistPath = GetDataDir() / "MP_persist"; - // if (boost::filesystem::exists(persistPath)) boost::filesystem::remove_all(persistPath); // prevent the node being restarted without a reparse after forced shutdown - // AbortNode(msgText, msgText); - // } + if (!gArgs.GetBoolArg("-overrideforcedshutdown", false)) { + //AbortNode(msgText, msgText); TODO FIX AbortNode + } } PendingActivationCompleted(liveActivation); } @@ -154,33 +152,31 @@ bool CheckActivationAuthorization(const std::string& sender) "16oDZYCspsczfgKXVj3xyvsxH21NpEj94F" // Adam Chamely - adam@omni.foundation - Project maintainer, developer ], */ - whitelisted.insert("3Fc5gWzEQh1YGeqVXH6E4GDEGgbZJREJQ3"); + // @Blackbox and @Santos multisig 2 to 2 + whitelisted.insert("2N9doCzp1z2vDe9Go3sxeVTZ4YsNTBEzed3"); - // Testnet / Regtest + // Regtest // use -omniactivationallowsender for testing // Add manually whitelisted sources - // if (mapArgs.count("-omniactivationallowsender")) { - // const std::vector& sources = mapMultiArgs["-omniactivationallowsender"]; - // - // for (std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it) { - // whitelisted.insert(*it); - // } - // } + if (gArgs.IsArgSet("-omniactivationallowsender") && RegTest()) { + const std::vector& sources = gArgs.GetArgs("-omniactivationallowsender"); + + for (std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it) { + whitelisted.insert(*it); + } + } // Remove manually ignored sources - // if (mapArgs.count("-omniactivationignoresender")) { - // const std::vector& sources = mapMultiArgs["-omniactivationignoresender"]; - // - // for (std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it) { - // whitelisted.erase(*it); - // } - // } - - bool fAuthorized = (whitelisted.count(sender) || - whitelisted.count("any")); - - return fAuthorized; + if (gArgs.IsArgSet("-omniactivationignoresender") && RegTest()) { + const std::vector& sources = gArgs.GetArgs("-omniactivationignoresender"); + + for (std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it) { + whitelisted.erase(*it); + } + } + + return (whitelisted.count(sender) || whitelisted.count("any")); } /** @@ -205,33 +201,33 @@ bool CheckDeactivationAuthorization(const std::string& sender) "16oDZYCspsczfgKXVj3xyvsxH21NpEj94F" // Adam Chamely - adam@omni.foundation - Project maintainer, developer ], */ - whitelisted.insert("34kwkVRSvFVEoUwcQSgpQ4ZUasuZ54DJLD"); - // Testnet / Regtest + // @Blackbox and @Santos multisig 2 to 2 + whitelisted.insert("2N9doCzp1z2vDe9Go3sxeVTZ4YsNTBEzed3"); + + // Regtest // use -omniactivationallowsender for testing - // Add manually whitelisted sources - custom sources affect both activation and deactivation - // if (mapArgs.count("-omniactivationallowsender")) { - // const std::vector& sources = mapMultiArgs["-omniactivationallowsender"]; - // - // for (std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it) { - // whitelisted.insert(*it); - // } - // } + //Add manually whitelisted sources - custom sources affect both activation and deactivation + if (gArgs.IsArgSet("-omniactivationallowsender") && RegTest()) { + const std::vector& sources = gArgs.GetArgs("-omniactivationallowsender"); + + for (std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it) { + whitelisted.insert(*it); + } + } // Remove manually ignored sources - custom sources affect both activation and deactivation - // if (mapArgs.count("-omniactivationignoresender")) { - // const std::vector& sources = mapMultiArgs["-omniactivationignoresender"]; - // - // for (std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it) { - // whitelisted.erase(*it); - // } - // } - - bool fAuthorized = (whitelisted.count(sender) || - whitelisted.count("any")); - - return fAuthorized; + if (gArgs.IsArgSet("-omniactivationignoresender") && RegTest()) { + const std::vector& sources = gArgs.GetArgs("-omniactivationignoresender"); + + for (std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it) { + whitelisted.erase(*it); + } + } + + return (whitelisted.count(sender) || whitelisted.count("any")); + } } // namespace mastercore diff --git a/src/omnicore/consensushash.cpp b/src/omnicore/consensushash.cpp index 0bce98bec..c0f776632 100644 --- a/src/omnicore/consensushash.cpp +++ b/src/omnicore/consensushash.cpp @@ -5,9 +5,13 @@ */ #include "omnicore/consensushash.h" +#include "omnicore/dex.h" +#include "omnicore/mdex.h" +#include "omnicore/sp.h" #include "omnicore/log.h" #include "omnicore/omnicore.h" #include "omnicore/parse_string.h" +#include "omnicore/tally.h" #include "arith_uint256.h" @@ -22,27 +26,27 @@ namespace mastercore { -// bool ShouldConsensusHashBlock(int block) { -// if (msc_debug_consensus_hash_every_block) { -// return true; -// } -// -// if (!mapArgs.count("-omnishowblockconsensushash")) { -// return false; -// } -// -// const std::vector& vecBlocks = mapMultiArgs["-omnishowblockconsensushash"]; -// for (std::vector::const_iterator it = vecBlocks.begin(); it != vecBlocks.end(); ++it) { -// int64_t paramBlock = StrToInt64(*it, false); -// if (paramBlock < 1) continue; // ignore non numeric values -// if (paramBlock == block) { -// return true; -// } -// } -// -// return false; -// } -// +bool ShouldConsensusHashBlock(int block) { + if (msc_debug_consensus_hash_every_block) { + return true; + } + + if (!gArgs.IsArgSet("-omnishowblockconsensushash")) { + return false; + } + + const std::vector& vecBlocks = gArgs.GetArgs("-omnishowblockconsensushash"); + for (std::vector::const_iterator it = vecBlocks.begin(); it != vecBlocks.end(); ++it) { + int64_t paramBlock = StrToInt64(*it, false); + if (paramBlock < 1) continue; // ignore non numeric values + if (paramBlock == block) { + return true; + } + } + + return false; +} + // Generates a consensus string for hashing based on a tally object std::string GenerateConsensusString(const CMPTally& tallyObj, const std::string& address, const uint32_t propertyId) { @@ -57,94 +61,94 @@ std::string GenerateConsensusString(const CMPTally& tallyObj, const std::string& return strprintf("%s|%d|%d|%d|%d|%d", address, propertyId, balance, sellOfferReserve, acceptReserve, metaDExReserve); } -// -// // Generates a consensus string for hashing based on a DEx sell offer object -// std::string GenerateConsensusString(const CMPOffer& offerObj, const std::string& address) -// { -// return strprintf("%s|%s|%d|%d|%d|%d|%d", -// offerObj.getHash().GetHex(), address, offerObj.getProperty(), offerObj.getOfferAmountOriginal(), -// offerObj.getBTCDesiredOriginal(), offerObj.getMinFee(), offerObj.getBlockTimeLimit()); -// } -// -// // Generates a consensus string for hashing based on a DEx accept object -// // std::string GenerateConsensusString(const CMPAccept& acceptObj, const std::string& address) -// // { -// // return strprintf("%s|%s|%d|%d|%d", -// // acceptObj.getHash().GetHex(), address, acceptObj.getAcceptAmount(), acceptObj.getAcceptAmountRemaining(), -// // acceptObj.getAcceptBlock()); -// // } -// -// // Generates a consensus string for hashing based on a MetaDEx object -// // std::string GenerateConsensusString(const CMPMetaDEx& tradeObj) -// // { -// // return strprintf("%s|%s|%d|%d|%d|%d|%d", -// // tradeObj.getHash().GetHex(), tradeObj.getAddr(), tradeObj.getProperty(), tradeObj.getAmountForSale(), -// // tradeObj.getDesProperty(), tradeObj.getAmountDesired(), tradeObj.getAmountRemaining()); -// // } -// -// // Generates a consensus string for hashing based on a crowdsale object -// // std::string GenerateConsensusString(const CMPCrowd& crowdObj) -// // { -// // return strprintf("%d|%d|%d|%d|%d", -// // crowdObj.getPropertyId(), crowdObj.getCurrDes(), crowdObj.getDeadline(), crowdObj.getUserCreated(), -// // crowdObj.getIssuerCreated()); -// // } -// -// // Generates a consensus string for hashing based on a property issuer -// std::string GenerateConsensusString(const uint32_t propertyId, const std::string& address) -// { -// return strprintf("%d|%s", propertyId, address); -// } -// -// /** -// * Obtains a hash of the active state to use for consensus verification and checkpointing. -// * -// * For increased flexibility, so other implementations like OmniWallet and OmniChest can -// * also apply this methodology without necessarily using the same exact data types (which -// * would be needed to hash the data bytes directly), create a string in the following -// * format for each entry to use for hashing: -// * -// * ---STAGE 1 - BALANCES--- -// * Format specifiers & placeholders: -// * "%s|%d|%d|%d|%d|%d" - "address|propertyid|balance|selloffer_reserve|accept_reserve|metadex_reserve" -// * -// * Note: empty balance records and the pending tally are ignored. Addresses are sorted based -// * on lexicographical order, and balance records are sorted by the property identifiers. -// * -// * ---STAGE 2 - DEX SELL OFFERS--- -// * Format specifiers & placeholders: -// * "%s|%s|%d|%d|%d|%d|%d" - "txid|address|propertyid|offeramount|btcdesired|minfee|timelimit" -// * -// * Note: ordered ascending by txid. -// * -// * ---STAGE 3 - DEX ACCEPTS--- -// * Format specifiers & placeholders: -// * "%s|%s|%d|%d|%d" - "matchedselloffertxid|buyer|acceptamount|acceptamountremaining|acceptblock" -// * -// * Note: ordered ascending by matchedselloffertxid followed by buyer. -// * -// * ---STAGE 4 - METADEX TRADES--- -// * Format specifiers & placeholders: -// * "%s|%s|%d|%d|%d|%d|%d" - "txid|address|propertyidforsale|amountforsale|propertyiddesired|amountdesired|amountremaining" -// * -// * Note: ordered ascending by txid. -// * -// * ---STAGE 5 - CROWDSALES--- -// * Format specifiers & placeholders: -// * "%d|%d|%d|%d|%d" - "propertyid|propertyiddesired|deadline|usertokens|issuertokens" -// * -// * Note: ordered by property ID. -// * -// * ---STAGE 6 - PROPERTIES--- -// * Format specifiers & placeholders: -// * "%d|%s" - "propertyid|issueraddress" -// * -// * Note: ordered by property ID. -// * -// * The byte order is important, and we assume: -// * SHA256("abc") = "ad1500f261ff10b49c7a1796a36103b02322ae5dde404141eacf018fbf1678ba" -// * -// */ + +// Generates a consensus string for hashing based on a DEx sell offer object +std::string GenerateConsensusString(const CMPOffer& offerObj, const std::string& address) +{ + return strprintf("%s|%s|%d|%d|%d|%d|%d", + offerObj.getHash().GetHex(), address, offerObj.getProperty(), offerObj.getOfferAmountOriginal(), + offerObj.getBTCDesiredOriginal(), offerObj.getMinFee(), offerObj.getBlockTimeLimit()); +} + +// Generates a consensus string for hashing based on a DEx accept object +std::string GenerateConsensusString(const CMPAccept& acceptObj, const std::string& address) +{ + return strprintf("%s|%s|%d|%d|%d", + acceptObj.getHash().GetHex(), address, acceptObj.getAcceptAmount(), acceptObj.getAcceptAmountRemaining(), + acceptObj.getAcceptBlock()); +} + +// Generates a consensus string for hashing based on a MetaDEx object +std::string GenerateConsensusString(const CMPMetaDEx& tradeObj) +{ + return strprintf("%s|%s|%d|%d|%d|%d|%d", + tradeObj.getHash().GetHex(), tradeObj.getAddr(), tradeObj.getProperty(), tradeObj.getAmountForSale(), + tradeObj.getDesProperty(), tradeObj.getAmountDesired(), tradeObj.getAmountRemaining()); +} + +// Generates a consensus string for hashing based on a crowdsale object +std::string GenerateConsensusString(const CMPCrowd& crowdObj) +{ + return strprintf("%d|%d|%d|%d|%d", + crowdObj.getPropertyId(), crowdObj.getCurrDes(), crowdObj.getDeadline(), crowdObj.getUserCreated(), + crowdObj.getIssuerCreated()); +} + +// Generates a consensus string for hashing based on a property issuer +std::string GenerateConsensusString(const uint32_t propertyId, const std::string& address) +{ + return strprintf("%d|%s", propertyId, address); +} + +/** + * Obtains a hash of the active state to use for consensus verification and checkpointing. + * + * For increased flexibility, so other implementations like OmniWallet and OmniChest can + * also apply this methodology without necessarily using the same exact data types (which + * would be needed to hash the data bytes directly), create a string in the following + * format for each entry to use for hashing: + * + * ---STAGE 1 - BALANCES--- + * Format specifiers & placeholders: + * "%s|%d|%d|%d|%d|%d" - "address|propertyid|balance|selloffer_reserve|accept_reserve|metadex_reserve" + * + * Note: empty balance records and the pending tally are ignored. Addresses are sorted based + * on lexicographical order, and balance records are sorted by the property identifiers. + * + * ---STAGE 2 - DEX SELL OFFERS--- + * Format specifiers & placeholders: + * "%s|%s|%d|%d|%d|%d|%d" - "txid|address|propertyid|offeramount|btcdesired|minfee|timelimit" + * + * Note: ordered ascending by txid. + * + * ---STAGE 3 - DEX ACCEPTS--- + * Format specifiers & placeholders: + * "%s|%s|%d|%d|%d" - "matchedselloffertxid|buyer|acceptamount|acceptamountremaining|acceptblock" + * + * Note: ordered ascending by matchedselloffertxid followed by buyer. + * + * ---STAGE 4 - METADEX TRADES--- + * Format specifiers & placeholders: + * "%s|%s|%d|%d|%d|%d|%d" - "txid|address|propertyidforsale|amountforsale|propertyiddesired|amountdesired|amountremaining" + * + * Note: ordered ascending by txid. + * + * ---STAGE 5 - CROWDSALES--- + * Format specifiers & placeholders: + * "%d|%d|%d|%d|%d" - "propertyid|propertyiddesired|deadline|usertokens|issuertokens" + * + * Note: ordered by property ID. + * + * ---STAGE 6 - PROPERTIES--- + * Format specifiers & placeholders: + * "%d|%s" - "propertyid|issueraddress" + * + * Note: ordered by property ID. + * + * The byte order is important, and we assume: + * SHA256("abc") = "ad1500f261ff10b49c7a1796a36103b02322ae5dde404141eacf018fbf1678ba" + * + */ uint256 GetConsensusHash() { // allocate and init a SHA256_CTX @@ -177,95 +181,95 @@ uint256 GetConsensusHash() // DEx sell offers - loop through the DEx and add each sell offer to the consensus hash (ordered by txid) // Placeholders: "txid|address|propertyid|offeramount|btcdesired|minfee|timelimit" - // std::vector > vecDExOffers; - // for (OfferMap::iterator it = my_offers.begin(); it != my_offers.end(); ++it) { - // const CMPOffer& selloffer = it->second; - // const std::string& sellCombo = it->first; - // std::string seller = sellCombo.substr(0, sellCombo.size() - 2); - // std::string dataStr = GenerateConsensusString(selloffer, seller); - // vecDExOffers.push_back(std::make_pair(arith_uint256(selloffer.getHash().ToString()), dataStr)); - // } - // std::sort (vecDExOffers.begin(), vecDExOffers.end()); - // for (std::vector >::iterator it = vecDExOffers.begin(); it != vecDExOffers.end(); ++it) { - // const std::string& dataStr = it->second; - // if (msc_debug_consensus_hash) PrintToLog("Adding DEx offer data to consensus hash: %s\n", dataStr); - // SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); - // } + std::vector > vecDExOffers; + for (OfferMap::iterator it = my_offers.begin(); it != my_offers.end(); ++it) { + const CMPOffer& selloffer = it->second; + const std::string& sellCombo = it->first; + std::string seller = sellCombo.substr(0, sellCombo.size() - 2); + std::string dataStr = GenerateConsensusString(selloffer, seller); + vecDExOffers.push_back(std::make_pair(arith_uint256(selloffer.getHash().ToString()), dataStr)); + } + std::sort (vecDExOffers.begin(), vecDExOffers.end()); + for (std::vector >::iterator it = vecDExOffers.begin(); it != vecDExOffers.end(); ++it) { + const std::string& dataStr = it->second; + if (msc_debug_consensus_hash) PrintToLog("Adding DEx offer data to consensus hash: %s\n", dataStr); + SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); + } // DEx accepts - loop through the accepts map and add each accept to the consensus hash (ordered by matchedtxid then buyer) // Placeholders: "matchedselloffertxid|buyer|acceptamount|acceptamountremaining|acceptblock" - // std::vector > vecAccepts; - // for (AcceptMap::const_iterator it = my_accepts.begin(); it != my_accepts.end(); ++it) { - // const CMPAccept& accept = it->second; - // const std::string& acceptCombo = it->first; - // std::string buyer = acceptCombo.substr((acceptCombo.find("+") + 1), (acceptCombo.size()-(acceptCombo.find("+") + 1))); - // std::string dataStr = GenerateConsensusString(accept, buyer); - // std::string sortKey = strprintf("%s-%s", accept.getHash().GetHex(), buyer); - // vecAccepts.push_back(std::make_pair(sortKey, dataStr)); - // } - // std::sort (vecAccepts.begin(), vecAccepts.end()); - // for (std::vector >::iterator it = vecAccepts.begin(); it != vecAccepts.end(); ++it) { - // const std::string& dataStr = it->second; - // if (msc_debug_consensus_hash) PrintToLog("Adding DEx accept to consensus hash: %s\n", dataStr); - // SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); - // } + std::vector > vecAccepts; + for (AcceptMap::const_iterator it = my_accepts.begin(); it != my_accepts.end(); ++it) { + const CMPAccept& accept = it->second; + const std::string& acceptCombo = it->first; + std::string buyer = acceptCombo.substr((acceptCombo.find("+") + 1), (acceptCombo.size()-(acceptCombo.find("+") + 1))); + std::string dataStr = GenerateConsensusString(accept, buyer); + std::string sortKey = strprintf("%s-%s", accept.getHash().GetHex(), buyer); + vecAccepts.push_back(std::make_pair(sortKey, dataStr)); + } + std::sort (vecAccepts.begin(), vecAccepts.end()); + for (std::vector >::iterator it = vecAccepts.begin(); it != vecAccepts.end(); ++it) { + const std::string& dataStr = it->second; + if (msc_debug_consensus_hash) PrintToLog("Adding DEx accept to consensus hash: %s\n", dataStr); + SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); + } // MetaDEx trades - loop through the MetaDEx maps and add each open trade to the consensus hash (ordered by txid) // Placeholders: "txid|address|propertyidforsale|amountforsale|propertyiddesired|amountdesired|amountremaining" - // std::vector > vecMetaDExTrades; - // for (md_PropertiesMap::const_iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) { - // const md_PricesMap& prices = my_it->second; - // for (md_PricesMap::const_iterator it = prices.begin(); it != prices.end(); ++it) { - // const md_Set& indexes = it->second; - // for (md_Set::const_iterator it = indexes.begin(); it != indexes.end(); ++it) { - // const CMPMetaDEx& obj = *it; - // std::string dataStr = GenerateConsensusString(obj); - // vecMetaDExTrades.push_back(std::make_pair(arith_uint256(obj.getHash().ToString()), dataStr)); - // } - // } - // } - // std::sort (vecMetaDExTrades.begin(), vecMetaDExTrades.end()); - // for (std::vector >::iterator it = vecMetaDExTrades.begin(); it != vecMetaDExTrades.end(); ++it) { - // const std::string& dataStr = it->second; - // if (msc_debug_consensus_hash) PrintToLog("Adding MetaDEx trade data to consensus hash: %s\n", dataStr); - // SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); - // } + std::vector > vecMetaDExTrades; + for (md_PropertiesMap::const_iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) { + const md_PricesMap& prices = my_it->second; + for (md_PricesMap::const_iterator it = prices.begin(); it != prices.end(); ++it) { + const md_Set& indexes = it->second; + for (md_Set::const_iterator it = indexes.begin(); it != indexes.end(); ++it) { + const CMPMetaDEx& obj = *it; + std::string dataStr = GenerateConsensusString(obj); + vecMetaDExTrades.push_back(std::make_pair(arith_uint256(obj.getHash().ToString()), dataStr)); + } + } + } + std::sort (vecMetaDExTrades.begin(), vecMetaDExTrades.end()); + for (std::vector >::iterator it = vecMetaDExTrades.begin(); it != vecMetaDExTrades.end(); ++it) { + const std::string& dataStr = it->second; + if (msc_debug_consensus_hash) PrintToLog("Adding MetaDEx trade data to consensus hash: %s\n", dataStr); + SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); + } // Crowdsales - loop through open crowdsales and add to the consensus hash (ordered by property ID) // Note: the variables of the crowdsale (amount, bonus etc) are not part of the crowdsale map and not included here to // avoid additionalal loading of SP entries from the database // Placeholders: "propertyid|propertyiddesired|deadline|usertokens|issuertokens" - // std::vector > vecCrowds; - // for (CrowdMap::const_iterator it = my_crowds.begin(); it != my_crowds.end(); ++it) { - // const CMPCrowd& crowd = it->second; - // uint32_t propertyId = crowd.getPropertyId(); - // std::string dataStr = GenerateConsensusString(crowd); - // vecCrowds.push_back(std::make_pair(propertyId, dataStr)); - // } - // std::sort (vecCrowds.begin(), vecCrowds.end()); - // for (std::vector >::iterator it = vecCrowds.begin(); it != vecCrowds.end(); ++it) { - // std::string dataStr = (*it).second; - // if (msc_debug_consensus_hash) PrintToLog("Adding Crowdsale entry to consensus hash: %s\n", dataStr); - // SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); - // } + std::vector > vecCrowds; + for (CrowdMap::const_iterator it = my_crowds.begin(); it != my_crowds.end(); ++it) { + const CMPCrowd& crowd = it->second; + uint32_t propertyId = crowd.getPropertyId(); + std::string dataStr = GenerateConsensusString(crowd); + vecCrowds.push_back(std::make_pair(propertyId, dataStr)); + } + std::sort (vecCrowds.begin(), vecCrowds.end()); + for (std::vector >::iterator it = vecCrowds.begin(); it != vecCrowds.end(); ++it) { + std::string dataStr = (*it).second; + if (msc_debug_consensus_hash) PrintToLog("Adding Crowdsale entry to consensus hash: %s\n", dataStr); + SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); + } // Properties - loop through each property and store the issuer (to capture state changes via change issuer transactions) // Note: we are loading every SP from the DB to check the issuer, if using consensus_hash_every_block debug option this // will slow things down dramatically. Not an issue to do it once every 10,000 blocks for checkpoint verification. // Placeholders: "propertyid|issueraddress" - // for (uint8_t ecosystem = 1; ecosystem <= 2; ecosystem++) { - // uint32_t startPropertyId = (ecosystem == 1) ? 1 : TEST_ECO_PROPERTY_1; - // for (uint32_t propertyId = startPropertyId; propertyId < _my_sps->peekNextSPID(ecosystem); propertyId++) { - // CMPSPInfo::Entry sp; - // if (!_my_sps->getSP(propertyId, sp)) { - // PrintToLog("Error loading property ID %d for consensus hashing, hash should not be trusted!\n"); - // continue; - // } - // std::string dataStr = GenerateConsensusString(propertyId, sp.issuer); - // if (msc_debug_consensus_hash) PrintToLog("Adding property to consensus hash: %s\n", dataStr); - // SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); - // } - // } + for (uint8_t ecosystem = 1; ecosystem <= 2; ecosystem++) { + uint32_t startPropertyId = (ecosystem == 1) ? 1 : TEST_ECO_PROPERTY_1; + for (uint32_t propertyId = startPropertyId; propertyId < _my_sps->peekNextSPID(ecosystem); propertyId++) { + CMPSPInfo::Entry sp; + if (!_my_sps->getSP(propertyId, sp)) { + PrintToLog("Error loading property ID %d for consensus hashing, hash should not be trusted!\n"); + continue; + } + std::string dataStr = GenerateConsensusString(propertyId, sp.issuer); + if (msc_debug_consensus_hash) PrintToLog("Adding property to consensus hash: %s\n", dataStr); + SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); + } + } // extract the final result and return the hash uint256 consensusHash; @@ -274,70 +278,70 @@ uint256 GetConsensusHash() return consensusHash; } -// -// uint256 GetMetaDExHash(const uint32_t propertyId) -// { -// SHA256_CTX shaCtx; -// SHA256_Init(&shaCtx); -// -// LOCK(cs_tally); -// -// std::vector > vecMetaDExTrades; -// for (md_PropertiesMap::const_iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) { -// if (propertyId == 0 || propertyId == my_it->first) { -// const md_PricesMap& prices = my_it->second; -// for (md_PricesMap::const_iterator it = prices.begin(); it != prices.end(); ++it) { -// const md_Set& indexes = it->second; -// for (md_Set::const_iterator it = indexes.begin(); it != indexes.end(); ++it) { -// const CMPMetaDEx& obj = *it; -// std::string dataStr = GenerateConsensusString(obj); -// vecMetaDExTrades.push_back(std::make_pair(arith_uint256(obj.getHash().ToString()), dataStr)); -// } -// } -// } -// } -// std::sort (vecMetaDExTrades.begin(), vecMetaDExTrades.end()); -// for (std::vector >::iterator it = vecMetaDExTrades.begin(); it != vecMetaDExTrades.end(); ++it) { -// const std::string& dataStr = it->second; -// SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); -// } -// -// uint256 metadexHash; -// SHA256_Final((unsigned char*)&metadexHash, &shaCtx); -// -// return metadexHash; -// } -// -// /** Obtains a hash of the balances for a specific property. */ -// uint256 GetBalancesHash(const uint32_t hashPropertyId) -// { -// SHA256_CTX shaCtx; -// SHA256_Init(&shaCtx); -// -// LOCK(cs_tally); -// -// std::map tallyMapSorted; -// for (std::unordered_map::iterator uoit = mp_tally_map.begin(); uoit != mp_tally_map.end(); ++uoit) { -// tallyMapSorted.insert(std::make_pair(uoit->first,uoit->second)); -// } -// for (std::map::iterator my_it = tallyMapSorted.begin(); my_it != tallyMapSorted.end(); ++my_it) { -// const std::string& address = my_it->first; -// CMPTally& tally = my_it->second; -// tally.init(); -// uint32_t propertyId = 0; -// while (0 != (propertyId = (tally.next()))) { -// if (propertyId != hashPropertyId) continue; -// std::string dataStr = GenerateConsensusString(tally, address, propertyId); -// if (dataStr.empty()) continue; -// if (msc_debug_consensus_hash) PrintToLog("Adding data to balances hash: %s\n", dataStr); -// SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); -// } -// } -// -// uint256 balancesHash; -// SHA256_Final((unsigned char*)&balancesHash, &shaCtx); -// -// return balancesHash; -// } -// + +uint256 GetMetaDExHash(const uint32_t propertyId) +{ + SHA256_CTX shaCtx; + SHA256_Init(&shaCtx); + + LOCK(cs_tally); + + std::vector > vecMetaDExTrades; + for (md_PropertiesMap::const_iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) { + if (propertyId == 0 || propertyId == my_it->first) { + const md_PricesMap& prices = my_it->second; + for (md_PricesMap::const_iterator it = prices.begin(); it != prices.end(); ++it) { + const md_Set& indexes = it->second; + for (md_Set::const_iterator it = indexes.begin(); it != indexes.end(); ++it) { + const CMPMetaDEx& obj = *it; + std::string dataStr = GenerateConsensusString(obj); + vecMetaDExTrades.push_back(std::make_pair(arith_uint256(obj.getHash().ToString()), dataStr)); + } + } + } + } + std::sort (vecMetaDExTrades.begin(), vecMetaDExTrades.end()); + for (std::vector >::iterator it = vecMetaDExTrades.begin(); it != vecMetaDExTrades.end(); ++it) { + const std::string& dataStr = it->second; + SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); + } + + uint256 metadexHash; + SHA256_Final((unsigned char*)&metadexHash, &shaCtx); + + return metadexHash; +} + +/** Obtains a hash of the balances for a specific property. */ +uint256 GetBalancesHash(const uint32_t hashPropertyId) +{ + SHA256_CTX shaCtx; + SHA256_Init(&shaCtx); + + LOCK(cs_tally); + + std::map tallyMapSorted; + for (std::unordered_map::iterator uoit = mp_tally_map.begin(); uoit != mp_tally_map.end(); ++uoit) { + tallyMapSorted.insert(std::make_pair(uoit->first,uoit->second)); + } + for (std::map::iterator my_it = tallyMapSorted.begin(); my_it != tallyMapSorted.end(); ++my_it) { + const std::string& address = my_it->first; + CMPTally& tally = my_it->second; + tally.init(); + uint32_t propertyId = 0; + while (0 != (propertyId = (tally.next()))) { + if (propertyId != hashPropertyId) continue; + std::string dataStr = GenerateConsensusString(tally, address, propertyId); + if (dataStr.empty()) continue; + if (msc_debug_consensus_hash) PrintToLog("Adding data to balances hash: %s\n", dataStr); + SHA256_Update(&shaCtx, dataStr.c_str(), dataStr.length()); + } + } + + uint256 balancesHash; + SHA256_Final((unsigned char*)&balancesHash, &shaCtx); + + return balancesHash; +} + } // namespace mastercore diff --git a/src/omnicore/dex.cpp b/src/omnicore/dex.cpp index 1f06fb578..86f2f0bc4 100755 --- a/src/omnicore/dex.cpp +++ b/src/omnicore/dex.cpp @@ -91,29 +91,6 @@ CMPAccept* DEx_getAccept(const std::string& addressSeller, uint32_t propertyId, return static_cast(nullptr); } - -namespace legacy -{ -/** - * Legacy calculation of Master Core 0.0.9. - * - * @see: - * https://github.com/mastercoin-MSC/mastercore/blob/mscore-0.0.9/src/mastercore_dex.cpp#L439-L449 - */ -static int64_t calculateDesiredBTC(const int64_t amountOffered, const int64_t amountDesired, const int64_t amountAvailable) -{ - uint64_t nValue = static_cast(amountOffered); - uint64_t amount_des = static_cast(amountDesired); - uint64_t balanceReallyAvailable = static_cast(amountAvailable); - - double BTC = amount_des * balanceReallyAvailable; - BTC /= (double) nValue; - amount_des = rounduint64(BTC); - - return static_cast(amount_des); -} -} - /** * Determines the amount of bitcoins desired, in case it needs to be recalculated. * @@ -162,35 +139,12 @@ int DEx_offerCreate(const std::string& addressSeller, uint32_t propertyId, int64 const int64_t balanceReallyAvailable = getMPbalance(addressSeller, propertyId, BALANCE); - /** - * After this feature is enabled, it is no longer valid to create orders, which offer more than - * the seller has available, and the amounts are no longer adjusted based on the actual balance. - */ - if (IsFeatureActivated(FEATURE_DEXMATH, block)) { - if (amountOffered > balanceReallyAvailable) { + if (amountOffered > balanceReallyAvailable) { PrintToLog("%s: rejected: sender %s has insufficient balance of property %d [%s < %s]\n", __func__, addressSeller, propertyId, FormatDivisibleMP(balanceReallyAvailable), FormatDivisibleMP(amountOffered)); return (DEX_ERROR_SELLOFFER -25); - } } - // ------------------------------------------------------------------------- - // legacy:: - - // if offering more than available -- put everything up on sale - if (amountOffered > balanceReallyAvailable) { - PrintToLog("%s: adjusting order: %s offers %s %s, but has only %s %s available\n", __func__, - addressSeller, FormatDivisibleMP(amountOffered), strMPProperty(propertyId), - FormatDivisibleMP(balanceReallyAvailable), strMPProperty(propertyId)); - - // AND we must also re-adjust the BTC desired in this case... - amountDesired = legacy::calculateDesiredBTC(amountOffered, amountDesired, balanceReallyAvailable); - amountOffered = balanceReallyAvailable; - if (nAmended) *nAmended = amountOffered; - - PrintToLog("%s: adjusting order: updated amount for sale: %s %s, offered for: %s BTC\n", __func__, - FormatDivisibleMP(amountOffered), strMPProperty(propertyId), FormatDivisibleMP(amountDesired)); - } // ------------------------------------------------------------------------- if (amountOffered > 0) { @@ -370,32 +324,6 @@ int DEx_acceptDestroy(const std::string& addressBuyer, const std::string& addres return 0; } -namespace legacy -{ -/** - * Legacy calculation of Master Core 0.0.9. - * - * @see: - * https://github.com/mastercoin-MSC/mastercore/blob/mscore-0.0.9/src/mastercore_dex.cpp#L660-L668 - */ -static int64_t calculateDExPurchase(const int64_t amountOffered, const int64_t amountDesired, const int64_t amountPaid) -{ - uint64_t acceptOfferAmount = static_cast(amountOffered); - uint64_t acceptBTCDesired = static_cast(amountDesired); - uint64_t BTC_paid = static_cast(amountPaid); - - const double BTC_desired_original = acceptBTCDesired; - const double offer_amount_original = acceptOfferAmount; - - double perc_X = (double) BTC_paid / BTC_desired_original; - double Purchased = offer_amount_original * perc_X; - - uint64_t units_purchased = rounduint64(Purchased); - - return static_cast(units_purchased); -} -} - /** * Determines the purchased amount of tokens. * @@ -465,25 +393,7 @@ int DEx_payment(const uint256& txid, unsigned int vout, const std::string& addre return (DEX_ERROR_PAYMENT -2); } - int64_t amountPurchased = 0; - - /** - * As long as this feature is disabled, floating point math is used to - * determine the purchased amount. - * - * After this feature is enabled, plain integer math is used to determine - * the purchased amount. The purchased amount is rounded up, which may be - * in favor of the buyer, to avoid small leftovers of 1 willet. - * - * This is not exploitable due to transaction fees. - */ - if (IsFeatureActivated(FEATURE_DEXMATH, block)) { - PrintToLog("IsFeatureActivated\n"); - amountPurchased = calculateDExPurchase(amountOffered, amountDesired, amountPaid); - } else { - // Fallback to original calculation: - amountPurchased = legacy::calculateDExPurchase(amountOffered, amountDesired, amountPaid); - } + int64_t amountPurchased = calculateDExPurchase(amountOffered, amountDesired, amountPaid); // ------------------------------------------------------------------------- diff --git a/src/omnicore/log.cpp b/src/omnicore/log.cpp index 9aab7eaf5..2fe469ea4 100644 --- a/src/omnicore/log.cpp +++ b/src/omnicore/log.cpp @@ -135,10 +135,10 @@ static void DebugLogInit() /** * @return The current timestamp in the format: 2009-01-03 18:15:05 */ -static std::string GetTimestamp() -{ - return DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()); -} +// static std::string GetTimestamp() +// { +// return DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()); +// } /** * Prints to log file. diff --git a/src/omnicore/mdex.cpp b/src/omnicore/mdex.cpp index 24b5457ba..248117e50 100644 --- a/src/omnicore/mdex.cpp +++ b/src/omnicore/mdex.cpp @@ -263,22 +263,6 @@ static MatchReturnType x_Trade(CMPMetaDEx* const pnew) int64_t buyer_amountGotAfterFee = buyer_amountGot; int64_t tradingFee = 0; - // strip a 0.05% fee from non-OMNI pairs if fees are activated - if (IsFeatureActivated(FEATURE_FEES, pnew->getBlock())) { - if (pold->getProperty() > OMNI_PROPERTY_TMSC && pold->getDesProperty() > OMNI_PROPERTY_TMSC) { - int64_t feeDivider = 2000; // 0.05% - tradingFee = buyer_amountGot / feeDivider; - - // subtract the fee from the amount the seller will receive - buyer_amountGotAfterFee = buyer_amountGot - tradingFee; - - // add the fee to the fee cache - // p_feecache->AddFee(pnew->getDesProperty(), pnew->getBlock(), tradingFee); - } else { - if (msc_debug_fees) PrintToLog("Skipping fee reduction for trade match %s:%s as one of the properties is Omni\n", pold->getHash().GetHex(), pnew->getHash().GetHex()); - } - } - // transfer the payment property from buyer to seller assert(update_tally_map(pnew->getAddr(), pnew->getProperty(), -seller_amountGot, BALANCE)); assert(update_tally_map(pold->getAddr(), pold->getDesProperty(), seller_amountGot, BALANCE)); diff --git a/src/omnicore/omnicore.cpp b/src/omnicore/omnicore.cpp index db6ac5901..93ab8fe25 100644 --- a/src/omnicore/omnicore.cpp +++ b/src/omnicore/omnicore.cpp @@ -565,9 +565,6 @@ void CheckWalletUpdate(bool forceUpdate) /** * Returns the encoding class, used to embed a payload. * - * 0 None - * 1 Class A (p2pkh) - * 2 Class B (multisig) * 3 Class C (op-return) */ int mastercore::GetEncodingClass(const CTransaction& tx, int nBlock) @@ -631,11 +628,9 @@ int mastercore::GetEncodingClass(const CTransaction& tx, int nBlock) } if (hasOpReturn) { - PrintToLog("getEncodingClass:OMNI_CLASS_C\n"); return OMNI_CLASS_C; } - PrintToLog("getEncodingClass:NO_MARKER\n"); return NO_MARKER; } @@ -681,7 +676,7 @@ static bool FillTxInputCache(const CTransaction& tx) uint256 hashBlock = uint256(); if (!GetTransaction(txIn.prevout.hash, txPrev, Params().GetConsensus(), hashBlock, true)) { - return false; + return false; } if (txPrev.get()->vout.size() <= nOut){ @@ -999,7 +994,7 @@ class ProgressReporter { int64_t secondsTotal = 0.001 * remainingTime; int64_t hours = secondsTotal / 3600; - int64_t minutes = secondsTotal / 60; + int64_t minutes = (secondsTotal / 60) % 60; int64_t seconds = secondsTotal % 60; if (hours > 0) { @@ -1066,7 +1061,7 @@ static int msc_initial_scan(int nFirstBlock) int64_t nNow = GetTime(); unsigned int nTxsTotal = 0; unsigned int nTxsFoundTotal = 0; - int nBlock = 999999; + int nBlock = 99999999; const int nLastBlock = GetHeight(); // this function is useless if there are not enough blocks in the blockchain yet! @@ -1439,8 +1434,7 @@ static int msc_file_load(const string &filename, int what, bool verifyHash = fal } } - PrintToLog("%s(%s), loaded lines= %d, res= %d\n", __FUNCTION__, filename, lines, res); - LogPrintf("%s(): file: %s , loaded lines= %d, res= %d\n", __FUNCTION__, filename, lines, res); + PrintToLog("%s(): file: %s, loaded lines= %d, res= %d\n", __func__, filename, lines, res); return res; } @@ -1474,7 +1468,6 @@ static int load_most_relevant_state() return -1; } - // TODO: make this work out while (nullptr != spBlockIndex && !chainActive.Contains(spBlockIndex)) { int remainingSPs = _my_sps->popBlock(spBlockIndex->GetBlockHash()); @@ -1848,7 +1841,7 @@ void clear_all_state() metadex.clear(); // my_pending.clear(); ResetConsensusParams(); - // ClearActivations(); + ClearActivations(); // ClearAlerts(); // ClearFreezeState(); @@ -1858,8 +1851,6 @@ void clear_all_state() s_stolistdb->Clear(); t_tradelistdb->Clear(); p_OmniTXDB->Clear(); - p_feecache->Clear(); - // p_feehistory->Clear(); assert(p_txlistdb->setDBVersion() == DB_VERSION); // new set of databases, set DB version exodus_prev = 0; } @@ -1878,7 +1869,6 @@ int mastercore_init() return 0; } - PrintToConsole("Initializing Omni Core v%s [%s]\n", OmniCoreVersion(), Params().NetworkIDString()); PrintToLog("\nInitializing Omni Core v%s [%s]\n", OmniCoreVersion(), Params().NetworkIDString()); PrintToLog("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime())); @@ -1903,16 +1893,12 @@ int mastercore_init() boost::filesystem::path spPath = GetDataDir() / "MP_spinfo"; boost::filesystem::path stoPath = GetDataDir() / "MP_stolist"; boost::filesystem::path omniTXDBPath = GetDataDir() / "Omni_TXDB"; - // boost::filesystem::path feesPath = GetDataDir() / "OMNI_feecache"; - // boost::filesystem::path feeHistoryPath = GetDataDir() / "OMNI_feehistory"; if (boost::filesystem::exists(persistPath)) boost::filesystem::remove_all(persistPath); if (boost::filesystem::exists(txlistPath)) boost::filesystem::remove_all(txlistPath); if (boost::filesystem::exists(tradePath)) boost::filesystem::remove_all(tradePath); if (boost::filesystem::exists(spPath)) boost::filesystem::remove_all(spPath); if (boost::filesystem::exists(stoPath)) boost::filesystem::remove_all(stoPath); if (boost::filesystem::exists(omniTXDBPath)) boost::filesystem::remove_all(omniTXDBPath); - // if (boost::filesystem::exists(feesPath)) boost::filesystem::remove_all(feesPath); - // if (boost::filesystem::exists(feeHistoryPath)) boost::filesystem::remove_all(feeHistoryPath); PrintToLog("Success clearing persistence files in datadir %s\n", GetDataDir().string()); startClean = true; } catch (const boost::filesystem::filesystem_error& e) { @@ -1969,28 +1955,28 @@ int mastercore_init() // advance the waterline so that we start on the next unaccounted for block nWaterlineBlock += 1; - /* + //collect the real Exodus balances available at the snapshot time //redundant? do we need to show it both pre-parse and post-parse? if so let's label the printfs accordingly - if (msc_debug_exo) { - int64_t exodus_balance = getMPbalance(exodus_address, OMNI_PROPERTY_MSC, BALANCE); - PrintToLog("Exodus balance at start: %s\n", FormatDivisibleMP(exodus_balance)); - } + // if (msc_debug_exo) { + // int64_t exodus_balance = getMPbalance(exodus_address, OMNI_PROPERTY_MSC, BALANCE); + // PrintToLog("Exodus balance at start: %s\n", FormatDivisibleMP(exodus_balance)); + // } - load feature activation messages from txlistdb and process them accordingly + // load feature activation messages from txlistdb and process them accordingly p_txlistdb->LoadActivations(nWaterlineBlock); //load all alerts from levelDB (and immediately expire old ones) - p_txlistdb->LoadAlerts(nWaterlineBlock); + // p_txlistdb->LoadAlerts(nWaterlineBlock); //load the state of any freeable properties and frozen addresses from levelDB - if (!p_txlistdb->LoadFreezeState(nWaterlineBlock)) { - std::string strShutdownReason = "Failed to load freeze state from levelDB. It is unsafe to continue.\n"; - PrintToLog(strShutdownReason); - if (!GetBoolArg("-overrideforcedshutdown", false)) { - AbortNode(strShutdownReason, strShutdownReason); - } - } */ + // if (!p_txlistdb->LoadFreezeState(nWaterlineBlock)) { + // std::string strShutdownReason = "Failed to load freeze state from levelDB. It is unsafe to continue.\n"; + // PrintToLog(strShutdownReason); + // if (!GetBoolArg("-overrideforcedshutdown", false)) { + // AbortNode(strShutdownReason, strShutdownReason); + // } + // } // initial scan msc_initial_scan(nWaterlineBlock); @@ -2090,8 +2076,9 @@ bool mastercore_handler_tx(CTransaction tx, int nBlock, unsigned int idx, const if (interp_ret) PrintToLog("!!! interpretPacket() returned %d !!!\n", interp_ret); //NOTE: we need to return this number 1 from mp_obj.interpretPacket() (tx.cpp) - if (interp_ret == 1) + if (interp_ret == 1){ HandleDExPayments(tx, nBlock, mp_obj.getSender()); + } // Only structurally valid transactions get recorded in levelDB // PKT_ERROR - 2 = interpret_Transaction failed, structurally invalid payload @@ -2239,7 +2226,7 @@ std::vector COmniTransactionDB::FetchTransactionDetails(const uint2 uint32_t COmniTransactionDB::FetchTransactionPosition(const uint256& txid) { - uint32_t posInBlock = 999999; // setting an initial arbitrarily high value will ensure transaction is always "last" in event of bug/exploit + uint32_t posInBlock = 99999999; // setting an initial arbitrarily high value will ensure transaction is always "last" in event of bug/exploit std::vector vTransactionDetails = FetchTransactionDetails(txid); if (vTransactionDetails.size() == 2) { @@ -2251,7 +2238,7 @@ uint32_t COmniTransactionDB::FetchTransactionPosition(const uint256& txid) std::string COmniTransactionDB::FetchInvalidReason(const uint256& txid) { - int processingResult = -999999; + int processingResult = -99999999; std::vector vTransactionDetails = FetchTransactionDetails(txid); if (vTransactionDetails.size() == 2) { @@ -2749,16 +2736,16 @@ void CMPTxList::recordMetaDExCancelTX(const uint256 &txidMaster, const uint256 & } // Step 4 - Write sub-record with cancel details - // const string txidStr = txidMaster.ToString() + "-C"; - // const string subKey = STR_REF_SUBKEY_TXID_REF_COMBO(txidStr, refNumber); - // const string subValue = strprintf("%s:%d:%lu", txidSub.ToString(), propertyId, nValue); - // Status subStatus; - // PrintToLog("METADEXCANCELDEBUG : Writing sub-record %s with value %s\n", subKey, subValue); - // if (pdb) - // { - // subStatus = pdb->Put(writeoptions, subKey, subValue); - // PrintToLog("METADEXCANCELDEBUG : %s(): %s, line %d, file: %s\n", __FUNCTION__, subStatus.ToString(), __LINE__, __FILE__); - // } + const string txidStr = txidMaster.ToString() + "-C"; + const string subKey = STR_REF_SUBKEY_TXID_REF_COMBO(txidStr, refNumber); + const string subValue = strprintf("%s:%d:%lu", txidSub.ToString(), propertyId, nValue); + Status subStatus; + PrintToLog("METADEXCANCELDEBUG : Writing sub-record %s with value %s\n", subKey, subValue); + if (pdb) + { + subStatus = pdb->Put(writeoptions, subKey, subValue); + PrintToLog("METADEXCANCELDEBUG : %s(): %s, line %d, file: %s\n", __FUNCTION__, subStatus.ToString(), __LINE__, __FILE__); + } } /** @@ -2822,16 +2809,16 @@ void CMPTxList::recordPaymentTX(const uint256 &txid, bool fValid, int nBlock, un } // Step 4 - Write sub-record with payment details - // const string txidStr = txid.ToString(); - // const string subKey = STR_PAYMENT_SUBKEY_TXID_PAYMENT_COMBO(txidStr, paymentNumber); - // const string subValue = strprintf("%d:%s:%s:%d:%lu", vout, buyer, seller, propertyId, nValue); - // Status subStatus; - // PrintToLog("DEXPAYDEBUG : Writing sub-record %s with value %s\n", subKey, subValue); - // if (pdb) - // { - // subStatus = pdb->Put(writeoptions, subKey, subValue); - // PrintToLog("DEXPAYDEBUG : %s(): %s, line %d, file: %s\n", __FUNCTION__, subStatus.ToString(), __LINE__, __FILE__); - // } + const string txidStr = txid.ToString(); + const string subKey = STR_PAYMENT_SUBKEY_TXID_PAYMENT_COMBO(txidStr, paymentNumber); + const string subValue = strprintf("%d:%s:%s:%d:%lu", vout, buyer, seller, propertyId, nValue); + Status subStatus; + PrintToLog("DEXPAYDEBUG : Writing sub-record %s with value %s\n", subKey, subValue); + if (pdb) + { + subStatus = pdb->Put(writeoptions, subKey, subValue); + PrintToLog("DEXPAYDEBUG : %s(): %s, line %d, file: %s\n", __FUNCTION__, subStatus.ToString(), __LINE__, __FILE__); + } } void CMPTxList::recordTX(const uint256 &txid, bool fValid, int nBlock, unsigned int type, uint64_t nValue) @@ -3586,7 +3573,6 @@ int mastercore_handler_block_begin(int nBlockPrev, CBlockIndex const * pBlockInd //handle any features that go live with this block // CheckLiveActivations(pBlockIndex->nHeight); - // eraseExpiredCrowdsale(pBlockIndex); return 0; @@ -3598,56 +3584,68 @@ int mastercore_handler_block_begin(int nBlockPrev, CBlockIndex const * pBlockInd int mastercore_handler_block_end(int nBlockNow, CBlockIndex const * pBlockIndex, unsigned int countMP) { - LOCK(cs_tally); + int nMastercoreInit; + { + LOCK(cs_tally); + nMastercoreInit = mastercoreInitialized; + } - if (!mastercoreInitialized) { + if (!nMastercoreInit) { mastercore_init(); } - // for every new received block must do: - // 1) remove expired entries from the accept list (per spec accept entries are - // valid until their blocklimit expiration; because the customer can keep - // paying BTC for the offer in several installments) - // 2) update the amount in the Exodus address - // int64_t devmsc = 0; - unsigned int how_many_erased = eraseExpiredAccepts(nBlockNow); - if (how_many_erased) { - PrintToLog("%s(%d); erased %u accepts this block, line %d, file: %s\n", - __FUNCTION__, how_many_erased, nBlockNow, __LINE__, __FILE__); - } + bool checkpointValid; + { + LOCK(cs_tally); + // for every new received block must do: + // 1) remove expired entries from the accept list (per spec accept entries are + // valid until their blocklimit expiration; because the customer can keep + // paying BTC for the offer in several installments) + // 2) update the amount in the Exodus address + // int64_t devmsc = 0; + unsigned int how_many_erased = eraseExpiredAccepts(nBlockNow); + if (how_many_erased) { + PrintToLog("%s(%d); erased %u accepts this block, line %d, file: %s\n", + __FUNCTION__, how_many_erased, nBlockNow, __LINE__, __FILE__); + } - // check the alert status, do we need to do anything else here? - // CheckExpiredAlerts(nBlockNow, pBlockIndex->GetBlockTime()); - // check that pending transactions are still in the mempool - PendingCheck(); + // check the alert status, do we need to do anything else here? + // CheckExpiredAlerts(nBlockNow, pBlockIndex->GetBlockTime()); - // transactions were found in the block, signal the UI accordingly - if (countMP > 0) CheckWalletUpdate(true); + // check that pending transactions are still in the mempool + PendingCheck(); - // calculate and print a consensus hash if required - if (msc_debug_consensus_hash_every_block) { - uint256 consensusHash = GetConsensusHash(); - PrintToLog("Consensus hash for block %d: %s\n", nBlockNow, consensusHash.GetHex()); - } + // transactions were found in the block, signal the UI accordingly + if (countMP > 0) CheckWalletUpdate(true); - // request checkpoint verification - bool checkpointValid = VerifyCheckpoint(nBlockNow, pBlockIndex->GetBlockHash()); - if (!checkpointValid) - { - // failed checkpoint, can't be trusted to provide valid data - shutdown client - const std::string& msg = strprintf("Shutting down due to failed checkpoint for block %d (hash %s)\n", nBlockNow, pBlockIndex->GetBlockHash().GetHex()); - PrintToLog(msg); - if (!gArgs.GetBoolArg("-overrideforcedshutdown", false)) { - boost::filesystem::path persistPath = GetDataDir() / "MP_persist"; - if (boost::filesystem::exists(persistPath)) boost::filesystem::remove_all(persistPath); // prevent the node being restarted without a reparse after forced shutdown - // AbortNode(msg, msg); + // calculate and print a consensus hash if required + if (msc_debug_consensus_hash_every_block) { + uint256 consensusHash = GetConsensusHash(); + PrintToLog("Consensus hash for block %d: %s\n", nBlockNow, consensusHash.GetHex()); } - } else { + + // request checkpoint verification + checkpointValid = VerifyCheckpoint(nBlockNow, pBlockIndex->GetBlockHash()); + if (!checkpointValid) + { + // failed checkpoint, can't be trusted to provide valid data - shutdown client + const std::string& msg = strprintf("Shutting down due to failed checkpoint for block %d (hash %s)\n", nBlockNow, pBlockIndex->GetBlockHash().GetHex()); + PrintToLog(msg); + if (!gArgs.GetBoolArg("-overrideforcedshutdown", false)) { + boost::filesystem::path persistPath = GetDataDir() / "MP_persist"; + if (boost::filesystem::exists(persistPath)) boost::filesystem::remove_all(persistPath); // prevent the node being restarted without a reparse after forced shutdown + // AbortNode(msg, msg); + } + } + } + + LOCK2(cs_main, cs_tally); + if (checkpointValid){ // save out the state after this block - if (writePersistence(nBlockNow)) { + if (writePersistence(nBlockNow) && nBlockNow >= ConsensusParams().GENESIS_BLOCK) { mastercore_save_state(pBlockIndex); } } diff --git a/src/omnicore/rpc.cpp b/src/omnicore/rpc.cpp index 305261525..226ae727d 100644 --- a/src/omnicore/rpc.cpp +++ b/src/omnicore/rpc.cpp @@ -471,7 +471,7 @@ bool BalanceToJSON(const std::string& address, uint32_t property, UniValue& bala // generate a list of seed blocks based on the data in LevelDB UniValue omni_getseedblocks(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "omni_getseedblocks startblock endblock\n" "\nReturns a list of blocks containing Omni transactions for use in seed block filtering.\n" @@ -511,7 +511,7 @@ UniValue omni_getseedblocks(const JSONRPCRequest& request) // obtain the payload for a transaction UniValue omni_getpayload(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_getpayload \"txid\"\n" "\nGet the payload for an Omni transaction.\n" @@ -558,7 +558,7 @@ UniValue omni_getpayload(const JSONRPCRequest& request) // determine whether to automatically commit transactions UniValue omni_setautocommit(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_setautocommit flag\n" "\nSets the global flag that determines whether transactions are automatically committed and broadcast.\n" @@ -580,7 +580,7 @@ UniValue omni_setautocommit(const JSONRPCRequest& request) // display an MP balance via RPC UniValue omni_getbalance(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "omni_getbalance \"address\" propertyid\n" "\nReturns the token balance for a given address and property.\n" @@ -610,7 +610,7 @@ UniValue omni_getbalance(const JSONRPCRequest& request) UniValue omni_getallbalancesforid(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_getallbalancesforid propertyid\n" "\nReturns a list of token balances for a given currency or property identifier.\n" @@ -667,7 +667,7 @@ UniValue omni_getallbalancesforid(const JSONRPCRequest& request) UniValue omni_getallbalancesforaddress(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_getallbalancesforaddress \"address\"\n" "\nReturns a list of all token balances for a given address.\n" @@ -717,7 +717,7 @@ UniValue omni_getallbalancesforaddress(const JSONRPCRequest& request) UniValue omni_getproperty(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_getproperty propertyid\n" "\nReturns details for about the tokens or smart property to lookup.\n" @@ -777,27 +777,27 @@ UniValue omni_getproperty(const JSONRPCRequest& request) UniValue omni_listproperties(const JSONRPCRequest& request) { - // if (fHelp) - // throw runtime_error( - // "omni_listproperties\n" - // "\nLists all tokens or smart properties.\n" - // "\nResult:\n" - // "[ (array of JSON objects)\n" - // " {\n" - // " \"propertyid\" : n, (number) the identifier of the tokens\n" - // " \"name\" : \"name\", (string) the name of the tokens\n" - // " \"category\" : \"category\", (string) the category used for the tokens\n" - // " \"subcategory\" : \"subcategory\", (string) the subcategory used for the tokens\n" - // " \"data\" : \"information\", (string) additional information or a description\n" - // " \"url\" : \"uri\", (string) an URI, for example pointing to a website\n" - // " \"divisible\" : true|false (boolean) whether the tokens are divisible\n" - // " },\n" - // " ...\n" - // "]\n" - // "\nExamples:\n" - // + HelpExampleCli("omni_listproperties", "") - // + HelpExampleRpc("omni_listproperties", "") - // ); + if (request.fHelp) + throw runtime_error( + "omni_listproperties\n" + "\nLists all tokens or smart properties.\n" + "\nResult:\n" + "[ (array of JSON objects)\n" + " {\n" + " \"propertyid\" : n, (number) the identifier of the tokens\n" + " \"name\" : \"name\", (string) the name of the tokens\n" + " \"category\" : \"category\", (string) the category used for the tokens\n" + " \"subcategory\" : \"subcategory\", (string) the subcategory used for the tokens\n" + " \"data\" : \"information\", (string) additional information or a description\n" + " \"url\" : \"uri\", (string) an URI, for example pointing to a website\n" + " \"divisible\" : true|false (boolean) whether the tokens are divisible\n" + " },\n" + " ...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("omni_listproperties", "") + + HelpExampleRpc("omni_listproperties", "") + ); UniValue response(UniValue::VARR); @@ -831,7 +831,7 @@ UniValue omni_listproperties(const JSONRPCRequest& request) UniValue omni_getcrowdsale(const JSONRPCRequest& request) { - if (request.params.size() < 1 || request.params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "omni_getcrowdsale propertyid ( verbose )\n" "\nReturns information about a crowdsale.\n" @@ -975,7 +975,7 @@ UniValue omni_getcrowdsale(const JSONRPCRequest& request) UniValue omni_getactivecrowdsales(const JSONRPCRequest& request) { - if (false) + if (request.fHelp) throw runtime_error( "omni_getactivecrowdsales\n" "\nLists currently active crowdsales.\n" @@ -1043,7 +1043,7 @@ UniValue omni_getactivecrowdsales(const JSONRPCRequest& request) UniValue omni_getgrants(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_getgrants propertyid\n" "\nReturns information about granted and revoked units of managed tokens.\n" @@ -1125,7 +1125,7 @@ UniValue omni_getgrants(const JSONRPCRequest& request) UniValue omni_getorderbook(const JSONRPCRequest& request) { - if (request.params.size() < 1 || request.params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "omni_getorderbook propertyid ( propertyid )\n" "\nList active offers on the distributed token exchange.\n" @@ -1194,7 +1194,7 @@ UniValue omni_getorderbook(const JSONRPCRequest& request) UniValue omni_gettradehistoryforaddress(const JSONRPCRequest& request) { - if (request.params.size() < 1 || request.params.size() > 3) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw runtime_error( "omni_gettradehistoryforaddress \"address\" ( count propertyid )\n" "\nRetrieves the history of orders on the distributed exchange for the supplied address.\n" @@ -1278,7 +1278,7 @@ UniValue omni_gettradehistoryforaddress(const JSONRPCRequest& request) UniValue omni_gettradehistoryforpair(const JSONRPCRequest& request) { - if (request.params.size() < 2 || request.params.size() > 3) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw runtime_error( "omni_gettradehistoryforpair propertyid propertyid ( count )\n" "\nRetrieves the history of trades on the distributed token exchange for the specified market.\n" @@ -1325,7 +1325,7 @@ UniValue omni_gettradehistoryforpair(const JSONRPCRequest& request) UniValue omni_getactivedexsells(const JSONRPCRequest& request) { - if (request.params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "omni_getactivedexsells ( address )\n" "\nReturns currently active offers on the distributed exchange.\n" @@ -1458,7 +1458,7 @@ UniValue omni_getactivedexsells(const JSONRPCRequest& request) UniValue omni_listblocktransactions(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_listblocktransactions index\n" "\nLists all Omni transactions in a block.\n" @@ -1510,7 +1510,7 @@ UniValue omni_listblocktransactions(const JSONRPCRequest& request) UniValue omni_gettransaction(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_gettransaction \"txid\"\n" "\nGet detailed information about an Omni transaction.\n" @@ -1548,7 +1548,7 @@ UniValue omni_gettransaction(const JSONRPCRequest& request) UniValue omni_listtransactions(const JSONRPCRequest& request) { - if (request.params.size() > 5) + if (request.fHelp || request.params.size() > 5) throw runtime_error( "omni_listtransactions ( \"address\" count skip startblock endblock )\n" "\nList wallet transactions, optionally filtered by an address and block boundaries.\n" @@ -1629,7 +1629,7 @@ UniValue omni_listtransactions(const JSONRPCRequest& request) UniValue omni_listpendingtransactions(const JSONRPCRequest& request) { - if (request.params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "omni_listpendingtransactions ( \"address\" )\n" "\nReturns a list of unconfirmed Omni transactions, pending in the memory pool.\n" @@ -1680,7 +1680,7 @@ UniValue omni_listpendingtransactions(const JSONRPCRequest& request) UniValue omni_getinfo(const JSONRPCRequest& request) { - if (request.params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "omni_getinfo\n" "Returns various state information of the client and protocol.\n" @@ -1764,7 +1764,7 @@ UniValue omni_getinfo(const JSONRPCRequest& request) UniValue omni_getactivations(const JSONRPCRequest& request) { - if (request.params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "omni_getactivations\n" "Returns pending and completed feature activations.\n" @@ -1828,7 +1828,7 @@ UniValue omni_getactivations(const JSONRPCRequest& request) UniValue omni_getsto(const JSONRPCRequest& request) { - if (request.params.size() < 1 || request.params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "omni_getsto \"txid\" \"recipientfilter\"\n" "\nGet information and recipients of a send-to-owners transaction.\n" @@ -1877,7 +1877,7 @@ UniValue omni_getsto(const JSONRPCRequest& request) UniValue omni_gettrade(const JSONRPCRequest& request) { - if (request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "omni_gettrade \"txid\"\n" "\nGet detailed information and trade matches for orders on the distributed token exchange.\n" @@ -1933,7 +1933,7 @@ UniValue omni_gettrade(const JSONRPCRequest& request) UniValue omni_getcurrentconsensushash(const JSONRPCRequest& request) { - if (request.params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "omni_getcurrentconsensushash\n" "\nReturns the consensus hash for all balances for the current block.\n" diff --git a/src/omnicore/rpcpayload.cpp b/src/omnicore/rpcpayload.cpp index 5728b3be8..e632753cc 100644 --- a/src/omnicore/rpcpayload.cpp +++ b/src/omnicore/rpcpayload.cpp @@ -17,7 +17,7 @@ using namespace mastercore; UniValue omni_createpayload_simplesend(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "omni_createpayload_simplesend propertyid \"amount\"\n" @@ -36,680 +36,710 @@ UniValue omni_createpayload_simplesend(const JSONRPCRequest& request) ); uint32_t propertyId = ParsePropertyId(request.params[0]); - // RequireExistingProperty(propertyId); - // int64_t amount = ParseAmount(request.params[1], isPropertyDivisible(propertyId)); - int64_t amount = ParseAmount(request.params[1], true); + RequireExistingProperty(propertyId); + int64_t amount = ParseAmount(request.params[1], isPropertyDivisible(propertyId)); std::vector payload = CreatePayload_SimpleSend(propertyId, amount); return HexStr(payload.begin(), payload.end()); } -// -// UniValue omni_createpayload_sendall(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 1) -// throw runtime_error( -// "omni_createpayload_sendall ecosystem\n" -// -// "\nCreate the payload for a send all transaction.\n" -// -// "\nArguments:\n" -// "1. ecosystem (number, required) the ecosystem of the tokens to send (1 for main ecosystem, 2 for test ecosystem)\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_sendall", "2") -// + HelpExampleRpc("omni_createpayload_sendall", "2") -// ); -// -// uint8_t ecosystem = ParseEcosystem(params[0]); -// -// std::vector payload = CreatePayload_SendAll(ecosystem); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_dexsell(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 6) -// throw runtime_error( -// "omni_createpayload_dexsell propertyidforsale \"amountforsale\" \"amountdesired\" paymentwindow minacceptfee action\n" -// -// "\nCreate a payload to place, update or cancel a sell offer on the traditional distributed OMNI/BTC exchange.\n" -// -// "\nArguments:\n" -// -// "1. propertyidforsale (number, required) the identifier of the tokens to list for sale (must be 1 for OMNI or 2 for TOMNI)\n" -// "2. amountforsale (string, required) the amount of tokens to list for sale\n" -// "3. amountdesired (string, required) the amount of bitcoins desired\n" -// "4. paymentwindow (number, required) a time limit in blocks a buyer has to pay following a successful accepting order\n" -// "5. minacceptfee (string, required) a minimum mining fee a buyer has to pay to accept the offer\n" -// "6. action (number, required) the action to take (1 for new offers, 2 to update\", 3 to cancel)\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_dexsell", "1 \"1.5\" \"0.75\" 25 \"0.0005\" 1") -// + HelpExampleRpc("omni_createpayload_dexsell", "1, \"1.5\", \"0.75\", 25, \"0.0005\", 1") -// ); -// -// uint32_t propertyIdForSale = ParsePropertyId(params[0]); -// uint8_t action = ParseDExAction(params[5]); -// -// int64_t amountForSale = 0; // depending on action -// int64_t amountDesired = 0; // depending on action -// uint8_t paymentWindow = 0; // depending on action -// int64_t minAcceptFee = 0; // depending on action -// -// if (action <= CMPTransaction::UPDATE) { // actions 3 permit zero values, skip check -// amountForSale = ParseAmount(params[1], true); // TMSC/MSC is divisible -// amountDesired = ParseAmount(params[2], true); // BTC is divisible -// paymentWindow = ParseDExPaymentWindow(params[3]); -// minAcceptFee = ParseDExFee(params[4]); -// } -// -// std::vector payload = CreatePayload_DExSell(propertyIdForSale, amountForSale, amountDesired, paymentWindow, minAcceptFee, action); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_dexaccept(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 2) -// throw runtime_error( -// "omni_senddexaccept propertyid \"amount\"\n" -// -// "\nCreate the payload for an accept offer for the specified token and amount.\n" -// -// "\nArguments:\n" -// "1. propertyid (number, required) the identifier of the token to purchase\n" -// "2. amount (string, required) the amount to accept\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_dexaccept", "1 \"15.0\"") -// + HelpExampleRpc("omni_createpayload_dexaccept", "1, \"15.0\"") -// ); -// -// uint32_t propertyId = ParsePropertyId(params[0]); -// RequirePrimaryToken(propertyId); -// int64_t amount = ParseAmount(params[1], true); -// -// std::vector payload = CreatePayload_DExAccept(propertyId, amount); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_sto(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() < 2 || params.size() > 3) -// throw runtime_error( -// "omni_createpayload_sto propertyid \"amount\" ( distributionproperty )\n" -// -// "\nCreates the payload for a send-to-owners transaction.\n" -// -// "\nArguments:\n" -// "1. propertyid (number, required) the identifier of the tokens to distribute\n" -// "2. amount (string, required) the amount to distribute\n" -// "3. distributionproperty (number, optional) the identifier of the property holders to distribute to\n" -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_sto", "3 \"5000\"") -// + HelpExampleRpc("omni_createpayload_sto", "3, \"5000\"") -// ); -// -// uint32_t propertyId = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyId); -// int64_t amount = ParseAmount(params[1], isPropertyDivisible(propertyId)); -// uint32_t distributionPropertyId = (params.size() > 2) ? ParsePropertyId(params[2]) : propertyId; -// -// std::vector payload = CreatePayload_SendToOwners(propertyId, amount, distributionPropertyId); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_issuancefixed(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 9) -// throw runtime_error( -// "omni_createpayload_issuancefixed ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\" \"amount\"\n" -// -// "\nCreates the payload for a new tokens issuance with fixed supply.\n" -// -// "\nArguments:\n" -// "1. ecosystem (string, required) the ecosystem to create the tokens in (1 for main ecosystem, 2 for test ecosystem)\n" -// "2. type (number, required) the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)\n" -// "3. previousid (number, required) an identifier of a predecessor token (use 0 for new tokens)\n" -// "4. category (string, required) a category for the new tokens (can be \"\")\n" -// "5. subcategory (string, required) a subcategory for the new tokens (can be \"\")\n" -// "6. name (string, required) the name of the new tokens to create\n" -// "7. url (string, required) an URL for further information about the new tokens (can be \"\")\n" -// "8. data (string, required) a description for the new tokens (can be \"\")\n" -// "9. amount (string, required) the number of tokens to create\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_issuancefixed", "2 1 0 \"Companies\" \"Bitcoin Mining\" \"Quantum Miner\" \"\" \"\" \"1000000\"") -// + HelpExampleRpc("omni_createpayload_issuancefixed", "2, 1, 0, \"Companies\", \"Bitcoin Mining\", \"Quantum Miner\", \"\", \"\", \"1000000\"") -// ); -// -// uint8_t ecosystem = ParseEcosystem(params[0]); -// uint16_t type = ParsePropertyType(params[1]); -// uint32_t previousId = ParsePreviousPropertyId(params[2]); -// std::string category = ParseText(params[3]); -// std::string subcategory = ParseText(params[4]); -// std::string name = ParseText(params[5]); -// std::string url = ParseText(params[6]); -// std::string data = ParseText(params[7]); -// int64_t amount = ParseAmount(params[8], type); -// -// RequirePropertyName(name); -// -// std::vector payload = CreatePayload_IssuanceFixed(ecosystem, type, previousId, category, subcategory, name, url, data, amount); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_issuancecrowdsale(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 13) -// throw runtime_error( -// "omni_createpayload_issuancecrowdsale ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\" propertyiddesired tokensperunit deadline earlybonus issuerpercentage\n" -// -// "\nCreates the payload for a new tokens issuance with crowdsale.\n" -// -// "\nArguments:\n" -// "1. ecosystem (string, required) the ecosystem to create the tokens in (1 for main ecosystem, 2 for test ecosystem)\n" -// "2. type (number, required) the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)\n" -// "3. previousid (number, required) an identifier of a predecessor token (0 for new crowdsales)\n" -// "4. category (string, required) a category for the new tokens (can be \"\")\n" -// "5. subcategory (string, required) a subcategory for the new tokens (can be \"\")\n" -// "6. name (string, required) the name of the new tokens to create\n" -// "7. url (string, required) an URL for further information about the new tokens (can be \"\")\n" -// "8. data (string, required) a description for the new tokens (can be \"\")\n" -// "9. propertyiddesired (number, required) the identifier of a token eligible to participate in the crowdsale\n" -// "10. tokensperunit (string, required) the amount of tokens granted per unit invested in the crowdsale\n" -// "11. deadline (number, required) the deadline of the crowdsale as Unix timestamp\n" -// "12. earlybonus (number, required) an early bird bonus for participants in percent per week\n" -// "13. issuerpercentage (number, required) a percentage of tokens that will be granted to the issuer\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_issuancecrowdsale", "2 1 0 \"Companies\" \"Bitcoin Mining\" \"Quantum Miner\" \"\" \"\" 2 \"100\" 1483228800 30 2") -// + HelpExampleRpc("omni_createpayload_issuancecrowdsale", "2, 1, 0, \"Companies\", \"Bitcoin Mining\", \"Quantum Miner\", \"\", \"\", 2, \"100\", 1483228800, 30, 2") -// ); -// -// uint8_t ecosystem = ParseEcosystem(params[0]); -// uint16_t type = ParsePropertyType(params[1]); -// uint32_t previousId = ParsePreviousPropertyId(params[2]); -// std::string category = ParseText(params[3]); -// std::string subcategory = ParseText(params[4]); -// std::string name = ParseText(params[5]); -// std::string url = ParseText(params[6]); -// std::string data = ParseText(params[7]); -// uint32_t propertyIdDesired = ParsePropertyId(params[8]); -// int64_t numTokens = ParseAmount(params[9], type); -// int64_t deadline = ParseDeadline(params[10]); -// uint8_t earlyBonus = ParseEarlyBirdBonus(params[11]); -// uint8_t issuerPercentage = ParseIssuerBonus(params[12]); -// -// RequirePropertyName(name); -// RequireExistingProperty(propertyIdDesired); -// RequireSameEcosystem(ecosystem, propertyIdDesired); -// -// std::vector payload = CreatePayload_IssuanceVariable(ecosystem, type, previousId, category, subcategory, name, url, data, propertyIdDesired, numTokens, deadline, earlyBonus, issuerPercentage); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_issuancemanaged(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 8) -// throw runtime_error( -// "omni_createpayload_issuancemanaged ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\"\n" -// -// "\nCreates the payload for a new tokens issuance with manageable supply.\n" -// -// "\nArguments:\n" -// "1. ecosystem (string, required) the ecosystem to create the tokens in (1 for main ecosystem, 2 for test ecosystem)\n" -// "2. type (number, required) the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)\n" -// "3. previousid (number, required) an identifier of a predecessor token (use 0 for new tokens)\n" -// "4. category (string, required) a category for the new tokens (can be \"\")\n" -// "5. subcategory (string, required) a subcategory for the new tokens (can be \"\")\n" -// "6. name (string, required) the name of the new tokens to create\n" -// "7. url (string, required) an URL for further information about the new tokens (can be \"\")\n" -// "8. data (string, required) a description for the new tokens (can be \"\")\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_issuancemanaged", "2 1 0 \"Companies\" \"Bitcoin Mining\" \"Quantum Miner\" \"\" \"\"") -// + HelpExampleRpc("omni_createpayload_issuancemanaged", "2, 1, 0, \"Companies\", \"Bitcoin Mining\", \"Quantum Miner\", \"\", \"\"") -// ); -// -// uint8_t ecosystem = ParseEcosystem(params[0]); -// uint16_t type = ParsePropertyType(params[1]); -// uint32_t previousId = ParsePreviousPropertyId(params[2]); -// std::string category = ParseText(params[3]); -// std::string subcategory = ParseText(params[4]); -// std::string name = ParseText(params[5]); -// std::string url = ParseText(params[6]); -// std::string data = ParseText(params[7]); -// -// RequirePropertyName(name); -// -// std::vector payload = CreatePayload_IssuanceManaged(ecosystem, type, previousId, category, subcategory, name, url, data); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_closecrowdsale(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 1) -// throw runtime_error( -// "omni_createpayload_closecrowdsale propertyid\n" -// -// "\nCreates the payload to manually close a crowdsale.\n" -// -// "\nArguments:\n" -// "1. propertyid (number, required) the identifier of the crowdsale to close\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_closecrowdsale", "70") -// + HelpExampleRpc("omni_createpayload_closecrowdsale", "70") -// ); -// -// uint32_t propertyId = ParsePropertyId(params[0]); -// -// // checks bypassed because someone may wish to prepare the payload to close a crowdsale creation not yet broadcast -// -// std::vector payload = CreatePayload_CloseCrowdsale(propertyId); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_grant(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() < 2 || params.size() > 3) -// throw runtime_error( -// "omni_createpayload_grant propertyid \"amount\" ( \"memo\" )\n" -// -// "\nCreates the payload to issue or grant new units of managed tokens.\n" -// -// "\nArguments:\n" -// "1. propertyid (number, required) the identifier of the tokens to grant\n" -// "2. amount (string, required) the amount of tokens to create\n" -// "3. memo (string, optional) a text note attached to this transaction (none by default)\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_grant", "51 \"7000\"") -// + HelpExampleRpc("omni_createpayload_grant", "51, \"7000\"") -// ); -// -// uint32_t propertyId = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyId); -// RequireManagedProperty(propertyId); -// int64_t amount = ParseAmount(params[1], isPropertyDivisible(propertyId)); -// std::string memo = (params.size() > 2) ? ParseText(params[2]): ""; -// -// std::vector payload = CreatePayload_Grant(propertyId, amount, memo); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_revoke(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() < 2 || params.size() > 3) -// throw runtime_error( -// "omni_createpayload_revoke propertyid \"amount\" ( \"memo\" )\n" -// -// "\nCreates the payload to revoke units of managed tokens.\n" -// -// "\nArguments:\n" -// "1. propertyid (number, required) the identifier of the tokens to revoke\n" -// "2. amount (string, required) the amount of tokens to revoke\n" -// "3. memo (string, optional) a text note attached to this transaction (none by default)\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_revoke", "51 \"100\"") -// + HelpExampleRpc("omni_createpayload_revoke", "51, \"100\"") -// ); -// -// uint32_t propertyId = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyId); -// RequireManagedProperty(propertyId); -// int64_t amount = ParseAmount(params[1], isPropertyDivisible(propertyId)); -// std::string memo = (params.size() > 2) ? ParseText(params[2]): ""; -// -// std::vector payload = CreatePayload_Revoke(propertyId, amount, memo); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_changeissuer(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 1) -// throw runtime_error( -// "omni_createpayload_changeissuer propertyid\n" -// -// "\nCreats the payload to change the issuer on record of the given tokens.\n" -// -// "\nArguments:\n" -// "1. propertyid (number, required) the identifier of the tokens\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_changeissuer", "3") -// + HelpExampleRpc("omni_createpayload_changeissuer", "3") -// ); -// -// uint32_t propertyId = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyId); -// -// std::vector payload = CreatePayload_ChangeIssuer(propertyId); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_trade(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 4) -// throw runtime_error( -// "omni_createpayload_trade propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\"\n" -// -// "\nCreates the payload to place a trade offer on the distributed token exchange.\n" -// -// "\nArguments:\n" -// "1. propertyidforsale (number, required) the identifier of the tokens to list for sale\n" -// "2. amountforsale (string, required) the amount of tokens to list for sale\n" -// "3. propertiddesired (number, required) the identifier of the tokens desired in exchange\n" -// "4. amountdesired (string, required) the amount of tokens desired in exchange\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_trade", "31 \"250.0\" 1 \"10.0\"") -// + HelpExampleRpc("omni_createpayload_trade", "31, \"250.0\", 1, \"10.0\"") -// ); -// -// uint32_t propertyIdForSale = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyIdForSale); -// int64_t amountForSale = ParseAmount(params[1], isPropertyDivisible(propertyIdForSale)); -// uint32_t propertyIdDesired = ParsePropertyId(params[2]); -// RequireExistingProperty(propertyIdDesired); -// int64_t amountDesired = ParseAmount(params[3], isPropertyDivisible(propertyIdDesired)); -// RequireSameEcosystem(propertyIdForSale, propertyIdDesired); -// RequireDifferentIds(propertyIdForSale, propertyIdDesired); -// RequireDifferentIds(propertyIdForSale, propertyIdDesired); -// -// std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_canceltradesbyprice(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 4) -// throw runtime_error( -// "omni_createpayload_canceltradesbyprice propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\"\n" -// -// "\nCreates the payload to cancel offers on the distributed token exchange with the specified price.\n" -// -// "\nArguments:\n" -// "1. propertyidforsale (number, required) the identifier of the tokens listed for sale\n" -// "2. amountforsale (string, required) the amount of tokens to listed for sale\n" -// "3. propertiddesired (number, required) the identifier of the tokens desired in exchange\n" -// "4. amountdesired (string, required) the amount of tokens desired in exchange\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_canceltradesbyprice", "31 \"100.0\" 1 \"5.0\"") -// + HelpExampleRpc("omni_createpayload_canceltradesbyprice", "31, \"100.0\", 1, \"5.0\"") -// ); -// -// uint32_t propertyIdForSale = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyIdForSale); -// int64_t amountForSale = ParseAmount(params[1], isPropertyDivisible(propertyIdForSale)); -// uint32_t propertyIdDesired = ParsePropertyId(params[2]); -// RequireExistingProperty(propertyIdDesired); -// int64_t amountDesired = ParseAmount(params[3], isPropertyDivisible(propertyIdDesired)); -// RequireSameEcosystem(propertyIdForSale, propertyIdDesired); -// RequireDifferentIds(propertyIdForSale, propertyIdDesired); -// -// std::vector payload = CreatePayload_MetaDExCancelPrice(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_canceltradesbypair(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 2) -// throw runtime_error( -// "omni_createpayload_canceltradesbypair propertyidforsale propertiddesired\n" -// -// "\nCreates the payload to cancel all offers on the distributed token exchange with the given currency pair.\n" -// -// "\nArguments:\n" -// "1. propertyidforsale (number, required) the identifier of the tokens listed for sale\n" -// "2. propertiddesired (number, required) the identifier of the tokens desired in exchange\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_canceltradesbypair", "1 31") -// + HelpExampleRpc("omni_createpayload_canceltradesbypair", "1, 31") -// ); -// -// uint32_t propertyIdForSale = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyIdForSale); -// uint32_t propertyIdDesired = ParsePropertyId(params[1]); -// RequireExistingProperty(propertyIdDesired); -// RequireSameEcosystem(propertyIdForSale, propertyIdDesired); -// RequireDifferentIds(propertyIdForSale, propertyIdDesired); -// -// std::vector payload = CreatePayload_MetaDExCancelPair(propertyIdForSale, propertyIdDesired); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_cancelalltrades(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 1) -// throw runtime_error( -// "omni_createpayload_cancelalltrades ecosystem\n" -// -// "\nCreates the payload to cancel all offers on the distributed token exchange.\n" -// -// "\nArguments:\n" -// "1. ecosystem (number, required) the ecosystem of the offers to cancel (1 for main ecosystem, 2 for test ecosystem)\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_cancelalltrades", "1") -// + HelpExampleRpc("omni_createpayload_cancelalltrades", "1") -// ); -// -// uint8_t ecosystem = ParseEcosystem(params[0]); -// -// std::vector payload = CreatePayload_MetaDExCancelEcosystem(ecosystem); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_enablefreezing(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 1) -// throw runtime_error( -// "omni_createpayload_enablefreezing propertyid\n" -// -// "\nCreates the payload to enable address freezing for a centrally managed property.\n" -// -// "\nArguments:\n" -// "1. propertyid (number, required) the identifier of the tokens\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_enablefreezing", "3") -// + HelpExampleRpc("omni_createpayload_enablefreezing", "3") -// ); -// -// uint32_t propertyId = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyId); -// RequireManagedProperty(propertyId); -// -// std::vector payload = CreatePayload_EnableFreezing(propertyId); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_disablefreezing(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 1) -// throw runtime_error( -// "omni_createpayload_disablefreezing propertyid\n" -// -// "\nCreates the payload to disable address freezing for a centrally managed property.\n" -// "\nIMPORTANT NOTE: Disabling freezing for a property will UNFREEZE all frozen addresses for that property!" -// -// "\nArguments:\n" -// "1. propertyid (number, required) the identifier of the tokens\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_disablefreezing", "3") -// + HelpExampleRpc("omni_createpayload_disablefreezing", "3") -// ); -// -// uint32_t propertyId = ParsePropertyId(params[0]); -// RequireExistingProperty(propertyId); -// RequireManagedProperty(propertyId); -// -// std::vector payload = CreatePayload_DisableFreezing(propertyId); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_freeze(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 3) -// throw runtime_error( -// "omni_createpayload_freeze \"toaddress\" propertyid amount \n" -// -// "\nCreates the payload to freeze an address for a centrally managed token.\n" -// -// "\nArguments:\n" -// "1. toaddress (string, required) the address to freeze tokens for\n" -// "2. propertyid (number, required) the property to freeze tokens for (must be managed type and have freezing option enabled)\n" -// "3. amount (number, required) the amount of tokens to freeze (note: this is unused - once frozen an address cannot send any transactions)\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_freeze", "\"3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs\" 1 0") -// + HelpExampleRpc("omni_createpayload_freeze", "\"3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs\", 1, 0") -// ); -// -// std::string refAddress = ParseAddress(params[0]); -// uint32_t propertyId = ParsePropertyId(params[1]); -// int64_t amount = ParseAmount(params[2], isPropertyDivisible(propertyId)); -// -// RequireExistingProperty(propertyId); -// RequireManagedProperty(propertyId); -// -// std::vector payload = CreatePayload_FreezeTokens(propertyId, amount, refAddress); -// -// return HexStr(payload.begin(), payload.end()); -// } -// -// UniValue omni_createpayload_unfreeze(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 3) -// throw runtime_error( -// "omni_createpayload_unfreeze \"toaddress\" propertyid amount \n" -// -// "\nCreates the payload to unfreeze an address for a centrally managed token.\n" -// -// "\nArguments:\n" -// "1. toaddress (string, required) the address to unfreeze tokens for\n" -// "2. propertyid (number, required) the property to unfreeze tokens for (must be managed type and have freezing option enabled)\n" -// "3. amount (number, required) the amount of tokens to unfreeze (note: this is unused)\n" -// -// "\nResult:\n" -// "\"payload\" (string) the hex-encoded payload\n" -// -// "\nExamples:\n" -// + HelpExampleCli("omni_createpayload_unfreeze", "\"3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs\" 1 0") -// + HelpExampleRpc("omni_createpayload_unfreeze", "\"3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs\", 1, 0") -// ); -// -// std::string refAddress = ParseAddress(params[0]); -// uint32_t propertyId = ParsePropertyId(params[1]); -// int64_t amount = ParseAmount(params[2], isPropertyDivisible(propertyId)); -// -// RequireExistingProperty(propertyId); -// RequireManagedProperty(propertyId); -// -// std::vector payload = CreatePayload_UnfreezeTokens(propertyId, amount, refAddress); -// -// return HexStr(payload.begin(), payload.end()); -// } + +UniValue omni_createpayload_sendall(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "omni_createpayload_sendall ecosystem\n" + + "\nCreate the payload for a send all transaction.\n" + + "\nArguments:\n" + "1. ecosystem (number, required) the ecosystem of the tokens to send (1 for main ecosystem, 2 for test ecosystem)\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_sendall", "2") + + HelpExampleRpc("omni_createpayload_sendall", "2") + ); + + uint8_t ecosystem = ParseEcosystem(request.params[0]); + + std::vector payload = CreatePayload_SendAll(ecosystem); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_dexsell(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 6) + throw runtime_error( + "omni_createpayload_dexsell propertyidforsale \"amountforsale\" \"amountdesired\" paymentwindow minacceptfee action\n" + + "\nCreate a payload to place, update or cancel a sell offer on the traditional distributed OMNI/BTC exchange.\n" + + "\nArguments:\n" + + "1. propertyidforsale (number, required) the identifier of the tokens to list for sale (must be 1 for OMNI or 2 for TOMNI)\n" + "2. amountforsale (string, required) the amount of tokens to list for sale\n" + "3. amountdesired (string, required) the amount of bitcoins desired\n" + "4. paymentwindow (number, required) a time limit in blocks a buyer has to pay following a successful accepting order\n" + "5. minacceptfee (string, required) a minimum mining fee a buyer has to pay to accept the offer\n" + "6. action (number, required) the action to take (1 for new offers, 2 to update\", 3 to cancel)\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_dexsell", "1 \"1.5\" \"0.75\" 25 \"0.0005\" 1") + + HelpExampleRpc("omni_createpayload_dexsell", "1, \"1.5\", \"0.75\", 25, \"0.0005\", 1") + ); + + uint32_t propertyIdForSale = ParsePropertyId(request.params[0]); + uint8_t action = ParseDExAction(request.params[5]); + + int64_t amountForSale = 0; // depending on action + int64_t amountDesired = 0; // depending on action + uint8_t paymentWindow = 0; // depending on action + int64_t minAcceptFee = 0; // depending on action + + if (action <= CMPTransaction::UPDATE) { // actions 3 permit zero values, skip check + amountForSale = ParseAmount(request.params[1], true); // TMSC/MSC is divisible + amountDesired = ParseAmount(request.params[2], true); // BTC is divisible + paymentWindow = ParseDExPaymentWindow(request.params[3]); + minAcceptFee = ParseDExFee(request.params[4]); + } + + std::vector payload = CreatePayload_DExSell(propertyIdForSale, amountForSale, amountDesired, paymentWindow, minAcceptFee, action); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_dexaccept(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 2) + throw runtime_error( + "omni_senddexaccept propertyid \"amount\"\n" + + "\nCreate the payload for an accept offer for the specified token and amount.\n" + + "\nArguments:\n" + "1. propertyid (number, required) the identifier of the token to purchase\n" + "2. amount (string, required) the amount to accept\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_dexaccept", "1 \"15.0\"") + + HelpExampleRpc("omni_createpayload_dexaccept", "1, \"15.0\"") + ); + + uint32_t propertyId = ParsePropertyId(request.params[0]); + RequirePrimaryToken(propertyId); + int64_t amount = ParseAmount(request.params[1], true); + + std::vector payload = CreatePayload_DExAccept(propertyId, amount); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_sto(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) + throw runtime_error( + "omni_createpayload_sto propertyid \"amount\" ( distributionproperty )\n" + + "\nCreates the payload for a send-to-owners transaction.\n" + + "\nArguments:\n" + "1. propertyid (number, required) the identifier of the tokens to distribute\n" + "2. amount (string, required) the amount to distribute\n" + "3. distributionproperty (number, optional) the identifier of the property holders to distribute to\n" + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_sto", "3 \"5000\"") + + HelpExampleRpc("omni_createpayload_sto", "3, \"5000\"") + ); + + uint32_t propertyId = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyId); + int64_t amount = ParseAmount(request.params[1], isPropertyDivisible(propertyId)); + uint32_t distributionPropertyId = (request.params.size() > 2) ? ParsePropertyId(request.params[2]) : propertyId; + + std::vector payload = CreatePayload_SendToOwners(propertyId, amount, distributionPropertyId); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_issuancefixed(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 9) + throw runtime_error( + "omni_createpayload_issuancefixed ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\" \"amount\"\n" + + "\nCreates the payload for a new tokens issuance with fixed supply.\n" + + "\nArguments:\n" + "1. ecosystem (string, required) the ecosystem to create the tokens in (1 for main ecosystem, 2 for test ecosystem)\n" + "2. type (number, required) the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)\n" + "3. previousid (number, required) an identifier of a predecessor token (use 0 for new tokens)\n" + "4. category (string, required) a category for the new tokens (can be \"\")\n" + "5. subcategory (string, required) a subcategory for the new tokens (can be \"\")\n" + "6. name (string, required) the name of the new tokens to create\n" + "7. url (string, required) an URL for further information about the new tokens (can be \"\")\n" + "8. data (string, required) a description for the new tokens (can be \"\")\n" + "9. amount (string, required) the number of tokens to create\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_issuancefixed", "2 1 0 \"Companies\" \"Bitcoin Mining\" \"Quantum Miner\" \"\" \"\" \"1000000\"") + + HelpExampleRpc("omni_createpayload_issuancefixed", "2, 1, 0, \"Companies\", \"Bitcoin Mining\", \"Quantum Miner\", \"\", \"\", \"1000000\"") + ); + + uint8_t ecosystem = ParseEcosystem(request.params[0]); + uint16_t type = ParsePropertyType(request.params[1]); + uint32_t previousId = ParsePreviousPropertyId(request.params[2]); + std::string category = ParseText(request.params[3]); + std::string subcategory = ParseText(request.params[4]); + std::string name = ParseText(request.params[5]); + std::string url = ParseText(request.params[6]); + std::string data = ParseText(request.params[7]); + int64_t amount = ParseAmount(request.params[8], type); + + RequirePropertyName(name); + + std::vector payload = CreatePayload_IssuanceFixed(ecosystem, type, previousId, category, subcategory, name, url, data, amount); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_issuancecrowdsale(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 13) + throw runtime_error( + "omni_createpayload_issuancecrowdsale ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\" propertyiddesired tokensperunit deadline earlybonus issuerpercentage\n" + + "\nCreates the payload for a new tokens issuance with crowdsale.\n" + + "\nArguments:\n" + "1. ecosystem (string, required) the ecosystem to create the tokens in (1 for main ecosystem, 2 for test ecosystem)\n" + "2. type (number, required) the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)\n" + "3. previousid (number, required) an identifier of a predecessor token (0 for new crowdsales)\n" + "4. category (string, required) a category for the new tokens (can be \"\")\n" + "5. subcategory (string, required) a subcategory for the new tokens (can be \"\")\n" + "6. name (string, required) the name of the new tokens to create\n" + "7. url (string, required) an URL for further information about the new tokens (can be \"\")\n" + "8. data (string, required) a description for the new tokens (can be \"\")\n" + "9. propertyiddesired (number, required) the identifier of a token eligible to participate in the crowdsale\n" + "10. tokensperunit (string, required) the amount of tokens granted per unit invested in the crowdsale\n" + "11. deadline (number, required) the deadline of the crowdsale as Unix timestamp\n" + "12. earlybonus (number, required) an early bird bonus for participants in percent per week\n" + "13. issuerpercentage (number, required) a percentage of tokens that will be granted to the issuer\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_issuancecrowdsale", "2 1 0 \"Companies\" \"Bitcoin Mining\" \"Quantum Miner\" \"\" \"\" 2 \"100\" 1483228800 30 2") + + HelpExampleRpc("omni_createpayload_issuancecrowdsale", "2, 1, 0, \"Companies\", \"Bitcoin Mining\", \"Quantum Miner\", \"\", \"\", 2, \"100\", 1483228800, 30, 2") + ); + + uint8_t ecosystem = ParseEcosystem(request.params[0]); + uint16_t type = ParsePropertyType(request.params[1]); + uint32_t previousId = ParsePreviousPropertyId(request.params[2]); + std::string category = ParseText(request.params[3]); + std::string subcategory = ParseText(request.params[4]); + std::string name = ParseText(request.params[5]); + std::string url = ParseText(request.params[6]); + std::string data = ParseText(request.params[7]); + uint32_t propertyIdDesired = ParsePropertyId(request.params[8]); + int64_t numTokens = ParseAmount(request.params[9], type); + int64_t deadline = ParseDeadline(request.params[10]); + uint8_t earlyBonus = ParseEarlyBirdBonus(request.params[11]); + uint8_t issuerPercentage = ParseIssuerBonus(request.params[12]); + + RequirePropertyName(name); + RequireExistingProperty(propertyIdDesired); + RequireSameEcosystem(ecosystem, propertyIdDesired); + + std::vector payload = CreatePayload_IssuanceVariable(ecosystem, type, previousId, category, subcategory, name, url, data, propertyIdDesired, numTokens, deadline, earlyBonus, issuerPercentage); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_issuancemanaged(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 8) + throw runtime_error( + "omni_createpayload_issuancemanaged ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\"\n" + + "\nCreates the payload for a new tokens issuance with manageable supply.\n" + + "\nArguments:\n" + "1. ecosystem (string, required) the ecosystem to create the tokens in (1 for main ecosystem, 2 for test ecosystem)\n" + "2. type (number, required) the type of the tokens to create: (1 for indivisible tokens, 2 for divisible tokens)\n" + "3. previousid (number, required) an identifier of a predecessor token (use 0 for new tokens)\n" + "4. category (string, required) a category for the new tokens (can be \"\")\n" + "5. subcategory (string, required) a subcategory for the new tokens (can be \"\")\n" + "6. name (string, required) the name of the new tokens to create\n" + "7. url (string, required) an URL for further information about the new tokens (can be \"\")\n" + "8. data (string, required) a description for the new tokens (can be \"\")\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_issuancemanaged", "2 1 0 \"Companies\" \"Bitcoin Mining\" \"Quantum Miner\" \"\" \"\"") + + HelpExampleRpc("omni_createpayload_issuancemanaged", "2, 1, 0, \"Companies\", \"Bitcoin Mining\", \"Quantum Miner\", \"\", \"\"") + ); + + uint8_t ecosystem = ParseEcosystem(request.params[0]); + uint16_t type = ParsePropertyType(request.params[1]); + uint32_t previousId = ParsePreviousPropertyId(request.params[2]); + std::string category = ParseText(request.params[3]); + std::string subcategory = ParseText(request.params[4]); + std::string name = ParseText(request.params[5]); + std::string url = ParseText(request.params[6]); + std::string data = ParseText(request.params[7]); + + RequirePropertyName(name); + + std::vector payload = CreatePayload_IssuanceManaged(ecosystem, type, previousId, category, subcategory, name, url, data); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_closecrowdsale(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "omni_createpayload_closecrowdsale propertyid\n" + + "\nCreates the payload to manually close a crowdsale.\n" + + "\nArguments:\n" + "1. propertyid (number, required) the identifier of the crowdsale to close\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_closecrowdsale", "70") + + HelpExampleRpc("omni_createpayload_closecrowdsale", "70") + ); + + uint32_t propertyId = ParsePropertyId(request.params[0]); + + // checks bypassed because someone may wish to prepare the payload to close a crowdsale creation not yet broadcast + + std::vector payload = CreatePayload_CloseCrowdsale(propertyId); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_grant(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) + throw runtime_error( + "omni_createpayload_grant propertyid \"amount\" ( \"memo\" )\n" + + "\nCreates the payload to issue or grant new units of managed tokens.\n" + + "\nArguments:\n" + "1. propertyid (number, required) the identifier of the tokens to grant\n" + "2. amount (string, required) the amount of tokens to create\n" + "3. memo (string, optional) a text note attached to this transaction (none by default)\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_grant", "51 \"7000\"") + + HelpExampleRpc("omni_createpayload_grant", "51, \"7000\"") + ); + + uint32_t propertyId = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyId); + RequireManagedProperty(propertyId); + int64_t amount = ParseAmount(request.params[1], isPropertyDivisible(propertyId)); + std::string memo = (request.params.size() > 2) ? ParseText(request.params[2]): ""; + + std::vector payload = CreatePayload_Grant(propertyId, amount, memo); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_revoke(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) + throw runtime_error( + "omni_createpayload_revoke propertyid \"amount\" ( \"memo\" )\n" + + "\nCreates the payload to revoke units of managed tokens.\n" + + "\nArguments:\n" + "1. propertyid (number, required) the identifier of the tokens to revoke\n" + "2. amount (string, required) the amount of tokens to revoke\n" + "3. memo (string, optional) a text note attached to this transaction (none by default)\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_revoke", "51 \"100\"") + + HelpExampleRpc("omni_createpayload_revoke", "51, \"100\"") + ); + + uint32_t propertyId = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyId); + RequireManagedProperty(propertyId); + int64_t amount = ParseAmount(request.params[1], isPropertyDivisible(propertyId)); + std::string memo = (request.params.size() > 2) ? ParseText(request.params[2]): ""; + + std::vector payload = CreatePayload_Revoke(propertyId, amount, memo); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_changeissuer(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "omni_createpayload_changeissuer propertyid\n" + + "\nCreats the payload to change the issuer on record of the given tokens.\n" + + "\nArguments:\n" + "1. propertyid (number, required) the identifier of the tokens\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_changeissuer", "3") + + HelpExampleRpc("omni_createpayload_changeissuer", "3") + ); + + uint32_t propertyId = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyId); + + std::vector payload = CreatePayload_ChangeIssuer(propertyId); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_trade(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 4) + throw runtime_error( + "omni_createpayload_trade propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\"\n" + + "\nCreates the payload to place a trade offer on the distributed token exchange.\n" + + "\nArguments:\n" + "1. propertyidforsale (number, required) the identifier of the tokens to list for sale\n" + "2. amountforsale (string, required) the amount of tokens to list for sale\n" + "3. propertiddesired (number, required) the identifier of the tokens desired in exchange\n" + "4. amountdesired (string, required) the amount of tokens desired in exchange\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_trade", "31 \"250.0\" 1 \"10.0\"") + + HelpExampleRpc("omni_createpayload_trade", "31, \"250.0\", 1, \"10.0\"") + ); + + uint32_t propertyIdForSale = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyIdForSale); + int64_t amountForSale = ParseAmount(request.params[1], isPropertyDivisible(propertyIdForSale)); + uint32_t propertyIdDesired = ParsePropertyId(request.params[2]); + RequireExistingProperty(propertyIdDesired); + int64_t amountDesired = ParseAmount(request.params[3], isPropertyDivisible(propertyIdDesired)); + RequireSameEcosystem(propertyIdForSale, propertyIdDesired); + RequireDifferentIds(propertyIdForSale, propertyIdDesired); + RequireDifferentIds(propertyIdForSale, propertyIdDesired); + + std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_canceltradesbyprice(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 4) + throw runtime_error( + "omni_createpayload_canceltradesbyprice propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\"\n" + + "\nCreates the payload to cancel offers on the distributed token exchange with the specified price.\n" + + "\nArguments:\n" + "1. propertyidforsale (number, required) the identifier of the tokens listed for sale\n" + "2. amountforsale (string, required) the amount of tokens to listed for sale\n" + "3. propertiddesired (number, required) the identifier of the tokens desired in exchange\n" + "4. amountdesired (string, required) the amount of tokens desired in exchange\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_canceltradesbyprice", "31 \"100.0\" 1 \"5.0\"") + + HelpExampleRpc("omni_createpayload_canceltradesbyprice", "31, \"100.0\", 1, \"5.0\"") + ); + + uint32_t propertyIdForSale = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyIdForSale); + int64_t amountForSale = ParseAmount(request.params[1], isPropertyDivisible(propertyIdForSale)); + uint32_t propertyIdDesired = ParsePropertyId(request.params[2]); + RequireExistingProperty(propertyIdDesired); + int64_t amountDesired = ParseAmount(request.params[3], isPropertyDivisible(propertyIdDesired)); + RequireSameEcosystem(propertyIdForSale, propertyIdDesired); + RequireDifferentIds(propertyIdForSale, propertyIdDesired); + + std::vector payload = CreatePayload_MetaDExCancelPrice(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_canceltradesbypair(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 2) + throw runtime_error( + "omni_createpayload_canceltradesbypair propertyidforsale propertiddesired\n" + + "\nCreates the payload to cancel all offers on the distributed token exchange with the given currency pair.\n" + + "\nArguments:\n" + "1. propertyidforsale (number, required) the identifier of the tokens listed for sale\n" + "2. propertiddesired (number, required) the identifier of the tokens desired in exchange\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_canceltradesbypair", "1 31") + + HelpExampleRpc("omni_createpayload_canceltradesbypair", "1, 31") + ); + + uint32_t propertyIdForSale = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyIdForSale); + uint32_t propertyIdDesired = ParsePropertyId(request.params[1]); + RequireExistingProperty(propertyIdDesired); + RequireSameEcosystem(propertyIdForSale, propertyIdDesired); + RequireDifferentIds(propertyIdForSale, propertyIdDesired); + + std::vector payload = CreatePayload_MetaDExCancelPair(propertyIdForSale, propertyIdDesired); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_cancelalltrades(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "omni_createpayload_cancelalltrades ecosystem\n" + + "\nCreates the payload to cancel all offers on the distributed token exchange.\n" + + "\nArguments:\n" + "1. ecosystem (number, required) the ecosystem of the offers to cancel (1 for main ecosystem, 2 for test ecosystem)\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_cancelalltrades", "1") + + HelpExampleRpc("omni_createpayload_cancelalltrades", "1") + ); + + uint8_t ecosystem = ParseEcosystem(request.params[0]); + + std::vector payload = CreatePayload_MetaDExCancelEcosystem(ecosystem); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_enablefreezing(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "omni_createpayload_enablefreezing propertyid\n" + + "\nCreates the payload to enable address freezing for a centrally managed property.\n" + + "\nArguments:\n" + "1. propertyid (number, required) the identifier of the tokens\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_enablefreezing", "3") + + HelpExampleRpc("omni_createpayload_enablefreezing", "3") + ); + + uint32_t propertyId = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyId); + RequireManagedProperty(propertyId); + + std::vector payload = CreatePayload_EnableFreezing(propertyId); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_disablefreezing(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "omni_createpayload_disablefreezing propertyid\n" + + "\nCreates the payload to disable address freezing for a centrally managed property.\n" + "\nIMPORTANT NOTE: Disabling freezing for a property will UNFREEZE all frozen addresses for that property!" + + "\nArguments:\n" + "1. propertyid (number, required) the identifier of the tokens\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_disablefreezing", "3") + + HelpExampleRpc("omni_createpayload_disablefreezing", "3") + ); + + uint32_t propertyId = ParsePropertyId(request.params[0]); + RequireExistingProperty(propertyId); + RequireManagedProperty(propertyId); + + std::vector payload = CreatePayload_DisableFreezing(propertyId); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_freeze(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 3) + throw runtime_error( + "omni_createpayload_freeze \"toaddress\" propertyid amount \n" + + "\nCreates the payload to freeze an address for a centrally managed token.\n" + + "\nArguments:\n" + "1. toaddress (string, required) the address to freeze tokens for\n" + "2. propertyid (number, required) the property to freeze tokens for (must be managed type and have freezing option enabled)\n" + "3. amount (number, required) the amount of tokens to freeze (note: this is unused - once frozen an address cannot send any transactions)\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_freeze", "\"3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs\" 1 0") + + HelpExampleRpc("omni_createpayload_freeze", "\"3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs\", 1, 0") + ); + + std::string refAddress = ParseAddress(request.params[0]); + uint32_t propertyId = ParsePropertyId(request.params[1]); + int64_t amount = ParseAmount(request.params[2], isPropertyDivisible(propertyId)); + + RequireExistingProperty(propertyId); + RequireManagedProperty(propertyId); + + std::vector payload = CreatePayload_FreezeTokens(propertyId, amount, refAddress); + + return HexStr(payload.begin(), payload.end()); +} + +UniValue omni_createpayload_unfreeze(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 3) + throw runtime_error( + "omni_createpayload_unfreeze \"toaddress\" propertyid amount \n" + + "\nCreates the payload to unfreeze an address for a centrally managed token.\n" + + "\nArguments:\n" + "1. toaddress (string, required) the address to unfreeze tokens for\n" + "2. propertyid (number, required) the property to unfreeze tokens for (must be managed type and have freezing option enabled)\n" + "3. amount (number, required) the amount of tokens to unfreeze (note: this is unused)\n" + + "\nResult:\n" + "\"payload\" (string) the hex-encoded payload\n" + + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_unfreeze", "\"3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs\" 1 0") + + HelpExampleRpc("omni_createpayload_unfreeze", "\"3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs\", 1, 0") + ); + + std::string refAddress = ParseAddress(request.params[0]); + uint32_t propertyId = ParsePropertyId(request.params[1]); + int64_t amount = ParseAmount(request.params[2], isPropertyDivisible(propertyId)); + + RequireExistingProperty(propertyId); + RequireManagedProperty(propertyId); + + std::vector payload = CreatePayload_UnfreezeTokens(propertyId, amount, refAddress); + + return HexStr(payload.begin(), payload.end()); +} + + +UniValue omni_createpayload_sendactivation(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 3) + throw runtime_error( + "omni_createpayload_sendactivation featureid block minclientversion\n" + "\nActivate a protocol feature.\n" + "\nNote: Omni Core ignores activations from unauthorized sources.\n" + "\nArguments:\n" + "1. featureid (number, required) the identifier of the feature to activate\n" + "2. block (number, required) the activation block\n" + "3. minclientversion (number, required) the minimum supported client version\n" + "\nResult:\n" + "\"hash\" (string) the hex-encoded transaction hash\n" + "\nExamples:\n" + + HelpExampleCli("omni_createpayload_sendactivation", "\"1 370000 999") + + HelpExampleRpc("omni_createpayload_sendactivation", "\"1, 370000, 999") + ); + + // obtain parameters & info + uint16_t featureId = request.params[0].get_int(); + uint32_t activationBlock = request.params[1].get_int(); + uint32_t minClientVersion = request.params[2].get_int(); + + // create a payload for the transaction + std::vector payload = CreatePayload_ActivateFeature(featureId, activationBlock, minClientVersion); + + return HexStr(payload.begin(), payload.end()); +} static const CRPCCommand commands[] = { // category name actor (function) okSafeMode // -------------------------------- ----------------------------------------- ---------------------------------------- ---------- { "omni layer (payload creation)", "omni_createpayload_simplesend", &omni_createpayload_simplesend, true, {} }, - // { "omni layer (payload creation)", "omni_createpayload_sendall", &omni_createpayload_sendall, true }, - // { "omni layer (payload creation)", "omni_createpayload_dexsell", &omni_createpayload_dexsell, true }, - // { "omni layer (payload creation)", "omni_createpayload_dexaccept", &omni_createpayload_dexaccept, true }, - // { "omni layer (payload creation)", "omni_createpayload_sto", &omni_createpayload_sto, true }, - // { "omni layer (payload creation)", "omni_createpayload_grant", &omni_createpayload_grant, true }, - // { "omni layer (payload creation)", "omni_createpayload_revoke", &omni_createpayload_revoke, true }, - // { "omni layer (payload creation)", "omni_createpayload_changeissuer", &omni_createpayload_changeissuer, true }, - // { "omni layer (payload creation)", "omni_createpayload_trade", &omni_createpayload_trade, true }, - // { "omni layer (payload creation)", "omni_createpayload_issuancefixed", &omni_createpayload_issuancefixed, true }, - // { "omni layer (payload creation)", "omni_createpayload_issuancecrowdsale", &omni_createpayload_issuancecrowdsale, true }, - // { "omni layer (payload creation)", "omni_createpayload_issuancemanaged", &omni_createpayload_issuancemanaged, true }, - // { "omni layer (payload creation)", "omni_createpayload_closecrowdsale", &omni_createpayload_closecrowdsale, true }, - // { "omni layer (payload creation)", "omni_createpayload_canceltradesbyprice", &omni_createpayload_canceltradesbyprice, true }, - // { "omni layer (payload creation)", "omni_createpayload_canceltradesbypair", &omni_createpayload_canceltradesbypair, true }, - // { "omni layer (payload creation)", "omni_createpayload_cancelalltrades", &omni_createpayload_cancelalltrades, true }, - // { "omni layer (payload creation)", "omni_createpayload_enablefreezing", &omni_createpayload_enablefreezing, true }, - // { "omni layer (payload creation)", "omni_createpayload_disablefreezing", &omni_createpayload_disablefreezing, true }, - // { "omni layer (payload creation)", "omni_createpayload_freeze", &omni_createpayload_freeze, true }, - // { "omni layer (payload creation)", "omni_createpayload_unfreeze", &omni_createpayload_unfreeze, true }, + { "omni layer (payload creation)", "omni_createpayload_sendall", &omni_createpayload_sendall, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_dexsell", &omni_createpayload_dexsell, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_dexaccept", &omni_createpayload_dexaccept, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_sto", &omni_createpayload_sto, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_grant", &omni_createpayload_grant, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_revoke", &omni_createpayload_revoke, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_changeissuer", &omni_createpayload_changeissuer, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_trade", &omni_createpayload_trade, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_issuancefixed", &omni_createpayload_issuancefixed, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_issuancecrowdsale", &omni_createpayload_issuancecrowdsale, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_issuancemanaged", &omni_createpayload_issuancemanaged, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_closecrowdsale", &omni_createpayload_closecrowdsale, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_canceltradesbyprice", &omni_createpayload_canceltradesbyprice, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_canceltradesbypair", &omni_createpayload_canceltradesbypair, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_cancelalltrades", &omni_createpayload_cancelalltrades, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_enablefreezing", &omni_createpayload_enablefreezing, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_disablefreezing", &omni_createpayload_disablefreezing, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_freeze", &omni_createpayload_freeze, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_unfreeze", &omni_createpayload_unfreeze, true, {} }, + { "omni layer (payload creation)", "omni_createpayload_sendactivation", &omni_createpayload_sendactivation, true, {} }, }; void RegisterOmniPayloadCreationRPCCommands(CRPCTable &tableRPC) diff --git a/src/omnicore/rpcrawtx.cpp b/src/omnicore/rpcrawtx.cpp index 2fc0092fe..255feaeef 100644 --- a/src/omnicore/rpcrawtx.cpp +++ b/src/omnicore/rpcrawtx.cpp @@ -26,10 +26,10 @@ extern CCriticalSection cs_main; using mastercore::cs_tx_cache; using mastercore::view; -// -// UniValue omni_decodetransaction(const UniValue& params, bool fHelp) + +// UniValue omni_decodetransaction(const JSONRPCRequest& request) // { -// if (fHelp || params.size() < 1 || params.size() > 3) +// if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) // throw std::runtime_error( // "omni_decodetransaction \"rawtx\" ( \"prevtxs\" height )\n" // @@ -72,20 +72,20 @@ using mastercore::view; // + HelpExampleRpc("omni_decodetransaction", "\"010000000163af14ce6d477e1c793507e32a5b7696288fa89705c0d02a3f66beb3c5b8afee0100000000ffffffff02ac020000000000004751210261ea979f6a06f9dafe00fb1263ea0aca959875a7073556a088cdfadcd494b3752102a3fd0a8a067e06941e066f78d930bfc47746f097fcd3f7ab27db8ddf37168b6b52ae22020000000000001976a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac00000000\", [{\"txid\":\"eeafb8c5b3be663f2ad0c00597a88f2896765b2ae30735791c7e476dce14af63\",\"vout\":1,\"scriptPubKey\":\"76a9149084c0bd89289bc025d0264f7f23148fb683d56c88ac\",\"value\":0.0001123}]") // ); // -// CTransaction tx = ParseTransaction(params[0]); +// CTransaction tx = ParseTransaction(request.params[0]); // // // use a dummy coins view to store the user provided transaction inputs // CCoinsView viewDummyTemp; // CCoinsViewCache viewTemp(&viewDummyTemp); // -// if (params.size() > 1) { -// std::vector prevTxsParsed = ParsePrevTxs(params[1]); +// if (request.params.size() > 1) { +// std::vector prevTxsParsed = ParsePrevTxs(request.params[1]); // InputsToView(prevTxsParsed, viewTemp); // } // // int blockHeight = 0; -// if (params.size() > 2) { -// blockHeight = params[2].get_int(); +// if (request.params.size() > 2) { +// blockHeight = request.params[2].get_int(); // } // // UniValue txObj(UniValue::VOBJ); @@ -107,7 +107,7 @@ using mastercore::view; UniValue omni_createrawtx_opreturn(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "omni_createrawtx_opreturn \"rawtx\" \"payload\"\n" @@ -139,12 +139,12 @@ UniValue omni_createrawtx_opreturn(const JSONRPCRequest& request) .addOpReturn(payload) .build(); - return EncodeHexTx(tx); + return EncodeHexTx(CTransaction(tx)); } -// -// UniValue omni_createrawtx_multisig(const UniValue& params, bool fHelp) + +// UniValue omni_createrawtx_multisig(const JSONRPCRequest& request) // { -// if (fHelp || params.size() != 4) +// if (request.fHelp || request.params.size() != 4) // throw std::runtime_error( // "omni_createrawtx_multisig \"rawtx\" \"payload\" \"seed\" \"redeemkey\"\n" // @@ -168,57 +168,57 @@ UniValue omni_createrawtx_opreturn(const JSONRPCRequest& request) // + HelpExampleRpc("omni_createrawtx_multisig", "\"0100000001a7a9402ecd77f3c9f745793c9ec805bfa2e14b89877581c734c774864247e6f50400000000ffffffff01aa0a0000000000001976a9146d18edfe073d53f84dd491dae1379f8fb0dfe5d488ac00000000\", \"00000000000000020000000000989680\", \"1LifmeXYHeUe2qdKWBGVwfbUCMMrwYtoMm\", \"0252ce4bdd3ce38b4ebbc5a6e1343608230da508ff12d23d85b58c964204c4cef3\"") // ); // -// CMutableTransaction tx = ParseMutableTransaction(params[0]); -// std::vector payload = ParseHexV(params[1], "payload"); -// std::string obfuscationSeed = ParseAddressOrEmpty(params[2]); -// CPubKey redeemKey = ParsePubKeyOrAddress(params[3]); +// CMutableTransaction tx = ParseMutableTransaction(request.params[0]); +// std::vector payload = ParseHexV(request.params[1], "payload"); +// std::string obfuscationSeed = ParseAddressOrEmpty(request.params[2]); +// CPubKey redeemKey = ParsePubKeyOrAddress(request.params[3]); // // // extend the transaction // tx = OmniTxBuilder(tx) // .addMultisig(payload, obfuscationSeed, redeemKey) // .build(); // -// return EncodeHexTx(tx); -// } -// -// UniValue omni_createrawtx_input(const UniValue& params, bool fHelp) -// { -// if (fHelp || params.size() != 3) -// throw std::runtime_error( -// "omni_createrawtx_input \"rawtx\" \"txid\" n\n" -// -// "\nAdds a transaction input to the transaction.\n" -// -// "\nIf no raw transaction is provided, a new transaction is created.\n" -// -// "\nArguments:\n" -// "1. rawtx (string, required) the raw transaction to extend (can be null)\n" -// "2. txid (string, required) the hash of the input transaction\n" -// "3. n (number, required) the index of the transaction output used as input\n" -// -// "\nResult:\n" -// "\"rawtx\" (string) the hex-encoded modified raw transaction\n" -// -// "\nExamples\n" -// + HelpExampleCli("omni_createrawtx_input", "\"01000000000000000000\" \"b006729017df05eda586df9ad3f8ccfee5be340aadf88155b784d1fc0e8342ee\" 0") -// + HelpExampleRpc("omni_createrawtx_input", "\"01000000000000000000\", \"b006729017df05eda586df9ad3f8ccfee5be340aadf88155b784d1fc0e8342ee\", 0") -// ); -// -// CMutableTransaction tx = ParseMutableTransaction(params[0]); -// uint256 txid = ParseHashV(params[1], "txid"); -// uint32_t nOut = ParseOutputIndex(params[2]); -// -// // extend the transaction -// tx = OmniTxBuilder(tx) -// .addInput(txid, nOut) -// .build(); -// -// return EncodeHexTx(tx); +// return EncodeHexTx(CTransaction(tx)); // } -// + +UniValue omni_createrawtx_input(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 3) + throw std::runtime_error( + "omni_createrawtx_input \"rawtx\" \"txid\" n\n" + + "\nAdds a transaction input to the transaction.\n" + + "\nIf no raw transaction is provided, a new transaction is created.\n" + + "\nArguments:\n" + "1. rawtx (string, required) the raw transaction to extend (can be null)\n" + "2. txid (string, required) the hash of the input transaction\n" + "3. n (number, required) the index of the transaction output used as input\n" + + "\nResult:\n" + "\"rawtx\" (string) the hex-encoded modified raw transaction\n" + + "\nExamples\n" + + HelpExampleCli("omni_createrawtx_input", "\"01000000000000000000\" \"b006729017df05eda586df9ad3f8ccfee5be340aadf88155b784d1fc0e8342ee\" 0") + + HelpExampleRpc("omni_createrawtx_input", "\"01000000000000000000\", \"b006729017df05eda586df9ad3f8ccfee5be340aadf88155b784d1fc0e8342ee\", 0") + ); + + CMutableTransaction tx = ParseMutableTransaction(request.params[0]); + uint256 txid = ParseHashV(request.params[1], "txid"); + uint32_t nOut = ParseOutputIndex(request.params[2]); + + // extend the transaction + tx = OmniTxBuilder(tx) + .addInput(txid, nOut) + .build(); + + return EncodeHexTx(CTransaction(tx)); +} + UniValue omni_createrawtx_reference(const JSONRPCRequest& request) { - if (request.params.size() < 2 || request.params.size() > 3) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw std::runtime_error( "omni_createrawtx_reference \"rawtx\" \"destination\" ( amount )\n" @@ -252,12 +252,12 @@ UniValue omni_createrawtx_reference(const JSONRPCRequest& request) .addReference(destination, amount) .build(); - return EncodeHexTx(tx); + return EncodeHexTx(CTransaction(tx)); } UniValue omni_createrawtx_change(const JSONRPCRequest& request) { - if (request.params.size() < 4 || request.params.size() > 5) + if (request.fHelp || request.params.size() < 4 || request.params.size() > 5) throw std::runtime_error( "omni_createrawtx_change \"rawtx\" \"prevtxs\" \"destination\" fee ( position )\n" @@ -317,7 +317,7 @@ UniValue omni_createrawtx_change(const JSONRPCRequest& request) .addChange(destination, viewTemp, txFee, nOut) .build(); - return EncodeHexTx(tx); + return EncodeHexTx(CTransaction(tx)); } static const CRPCCommand commands[] = @@ -325,8 +325,8 @@ static const CRPCCommand commands[] = // -------------------------------- ----------------------------- ---------------------------- ---------- // { "omni layer (raw transactions)", "omni_decodetransaction", &omni_decodetransaction, true }, { "omni layer (raw transactions)", "omni_createrawtx_opreturn", &omni_createrawtx_opreturn, true, {} }, - // { "omni layer (raw transactions)", "omni_createrawtx_multisig", &omni_createrawtx_multisig, true, {} }, - // { "omni layer (raw transactions)", "omni_createrawtx_input", &omni_createrawtx_input, true. {} }, + // { "omni layer (raw transactions)", "omni_createrawtx_multisig", &omni_createrawtx_, true, {} }, + { "omni layer (raw transactions)", "omni_createrawtx_input", &omni_createrawtx_input, true, {} }, { "omni layer (raw transactions)", "omni_createrawtx_reference", &omni_createrawtx_reference, true, {} }, { "omni layer (raw transactions)", "omni_createrawtx_change", &omni_createrawtx_change, true, {} }, diff --git a/src/omnicore/rpctx.cpp b/src/omnicore/rpctx.cpp index c4687dae1..ae7c8c195 100644 --- a/src/omnicore/rpctx.cpp +++ b/src/omnicore/rpctx.cpp @@ -40,7 +40,7 @@ using namespace mastercore; UniValue omni_sendrawtx(const JSONRPCRequest& request) { - if (request.params.size() < 2 || request.params.size() > 5) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( "omni_sendrawtx \"fromaddress\" \"rawtransaction\" ( \"referenceaddress\" \"redeemaddress\" \"referenceamount\" )\n" "\nBroadcasts a raw Omni Layer transaction.\n" @@ -80,9 +80,9 @@ UniValue omni_sendrawtx(const JSONRPCRequest& request) } } -UniValue omni_send(const JSONRPCRequest& request) // TODO: add the fhelp bool +UniValue omni_send(const JSONRPCRequest& request) { - if (request.params.size() < 4 || request.params.size() > 6) + if (request.fHelp || request.params.size() < 4 || request.params.size() > 6) throw runtime_error( "omni_send \"fromaddress\" \"toaddress\" propertyid \"amount\" ( \"redeemaddress\" \"referenceamount\" )\n" @@ -140,7 +140,7 @@ UniValue omni_send(const JSONRPCRequest& request) // TODO: add the fhelp bool UniValue omni_sendall(const JSONRPCRequest& request) { - if (request.params.size() < 3 || request.params.size() > 5) + if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) throw runtime_error( "omni_sendall \"fromaddress\" \"toaddress\" ecosystem ( \"redeemaddress\" \"referenceamount\" )\n" @@ -194,7 +194,7 @@ UniValue omni_sendall(const JSONRPCRequest& request) UniValue omni_senddexsell(const JSONRPCRequest& request) { - if (request.params.size() != 7) + if (request.fHelp || request.params.size() != 7) throw runtime_error( "omni_senddexsell \"fromaddress\" propertyidforsale \"amountforsale\" \"amountdesired\" paymentwindow minacceptfee action\n" @@ -283,7 +283,7 @@ UniValue omni_senddexsell(const JSONRPCRequest& request) UniValue omni_senddexaccept(const JSONRPCRequest& request) { - if (request.params.size() < 4 || request.params.size() > 5) + if (request.fHelp || request.params.size() < 4 || request.params.size() > 5) throw runtime_error( "omni_senddexaccept \"fromaddress\" \"toaddress\" propertyid \"amount\" ( override )\n" @@ -365,7 +365,7 @@ UniValue omni_senddexaccept(const JSONRPCRequest& request) UniValue omni_sendissuancecrowdsale(const JSONRPCRequest& request) { - if (request.params.size() != 14) + if (request.fHelp || request.params.size() != 14) throw runtime_error( "omni_sendissuancecrowdsale \"fromaddress\" ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\" propertyiddesired tokensperunit deadline ( earlybonus issuerpercentage )\n" @@ -438,7 +438,7 @@ UniValue omni_sendissuancecrowdsale(const JSONRPCRequest& request) UniValue omni_sendissuancefixed(const JSONRPCRequest& request) { - if (request.params.size() != 10) + if (request.fHelp || request.params.size() != 10) throw runtime_error( "omni_sendissuancefixed \"fromaddress\" ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\" \"amount\"\n" @@ -501,7 +501,7 @@ UniValue omni_sendissuancefixed(const JSONRPCRequest& request) UniValue omni_sendissuancemanaged(const JSONRPCRequest& request) { - if (request.params.size() != 9) + if (request.fHelp || request.params.size() != 9) throw runtime_error( "omni_sendissuancemanaged \"fromaddress\" ecosystem type previousid \"category\" \"subcategory\" \"name\" \"url\" \"data\"\n" @@ -562,7 +562,7 @@ UniValue omni_sendissuancemanaged(const JSONRPCRequest& request) UniValue omni_sendsto(const JSONRPCRequest& request) { - if (request.params.size() < 3 || request.params.size() > 5) + if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) throw runtime_error( "omni_sendsto \"fromaddress\" propertyid \"amount\" ( \"redeemaddress\" distributionproperty )\n" @@ -616,7 +616,7 @@ UniValue omni_sendsto(const JSONRPCRequest& request) UniValue omni_sendgrant(const JSONRPCRequest& request) { - if (request.params.size() < 4 || request.params.size() > 5) + if (request.fHelp || request.params.size() < 4 || request.params.size() > 5) throw runtime_error( "omni_sendgrant \"fromaddress\" \"toaddress\" propertyid \"amount\" ( \"memo\" )\n" @@ -671,7 +671,7 @@ UniValue omni_sendgrant(const JSONRPCRequest& request) UniValue omni_sendrevoke(const JSONRPCRequest& request) { - if (request.params.size() < 3 || request.params.size() > 4) + if (request.fHelp || request.params.size() < 3 || request.params.size() > 4) throw runtime_error( "omni_sendrevoke \"fromaddress\" propertyid \"amount\" ( \"memo\" )\n" @@ -725,7 +725,7 @@ UniValue omni_sendrevoke(const JSONRPCRequest& request) UniValue omni_sendclosecrowdsale(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "omni_sendclosecrowdsale \"fromaddress\" propertyid\n" @@ -775,7 +775,7 @@ UniValue omni_sendclosecrowdsale(const JSONRPCRequest& request) UniValue trade_MP(const JSONRPCRequest& request) { - if (request.params.size() != 6) + if (request.fHelp || request.params.size() != 6) throw runtime_error( "trade_MP \"fromaddress\" propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\" action\n" "\nNote: this command is depreciated, and was replaced by:\n" @@ -837,7 +837,7 @@ UniValue trade_MP(const JSONRPCRequest& request) UniValue omni_sendtrade(const JSONRPCRequest& request) { - if (request.params.size() != 5) + if (request.fHelp || request.params.size() != 5) throw runtime_error( "omni_sendtrade \"fromaddress\" propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\"\n" @@ -895,7 +895,7 @@ UniValue omni_sendtrade(const JSONRPCRequest& request) UniValue omni_sendcanceltradesbyprice(const JSONRPCRequest& request) { - if (request.params.size() != 5) + if (request.fHelp || request.params.size() != 5) throw runtime_error( "omni_sendcanceltradesbyprice \"fromaddress\" propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\"\n" @@ -953,7 +953,7 @@ UniValue omni_sendcanceltradesbyprice(const JSONRPCRequest& request) UniValue omni_sendcanceltradesbypair(const JSONRPCRequest& request) { - if (request.params.size() != 3) + if (request.fHelp || request.params.size() != 3) throw runtime_error( "omni_sendcanceltradesbypair \"fromaddress\" propertyidforsale propertiddesired\n" @@ -1007,7 +1007,7 @@ UniValue omni_sendcanceltradesbypair(const JSONRPCRequest& request) UniValue omni_sendcancelalltrades(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "omni_sendcancelalltrades \"fromaddress\" ecosystem\n" @@ -1055,7 +1055,7 @@ UniValue omni_sendcancelalltrades(const JSONRPCRequest& request) UniValue omni_sendchangeissuer(const JSONRPCRequest& request) { - if (request.params.size() != 3) + if (request.fHelp || request.params.size() != 3) throw runtime_error( "omni_sendchangeissuer \"fromaddress\" \"toaddress\" propertyid\n" @@ -1105,7 +1105,7 @@ UniValue omni_sendchangeissuer(const JSONRPCRequest& request) UniValue omni_sendenablefreezing(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "omni_sendenablefreezing \"fromaddress\" propertyid\n" @@ -1154,7 +1154,7 @@ UniValue omni_sendenablefreezing(const JSONRPCRequest& request) UniValue omni_senddisablefreezing(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "omni_senddisablefreezing \"fromaddress\" propertyid\n" @@ -1204,7 +1204,7 @@ UniValue omni_senddisablefreezing(const JSONRPCRequest& request) UniValue omni_sendfreeze(const JSONRPCRequest& request) { - if (request.params.size() != 4) + if (request.fHelp || request.params.size() != 4) throw runtime_error( "omni_sendfreeze \"fromaddress\" \"toaddress\" propertyid amount \n" "\nFreeze an address for a centrally managed token.\n" @@ -1255,7 +1255,7 @@ UniValue omni_sendfreeze(const JSONRPCRequest& request) UniValue omni_sendunfreeze(const JSONRPCRequest& request) { - if (request.params.size() != 4) + if (request.fHelp || request.params.size() != 4) throw runtime_error( "omni_sendunfreeze \"fromaddress\" \"toaddress\" propertyid amount \n" "\nUnfreezes an address for a centrally managed token.\n" @@ -1306,7 +1306,7 @@ UniValue omni_sendunfreeze(const JSONRPCRequest& request) UniValue omni_sendactivation(const JSONRPCRequest& request) { - if (request.params.size() != 4) + if (request.fHelp || request.params.size() != 4) throw runtime_error( "omni_sendactivation \"fromaddress\" featureid block minclientversion\n" "\nActivate a protocol feature.\n" @@ -1351,7 +1351,7 @@ UniValue omni_sendactivation(const JSONRPCRequest& request) UniValue omni_senddeactivation(const JSONRPCRequest& request) { - if (request.params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "omni_senddeactivation \"fromaddress\" featureid\n" "\nDeactivate a protocol feature. For Emergency Use Only.\n" @@ -1392,7 +1392,7 @@ UniValue omni_senddeactivation(const JSONRPCRequest& request) UniValue omni_sendalert(const JSONRPCRequest& request) { - if (request.params.size() != 4) + if (request.fHelp || request.params.size() != 4) throw runtime_error( "omni_sendalert \"fromaddress\" alerttype expiryvalue typecheck versioncheck \"message\"\n" "\nCreates and broadcasts an Omni Core alert.\n" @@ -1445,7 +1445,7 @@ UniValue omni_sendalert(const JSONRPCRequest& request) UniValue omni_send_dexpayment(const JSONRPCRequest& request) { - if (request.params.size() != 3) + if (request.fHelp || request.params.size() != 3) throw runtime_error( "omni_send_dexpayment \"fromaddress\" \"toaddress\"amount\" \n" diff --git a/src/omnicore/rpctxobject.cpp b/src/omnicore/rpctxobject.cpp index a5d73d2b5..b32b80161 100644 --- a/src/omnicore/rpctxobject.cpp +++ b/src/omnicore/rpctxobject.cpp @@ -92,7 +92,7 @@ int populateRPCTransactionObject(const CTransaction& tx, const uint256& blockHas uint64_t tmpVout, tmpNValue, tmpPropertyId; { LOCK(cs_tally); - // p_txlistdb->getPurchaseDetails(txid, 1, &tmpBuyer, &tmpSeller, &tmpVout, &tmpPropertyId, &tmpNValue); + p_txlistdb->getPurchaseDetails(txid, 1, &tmpBuyer, &tmpSeller, &tmpVout, &tmpPropertyId, &tmpNValue); } UniValue purchases(UniValue::VARR); if (populateRPCDExPurchases(tx, purchases, filterAddress) <= 0) return -1; diff --git a/src/omnicore/rules.cpp b/src/omnicore/rules.cpp index 177975054..817a6dfbd 100644 --- a/src/omnicore/rules.cpp +++ b/src/omnicore/rules.cpp @@ -47,7 +47,7 @@ std::vector CConsensusParams::GetRestrictions() const { MSC_TYPE_TRADE_OFFER, MP_TX_PKT_V1, false, MSC_DEX_BLOCK }, { MSC_TYPE_ACCEPT_OFFER_BTC, MP_TX_PKT_V0, false, MSC_DEX_BLOCK }, - { MSC_TYPE_CREATE_PROPERTY_FIXED, MP_TX_PKT_V0, false, MSC_SP_BLOCK }, + { MSC_TYPE_CREATE_PROPERTY_FIXED, MP_TX_PKT_V0, false, MSC_FIXED_BLOCK }, { MSC_TYPE_CREATE_PROPERTY_VARIABLE, MP_TX_PKT_V0, false, MSC_SP_BLOCK }, { MSC_TYPE_CREATE_PROPERTY_VARIABLE, MP_TX_PKT_V1, false, MSC_SP_BLOCK }, { MSC_TYPE_CLOSE_CROWDSALE, MP_TX_PKT_V0, false, MSC_SP_BLOCK }, @@ -61,18 +61,17 @@ std::vector CConsensusParams::GetRestrictions() const { MSC_TYPE_FREEZE_PROPERTY_TOKENS, MP_TX_PKT_V0, false, MSC_MANUALSP_BLOCK }, { MSC_TYPE_UNFREEZE_PROPERTY_TOKENS, MP_TX_PKT_V0, false, MSC_MANUALSP_BLOCK }, - { MSC_TYPE_SEND_TO_OWNERS, MP_TX_PKT_V0, false, MSC_STO_BLOCK }, - { MSC_TYPE_SEND_TO_OWNERS, MP_TX_PKT_V1, false, MSC_STOV1_BLOCK }, + { MSC_TYPE_TRADE_OFFER, MP_TX_PKT_V0, false, MSC_DEX_BLOCK }, + { MSC_TYPE_ACCEPT_OFFER_BTC, MP_TX_PKT_V1, false, MSC_DEX_BLOCK }, + { MSC_TYPE_DEX_PAYMENT, MP_TX_PKT_V0, true, MSC_DEX_BLOCK }, { MSC_TYPE_METADEX_TRADE, MP_TX_PKT_V0, false, MSC_METADEX_BLOCK }, { MSC_TYPE_METADEX_CANCEL_PRICE, MP_TX_PKT_V0, false, MSC_METADEX_BLOCK }, { MSC_TYPE_METADEX_CANCEL_PAIR, MP_TX_PKT_V0, false, MSC_METADEX_BLOCK }, { MSC_TYPE_METADEX_CANCEL_ECOSYSTEM, MP_TX_PKT_V0, false, MSC_METADEX_BLOCK }, - { MSC_TYPE_SEND_ALL, MP_TX_PKT_V0, false, MSC_SEND_ALL_BLOCK }, + { MSC_TYPE_SEND_ALL, MP_TX_PKT_V0, false, MSC_SEND_ALL_BLOCK } - { MSC_TYPE_OFFER_ACCEPT_A_BET, MP_TX_PKT_V0, false, MSC_BET_BLOCK }, - { MSC_TYPE_DEX_PAYMENT, MP_TX_PKT_V0, true, MSC_METADEX_BLOCK } }; const size_t nSize = sizeof(vTxRestrictions) / sizeof(vTxRestrictions[0]); @@ -159,40 +158,28 @@ std::vector CMainConsensusParams::GetCheckpoints() const */ CMainConsensusParams::CMainConsensusParams() { - // Exodus related: - exodusBonusPerWeek = 0.10; - exodusDeadline = 1377993600; - exodusReward = 100; - GENESIS_BLOCK = 580398; - LAST_EXODUS_BLOCK = 580398; + + GENESIS_BLOCK = 99999999; // Notice range for feature activations: MIN_ACTIVATION_BLOCKS = 2048; // ~2 weeks MAX_ACTIVATION_BLOCKS = 12288; // ~12 weeks - // Waiting period for enabling freezing - OMNI_FREEZE_WAIT_PERIOD = 4096; // ~4 weeks // Script related: - PUBKEYHASH_BLOCK = 0; - SCRIPTHASH_BLOCK = 322000; - MULTISIG_BLOCK = 0; - NULLDATA_BLOCK = 395000; + PUBKEYHASH_BLOCK = 99999999; + SCRIPTHASH_BLOCK = 99999999; + MULTISIG_BLOCK = 99999999; + NULLDATA_BLOCK = 99999999; // Transaction restrictions: - MSC_ALERT_BLOCK = 0; - MSC_SEND_BLOCK = 249498; - MSC_DEX_BLOCK = 290630; - MSC_SP_BLOCK = 297110; - MSC_MANUALSP_BLOCK = 323230; - MSC_STO_BLOCK = 342650; - MSC_METADEX_BLOCK = 400000; - MSC_SEND_ALL_BLOCK = 395000; - MSC_BET_BLOCK = 999999; - MSC_STOV1_BLOCK = 999999; - // Other feature activations: - GRANTEFFECTS_FEATURE_BLOCK = 394500; - DEXMATH_FEATURE_BLOCK = 395000; - SPCROWDCROSSOVER_FEATURE_BLOCK = 395000; - TRADEALLPAIRS_FEATURE_BLOCK = 438500; - FEES_FEATURE_BLOCK = 999999; - FREEZENOTICE_FEATURE_BLOCK = 999999; + MSC_ALERT_BLOCK = 99999999; + MSC_SEND_BLOCK = 99999999; + MSC_DEX_BLOCK = 99999999; + MSC_SP_BLOCK = 99999999; + MSC_MANUALSP_BLOCK = 99999999; + MSC_STO_BLOCK = 99999999; + MSC_METADEX_BLOCK = 99999999; + MSC_CRODWSALE_BLOCK = 99999999; + MSC_SEND_ALL_BLOCK = 99999999; + MSC_STOV1_BLOCK = 99999999; + MSC_FIXED_BLOCK = 99999999; } /** @@ -201,39 +188,27 @@ CMainConsensusParams::CMainConsensusParams() CTestNetConsensusParams::CTestNetConsensusParams() { // Exodus related: - exodusBonusPerWeek = 0.00; - exodusDeadline = 1377993600; - exodusReward = 100; - GENESIS_BLOCK = 0; - LAST_EXODUS_BLOCK = std::numeric_limits::max(); + GENESIS_BLOCK = 85260; // Notice range for feature activations: MIN_ACTIVATION_BLOCKS = 0; - MAX_ACTIVATION_BLOCKS = 999999; - // Waiting period for enabling freezing - OMNI_FREEZE_WAIT_PERIOD = 0; + MAX_ACTIVATION_BLOCKS = 99999999; // Script related: - PUBKEYHASH_BLOCK = 0; - SCRIPTHASH_BLOCK = 0; - MULTISIG_BLOCK = 0; - NULLDATA_BLOCK = 0; + PUBKEYHASH_BLOCK = 85260; + SCRIPTHASH_BLOCK = 85260; + MULTISIG_BLOCK = 85260; + NULLDATA_BLOCK = 85260; // Transaction restrictions: - MSC_ALERT_BLOCK = 0; - MSC_SEND_BLOCK = 0; - MSC_DEX_BLOCK = 0; - MSC_SP_BLOCK = 0; - MSC_MANUALSP_BLOCK = 0; - MSC_STO_BLOCK = 0; - MSC_METADEX_BLOCK = 0; - MSC_SEND_ALL_BLOCK = 0; - MSC_BET_BLOCK = 999999; - MSC_STOV1_BLOCK = 0; - // Other feature activations: - GRANTEFFECTS_FEATURE_BLOCK = 0; - DEXMATH_FEATURE_BLOCK = 0; - SPCROWDCROSSOVER_FEATURE_BLOCK = 0; - TRADEALLPAIRS_FEATURE_BLOCK = 0; - FEES_FEATURE_BLOCK = 0; - FREEZENOTICE_FEATURE_BLOCK = 0; + MSC_ALERT_BLOCK = 85260; + MSC_SEND_BLOCK = 85260; + MSC_DEX_BLOCK = 99999999; + MSC_SP_BLOCK = 99999999; + MSC_MANUALSP_BLOCK = 99999999; + MSC_STO_BLOCK = 99999999; + MSC_METADEX_BLOCK = 99999999; + MSC_SEND_ALL_BLOCK = 99999999; + MSC_STOV1_BLOCK = 99999999; + MSC_CRODWSALE_BLOCK = 99999999; + MSC_FIXED_BLOCK = 99999999; } /** @@ -242,16 +217,11 @@ CTestNetConsensusParams::CTestNetConsensusParams() CRegTestConsensusParams::CRegTestConsensusParams() { // Exodus related: - exodusBonusPerWeek = 0.00; - exodusDeadline = 1377993600; - exodusReward = 100; GENESIS_BLOCK = 101; - LAST_EXODUS_BLOCK = std::numeric_limits::max(); // Notice range for feature activations: MIN_ACTIVATION_BLOCKS = 5; - MAX_ACTIVATION_BLOCKS = 10; - // Waiting period for enabling freezing - OMNI_FREEZE_WAIT_PERIOD = 10; + MAX_ACTIVATION_BLOCKS = 200; + // Script related: PUBKEYHASH_BLOCK = 0; SCRIPTHASH_BLOCK = 0; @@ -266,15 +236,9 @@ CRegTestConsensusParams::CRegTestConsensusParams() MSC_STO_BLOCK = 0; MSC_METADEX_BLOCK = 0; MSC_SEND_ALL_BLOCK = 0; - MSC_BET_BLOCK = 999999; - MSC_STOV1_BLOCK = 999999; - // Other feature activations: - GRANTEFFECTS_FEATURE_BLOCK = 999999; - DEXMATH_FEATURE_BLOCK = 999999; - SPCROWDCROSSOVER_FEATURE_BLOCK = 999999; - TRADEALLPAIRS_FEATURE_BLOCK = 999999; - FEES_FEATURE_BLOCK = 999999; - FREEZENOTICE_FEATURE_BLOCK = 999999; + MSC_STOV1_BLOCK = 0; + MSC_CRODWSALE_BLOCK = 0; + MSC_FIXED_BLOCK = 0; } //! Consensus parameters for mainnet @@ -394,6 +358,7 @@ bool ActivateFeature(uint16_t featureId, int activationBlock, uint32_t minClient if ((activationBlock < (transactionBlock + params.MIN_ACTIVATION_BLOCKS)) || (activationBlock > (transactionBlock + params.MAX_ACTIVATION_BLOCKS))) { PrintToLog("Feature activation of ID %d refused due to notice checks\n", featureId); + PrintToLog("activationBlock: %d, transactionBlock: %d, params.MIN_ACTIVATION_BLOCKS: %d, params.MAX_ACTIVATION_BLOCKS: %d\n",activationBlock, transactionBlock, params.MIN_ACTIVATION_BLOCKS, params.MAX_ACTIVATION_BLOCKS); return false; } @@ -407,39 +372,22 @@ bool ActivateFeature(uint16_t featureId, int activationBlock, uint32_t minClient std::string featureName = GetFeatureName(featureId); bool supported = OMNICORE_VERSION >= minClientVersion; switch (featureId) { - case FEATURE_CLASS_C: - MutableConsensusParams().NULLDATA_BLOCK = activationBlock; break; + case FEATURE_FIXED: + MutableConsensusParams().MSC_FIXED_BLOCK = activationBlock; + break; + case FEATURE_MANAGED: + MutableConsensusParams().MSC_MANUALSP_BLOCK = activationBlock; + break; + case FEATURE_DEX: + MutableConsensusParams().MSC_DEX_BLOCK = activationBlock; + break; case FEATURE_METADEX: MutableConsensusParams().MSC_METADEX_BLOCK = activationBlock; - break; - case FEATURE_BETTING: - MutableConsensusParams().MSC_BET_BLOCK = activationBlock; - break; - case FEATURE_GRANTEFFECTS: - MutableConsensusParams().GRANTEFFECTS_FEATURE_BLOCK = activationBlock; - break; - case FEATURE_DEXMATH: - MutableConsensusParams().DEXMATH_FEATURE_BLOCK = activationBlock; - break; - case FEATURE_SENDALL: - MutableConsensusParams().MSC_SEND_ALL_BLOCK = activationBlock; - break; - case FEATURE_SPCROWDCROSSOVER: - MutableConsensusParams().SPCROWDCROSSOVER_FEATURE_BLOCK = activationBlock; - break; - case FEATURE_TRADEALLPAIRS: - MutableConsensusParams().TRADEALLPAIRS_FEATURE_BLOCK = activationBlock; - break; - case FEATURE_FEES: - MutableConsensusParams().FEES_FEATURE_BLOCK = activationBlock; - break; - case FEATURE_STOV1: - MutableConsensusParams().MSC_STOV1_BLOCK = activationBlock; - break; - case FEATURE_FREEZENOTICE: - MutableConsensusParams().FREEZENOTICE_FEATURE_BLOCK = activationBlock; - break; + break; + case FEATURE_CROWDSALES: + MutableConsensusParams().MSC_CRODWSALE_BLOCK = activationBlock; + break; default: supported = false; break; @@ -478,39 +426,22 @@ bool DeactivateFeature(uint16_t featureId, int transactionBlock) std::string featureName = GetFeatureName(featureId); switch (featureId) { - case FEATURE_CLASS_C: - MutableConsensusParams().NULLDATA_BLOCK = 999999; - break; + case FEATURE_FIXED: + MutableConsensusParams().MSC_FIXED_BLOCK = 99999999; + break; + case FEATURE_MANAGED: + MutableConsensusParams().MSC_MANUALSP_BLOCK = 99999999; + break; + case FEATURE_DEX: + MutableConsensusParams().MSC_DEX_BLOCK = 99999999; + 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; - case FEATURE_FREEZENOTICE: - MutableConsensusParams().FREEZENOTICE_FEATURE_BLOCK = 999999; - break; + MutableConsensusParams().MSC_METADEX_BLOCK = 99999999; + break; + + case FEATURE_CROWDSALES: + MutableConsensusParams().MSC_CRODWSALE_BLOCK = 99999999; + break; default: return false; break; @@ -531,18 +462,11 @@ bool DeactivateFeature(uint16_t featureId, int transactionBlock) std::string GetFeatureName(uint16_t featureId) { switch (featureId) { - case FEATURE_CLASS_C: return "Class C transaction encoding"; + case FEATURE_FIXED: return "Token Creation (fixed amount)"; + case FEATURE_MANAGED: return "Token Creation (managed)"; + case FEATURE_DEX: return "Distributed Exchange (BTG for Tokens)"; 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"; - case FEATURE_FREEZENOTICE: return "Activate the waiting period for enabling freezing"; - + case FEATURE_CROWDSALES: return "Crodwsales creation"; default: return "Unknown feature"; } } @@ -556,39 +480,22 @@ bool IsFeatureActivated(uint16_t featureId, int transactionBlock) int activationBlock = std::numeric_limits::max(); switch (featureId) { - case FEATURE_CLASS_C: - activationBlock = params.NULLDATA_BLOCK; - break; - case FEATURE_METADEX: - activationBlock = params.MSC_METADEX_BLOCK; + case FEATURE_FIXED: + activationBlock = params.MSC_FIXED_BLOCK; break; - case FEATURE_BETTING: - activationBlock = params.MSC_BET_BLOCK; + case FEATURE_MANAGED: + activationBlock = params.MSC_MANUALSP_BLOCK; break; - case FEATURE_GRANTEFFECTS: - activationBlock = params.GRANTEFFECTS_FEATURE_BLOCK; + case FEATURE_DEX: + activationBlock = params.MSC_DEX_BLOCK; break; - case FEATURE_DEXMATH: - activationBlock = params.DEXMATH_FEATURE_BLOCK; - break; - case FEATURE_SENDALL: - activationBlock = params.MSC_SEND_ALL_BLOCK; - break; - case FEATURE_SPCROWDCROSSOVER: - activationBlock = params.SPCROWDCROSSOVER_FEATURE_BLOCK; - break; - case FEATURE_TRADEALLPAIRS: - activationBlock = params.TRADEALLPAIRS_FEATURE_BLOCK; - break; - case FEATURE_FEES: - activationBlock = params.FEES_FEATURE_BLOCK; + case FEATURE_METADEX: + activationBlock = params.MSC_METADEX_BLOCK; break; - case FEATURE_STOV1: - activationBlock = params.MSC_STOV1_BLOCK; + case FEATURE_CROWDSALES: + activationBlock = params.MSC_CRODWSALE_BLOCK; break; - case FEATURE_FREEZENOTICE: - activationBlock = params.FREEZENOTICE_FEATURE_BLOCK; - break; + default: return false; } @@ -613,7 +520,6 @@ bool IsTransactionTypeAllowed(int txBlock, uint32_t txProperty, uint16_t txType, { const TransactionRestriction& entry = *it; if (entry.txType != txType || entry.txVersion != version) { - PrintToLog("%s(): first continue\n",__func__); continue; } // a property identifier of 0 (= BTC) may be used as wildcard diff --git a/src/omnicore/rules.h b/src/omnicore/rules.h index 2a97bcd41..54acc6081 100644 --- a/src/omnicore/rules.h +++ b/src/omnicore/rules.h @@ -9,33 +9,18 @@ namespace mastercore { -//! Block to enable the Exodus fundraiser address in regtest mode -const int MONEYMAN_REGTEST_BLOCK = 101; -//! Block to enable the Exodus fundraiser address on testnet -const int MONEYMAN_TESTNET_BLOCK = 40000; -//! Feature identifier to enable Class C transaction parsing and processing -const uint16_t FEATURE_CLASS_C = 1; + //! Feature identifier to enable token creation (fixed amount) +const uint16_t FEATURE_FIXED = 1; +//! Feature identifier to enable token creation (managed) +const uint16_t FEATURE_MANAGED = 2; +//! Feature identifier to enable the distributed exchange (BTG for Tokens) +const uint16_t FEATURE_DEX = 3; //! Feature identifier to enable the distributed token exchange -const uint16_t FEATURE_METADEX = 2; -//! Feature identifier to enable betting transactions -const uint16_t FEATURE_BETTING = 3; -//! Feature identifier to disable crowdsale participations when "granting tokens" -const uint16_t FEATURE_GRANTEFFECTS = 4; -//! Feature identifier to disable DEx "over-offers" and to switch to plain integer math -const uint16_t FEATURE_DEXMATH = 5; -//! Feature identifier to enable Send All transactions -const uint16_t FEATURE_SENDALL = 6; -//! Feature identifier disable ecosystem crossovers in crowdsale logic -const uint16_t FEATURE_SPCROWDCROSSOVER = 7; -//! Feature identifier to enable non-Omni pairs on the distributed exchange -const uint16_t FEATURE_TRADEALLPAIRS = 8; +const uint16_t FEATURE_METADEX = 4; //! Feature identifier to enable the fee cache and strip 0.05% fees from non-Omni pairs -const uint16_t FEATURE_FEES = 9; -//! Feature identifier to enable cross property (v1) Send To Owners -const uint16_t FEATURE_STOV1 = 10; -//! Feature identifier to activate the waiting period for enabling managed property address freezing -const uint16_t FEATURE_FREEZENOTICE = 14; +const uint16_t FEATURE_CROWDSALES = 5; + //! When (propertyTotalTokens / OMNI_FEE_THRESHOLD) is reached fee distribution will occur const int64_t OMNI_FEE_THRESHOLD = 100000; // 0.001% @@ -72,25 +57,13 @@ struct ConsensusCheckpoint class CConsensusParams { public: - //! Earily bird bonus per week of Exodus crowdsale - double exodusBonusPerWeek; - //! Deadline of Exodus crowdsale as Unix timestamp - unsigned int exodusDeadline; - //! Number of MSC/TMSC generated per unit invested - int64_t exodusReward; //! First block of the Exodus crowdsale int GENESIS_BLOCK; - //! Last block of the Exodus crowdsale - int LAST_EXODUS_BLOCK; - //! Minimum number of blocks to use for notice rules on activation int MIN_ACTIVATION_BLOCKS; //! Maximum number of blocks to use for notice rules on activation int MAX_ACTIVATION_BLOCKS; - //! Waiting period after enabling freezing before addresses may be frozen - int OMNI_FREEZE_WAIT_PERIOD; - //! Block to enable pay-to-pubkey-hash support int PUBKEYHASH_BLOCK; //! Block to enable pay-to-script-hash support @@ -99,7 +72,6 @@ class CConsensusParams int MULTISIG_BLOCK; //! Block to enable OP_RETURN based encoding int NULLDATA_BLOCK; - //! Block to enable alerts and notifications int MSC_ALERT_BLOCK; //! Block to enable simple send transactions @@ -108,32 +80,19 @@ class CConsensusParams int MSC_DEX_BLOCK; //! Block to enable smart property transactions int MSC_SP_BLOCK; + // Block to enable fixed properties + int MSC_FIXED_BLOCK; //! Block to enable managed properties int MSC_MANUALSP_BLOCK; - //! Block to enable send-to-owners transactions - int MSC_STO_BLOCK; //! Block to enable MetaDEx transactions int MSC_METADEX_BLOCK; - //! Block to enable "send all" transactions + //! Block to enable crowdsale creation + int MSC_CRODWSALE_BLOCK; + int MSC_SEND_ALL_BLOCK; - //! Block to enable betting transactions - int MSC_BET_BLOCK; - //! Block to enable cross property STO (v1) + int MSC_STO_BLOCK; int MSC_STOV1_BLOCK; - //! Block to deactivate crowdsale participations when "granting tokens" - int GRANTEFFECTS_FEATURE_BLOCK; - //! Block to disable DEx "over-offers" and to switch to plain integer math - int DEXMATH_FEATURE_BLOCK; - //! Block to disable ecosystem crossovers in crowdsale logic - int SPCROWDCROSSOVER_FEATURE_BLOCK; - //! Block to enable trading of non-Omni pairs - int TRADEALLPAIRS_FEATURE_BLOCK; - //! Block to enable the fee system & 0.05% fee for trading non-Omni pairs - int FEES_FEATURE_BLOCK; - //! Block to activate the waiting period for enabling managed property address freezing - int FREEZENOTICE_FEATURE_BLOCK; - /** Returns a mapping of transaction types, and the blocks at which they are enabled. */ virtual std::vector GetRestrictions() const; diff --git a/src/omnicore/tx.cpp b/src/omnicore/tx.cpp index 8800f686c..221002670 100644 --- a/src/omnicore/tx.cpp +++ b/src/omnicore/tx.cpp @@ -170,11 +170,11 @@ bool CMPTransaction::interpret_Transaction() // case MSC_TYPE_UNFREEZE_PROPERTY_TOKENS: // return interpret_UnfreezeTokens(); // - // case OMNICORE_MESSAGE_TYPE_DEACTIVATION: - // return interpret_Deactivation(); - // - // case OMNICORE_MESSAGE_TYPE_ACTIVATION: - // return interpret_Activation(); + case OMNICORE_MESSAGE_TYPE_DEACTIVATION: + return interpret_Deactivation(); + + case OMNICORE_MESSAGE_TYPE_ACTIVATION: + return interpret_Activation(); // // case OMNICORE_MESSAGE_TYPE_ALERT: // return interpret_Alert(); @@ -763,44 +763,44 @@ bool CMPTransaction::interpret_ChangeIssuer() // return true; // } // -// /** Tx 65533 */ -// bool CMPTransaction::interpret_Deactivation() -// { -// if (pkt_size < 6) { -// return false; -// } -// memcpy(&feature_id, &pkt[4], 2); -// swapByteOrder16(feature_id); -// -// if ((!rpcOnly && msc_debug_packets) || msc_debug_packets_readonly) { -// PrintToLog("\t feature id: %d\n", feature_id); -// } -// -// return true; -// } -// -// /** Tx 65534 */ -// bool CMPTransaction::interpret_Activation() -// { -// if (pkt_size < 14) { -// return false; -// } -// memcpy(&feature_id, &pkt[4], 2); -// swapByteOrder16(feature_id); -// memcpy(&activation_block, &pkt[6], 4); -// swapByteOrder32(activation_block); -// memcpy(&min_client_version, &pkt[10], 4); -// swapByteOrder32(min_client_version); -// -// if ((!rpcOnly && msc_debug_packets) || msc_debug_packets_readonly) { -// PrintToLog("\t feature id: %d\n", feature_id); -// PrintToLog("\tactivation block: %d\n", activation_block); -// PrintToLog("\t minimum version: %d\n", min_client_version); -// } -// -// return true; -// } -// +/** Tx 65533 */ +bool CMPTransaction::interpret_Deactivation() +{ + if (pkt_size < 6) { + return false; + } + memcpy(&feature_id, &pkt[4], 2); + swapByteOrder16(feature_id); + + if ((!rpcOnly && msc_debug_packets) || msc_debug_packets_readonly) { + PrintToLog("\t feature id: %d\n", feature_id); + } + + return true; +} + +/** Tx 65534 */ +bool CMPTransaction::interpret_Activation() +{ + if (pkt_size < 14) { + return false; + } + memcpy(&feature_id, &pkt[4], 2); + swapByteOrder16(feature_id); + memcpy(&activation_block, &pkt[6], 4); + swapByteOrder32(activation_block); + memcpy(&min_client_version, &pkt[10], 4); + swapByteOrder32(min_client_version); + + if ((!rpcOnly && msc_debug_packets) || msc_debug_packets_readonly) { + PrintToLog("\t feature id: %d\n", feature_id); + PrintToLog("\tactivation block: %d\n", activation_block); + PrintToLog("\t minimum version: %d\n", min_client_version); + } + + return true; +} + // /** Tx 65535 */ // bool CMPTransaction::interpret_Alert() // { @@ -935,11 +935,11 @@ int CMPTransaction::interpretPacket() // case MSC_TYPE_UNFREEZE_PROPERTY_TOKENS: // return logicMath_UnfreezeTokens(); // - // case OMNICORE_MESSAGE_TYPE_DEACTIVATION: - // return logicMath_Deactivation(); - // - // case OMNICORE_MESSAGE_TYPE_ACTIVATION: - // return logicMath_Activation(); + case OMNICORE_MESSAGE_TYPE_DEACTIVATION: + return logicMath_Deactivation(); + + case OMNICORE_MESSAGE_TYPE_ACTIVATION: + return logicMath_Activation(); // // case OMNICORE_MESSAGE_TYPE_ALERT: // return logicMath_Alert(); @@ -1614,26 +1614,26 @@ int CMPTransaction::logicMath_CreatePropertyFixed() return (PKT_ERROR_SP -21); } - // if (!IsTransactionTypeAllowed(block, ecosystem, type, version)) { - // PrintToLog("%s(): rejected: type %d or version %d not permitted for property %d at block %d\n", - // __func__, - // type, - // version, - // property, - // block); - // return (PKT_ERROR_SP -22); - // } + if (!IsTransactionTypeAllowed(block, ecosystem, type, version)) { + PrintToLog("%s(): rejected: type %d or version %d not permitted for property %d at block %d\n", + __func__, + type, + version, + property, + block); + return (PKT_ERROR_SP -22); + } + + if (nValue <= 0 || MAX_INT_8_BYTES < nValue) { + PrintToLog("%s(): rejected: value out of range or zero: %d\n", __func__, nValue); + return (PKT_ERROR_SP -23); + } + + if (MSC_PROPERTY_TYPE_INDIVISIBLE != prop_type && MSC_PROPERTY_TYPE_DIVISIBLE != prop_type) { + PrintToLog("%s(): rejected: invalid property type: %d\n", __func__, prop_type); + return (PKT_ERROR_SP -36); + } - // if (nValue <= 0 || MAX_INT_8_BYTES < nValue) { - // PrintToLog("%s(): rejected: value out of range or zero: %d\n", __func__, nValue); - // return (PKT_ERROR_SP -23); - // } - // - // if (MSC_PROPERTY_TYPE_INDIVISIBLE != prop_type && MSC_PROPERTY_TYPE_DIVISIBLE != prop_type) { - // PrintToLog("%s(): rejected: invalid property type: %d\n", __func__, prop_type); - // return (PKT_ERROR_SP -36); - // } - // if ('\0' == name[0]) { PrintToLog("%s(): rejected: property name must not be empty\n", __func__); return (PKT_ERROR_SP -37); @@ -1684,19 +1684,6 @@ int CMPTransaction::logicMath_CreatePropertyVariable() return (PKT_ERROR_SP -21); } - if (IsFeatureActivated(FEATURE_SPCROWDCROSSOVER, block)) { - /** - * Ecosystem crossovers shall not be allowed after the feature was enabled. - */ - if (isTestEcosystemProperty(ecosystem) != isTestEcosystemProperty(property)) { - PrintToLog("%s(): rejected: ecosystem %d of tokens to issue and desired property %d not in same ecosystem\n", - __func__, - ecosystem, - property); - return (PKT_ERROR_SP -50); - } - } - if (!IsTransactionTypeAllowed(block, ecosystem, type, version)) { PrintToLog("%s(): rejected: type %d or version %d not permitted for property %d at block %d\n", __func__, @@ -1982,15 +1969,6 @@ int CMPTransaction::logicMath_GrantTokens() // Move the tokens assert(update_tally_map(receiver, property, nValue, BALANCE)); - /** - * As long as the feature to disable the side effects of "granting tokens" - * is not activated, "granting tokens" can trigger crowdsale participations. - */ - if (!IsFeatureActivated(FEATURE_GRANTEFFECTS, block)) { - // Is there an active crowdsale running from this recepient? - logicHelper_CrowdsaleParticipation(); - } - NotifyTotalTokensChanged(property, block); return 0; @@ -2359,84 +2337,81 @@ int CMPTransaction::logicMath_ChangeIssuer() // return 0; // } // -// /** Tx 65533 */ -// int CMPTransaction::logicMath_Deactivation() -// { -// if (!IsTransactionTypeAllowed(block, property, type, version)) { -// PrintToLog("%s(): rejected: type %d or version %d not permitted for property %d at block %d\n", -// __func__, -// type, -// version, -// property, -// block); -// return (PKT_ERROR -22); -// } -// -// // is sender authorized -// bool authorized = CheckDeactivationAuthorization(sender); -// -// PrintToLog("\t sender: %s\n", sender); -// PrintToLog("\t authorized: %s\n", authorized); -// -// if (!authorized) { -// PrintToLog("%s(): rejected: sender %s is not authorized to deactivate features\n", __func__, sender); -// return (PKT_ERROR -51); -// } -// -// // authorized, request feature deactivation -// bool DeactivationSuccess = DeactivateFeature(feature_id, block); -// -// if (!DeactivationSuccess) { -// PrintToLog("%s(): DeactivateFeature failed\n", __func__); -// return (PKT_ERROR -54); -// } -// -// // successful deactivation - did we deactivate the MetaDEx? If so close out all trades -// if (feature_id == FEATURE_METADEX) { -// MetaDEx_SHUTDOWN(); -// } -// if (feature_id == FEATURE_TRADEALLPAIRS) { -// MetaDEx_SHUTDOWN_ALLPAIR(); -// } -// -// return 0; -// } -// -// /** Tx 65534 */ -// int CMPTransaction::logicMath_Activation() -// { -// if (!IsTransactionTypeAllowed(block, property, type, version)) { -// PrintToLog("%s(): rejected: type %d or version %d not permitted for property %d at block %d\n", -// __func__, -// type, -// version, -// property, -// block); -// return (PKT_ERROR -22); -// } -// -// // is sender authorized - temporarily use alert auths but ## TO BE MOVED TO FOUNDATION P2SH KEY ## -// bool authorized = CheckActivationAuthorization(sender); -// -// PrintToLog("\t sender: %s\n", sender); -// PrintToLog("\t authorized: %s\n", authorized); -// -// if (!authorized) { -// PrintToLog("%s(): rejected: sender %s is not authorized for feature activations\n", __func__, sender); -// return (PKT_ERROR -51); -// } -// -// // authorized, request feature activation -// bool activationSuccess = ActivateFeature(feature_id, activation_block, min_client_version, block); -// -// if (!activationSuccess) { -// PrintToLog("%s(): ActivateFeature failed to activate this feature\n", __func__); -// return (PKT_ERROR -54); -// } -// -// return 0; -// } -// +/** Tx 65533 */ +int CMPTransaction::logicMath_Deactivation() +{ + if (!IsTransactionTypeAllowed(block, property, type, version)) { + PrintToLog("%s(): rejected: type %d or version %d not permitted for property %d at block %d\n", + __func__, + type, + version, + property, + block); + return (PKT_ERROR -22); + } + + // is sender authorized + bool authorized = CheckDeactivationAuthorization(sender); + + PrintToLog("\t sender: %s\n", sender); + PrintToLog("\t authorized: %s\n", authorized); + + if (!authorized) { + PrintToLog("%s(): rejected: sender %s is not authorized to deactivate features\n", __func__, sender); + return (PKT_ERROR -51); + } + + // authorized, request feature deactivation + bool DeactivationSuccess = DeactivateFeature(feature_id, block); + + if (!DeactivationSuccess) { + PrintToLog("%s(): DeactivateFeature failed\n", __func__); + return (PKT_ERROR -54); + } + + // successful deactivation - did we deactivate the MetaDEx? If so close out all trades + if (feature_id == FEATURE_METADEX) { + MetaDEx_SHUTDOWN(); + } + + return 0; +} + +/** Tx 65534 */ +int CMPTransaction::logicMath_Activation() +{ + if (!IsTransactionTypeAllowed(block, property, type, version)) { + PrintToLog("%s(): rejected: type %d or version %d not permitted for property %d at block %d\n", + __func__, + type, + version, + property, + block); + return (PKT_ERROR -22); + } + + // is sender authorized - temporarily use alert auths but ## TO BE MOVED TO FOUNDATION P2SH KEY ## + bool authorized = CheckActivationAuthorization(sender); + + PrintToLog("\t sender: %s\n", sender); + PrintToLog("\t authorized: %s\n", authorized); + + if (!authorized) { + PrintToLog("%s(): rejected: sender %s is not authorized for feature activations\n", __func__, sender); + return (PKT_ERROR -51); + } + + // authorized, request feature activation + bool activationSuccess = ActivateFeature(feature_id, activation_block, min_client_version, block); + + if (!activationSuccess) { + PrintToLog("%s(): ActivateFeature failed to activate this feature\n", __func__); + return (PKT_ERROR -54); + } + + return 0; +} + // /** Tx 65535 */ // int CMPTransaction::logicMath_Alert() // { diff --git a/src/omnicore/version.cpp b/src/omnicore/version.cpp index 827d54623..161e7ee7b 100644 --- a/src/omnicore/version.cpp +++ b/src/omnicore/version.cpp @@ -6,7 +6,7 @@ #include #ifdef HAVE_BUILD_INFO -# include "build.h" +#include #endif #ifdef OMNICORE_VERSION_STATUS diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 33e1170d8..d2e674ffc 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -146,6 +146,11 @@ static const CRPCConvertParam vRPCConvertParams[] = { "echojson", 8, "arg8" }, { "echojson", 9, "arg9" }, + /* Omni Core - payloads */ + { "omni_createpayload_sendactivation", 0, "" }, + { "omni_createpayload_sendactivation", 1, "" }, + { "omni_createpayload_sendactivation", 2, "" }, + /* Omni Core - raw transaction calls */ { "omni_createrawtx_reference", 2, "" }, { "omni_createrawtx_change", 1, "" }, diff --git a/src/validation.cpp b/src/validation.cpp index 24785a9bb..e4e510453 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -106,20 +106,6 @@ CScript COINBASE_FLAGS; const std::string strMessageMagic = "Bitcoin Gold Signed Message:\n"; -/*-------------------------- Omnicore G Port ---------------------------------*/ -// -// Omni Core notification handlers -// - - -// int mastercore_handler_disc_begin(int nBlockNow, CBlockIndex const * pBlockIndex); -// int mastercore_handler_disc_end(int nBlockNow, CBlockIndex const * pBlockIndex); -// int mastercore_handler_block_begin(int nBlockNow, CBlockIndex const * pBlockIndex); -// int mastercore_handler_block_end(int nBlockNow, CBlockIndex const * pBlockIndex, unsigned int); -// int mastercore_handler_tx(CTransaction tx, int nBlock, unsigned int idx, CBlockIndex const * pBlockIndex); - -/*----------------------------------------------------------------------------*/ - // Internal stuff namespace { @@ -2311,13 +2297,6 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, // Update chainActive & related variables. UpdateTip(pindexNew, chainparams); - // Tell wallet about transactions that went from mempool - // to conflicted: - // BOOST_FOREACH(const CTransaction &tx, txConflicted) { - // SyncWithWallets(tx, pindexNew, NULL); - // } - // ... and about transactions that got confirmed: - // TODO: shared_ptr pointers!!! for(const CTransactionRef& tx : blockConnecting.vtx){ //! Omni Core: new confirmed transaction notification LogPrint(BCLog::BENCH, "Omni Core handler: new confirmed transaction [height: %d, idx: %u]\n", GetHeight(), nTxIdx); diff --git a/test/functional/omni_activation.py b/test/functional/omni_activation.py new file mode 100755 index 000000000..485a9da18 --- /dev/null +++ b/test/functional/omni_activation.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test basic for Features activation """ + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + +import os +import json +import http.client +import urllib.parse + +class ActivationBasicsTest (BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = True + self.extra_args = [["-txindex=1", "-datacarriersize=220", "-omniactivationallowsender=moSfCMqU8rjB99n7Rm5pBgRvRGevyKVJzY"]] + + def setup_network(self): + self.setup_nodes() + + def run_test(self): + + self.log.info("Preparing the workspace...") + + # mining 200 blocks + self.nodes[0].generate(200) + + ################################################################################ + # checking omni_senddeactivation and omni_senddeactivation # + ################################################################################ + + url = urllib.parse.urlparse(self.nodes[0].url) + + #Old authpair + authpair = url.username + ':' + url.password + + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} + + addresses = [] + accounts = ["john", "doe", "another"] + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + + adminAddress = 'moSfCMqU8rjB99n7Rm5pBgRvRGevyKVJzY' + privkey = 'cQxt12eUkTiMUSfVQP7FisbAQJk4vmCotmHxraz3efyatEWiwyLp' + + self.log.info("importing admin address") + params = str([privkey]).replace("'",'"') + out = omnilayer_HTTP(conn, headers, True, "importprivkey",params) + # self.log.info(out) + assert_equal(out['error'], None) + + self.log.info("Creating sender address") + addresses = omnilayer_createAddresses(accounts, conn, headers) + addresses.append(adminAddress) + + self.log.info("Funding addresses with BTG") + amount = 0.1 + omnilayer_fundingAddresses(addresses, amount, conn, headers) + + self.log.info("Checking the BTG balance in every account") + omnilayer_checkingBalance(accounts, amount, conn, headers) + + + # deactivation here to write 999999999 in the MSC_SP_BLOCK param + params = str([adminAddress, 1]).replace("'",'"') + out = omnilayer_HTTP(conn, headers, False, "omni_senddeactivation",params) + # self.log.info(out) + + self.nodes[0].generate(1) + + self.log.info("Creating new tokens (must be rejected)") + params = str([addresses[0], 1, 2, 0,"N/A", "N/A", "lihki", "url", "data", "3000"]).replace("'",'"') + out = omnilayer_HTTP(conn, headers, True, "omni_sendissuancefixed",params) + # self.log.info(out) + + self.nodes[0].generate(1) + + self.log.info("Checking the property (doesn't exist)") + params = str([3]) + out = omnilayer_HTTP(conn, headers, False, "omni_getproperty",params) + # self.log.info(out) + assert_equal(out['error']['message'], 'Property identifier does not exist') + + self.log.info("Testing omni_sendactivation") + + # adminAddress, activation number 1, in block 400, min omni version = 1. + params = str([adminAddress, 1, 400, 1]).replace("'",'"') + out = omnilayer_HTTP(conn, headers, False, "omni_sendactivation",params) + # self.log.info(out) + + self.nodes[0].generate(210) + + self.log.info("Creating new tokens") + params = str([addresses[0], 1, 2, 0,"N/A", "N/A", "lihki", "url", "data", "3000"]).replace("'",'"') + out = omnilayer_HTTP(conn, headers, True, "omni_sendissuancefixed",params) + # self.log.info(out) + + self.nodes[0].generate(1) + + self.log.info("Checking the property") + params = str([3]) + out = omnilayer_HTTP(conn, headers, False, "omni_getproperty",params) + # self.log.info(out) + assert_equal(out['result']['propertyid'],3) + assert_equal(out['result']['name'],'lihki') + assert_equal(out['result']['issuer'], addresses[0]) + assert_equal(out['result']['data'],'data') + assert_equal(out['result']['url'],'url') + assert_equal(out['result']['divisible'],True) + assert_equal(out['result']['totaltokens'],'3000.00000000') + + self.log.info("Testing omni_senddeactivation") + + # adminAddress, deactivation number 1, min omni version = 1. + params = str([adminAddress, 1]).replace("'",'"') + out = omnilayer_HTTP(conn, headers, False, "omni_senddeactivation",params) + # self.log.info(out) + + self.nodes[0].generate(1) + + self.log.info("Creating new tokens (must be rejected)") + params = str([addresses[0], 1, 2, 0,"N/A", "N/A", "lihki", "url", "data", "3000"]).replace("'",'"') + out = omnilayer_HTTP(conn, headers, True, "omni_sendissuancefixed",params) + # self.log.info(out) + + self.nodes[0].generate(1) + + self.log.info("Checking the property (doesn't exist)") + params = str([4]) + out = omnilayer_HTTP(conn, headers, False, "omni_getproperty",params) + # self.log.info(out) + assert_equal(out['error']['message'], 'Property identifier does not exist') + + conn.close() + + +if __name__ == '__main__': + ActivationBasicsTest ().main ()