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

eth: coin ID uses and encodings (discussion) #1021

Closed
chappjc opened this issue Mar 22, 2021 · 6 comments
Closed

eth: coin ID uses and encodings (discussion) #1021

chappjc opened this issue Mar 22, 2021 · 6 comments

Comments

@chappjc
Copy link
Member

chappjc commented Mar 22, 2021

This is closely related to the issue "eth: Solidity atomic swap contract discussion", but is intended to shed light on the more broad issue of coin IDs in eth. Also the PR #979 where the initial coin ID encoding is being defined.

Coin IDs in DCRDEX

In DCRDEX (client and server), the notion of a "coin ID" is used for several purposes. Currently it is always tied to a txn, for which a confirmation count can be obtained. It can be used to identify unspent value, locate a swap contract and check confirmations of the payment to that contract, and generally refer to transactions needing confirms (no particular utxo).

Side question: In ETH, how are account balances handled w.r.t. the confirmations of the transactions that credit/debit the accounts? Specify block count or is it standard?

Uses of Coin IDs

funding coins: used to account for spendable value, verified on server when orders placed, locked on client

In eth, a regular (non-contract) account with a balance. Sufficient amount must be order qty PLUS an explicitly specified tx fee amount for executing the swap txns.

For server to validate, check balance of the encoded eth account. More specifically, for ALL of the user's orders using this account as a funding source, sum the required values, and compare to that account balance.

The client itself would need to do similar accounting when funding orders since coin locking make no sense with accounts.

Note: presumably all orders from a given user would use the same eth account.

swap contract coin: both value and tx needing confirms

In eth, a tx executing The One Swap Contract. Would encode: tx for confirmations, input data to the txn such as secret hash (and nonce, amount, dest acct, etc?). What data would be part of the swap coin ID, and which would just be part of the messages (e.g. init/audit)? Presently the contract itself is in message data, and that decoded provides secret hash and counterparty address/pkh, while value comes from the amount of that txn's output.

Or if the answer to the confirmations question indicates we don't need to monitor the transaction executing the contract, do we just check The One contract account's state data for the secret hash (the contract's map key), etc? I expect that even if this is the case, the tx that pays to contract account should be recorded regardless.

Would we encode the txn executing The One contract, and an audit would mean checking that it indeed executes the expected contract, and provides the expected "input data" for the terms of the trade?

Related comment: #1001 (comment)

change coin: see funding coins

Does NOT exist in ETH. On swap, balance of funding account is reduced by precise amount, while balance in The One contract is increased.

redeem coins: track completion of trade on confirms, can become funding coins

In eth, a tx for the user to track confs for receipt of the swap value.

Possibly no need for client to track it as funding account balance will just go up. (Similar for UTXOs where client would just eventually list those utxos as confirmed.) But other swaps paying to the same account would affect the balance too, so monitoring the swap until the redeem is confirmed would be essential it seems.

withdrawals: txn for user to check/reference

In eth, a tx for user to track confs, and inspect on an explorer to see To address, amount, etc.

@buck54321
Copy link
Member

buck54321 commented Mar 25, 2021

funding coins: Obviously there are no funding utxos in Ethereum, so what the server is interested in is the funding account address. I'm going back and forth on this, but at this point I think we need to update the order API to have a funding_account field used for ETH-like assets. Those assets themselves would not send any coins. Since this means that the server must be aware of the different protocols throughout (order validation, coin lockers), we'll need a way for the backend to signal to the server which protocol it follows. This could be done with a Backend method, e.g. (Backend).Protocol(), or we could provide a driver method or something akin to WalletInfo.

I guess adding the extra data field might end up requiring a DB upgrade too, but I suspect we're not getting out of this without a DB upgrade anyway.

swap contract coin: What we do with the coin ID here may depend on how we decide to handle txids. If we choose to go a pure-contract route with no txids sent over API (another related comment), then the swap contract coin will just be the secret hash. If we decide that we do need the txids, then it could be the concatenation of the secret hash and the txid.

Does anyone know if you can make multiple calls to a contract method in a single transaction? If that is the case, then clients should prefer to group contract calls, and we may end up needing some kind of index to identify the exact match being specified, should we decide to send txids.

redeem coins: So I guess we don't need to send this if we go the pure-contract route. Otherwise, we'll send the txid, I guess.

@chappjc
Copy link
Member Author

chappjc commented Mar 25, 2021

So we agree about funding coins being the funding account. But I think we can keep using the opaque coin ID blob. It all depends on the coin ID encoding and how we have flags change the meaning of the encoded bytes. That's the main reason I made this issue, to figure out if a single coin ID encoding is feasible for all applications or if it would be too contrived. It's not hard to imagine decodeCoinID doing a switch on the flags IMO. Ideally the Backend would know how to interpret the coin IDs and we could avoid such Protocol switching.

I think we also agree about swap contract coin. I've suggested initConfirmCount(mapKey/secredHash) in that other thread, and alluded to the possibility of cutting right to the chase and having participate and redeem do the confirmations requirement check using an reqConfs input arg... but a simple confirmation query method of the contract probably is best. My only concerns about that are:

  • unknown/possible downsides to making read-only contract method calls, which Joe has confirmed require no transaction and can be done by light clients at virtually no cost
  • unconfirmed init transactions, because presumably the state data (the Swaps map) is not updated until the init transaction is executed (when it is mined, right?), which makes both audit and confirmation checks of unconfirmed init txns impossible

Actually I think the unconfirmed issue applies to the redeem tx too. Without the txid, server can't validate an unconfirmed redeem just based on the swap contract's state data that doesn't reflect the unmined redeem, and counterparty has to wait for it to be confirmed to get the actual secret, which presently happens without confirmations. Gotta think about this... messaging the secret without the actual redeem txn might be sufficient because the parties can hash the secret and confirm it is right and that's all that matters.

@buck54321
Copy link
Member

buck54321 commented Mar 31, 2021

As of #1000, we reject zero-conf funding outputs with low fee rates. This raises a couple of questions.

  1. What is the ETH equivalent of zero-conf funding coins?
  2. How do we protect against double-spending attacks on ETH?

@chappjc
Copy link
Member Author

chappjc commented Mar 31, 2021

I think the only way to accept zero-conf funding coins with eth is to refer to a txn, not just the funding account. If there is a txn paying to their funding account that is not yet confirmed, the balance of the funding account will not have increased, and they can't place an order using that balance increase. Thus, I think we can just require confirmed funds (that update the funding account state/balance). Besides, with no split txns in ETH, that is not a problem.... unless we ever have a need to get an account balance for a certain confirmation requirement, not just 1 presumably.

@JoeGruffins
Copy link
Member

re: 0-conf

I do not believe this is capable with eth. Every transaction from an account has a nonce, just an iterated number, that prevents replay attacks: https://kb.myetherwallet.com/en/transactions/what-is-nonce/
Until a tx is mined, I believe that transaction can be changed in any way imaginable, much like bitcoin's Replace-by-Fee, with any transaction using the same nonce but a higher gas fee.

On a side note, do we check that bitcoin transactions are not Replace-by-Fee enabled? I'm guessing yes?

@JoeGruffins
Copy link
Member

Side question: In ETH, how are account balances handled w.r.t. the confirmations of the transactions that credit/debit the accounts? Specify block count or is it standard?

If I understand the question, once a tx is mined state is changed and the state machine doesn't care about number of confs. Those funds are now reflected in the account and spendable. I don't think there is a separation between value received one block ago or yesterday. So yeah, how to confirm the age of coins? Using a txid, one could give you an old txid, move those coins and do another quick transaction with newer coins, and I don't think there's a way to know the txid you have represents the current value held in the account. I think the way to be certain of number of blocks mined for a certain amount of funds is probably a contract.

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

3 participants