From 6fe16047e583cacdd02fa87f1f891a9863915136 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 14:53:52 -0800 Subject: [PATCH 01/24] New branch - add trade history --- src/mastercore.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mastercore.h b/src/mastercore.h index 46f288c62780..1d32dfdfb817 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -290,6 +290,12 @@ typedef struct } }; +/* leveldb-based storage for trade history - trades will be listed here atomically with key txid1:txid2 */ +class CMPTradeList +{ + +} + /* leveldb-based storage for the list of ALL Master Protocol TXIDs (key) with validity bit & other misc data as value */ class CMPTxList { From e319740be38074573e5607b668e15b37070e3bd4 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 15:03:35 -0800 Subject: [PATCH 02/24] Initial MPTradeList class --- src/mastercore.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/mastercore.h b/src/mastercore.h index 1d32dfdfb817..aa54a1fbd854 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -293,7 +293,42 @@ typedef struct /* leveldb-based storage for trade history - trades will be listed here atomically with key txid1:txid2 */ class CMPTradeList { +protected: + // datebase options reused from MPTxList + leveldb::Options options; + leveldb::ReadOptions readoptions; + leveldb::ReadOptions iteroptions; + leveldb::WriteOptions writeoptions; + leveldb::WriteOptions syncoptions; + leveldb::DB *tdb; + // statistics + unsigned int nWritten; + unsigned int nRead; + +public: + CMPTradeList(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe):nWritten(0),nRead(0) + { + options.paranoid_checks = true; + options.create_if_missing = true; + readoptions.verify_checksums = true; + iteroptions.verify_checksums = true; + iteroptions.fill_cache = false; + syncoptions.sync = true; + leveldb::Status status = leveldb::DB::Open(options, path.string(), &tdb); + printf("%s(): %s, line %d, file: %s\n", __FUNCTION__, status.ToString().c_str(), __LINE__, __FILE__); + } + ~CMPTradeList() + { + delete tdb; + tdb = NULL; + } + + void recordTrade(const uint256 &txid1, const uint256 &txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum); + bool exists(const uint256 &txid); + //bool getTrade(const uint256 &txid, string &value); + void printStats(); + void printAll(); } /* leveldb-based storage for the list of ALL Master Protocol TXIDs (key) with validity bit & other misc data as value */ From 4cd8cee811f0d507128de185b412f77e38d6ec5b Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 15:17:09 -0800 Subject: [PATCH 03/24] initial t_tradelistdb setup --- src/mastercore.cpp | 7 +++++++ src/mastercore.h | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 262446ebb1ad..9c4f4201181a 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -151,6 +151,7 @@ static const int txRestrictionsRules[][3] = { }; CMPTxList *mastercore::p_txlistdb; +CMPTradeList *mastercore::t_tradelistdb; // a copy from main.cpp -- unfortunately that one is in a private namespace int mastercore::GetHeight() @@ -2289,6 +2290,7 @@ int mastercore_init() exodus_address = exodus_testnet; }*/ + t_tradelistdb = new CMPTradeList(GetDataDir() / "MP_tradelist", 1<<20, false, fReindex); p_txlistdb = new CMPTxList(GetDataDir() / "MP_txlist", 1<<20, false, fReindex); _my_sps = new CMPSPInfo(GetDataDir() / "MP_spinfo"); MPPersistencePath = GetDataDir() / "MP_persist"; @@ -2387,6 +2389,11 @@ int mastercore_shutdown() delete p_txlistdb; p_txlistdb = NULL; } + if (t_tradelistdb) + { + delete t_tradelistdb; t_tradelistdb = NULL; + } + if (mp_fp) { fprintf(mp_fp, "\n%s MASTERCORE SHUTDOWN, build date: " __DATE__ " " __TIME__ "\n\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str()); diff --git a/src/mastercore.h b/src/mastercore.h index aa54a1fbd854..69883c28dfcc 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -329,7 +329,7 @@ class CMPTradeList //bool getTrade(const uint256 &txid, string &value); void printStats(); void printAll(); -} +}; /* leveldb-based storage for the list of ALL Master Protocol TXIDs (key) with validity bit & other misc data as value */ class CMPTxList @@ -443,6 +443,7 @@ namespace mastercore { extern std::map mp_tally_map; extern CMPTxList *p_txlistdb; +extern CMPTradeList *t_tradelistdb; typedef std::map PendingMap; From 04e531f6507d270aa19af2ac073196844fd2ba77 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 15:28:34 -0800 Subject: [PATCH 04/24] initial record trade function --- src/mastercore.cpp | 15 +++++++++++++++ src/mastercore.h | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 9c4f4201181a..0aa7fe01d3d1 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3083,6 +3083,21 @@ unsigned int n_found = 0; return (n_found); } +void CMPTradeList::recordTrade(const uint256 &txid1, const uint256 &txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum) +{ + if (!tdb) return; + + const string key = txid1.ToString() + txid2.ToString(); + const string value = strprintf("%s:%s:&u:%u:%lu:%lu:%d", address1, address2, prop1, prop2, amount1, amount2, nblockNum); + Status status; + if (tdb) + { + status = tdb->Put(writeoptions, key, value); + ++tWritten; + if (msc_debug_tradedb) fprintf(mp_fp, "%s(): %s, line %d, file: %s\n", __FUNCTION__, status.ToString().c_str(), __LINE__, __FILE__); + } +} + // global wrapper, block numbers are inclusive, if ending_block is 0 top of the chain will be used bool mastercore::isMPinBlockRange(int starting_block, int ending_block, bool bDeleteFound) { diff --git a/src/mastercore.h b/src/mastercore.h index 69883c28dfcc..857f9c47dbf7 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -302,8 +302,8 @@ class CMPTradeList leveldb::WriteOptions syncoptions; leveldb::DB *tdb; // statistics - unsigned int nWritten; - unsigned int nRead; + unsigned int tWritten; + unsigned int tRead; public: CMPTradeList(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe):nWritten(0),nRead(0) From d52af2585e9db25dfa7df14694d8798c0992db16 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 15:28:58 -0800 Subject: [PATCH 05/24] add tradedb debugging global --- src/mastercore.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 0aa7fe01d3d1..ab194e274389 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -114,6 +114,7 @@ int msc_debug_tally = 1; int msc_debug_sp = 1; int msc_debug_sto = 1; int msc_debug_txdb = 0; +int msc_debug_tradedb = 1; int msc_debug_persistence = 0; int msc_debug_metadex = 1; int msc_debug_metadex2= 1; From 9be4e4d3aa23e0f1c47a476a6f08c7b8e7f015fc Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 15:33:53 -0800 Subject: [PATCH 06/24] minor build fixes --- src/mastercore.cpp | 2 +- src/mastercore.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index ab194e274389..ae4f852485b9 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3089,7 +3089,7 @@ void CMPTradeList::recordTrade(const uint256 &txid1, const uint256 &txid2, strin if (!tdb) return; const string key = txid1.ToString() + txid2.ToString(); - const string value = strprintf("%s:%s:&u:%u:%lu:%lu:%d", address1, address2, prop1, prop2, amount1, amount2, nblockNum); + const string value = strprintf("%s:%s:&u:%u:%lu:%lu:%d", address1, address2, prop1, prop2, amount1, amount2, blockNum); Status status; if (tdb) { diff --git a/src/mastercore.h b/src/mastercore.h index 857f9c47dbf7..6f0a312c4a1f 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -306,7 +306,7 @@ class CMPTradeList unsigned int tRead; public: - CMPTradeList(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe):nWritten(0),nRead(0) + CMPTradeList(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe):tWritten(0),tRead(0) { options.paranoid_checks = true; options.create_if_missing = true; From 981806761a87ed4876c6aa46b14411016be14e72 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 15:36:37 -0800 Subject: [PATCH 07/24] leveldb stats/prints --- src/mastercore.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index ae4f852485b9..98bfe55c54b1 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3084,6 +3084,7 @@ unsigned int n_found = 0; return (n_found); } +// MPTradeList here void CMPTradeList::recordTrade(const uint256 &txid1, const uint256 &txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum) { if (!tdb) return; @@ -3099,6 +3100,31 @@ void CMPTradeList::recordTrade(const uint256 &txid1, const uint256 &txid2, strin } } +void CMPTradeList::printStats() +{ + fprintf(mp_fp, "CMPTradeList stats: tWritten= %d , tRead= %d\n", tWritten, tRead); +} + +void CMPTradeList::printAll() +{ + int count = 0; + Slice skey, svalue; + + readoptions.fill_cache = false; + + Iterator* it = tdb->NewIterator(readoptions); + + for(it->SeekToFirst(); it->Valid(); it->Next()) + { + skey = it->key(); + svalue = it->value(); + ++count; + printf("entry #%8d= %s:%s\n", count, skey.ToString().c_str(), svalue.ToString().c_str()); + } + + delete it; +} + // global wrapper, block numbers are inclusive, if ending_block is 0 top of the chain will be used bool mastercore::isMPinBlockRange(int starting_block, int ending_block, bool bDeleteFound) { From a1d0e0e786081c70720cddbfecb78ae5b5bdb035 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 15:53:28 -0800 Subject: [PATCH 08/24] add recordtrade & mscrpc 7 --- src/mastercore_dex.cpp | 2 ++ src/mastercore_rpc.cpp | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/mastercore_dex.cpp b/src/mastercore_dex.cpp index ebe4a84d3c6c..7d5beefaa570 100644 --- a/src/mastercore_dex.cpp +++ b/src/mastercore_dex.cpp @@ -270,6 +270,8 @@ const XDOUBLE desprice = (1/buyersprice); } if (msc_debug_metadex) fprintf(mp_fp, "==== TRADED !!! %u=%s\n", NewReturn, getTradeReturnType(NewReturn).c_str()); + // record the trade in MPTradeList + t_tradelistdb->recordTrade(p_older->getHash(), newo->getHash(), p_older->getAddr(), newo->getAddr(), p_older->getProperty(), newo->getProperty(), 1, 1, newo->getBlock()); if (msc_debug_metadex) fprintf(mp_fp, "++ erased old: %s\n", iitt->ToString().c_str()); // erase the old seller element diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index 127971d30dd1..61f5c8b7aad6 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -131,6 +131,13 @@ int extra2 = 0, extra3 = 0; case 6: MetaDEx_debug_print(); break; + + case 7: + // display the whole CMPTradeList (leveldb) + t_tradelistdb->printAll(); + t_tradelistdb->printStats(); + break; + } return GetHeight(); From 2b885ccfdf30183db746a97e6a2c41965936753e Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 16:14:14 -0800 Subject: [PATCH 09/24] working recordTrade --- src/mastercore.cpp | 5 ++--- src/mastercore.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 98bfe55c54b1..7bf072b446c5 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3085,12 +3085,11 @@ unsigned int n_found = 0; } // MPTradeList here -void CMPTradeList::recordTrade(const uint256 &txid1, const uint256 &txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum) +void CMPTradeList::recordTrade(const uint256 txid1, const uint256 txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum) { if (!tdb) return; - const string key = txid1.ToString() + txid2.ToString(); - const string value = strprintf("%s:%s:&u:%u:%lu:%lu:%d", address1, address2, prop1, prop2, amount1, amount2, blockNum); + const string value = strprintf("%s:%s:%u:%u:%lu:%lu:%d", address1, address2, prop1, prop2, amount1, amount2, blockNum); Status status; if (tdb) { diff --git a/src/mastercore.h b/src/mastercore.h index 6f0a312c4a1f..a327702c8b5d 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -324,7 +324,7 @@ class CMPTradeList tdb = NULL; } - void recordTrade(const uint256 &txid1, const uint256 &txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum); + void recordTrade(const uint256 txid1, const uint256 txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum); bool exists(const uint256 &txid); //bool getTrade(const uint256 &txid, string &value); void printStats(); From f88696b3c990a5612114aa847916ff06ec929a30 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 16:37:31 -0800 Subject: [PATCH 10/24] reorg protection --- src/mastercore.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/mastercore.h | 1 + 2 files changed, 39 insertions(+) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 7bf072b446c5..61769a5c3ac0 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3099,6 +3099,43 @@ void CMPTradeList::recordTrade(const uint256 txid1, const uint256 txid2, string } } +// delete any trades after blockNum +int CMPTradeList::deleteAboveBlock(int blockNum) +{ + leveldb::Slice skey, svalue; + unsigned int count = 0; + std::vector vstr; + int block; + unsigned int n_found = 0; + leveldb::Iterator* it = tdb->NewIterator(iteroptions); + for(it->SeekToFirst(); it->Valid(); it->Next()) + { + skey = it->key(); + svalue = it->value(); + ++count; + string strvalue = it->value().ToString(); + boost::split(vstr, strvalue, boost::is_any_of(":"), token_compress_on); + // only care about the block number/height here + if (7 == vstr.size()) + { + block = atoi(vstr[6]); + + if (block >= blockNum) + { + ++n_found; + fprintf(mp_fp, "%s() DELETING FROM TRADEDB: %s=%s\n", __FUNCTION__, skey.ToString().c_str(), svalue.ToString().c_str()); + tdb->Delete(writeoptions, skey); + } + } + } + + printf("%s(%d); tradedb n_found= %d\n", __FUNCTION__, blockNum, n_found); + + delete it; + + return (n_found); +} + void CMPTradeList::printStats() { fprintf(mp_fp, "CMPTradeList stats: tWritten= %d , tRead= %d\n", tWritten, tRead); @@ -3224,6 +3261,7 @@ int mastercore_handler_block_begin(int nBlockPrev, CBlockIndex const * pBlockInd // reset states if(!readPersistence()) clear_all_state(); p_txlistdb->isMPinBlockRange(pBlockIndex->nHeight, reorgRecoveryMaxHeight, true); + t_tradelistdb->deleteAboveBlock(pBlockIndex->nHeight); reorgRecoveryMaxHeight = 0; diff --git a/src/mastercore.h b/src/mastercore.h index a327702c8b5d..f51e37263377 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -325,6 +325,7 @@ class CMPTradeList } void recordTrade(const uint256 txid1, const uint256 txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum); + int deleteAboveBlock(int blockNum); bool exists(const uint256 &txid); //bool getTrade(const uint256 &txid, string &value); void printStats(); From 301e728c73f701267f8ae61600e696bd00963698 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 17:01:30 -0800 Subject: [PATCH 11/24] Add values in to recordtrade --- src/mastercore_dex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mastercore_dex.cpp b/src/mastercore_dex.cpp index 7d5beefaa570..5143a404579f 100644 --- a/src/mastercore_dex.cpp +++ b/src/mastercore_dex.cpp @@ -271,7 +271,7 @@ const XDOUBLE desprice = (1/buyersprice); if (msc_debug_metadex) fprintf(mp_fp, "==== TRADED !!! %u=%s\n", NewReturn, getTradeReturnType(NewReturn).c_str()); // record the trade in MPTradeList - t_tradelistdb->recordTrade(p_older->getHash(), newo->getHash(), p_older->getAddr(), newo->getAddr(), p_older->getProperty(), newo->getProperty(), 1, 1, newo->getBlock()); + t_tradelistdb->recordTrade(p_older->getHash(), newo->getHash(), p_older->getAddr(), newo->getAddr(), p_older->getProperty(), newo->getProperty(), buyer_amountGot, paymentAmount, newo->getBlock()); if (msc_debug_metadex) fprintf(mp_fp, "++ erased old: %s\n", iitt->ToString().c_str()); // erase the old seller element From 1aed41f555457e0b6b107feb515f96482731d044 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 17:22:13 -0800 Subject: [PATCH 12/24] add RPC for gettrade_MP --- src/mastercore_rpc.cpp | 4 ++++ src/rpcserver.cpp | 1 + src/rpcserver.h | 1 + 3 files changed, 6 insertions(+) diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index 61f5c8b7aad6..d8a5ab91fc48 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -2057,3 +2057,7 @@ Value listtransactions_MP(const Array& params, bool fHelp) return response; // return response array for JSON serialization } +Value gettrade_MP(const Array& params, bool fHelp) +{ + +} diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 55e9015f9699..35cdc99c83f6 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -335,6 +335,7 @@ static const CRPCCommand vRPCCommands[] = { "gettradehistory_MP", &gettradehistory_MP, false, false, true }, { "sendtoowners_MP", &sendtoowners_MP, false, false, true }, { "sendrawtx_MP", &sendrawtx_MP, false, false, true }, + { "gettrade_MP", &gettrade_MP, false, false, true }, { "listblocktransactions_MP", &listblocktransactions_MP, false, false, true }, { "getallbalancesforaddress_MP", &getallbalancesforaddress_MP, false, false, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 0073138e488e..08629fe13bf7 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -203,6 +203,7 @@ extern json_spirit::Value getallbalancesforaddress_MP(const json_spirit::Array& extern json_spirit::Value getactivedexsells_MP(const json_spirit::Array& params, bool fHelp); // in mastercore.cpp extern json_spirit::Value gettransaction_MP(const json_spirit::Array& params, bool fHelp); // in mastercore.cpp extern json_spirit::Value trade_MP(const json_spirit::Array& params, bool fHelp); // in mastercore.cpp +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); // in mastercore.cpp extern json_spirit::Value gettradessince_MP(const json_spirit::Array& params, bool fHelp); // in mastercore.cpp extern json_spirit::Value getopenorders_MP(const json_spirit::Array& params, bool fHelp); From 1e5ee2f936771f0762414f6d95ba47b5a0a84d65 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 17:40:17 -0800 Subject: [PATCH 13/24] gettrade_MP call initial --- src/mastercore_rpc.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index d8a5ab91fc48..b731ef0efe18 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -2059,5 +2059,61 @@ Value listtransactions_MP(const Array& params, bool fHelp) Value gettrade_MP(const Array& params, bool fHelp) { + // note this call has been refactored to use the singular populateRPCTransactionObject function + if (fHelp || params.size() != 1) + throw runtime_error( + "gettransaction_MP \"txid\"\n" + "\nGet detailed information about a Master Protocol transaction \n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "\nResult:\n" + "{\n" + " \"txid\" : \"transactionid\", (string) The transaction id\n" + + HelpExampleCli("gettrade_MP", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + + HelpExampleRpc("gettrade_MP", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + ); + + uint256 hash; + hash.SetHex(params[0].get_str()); + Object tradeobj; + Object txobj; + + // make a request to new RPC populator function to populate a transaction object + int populateResult = populateRPCTransactionObject(hash, &txobj); + + // check the response, throw any error codes if false + if (0>populateResult) + { + // TODO: consider throwing other error codes, check back with Bitcoin Core + switch (populateResult) + { + case MP_TX_NOT_FOUND: + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + case MP_TX_UNCONFIRMED: + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unconfirmed transactions are not supported"); + case MP_BLOCK_NOT_IN_CHAIN: + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not part of the active chain"); + case MP_CROWDSALE_WITHOUT_PROPERTY: + throw JSONRPCError(RPC_INTERNAL_ERROR, "Potential database corruption: \ + \"Crowdsale Purchase\" without valid property identifier"); + case MP_INVALID_TX_IN_DB_FOUND: + throw JSONRPCError(RPC_INTERNAL_ERROR, "Potential database corruption: Invalid transaction found"); + case MP_TX_IS_NOT_MASTER_PROTOCOL: + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not a Master Protocol transaction"); + } + } + + // everything seems ok, now add status and get an array of matches to add to the object + // status - is order cancelled/filled/open? + bool orderOpen = false; + bool orderFilled = false; + + //txobj->push_back(Pair("status", wtxid.GetHex())); + // create array of matches + + // add array to object + + // return object + return txobj; } From 7ef27ea17a65c90a81839dd582928fd6b0dc529c Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 19:14:26 -0800 Subject: [PATCH 14/24] getMatchingTrades --- src/mastercore.cpp | 28 ++++++++++++++++++++++++++++ src/mastercore.h | 2 +- src/mastercore_rpc.cpp | 4 ++++ src/qt/balancesview.cpp | 2 +- src/qt/overviewpage.cpp | 2 +- src/qt/sendmpdialog.cpp | 2 +- src/qt/transactiontablemodel.cpp | 2 +- 7 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index c92d7f899397..5af1c934356e 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3085,6 +3085,34 @@ unsigned int n_found = 0; } // MPTradeList here +bool CMPTradeList::getMatchingTrades(const uint256 txid, Array *tradeArray) +{ + if (!tdb) return false; + leveldb::Slice skey, svalue; + unsigned int count = 0; + std::vector vstr; + string txidStr = txid.ToString(); + int block; + unsigned int n_found = 0; + leveldb::Iterator* it = tdb->NewIterator(iteroptions); + for(it->SeekToFirst(); it->Valid(); it->Next()) + { + skey = it->key(); + svalue = it->value(); + string strkey = it->key().ToString(); + size_t txidMatch = strkey.find(txidStr); + if(txidMatch!=std::string::npos) + { + // we have a matching trade involving this txid + string strvalue = it->value().ToString(); + boost::split(vstr, strvalue, boost::is_any_of(":"), token_compress_on); + printf("match\n"); + if (7 == vstr.size()) { } + Object trade; + } + } +} + void CMPTradeList::recordTrade(const uint256 txid1, const uint256 txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum) { if (!tdb) return; diff --git a/src/mastercore.h b/src/mastercore.h index f51e37263377..0c6fa2513c9d 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -327,9 +327,9 @@ class CMPTradeList void recordTrade(const uint256 txid1, const uint256 txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum); int deleteAboveBlock(int blockNum); bool exists(const uint256 &txid); - //bool getTrade(const uint256 &txid, string &value); void printStats(); void printAll(); + bool getMatchingTrades(const uint256 txid, Array *tradeArray); }; /* leveldb-based storage for the list of ALL Master Protocol TXIDs (key) with validity bit & other misc data as value */ diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index b731ef0efe18..44d47d380ec0 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -2110,9 +2110,13 @@ Value gettrade_MP(const Array& params, bool fHelp) bool orderFilled = false; //txobj->push_back(Pair("status", wtxid.GetHex())); + // create array of matches + Array tradeArray; + t_tradelistdb->getMatchingTrades(hash,&tradeArray); // add array to object + txobj.push_back(Pair("matches", tradeArray)); // return object return txobj; diff --git a/src/qt/balancesview.cpp b/src/qt/balancesview.cpp index 1899c519f1e2..f227e87adaca 100644 --- a/src/qt/balancesview.cpp +++ b/src/qt/balancesview.cpp @@ -46,6 +46,7 @@ #include "leveldb/db.h" #include "leveldb/write_batch.h" // end potentially overzealous includes +using namespace json_spirit; // since now using Array in mastercore.h this needs to come first #include "mastercore.h" using namespace mastercore; @@ -54,7 +55,6 @@ using namespace mastercore; using namespace std; using namespace boost; using namespace boost::assign; -using namespace json_spirit; using namespace leveldb; // end potentially overzealous using diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 58c2b231ad54..3ccfd2d06ecf 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -37,6 +37,7 @@ #include "leveldb/db.h" #include "leveldb/write_batch.h" // end potentially overzealous includes +using namespace json_spirit; // since now using Array in mastercore.h this needs to come first #include "mastercore.h" using namespace mastercore; @@ -45,7 +46,6 @@ using namespace mastercore; using namespace std; using namespace boost; using namespace boost::assign; -using namespace json_spirit; using namespace leveldb; // end potentially overzealous using diff --git a/src/qt/sendmpdialog.cpp b/src/qt/sendmpdialog.cpp index 718a9e4906f3..a94a9d54b01c 100644 --- a/src/qt/sendmpdialog.cpp +++ b/src/qt/sendmpdialog.cpp @@ -43,6 +43,7 @@ #include "leveldb/db.h" #include "leveldb/write_batch.h" // end potentially overzealous includes +using namespace json_spirit; // since now using Array in mastercore.h this needs to come first #include "mastercore.h" using namespace mastercore; @@ -51,7 +52,6 @@ using namespace mastercore; using namespace std; using namespace boost; using namespace boost::assign; -using namespace json_spirit; using namespace leveldb; // end potentially overzealous using diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 43be1fd9365d..5a2b733bcbd5 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -46,6 +46,7 @@ #include "leveldb/db.h" #include "leveldb/write_batch.h" // end potentially overzealous includes +using namespace json_spirit; // since now using Array in mastercore.h this needs to come first #include "mastercore.h" using namespace mastercore; @@ -54,7 +55,6 @@ using namespace mastercore; using namespace std; using namespace boost; using namespace boost::assign; -using namespace json_spirit; using namespace leveldb; // end potentially overzealous using From dec1a1ccde15d3b5ad966e738758fe90eb6a69e6 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 19:58:14 -0800 Subject: [PATCH 15/24] more work on gettrade_MP --- src/mastercore.cpp | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 5af1c934356e..ca363795c66f 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3104,19 +3104,45 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, Array *tradeArray) if(txidMatch!=std::string::npos) { // we have a matching trade involving this txid - string strvalue = it->value().ToString(); - boost::split(vstr, strvalue, boost::is_any_of(":"), token_compress_on); - printf("match\n"); - if (7 == vstr.size()) { } - Object trade; + // get the txid of the match + string matchTxid; + // make sure string is correct length + if (strkey.length() == 129) + { + if (txidMatch==0) { matchTxid = strkey.substr(65,64); } else { matchTxid = strkey.substr(0,64); } + + string strvalue = it->value().ToString(); + boost::split(vstr, strvalue, boost::is_any_of(":"), token_compress_on); + if (7 == vstr.size()) // ensure there are the expected amount of tokens + { + string address1 = vstr[0]; + string address2 = vstr[1]; + unsigned int prop1 = boost::lexical_cast(vstr[2]); + unsigned int prop2 = boost::lexical_cast(vstr[3]); + uint64_t amount1 = boost::lexical_cast(vstr[4]); + uint64_t amount2 = boost::lexical_cast(vstr[5]); + int blockNum = atoi(vstr[6]); + + Object trade; + //determine orientation of trade + trade.push_back(Pair("txid", matchTxid)); + trade.push_back(Pair("address", "address")); + trade.push_back(Pair("amountpaid", FormatDivisibleMP(1))); + trade.push_back(Pair("amountbought", FormatDivisibleMP(1))); + trade.push_back(Pair("price", FormatDivisibleMP(1))); + tradeArray->push_back(trade); + ++count; + } + } } } +if (count) { return true; } else { return false; } } void CMPTradeList::recordTrade(const uint256 txid1, const uint256 txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum) { if (!tdb) return; - const string key = txid1.ToString() + txid2.ToString(); + const string key = txid1.ToString() + "+" + txid2.ToString(); const string value = strprintf("%s:%s:%u:%u:%lu:%lu:%d", address1, address2, prop1, prop2, amount1, amount2, blockNum); Status status; if (tdb) From 92fce2edac01858863b9c47cdaaeebeb409475fd Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 21:13:09 -0800 Subject: [PATCH 16/24] matching trades and RPC work --- src/mastercore.cpp | 37 ++++++++++++----- src/mastercore.h | 2 +- src/mastercore_dex.h | 5 +++ src/mastercore_rpc.cpp | 91 +++++++++++++++++++++++------------------- 4 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index ca363795c66f..9b03635a12b5 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3085,7 +3085,7 @@ unsigned int n_found = 0; } // MPTradeList here -bool CMPTradeList::getMatchingTrades(const uint256 txid, Array *tradeArray) +bool CMPTradeList::getMatchingTrades(const uint256 txid, string sellerAddress, Array *tradeArray) { if (!tdb) return false; leveldb::Slice skey, svalue; @@ -3115,20 +3115,37 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, Array *tradeArray) boost::split(vstr, strvalue, boost::is_any_of(":"), token_compress_on); if (7 == vstr.size()) // ensure there are the expected amount of tokens { + string address; string address1 = vstr[0]; string address2 = vstr[1]; - unsigned int prop1 = boost::lexical_cast(vstr[2]); - unsigned int prop2 = boost::lexical_cast(vstr[3]); - uint64_t amount1 = boost::lexical_cast(vstr[4]); - uint64_t amount2 = boost::lexical_cast(vstr[5]); + unsigned int propBought; + unsigned int propSold; + uint64_t amountBought; + uint64_t amountSold; + if (address1 == sellerAddress) + { + address = address2; + propBought = boost::lexical_cast(vstr[2]); + propSold = boost::lexical_cast(vstr[3]); + amountBought = boost::lexical_cast(vstr[4]); + amountSold = boost::lexical_cast(vstr[5]); + } + else + { + address = address1; + propBought = boost::lexical_cast(vstr[3]); + propSold = boost::lexical_cast(vstr[2]); + amountBought = boost::lexical_cast(vstr[5]); + amountSold = boost::lexical_cast(vstr[4]); + } int blockNum = atoi(vstr[6]); Object trade; - //determine orientation of trade trade.push_back(Pair("txid", matchTxid)); - trade.push_back(Pair("address", "address")); - trade.push_back(Pair("amountpaid", FormatDivisibleMP(1))); - trade.push_back(Pair("amountbought", FormatDivisibleMP(1))); + trade.push_back(Pair("address", address)); + trade.push_back(Pair("block", blockNum)); + trade.push_back(Pair("amountpaid", FormatDivisibleMP(amountSold))); + trade.push_back(Pair("amountbought", FormatDivisibleMP(amountBought))); trade.push_back(Pair("price", FormatDivisibleMP(1))); tradeArray->push_back(trade); ++count; @@ -3136,7 +3153,7 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, Array *tradeArray) } } } -if (count) { return true; } else { return false; } + if (count) { return true; } else { return false; } } void CMPTradeList::recordTrade(const uint256 txid1, const uint256 txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum) diff --git a/src/mastercore.h b/src/mastercore.h index 0c6fa2513c9d..3781fa2fa492 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -329,7 +329,7 @@ class CMPTradeList bool exists(const uint256 &txid); void printStats(); void printAll(); - bool getMatchingTrades(const uint256 txid, Array *tradeArray); + bool getMatchingTrades(const uint256 txid, string sellerAddress, Array *tradeArray); }; /* leveldb-based storage for the list of ALL Master Protocol TXIDs (key) with validity bit & other misc data as value */ diff --git a/src/mastercore_dex.h b/src/mastercore_dex.h index a6c9d0f3314f..6e11fa0d4d2d 100644 --- a/src/mastercore_dex.h +++ b/src/mastercore_dex.h @@ -211,6 +211,11 @@ class CMPMetaDEx return pblockindex->GetBlockTime(); } + CMPMetaDEx():block(0),txid(0),idx(0),property(0),amount(0),desired_property(0),amount_desired(0),subaction(0) + { + addr.empty(); + } + CMPMetaDEx(const string &, int, unsigned int, uint64_t, unsigned int, uint64_t, const uint256 &, unsigned int, unsigned char); void Set(const string &, int, unsigned int, uint64_t, unsigned int, uint64_t, const uint256 &, unsigned int, unsigned char); diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index 44d47d380ec0..d88c6b3e209c 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -1529,6 +1529,7 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt bool bIsMine = false; bool isMPTx = false; uint64_t nFee = 0; + bool offerOpen = false; string MPTxType; unsigned int MPTxTypeInt; string selectedAddress; @@ -1555,11 +1556,8 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt bool mdex = false; bool mdex_propertyId_Div = false; uint64_t mdex_propertyWanted = 0; + uint64_t mdex_amountWanted = 0; bool mdex_propertyWanted_Div = false; - string mdex_unitPrice; - string mdex_invUnitPrice; - uint64_t mdex_amt_orig_sale = 0; - uint64_t mdex_amt_des = 0; unsigned int mdex_action = 0; if ((0 == blockHash) || (NULL == mapBlockIndex[blockHash])) { return MP_TX_UNCONFIRMED; } @@ -1573,6 +1571,7 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt mp_obj.SetNull(); CMPOffer temp_offer; + CMPMetaDEx temp_metadexoffer; // replace initial MP detection with levelDB lookup instead of parse, this is much faster especially in calls like list/search if (p_txlistdb->exists(wtxid)) @@ -1654,42 +1653,37 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt switch (MPTxTypeInt) { case MSC_TYPE_METADEX: + offerOpen = false; if (0 == mp_obj.step2_Value()) { - mdex = true; + mdex = true; + propertyId = mp_obj.getProperty(); + amount = mp_obj.getAmount(); + mdex_propertyId_Div = isPropertyDivisible(propertyId); + if (0 <= mp_obj.interpretPacket(NULL,&temp_metadexoffer)) + { + mdex_propertyWanted = temp_metadexoffer.getDesProperty(); + mdex_propertyWanted_Div = isPropertyDivisible(mdex_propertyWanted); + mdex_amountWanted = temp_metadexoffer.getAmountDesired(); + mdex_action = temp_metadexoffer.getAction(); + } + } - for (md_PropertiesMap::iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) - { - md_PricesMap & prices = my_it->second; - for (md_PricesMap::iterator it = prices.begin(); it != prices.end(); ++it) - { - md_Set & indexes = (it->second); - for (md_Set::iterator it = indexes.begin(); it != indexes.end(); ++it) - { - CMPMetaDEx obj = *it; - CMPSPInfo::Entry sp; - - - if( obj.getHash().GetHex() == wtxid.GetHex() ) { - propertyId = mp_obj.getProperty(); - amount = mp_obj.getAmount(); - _my_sps->getSP(propertyId, sp); - mdex_propertyId_Div = sp.isDivisible(); - mdex_propertyWanted = obj.getDesProperty(); - _my_sps->getSP(mdex_propertyWanted, sp); - mdex_propertyWanted_Div = sp.isDivisible(); - - //uint64_t *price = obj.getPrice(); - //uint64_t *invprice = obj.getInversePrice(); - - //mdex_unitPrice = strprintf("%lu.%.8s", price[0], boost::lexical_cast(price[1]) ).c_str(); - //mdex_invUnitPrice = strprintf("%lu.%.8s", invprice[0], boost::lexical_cast(invprice[1]) ).c_str(); - mdex_amt_orig_sale = obj.getAmount(); - mdex_amt_des = obj.getAmountDesired(); - mdex_action = obj.getAction(); - } - } - } + // is the sell offer still open - need more efficient way to do this + for (md_PropertiesMap::iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) + { + if (my_it->first == propertyId) //at bear minimum only go deeper if it's the right property id + { + md_PricesMap & prices = my_it->second; + for (md_PricesMap::iterator it = prices.begin(); it != prices.end(); ++it) + { + md_Set & indexes = (it->second); + for (md_Set::iterator it = indexes.begin(); it != indexes.end(); ++it) + { + CMPMetaDEx obj = *it; + if( obj.getHash().GetHex() == wtxid.GetHex() ) offerOpen = true; + } + } } } break; @@ -1881,8 +1875,8 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt //txobj->push_back(Pair("unit_price", mdex_unitPrice ) ); //txobj->push_back(Pair("inverse_unit_price", mdex_invUnitPrice ) ); //active? - txobj->push_back(Pair("amount_original", FormatDivisibleMP(mdex_amt_orig_sale))); - txobj->push_back(Pair("amount_desired", FormatDivisibleMP(mdex_amt_des))); + //txobj->push_back(Pair("amount_original", FormatDivisibleMP(mdex_amt_orig_sale))); + //txobj->push_back(Pair("amount_desired", FormatDivisibleMP(mdex_amt_des))); txobj->push_back(Pair("action", (uint64_t) mdex_action)); } txobj->push_back(Pair("valid", valid)); @@ -2079,6 +2073,23 @@ Value gettrade_MP(const Array& params, bool fHelp) Object tradeobj; Object txobj; + //get sender + string senderAddress; + CTransaction wtx; + uint256 blockHash = 0; + if (!GetTransaction(hash, wtx, blockHash, true)) { return MP_TX_NOT_FOUND; } + CMPTransaction mp_obj; + int parseRC = parseTransaction(true, wtx, 0, 0, &mp_obj); + if (0 <= parseRC) //negative RC means no MP content/badly encoded TX, we shouldn't see this if TX in levelDB but check for sa$ + { + if (0<=mp_obj.step1()) + { + senderAddress = mp_obj.getSender(); + } + } + if (senderAddress.empty()) // something went wrong, couldn't decode transaction + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not a Master Protocol transaction"); + // make a request to new RPC populator function to populate a transaction object int populateResult = populateRPCTransactionObject(hash, &txobj); @@ -2113,7 +2124,7 @@ Value gettrade_MP(const Array& params, bool fHelp) // create array of matches Array tradeArray; - t_tradelistdb->getMatchingTrades(hash,&tradeArray); + t_tradelistdb->getMatchingTrades(hash, senderAddress, &tradeArray); // add array to object txobj.push_back(Pair("matches", tradeArray)); From e0b54a41baa13ea2a6c93f717dfcc574eade95c0 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 21:30:43 -0800 Subject: [PATCH 17/24] RPC fixes to populateRPCTransactionObject --- src/mastercore_rpc.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index d88c6b3e209c..92096ad862c7 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -1827,19 +1827,22 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt txobj->push_back(Pair("fee", ValueFromAmount(nFee))); txobj->push_back(Pair("blocktime", blockTime)); txobj->push_back(Pair("type", MPTxType)); - txobj->push_back(Pair("propertyid", propertyId)); + if (!MSC_TYPE_METADEX == MPTxTypeInt) txobj->push_back(Pair("propertyid", propertyId)); if ((MSC_TYPE_CREATE_PROPERTY_VARIABLE == MPTxTypeInt) || (MSC_TYPE_CREATE_PROPERTY_FIXED == MPTxTypeInt) || (MSC_TYPE_CREATE_PROPERTY_MANUAL == MPTxTypeInt)) { txobj->push_back(Pair("propertyname", propertyName)); } txobj->push_back(Pair("divisible", divisible)); - if (divisible) - { - txobj->push_back(Pair("amount", FormatDivisibleMP(amount))); //divisible, format w/ bitcoins VFA func - } - else + if (!MSC_TYPE_METADEX == MPTxTypeInt) { - txobj->push_back(Pair("amount", FormatIndivisibleMP(amount))); //indivisible, push raw 64 + if (divisible) + { + txobj->push_back(Pair("amount", FormatDivisibleMP(amount))); //divisible, format w/ bitcoins VFA func + } + else + { + txobj->push_back(Pair("amount", FormatIndivisibleMP(amount))); //indivisible, push raw 64 + } } if (crowdPurchase) { @@ -1866,18 +1869,26 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt if (3 == sell_subaction) txobj->push_back(Pair("subaction", "Cancel")); txobj->push_back(Pair("bitcoindesired", ValueFromAmount(sell_btcdesired))); } - if (mdex) + if (MSC_TYPE_METADEX == MPTxTypeInt) { - txobj->push_back(Pair("property_owned", propertyId)); - txobj->push_back(Pair("property_owned_divisible", mdex_propertyId_Div)); - txobj->push_back(Pair("property_desired", mdex_propertyWanted)); - txobj->push_back(Pair("property_desired_divisible", mdex_propertyWanted_Div)); + string amountOffered; + string amountDesired; + if (mdex_propertyId_Div) {amountOffered=FormatDivisibleMP(amount);} else {amountOffered=FormatIndivisibleMP(amount);} + if (mdex_propertyWanted_Div) {amountDesired=FormatDivisibleMP(mdex_amountWanted);} else {amountDesired=FormatIndivisibleMP(mdex_amountWanted);} + + txobj->push_back(Pair("amountoffered", amountOffered)); + txobj->push_back(Pair("propertyoffered", propertyId)); + txobj->push_back(Pair("propertyofferedisdivisible", mdex_propertyId_Div)); + txobj->push_back(Pair("amountdesired", amountDesired)); + txobj->push_back(Pair("propertydesired", mdex_propertyWanted)); + txobj->push_back(Pair("propertydesiredisdivisible", mdex_propertyWanted_Div)); + txobj->push_back(Pair("action", (uint64_t) mdex_action)); + txobj->push_back(Pair("status", "status")); //txobj->push_back(Pair("unit_price", mdex_unitPrice ) ); //txobj->push_back(Pair("inverse_unit_price", mdex_invUnitPrice ) ); //active? //txobj->push_back(Pair("amount_original", FormatDivisibleMP(mdex_amt_orig_sale))); //txobj->push_back(Pair("amount_desired", FormatDivisibleMP(mdex_amt_des))); - txobj->push_back(Pair("action", (uint64_t) mdex_action)); } txobj->push_back(Pair("valid", valid)); } From ef56f880a9c6da28d887e6b0097188d1397fe2bc Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 21:47:13 -0800 Subject: [PATCH 18/24] add totalBought vars --- src/mastercore.cpp | 4 +++- src/mastercore.h | 2 +- src/mastercore_rpc.cpp | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 9b03635a12b5..cb172a7ff737 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3085,9 +3085,10 @@ unsigned int n_found = 0; } // MPTradeList here -bool CMPTradeList::getMatchingTrades(const uint256 txid, string sellerAddress, Array *tradeArray) +bool CMPTradeList::getMatchingTrades(const uint256 txid, string sellerAddress, Array *tradeArray, uint64_t *totalBought) { if (!tdb) return false; + totalBought = 0; leveldb::Slice skey, svalue; unsigned int count = 0; std::vector vstr; @@ -3149,6 +3150,7 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, string sellerAddress, A trade.push_back(Pair("price", FormatDivisibleMP(1))); tradeArray->push_back(trade); ++count; + totalBought=totalBought + amountBought; } } } diff --git a/src/mastercore.h b/src/mastercore.h index 3781fa2fa492..166066cfe58b 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -329,7 +329,7 @@ class CMPTradeList bool exists(const uint256 &txid); void printStats(); void printAll(); - bool getMatchingTrades(const uint256 txid, string sellerAddress, Array *tradeArray); + bool getMatchingTrades(const uint256 txid, string sellerAddress, Array *tradeArray, uint64_t *totalBought); }; /* leveldb-based storage for the list of ALL Master Protocol TXIDs (key) with validity bit & other misc data as value */ diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index 92096ad862c7..d5a89807e044 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -1832,7 +1832,7 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt { txobj->push_back(Pair("propertyname", propertyName)); } - txobj->push_back(Pair("divisible", divisible)); + if (!MSC_TYPE_METADEX == MPTxTypeInt) txobj->push_back(Pair("divisible", divisible)); if (!MSC_TYPE_METADEX == MPTxTypeInt) { if (divisible) @@ -1883,7 +1883,6 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt txobj->push_back(Pair("propertydesired", mdex_propertyWanted)); txobj->push_back(Pair("propertydesiredisdivisible", mdex_propertyWanted_Div)); txobj->push_back(Pair("action", (uint64_t) mdex_action)); - txobj->push_back(Pair("status", "status")); //txobj->push_back(Pair("unit_price", mdex_unitPrice ) ); //txobj->push_back(Pair("inverse_unit_price", mdex_invUnitPrice ) ); //active? @@ -2127,15 +2126,16 @@ Value gettrade_MP(const Array& params, bool fHelp) } // everything seems ok, now add status and get an array of matches to add to the object - // status - is order cancelled/filled/open? + // status - is order cancelled/closed-filled/open/open-partialfilled? bool orderOpen = false; bool orderFilled = false; - + bool orderPartialFilled = false; //txobj->push_back(Pair("status", wtxid.GetHex())); // create array of matches Array tradeArray; - t_tradelistdb->getMatchingTrades(hash, senderAddress, &tradeArray); + uint64_t totalBought; + t_tradelistdb->getMatchingTrades(hash, senderAddress, &tradeArray, &totalBought); // add array to object txobj.push_back(Pair("matches", tradeArray)); From bb7e4c57fcbab54395281ce51961cf2f0309a38f Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Tue, 4 Nov 2014 22:52:40 -0800 Subject: [PATCH 19/24] latest changes --- src/mastercore.cpp | 21 +++++++++++---------- src/mastercore.h | 2 +- src/mastercore_rpc.cpp | 42 ++++++++++++++++++++++-------------------- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index cb172a7ff737..f026ddcb6fc2 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3085,7 +3085,7 @@ unsigned int n_found = 0; } // MPTradeList here -bool CMPTradeList::getMatchingTrades(const uint256 txid, string sellerAddress, Array *tradeArray, uint64_t *totalBought) +bool CMPTradeList::getMatchingTrades(const uint256 txid, unsigned int propertyId, Array *tradeArray, uint64_t *totalBought) { if (!tdb) return false; totalBought = 0; @@ -3119,25 +3119,26 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, string sellerAddress, A string address; string address1 = vstr[0]; string address2 = vstr[1]; + unsigned int prop1; + unsigned int prop2; unsigned int propBought; unsigned int propSold; uint64_t amountBought; uint64_t amountSold; - if (address1 == sellerAddress) + prop1 = boost::lexical_cast(vstr[2]); + prop2 = boost::lexical_cast(vstr[3]); + + if (prop1 == propertyId) { address = address2; - propBought = boost::lexical_cast(vstr[2]); - propSold = boost::lexical_cast(vstr[3]); - amountBought = boost::lexical_cast(vstr[4]); - amountSold = boost::lexical_cast(vstr[5]); + amountBought = boost::lexical_cast(vstr[5]); + amountSold = boost::lexical_cast(vstr[4]); } else { address = address1; - propBought = boost::lexical_cast(vstr[3]); - propSold = boost::lexical_cast(vstr[2]); - amountBought = boost::lexical_cast(vstr[5]); - amountSold = boost::lexical_cast(vstr[4]); + amountBought = boost::lexical_cast(vstr[4]); + amountSold = boost::lexical_cast(vstr[5]); } int blockNum = atoi(vstr[6]); diff --git a/src/mastercore.h b/src/mastercore.h index 166066cfe58b..c47acd1d785e 100644 --- a/src/mastercore.h +++ b/src/mastercore.h @@ -329,7 +329,7 @@ class CMPTradeList bool exists(const uint256 &txid); void printStats(); void printAll(); - bool getMatchingTrades(const uint256 txid, string sellerAddress, Array *tradeArray, uint64_t *totalBought); + bool getMatchingTrades(const uint256 txid, unsigned int propertyId, Array *tradeArray, uint64_t *totalBought); }; /* leveldb-based storage for the list of ALL Master Protocol TXIDs (key) with validity bit & other misc data as value */ diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index d5a89807e044..38f2ed6ec7b8 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -1669,23 +1669,6 @@ static int populateRPCTransactionObject(uint256 txid, Object *txobj, string filt } } - // is the sell offer still open - need more efficient way to do this - for (md_PropertiesMap::iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) - { - if (my_it->first == propertyId) //at bear minimum only go deeper if it's the right property id - { - md_PricesMap & prices = my_it->second; - for (md_PricesMap::iterator it = prices.begin(); it != prices.end(); ++it) - { - md_Set & indexes = (it->second); - for (md_Set::iterator it = indexes.begin(); it != indexes.end(); ++it) - { - CMPMetaDEx obj = *it; - if( obj.getHash().GetHex() == wtxid.GetHex() ) offerOpen = true; - } - } - } - } break; case MSC_TYPE_GRANT_PROPERTY_TOKENS: if (0 == mp_obj.step2_Value()) @@ -2083,8 +2066,9 @@ Value gettrade_MP(const Array& params, bool fHelp) Object tradeobj; Object txobj; - //get sender + //get sender & propId string senderAddress; + unsigned int propertyId = 0; CTransaction wtx; uint256 blockHash = 0; if (!GetTransaction(hash, wtx, blockHash, true)) { return MP_TX_NOT_FOUND; } @@ -2095,6 +2079,7 @@ Value gettrade_MP(const Array& params, bool fHelp) if (0<=mp_obj.step1()) { senderAddress = mp_obj.getSender(); + propertyId = mp_obj.getProperty(); } } if (senderAddress.empty()) // something went wrong, couldn't decode transaction @@ -2130,12 +2115,29 @@ Value gettrade_MP(const Array& params, bool fHelp) bool orderOpen = false; bool orderFilled = false; bool orderPartialFilled = false; - //txobj->push_back(Pair("status", wtxid.GetHex())); + // is the sell offer still open - need more efficient way to do this + for (md_PropertiesMap::iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) + { + if (my_it->first == propertyId) //at bear minimum only go deeper if it's the right property id + { + md_PricesMap & prices = my_it->second; + for (md_PricesMap::iterator it = prices.begin(); it != prices.end(); ++it) + { + md_Set & indexes = (it->second); + for (md_Set::iterator it = indexes.begin(); it != indexes.end(); ++it) + { + CMPMetaDEx obj = *it; + if( obj.getHash().GetHex() == hash.GetHex() ) orderOpen = true; + } + } + } + } + txobj.push_back(Pair("orderopen", orderOpen)); // create array of matches Array tradeArray; uint64_t totalBought; - t_tradelistdb->getMatchingTrades(hash, senderAddress, &tradeArray, &totalBought); + t_tradelistdb->getMatchingTrades(hash, propertyId, &tradeArray, &totalBought); // add array to object txobj.push_back(Pair("matches", tradeArray)); From c31699f348a76ead83c9dff2b623835908f78fb9 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Wed, 5 Nov 2014 13:39:32 -0800 Subject: [PATCH 20/24] fix up amounts in matches --- src/mastercore.cpp | 34 +++++++++++++++++++++++++--------- src/mastercore_rpc.cpp | 7 ++++++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 86f3f77028d7..9494655907ca 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3125,22 +3125,37 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, unsigned int propertyId unsigned int prop2; unsigned int propBought; unsigned int propSold; - uint64_t amountBought; - uint64_t amountSold; + uint64_t nBought; + string amountBought; + string amountSold; + string amount1; + string amount2; prop1 = boost::lexical_cast(vstr[2]); prop2 = boost::lexical_cast(vstr[3]); +printf("propertyid %d prop1 %d prop2 %d\n",propertyId,prop1,prop2); + if(isPropertyDivisible(prop1)) + { amount1 = FormatDivisibleMP(boost::lexical_cast(vstr[4])); } + else + { amount1 = FormatIndivisibleMP(boost::lexical_cast(vstr[4])); } + if(isPropertyDivisible(prop2)) + { amount2 = FormatDivisibleMP(boost::lexical_cast(vstr[5])); } + else + { amount2 = FormatIndivisibleMP(boost::lexical_cast(vstr[5])); } + // correct orientation of trade if (prop1 == propertyId) { address = address2; - amountBought = boost::lexical_cast(vstr[5]); - amountSold = boost::lexical_cast(vstr[4]); + amountBought = amount2; + amountSold = amount1; + nBought = boost::lexical_cast(vstr[5]); } else { address = address1; - amountBought = boost::lexical_cast(vstr[4]); - amountSold = boost::lexical_cast(vstr[5]); + amountBought = amount1; + amountSold = amount2; + nBought = boost::lexical_cast(vstr[4]); } int blockNum = atoi(vstr[6]); @@ -3148,12 +3163,13 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, unsigned int propertyId trade.push_back(Pair("txid", matchTxid)); trade.push_back(Pair("address", address)); trade.push_back(Pair("block", blockNum)); - trade.push_back(Pair("amountpaid", FormatDivisibleMP(amountSold))); - trade.push_back(Pair("amountbought", FormatDivisibleMP(amountBought))); + + trade.push_back(Pair("amountsold", amountSold)); + trade.push_back(Pair("amountbought", amountBought)); trade.push_back(Pair("price", FormatDivisibleMP(1))); tradeArray->push_back(trade); ++count; - totalBought=totalBought + amountBought; + totalBought=totalBought + nBought; } } } diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index 38f2ed6ec7b8..b8aa0f65f6d0 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -2079,9 +2079,14 @@ Value gettrade_MP(const Array& params, bool fHelp) if (0<=mp_obj.step1()) { senderAddress = mp_obj.getSender(); - propertyId = mp_obj.getProperty(); + if (0 == mp_obj.step2_Value()) + { + propertyId = mp_obj.getProperty(); + } } } + if (propertyId == 0) // something went wrong, couldn't decode property ID - bad packet? + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not a Master Protocol transaction"); if (senderAddress.empty()) // something went wrong, couldn't decode transaction throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not a Master Protocol transaction"); From cf37df5a509d6ce87a0f4ac73596cb5c68e398bf Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Wed, 5 Nov 2014 15:22:06 -0800 Subject: [PATCH 21/24] clean up and remove price from matches --- src/mastercore.cpp | 21 ++++++++++----------- src/mastercore_rpc.cpp | 4 +--- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 9494655907ca..39adc353919e 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -2391,11 +2391,12 @@ int mastercore_shutdown() { delete p_txlistdb; p_txlistdb = NULL; } - +printf("here1\n"); if (t_tradelistdb) { delete t_tradelistdb; t_tradelistdb = NULL; } +printf("here2\n"); if (mp_fp) { @@ -3123,8 +3124,8 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, unsigned int propertyId string address2 = vstr[1]; unsigned int prop1; unsigned int prop2; - unsigned int propBought; - unsigned int propSold; + uint64_t uAmount1; + uint64_t uAmount2; uint64_t nBought; string amountBought; string amountSold; @@ -3132,15 +3133,16 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, unsigned int propertyId string amount2; prop1 = boost::lexical_cast(vstr[2]); prop2 = boost::lexical_cast(vstr[3]); -printf("propertyid %d prop1 %d prop2 %d\n",propertyId,prop1,prop2); + uAmount1 = boost::lexical_cast(vstr[4]); + uAmount2 = boost::lexical_cast(vstr[5]); if(isPropertyDivisible(prop1)) - { amount1 = FormatDivisibleMP(boost::lexical_cast(vstr[4])); } + { amount1 = FormatDivisibleMP(uAmount1); } else - { amount1 = FormatIndivisibleMP(boost::lexical_cast(vstr[4])); } + { amount1 = FormatIndivisibleMP(uAmount1); } if(isPropertyDivisible(prop2)) - { amount2 = FormatDivisibleMP(boost::lexical_cast(vstr[5])); } + { amount2 = FormatDivisibleMP(uAmount2); } else - { amount2 = FormatIndivisibleMP(boost::lexical_cast(vstr[5])); } + { amount2 = FormatIndivisibleMP(uAmount2); } // correct orientation of trade if (prop1 == propertyId) @@ -3158,15 +3160,12 @@ printf("propertyid %d prop1 %d prop2 %d\n",propertyId,prop1,prop2); nBought = boost::lexical_cast(vstr[4]); } int blockNum = atoi(vstr[6]); - Object trade; trade.push_back(Pair("txid", matchTxid)); trade.push_back(Pair("address", address)); trade.push_back(Pair("block", blockNum)); - trade.push_back(Pair("amountsold", amountSold)); trade.push_back(Pair("amountbought", amountBought)); - trade.push_back(Pair("price", FormatDivisibleMP(1))); tradeArray->push_back(trade); ++count; totalBought=totalBought + nBought; diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index b8aa0f65f6d0..90855878cedd 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -2118,8 +2118,6 @@ Value gettrade_MP(const Array& params, bool fHelp) // everything seems ok, now add status and get an array of matches to add to the object // status - is order cancelled/closed-filled/open/open-partialfilled? bool orderOpen = false; - bool orderFilled = false; - bool orderPartialFilled = false; // is the sell offer still open - need more efficient way to do this for (md_PropertiesMap::iterator my_it = metadex.begin(); my_it != metadex.end(); ++my_it) { @@ -2137,7 +2135,7 @@ Value gettrade_MP(const Array& params, bool fHelp) } } } - txobj.push_back(Pair("orderopen", orderOpen)); + txobj.push_back(Pair("active", orderOpen)); // create array of matches Array tradeArray; From af212741dd7704748a7887410cc247d46895cc44 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Wed, 5 Nov 2014 15:55:29 -0800 Subject: [PATCH 22/24] fix crash on exit with levelDB --- src/mastercore.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index 39adc353919e..bbcaa3537e64 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -2391,12 +2391,10 @@ int mastercore_shutdown() { delete p_txlistdb; p_txlistdb = NULL; } -printf("here1\n"); if (t_tradelistdb) { delete t_tradelistdb; t_tradelistdb = NULL; } -printf("here2\n"); if (mp_fp) { @@ -3173,6 +3171,7 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, unsigned int propertyId } } } + delete it; if (count) { return true; } else { return false; } } From 64c11923d53b70f96716fa41b72c95e4734b4af8 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Wed, 5 Nov 2014 15:57:14 -0800 Subject: [PATCH 23/24] clean up unused vars --- src/mastercore.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mastercore.cpp b/src/mastercore.cpp index bbcaa3537e64..ae464af03977 100644 --- a/src/mastercore.cpp +++ b/src/mastercore.cpp @@ -3094,8 +3094,6 @@ bool CMPTradeList::getMatchingTrades(const uint256 txid, unsigned int propertyId unsigned int count = 0; std::vector vstr; string txidStr = txid.ToString(); - int block; - unsigned int n_found = 0; leveldb::Iterator* it = tdb->NewIterator(iteroptions); for(it->SeekToFirst(); it->Valid(); it->Next()) { From 951e6879a7fa53dda4a086f7e2643de3433c1d61 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Wed, 5 Nov 2014 16:05:25 -0800 Subject: [PATCH 24/24] clean help --- src/mastercore_rpc.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mastercore_rpc.cpp b/src/mastercore_rpc.cpp index 90855878cedd..dd7017854f1d 100644 --- a/src/mastercore_rpc.cpp +++ b/src/mastercore_rpc.cpp @@ -2046,12 +2046,10 @@ Value listtransactions_MP(const Array& params, bool fHelp) Value gettrade_MP(const Array& params, bool fHelp) { - // note this call has been refactored to use the singular populateRPCTransactionObject function - if (fHelp || params.size() != 1) throw runtime_error( - "gettransaction_MP \"txid\"\n" - "\nGet detailed information about a Master Protocol transaction \n" + "gettrade_MP \"txid\"\n" + "\nGet detailed information and trade matches for a Master Protocol MetaDEx trade offer \n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "\nResult:\n"