-
Notifications
You must be signed in to change notification settings - Fork 80
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
Removing/Fixing/Encrypting monero's timelocks #78
Comments
I'm currently cautiously for the removal of the timelock field. In no case would I recommend adding encrypted timelocks in current form. |
Yes, it makes sense to remove the timelock field and not to re-introduce it in encrypted form until we know what kind of precision is needed for a relevant use case. |
I've long disliked the current |
Just wondering, and this isn't a reason to keep it, but are there any practical objections to take into account, e.g. tools like explorers expecting the timelock field? |
I think it makes sense to keep the field in any existing RPC interfaces, as unlock times did (on rare occasion) exist for old blocks. So, there wouldn't be a compatibility problem. But, the RPC documentation should be updated to reflect the fact that the value will be fixed for all blocks after a certain point. And, care must be taken not to introduce an identically named field with alternate semantics later, as that could be a recipe for serious problems in existing clients (the clients could, of course, alter their interpretation of the field based on height, but that approach seems more likely to introduce errors). |
We used the timelocks as a way to verify the amount in the donation fund aeonix/aeon#215. So not totally useless, yet also still very confusing how to use it. Would be better to just lock for |
Rather than removing, there should be a minimum timelock that actually
makes practical sense, and that should be enforced by consensus. This would
be preferable to removing time locks entirely, and less preferable than
encrypting them.
…On Thu, May 20, 2021 at 7:28 AM yorha-0x ***@***.***> wrote:
We used the timelocks as a way to verify the amount in the donation fund
aeonix/aeon#215 <aeonix/aeon#215>. So not
totally useless, yet also still very confusing how to use it. Would be
better to just lock for n blocks rather than so many different behaviors.
If there is a timestamp preferred better to have a separate function
lock_time lock_blocks. Then no confusion.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#78 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AD2ZD7XYECDIJQTZMZPD4CLTOUE65ANCNFSM4S2NKZAA>
.
|
I think the issue wouldn't be whether the feature has a possible use, but whether that use justifies the overall code complexity (and also, relatedly, whether removing it likely increases long-term complexity due to likelihood of future re-introduction). Proving wallet balance via timelocks doesn't seem terribly compelling to me, one can achieve a similar end by simply executing periodic send-to-self transactions and publishing a viewkey. I suppose one can argue that timelocks actually improve privacy in this scenario, as they allow the daemon to reject guaranteed timelocked transactions, a database of which could be assembled for analysis, similar to mining pool payout data (note this argument also applies to encrypted timelocks). Atomic swaps could require timelocks, but, to my knowledge, a lot of other pieces would have to fall into place for such a scenario to arise (i.e. no current atomic swap proposals use them on the Monero chain, depending instead on the alternate chain's timelock implementation). |
Unlock times have another drawback: they don't play well with deterministic ring member selection (see Issue #84). Since any output could potentially be locked, if you deterministically select a locked output to be a decoy, then you have to rewind tx building to try a new ring member generation seed. That alone isn’t catastrophic, but binning makes it a big problem. What if the local outputs around the output you want to spend are all locked? There might not be enough decoy outputs available to make a bin with the real spend in it. This opens a serious attack vector. There are a few solutions:
|
Effective? |
Hidden timelocks are hidden, there are no attack vectors. They would be enforced by range proofs. |
Current StatusDiscussion on what to do with Monero's current timelock feature is ongoing. In the last MRL meeting, there seemed to be some support for deprecating the feature in either the hard fork after next, and/or in the hard fork that would bring the next major tx protocol change (such as Lelantus/Seraphis/Triptych). Deprecation is supported because of the feature's potential to introduce privacy issues, and its lack of compelling use cases. There also seems to be support that if a compelling use case is known that utilizes the feature, then it could be brought back (or kept). In the rest of this post, I'll:
Pros/Cons of Deprecating/Keeping/EncryptingDeprecatingPros
Cons
Keeping as is (& enforcing sensible minimum as proposed here)Pros
Cons
EncryptingPros
Cons
Known use casesProof of unspent fundsAs highlighted above, timelocks can be (and have been) used to have an entity prove they have unspent funds. The prover constructs a tx where the amount of funds are locked in an output until block X, then the prover provides the tx key for the transaction before block X to a verifier. Also highlighted above, a prover could instead re-construct tx's and provide tx keys (or a view key) on request, without needing to lock outputs at all. However, this has a privacy issue where publicly revealed outputs are more likely known spent via this method (e.g. you had this much Monero then, and likely re-sent that output to yourself in this tx = link from this tx to prior tx = known spent output on chain). Subscription modelThis is a creative idea with some known privacy/UX/technical challenges shared by @moneromooo-monero in #monero-dev. Let's say a user wants to sign up for a subscription service, has all the Monero up-front ready to go for the service, wants the option to pay monthly, and wants the option to cancel the subscription at any time. A user could sign (and not broadcast) a number of transactions that each have 2 inputs. 1 input is a normal output, and the other input in each transaction is an output that is locked until the start date of each month's billing cycle. The user could then send all the transactions over to the service provider. The service provider could then broadcast each transaction at the start of each billing cycle. Before each transaction is broadcast, the user has the option to spend the normal output in all the transactions sent to the service provider, which would effectively render the pre-signed transactions impossible to broadcast to the network, thereby "canceling" the subscription. The privacy issues with this approach are:
UX challenges:
An alternative way of supporting a subscription model would be for a wallet to support an "auto-pay" feature that would send out payments to intended recipients when the wallet is running. Extreme budgeting/exec payoutsSimilar to the concept of "vesting" and/or restricted stock, you could send an output to someone that does not allow them to use it until a later date. However, unlike restricted stock, the sender can't reclaim the the funds after sent. Misunderstood non-use cases for Monero's timelocksIn the latest MRL meeting and in ensuing conversation, there was also some confusion over the use cases that Monero's current timelocks have (in atomic swaps/payment channels), so summarizing what I've surmised since then: Monero's timelocks as currently designed are limited to niche use cases, and are not useful for atomic swaps and payment channels AFAIU. The critical ingredient for swaps/channels is the ability for a recipient to claim the output before the timelock expires, and if not, the output is refunded to the sender. However, Monero's timelocks do not enable this. Monero's timelocks strictly lock an output for a specified period of time, preventing the recipient from spending the output until the timelock expires. Atomic Swaps@iamamyth appears correct in saying the current swap implementation only relies on Bitcoin's HTLCs, and not Monero's timelocks. The protocol uses adaptor signatures to work around Monero timelock limitations. From the COMIT paper:
Also from Daniel over at COMIT:
Payment ChannelsDLSAG: Non-Interactive Refund Transactions For Interoperable Payment Channels in MoneroThis would essentially be a fundamental change to Monero's tx protocol that would allow for refundable transactions, and would need a hard fork to support. Additionally, it's what introduces the concept of hidden timelocks in the first place. Basically, as I understand it, timelocks as currently constructed are not useful for the payment channels proposed in this paper without a separate hard fork that would allow for someone to claim an output before the timelock expires. PayMo: Payment Channels For Monero
The basic idea behind time-lock puzzles is that a recipient would take a pre-determined amount of time to solve the puzzle off-chain, such that they can spend the output with the solution to the puzzle. It's a workaround to simulate the expected "refund" mechanism of timelocks, the mechanism that Monero's timelocks don't presently support. EDIT: modified the "keep as is" option to "keep as is (& enforce a sensible minimum)" |
@j-berman For the subscription model, this approach may yield some insight: |
Subscription model makes no sense - no subscription I've ever had locks X amount of payments ahead of time. |
The point is - how can you have scheduled payments that can be canceled (i.e. without pre-paying all months) in Monero? The method he described is one of the few available methods, even if not very appealing UX. |
I agree that the subscription use case makes very little sense: The subscriber needs to record which transaction to broadcast in order to cancel the subscription, meaning there must be client-side support for subscription tracking and cancellation. If the client must perform such bookkeeping, it seems easier for it to simply record addresses and frequencies of subscriptions, and auto-pay at the appropriate time. The following is not, and should not be considered, investment advice: I think the "vesting" concept strains credulity, as vesting schemes involve selling an issuer's contractual right in a common enterprise. There's no common enterprise here, and minting Monero has a cost, so why would anyone deliberately lock it away? The act of locking itself introduces a negative return, which isn't really the case with unvested stock. |
Features should reflect real world habits and use cases. No need for complicated UX to solve a nonissue - if you have the funds for a yearly subscription upfront you usually get a discount to pay in full. This is one instance where the market decides. |
Ok... academically, it is our responsibility to enumerate theoretical use cases. After enumerating them, then you can assess practicality and usability. Which you have been doing, but I want to be clear that @j-berman is not in the wrong for discussing subscriptions. |
I understand, but no one sets aside a year worth of payments upfront. Otherwise they'd just pay in full. The idea of recurring payments is interesting, but I don't think locking up funds for future payments is the solution. |
I think you're missing an important downside to timelocks: They require recipients to check the timelock status of received funds. I've seen cases where service providers fail to implement such checks and end up with effectively unspendable funds. |
To be clear, I'm also in favor of deprecating Monero's timelocks as is. I think the privacy/safety benefits far outweigh the potential niche use cases. I'm just trying to give as much weight as possible to the counter-arguments. I figure it's best to be cautious in deprecating a feature. Perhaps we could give it another month or so, and if no compelling counter-arguments emerge, we could more officially pencil it in for deprecation in a later hard fork (not this hard fork, but the one after, or the one with the tx protocol change). Most seem strongly in favor of removing it when it's brought up for discussion in #monero-research-lab/#monero-dev as well. In any case, I also agree the subscription model described (and "vesting" concept described) is (are) probably not useful in practice. Perhaps the ideas may inspire other ideas and seemed worth sharing to be comprehensive. You could in theory combine the concepts to have a "cancelable" payout schedule for whatever purpose, however, I believe the core of the privacy/UX challenges of that use case remain, and there are probably better ways to support that use case anyway. I would agree that delayed cancelable payouts (with significant privacy/UX challenges) probably not compelling enough to support keeping the timelock feature when weighed against the cons. So far it seems the "proof of unspent funds" feature may be the most compelling use case for keeping Monero's timelocks as is, though I personally feel the alternative methods of achieving this use case today are suitable. Fleshing out some alternative methods of achieving this use case: Simply provide a tx key for a single new on-chain txA prover submits a new tx to themselves with an amount they want to prove, then provides a verifier with the tx key/address pair. In @yorha-0x 's case for example, I'm not seeing why not simply say to the prover: "on future date X, please send yourself a tx containing the amount of funds you're in control of, and give us the tx key to verify." The drawback to this approach versus using a timelock is that a verifier can't be certain that the prover doesn't spend the output after the tx entered the chain, and before some later date. But is that really necessary? As far as holding an entity accountable, I don't see why there is practical value to a verifier in ensuring the prover remains in control of the funds for some small period after the date the output was constructed. I also don't see major institutions (such as exchanges) locking up outputs for meaningful periods of time for the timelock use case to be useful. get_reserve_proof / check_reserve_proofThis method allows a prover to prove control of unspent funds without an on-chain tx, and allows the verifier to know exactly when the outputs are spent in the future. It's offered by the reference wallet and is documented here and explained further here. Copied from
Basically the proof is composed of all (or < amount >'s worth of) the unspent outputs in a wallet, the key images for those outputs, key image signatures to prove the outputs correspond to the key images, and shared secrets to know the outputs were sent to a given address. The drawback (or pro, depending on context I guess) with this approach is that a verifier will know exactly when the outputs are spent in the future. There are some (imperfect) mitigations to this drawback, but I feel it would be out of scope of this issue to get deep into it. ConclusionI don't think the timelock adds much practical value compared to alternative methods of proving unspent funds. |
That is good. Timelock proof of funds is one use case but that is confusing because it is not the intended use. The reserve proof is better. Optionally privacy for spent outputs could be added. I can believe vesting would be a useful tool in what @j-berman says. Proving you have a vested holding in monero for a set duration of time in order to perform some role. |
Regarding the get_reserve_proof method and the drawbacks, it seems that if you were being audited you would first consolidate you inputs and then go through a churning process if you didn't want the reserve proof to impact you past/future privacy. I've seen no compelling case for keeping timelocks. |
I keep most of my stack timelocked at all times to force myself to hodl and protect against the $5 wrench attack. I agree the interface is clunky but I would prefer to keep the functionality. |
Hi I have to express my opinion because I think it would be an important loss for Monero if this frozen transaction feature was removed. I will describe two use cases which are very useful to me. First use case - tax law. Second use case - bankruptcy law. Please don't remove this feature. Even if the fee for frozen transaction was 100 times higher, I would still be using it. Converting Monero to Bitcoin in order to freeze Bitcoin is much more expensive. And I need Monero privacy features. I really need this feature. |
I'm not a lawyer, but this sounds dubious. There are fiat-denominated term deposits which work in a similar way and I'm pretty sure the depositor is still considered to be the owner although they can't withdraw the funds. In any case, helping you avoid paying taxes/debts is definitely not something that would be considered a legitimate use case when deciding to deprecate the "time-lock" feature. |
I'm just saying what law is in my country. I don't say that this law is everywhere. I'm also not 100% sure that this is true so I'm not telling the name of my country, because I don't want that someone go to jail if I'm mistaken and I don't want to have fiscal control, but I'm using time locked transactions and I'm not paying taxes legally. And I'm convinced that this is not tax avoidance or debt avoidance. In my country it is commonly believed that this is fair and not immoral and not unfair. |
Has there been any notable increase in usage of timelocks, or is the feature just as niche as when this issue was first posted? Have some of the discussed usecases moved off-chain? From what I've seen discussion has basically stopped around the topic for the time being. I believe the discussion around timelocks should go for a second round, to determine whether it would benefit Monero to leave it alone, remove it, or change it in a way that alleviates some of the issues raised and allows us to implement some of the things the original timelocks were unsuited for. |
After studying the decoy selection algorithm in The effect of choosing M elements of D elements according to some distribution without replacement, then choosing N elements from those M elements uniformly at random has the effect of distorting the distribution of your N picks towards a uniform random distribution. What this means for users is that sender-privacy is slightly degraded depending on how noticeable this statistical effect is. To this, one could respond with a reasonable question: "Why not just change that one specific wallet implementation?" Certain solutions have different downsides, but all downsides could disappear if all outputs on-chain before a certain height are usable for decoy selection or known to be unusable ahead of time. In other words, making solid non-fingerprinting decoy selection implementations is much, much easier if time-locked outputs are not something that we have to worry about. Let's say that we forked/changed relay rules to ban unlock times in future transactions. Assuming that we still honor the unlock times of past transactions, we obviously still need to account for timelocked transactions in future decoy selection algorithms. However, since we know that only ~0.01% of transactions used It is not currently possible to know which outputs are unusable before/during decoy selection without adding more database tables |
@jeffro256 - thanks for the summary, ie: "What this means for users is that sender-privacy is slightly degraded depending on how noticeable this statistical effect is." My understanding is that time locked transactions are currently very limited in use. In terms of the actual privacy implications for the network and transactions currently, is there a way to quantify this? For example, of x% of transactions implicated, we see a privacy degradation of y? |
I assume the privacy implications right now are negligible. The question is what will happen if someone, knowing this issue, decides to start spamming the network with time locked outputs for some time period |
@dimalinux Yes you would have to be the wallet's node and if you created a ton of time-locked outputs and the user makes an RPC request which contains all locked outputs except for one, there's a near guarantee that that user owns that output.
I haven't done any kind of analysis like that unfortunately. |
I just finished doing an analysis like that. I'm using data on transactions since the last hard fork (August 2022) until the first week of this year (2024). The number of non-coinbase transactions with custom unlock times is:
These transactions make up about 0.036% of the 10.38 million transactions on the blockchain in this period. Remember that when Privacy impactI performed the same analysis for some of the unlock_times that I did for nonstandrad fees to evaluate the impact on the privacy of users who are creating transactions with these nonstandard unlock times. The Positive Predictive Value (PPV) is the probability that the real spend can be guessed. Please read my Discussion Note: Formula for Accuracy of Guessing Monero Real Spends Using Fungibility Defects for more info about how an adversary can attempt to guess the real spend when a wallet is producing nonstandard transactions.
The probability of guessing the real spend is as high as 94% and as low as 34%. With ring size 16, the probability of guessing the real spend randomly when the probability is equal is 1/16 = 6.25%. Numbers revised Feb 14, 2024 21:00 UTC. In a previous version I accidentally excluded some transactions. |
I know most of the discussion is regarding Monero-style timelocks, but I'd like to bring up the possibility of implementing Bitcoin-style timelocks. For those unaware, nLockTime prevents a signed transaction from being accepted into a block before time/blockheight nLockTime would enable Monero-first atomic swaps, simple & robust payment channels (even a Lightning Network clone, maybe?), and other layer-2 systems. nLockTime has much fewer privacy issues than Monero's system, and yet is much more powerful. There are still some privacy considerations, but I believe they could be overcome at relatively little cost. I just wanted to potentially start a discussion on this, so I won't go into possibly-unncessary details on that. |
Related to monero-project/research-lab#78 Added a relay rule that enforces the `unlock_time` field is equal to 0 for non-coinbase transactions. UIs changed: * Removed `locked_transfer` and `locked_sweep_all` commands from `monero-wallet-cli` APIs changed: * Removed `unlock_time` parameters from `wallet2` transfer methods * Wallet RPC transfer endpoints send error codes when requested unlock time is not 0 * Removed `unlock_time` parameters from `construct_tx*` cryptonote core functions
Related to monero-project/research-lab#78 Added a relay rule that enforces the `unlock_time` field is equal to 0 for non-coinbase transactions. UIs changed: * Removed `locked_transfer` and `locked_sweep_all` commands from `monero-wallet-cli` APIs changed: * Removed `unlock_time` parameters from `wallet2` transfer methods * Wallet RPC transfer endpoints send error codes when requested unlock time is not 0 * Removed `unlock_time` parameters from `construct_tx*` cryptonote core functions @tobtoht: undo rebase changes tx.dsts -> tx_dsts
A Plea to Restore a Crucial Feature in XMRAs a computer science student and a long-time follower of XMR & Dr. Daniel Kim (sweetwater.consulting), I'm compelled to share my thoughts on a feature that I believe is important to the value proposition of XMR. I've created an account specifically to express my disappointment and frustration with the removal of the A Personal Journey with XMRI've been following the XMR project since 2018, and its value proposition was evident to me even back then. However, I wasn't technical enough to fully appreciate its features. This year, I became proficient enough to run a full node and use the CLI, which is when I discovered the As someone who has impulsively sold assets like NVIDIA, BTC, and TSLA before they reached their full potential, I've come to realize that XMR is a long-term play that will appreciate in value over the next 5-20 years. The ability to lock transactions for an extended period has been a game-changer for me, allowing me to make sacrifices that my future self will appreciate. The Value of Locked TransactionsThe A Call to ActionI urge the XMR community to reconsider the removal of this feature and to implement safeguards to prevent similar decisions in the future. Specifically, I request:
ConclusionAs more users join the XMR community, they will come to appreciate the unique properties of the blockchain. I firmly believe that the A Final AppealI've gone from hearing about XMR as the real privacy-focused vision of BTC, to buying some XMR on an exchange, to self-custodying on Exodus wallet, and finally to downloading and running the CLI. XMR is beautiful, and it's idealistic. Please keep or reimplement this feature. https://reddit.com/r/Monero/comments/mwrm6g/how_to_lock_send_future_monero_to_yourself_with/ This was the post and feature that motivated me to dedicate a weekend last semester to read the documentation, compile from source, and use the CLI. …Please keep this feature… |
Monero (the blockchain) has 1 job. Digital currency. Gambling on its fiat valuation is completely unrelated to Monero and is very poor reasoning to reinstate what is, among other things, a privacy harming feature. If you want to force yourself to HODL: |
I've hit a hiccup in wallet side scanning for fcmp++ because of timelocks. TL;DR they can slow down full wallet scanning under fcmp++. Contextfcmp++ works by proving you own an output (or "enote") within a special merkle tree called a curve tree. All valid, spendable (i.e. unlocked) outputs across the entire chain compose the leaves of the tree. When constructing the full-chain membership proof, the user proves their output is a member of the tree, without revealing which output it is. To construct the proof, a wallet needs the output's path in the tree (from leaf to root) at the latest block. The state of the tree changes every block, so an output's complete path in the tree changes every block as well. I'm currently working on building the tree locally as the wallet syncs, so that wallets can update received outputs' changing paths while syncing (and can therefore construct fcmp++ txs without leaving any statistical trace to the daemon which output is being spent when the user constructs an fcmp++ tx). In order to build the tree correctly, clients need to grow the tree with outputs that unlock each block. The problemThanks to timelocks, an output's unlock block can be any block far in the future, so clients need to take special effort to keep track of outputs by unlock block. Solution AClients download all outputs that unlock in a block in addition to outputs created in a block. This is bad because it's almost 2x'ing the amount of data clients download in order to sync. Solution BClients locally keep a cache of locked outputs, and then remove from the cache upon inclusion in the tree. The main problem with this is thanks to timelocks, it's a potentially unbounded cache that clients need to store. Solution B++Keep track of valid normally locked (i.e. not timelocked) outputs in a persistent cache in the client, then remove from the cache upon inclusion in the tree. Modify If we remove timelocks at consensus, it closes the door to enabling excess scanning cost to clients via timelocks, and full wallets can reasonably keep a local cache of all locked outputs. Note that keeping a locked outputs cache in the client would increase the client's space footprint by P.S. also open to any ideas on other solutions. |
Why would this be needed if you are just growing the tree with every block received?
This seems the best option to me. Let the daemon keep track of which block an enote will unlock in. The main problem is potential DoS by locking many enotes to a single block. If timelocks are deprecated then this is no longer as big an issue because 'known DoS targets' can be hard-coded (if there are any). |
You can't include transaction outputs inside the merkle tree until the moment that it is valid to spend them. So even for normal transaction outputs, you have to keep them around for 10 blocks before insertion. If they were added to the tree before, then the validators wouldn't be able to determine whether you were spending a "locked" output or an "unlocked" output. All they can tell is whether that transaction output is an element contained in the tree, or not.
The problem here for me is that this isn't easily verifiable to the wallet. Normally all content returned by |
I think solution B is fine give the current usage of Monero timelocks is niche and the fact that there is currently a relay rule in place to prevent future transactions from including an unlock time. We could initiate a soft fork before the FCMP hard fork to completely cement the rule in-place, or we could decide to not honor time-locked transaction outputs past height X during the building of the FCMP tree. Both of these would allow us to know the exact size of the wallet cache before deploying the code. |
Good point on the relay rule -- I also generally agree solution B will be acceptable in combo with a guarantee we'll know the size of the wallet cache before deploying.
This seems a cleaner break to me, rather than setting a precedent of voiding prior expectations. |
Following discussions during a #monero-research-lab meeting, see logs here, there seems to be some support for removing monero's timelock implementation. This issue should open further discussion on this topic. There are future use cases, for example payment channels and payment channel networks, that require some form of timelock, as described in the DLSAG paper.
Monero's timelock is used with the
unlock_time
field, which is available in every transaction. By default it is always 0. A user can choose to either set it to a block height, indicating until which block all the outputs of the transaction remained locked, or a timestamp, indicating until what time all the outputs should be locked. A user receiving an output in a timelocked transaction can only spend this output once it has expired.The
unlock_time
field has a host of problems. I detailed most of them in a series of blogposts: https://thecharlatan.ch/Monero-Unlock-Time-Privacy/.The problems can be summarised in short:
The
unlock_time
can be encrypted, which solves all these issues, but costs about a doubling in transaction verification time and a significant increase in transaction size. With current usage being so low, this is a high price to pay. If a legitimate use case arises the price becomes more acceptable though.Alternatively, there are a number of things that can be done to improve the situation without increasing transaction size or verification time:
Even with these improvements, usage patterns can still emerge and leak significant information, for example identifying transactions from a special wallet that always sets the
unlock_time
150 blocks into the future. I therefore support removing the field. If an actual use case appears in the future, timelocks canbe re-added in a fashion best fitting this use case (and hopefully encrypted).The text was updated successfully, but these errors were encountered: