Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6fe1604
New branch - add trade history
zathras-crypto Nov 4, 2014
e319740
Initial MPTradeList class
zathras-crypto Nov 4, 2014
4cd8cee
initial t_tradelistdb setup
zathras-crypto Nov 4, 2014
04e531f
initial record trade function
zathras-crypto Nov 4, 2014
d52af25
add tradedb debugging global
zathras-crypto Nov 4, 2014
9be4e4d
minor build fixes
zathras-crypto Nov 4, 2014
9818067
leveldb stats/prints
zathras-crypto Nov 4, 2014
a1d0e0e
add recordtrade & mscrpc 7
zathras-crypto Nov 4, 2014
2b885cc
working recordTrade
zathras-crypto Nov 5, 2014
f88696b
reorg protection
zathras-crypto Nov 5, 2014
301e728
Add values in to recordtrade
zathras-crypto Nov 5, 2014
9b45f2b
Merge branch 'mscore-0.0.9' of github.com:mastercoin-MSC/mastercore i…
zathras-crypto Nov 5, 2014
1aed41f
add RPC for gettrade_MP
zathras-crypto Nov 5, 2014
1e5ee2f
gettrade_MP call initial
zathras-crypto Nov 5, 2014
7ef27ea
getMatchingTrades
zathras-crypto Nov 5, 2014
dec1a1c
more work on gettrade_MP
zathras-crypto Nov 5, 2014
92fce2e
matching trades and RPC work
zathras-crypto Nov 5, 2014
e0b54a4
RPC fixes to populateRPCTransactionObject
zathras-crypto Nov 5, 2014
ef56f88
add totalBought vars
zathras-crypto Nov 5, 2014
bb7e4c5
latest changes
zathras-crypto Nov 5, 2014
fc2b334
Merge branch 'mscore-0.0.9' of github.com:mastercoin-MSC/mastercore i…
zathras-crypto Nov 5, 2014
c31699f
fix up amounts in matches
zathras-crypto Nov 5, 2014
cf37df5
clean up and remove price from matches
zathras-crypto Nov 5, 2014
af21274
fix crash on exit with levelDB
zathras-crypto Nov 5, 2014
64c1192
clean up unused vars
zathras-crypto Nov 5, 2014
951e687
clean help
zathras-crypto Nov 6, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions src/mastercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -151,6 +152,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()
Expand Down Expand Up @@ -2291,6 +2293,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";
Expand Down Expand Up @@ -2388,6 +2391,10 @@ int mastercore_shutdown()
{
delete p_txlistdb; p_txlistdb = NULL;
}
if (t_tradelistdb)
{
delete t_tradelistdb; t_tradelistdb = NULL;
}

if (mp_fp)
{
Expand Down Expand Up @@ -3078,6 +3085,170 @@ unsigned int n_found = 0;
return (n_found);
}

// MPTradeList here
bool CMPTradeList::getMatchingTrades(const uint256 txid, unsigned int propertyId, Array *tradeArray, uint64_t *totalBought)
{
if (!tdb) return false;
totalBought = 0;
leveldb::Slice skey, svalue;
unsigned int count = 0;
std::vector<std::string> vstr;
string txidStr = txid.ToString();
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
// 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 address;
string address1 = vstr[0];
string address2 = vstr[1];
unsigned int prop1;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imho it's more readable, if declaration and initialization are combined in this case (and the others), because you're using them just a few lines later anyway.

unsigned int prop2;
uint64_t uAmount1;
uint64_t uAmount2;
uint64_t nBought;
string amountBought;
string amountSold;
string amount1;
string amount2;
prop1 = boost::lexical_cast<unsigned int>(vstr[2]);
prop2 = boost::lexical_cast<unsigned int>(vstr[3]);
uAmount1 = boost::lexical_cast<uint64_t>(vstr[4]);
uAmount2 = boost::lexical_cast<uint64_t>(vstr[5]);
if(isPropertyDivisible(prop1))
{ amount1 = FormatDivisibleMP(uAmount1); }
else
{ amount1 = FormatIndivisibleMP(uAmount1); }
if(isPropertyDivisible(prop2))
{ amount2 = FormatDivisibleMP(uAmount2); }
else
{ amount2 = FormatIndivisibleMP(uAmount2); }

// correct orientation of trade
if (prop1 == propertyId)
{
address = address2;
amountBought = amount2;
amountSold = amount1;
nBought = boost::lexical_cast<uint64_t>(vstr[5]);
}
else
{
address = address1;
amountBought = amount1;
amountSold = amount2;
nBought = boost::lexical_cast<uint64_t>(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));
tradeArray->push_back(trade);
++count;
totalBought=totalBought + nBought;
}
}
}
}
delete it;
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 value = strprintf("%s:%s:%u:%u:%lu:%lu:%d", address1, address2, prop1, prop2, amount1, amount2, blockNum);
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__);
}
}

// delete any trades after blockNum
int CMPTradeList::deleteAboveBlock(int blockNum)
{
leveldb::Slice skey, svalue;
unsigned int count = 0;
std::vector<std::string> 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);
}

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)
{
Expand Down Expand Up @@ -3178,6 +3349,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;


Expand Down
43 changes: 43 additions & 0 deletions src/mastercore.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,48 @@ typedef struct
}
};

/* leveldb-based storage for trade history - trades will be listed here atomically with key txid1:txid2 */
class CMPTradeList
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably goes beyond the scope of this PR:

I suggest to move those stuff into mastercore_persistence.h and mastercore_persistence.cpp.

{
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 tWritten;
unsigned int tRead;

public:
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;
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__);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was printf used intentionally or should this line end up in the log?

}

~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);
int deleteAboveBlock(int blockNum);
bool exists(const uint256 &txid);
void printStats();
void printAll();
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 */
class CMPTxList
{
Expand Down Expand Up @@ -402,6 +444,7 @@ namespace mastercore
{
extern std::map<string, CMPTally> mp_tally_map;
extern CMPTxList *p_txlistdb;
extern CMPTradeList *t_tradelistdb;

typedef std::map<uint256, CMPPending> PendingMap;

Expand Down
2 changes: 2 additions & 0 deletions src/mastercore_dex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ const XDOUBLE desprice = (1/buyersprice); // inverse
}

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(), 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
Expand Down
Loading