-
Notifications
You must be signed in to change notification settings - Fork 15
Issued Asset Fees #27
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
base: main
Are you sure you want to change the base?
Conversation
|
Can you squash all the commits that affect the same file, add commit descriptions, and a PR description saying what this is and where it is used? |
|
Some spelling/typos: |
delta1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass, a few minor things
Add controller descritpion Add publication descritpion Add test vectors fix typos
Fix path
|
In 5f0dbbd: trailing whitespace on most lines typo There are three instances of typo You say "The total transaction fee calculated..." but then give a formula that appears to be about the minimum relay feerate. You don't specify how to calculate the total transaction fee. You also don't specify whether multiplication should use a floor or ceiling if rates are non-integral. In "Issued asset fees" you say that the maximum fee rate (I guess you mean exchange rate, since the units for this are sats/asset?) is 92233720368. But in practice this is then multiplied by the actual fee rate (in sats/weight). What happens in case of overflow? You mention MAX_MONEY and say that "currently in BlockAssembler the total value of fee outputs 'will not' exceed MAX_MONEY" but what does this actually mean? Is |
Fixed.
I've changed the explanation of this to correct some things and make it clearer. I've renamed the asset 'fee rate' to asset fee rate multiplier to emphasise that this value just scales the existing policy asset minimum rates as applied to mempool and relay policy.
I initially used a double for the issued asset fee rate multiplier, but then changed for a fixed precision integer (I believe this to be a more robust approach, in the same way rates currently specified in sat/vbyte use a fixed precision of 1000), so all arithmetic is in unit_64. ASSET_RATE_SCALE_FACTOR sets the precision of the issued asset fee rate multiplier. Config and RPC input/output uses floating points.
The minRelay rate or min mempool rate would have be bigger than ASSET_RATE_SCALE_FACTOR. But a check for this should be added. You mention MAX_MONEY and say that "currently in BlockAssembler the total value of fee outputs 'will not' exceed MAX_MONEY" but what does this actually mean? This was in relation to this PR ElementsProject/elements#1476
Yes, it just defines the precision for the issued asset fee rate multiplier. |
|
In 9641693: This introduces the terms "input" and "output" without defining them, and still says nothing about how overflow in feerates is handled.
It would just need to be greater than one. But my question was not about min relay, but about how these transactions' feerates are computed so that transactions can be ordered in the mempool (AFAICT this is never mentioned in this document). |
|
Sorry for the delay in replying. I've gone through and changed the logic of how the rate multiplier is applied, changing it to computing an 'effective rate' for a transaction with an issued asset fee which can then be used in place of the policyAsset rate for both meeting relay/mempool minimums and mempool ordering.
I've removed that, and specified clearly the format of values used in configuration and RPC arguments and how it is then converted to the fixed precision integer.
Yes, you are right. I've added a maximum value parameter for the rate multiplier.
The 'effective rate' for an issued asset fee transaction is now used for both comparison with minimums and also for mempool ordering. Statements explaining this have been added to the text. |
elip-0202.mediawiki
Outdated
|
|
||
| For fees outputs in an issued asset, the fee rate (in units/vbyte) will be scaled by a fee rate multiplier to determine an 'effective rate'. This effective rate is then used in place of the policyAsset fee rate for the purpose of meeting relay and mempool minimums and for mempool ordering. | ||
|
|
||
| E.g. An issued asset is USDT. The current conversion rate between USDT and LBTC (<code>policyAsset</code>) is 100:1 (i.e. 100 USDT to one LBTC) the issued asset fee rate multiplier would then be set to 0.01 (i.e. the fee paid in USDT will be multiplied by 0.01 for comparison with LBTC fees). If the USDT asset is used for the fee in any transaction, it should pay 100 times in USDT base units the fee rate that would have applied in LBTC (the policyAsset). If the current minimum fee rate for mempool and relay is 1 sat/vbyte in LBTC (i.e. the policy asset fee rate), then the effective minimum fee rate for this asset would be 100 units/byte. The minimum fee output value required for a transaction of size e.g. <code>vsize = 257</code> transaction to be relayed would be: <code>257 x 1 x 100 = 25700</code> base units of the USDT asset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 4b5eeb2:
I don't undersztand this example. For one thing, it seems cherry-picked to have an integer ratio; what if the actual exchange rate is 105:100 say? For another thing, it seems to normalize the fee to USDT rather than L-BTC. If there are multiple fee outputs with different assets then which one is chosen to normalise to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A simple integer ratio was chosen to make the arithmetic of this introductory example easier, but maybe it's too abstract. A more realistic exchange rate can be used, which illustrates precision/rounding issues.
The fee is paid in USDT, and the monetary value of that fee must equal (or exceed) the monetary value of the fee currently required in LBTC. The multiplier converts the monetary value of an amount of USDT to an amount of LBTC.
Another attempt:
"E.g. An issued asset is USDT. The current accepted exchange rate between USDT and LBTC (the policyAsset) is $114,171.23 to 1 LBTC. The issued asset fee rate multiplier for this ratio is then set to 1/114,171.23 = 0.00000876 (rounded to a precision of 1e-8). For a transaction that uses the USDT asset for the fee, the fee rate (in units/vbyte) multiplied by this number must be greater than or equal to the minimum fee rate (in sat/vbyte) applied in LBTC.
If the current minimum relay fee rate is 1 sat/vbyte in LBTC, then the minimum fee rate required in USDT would be 1/0.00000876 = 114156 units/vbyte (rounded up to the nearest integer). To relay this transaction, a client will determine the fee rate in the USDT asset, multiply it by 0.00000876 to calculate the effective rate and then verify it is greater than or equal to 1 sat/vbyte. "
In the case of multiple fee outputs, in principle, an effective fee (the fee amount scaled by the multiplier for each different asset) can be calculated for each fee output and then an effective fee rate for the transaction determined. However, it may be simpler to require wallets to use a single asset and output, and only consider the first one.
elip-0202.mediawiki
Outdated
|
|
||
| A new configuration option will be added to enable any node that is creating blocks to publish the assets, rates (and optionally destination) they are applying to their own policy. This information will be encoded into an <code>OP_RETURN</code> output for each accepted asset and included in the coinbase transaction for blocks that they create every <code>N</code> blocks (where <code>N</code> is specified in the configuration). Wallets and users will then be able to read and decode the latest assets and rates being applied by block creators and use this information for determining fees when creating transactions. For ease in retrieving this, all nodes will cache the latest rates which can be accessed via a new RPC. This publication method assumes that all block creators are applying the same assets and rates to their policy, which they would need to agree upon. | ||
|
|
||
| In order for the acceptance of issued asset and rates for fees to be reliable and predictable, all block creators and bridging nodes (and all relaying nodes) should be applying the same policy with the same list of accepted assets and rates. To coordinate this and apply changes to a large number of nodes is impractical, which may be required regularly as exchange rates change. To provide an alternative method for remotely modifying the accepted assets and rates, individual nodes can be configured to accept updates via an on-chain transaction - this way all block creator and bridge nodes can have their applied policy updated simultaneously without requiring direct access to the RPC interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 4b5eeb2:
This paragraph doesn't make sense after the previous paragraph. It says that the blocksigners will encode exchange rates in OP_RETURN outputs from coinbases, then describes an "alternate" method in which exchange rates are accepted "via an on-chain transaction" with no further details given. Is this the same thing as the OP_RETURN mechanism you just described? It is contrasted to "requiring direct access to the RPC interface" but you've only described using the RPC interface to access the current rates, not for setting them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general this seems really overcomplicated. Ultimately the blocksigners are deciding what transactions are being put into blocks in what order. Why do we need a complex mechanism for people to set their mempool policy to something different? (If that is what's happening here -- I am really having trouble reading this. I think you could probably remove around 75% of the words in the Overview and Design sections without loss.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This paragraph doesn't make sense after the previous paragraph. It says that the blocksigners will encode exchange rates in
OP_RETURNoutputs from coinbases, then describes an "alternate" method in which exchange rates are accepted "via an on-chain transaction" with no further details given. Is this the same thing as the OP_RETURN mechanism you just described?
These are two separate features. The first paragraph introduces a method for publishing the assets and rates accepted by a node. The second is a separate method for remotely setting the assets and rates accepted by a node without direct access to it, as an alternative to configuring node directly.
It is contrasted to "requiring direct access to the RPC interface" but you've only described using the RPC interface to access the current rates, not for setting them.
It states above "This can be set as part of the node configuration, specifying the assetID, the relative rate multiplier (and optionally the coinbase destination for the fee collection by the block creator) before initialization, or set dynamically at runtime via a new RPC option."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general this seems really overcomplicated. Ultimately the blocksigners are deciding what transactions are being put into blocks in what order. Why do we need a complex mechanism for people to set their mempool policy to something different? (If that is what's happening here -- I am really having trouble reading this. I think you could probably remove around 75% of the words in the Overview and Design sections without loss.)
The issue is that in practice 1) All block signers, and bridging nodes, and any other node that is relaying, must all be applying the same policy in order for the system to be usable. 2) This policy may be required to be updated and changed regularly.
Say for example there is a large change in the price of bitcoin and it is decided the fee rate multiplier for USDT needs to be changed, or the federation agrees to accept a new asset for fees. In Liquid, this would require updating the config of all functionary and bridging nodes, and redeploying everything. This is a proposed method to enable the remote updating of policy without requiring access to the nodes or any require external dependencies (like e.g. configuring a URL to read the asset policy from).
It was maybe a mistake to try and include all of this in a single ELIP (with a single overview), but I will separate it out and reduce it.
This ELIP describes proposed features for Elements that enable the use of issued assets for transaction fees in addition to the policy asset (pegged asset).
This will enable an Elements blockchain/sidechain to use any issued asset for the transaction fees, with the assets used and rates applied being agreed and set by the block creators. Changes are proposed to relay/mempool policy and block creation.
Several mechanisms are proposed to set, synchronise and publish the assets and rates that are accepted by the block producers.