{"action":"created","issue":{"url":"https://api.github.com/repos/OmniLayer/omnicore/issues/73","labels_url":"https://api.github.com/repos/OmniLayer/omnicore/issues/73/labels{/name}","comments_url":"https://api.github.com/repos/OmniLayer/omnicore/issues/73/comments","events_url":"https://api.github.com/repos/OmniLayer/omnicore/issues/73/events","html_url":"https://github.com/OmniLayer/omnicore/issues/73","id":84157742,"number":73,"title":"Exodus purchases, DEx payments, crowdsales unconfirmed transactions","user":{"login":"dexX7","id":5836089,"avatar_url":"https://avatars.githubusercontent.com/u/5836089?v=3","gravatar_id":"","url":"https://api.github.com/users/dexX7","html_url":"https://github.com/dexX7","followers_url":"https://api.github.com/users/dexX7/followers","following_url":"https://api.github.com/users/dexX7/following{/other_user}","gists_url":"https://api.github.com/users/dexX7/gists{/gist_id}","starred_url":"https://api.github.com/users/dexX7/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dexX7/subscriptions","organizations_url":"https://api.github.com/users/dexX7/orgs","repos_url":"https://api.github.com/users/dexX7/repos","events_url":"https://api.github.com/users/dexX7/events{/privacy}","received_events_url":"https://api.github.com/users/dexX7/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/OmniLayer/omnicore/labels/feature%20discussion","name":"feature discussion","color":"d4c5f9"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":16,"created_at":"2015-06-02T19:00:45Z","updated_at":"2015-06-03T22:37:17Z","closed_at":null,"body":"Over the last days I tried to make up my mind about how BTC related actions can be nicely integrated into Omni Core, because right now BTC doesn't really fit into the model.\r\n\r\nThere are a few points I'd like to discuss.\r\n\r\n1) Exodus purchases and DEx payments are BTC payments, but they are handled differently.\r\n\r\nIt's probably not too far fetched to consider Exodus purchases and DEx payments as something similar, at least design wise. There are some significant differences though:\r\n\r\n - A DEx payment requires a marker (Exodus output, or \"om\" bytes), while an Exodus purchase, strictly seen, doesn't. This is only relevant for testnet and regtest mode [extra question: why do use a different destination, which is not the marker here?], because on mainnet the Exodus marker is also the fundraiser destination. However, it's worth to notice that a BTC payment to `moneyqMan7uh8FqdCA2BV5yZ8qVrc9ikLP` can count as Exodus purchase, even without explicit marker.\r\n\r\n - A DEx payment is only considered as such, if the transaction does not embed any payload, i.e. the transaction has a marker, but isn't a class A, B or C transaction. In contrast, the Exodus purchase logic is executed in any case, even if there is another \"action\" bound to the transaction (such as a simple send, as seen on mainnet).\r\n\r\n - There can only be one Exodus purchase per transaction, namely the highest amount sent to Exodus is used to determine the purchased amount, while at the same time, there can be several DEx payments, and for each output on it's own the DEx payment logic is executed (whether it's more than one payment to the same seller, or multiple sellers).\r\n\r\nI would really like, if we come up with an approach, which is more consistent, so that Exodus purchases and DEx payments might be handled by the same module. Given that we can't change history, we have to build a model around those limitations, or change the rules for the future.\r\n\r\n2) Exodus purchases are crowsale purchases\r\n\r\n - That's a very interesting point in my opinon: what exactly is an Exodus purchase? Isn't it a crowdsale, with 10 % early bird bonus per week, with a block height based deadline at block 255365, and a time based deadline at 1377993600 (2013-09-01 00:00:00 UTC)? ;)\r\n\r\n - The unfortunate point here is that the deadline block 255365 and the deadline timestamp 1377993600 don't refer to the same point in time, and block 255365 actually has a timestamp of 2013-09-01 00:04:34 UTC.\r\n\r\nThis alone isn't a deal breaker, because we might introduce the concept (code wise) of an actual deadline (in terms of: end of crowdsale), and a deadline for the bonus calculations. For all tx 51 crowdsales those deadlines are time based, and equal.\r\n\r\n3) Floating-point numbers and rounding directions ...\r\n\r\n - The Meta-DEx and STO transactions are completely unaffected by any floating point issues, and use plain integer math. Results are either rounded up, or down (i.e. `1.00001 -> 2 or 1`).\r\n\r\n - The tx 51 crowdsale logic uses integer math for intermediate calculations, but has a concept of fixed precision, and results are divided by `1000000000000L` and `100000000` to limit the number of digits. I'm not yet sure, what this means in practise, and whether this implies a loss of precision.\r\n\r\n - Unfortunally the DEx payment logic, as well as the Exodus purchase logic use `double` for the calculations, and results are \"rounded half up\" (i.e. `0.49 -> 0, 0.50 -> 1`).\r\n\r\nI started to test the tx 51 crowdsale logic with Exodus fundraiser values, and at least for some input, the results differ by one satoshi. I have no idea, whether this applies to mainnet purchases, or if we may get away in practise with using the crowdsale logic to handle Exodus purchases.\r\n\r\nIt would be incredibly awesome, if we could get away with it, because then we could get rid of any special \"Exodus purchase logic\", and simply consider Exodus purchases as crowdsale purchases.\r\n\r\n---\r\n\r\nMy intention is to find a model, where BTC payments fit in nicely, while thinking ahead, where we have to deal with BTC based crowdsales, and maybe a traditional DEx v2 (e.g. #253: Adaptive DEx fees based on purchased amount, #184: Creating MSC/BTC options via DEx fees to the seller).\r\n\r\nI'm a bit lost, because I'm not sure, how to continue from here, but I think finding answers to the following questions might help:\r\n\r\n1. Do we want to continue to consider DEx payments only as such, if the transaction doesn't embed a payload?\r\n\r\n2. How are BTC based crowdsales going to be handled? Might it be possible to participate in several BTC based crowdsales in one transaction, similar to DEx payments, where each output may be a participation/purchase/payment?\r\n\r\n3. Would it be possible to get rid of floating point numbers for DEx payments and Exodus purchases?\r\n\r\n\r\nCode wise, I'd like to turn `parseTransaction()` into a plain \"extract the payload, determine sender and reference\" function, and execute any actions (DEx payments, Exodus purchases) somewhere else.\r\n\r\nIn light of the above, we currently have to determine:\r\n\r\n - (a) does the transaction have a marker? (relevant for class A, B, C, DEx payments - not relevant for Exodus purchases)\r\n - (a) which encoding class is used? (relevant for class A, B, C)\r\n - (b) who is the sender? (relevant for for class A, B, C, DEx payments, Exodus purchases)\r\n - (b) who is the reference? (relevant for for class A, B, C)\r\n - (b) does the transaction have a payload? (relevant for DEx payments)\r\n - (b) if so, what is the payload? (relevant for for class A, B, C)\r\n - (b) what is the transaction fee? (relevant for DEx accepts)\r\n - (c) does the transaction have a money output [1EXoDus, moneyqMan]? (relevant for Exodus purchases)\r\n - (c) what is the highest value sent to the money output? (relevant for Exodus purchases)\r\n\r\nAnd we have to handle:\r\n\r\n - Exodus purchases (requires b, c)\r\n - DEx payments (requires a, b, c)\r\n - BTC crowdsales at some point (requires a, b, c)\r\n - standard payload-transactions (requires a, b, c)\r\n\r\nAs far as I can see we may split `parseTransaction()` and tackle (a), (b), (c) seperately:\r\n\r\n - (a) Determine, whether the transaction has a marker, or better: determine the encoding class (cheap)\r\n - (b) Extract payload, determine sender, reference, and transaction fees (expensive)\r\n - (c) Get highest money output [...] (cheap)\r\n\r\nIterating over outputs is smoking fast and \"cheap\", while retrieving inputs isn't, thus \"expensive\". There is probably no performance penalty, even if we check the existence of a marker twice, or collect output values for class A, and do another loop for Exdus purchases.\r\n\r\nI further imagine we may persist the data gained by (b), in particular: `txid`, `tx fee`, `encoding class`, `sender`, `payload`, `reference` (is that all?), so we don't have to do the expensive parsing more than once. This is something that is going to be very handy for unconfirmed transactions, or a no-txindex mode as well. It raises the following additional questions:\r\n\r\n4. If we are going to parse unconfirmed transactions, then we can only estimate in which block a transaction may end up. This isn't a huge problem, and we may persist the data we have, and update the entry (i.e. add block height, transaction position within block), once the transaction confirms. However, the problem I'm not sure about: the parsing logic explicitly uses a block height to determine, whether P2SH outputs are allowed, if class C transactions are enabled. We may assume that an unconfirmed transaction ends up in a block, which has a height greater than the current chain height, but it's still fuzzy during switch-over times. Say for example: current chain height is 356003, and class C transactions are activated at height 356005. Should an unconfirmed transaction be processed as class C transaction or not? Or maybe both cases might be handled, i.e. as class B and as class C? If so, where is the cutoff? 3 blocks before the switch-over, 5 blocks, 10 blocks, ...?\r\n\r\n5. If `parseTransaction` processes transactions only once, and the data is persisted, then it's reasonable to properly persist information about Exodus purchases, and DEx payments, as well. This is already done to some degree, but not completely. Ideally this should be usable for BTC crowdsales as well. Persisting *any* output of transactions with marker/money output surely works, but it's an absurd overkill. So my last question: what is the minimum data do we need to persist, to cover that as well? I think a small overhead is fine, i.e. it's acceptable, if we store data, which *could* be related to Exodus purchases or DEx payments (even if it turns out it's not), but we probably don't have to persist data, which certainly won't be used for Exodus purchases [...], say for example, because the Exodus period is already over.\r\n\r\nIdeally, I'd like to be able to start with a clean state, and then iterate over the persisted data, and end up with a similar state, as if the data wasn't retrieved from a DB, but extracted from transactions, as currently done.\r\n\r\nSorry in advance for the very long post, but especially finding answers to the last two questions would be very, very helpful for me."},"comment":{"url":"https://api.github.com/repos/OmniLayer/omnicore/issues/comments/108633670","html_url":"https://github.com/OmniLayer/omnicore/issues/73#issuecomment-108633670","issue_url":"https://api.github.com/repos/OmniLayer/omnicore/issues/73","id":108633670,"user":{"login":"dexX7","id":5836089,"avatar_url":"https://avatars.githubusercontent.com/u/5836089?v=3","gravatar_id":"","url":"https://api.github.com/users/dexX7","html_url":"https://github.com/dexX7","followers_url":"https://api.github.com/users/dexX7/followers","following_url":"https://api.github.com/users/dexX7/following{/other_user}","gists_url":"https://api.github.com/users/dexX7/gists{/gist_id}","starred_url":"https://api.github.com/users/dexX7/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dexX7/subscriptions","organizations_url":"https://api.github.com/users/dexX7/orgs","repos_url":"https://api.github.com/users/dexX7/repos","events_url":"https://api.github.com/users/dexX7/events{/privacy}","received_events_url":"https://api.github.com/users/dexX7/received_events","type":"User","site_admin":false},"created_at":"2015-06-03T22:37:17Z","updated_at":"2015-06-03T22:37:17Z","body":"> I don't really get that mate - some (I'd guess a majority) of existing sends to moneyman will not have an Exodus marker \r\n\r\nAhh, sorry, this changes everything. All my previous posts were based on the assumption those purchases actually have an Exodus marker *and* Money output.\r\n\r\n> Scenario B is simpler in my book and I don't really see a huge value to using\r\n\r\nI guess my only argument against it is how DEx payments are handled, otherwise I agree."}}