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

Anti-replay / Replay protection #34

Closed
chjj opened this Issue Jun 20, 2017 · 96 comments

Comments

Projects
None yet
@chjj

chjj commented Jun 20, 2017

@gavinandresen's anti-replay patch carries with it the benefit of preventing the 1mb chain from ever reorging the 2mb chain. As soon as an OP_RETURN [segwit2x] transaction is mined on the 1mb chain, the 1mb chain is now invalid in the eyes of the HF code. I think this should be implemented for both anti-replay and anti-reorg benefits.

While Gavin's anti-replay is probably the simplest, it's worth mentioning that @jl2012 also had a clever way of preventing replays on spoonnet: a special tx version bit enforces segwit-style sighashing for even non-segwit inputs (a nice perf boost to boot), but this is a bit trickier, since it has a higher chance to invalidate existing pre-signed transactions, and requires more to implement in wallets (especially hardware wallets).

Thoughts?

@RHavar

This comment has been minimized.

RHavar commented Jun 20, 2017

Probably the simplist wipeout protection is to just require that the first block of the HF is to have a blockweight > 4M and <= 8M

@joshuayabut

This comment has been minimized.

joshuayabut commented Jun 21, 2017

@RHavar #35

With that above commit there will be no risk of a re-org since it enforces a large block at a certain block index...I'm still catching up here but how come OP_CHECKBLOCKATHEIGHT isn't suggested as a solution?

@jgarzik

This comment has been minimized.

jgarzik commented Jun 28, 2017

@joshuayabut I'm a personal fan of OP_CHECKBLOCKATHEIGHT (though that's outside the scope of segwit2x)

@RHavar

This comment has been minimized.

RHavar commented Jun 28, 2017

One idea (and totally out of scope) I had was to use the block hash of the nLock of a transaction to sign inputs (similar to how segwit uses the amount). You could opt out of it by setting the transaction nLock to 0, and if you want to time lock a transaction in the future, you'd have to use a future time and not a block number.

The benefit would be that all transactions by default would be very replay resistant (since they're only valid on a specific chain) while being no bigger in actual size. It would also make selfish mining and reorg attacks less profitable.

But it'd bring in a fair bit of complexity, and probably has quite a few downsides I haven't thought of.

@earonesty

This comment has been minimized.

earonesty commented Jul 11, 2017

We could just reject all non segwit tx. That way malleability is fixed for good. Since we're bothering to hard fork anyway... might as well reject pesky legacy transactions.

@JaredR26

This comment has been minimized.

JaredR26 commented Jul 11, 2017

@robbak

This comment has been minimized.

robbak commented Jul 16, 2017

We can't just drop legacy transactions. A stated use case of bitcoin was locking away funds until a future time with nlocktime. So people who have locked funds up using that method need to be able to get their legacy transactions mined whenever they become valid - so current transactions need to remain valid. Such a pity that the original transaction format had such an annoying bug.

@earonesty

This comment has been minimized.

earonesty commented Jul 16, 2017

@xenog

This comment has been minimized.

xenog commented Jul 27, 2017

nLockTime is not part of the signature, but it is part of the pkScript, and a pkScript is spent by a sigScript, not by a witness. A somewhat-disruptive hard-fork rule could allow a witness to spend a legacy pkScript, but that's not currently on the table.

@jgarzik jgarzik changed the title from Anti-replay and anti-reorg to Anti-replay / Replay protection Aug 19, 2017

@jgarzik

This comment has been minimized.

jgarzik commented Aug 19, 2017

Changing Issue title to focus more narrowly on just the replay protection issue, since wipeout protection was already added.

Replay protection remains an issue of much discussion throughout the community.

To reiterate, opt-out replay protection creates chain splits and goes against the goal of remaining one chain.

Opt-in replay protection, such as the @gavinandresen example in @chjj 's OP, seems like something we could merge.

@booung

This comment has been minimized.

booung commented Aug 21, 2017

@jgarzik I think btc1 should consider a chain-split a very real possibility. Or will btc1 abandon the project if it looks like it may cause a split as that goes against the goal of remaining one chain?

I just checked https://coinmarketcap.com/exchanges/volume/24-hour/ compared to https://medium.com/@DCGco/bitcoin-scaling-agreement-at-consensus-2017-133521fe9a77 and only 4 of the top 20 exchanges have committed to the NYA and there is also this list http://nob2x.org/. I know most of these businesses haven't said they wont follow btc1 but that's far from committing to it. As its a HF they will need to upgrade/change code and are therefore currently incompatible with btc1 and will cause a split (apologies if I have this wrong)

https://cash.coin.dance/blocks/thisweek shows bitcoin.com, BTC.com, Antpool, BitClub, and ViaBTC are all now mining another chain. These companies all signed the NYA but are now mining something else proving that hashpower can change and (used by itself) may not be a good measure for consensus.

I have heard argument for core to implement replay protection but this doesn't make sense as they are not the ones doing the HF that requires an update.

Also there doesn't seem to be many poeple running btc1 yet https://coin.dance/nodes is this accurate?

@jgarzik @chjj @jameshilliard @SergioDemianLerner Would be great to get some feedback on this thanks.

@rodasmith

This comment has been minimized.

rodasmith commented Aug 21, 2017

It's starting to look like replay protection may not be needed for the NYA 2 MB activation in November. We may not even have to fork! At https://github.com/NYAcoin/bitcoin/issues/1 the idea is to implement replay protection only at a later date when ~4 MB blocks are needed. For now we can get to ~2 MB with SegWit, so we don't even need to fork in November!

@NiKiZe

This comment has been minimized.

NiKiZe commented Aug 21, 2017

@booung simple correction:

https://cash.coin.dance/blocks/thisweek shows bitcoin.com, BTC.com, Antpool, BitClub, and ViaBTC are all now mining another chain. These companies all signed the NYA but are now mining something else proving that hashpower can change and (used by itself) may not be a good measure for consensus.

These are mining pools, which are now also mining Bitcoin Cash due to high user demand, but they (as companies) are still dedicated to NYA. Just to mention one easy to find statement: https://www.bitcoin.com/public-service-announcement

btc1 nodes are not the only ones that accept >1MB blocks, and are also not the only ones enforcing the rules needed for Segwit2x, With little more then 50% of the miners enforcing >1MB block this is enough since 1MB+ accepting nodes will be just fine.

This is something that have been asked over and over again - so I suggest reading the responses that already exists.

@booung

This comment has been minimized.

booung commented Aug 21, 2017

These are mining pools, which are now also mining Bitcoin Cash due to high user demand, but they (as companies) are still dedicated to NYA. Just to mention one easy to find statement: https://www.bitcoin.com/public-service-announcement

Thanks, yes that's my point, miners follow user demand. As they are doing with bitcoin cash they can also do to the core chain. Bitcoin cash did the responsible thing and implemented replay protection.

As I mentioned only 4 of the top 20 exchanges have signed to run btc1. Here https://www.btcc.com/news/en/announcements/2017/03/18/hard-fork-statement/ is a statement from some of the exchanges from the previous BU hardfork attempt. Obviously a different situation but shows exchanges like replay protection.

It's possible (likely imo) btc1 doesn't have the consensus its needs to pull of the HF without creating a split so replay protection should be implemented if its going ahead.

@Pheromon

This comment has been minimized.

Pheromon commented Aug 21, 2017

The NYA was only a charade to let segwit happen.

The only way to make a block increase successfull would have been to hard fork to 2MB together with the activation of segwit, and this has been repeated by me and others ad nauseam.

Now that we have Bitcoin Cash the need for this fork is not needed anymore, farewall for the (few) people that in good faith thought that the NYA could work.

@pekatete

This comment has been minimized.

pekatete commented Aug 21, 2017

I apologise in advance if this is meant to be a strictly technical discussion.

I have heard argument for core to implement replay protection but this doesn't make sense as they are not the ones doing the HF that requires an update.

You comprehensively misunderstand this.

  1. The 2MB HF of SegWit2x is an upgrade to Bitcoin, Moreover, the upgrade was locked-in by majority network hash (over 85%).
  2. Core refusing to merge the consensus rules upgrade (and partitioning the network with the 0.15 release) is effectively a HF off the Bitcoin network BUT with minority hash (not unlike the Bitcoin Cash fork).
  3. The NYA seeks to avoid a split, which implementing (mandatory / opt out) RP would encourage, and should rightly persue this goal perpetually.

It is therefore incumbent on core, as the minority chain forking off Bitcoin (not unlike Bitcoin Cash which they applauded for implementing RP), to implement RP and not btc1

@Mashuri

This comment has been minimized.

Mashuri commented Aug 21, 2017

Disclaimer: I am not a lawyer nor do I represent anyone legally. This is not legal advice. Please consult a lawyer and perform your own due diligence before coming to any legal conclusions. There are serious legal issues to consider here. Causation ( https://en.wikipedia.org/wiki/Causation_(law) ) is a cornerstone of law when determining what parties are responsible for particular situations. If a chain split happens, then the parties who actively created the conditions that enabled the split are legally viewed as responsible. Being passive (not doing anything) typically legally exempts one from any responsibility. In this situation, it would be the parties involved with the btc1 project who are actively creating the conditions for a chain split -- and currently with no replay protection for users. This puts anyone who chooses to adopt btc1 into potentially serious legal trouble. Exchanges and payment processors in particular could be targets of damaging lawsuits and/or criminal charges. Replay protection not only protects users on both chains from financial loss / fraud, but also a myriad of legal problems.

@earonesty

This comment has been minimized.

earonesty commented Aug 21, 2017

@jgarzik

This comment has been minimized.

jgarzik commented Aug 21, 2017

This issue is for discussing the technicals of an implementation that would work for segwit2x.

The goal of segwit2x is to upgrade Bitcoin - to be Bitcoin - not create an altcoin.

@Mashuri

This comment has been minimized.

Mashuri commented Aug 21, 2017

My concern deals with that very issue. Exchanges and payment processors will not want to subject themselves to legal risk. How can segwit2x "become" bitcoin when their participation is so heavily disincentivized?

@JaredR26

This comment has been minimized.

JaredR26 commented Aug 21, 2017

If a chain split happens, then the parties who actively created the conditions that enabled the split are legally viewed as responsible.

Good luck suing Bitcoin.

If what you say were true, Bitcoin Core could be liable for removing Bitpay from bitcoin.org. I already thought about that, and if it were feasible to do so, Bitpay should sue them. It isn't possible unless they have standing, the proper jurisdiction, bitcoin.org would have had an obligation to Bitpay, and there must be damages calculable.

No standing without claiming ownership over btc1/Bitcoin, which no one can.

Bitcoin doesn't have a jurisdiction.

There's no obligations implicit in using Bitcoin, or in Bitcoin.org.

While Bitpay might be able to measure damages, CoreCoin's split could not. Users have a responsibility to take prudent actions to mitigate their damages prior to being able to claim them. As core themselves have repeatedly stated regarding BIP148(And BCH), coins can be split without replay protection.

No standing... No jurisdiction... No obligations... No unmitigable damages... No lawsuit possible. You're not actually a lawyer, are you?

@JaredR26

This comment has been minimized.

JaredR26 commented Aug 21, 2017

My concern deals with that very issue. Exchanges and payment processors will not want to subject themselves to legal risk.

Please explain the standing, jurisdiction, what obligations exchanges owe to Bitcoin/Core, and the unmitigable damages that represent such a risk.

@Mashuri

This comment has been minimized.

Mashuri commented Aug 21, 2017

JaredR26,

No major exchanges declared they would adopt a BIP148 split chain either for obvious reasons. The concern is not "suing bitcoin". It's the identifiable participants, like exchanges and payment processors, who are vulnerable. If they choose to run code that can cause financial damage to parties they do business with, they can be held liable. Don't kid yourself.

@JimHarperDC

This comment has been minimized.

JimHarperDC commented Aug 21, 2017

I am a lawyer, and I differ with @Mashuri's take on the application of the law. In brief (because @jgarzik just cautioned about keeping things technical!), you have got to have a theory of liability before you go into causation, which examines the extent to which the breach of a duty or obligation caused an injury.

Is there a contract? Almost certainly not. Is someone being defrauded? No. (Fraud is deception intending financial gain, not failing to cure others' ignorance.) Is there a general duty on the part of FOSS devs to provide some level of protection to users of the software that results from their efforts? That's the most plausible legal theory, but I think it's still not a strong one, and nobody should want it to be because devs would drop off of projects en masse.

Here's a Twitter conversation from a few years back that explores some of these issues: https://twitter.com/Jim_Harper/status/633123290261921792

I think legal liability shouldn't be a concern of FOSS developers. Carry on! (But, of course, I must add that I am not giving you advice! Consult your own member of the attorney cartel!)

@JaredR26

This comment has been minimized.

JaredR26 commented Aug 21, 2017

IMO, replay protection guarantees that there is no chance that btc1 will
ever be called "Bitcoin" by anyone.

It already is. Sorry if you don't like it.

In order to "be bitcoin", SPV users should not have to upgrade their code.

Correct, which is why weren't not breaking compatibility with them, especially since they are not affected by the only consensus change being made in this codebase.

If protections are added, then we just get "B2X coin".

I find it rather funny that this issue has been brought up no less than 10 times, and this issue has been open for 20 days, yet we still don't have any discussion or a pull request for the thing that was found acceptable - an optional replay protection mechanism.

If this really were all about protecting the users as claimed, this would have been done at least... no? Why not? We even have someone trying to create a fork that isn't compatible instead after being told it would not be accepted... How odd... Maybe it isn't really about protecting the users, maybe it's about trying to protect something else instead?

@JaredR26

This comment has been minimized.

JaredR26 commented Aug 21, 2017

If they choose to run code that can cause financial damage to parties they do business with, they can be held liable.

Then this would be governed by their terms of service, no?

That's easily handled on a business by business level. It doesn't warrant protocol-level discussion.

@mjamin

This comment has been minimized.

mjamin commented Aug 21, 2017

SegWit2x has no future other than to become an altcoin. Might as well make the split as safe as possible for everyone involved.

The core project will not be coerced to merge SegWit2x's changes without sound reasoning. Core however will move full speed ahead while SegWit2x is stuck on 0.14. This project doesn't have the power to keep up.

What you have is a several months old, non-binding agreement that's starting to fall apart in light of bcash. An agreement among businesses and miners, trying to decide for their customers and the rest of the bitcoin userbase. An agreement that sets a very bad precedence. "Why do we want to hard fork? Because our group agreed on doing that."

But I guess "It is difficult to get a man to understand something, when his salary depends on his not understanding it."

@jheathco

This comment has been minimized.

jheathco commented Oct 3, 2017

@morcos Take a look at #120 - similar proposal to what you're suggesting, although tagging bits from the tx nVersion number rather than sequence number. I personally find the P2SH method cleaner and much easier for users to adopt.

@booung This is simply based on signaling, which is the only hard data we have to go off of.

@booung

This comment has been minimized.

booung commented Oct 3, 2017

@jheathco Signalling does not mean you are only going to mine the 2X chain so using this data to say you will have 90% hash is wishful thinking. Miners can point hash at whatever chain they want an still signal/support NYA

@jheathco

This comment has been minimized.

jheathco commented Oct 3, 2017

@booung What metric would you prefer to use other than signaling and NYA signatories? Reddit posts?

What motive would miners have to falsely signal 2x if they support and plan on pointing their hashpower at 1x?

@jgarzik

This comment has been minimized.

jgarzik commented Oct 4, 2017

Merged #127 into segwit2x-dev.

Note that #120 remains open. The method in #120 represents a trade-off. The just-merged P2SH method (#127) does not require any software modification for users to use. The method in #120 is more efficient by lack of UTXO creation, but requires special software modifications.

Closing this issue -- but please do continue to use this issue to comment on #120 or other, better methods of replay protection.

Notably, if a method exists -- no one has found such yet -- that enables two-way replay protection that does not break 10M+ wallets -- perhaps OP_CHECKBLOCKATHEIGHT? -- we remain open to that avenue.

The goal is maximizing protection without breaking 10M+ wallets that would otherwise continue working through the fork.

@jgarzik jgarzik closed this Oct 4, 2017

@booung

This comment has been minimized.

booung commented Oct 4, 2017

@jheathco there is no good metric hence you should not claim you will have 90% of the hash and don't need replay protection.

You seem to have missed the point I'm trying to make. The signalling you talk about is to show being ready for the NYA. It does NOT mean miners will not point hash at another chain if it's profitable

@jgarzik jgarzik reopened this Oct 7, 2017

@jgarzik

This comment has been minimized.

jgarzik commented Oct 7, 2017

Re-opening issue and re-opened PR #117

There's definitely been some good feedback on the P2SH replay protection method, that may warrant revisiting back to the OP_RETURN method. Vectors of consideration include

  • Difficulty (or ease) of ability to split funds with multi-send
  • Problems that might be encountered with multi-send
  • Impact on layer 2 systems like Lightning
  • Difficulty or ease of ability to execute with existing software, without modification.
  • Sunsetting provision
@jcansdale

This comment has been minimized.

jcansdale commented Oct 7, 2017

Difficulty (or ease) of ability to split funds with multi-send
Problems that might be encountered with multi-send
Difficulty or ease of ability to execute with existing software, without modification.

Using explicit multi-send would be too esoteric for the average user and it isn't supported by many wallets. The implicit multi-send where there's a target and a change address is much more reasonable. I'd have thought moving coins to a new wallet and then sending dust to the replay protection address would be understandable by most users.

Impact on layer 2 systems like Lightning
Sunsetting provision

There should definitely be a sunsetting provision and preferably sooner rather than later. We certainly don't want to live with technical dept or unintended layer 2 consequences. A temporary block on 2x chain replays rather then a permanent consensus rule change. People's coins aren't completely safe until they've been moved on both chains.

@benkloester

This comment has been minimized.

benkloester commented Oct 26, 2017

Another way to do what @Sjors was suggesting (opt-out of 1x chain) would be to change the 2x code to accept transactions with nLocktime = uint.MAX_VALUE as being valid now, rather than in 2106. These are then transactions that are invalid on 1X (for the next ~90 years at least) but would be valid on 2X.

Such transactions would not be relayed on 1X, but you could change the 2X consensus code to treat nLocktime transactions, only for the special case of max_value, as being valid now. The consensus code already has a special case treatment for 0 - this just expands that set.

One possible small objection to this, since I've noticed that core devs always seem to worry a lot about breaking nLocktime transactions with future dates, is that this breaks the security model for any nLocktime transaction that has already been signed and uses nLocktime=maxint. I can't really conceive of why such transactions should exist, but if that were a problem, then you could also require that a specific sequence number (eg 0xfffffff0) occur in at least one of the inputs in order for the transaction to be valid now. this seems like a sufficiently esoteric combination that it won't have ever happened. That's if nLocktime=maxint is not already deemed sufficiently unlikely.

@benkloester

This comment has been minimized.

benkloester commented Oct 26, 2017

Since there is no longer any replay protection in either the master or dev branches of this project, and since it now looks inevitable that there will be two chains, at least for some time after the fork, it will fall to users to come up with ways to split their coins across the forks to prevent unintended replays.

I thought I may as well capture some of the ways they (and particularly exchanges) might do that. The options I can think of are:

Spend the same output to different addresses on the two different chains

There are at least two ways to do this:

Using Replace-by-Fee and luck

Get a spend (w RBF) confirmed on one chain to an address you control. Spend the same utxo on the other chain to a different address you control, using RBF possibly with a higher fee. Hope the one that gets confirmed on the second chain is the different address, not the replayed transaction. If not, try again.

Pros: Supported by using existing wallets and block explorers (kind of). No need for help from third parties / miners. No specially constructed transactions.
Cons: No guarantee it works each time, might take several tries, and fees could get expensive.

Using nLocktime

Wait until one chain is a couple of blocks ahead of the other, and use an nLocktime transaction with valid height of the higher block height + 1. Since nLocktime transactions that are not yet valid (ie the lock height is above the next block) are not relayed or accepted into the mempool, this should confirm on the longer chain, and be discarded on the slow chain. You can then spend the same output with a different transaction on the slow chain.

Pros: No need for help from third parties, or coordination, possibly more likely to work first try than RBF.
Cons: Have to wait for chains to diverge (likely tens of minutes only, but this could be an issue for exchanges who will have time pressure). Not clear if it is easily supported in existing wallets?

Tainting the transaction using already-split outputs, anyonecanpay transactions, and cooperation from anyone with split coins

There are four variants, depending on who initiates, and the source of taint.

Who initiates

These can be either user initiated or miner initiated:

Miner initiated

Miners create transactions spending from tainted outputs (coinbase outputs/bounties) with signature hash type SIGHASH_SINGLE|SIGHASH_ANYONECANPAY and use some out-of-band means to make these 'templates' available. Users can then add their inputs and outputs to the transaction.

Cons: The out-of-band distribution and use of templates also requires some coordination between those wanting to use these 'template' transactions to split their coins - in theory one of these templates could be used by many users who all append their inputs and outputs to it, I think, but even if you used 1 template per user wanting to split, you'd ideally make sure that users didn't just grab the first template and add their splitting transaction to it, or you'd flood the mempool with lots of partial duplicate incompatible transactions.

User initiated (taken from this SE answer)

Option 1) Sign your inputs with SIGHASH_ANYONECANPAY|SIGHASH_ALL and allow the miners to add a single satoshi tainted input that they get back in the form of fees (miners can't add outputs because of the SIGHASH_ALL of the signatures for this option).

Option 2) Sign your inputs with SIGHASH_ANYONECANPAY|SIGHASH_SINGLE and use a single zero index output. This allows a miner to add inputs and outputs that input taint and pay back one of their addresses.

Pros: Users can simpy create and broadcast such transactions, they don't need the miners to initiate.
Cons: Need miners to cooperate (though option 1 incentivizes with mining fees). Might need to mess with raw transactions to create this.

Source of taint

Taint using coinbase outputs

Pros: Is essentially free, is guaranteed to work first try.
Cons: 100 blocks before you can spend coinbase outputs!

Taint using bounty transaction outputs

Pros: Is essentially free, is guaranteed to work straight away after the fork
Cons: No guarantee that the bounty transaction is still valid at the fork height. Same issues with coordinating the use of the templates.

Taint using already split coins, and CoinJoin

Services like joinmarket already allow parties looking to perform coinjoin transactions to find each other and do the transaction. If one party had coins that were already split across chains, a coinjoin transaction involving those and unsplit outputs would only be valid on one side of the chain. Markets for this type of service would allow P2P coin splitting.

Pros: Decentralized, scales extremely well (the more coins are split the more can split others), P2P coordination (rather than just miners), supported by existing software
Cons: Fairly technical, would need to build a framework to verify that coins were actually split across chains if a market for splitting coinjoin transactions, in the vein of joinmarket, were to develop

Create a transaction that is (effectively) invalid on the 1X chain and valid on 2X

This would usually be where replay protection comes in and makes this the easiest option, but we don't have any, so this section is quite scarce! There is a single option I'm aware of:

Spend coins within a 1MB transaction

This is likely to only be relevant to large players that can afford to take up half of an entire block to split coins - so the big exchanges, etc. However, a 1MB transaction can only be mined on the 2X chain, so this is a way to guarantee a split, without having to wait, or cooperate.

Pros: No need to wait, no uncertainty about whether transaction could be confirmed on both chains. No need for out-of-band cooperation.
Cons: 1MB transaction is still non-standard, so may need cooperation of miners, and direct peering to cooperating miner. Likely to be expensive, so not available to average users. Doesn't scale - only one user can split per block.

@jcansdale

This comment has been minimized.

jcansdale commented Oct 26, 2017

@benkloester Nice summary! Maybe this topic deserves its own issue?

Here is one solution I've been thinking about/working on:

  1. Before the fork we create a number of transactions with lots of dust outputs.
  2. When the fork happens, we create a ~1M tx that consumes all of these outputs and creates a similar number of outputs of its own. We can be sure that this tx will only be mined on the 2x chain, so all of the outputs that it consumed can now be used for replay protection on the 1x side.
  3. We create a service that listens to a special replay protection bitcoin address. When bitcoin is sent to the service address, it gets mixed with an output on the mega-tx and returned to the sending address.
  4. It also gets mixed with bitcoin on the original (already mined) sub-mega tx and returned to the sender on the 1x side.
  5. The user sets up a 1x wallet that's connected to a Bitcoin Core node and a 2x wallet that's connected to a Segwit2x node (they share the same mnemonic).

People send small amounts of coin to this address, not their whole wallet! Once the replay protected coins are returned, the user can send the complete contents of each wallet to itself. The user ends up with all coins in both wallets replay protected.

@Sjors

This comment has been minimized.

Sjors commented Oct 26, 2017

I'm compiling various solutions for a presentation I'm giving in Hong Kong next week, which I'll also try to write up as a blog post. Having a separate issue for each potential workaround method might be useful.

@robbak

This comment has been minimized.

robbak commented Oct 26, 2017

The main thing you have to make clear at your presentation is that doing any of these things will make your coin worthless, for any purpose except speculation, until the minority chain has been abandoned. Until that time, a transaction can only be considered valid once it has confirmed on both chains, and, if your coins have been 'split', that can't happen.

Why people seem so eager to race to the worst possible outcome - that of two functional, continuing chains - is beyond me.

@Sjors

This comment has been minimized.

Sjors commented Oct 26, 2017

@robbak:

a transaction can only be considered valid once it has confirmed on both chains, and, if your coins have been 'split', that can't happen.

I would say a transaction is only valid when it has confirmed on the correct chain, i.e. the chain sender and recipient agree on. Although they could agree to use both chains at the same time, this would require a replay guarantee, which is even more difficult than replay protection.

I don't see how any of this precludes the existence of separate viable chains. If miners choose to run consensus code without replay protection and SegWit2x parties decide to offer or force this onto their users, it will be the users (or the companies themselves) that add replay protection through these more convoluted ways. Eventually the UTXO sets will diverge enough so it "just works" (assuming both chains survive long enough for this to matter).

@pekatete

This comment has been minimized.

pekatete commented Oct 26, 2017

If miners choose to run consensus code without replay protection and SegWit2x parties decide to offer or force this onto their users, it will be the users (or the companies themselves) that add replay protection through these more convoluted ways.

What with the pre-occupation with the btc1 client having to implement any kind of RP when core, with the legacy chain being the minority at best, could have easily done the same (at the very least a SF Opt-In RP) with their buggy network partitioning release of 0.15.x?

@jcansdale

This comment has been minimized.

jcansdale commented Oct 26, 2017

@Sjors, do you know what the sate of child-pays-for-parent is? If this feature is functioning, it would simplify things a lot. Fee estimation is a problem for any service trying to deal with this.

@Sjors

This comment has been minimized.

Sjors commented Oct 26, 2017

@pekatete I did not say "having to", so I don't know what pre-occupation you're referring to. Nor what these alleged bugs have to do with replay protection. Simple fact is that if the SegWit2x team doesn't do it at the protocol level, someone else will. Companies, including signatories, have a vested interest to protect their own users, or choose not to at their own risk. I personally think this is a penny-wise-pound-stupid way of managing scarce engineering resources, but that's not up to me.

Conversely, you seem to believe Core needs to do anything other than ignore this fork (and add some protection to full nodes so they don't waste their time communicating with dissenting nodes). Anyone is welcome to submit a pull request; there is no "they" when it comes to Core. Several core developers back in May made it quite clear there wasn't enough time for such consensus code changes, but afaik nobody on the SegWit2x team even tried to submit a PR; who knows, maybe it would have merged.

It also doesn't make any sense strategically: with 70-80% of miners currently signaling to (at least momentarily) abandon software written by Core, and soft forks generally requiring 95% and plenty of time to lock in, why would you expect these miners to activate such a replay protection soft-fork? It would just be a waste of development effort. But again, nobody on the SegWit2x team even tried afaik.

A better use of time for people who aren't excited about SegWit2x seems to be to warn users to beware of replay issues and perhaps ask their favorite participating company how exactly they intend to protect them.

@jcansdale afaik CPFP "just works", but I'm not very familiar with it. Interesting idea to use CPFP to speed up confirmation on one chain. However on August 1 I was able to confirm a transaction the next block with just 1 satoshi per byte, which is the minimum relay fee. So if the network is as quiet right around this fork, I wouldn't use this strategy. That said, maybe SegWit2x nodes could use 2 sat/byte as the minimum relay fee.

@jcansdale

This comment has been minimized.

jcansdale commented Oct 26, 2017

BTW, I have a prototype splitter service on testnet at mjahAPaugGiMt4PKNbp4nkZ6qdCsFft5h2. Feel free to throw some tBTC at it! You should get it back mixed with a (fake) replay-protecting output.

@Sjors

This comment has been minimized.

Sjors commented Nov 1, 2017

Here's the slides I plan to use to explain nLockTime (feedback welcome).

Steps:
schermafbeelding 2017-11-01 om 13 13 23

Problems:
schermafbeelding 2017-11-01 om 13 14 23

Additional notes:

Only works while one side of fork has a big enough lead. Can't be used immediately after fork.

This is hard to do manually, but also hard to automate for non-custodial wallets. User needs to come back several times, lots of edge cases to handle in UI.

When receiving new funds, wallet must reason if those funds are already replay protected, or its coin selection must always include coins that are known to be protected.

@Sjors

This comment has been minimized.

Sjors commented Nov 1, 2017

> 1MB transaction

  • valid on 2x, invalid on 1x
  • non-standard (needs coordination with miners)
  • expensive (easier for a service)

Maybe CoinJoin can be used? But then how do participants know the transaction is going to be greater than 1 MB? Also might take a while to fill up.

UTXO Ferry Dust

Coinbase transactions are unique for each side, but they require coordination with miners. Perhaps miners could make lots of outputs available using anyone-can-spend extremely low fee transactions. Users can then pick one and use CPFP to sweep it. Won't work well in a low-fee environment like we had on August 1.

Update, as @benkloester pointed out: "100 blocks before you can spend coinbase outputs!"

Services can split using any other method and make anyone-can-spend UTXO's available through a (paid) API.

This works immediately after the fork, unlike nLockTime.

Wallet coin selection must make sure to include these inputs.

In general, wallets need to be aware of which UTXO's are replay protected and which aren't. Especially when they receive new funds. I'm sure there'll be API's for that...

Godspeed :-)

@jcansdale

This comment has been minimized.

jcansdale commented Nov 1, 2017

This is hard to do manually, but also hard to automate for non-custodial wallets. User needs to come back several times, lots of edge cases to handle in UI.

Is it really hard to do manually? I know Bitcoin Core sets nLockTime to the current block height by default. Do any mobile wallets also do this?

  1. Send contents of 2x connected wallet to self.
  2. Wait for confirmation.
  3. Send contents of 1x connected wallet to self.

That's assuming nLockTime is being set correctly. You can also use child-pays-for-parent to pull the tx through on the slower side. Some wallets include a "Use Unconfirmed Funds" option under advanced.

Re: sweep being bad for privacy, I'd be inclined to only split the coins I want to exchange or spend. You can HODL the remainder in your hardware wallet.

Maybe CoinJoin can be used? But then how do participants know the transaction is going to be greater than 1 MB? Also might take a while to fill up.

I think the easiest way to do this will be to use the save-the-chain tx. Miners will definitely be going after this one!
http://www.blockbounties.info/list.html

The tx is made up of mostly OP_TRUE outputs that anyone can spend. The trick will be getting these mined because (I think) spending an OP_TRUE output non-standard.

It would be great is spending a single OP_TRUE output could be made standard assuming a minimum fee was spent. We wouldn't want a single low fee tx consuming all of the outputs!

@Sjors

This comment has been minimized.

Sjors commented Nov 2, 2017

Running two wallets, with the same private keys, on the same machine is non-trivial. I think even explaining what a fork is and what replay protection is good for is a non-starter for 99% of bitcoin users, who probably see Bitcoin as this magical stuff that just works.

I agree it's best to only split funds you need, also considering that this gives you more time to learn about things that can go wrong.

@jcansdale

This comment has been minimized.

jcansdale commented Nov 2, 2017

Running two wallets, with the same private keys, on the same machine is non-trivial.

There are a bunch of mobile wallets that actually make this really easy. For example on the Copay wallet, you can set up multiple Bitcoin, Testnet and Bitcoin Cash wallets. You can even set up different Wallet Service URL on each wallet. If there are BWS URLs that connect to Core/2x nodes, you wouln't even need explicit support from the wallet (though I imagine that's coming).

I think even explaining what a fork is and what replay protection is good for is a non-starter for 99% of bitcoin users, who probably see Bitcoin as this magical stuff that just works.

It would need to be step-by-step instructions (ideally for a specific wallet) to make it easy for non-tech users to follow. I don't think it would be all that complicated.

@Sjors

This comment has been minimized.

Sjors commented Nov 3, 2017

I just realized reorgs may be a an ever bigger problem than I thought, especially if any miner decides to invest in an unusually large reorg.

Let's say you want to sell your 2x coins for fiat to pay rent, using an exchange that doesn't support 1x yet and won't process refunds on that chain for at least a few weeks. That's all fine, you think, because you can replay protect yourself.

So you use nLockTime to split your funds to address A1 on the 1x chain and A2 on the 2x chain. If 1x is at block 500,000 and 2x is at block 500,010, you would create a transaction to A2 using nLockTime 500,010. Wait a few confirmations and then send to A1 without nLockTime, which ends up in e.g. block 500,005.

Now you send your 2x coins from address A2 to this exchange, wait 10 confirmations, and place your sell order. Let's say the 2x chain is at block 500,020 now, while the 1x chain is at 500,010.

Suddenly a reorg takes place on the 1x chain with the last 5 blocks replaced. For some reason your transaction without nLockTime is ignored and instead the one with nLockTime 500,010 is mined into block 500,010. This in turn causes your transaction from A1 to the exchange to replay itself on the 2x chain, so your funds are stuck.

The opposite scenario would be bad for the exchange. I'm less worried about that, because I assume they'll pick a minimum confirmations based on their own risk assessment. That said, there seemed to be a race to the bottom around the Bitcoin Cash fork, with users flocking to whichever exchange accepted the fewest confirmations.

It gets worse. Let's say some service creates a >1 MB transaction and sends you an output. They also moved their coins on the 1x chain (for whatever reason). You send your pre-split funds plus this UTXO fairy dust output to address A2 on the 2x chain. Once that confirms, you create a transaction on the 1x chain to send your pre-split funds to A1. You're safe, right?

This service could be the victim of a similar reorg, where their > 1MB transaction suddenly becomes a double spend, making all transactions that follow from it invalid. If there's just a handful these 1 MB transactions, there could be a substantial mess.

Using coinbase transactions for UTXO mixing has the same issue, because re-orged blocks would have different coinbase transactions. Although this attack requires a 100+ block reorg, which would cost $5,000,000 on the current chain, it could potentially be much cheaper on the minority chain. Who cares about the minority chain? Well, both chains are entangled, due to these ad hoc replay protection schemes. So causing trouble on one chain, could wreak havoc on the other.

@jcansdale

This comment has been minimized.

jcansdale commented Nov 3, 2017

This service could be the victim of a similar reorg, where their > 1MB transaction suddenly becomes a double spend, making all transactions that follow from it invalid. If there's just a handful these 1 MB transactions, there could be a substantial mess.

They should use the save-the-chain tx and put a checkpoint on block 2 after the fork. This tx will be an attractive target to go after if there is going to be a reorg. It might need some special protection!

@Sjors

This comment has been minimized.

Sjors commented Nov 3, 2017

@jcansdale a service would need to trust that whoever created that transaction won't try to double spend it in a reorg. $2 million is a lot of money, but there's far more money to be made from trading on the chaos that would result from a reorg, for whoever can time it (and maybe hide from law enforcement).

It's probably better for each service to create their own transaction with a hard to resist fee.

I would also point out that this money might have been better spent hiring a bunch of developers to get proper native replay protection merged here.

@jgarzik

This comment has been minimized.

jgarzik commented Nov 8, 2017

Closing - not needed

@jgarzik jgarzik closed this Nov 8, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment