Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TX 21 -- desired enhancement -- placing multiple orders from same address for same currency pair #270

Closed
m21 opened this issue Oct 9, 2014 · 103 comments

Comments

@m21
Copy link

m21 commented Oct 9, 2014

I've been asked to implement MetaDex trading where orders are not restricted by this:

"An address cannot create a new sell order while that address has an active sell order with the same currencies in the same roles (for sale, desired)."

And I have. The trouble is in the Cancel. Perhaps issuing the same Trade order with same exact fields & parameters, but with the Cancel flag would do for multiple orders from the same Address.
If there was a partial sell at the price specified the rest of the order could still be canceled (or up to the amount remaining), etc.

@ghost
Copy link

ghost commented Oct 9, 2014

Is there a way to lookup/compare the original offer values versus the ones in the cancellation? This would be a straightforward path to looking up the offer and marking it as a cancel - On the same token, if there are multiple offers with the same offer values and a cancel comes in , all of the offers with the same offer values would be cancelled.

@zathras-crypto
Copy link
Contributor

My initial thoughts on this are:

  • That the business side wants support for multiple sells from the same address for same property pairs
  • That a 'cancel all' for a property pair makes this easiest to implement, meaning a sell action will cancel all offers on that property pair.

However, by adding an extra informational field on the cancel and update side of things we can thus nominate a specific sell offer to update/cancel. This extra informational field could for example be the last 8 bytes of the sell offer TXID to be updated which would push the packet size to 36 bytes - two packets for Class B or a single OP_RETURN output for Class C. This would then provide the per order update/cancellation process while supporting multiple sells per pair for an address.

Thanks
Z

@zathras-crypto
Copy link
Contributor

Also couple of notes from Skype chat:

  • Supplying all 1's for example in the TXID would serve as a cancel-all (not 0's as if it's last field they are usually zero'd in packet anyway so all req 1's is a sanity check)
  • The UPDATE kind of needs an order ID (such as TXID) to reference in order to function the same way process wise as DEx (which is a replacement model) if we are to allow same address sells per pair - address is no longer a unique identifier.

Thanks
Z

@dexX7
Copy link
Member

dexX7 commented Oct 9, 2014

There are a few other issues that were created in a context of "selecting" specific transactions. Using the transaction hash seems only reasonable and is very robust - length aside.

Depending on how it's done, it might not be as bad as it seems:


Cancel one:

Version: 0
Type: 21
Currency identifier for sale: 1 (Mastercoin)
Amount for sale: 0
Currency identifier desired: 3 (GoldCoin)
Amount desired:  0
Action: 3 (cancel offer)

Raw: 0000001500000001000000000000000000000003000000000000000003
Length: 29 byte

(note: placing the action field at the very end is flawed imho)

vs.

Version: 0
Type: 21
Action: 3 (Cancel offer)
Transaction reference: 710d10befb2a66192ec1e8a7dcf3243925e315cd7b648b3a63ba855ddd1b52c5

Raw: 0000001503710d10befb2a66192ec1e8a7dcf3243925e315cd7b648b3a63ba855ddd1b52c5
Length: 37 byte

Cancel all:

Version: 0
Type: 21
Action: 4 (Cancel all*)

Raw: 0000001504
Length: 5 byte

*A new action value isn't ambiguous and seems appropriate, given that junk data might be mistaken for a transaction reference.

Stuffing the reference with 111..11 is wasteful and feels wrong, because the inted is not to "cancel (a single) offer with txid 111..11" but something different.


Updating specific orders - or queries such as "cancel all orders with currency pair x/y" - seems like a challenge though.

Edit: actually.. it might also be an idea to stop thinking about how everything could be fit into a single transaction or action and start to use a very wide range of more specific update/delete/create operations. The transaction type field on it's own provides space for 65536 values - which makes me wonder: why bother with sub-actions at all?

@m21
Copy link
Author

m21 commented Oct 9, 2014

@marv-engine @dacoinminster comments please?

@marv-engine
Copy link

My initial comments:

  1. We should decide about and put any functionality/feature changes into the spec first, and always code to the spec rather than the other way around.
  2. We should address the issue of identifying items and come up with a general solution rather than doing it in an ad hoc manner.

@dacoinminster
Copy link
Contributor

We had a meeting about this, and we decided:

  1. Cancels must match the amount desired and amount for sale
  2. Updates will add two new fields to specify the PREVIOUS amount desired and amount for sale
  3. Cancels with the amount for sale set to zero and amount desired set to zero cancel ALL open orders for the specified currency pair
  4. There are no restrictions on how many orders can be open or of what type
  5. If there is ambiguity about which order is affected by an update or cancel, it affects the oldest order

@marv-engine
Copy link

There's a complication for identifying the sell order to cancel or update -
which amount is the amount for sale, is it what was initially offered or what's remaining after any partial matches? It shouldn't be the latter because that can change after the update/cancel is submitted but before it's processed.

I think it makes sense for it to be the value that was in the create or the most recent update tx21 message.

@zathras-crypto @m21 @faizkhan00 @dacoinminster @achamely what do you think?

@dacoinminster
Copy link
Contributor

Agree it should match the previous TX21 - not the current state of the order

@ghost
Copy link

ghost commented Oct 10, 2014

Agreed as well - the identity of the offer to act on should be the last tx21 to affect that address/currency-pair (or the original tx21)

@zathras-crypto
Copy link
Contributor

This still seems ambiguous to me.

Eg
*I list one sell for 100 #n for 200 #y - 50 #n is left in this sell
*I list another sell for 100 #n for 200 #y - 60 #n is left in this sell
*I list another sell for 100 #n for 200 #y - 20 #n is left in this sell

Which one am I cancelling and/or updating when I send in the 'cancellation' values of 100 #n and 200 #y?

If it's most recent or oldest etc, what if I want to change one of the other ones? I'm prevented from cancelling/updating all but one of the orders in current form it seems.

It strikes me as remaining ambiguous. The same transaction (cancel/update with 100 #n and 200 #y values) has three different potential outcomes on the change to my balance depending on which is updated. I understand we can set orders of precedence but we have to also make this simple for end user.

Could someone tl:dr; for me why we didn't want to reference the last 8 bytes of the tx hash, where we already have a unique sell offer identifier? We're talking about adding 16 bytes worth of fields in the proposed so it can't be tx space.

16 bytes to give #n and #y values to help us potentially locate the right offer
8 bytes (last 8 of tx hash) to give us exactly the right offer

Thanks
Z

@marv-engine
Copy link

PR #271 is ready for review and merge.

@dexX7
Copy link
Member

dexX7 commented Oct 10, 2014

Could someone tl:dr; for me why we didn't want to reference the last 8 bytes of the tx hash, where we already have a unique sell offer identifier

Which sell offer identifier are you referring to? But I agree. And I also realized thanks to your post and contrary to my initial believe a full hash is not required, given that the address of the sender acts as additional identifier. This is imho especially relevant regarding the other discussions about selecting specific offers and so on.

@marv-engine
Copy link

@zathras-crypto At the mtg yesterday I asked about doing something to/with the tx hash to get a shorter unique value (e.g. with the sender address) but no one offered this idea. I prefer explicitly using an identifier, rather than other attributes, to identify the sell offer or any other object.

Can you explain how your idea produces a unique identifier?

@dexX7
Copy link
Member

dexX7 commented Oct 10, 2014

I believe the idea is to use parts of the (completely random) hash/txid of the transaction used to publish an offer. Due to the composition with the sender's address or a reference in general (e.g. for accepting offers) this should yield sufficient collision resistance.

@dacoinminster
Copy link
Contributor

I'm fine with this route, except for one thing: we still have to write code
to handle collisions, however rare they may be. What should that code do?

On Fri, Oct 10, 2014 at 9:38 AM, dexX7 [email protected] wrote:

I believe the idea is to use parts of the (completely random) hash/txid of
the transaction used to publish an offer. Due to the composition with the
sender's address or a reference in general (e.g. for accepting offers) this
should be yield sufficient collision resistance.


Reply to this email directly or view it on GitHub
#270 (comment).

@dacoinminster
Copy link
Contributor

. . . I'd suggest that an update/cancel should affect the oldest matching
TXID. It may never happen, but it is still possible.

On Fri, Oct 10, 2014 at 11:21 AM, J.R. Willett [email protected] wrote:

I'm fine with this route, except for one thing: we still have to write
code to handle collisions, however rare they may be. What should that code
do?

On Fri, Oct 10, 2014 at 9:38 AM, dexX7 [email protected] wrote:

I believe the idea is to use parts of the (completely random) hash/txid
of the transaction used to publish an offer. Due to the composition with
the sender's address or a reference in general (e.g. for accepting offers)
this should be yield sufficient collision resistance.


Reply to this email directly or view it on GitHub
#270 (comment)
.

@dexX7
Copy link
Member

dexX7 commented Oct 10, 2014

On an UI level the user could be notified about a collision before sending the update. On a protocol level I'd say: apply update/x to oldest first. In the worst case an update which actually doesn't update anything could be sent to get a "fresh" reference.

@dexX7
Copy link
Member

dexX7 commented Oct 10, 2014

What if no specific length such as 8 byte is defined at all and one would simply provide a sufficient long piece of hash to avoid conflicts? Say I have only one open order: this is unambigious even without any reference. In the case of two, I would likely get away with providing only one byte, etc. ... this would require publishing information about the acutal length, because a string null-terminator likely doens't work here.

@dacoinminster
Copy link
Contributor

Ooooo. Interesting idea! So:

1 byte for the length of the shortened hash (however many bytes are needed
to be unique), followed by the needed bytes.

If for some reason there is still a collision (due to a reorg or UI error),
affect the oldest matching TX.

Sound good?

Apologies to Marv for sending him on a wild goose chase . . .

On Fri, Oct 10, 2014 at 11:46 AM, dexX7 [email protected] wrote:

What if no specific length such as 8 byte is defined at all and one would
simply provide a sufficient long piece of hash to avoid conflicts? Say I
have only one open order: this is unambigious even without any reference.
In the case of two, I would likely get away with providing only one byte,
etc. ... this would require publishing information about the acutal length,
because a string null-terminator likely doens't work here.


Reply to this email directly or view it on GitHub
#270 (comment).

@dexX7
Copy link
Member

dexX7 commented Oct 10, 2014

In my opinion this sounds perfect. Hopefully this is what @zathras-crypto had in mind as well. :)

@marv-engine
Copy link

Another idea -
The user or wallet creates an N-byte identifier for each new sell order. Updates & Cancels use that identifier to specify which order is the target. The identifier is fixed for the life of that sell order.

Because this identifier is address-specific, the user and wallet know what other sell orders (and identifiers) are active when the user is creating the new order. If we let the user enter an identifier for the new order, the wallet can check that it's unique among active orders for the address (and the currency id pair). If the wallet generates the identifier for the new order, it can use or hash the current timestamp as the id.

If by some chance the id is not unique when the tx21 (New) is processed, then it's marked invalid.

@dexX7
Copy link
Member

dexX7 commented Oct 10, 2014

the user and wallet know what other sell orders (and identifiers) are active when the user is creating the new order

Not necessarily. But say this doesn't matter: what's the upside?

@m21
Copy link
Author

m21 commented Oct 10, 2014

Guys, IMO it's not necessary to force the customer to track down the original trade(s), ordering, blocks, TXIDs or anything of that nature.

Consider the following scenario from the user's point-of-view here (orders are from the same address, for the same currency-pair all issued at the same effective unit price).

These commands are issued by the user in question, in the following order:

a) TRADE 50tokens for 5MSC
b) *** placeholder ***
c) TRADE 10tokens for 1MSC
d) *** placeholder ***
e) TRADE 100tokens for 10MSC
f) *** placeholder ***
g) CANCEL 60tokens for 6MSC
h) *** placeholder ***
i) UPDATE 20tokens for 2MSC TO 20tokens for 3MSC

Steps a, c, e put the tokens up for sale.
At step (g) if nothing else happened prior, the user wants to remove 60 of the currently offered 160tokens from the market.
At step (i) if nothing else happened -- the user wants to remove 20 (more) tokens from the market and re-price them.

Now, if all clear so far -- let me introduce the buyer(s) into the equation.
At step (b) someone may come in and buy what's offered up to the max offered at that time (50tokens).
At step (d) someone may come in and buy what's offered up to the max offered at that time (60tokens).
At step (f) someone may come in and buy what's offered up to the max offered at that time (160tokens).
So, depending on buyers' actions:
At step (g) CANCEL should cancel up to 60tokens if available at that time.
At step (i) UPDATE (functionally it's a CANCEL+NEW at a new price point) will cancel and re-list up to 20tokens if available at that time.

@marv-engine
Copy link

@dexX7 what I meant was:
the user and wallet know what other sell orders (and identifiers) belonging to that address are active when the user is creating the new order.

Identifiers could be reused once a sell order to no longer active.

The upside is that there's no ambiguity about identifying a sell order to be updated/cancelled. The identifier is unique for active sell orders for the address.

@marv-engine
Copy link

@m21 one reason the seller wants to be specific about which order is updated/cancelled is that the protocol's matching algorithm chooses the oldest first if there are multiples that match at the same price. So, a seller wouldn't want to lose his place as the current oldest.

@m21
Copy link
Author

m21 commented Oct 10, 2014

Can you be specific please?
Without buyers, using my example: which of the 3 TRADEs would you like to CANCEL if you do a 5token CANCEL in step (g)?

@dexX7
Copy link
Member

dexX7 commented Oct 10, 2014

Guys, IMO it's not necessary to force the customer to track ...

@m21: what if I have several offers for the same currency pair, but on different price levels?

Locating or targeting orders would be used to resolve ambiguousness (if wanted, needed). Providing a zero length reference could equal the intend to let some default logic handle the selection.

@marv-engine: only the state of "inactive" offers is certain and actions are linked to transactions - which are fully identifiable right from the start, so providing another identifier seems sort of redundant.

@marv-engine
Copy link

@dexX7 the application-provided timestamp, or user-entered N-byte string as an identifier is useful because it's a lot shorter than the tx hash, and it can be checked for collisions against a comparatively short list of the address' active orders before the tx is broadcast. Identifiers of past (inactive) offers aren't of interest and they can be ignored.

The id could also be a serial number in 2 bytes - the wallet just adds 1 to the current highest active id. If 65k isn't enough, we could use 4 bytes to support 4 billion orders per address (and per currency pair, if we want).

@m21
Copy link
Author

m21 commented Oct 16, 2014

@dacoinminster
float is sometimes a 64bit storage unit; very non-portable. We've spent days even weeks on the channel discussion all sorts of precision issues (larger than metadex).

The protocol defining the "effective price" as INT64 / INT64 gives us double the precision of a float to begin with.

I did start a conversation on precision and limits with Marv (gotta find my notes), but there are pretty low limits we run into even with 128bits.

Here's an example my my oderbook with 10-digit precision after the period:
http://pastie.org/pastes/9653677/text?key=mgcoqocgb2gq3kixbpigg

You can see that trading 1 Satoshi for 200 BTC (coins) is already impossible.
The above may need to be a separate issue: limits.

UPDATE: the spec may not have an issue, if we stick with INT64 / INT64 JR, all -- I take that back.
(It's an implementation detail.)

@m21
Copy link
Author

m21 commented Oct 16, 2014

@dacoinminster -- spec may not have an issue with precision, if we stick with INT64 / INT64 JR, all -- I take that back. So no worries.
(It's an implementation detail.)
Let's iron out the ADD/SUBTRACT, etc.

@marv-engine
Copy link

I haven't been able to keep up with the latest direction of this thread, but I have a proposal of my own which I think eliminates a lot of the complexity.

It provides a way to identify the sell order to be affected by an update or cancel, so multiple orders with the same currency pair and terms are treated separately. That's simpler than trying to figure out how to aggregate multiple tx21's into a single order.

We can implement Update and Cancel as tx21 sub-actions or as new txtypes. I don't think it matters.

Update/Cancel msg will include the following items to identify the target tx21:

  • blocknumber
  • blocktime
  • txseq in the block

MasterCore will confirm the correct seller (sender) address and txtype=21. The combination of these 5 items should make it highly unlikely that a re-org will cause the wrong tx21 to be affected.

If the sender address and txtype in the specified tx aren't right, then the Update/Cancel is invalid.

Update can:

  • change # for sale
    • change amount for sale
    • adjust # desired to maintain the original calculated unit price (as close as possible)
  • change # desired
    • adjust calculated unit price for same amount for sale
  • change both # for sale and # desired
    • effectively a new sell order with all new terms, replaces the existing terms

Cancel can:

  • affect a specified order
  • affect all orders for a particular currency pair

@dexX7
Copy link
Member

dexX7 commented Oct 16, 2014

txseq in the block

I assume you mean transaction position within block? There is no need for block time and strictly seen also no need for an address, because height + position is already unique. But in general: this is imperior to a selection via transaction hash, because block height and transaction position are mutable in the case of block reorganziations.

It's worth to read the recent discussion - the trend is in favor of merging orders by price with commands such as ADD and SUBTRACT. ;)

@marv-engine
Copy link

A big disadvantage of using tx hash is its length. How often does a re-org
happen?

Keeping the orders separate requires much simpler logic than trying to
determine when and how they should be merged.

On Thursday, October 16, 2014, dexX7 [email protected] wrote:

txseq in the block

I assume you mean transaction position within block? There is no need for
block time and strictly seen also no need for an address, because height +
position is already unique. But in general: this is imperior to a selection
via transaction hash, because block height and transaction position are
mutable in the case of block reorganziations.

It's worth to read the recent discussion - the trend is in favor of
merging orders by price with commands such as ADD and SUBTRACT. ;)


Reply to this email directly or view it on GitHub
#270 (comment).

Marv Schneider
VP, User Experience/Product Usability
Engine, Inc.
[email protected]

@dexX7
Copy link
Member

dexX7 commented Oct 16, 2014

Regarding blocks: it's "often" the case that two miners find a new block at a somewhat similar time whereby only one is accepted by the network and the other is orphaned. An overview (which doesn't necessarily reflect all occurrences of such an event):

https://blockchain.info/orphaned-blocks

Given how Master Core is constructed, selecting orders by transaction hash piece or height + transaction position would probably be equally easy to implement. Edit: re: length: it should usually require less length of hash piece than height + position.

requires much simpler logic

That's arguable. If it is indeed possible to select orders by price without introducing all kinds of edge cases, then it's simply "match oldest order first" and "subtract from newest order first" for a specific price level, see #270 (comment) for an example.

@m21
Copy link
Author

m21 commented Oct 17, 2014

@dexX7 , all
ADD is pretty clear at this point for everybody: requires the 2 currencies & 2 amounts.
SUBTRACT = also requires 2 currencies & 2 amounts. If the amounts given exceed what's offered by the user on the market -- this command could function as CANCEL-ALL-AT-GIVEN-PRICE which you asked for above. (This convention follows some Dex commands - sell/buy all if amount given exceed what's available).
SUBTRACT with amounts given as 0s could CANCEL-ALL for the currency pair in question (from this user).
What do you think?

(UPDATE is no longer in the picture = could be added later at its own block height if atomic REPRICE-RELIST command is needed, too confusing at this moment).

@dexX7
Copy link
Member

dexX7 commented Oct 17, 2014

SUBTRACT with amounts given as 0s could CANCEL-ALL for the currency pair in question (from this user).

Please not. There is no need for workarounds imho. I suggest a clean CANCEL-ALL which affects the given currency pair as well as a CANCEL-EVERYTHING which removes every open offer. It's also cheaper in terms of space requirements, because there wouldn't be the need for zero'ed amounts or currency pairs.

If the amounts given exceed what's offered by the user on the market -- this command could function as CANCEL-ALL-AT-GIVEN-PRICE ...

One might have the intend to remove some amount, but during broadcast and confirmation there could be fills, resulting in an amount that exceeds what's offered. The initial intend probably doesn't change in this case, so I tend to "yes, let's do it this way".

@m21
Copy link
Author

m21 commented Oct 17, 2014

I am fine with your method as well Dexx.

Currently I have:
enum ActionTypes { INVALID = 0, NEW = 1, UPDATE = 2, CANCEL = 3 };
(renaming NEW to ADD & CANCEL to SUBTRACT at UI level) -- which new ones spec/protocol Types are you asking for again?
4 = CANCEL-ALL -- is that it?
And allowing CANCEL=3 to Cancel up to the max possible if the amount specified in the command exceeds what's currently on the market?

@dexX7
Copy link
Member

dexX7 commented Oct 17, 2014

CANCEL should remove all offers for a given currency pair and price.
CANCEL-ALL should remove all offers for a given currency.
CANCEL-EVERYTHING should remove any offer.

Now that I think of it: would it make sense to further differentiate between CANCEL-ALL-AT-PRICE and CANCEL-ALL-WITH-CURRENCY-PAIR?

@m21
Copy link
Author

m21 commented Oct 17, 2014

Sure Dexx. Suggest as many Cancel Action Types as possible. Assign numbers to them, easier to discuss.
I prefer that (the intent is made clear in the TX packet) to convoluted "if amount is 0 = it means This-Type-of-Cancel, otherwise That-Type..." etc.

@dexX7
Copy link
Member

dexX7 commented Oct 17, 2014

Well, let's see what the others think. But since we are speaking about using prices: it seems rather unhandy to use ADD ... INVERTED-CURRENCY-PAIR which yields a SELL-OF-INVERTED-CURRENCY-PAIR .... while the actual intend is to BUY ... CURRENCY-PAIR. Or is this rather an issue that should be taken care of by the user interface? I believe so, but still wondering.

@dexX7
Copy link
Member

dexX7 commented Oct 17, 2014

@m21: small note regarding INT64/INT64 -- since the default behavior as far as I know is to round down in such a case, you may take a special look at #170 (comment) which "ruled" divisions should round up.

Time 0: A1 offers 20 Indiv1 coins for 10 Indiv2 coins (unit price .5)
Time 1: A2 offers 12 Indiv2 coins for 17 Indiv1 coins (unit price ~1.4, reciprocal ~.6)
Result: 17 Indiv1 coins from A1 to A2 and 9 Indiv2 coins from A2 to A1

@marv-engine
Copy link

I ran some queries against the current set of 16000+ MP transaction records in the Omniwallet database to get a feel for how many bytes of the txhash are needed to get a unique string. Here's what I found:

First, the number of txhashes starting with each value of 0-F ranges from 961 to 1079, so the first char is pretty evenly distributed. The distribution is about the same for each of the next 6 characters (and others, I expect), as well.

There are no duplicates when comparing the first 6 characters in the txhashes.

Here's the number of collisions I found starting at the beginning of the txhash: by address, by address for tx51 issuer, and across the whole set of 16000+ transactions:

# of chars by address tx51 issuer whole set
1 1195 34 13236
2 267 10 7147
3 59 2 1413
4 9 0 114
5 2 0 7
6 0 0 0

So, we should have confidence that in the vast majority of cases we'll be able to use the first 8 characters of the txhash to uniquely identify a tx21 belonging to a particular address (or any tx, for that matter). I chose 8 to increase the percentages in our favor, but it will likely be fewer than that.

Put another way, the chance of a collision is (1/16) ^ N:

  • N=6 chars: 0.000000059604645
  • N=8 chars: 0.000000000232831

It's up to the front end to uniquely identify the tx21 to be affected. If there are 2 or more that match the substring, then the tx would be invalid.

It is reasonable to identify the tx21 to be affected without having to come up with unit price matching fuzzy logic.

@dexX7
Copy link
Member

dexX7 commented Oct 18, 2014

Marv, you are awesome. Having data on this is superb!

I chose 8 to increase the percentages in our favor, but it will likely be fewer than that.

Ahh, now I see: you took (hash, [address, [tx 51]]) into consideration and compared against any other hash. We can get away with much less, because we'd only need to match against someone's own transactions instead of any transaction ever made. The set to compare against can further be reduced by removing transactions that are no orders and even further by removing all transactions/orders that are no longer active: when I'd wish to publish an update/cancel/whatever for one of my active orders, then all I'd need to compare against are other active orders that I made in the past - because there is never the case where I'd update/cancel/x an order of someone else.

chose 8 to increase the percentages in our favor

I'm not sure, if you suggest to use a fixed number - my idea was to adjust the length based on what's required to form an unique piece. Historical transactions are known, whether the set is solely based on no-longer-active orders of a single entity or any transaction ever made - this makes it possible to determine a sufficient length with 100 % confidence of no collision by testing a piece with length n against the set and increasing the length until there is no collision.

If there are 2 or more that match the substring, then the tx would be invalid.

I object: a "take oldest/newest first" policy is very simple, yet effective and may reduce the set significantly. If this indeed resolves a conflict or reduce the required minimum length to satisfy the actual intend can be determined when creating a transaction, because full knowledge of historical transactions is given in this case, too.

It is reasonable to identify the tx21 to be affected without having to come up with unit price matching fuzzy logic.

I'm very curious, if @m21 is able to provide a solid solution for the "group and merge orders on a logical level based on price" approach due to the problems that may occure by using price as identifier, but if this is the case, then I believe it would offer greater flexibility.

But that aside: I'm all in for adopting an "identify and select transaction by XX" mechanism for the traditional DEx or crowdsales - or let me rephrase: to use this mechanism to what you were looking for in #261: Allow users to specify the specific terms of an offer they are responding to and this could also be used to solve the underlying issue discussed in #132: Grace period after manually closing a crowdfund which I started for similar reasons.

@dacoinminster
Copy link
Contributor

Guys, we specifically asked Craig and David to weigh on this issue last week, and they have ruled out TX hashes and the like. We are going with add/subtract logic. Additional cool cancel commands are fine if you want them, but further discussion of tx hashes and such are probably not going to be productive.

@marv-engine - I think you had to leave early before that point in the meeting, but it was a pretty clear decision from the top which way we would go.

The only thing left to do is codify the format in the spec. It may already be coded at this point, in which case, we need to match that.

@marv-engine
Copy link

It seems I wasn't around for some critical details about all this, so it makes sense for someone who has all the details (@dacoinminster?) to write the spec PR. Feel free to incorporate any parts of my now outdated PR #271 if they're useful.

@dacoinminster
Copy link
Contributor

No problemo. I think I've got a handle on what needs to happen. @m21 is this coded already? I don't want you to have to change your work . . .

@m21
Copy link
Author

m21 commented Oct 21, 2014

JR, all, roughly yes coded like this (currency is 32bit, amounts are 64bit as always):

ADD given currency-pair & amount_got, amount_desired
SUBTRACT given currency-pair & amount_got, amount_desired (to create same ratio as in the ADD)

This part is up to you:

  1. When subtracting - I am removing orders from my internal segmented list - should I be removing the oldest or the youngest order first?
  2. May be nice to give users some way to SUBTRACT (CANCEL) ALL at that effective price - perhaps requiring huge amounts, perhaps given 0, perhaps a new ActionType.
  3. Per above discussions with Dexx -- perhaps it would be nice to give the users a broader CANCEL-ALL-for-that-currency-pair-no-matter-what-the-price-is command (preferably another new action type).

@zathras-crypto
Copy link
Contributor

Just throwing it out there again:

amount_got, amount_desired (to create same ratio as in the ADD)

If we're creating ratios (unit prices) why not specify them explicitly - amount_for_sale, unitprice

@zathras-crypto
Copy link
Contributor

Discussing lots on Skype - there is some good discussion and I see the flaw with unit prices (sell 1000 MSC for 1 satoshi total) though I consider perhaps a 0.00000001 minimum unit price.

My main concern is this, the ratios (unit prices) we're coming up with are so precise that we will not be able to match them with future ADD/SUBTRACTS, example:

[9:42 AM] zathrasc:
Mike sells 523 SPT#3 for 10 MSC
This is a ratio (unit price) of 0.000000533

Now, please craft any transaction that can
a) ADD any number of SPT#3 to this order other than a multiple of 533
b) SUBTRACT any number of SPT#3 from this order other than a multiple of 533

@dacoinminster
Copy link
Contributor

I think that behavior is fine, personally, as long as the user can tell the difference between the prices of two similar orders in the UI

@dacoinminster
Copy link
Contributor

Sorry - I didn't answer Michael's 3 questions:

This part is up to you:

  1. When subtracting - I am removing orders from my internal segmented list - should I be removing the oldest or the youngest order first?

Remove youngest first makes sense to me.

  1. May be nice to give users some way to SUBTRACT (CANCEL) ALL at that effective price - perhaps requiring huge amounts, perhaps given 0, perhaps a new ActionType.

The UI can always cancel-all at an effective price with a huge subtract, so I don't think we need a different command for this.

  1. Per above discussions with Dexx -- perhaps it would be nice to give the users a broader CANCEL-ALL-for-that-currency-pair-no-matter-what-the-price-is command (preferably another new action type).

I'll try to put a flag in the spec which means cancel-all for a given currency pair.

@dacoinminster
Copy link
Contributor

Actually @m21, there is no "newest" or "oldest" coins, since we are now merging orders. There is only one order at any given unit price.

I think your question is actually whether we should change the datestamp when adding/subtracting coins. I think the answer is "no we should not".

dacoinminster added a commit to dacoinminster/spec that referenced this issue Oct 22, 2014
@dacoinminster
Copy link
Contributor

Pull request #276 is ready to go. Any further discussion goes there, I think, so I'm closing this issue.

@dexX7
Copy link
Member

dexX7 commented Oct 22, 2014

Actually @m21, there is no "newest" or "oldest" coins, since we are now merging orders. There is only one order at any given unit price.

Internally there is, I believe. See my comment here for an example, because I was wondering about this, too: #270 (comment)

@dexX7 dexX7 mentioned this issue Oct 24, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants