Skip to content

Commit

Permalink
MetaDEx: Add MetaDEx_INSERT
Browse files Browse the repository at this point in the history
  • Loading branch information
zathras-crypto committed May 1, 2015
1 parent 64fde48 commit bcc43c2
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 100 deletions.
58 changes: 10 additions & 48 deletions src/mastercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1685,55 +1685,17 @@ int input_mp_offers_string(const string &s)
blocktimelimit = atoi(vstr[i++]); // metadex: index of tx in block
txidStr = vstr[i++];

if (OMNI_PROPERTY_BTC == prop_desired)
{
const string combo = STR_SELLOFFER_ADDR_PROP_COMBO(sellerAddr);
CMPOffer newOffer(offerBlock, amountOriginal, prop, btcDesired, minFee, blocktimelimit, uint256(txidStr));

if (my_offers.insert(std::make_pair(combo, newOffer)).second)
{
return 0;
}
else
{
return -1;
}
}
else
{
assert(10 == vstr.size());

left_forsale = boost::lexical_cast<uint64_t>(vstr[i++]);

CMPMetaDEx new_mdex(sellerAddr, offerBlock, prop, amountOriginal, prop_desired,
btcDesired, uint256(txidStr), blocktimelimit, (unsigned char) minFee, left_forsale );

XDOUBLE neworder_price = (XDOUBLE)amountOriginal / (XDOUBLE)btcDesired;

if (0 >= neworder_price) return METADEX_ERROR -66;

md_PricesMap temp_prices, *p_prices = get_Prices(prop);
md_Set temp_indexes, *p_indexes = NULL;

std::pair<md_Set::iterator,bool> ret;

if (p_prices) p_indexes = get_Indexes(p_prices, neworder_price);

if (!p_indexes) p_indexes = &temp_indexes;
{
ret = p_indexes->insert(new_mdex);

if (false == ret.second) return -1;
}

if (!p_prices) p_prices = &temp_prices;

(*p_prices)[neworder_price] = *p_indexes;

metadex[prop] = *p_prices;
if (OMNI_PROPERTY_BTC == prop_desired) {
const string combo = STR_SELLOFFER_ADDR_PROP_COMBO(sellerAddr);
CMPOffer newOffer(offerBlock, amountOriginal, prop, btcDesired, minFee, blocktimelimit, uint256(txidStr));
if (my_offers.insert(std::make_pair(combo, newOffer)).second) { return 0; } else { return -1; }
} else {
assert(10 == vstr.size());
left_forsale = boost::lexical_cast<uint64_t>(vstr[i++]);
CMPMetaDEx new_mdex(sellerAddr, offerBlock, prop, amountOriginal, prop_desired,
btcDesired, uint256(txidStr), blocktimelimit, (unsigned char) minFee, left_forsale );
if (MetaDEx_INSERT(new_mdex)) { return 0; } else { return -1; }
}

return 0;
}

// seller-address, property, buyer-address, amount, fee, block
Expand Down
101 changes: 50 additions & 51 deletions src/mastercore_mdex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,79 +314,78 @@ bool MetaDEx_compare::operator()(const CMPMetaDEx &lhs, const CMPMetaDEx &rhs) c
else return lhs.getBlock() < rhs.getBlock();
}

bool mastercore::MetaDEx_INSERT(CMPMetaDEx objMetaDEx)

This comment has been minimized.

Copy link
@dexX7

dexX7 May 2, 2015

Quick note: this should be const CMPMetaDEx& objMetaDEx, because otherwise a clone/copy of the object is created, which isn't necessary.

{
// Create an empty price map (to use in case price map for this property does not already exist)
md_PricesMap temp_prices;
// Attempt to obtain the price map for the property
md_PricesMap *p_prices = get_Prices(objMetaDEx.getProperty());

// Create an empty set of metadex objects (to use in case no set currently exists at this price)
md_Set temp_indexes;
md_Set *p_indexes = NULL;

// Prepare for return code
std::pair <md_Set::iterator, bool> ret;

// Attempt to obtain a set of metadex objects for this price from the price map
if (p_prices) p_indexes = get_Indexes(p_prices, objMetaDEx.effectivePrice());
// See if the set was populated, if not no set exists at this price level, use the empty set that we created earlier
if (!p_indexes) p_indexes = &temp_indexes;

// Attempt to insert the metadex object into the set
ret = p_indexes->insert(objMetaDEx);
if (false == ret.second) return false;

// If a prices map did not exist for this property, set p_prices to the temp empty price map
if (!p_prices) p_prices = &temp_prices;

// Update the prices map with the new set at this price
(*p_prices)[objMetaDEx.effectivePrice()] = *p_indexes;

// Set the metadex map for the property to the updated (or new if it didn't exist) price map
metadex[objMetaDEx.getProperty()] = *p_prices;

return true;
}

// pretty much directly linked to the ADD TX21 command off the wire
int mastercore::MetaDEx_ADD(const std::string& sender_addr, uint32_t prop, int64_t amount, int block, uint32_t property_desired, int64_t amount_desired, const uint256& txid, unsigned int idx)
{
int rc = METADEX_ERROR -1;

// MetaDEx implementation phase 1 check
// Ensure that one side of the trade is MSC/TMSC (phase 1 check)
if ((prop != OMNI_PROPERTY_MSC) && (property_desired != OMNI_PROPERTY_MSC) &&
(prop != OMNI_PROPERTY_TMSC) && (property_desired != OMNI_PROPERTY_TMSC)) {
return METADEX_ERROR -800;
}
(prop != OMNI_PROPERTY_TMSC) && (property_desired != OMNI_PROPERTY_TMSC)) return METADEX_ERROR -800;

// store the data into the temp MetaDEx object here
// Create a MetaDEx object from paremeters
CMPMetaDEx new_mdex(sender_addr, block, prop, amount, property_desired, amount_desired, txid, idx, CMPTransaction::ADD);
XDOUBLE neworder_buyersprice = new_mdex.effectivePrice();

if (msc_debug_metadex1) file_log("%s(); buyer obj: %s\n", __FUNCTION__, new_mdex.ToString());

// given the property and the price find the proper place for insertion

if (0 >= neworder_buyersprice) {
// do not work with 0 prices
return METADEX_ERROR -66;
}
// Ensure this is not a badly priced trade (for example due to zero amounts)
if (0 >= new_mdex.effectivePrice()) return METADEX_ERROR -66;

// Match against existing trades, remainder of the order will be put into the order book
if (msc_debug_metadex3) MetaDEx_debug_print();

// TRADE, check matches, remainder of the order will be put into the order book
x_Trade(&new_mdex);

if (msc_debug_metadex3) MetaDEx_debug_print();

// plain insert
if (0 < new_mdex.getAmountForSale()) { // not added nor subtracted, insert as new or post-traded amounts
md_PricesMap temp_prices, *p_prices = get_Prices(prop);
md_Set temp_indexes, *p_indexes = NULL;
std::pair<md_Set::iterator, bool> ret;

if (p_prices) {
p_indexes = get_Indexes(p_prices, neworder_buyersprice);
}

if (!p_indexes) p_indexes = &temp_indexes;

ret = p_indexes->insert(new_mdex);

if (false == ret.second) {
// Insert the remaining order into the MetaDEx maps
if (0 < new_mdex.getAmountForSale()) { //switch to getAmountRemaining() when ready
if (!MetaDEx_INSERT(new_mdex)) {
file_log("%s() ERROR: ALREADY EXISTS, line %d, file: %s\n", __FUNCTION__, __LINE__, __FILE__);
return METADEX_ERROR -70;
} else {
// TODO: think about failure scenarios
// FIXME
if (update_tally_map(sender_addr, prop, -new_mdex.getAmountForSale(), BALANCE)) // subtract from what's available
{
// TODO: think about failure scenarios
// FIXME
update_tally_map(sender_addr, prop, new_mdex.getAmountForSale(), METADEX_RESERVE); // put in reserve
// TODO: think about failure scenarios // FIXME
if (update_tally_map(sender_addr, prop, -new_mdex.getAmountForSale(), BALANCE)) { // move from balance to reserve
update_tally_map(sender_addr, prop, new_mdex.getAmountForSale(), METADEX_RESERVE);
}

PriceCheck("Insert", neworder_buyersprice, new_mdex.effectivePrice());

if (msc_debug_metadex1) file_log("==== INSERTED: %s= %s\n", xToString(neworder_buyersprice), new_mdex.ToString());
if (msc_debug_metadex1) file_log("==== INSERTED: %s= %s\n", xToString(new_mdex.effectivePrice()), new_mdex.ToString());
if (msc_debug_metadex3) MetaDEx_debug_print();
}

if (!p_prices) p_prices = &temp_prices;

(*p_prices)[neworder_buyersprice] = *p_indexes;

metadex[prop] = *p_prices;
}

rc = 0;

if (msc_debug_metadex3) MetaDEx_debug_print();

return rc;
}

Expand Down
2 changes: 1 addition & 1 deletion src/mastercore_mdex.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ int MetaDEx_ADD(const std::string& sender_addr, uint32_t, int64_t, int block, ui
int MetaDEx_CANCEL_AT_PRICE(const uint256&, uint32_t, const std::string&, uint32_t, int64_t, uint32_t, int64_t);
int MetaDEx_CANCEL_ALL_FOR_PAIR(const uint256&, uint32_t, const std::string&, uint32_t, uint32_t);
int MetaDEx_CANCEL_EVERYTHING(const uint256& txid, uint32_t block, const std::string& sender_addr, unsigned char ecosystem);

bool MetaDEx_INSERT(CMPMetaDEx objMetaDEx);
void MetaDEx_debug_print(bool bShowPriceLevel = false, bool bDisplay = false);
}

Expand Down

4 comments on commit bcc43c2

@dexX7
Copy link

@dexX7 dexX7 commented on bcc43c2 May 2, 2015

Choose a reason for hiding this comment

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

For some reason this commit triggers a failure in the test plan, because this cancel fails:
https://github.com/dexX7/mastercore-rpc-tests/blob/master/test_meta_dex_plan.py#L1021

It's caused by a price mismatch, which was introduced by the trade that happened right before the cancel operation:
https://github.com/dexX7/mastercore-rpc-tests/blob/master/test_meta_dex_plan.py#L994

Here is the log with the relevant parts, where "correct" refers to the test run, which doesn't fail, based on a build of one commit before this one, and "faulty" refers to the test run, which fails, based on this commit:

It's known that there are issues with the numbers, but this is what makes it complicated now. So maybe you have an idea, and it would be great to know, whether you are certain, if this commit is fine?

@dexX7
Copy link

@dexX7 dexX7 commented on bcc43c2 May 2, 2015

Choose a reason for hiding this comment

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

As far as I can see in the old version neworder_buyersprice is inserted, while in the new version new_mdex.effectivePrice() is inserted.

In the old version, neworder_buyersprice equals the price the offer had before the trade.
In the new version, new_mdex.effectivePrice() equals the price the offer has after the trade.

So if I'm not completely mistaken, this is correct and expected behavior, and the failure is caused, because the original unit price isn't honored.

@dexX7
Copy link

@dexX7 dexX7 commented on bcc43c2 May 2, 2015

Choose a reason for hiding this comment

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

First, rather messy, take on honoring the original price, build upon this branch:

bitcoin/bitcoin@bcc43c2...dexX7:wip-oc-0.10-mdex-prices-dirty

RPC fields have to be adjusted, and I haven't tested, whether persistence works, but I really wanted to test it, and it passes the tests.. :)

@zathras-crypto
Copy link
Owner Author

Choose a reason for hiding this comment

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

In the new version, new_mdex.effectivePrice() equals the price the offer has after the trade.

That's right yep, I felt it was better to fix the CMPMetaDEx object so it always returned the original price.

First, rather messy, take on honoring the original price, build upon this branch

Had a quick skim through this - looks awesome thanks dude, will spin it up when I'm back after the weekend

Please sign in to comment.