From 54c19dfd5ac4a7b513bb2cbb896a3c20d142bef9 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Wed, 20 May 2015 21:52:52 +0200 Subject: [PATCH 1/3] Split MetaDEx RPC commands for trading "sendtrade" with action value is replaced by: - sendtrade: fromaddress propertyidforsale amountforsale propertyiddesired amountdesired - sendcanceltradesbyprice: fromaddress propertyidforsale amountforsale propertyiddesired amountdesired - sendcanceltradesbypair: fromaddress propertyidforsale propertyiddesired - sendcancelalltrades: fromaddress ecosystem Until the test tools are updated, the old command "trade_MP" is still available and it forwards the call. --- src/omnicore/rpctx.cpp | 284 ++++++++++++++++++++++++++++++++++++----- src/rpcclient.cpp | 12 +- src/rpcserver.cpp | 15 ++- src/rpcserver.h | 7 +- 4 files changed, 276 insertions(+), 42 deletions(-) diff --git a/src/omnicore/rpctx.cpp b/src/omnicore/rpctx.cpp index 187e44fdf0f84..bebba248ce8e6 100644 --- a/src/omnicore/rpctx.cpp +++ b/src/omnicore/rpctx.cpp @@ -704,63 +704,287 @@ Value sendclosecrowdsale_OMNI(const Array& params, bool fHelp) } } -// sendtrade_OMNI - MetaDEx trade -Value sendtrade_OMNI(const Array& params, bool fHelp) +// trade_MP - MetaDEx trade +Value trade_MP(const Array& params, bool fHelp) { if (fHelp || params.size() != 6) throw runtime_error( - "sendtrade_OMNI \"fromaddress\" propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\" action\n" - "\nPlace or cancel a trade offer on the distributed token exchange.\n" + "trade_MP \"fromaddress\" propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\" action\n" + "\nNote: this command is depreciated, and was replaced by:\n" + " - sendtrade_OMNI\n" + " - sendcanceltradebyprice_OMNI\n" + " - sendcanceltradebypair_OMNI\n" + " - sendcanceltradebypair_OMNI\n" + ); + + Array values; + uint8_t action = params[5].get_int64(); + + // Forward to the new commands, based on action value + switch (action) { + case CMPTransaction::ADD: + { + values.push_back(params[0]); // fromAddress + values.push_back(params[1]); // propertyIdForSale + values.push_back(params[2]); // amountForSale + values.push_back(params[3]); // propertyIdDesired + values.push_back(params[4]); // amountDesired + return sendtrade_OMNI(values, fHelp); + } + case CMPTransaction::CANCEL_AT_PRICE: + { + values.push_back(params[0]); // fromAddress + values.push_back(params[1]); // propertyIdForSale + values.push_back(params[2]); // amountForSale + values.push_back(params[3]); // propertyIdDesired + values.push_back(params[4]); // amountDesired + return sendcanceltradesbyprice_OMNI(values, fHelp); + } + case CMPTransaction::CANCEL_ALL_FOR_PAIR: + { + values.push_back(params[0]); // fromAddress + values.push_back(params[1]); // propertyIdForSale + values.push_back(params[3]); // propertyIdDesired + return sendcanceltradesbypair_OMNI(values, fHelp); + } + case CMPTransaction::CANCEL_EVERYTHING: + { + uint8_t ecosystem = 0; + if (isMainEcosystemProperty(params[1].get_int64()) + && isMainEcosystemProperty(params[3].get_int64())) { + ecosystem = OMNI_PROPERTY_MSC; + } + if (isTestEcosystemProperty(params[1].get_int64()) + && isTestEcosystemProperty(params[3].get_int64())) { + ecosystem = OMNI_PROPERTY_TMSC; + } + values.push_back(params[0]); // fromAddress + values.push_back(ecosystem); + return sendcancelalltrades_OMNI(values, fHelp); + } + } + + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid action (1,2,3,4 only)"); +} + +// Send a new MetaDEx trade +Value sendtrade_OMNI(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 5) + throw runtime_error( + "sendtrade_OMNI \"fromaddress\" propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\"\n" + "\nPlace a trade offer on the distributed token exchange.\n" "\nParameters:\n" "FromAddress : the address to send this transaction from\n" "PropertyIDForSale : the property to list for sale\n" "AmountForSale : the amount to list for sale\n" "PropertyIDDesired : the property desired\n" "AmountDesired : the amount desired\n" - "Action : the action to take: (1) new, (2) cancel by price, (3) cancel by pair, (4) cancel all\n" "Result:\n" "txid (string) The transaction ID of the sent transaction\n" "\nExamples:\n" - ">omnicored sendtrade_OMNI \"1FromAddress\" PropertyIDForSale \"AmountForSale\" PropertyIDDesired \"AmountDesired\" Action\n" + ">omnicored sendtrade_OMNI \"1FromAddress\" PropertyIDForSale \"AmountForSale\" PropertyIDDesired \"AmountDesired\"\n" ); // obtain parameters & info std::string fromAddress = params[0].get_str(); - unsigned int propertyIdForSale = int64Touint32Safe(params[1].get_int64()); - string strAmountForSale = params[2].get_str(); - unsigned int propertyIdDesired = int64Touint32Safe(params[3].get_int64()); - string strAmountDesired = params[4].get_str(); - int64_t action = params[5].get_int64(); + uint32_t propertyIdForSale = int64Touint32Safe(params[1].get_int64()); + std::string strAmountForSale = params[2].get_str(); + uint32_t propertyIdDesired = int64Touint32Safe(params[3].get_int64()); + std::string strAmountDesired = params[4].get_str(); + + CMPSPInfo::Entry spForSale; + CMPSPInfo::Entry spDesired; + if (false == _my_sps->getSP(propertyIdForSale, spForSale)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale does not exist"); + if (false == _my_sps->getSP(propertyIdDesired, spDesired)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property desired does not exist"); + if (isTestEcosystemProperty(propertyIdForSale) != isTestEcosystemProperty(propertyIdDesired)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale and property desired must be in the same ecosystem"); + if (propertyIdForSale == propertyIdDesired) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale and property desired must be different"); + + int64_t amountForSale = StrToInt64(strAmountForSale, spForSale.isDivisible()); + int64_t amountDesired = StrToInt64(strAmountDesired, spDesired.isDivisible()); + if (0 >= amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for sale"); + if (!isRangeOK(amountForSale)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount for sale not in range"); + if (0 >= amountDesired) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount desired"); + if (!isRangeOK(amountDesired)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount desired not in range"); + const int64_t senderBalance = getMPbalance(fromAddress, propertyIdForSale, BALANCE); const int64_t senderAvailableBalance = getUserAvailableMPbalance(fromAddress, propertyIdForSale); + if (senderBalance < amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Sender has insufficient balance"); + if (senderAvailableBalance < amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Sender has insufficient balance (due to pending transactions)"); + + // create a payload for the transaction + uint8_t action = CMPTransaction::ADD; // TODO: move into payload creation + std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + + // request the wallet build the transaction (and if needed commit it) + uint256 txid = 0; + std::string rawHex; + int result = ClassAgnosticWalletTXBuilder(fromAddress, "", "", 0, payload, txid, rawHex, autoCommit); + + // check error and return the txid (or raw hex depending on autocommit) + if (result != 0) { + throw JSONRPCError(result, error_str(result)); + } else { + if (!autoCommit) { + return rawHex; + } else { + PendingAdd(txid, fromAddress, "", MSC_TYPE_METADEX, propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + return txid.GetHex(); + } + } +} + +// Cancel MetaDEx by price +Value sendcanceltradesbyprice_OMNI(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 5) + throw runtime_error( + "sendcanceltradesbyprice_OMNI \"fromaddress\" propertyidforsale \"amountforsale\" propertiddesired \"amountdesired\"\n" + "\nCancel offers on the distributed token exchange with the given price.\n" + "\nParameters:\n" + "FromAddress : the address to send this transaction from\n" + "PropertyIDForSale : the property listed for sale\n" + "AmountForSale : the amount listed for sale\n" + "PropertyIDDesired : the property desired\n" + "AmountDesired : the desired amount\n" + "Result:\n" + "txid (string) The transaction ID of the sent transaction\n" + "\nExamples:\n" + ">omnicored sendcanceltradesbyprice_OMNI \"1FromAddress\" PropertyIDForSale \"AmountForSale\" PropertyIDDesired \"AmountDesired\"\n" + ); + + // obtain parameters & info + std::string fromAddress = params[0].get_str(); + uint32_t propertyIdForSale = int64Touint32Safe(params[1].get_int64()); + std::string strAmountForSale = params[2].get_str(); + uint32_t propertyIdDesired = int64Touint32Safe(params[3].get_int64()); + std::string strAmountDesired = params[4].get_str(); - // setup a few vars - int64_t amountForSale = 0, amountDesired = 0; CMPSPInfo::Entry spForSale; CMPSPInfo::Entry spDesired; + if (false == _my_sps->getSP(propertyIdForSale, spForSale)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale does not exist"); + if (false == _my_sps->getSP(propertyIdDesired, spDesired)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property desired does not exist"); + if (isTestEcosystemProperty(propertyIdForSale) != isTestEcosystemProperty(propertyIdDesired)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale and property desired must be in the same ecosystem"); + if (propertyIdForSale == propertyIdDesired) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale and property desired must be different"); + + int64_t amountForSale = StrToInt64(strAmountForSale, spForSale.isDivisible()); + int64_t amountDesired = StrToInt64(strAmountDesired, spDesired.isDivisible()); + if (0 >= amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for sale"); + if (!isRangeOK(amountForSale)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount for sale not in range"); + if (0 >= amountDesired) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount desired"); + if (!isRangeOK(amountDesired)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount desired not in range"); + + // TODO: check, if there are matching offers to cancel + + // create a payload for the transaction + uint8_t action = CMPTransaction::CANCEL_AT_PRICE; // TODO: move into payload creation + std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); - // perform conversions & checks - if (action <= 0 || CMPTransaction::CANCEL_EVERYTHING < action) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid action (1,2,3,4 only)"); - if (action != CMPTransaction::CANCEL_EVERYTHING) { // these checks are not applicable to cancel everything - if (false == _my_sps->getSP(propertyIdForSale, spForSale)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale does not exist"); - if (false == _my_sps->getSP(propertyIdDesired, spDesired)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property desired does not exist"); - if (isTestEcosystemProperty(propertyIdForSale) != isTestEcosystemProperty(propertyIdDesired)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale and property desired must be in the same ecosystem"); - if (propertyIdForSale == propertyIdDesired) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale and property desired must be different"); + // request the wallet build the transaction (and if needed commit it) + uint256 txid = 0; + std::string rawHex; + int result = ClassAgnosticWalletTXBuilder(fromAddress, "", "", 0, payload, txid, rawHex, autoCommit); + + // check error and return the txid (or raw hex depending on autocommit) + if (result != 0) { + throw JSONRPCError(result, error_str(result)); + } else { + if (!autoCommit) { + return rawHex; + } else { + PendingAdd(txid, fromAddress, "", MSC_TYPE_METADEX, propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + return txid.GetHex(); + } } - if (action <= CMPTransaction::CANCEL_AT_PRICE) { // cancel pair and cancel everything permit zero values - amountForSale = StrToInt64(strAmountForSale, spForSale.isDivisible()); - amountDesired = StrToInt64(strAmountDesired, spDesired.isDivisible()); - if (0 >= amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for sale"); - if (!isRangeOK(amountForSale)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount for sale not in range"); - if (0 >= amountDesired) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount desired"); - if (!isRangeOK(amountDesired)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount desired not in range"); +} + +// Cancel MetaDEx orders by currency pair +Value sendcanceltradesbypair_OMNI(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 3) + throw runtime_error( + "sendcanceltradesbypair_OMNI \"fromaddress\" propertyidforsale propertiddesired\n" + "\nCancel offers on the distributed token exchange with the given currency pair.\n" + "\nParameters:\n" + "FromAddress : the address to send this transaction from\n" + "PropertyIDForSale : the property listed for sale\n" + "PropertyIDDesired : the property desired\n" + "Result:\n" + "txid (string) The transaction ID of the sent transaction\n" + "\nExamples:\n" + ">omnicored sendcanceltradesbypair_OMNI \"1FromAddress\" PropertyIDForSale \"AmountForSale\" PropertyIDDesired \"AmountDesired\"\n" + ); + + // obtain parameters & info + std::string fromAddress = params[0].get_str(); + uint32_t propertyIdForSale = int64Touint32Safe(params[1].get_int64()); + uint32_t propertyIdDesired = int64Touint32Safe(params[2].get_int64()); + + CMPSPInfo::Entry spForSale; + CMPSPInfo::Entry spDesired; + if (false == _my_sps->getSP(propertyIdForSale, spForSale)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale does not exist"); + if (false == _my_sps->getSP(propertyIdDesired, spDesired)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property desired does not exist"); + if (isTestEcosystemProperty(propertyIdForSale) != isTestEcosystemProperty(propertyIdDesired)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale and property desired must be in the same ecosystem"); + if (propertyIdForSale == propertyIdDesired) throw JSONRPCError(RPC_INVALID_PARAMETER, "Property for sale and property desired must be different"); + + // TODO: check, if there are matching offers to cancel + + // create a payload for the transaction + uint8_t action = CMPTransaction::CANCEL_ALL_FOR_PAIR; // TODO: move into payload creation + int64_t amountForSale = 0; + int64_t amountDesired = 0; + std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + + // request the wallet build the transaction (and if needed commit it) + uint256 txid = 0; + std::string rawHex; + int result = ClassAgnosticWalletTXBuilder(fromAddress, "", "", 0, payload, txid, rawHex, autoCommit); + + // check error and return the txid (or raw hex depending on autocommit) + if (result != 0) { + throw JSONRPCError(result, error_str(result)); + } else { + if (!autoCommit) { + return rawHex; + } else { + PendingAdd(txid, fromAddress, "", MSC_TYPE_METADEX, propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + return txid.GetHex(); + } } - if (action == CMPTransaction::ADD) { // only check for sufficient balance for new trades - if (senderBalance < amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Sender has insufficient balance"); - if (senderAvailableBalance < amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Sender has insufficient balance (due to pending transactions)"); +} + +// Cancel MetaDEx orders by ecosystem +Value sendcancelalltrades_OMNI(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "sendcancelalltrades_OMNI \"fromaddress\" ecosystem\n" + "\nCancel all offers on the distributed token exchange in the given ecosystem.\n" + "\nParameters:\n" + "FromAddress : the address to send this transaction from\n" + "Ecosystem : the ecosystem of the offers to cancel - (0) both, (1) main, (2) test\n" + "Result:\n" + "txid (string) The transaction ID of the sent transaction\n" + "\nExamples:\n" + ">omnicored sendcancelalltrades_OMNI \"1FromAddress\" Ecosystem\n" + ); + + // obtain parameters & info + std::string fromAddress = params[0].get_str(); + uint8_t ecosystem = params[1].get_uint64(); + + if (OMNI_PROPERTY_TMSC < ecosystem) { + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid ecosystem"); } + // TODO: check, if there are matching offers to cancel + // create a payload for the transaction + uint8_t action = CMPTransaction::CANCEL_EVERYTHING; // TODO: move into payload creation + int64_t amountForSale = 0; + int64_t amountDesired = 0; + uint32_t propertyIdForSale = ecosystem; + uint32_t propertyIdDesired = ecosystem; std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); // request the wallet build the transaction (and if needed commit it) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index d291f51f9b49c..602a70502657d 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -104,9 +104,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getallbalancesforid_MP", 0 }, { "listblocktransactions_MP", 0 }, { "setautocommit_OMNI", 0 }, - { "trade_MP", 2 }, - { "trade_MP", 4 }, - { "trade_MP", 5 }, { "getorderbook_MP", 0 }, { "getorderbook_MP", 1 }, { "gettradessince_MP", 0 }, @@ -117,9 +114,16 @@ static const CRPCConvertParam vRPCConvertParams[] = // omni_rpctx { "send_OMNI", 2 }, { "sendsto_OMNI", 1 }, + { "trade_MP", 1 }, // depreciated + { "trade_MP", 3 }, // depreciated + { "trade_MP", 5 }, // depreciated { "sendtrade_OMNI", 1 }, { "sendtrade_OMNI", 3 }, - { "sendtrade_OMNI", 5 }, + { "sendcanceltradesbyprice_OMNI", 1 }, + { "sendcanceltradesbyprice_OMNI", 3 }, + { "sendcanceltradesbypair_OMNI", 1 }, + { "sendcanceltradesbypair_OMNI", 2 }, + { "sendcancelalltrades_OMNI", 1 }, { "sendissuancefixed_OMNI", 1 }, { "sendissuancefixed_OMNI", 2 }, { "sendissuancefixed_OMNI", 3 }, diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index a7ae73bbd57d1..f1866a504711a 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -364,12 +364,16 @@ static const CRPCCommand vRPCCommands[] = { "omni layer", "getgrants_MP", &getgrants_MP, false, false, true }, { "omni layer", "getactivedexsells_MP", &getactivedexsells_MP, false, false, true }, { "omni layer", "getactivecrowdsales_MP", &getactivecrowdsales_MP, false, false, true }, - { "hidden", "trade_MP", &sendtrade_OMNI, false, false, true }, - { "hidden", "getorderbook_MP", &getorderbook_MP, false, false, true }, - { "hidden", "gettradessince_MP", &gettradessince_MP, false, false, true }, + { "omni layer", "getorderbook_MP", &getorderbook_MP, false, false, true }, + { "omni layer", "gettradessince_MP", &gettradessince_MP, false, false, true }, { "hidden", "getopenorders_MP", &getopenorders_MP, false, false, true }, - { "hidden", "gettradehistory_MP", &gettradehistory_MP, false, false, true }, - { "hidden", "gettrade_MP", &gettrade_MP, false, false, true }, + { "omni layer", "gettradehistory_MP", &gettradehistory_MP, false, false, true }, + { "omni layer", "gettrade_MP", &gettrade_MP, false, false, true }, + { "hidden", "trade_MP", &trade_MP, false, false, true }, // depreciated + { "omni layer", "sendtrade_OMNI", &sendtrade_OMNI, false, false, true }, + { "omni layer", "sendcanceltradesbyprice_OMNI", &sendcanceltradesbyprice_OMNI, false, false, true }, + { "omni layer", "sendcanceltradesbypair_OMNI", &sendcanceltradesbypair_OMNI, false, false, true }, + { "omni layer", "sendcancelalltrades_OMNI", &sendcancelalltrades_OMNI, false, false, true }, { "omni layer", "sendtoowners_MP", &sendsto_OMNI, false, false, true }, { "omni layer", "sendrawtx_MP", &sendrawtx_MP, false, false, true }, { "omni layer", "getsto_MP", &getsto_MP, false, false, true }, @@ -386,7 +390,6 @@ static const CRPCCommand vRPCCommands[] = { "omni layer", "sendgrant_OMNI", &sendgrant_OMNI, false, false, true }, { "omni layer", "sendrevoke_OMNI", &sendrevoke_OMNI, false, false, true }, { "omni layer", "sendclosecrowdsale_OMNI", &sendclosecrowdsale_OMNI, false, false, true }, - { "omni layer", "sendtrade_OMNI", &sendtrade_OMNI, false, false, true }, { "omni layer", "sendchangeissuer_OMNI", &sendchangeissuer_OMNI, false, false, true }, #endif // ENABLE_WALLET [required by Omni Core for now] }; diff --git a/src/rpcserver.h b/src/rpcserver.h index 438731532bcff..46622ca492e4d 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -240,7 +240,6 @@ extern json_spirit::Value getgrants_MP(const json_spirit::Array& params, bool fH extern json_spirit::Value getallbalancesforaddress_MP(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getactivedexsells_MP(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gettransaction_MP(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value trade_MP(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gettrade_MP(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getorderbook_MP(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gettradessince_MP(const json_spirit::Array& params, bool fHelp); @@ -263,8 +262,12 @@ extern json_spirit::Value sendsto_OMNI(const json_spirit::Array& params, bool fH extern json_spirit::Value sendgrant_OMNI(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value sendrevoke_OMNI(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value sendclosecrowdsale_OMNI(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendtrade_OMNI(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value sendchangeissuer_OMNI(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value trade_MP(const json_spirit::Array& params, bool fHelp); // depreciated +extern json_spirit::Value sendtrade_OMNI(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendcanceltradesbyprice_OMNI(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendcanceltradesbypair_OMNI(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendcancelalltrades_OMNI(const json_spirit::Array& params, bool fHelp); // in rest.cpp extern bool HTTPReq_REST(AcceptedConnection *conn, From dcb5a008d0e7ea2ed6c0affb5ec453e9fc63e3d5 Mon Sep 17 00:00:00 2001 From: dexX7 Date: Wed, 20 May 2015 23:07:47 +0200 Subject: [PATCH 2/3] Split MetaDEx payload creation (not on transaction level) CreatePayload_MetaDExTrade() is split into: - CreatePayload_MetaDExTrade() - CreatePayload_MetaDExCancelPrice() - CreatePayload_MetaDExCancelPair() - CreatePayload_MetaDExCancelEcosystem() This change has no functional effect, and does not change the transaction format, but solely wraps and seperate the seperate actions into different logic units. Related code is updated, including reference-payload-creation unit tests. --- src/omnicore/createpayload.cpp | 88 +++++++++++++++++++++- src/omnicore/createpayload.h | 5 +- src/omnicore/rpctx.cpp | 28 +++---- src/omnicore/test/create_payload_tests.cpp | 49 +++++++++++- src/qt/metadexcanceldialog.cpp | 15 +++- src/qt/metadexdialog.cpp | 2 +- 6 files changed, 166 insertions(+), 21 deletions(-) diff --git a/src/omnicore/createpayload.cpp b/src/omnicore/createpayload.cpp index c3d8beec2d4c1..d63837b59a998 100644 --- a/src/omnicore/createpayload.cpp +++ b/src/omnicore/createpayload.cpp @@ -277,16 +277,73 @@ std::vector CreatePayload_ChangeIssuer(uint32_t propertyId) return payload; } -std::vector CreatePayload_MetaDExTrade(uint32_t propertyIdForSale, uint64_t amountForSale, uint32_t propertyIdDesired, uint64_t amountDesired, uint8_t action) +std::vector CreatePayload_MetaDExTrade(uint32_t propertyIdForSale, uint64_t amountForSale, uint32_t propertyIdDesired, uint64_t amountDesired) { std::vector payload; + uint16_t messageType = 21; uint16_t messageVer = 0; + uint8_t action = 1; // ADD + + mastercore::swapByteOrder16(messageVer); mastercore::swapByteOrder16(messageType); + mastercore::swapByteOrder32(propertyIdForSale); + mastercore::swapByteOrder64(amountForSale); + mastercore::swapByteOrder32(propertyIdDesired); + mastercore::swapByteOrder64(amountDesired); + + PUSH_BACK_BYTES(payload, messageVer); + PUSH_BACK_BYTES(payload, messageType); + PUSH_BACK_BYTES(payload, propertyIdForSale); + PUSH_BACK_BYTES(payload, amountForSale); + PUSH_BACK_BYTES(payload, propertyIdDesired); + PUSH_BACK_BYTES(payload, amountDesired); + PUSH_BACK_BYTES(payload, action); + + return payload; +} + +std::vector CreatePayload_MetaDExCancelPrice(uint32_t propertyIdForSale, uint64_t amountForSale, uint32_t propertyIdDesired, uint64_t amountDesired) +{ + std::vector payload; + + uint16_t messageType = 21; + uint16_t messageVer = 0; + uint8_t action = 2; // CANCEL_AT_PRICE + mastercore::swapByteOrder16(messageVer); + mastercore::swapByteOrder16(messageType); mastercore::swapByteOrder32(propertyIdForSale); + mastercore::swapByteOrder64(amountForSale); mastercore::swapByteOrder32(propertyIdDesired); + mastercore::swapByteOrder64(amountDesired); + + PUSH_BACK_BYTES(payload, messageVer); + PUSH_BACK_BYTES(payload, messageType); + PUSH_BACK_BYTES(payload, propertyIdForSale); + PUSH_BACK_BYTES(payload, amountForSale); + PUSH_BACK_BYTES(payload, propertyIdDesired); + PUSH_BACK_BYTES(payload, amountDesired); + PUSH_BACK_BYTES(payload, action); + + return payload; +} + +std::vector CreatePayload_MetaDExCancelPair(uint32_t propertyIdForSale, uint32_t propertyIdDesired) +{ + std::vector payload; + + uint16_t messageType = 21; + uint16_t messageVer = 0; + uint64_t amountForSale = 0; + uint64_t amountDesired = 0; + uint8_t action = 3; // CANCEL_ALL_FOR_PAIR + + mastercore::swapByteOrder16(messageVer); + mastercore::swapByteOrder16(messageType); + mastercore::swapByteOrder32(propertyIdForSale); mastercore::swapByteOrder64(amountForSale); + mastercore::swapByteOrder32(propertyIdDesired); mastercore::swapByteOrder64(amountDesired); PUSH_BACK_BYTES(payload, messageVer); @@ -300,4 +357,33 @@ std::vector CreatePayload_MetaDExTrade(uint32_t propertyIdForSale return payload; } +std::vector CreatePayload_MetaDExCancelEcosystem(uint8_t ecosystem) +{ + std::vector payload; + + uint16_t messageType = 21; + uint16_t messageVer = 0; + uint32_t propertyIdForSale = ecosystem; + uint64_t amountForSale = 0; + uint32_t propertyIdDesired = ecosystem; + uint64_t amountDesired = 0; + uint8_t action = 4; // CANCEL_EVERYTHING + + mastercore::swapByteOrder16(messageVer); + mastercore::swapByteOrder16(messageType); + mastercore::swapByteOrder32(propertyIdForSale); + mastercore::swapByteOrder64(amountForSale); + mastercore::swapByteOrder32(propertyIdDesired); + mastercore::swapByteOrder64(amountDesired); + + PUSH_BACK_BYTES(payload, messageVer); + PUSH_BACK_BYTES(payload, messageType); + PUSH_BACK_BYTES(payload, propertyIdForSale); + PUSH_BACK_BYTES(payload, amountForSale); + PUSH_BACK_BYTES(payload, propertyIdDesired); + PUSH_BACK_BYTES(payload, amountDesired); + PUSH_BACK_BYTES(payload, action); + + return payload; +} diff --git a/src/omnicore/createpayload.h b/src/omnicore/createpayload.h index 6968cdc87d67c..88d468d696185 100644 --- a/src/omnicore/createpayload.h +++ b/src/omnicore/createpayload.h @@ -20,7 +20,10 @@ std::vector CreatePayload_CloseCrowdsale(uint32_t propertyId); std::vector CreatePayload_Grant(uint32_t propertyId, uint64_t amount, std::string memo); std::vector CreatePayload_Revoke(uint32_t propertyId, uint64_t amount, std::string memo); std::vector CreatePayload_ChangeIssuer(uint32_t propertyId); -std::vector CreatePayload_MetaDExTrade(uint32_t propertyIdForSale, uint64_t amountForSale, uint32_t propertyIdDesired, uint64_t amountDesired, uint8_t action); +std::vector CreatePayload_MetaDExTrade(uint32_t propertyIdForSale, uint64_t amountForSale, uint32_t propertyIdDesired, uint64_t amountDesired); +std::vector CreatePayload_MetaDExCancelPrice(uint32_t propertyIdForSale, uint64_t amountForSale, uint32_t propertyIdDesired, uint64_t amountDesired); +std::vector CreatePayload_MetaDExCancelPair(uint32_t propertyIdForSale, uint32_t propertyIdDesired); +std::vector CreatePayload_MetaDExCancelEcosystem(uint8_t ecosystem); #endif // OMNICORE_CREATEPAYLOAD_H diff --git a/src/omnicore/rpctx.cpp b/src/omnicore/rpctx.cpp index bebba248ce8e6..26555747e46da 100644 --- a/src/omnicore/rpctx.cpp +++ b/src/omnicore/rpctx.cpp @@ -813,8 +813,7 @@ Value sendtrade_OMNI(const Array& params, bool fHelp) if (senderAvailableBalance < amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Sender has insufficient balance (due to pending transactions)"); // create a payload for the transaction - uint8_t action = CMPTransaction::ADD; // TODO: move into payload creation - std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired); // request the wallet build the transaction (and if needed commit it) uint256 txid = 0; @@ -828,6 +827,7 @@ Value sendtrade_OMNI(const Array& params, bool fHelp) if (!autoCommit) { return rawHex; } else { + uint8_t action = CMPTransaction::ADD; // TODO: move into pending creation PendingAdd(txid, fromAddress, "", MSC_TYPE_METADEX, propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); return txid.GetHex(); } @@ -877,8 +877,7 @@ Value sendcanceltradesbyprice_OMNI(const Array& params, bool fHelp) // TODO: check, if there are matching offers to cancel // create a payload for the transaction - uint8_t action = CMPTransaction::CANCEL_AT_PRICE; // TODO: move into payload creation - std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + std::vector payload = CreatePayload_MetaDExCancelPrice(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired); // request the wallet build the transaction (and if needed commit it) uint256 txid = 0; @@ -892,6 +891,7 @@ Value sendcanceltradesbyprice_OMNI(const Array& params, bool fHelp) if (!autoCommit) { return rawHex; } else { + uint8_t action = CMPTransaction::CANCEL_AT_PRICE; // TODO: move into pending creation PendingAdd(txid, fromAddress, "", MSC_TYPE_METADEX, propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); return txid.GetHex(); } @@ -930,10 +930,7 @@ Value sendcanceltradesbypair_OMNI(const Array& params, bool fHelp) // TODO: check, if there are matching offers to cancel // create a payload for the transaction - uint8_t action = CMPTransaction::CANCEL_ALL_FOR_PAIR; // TODO: move into payload creation - int64_t amountForSale = 0; - int64_t amountDesired = 0; - std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + std::vector payload = CreatePayload_MetaDExCancelPair(propertyIdForSale, propertyIdDesired); // request the wallet build the transaction (and if needed commit it) uint256 txid = 0; @@ -947,6 +944,9 @@ Value sendcanceltradesbypair_OMNI(const Array& params, bool fHelp) if (!autoCommit) { return rawHex; } else { + uint8_t action = CMPTransaction::CANCEL_ALL_FOR_PAIR; // TODO: move into pending creation + int64_t amountForSale = 0; + int64_t amountDesired = 0; PendingAdd(txid, fromAddress, "", MSC_TYPE_METADEX, propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); return txid.GetHex(); } @@ -980,12 +980,7 @@ Value sendcancelalltrades_OMNI(const Array& params, bool fHelp) // TODO: check, if there are matching offers to cancel // create a payload for the transaction - uint8_t action = CMPTransaction::CANCEL_EVERYTHING; // TODO: move into payload creation - int64_t amountForSale = 0; - int64_t amountDesired = 0; - uint32_t propertyIdForSale = ecosystem; - uint32_t propertyIdDesired = ecosystem; - std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + std::vector payload = CreatePayload_MetaDExCancelEcosystem(ecosystem); // request the wallet build the transaction (and if needed commit it) uint256 txid = 0; @@ -999,6 +994,11 @@ Value sendcancelalltrades_OMNI(const Array& params, bool fHelp) if (!autoCommit) { return rawHex; } else { + uint8_t action = CMPTransaction::CANCEL_EVERYTHING; // TODO: move into pending creation + int64_t amountForSale = 0; + int64_t amountDesired = 0; + uint32_t propertyIdForSale = ecosystem; + uint32_t propertyIdDesired = ecosystem; PendingAdd(txid, fromAddress, "", MSC_TYPE_METADEX, propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); return txid.GetHex(); } diff --git a/src/omnicore/test/create_payload_tests.cpp b/src/omnicore/test/create_payload_tests.cpp index 8b37f0a395bc8..77823c734b7b4 100644 --- a/src/omnicore/test/create_payload_tests.cpp +++ b/src/omnicore/test/create_payload_tests.cpp @@ -45,20 +45,63 @@ BOOST_AUTO_TEST_CASE(payload_dex_offer) "00010014000000010000000005f5e1000000000001312d000a000000000000271001"); } -BOOST_AUTO_TEST_CASE(payload_meta_dex_offer) +BOOST_AUTO_TEST_CASE(payload_meta_dex_new_trade) { // Trade tokens for tokens [type 21, version 0] std::vector vch = CreatePayload_MetaDExTrade( static_cast(1), // property: MSC static_cast(250000000), // amount for sale: 2.5 MSC static_cast(31), // property desired: TetherUS - static_cast(5000000000), // amount desired: 50.0 TetherUS - static_cast(1)); // sub-action: new offer + static_cast(5000000000)); // amount desired: 50.0 TetherUS + // sub-action: (1) new-offer BOOST_CHECK_EQUAL(HexStr(vch), "0000001500000001000000000ee6b2800000001f000000012a05f20001"); } +BOOST_AUTO_TEST_CASE(payload_meta_dex_cancel_at_price) +{ + // Trade tokens for tokens [type 21, version 0] + std::vector vch = CreatePayload_MetaDExCancelPrice( + static_cast(1), // property: MSC + static_cast(250000000), // amount for sale: 2.5 MSC + static_cast(31), // property desired: TetherUS + static_cast(5000000000)); // amount desired: 50.0 TetherUS + // sub-action: (2) cancel-at-price + + BOOST_CHECK_EQUAL(HexStr(vch), + "0000001500000001000000000ee6b2800000001f000000012a05f20002"); +} + +BOOST_AUTO_TEST_CASE(payload_meta_dex_cancel_pair) +{ + // Trade tokens for tokens [type 21, version 0] + std::vector vch = CreatePayload_MetaDExCancelPair( + static_cast(1), // property: MSC + // amount for sale: 0.0 MSC + static_cast(31)); // property desired: TetherUS + // amount desired: 0.0 TetherUS + // sub-action: (3) cancel-pair + + BOOST_CHECK_EQUAL(HexStr(vch), + "000000150000000100000000000000000000001f000000000000000003"); +} + +BOOST_AUTO_TEST_CASE(payload_meta_dex_cancel_ecosystem) +{ + // Trade tokens for tokens [type 21, version 0] + std::vector vch = CreatePayload_MetaDExCancelEcosystem( + static_cast(1)); // ecosystem: Main + // property: MSC + // amount for sale: 0.0 MSC + // property desired: MSC + // amount for sale: 0.0 MSC + // sub-action: (4) cancel-ecosystem + + BOOST_CHECK_EQUAL(HexStr(vch), + "0000001500000001000000000000000000000001000000000000000004"); +} + BOOST_AUTO_TEST_CASE(payload_accept_dex_offer) { // Purchase tokens with bitcoins [type 22, version 0] diff --git a/src/qt/metadexcanceldialog.cpp b/src/qt/metadexcanceldialog.cpp index f21e015ee044a..15831cc7d3f7a 100755 --- a/src/qt/metadexcanceldialog.cpp +++ b/src/qt/metadexcanceldialog.cpp @@ -327,8 +327,21 @@ void MetaDExCancelDialog::SendCancelTransaction() return; } + // TODO: restructure and seperate // create a payload for the transaction - std::vector payload = CreatePayload_MetaDExTrade(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired, action); + std::vector payload; + if (action == 2) { // CANCEL_AT_PRICE + payload = CreatePayload_MetaDExCancelPrice(propertyIdForSale, amountForSale, propertyIdDesired, amountDesired); + } + if (action == 3) { // CANCEL_ALL_FOR_PAIR + payload = CreatePayload_MetaDExCancelPair(propertyIdForSale, propertyIdDesired); + } + if (action == 4) { // CANCEL_ALL_FOR_PAIR + uint8_t ecosystem = 0; + if (isMainEcosystemProperty(propertyIdForSale) && isMainEcosystemProperty(propertyIdDesired)) ecosystem = OMNI_PROPERTY_MSC; + if (isTestEcosystemProperty(propertyIdForSale) && isTestEcosystemProperty(propertyIdDesired)) ecosystem = OMNI_PROPERTY_TMSC; + payload = CreatePayload_MetaDExCancelEcosystem(ecosystem); + } // request the wallet build the transaction (and if needed commit it) uint256 txid = 0; diff --git a/src/qt/metadexdialog.cpp b/src/qt/metadexdialog.cpp index ff508656a0ec3..5ae59b40f2292 100755 --- a/src/qt/metadexdialog.cpp +++ b/src/qt/metadexdialog.cpp @@ -607,7 +607,7 @@ void MetaDExDialog::sendTrade(bool sell) } // create a payload for the transaction - std::vector payload = CreatePayload_MetaDExTrade(propertyIdSell, amountSell, propertyIdDes, amountDes, 1); + std::vector payload = CreatePayload_MetaDExTrade(propertyIdSell, amountSell, propertyIdDes, amountDes); // request the wallet build the transaction (and if needed commit it) uint256 txid = 0; From f21b6ff91dc2766d00469236fe4322de25904b5a Mon Sep 17 00:00:00 2001 From: dexX7 Date: Fri, 22 May 2015 17:23:42 +0200 Subject: [PATCH 3/3] Move PUSH_BACK_BYTES into createpayload --- src/omnicore/convert.h | 13 ------------- src/omnicore/createpayload.cpp | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/omnicore/convert.h b/src/omnicore/convert.h index 9916cba5aaa69..39d8695d3107d 100644 --- a/src/omnicore/convert.h +++ b/src/omnicore/convert.h @@ -22,19 +22,6 @@ void swapByteOrder16(uint16_t&); void swapByteOrder32(uint32_t&); void swapByteOrder64(uint64_t&); -/** - * Pushes bytes to the end of a vector. - */ -#define PUSH_BACK_BYTES(vector, value)\ - vector.insert(vector.end(), reinterpret_cast(&(value)),\ - reinterpret_cast(&(value)) + sizeof((value))); - -/** - * Pushes bytes to the end of a vector based on a pointer. - */ -#define PUSH_BACK_BYTES_PTR(vector, ptr, size)\ - vector.insert(vector.end(), reinterpret_cast((ptr)),\ - reinterpret_cast((ptr)) + (size)); } diff --git a/src/omnicore/createpayload.cpp b/src/omnicore/createpayload.cpp index d63837b59a998..230920c6ee0de 100644 --- a/src/omnicore/createpayload.cpp +++ b/src/omnicore/createpayload.cpp @@ -8,6 +8,21 @@ #include #include +/** + * Pushes bytes to the end of a vector. + */ +#define PUSH_BACK_BYTES(vector, value)\ + vector.insert(vector.end(), reinterpret_cast(&(value)),\ + reinterpret_cast(&(value)) + sizeof((value))); + +/** + * Pushes bytes to the end of a vector based on a pointer. + */ +#define PUSH_BACK_BYTES_PTR(vector, ptr, size)\ + vector.insert(vector.end(), reinterpret_cast((ptr)),\ + reinterpret_cast((ptr)) + (size)); + + std::vector CreatePayload_SimpleSend(uint32_t propertyId, uint64_t amount) { std::vector payload; @@ -387,3 +402,6 @@ std::vector CreatePayload_MetaDExCancelEcosystem(uint8_t ecosyste return payload; } +#undef PUSH_BACK_BYTES +#undef PUSH_BACK_BYTES_PTR +