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

Mixed mode for SegWit wallets #483

Closed
Giszmo opened this issue Oct 23, 2018 · 30 comments
Closed

Mixed mode for SegWit wallets #483

Giszmo opened this issue Oct 23, 2018 · 30 comments

Comments

@Giszmo
Copy link
Contributor

Giszmo commented Oct 23, 2018

In the migration to SegWit and bech32, one usability obstacle was, what to do in order to transition from legacy to segwit accounts and how to phase in bech32 when almost no wallets support it.

Create accounts per type (hardware wallets do this)

This approach would mean that the user would keep using his legacy accounts as defined by BIP44 and when creating a new account, it would default to BIP49 (segWit compatibility mode) and the user could also create accounts according to BIP84 (segwit bech32) or BIP44 (legacy).

Advantages:

  • Compatibility with the existing standards (BIP44, 49 and 84). The change output goes into the same and only content type as the funds were in before and thus no change goes to unused accounts or even unused accounts creating gaps.
  • Hardware wallets don't show scary messages, as the change output is treated as a second "send", although the device might mark it as going to the device. Anyone but very tech savvy users will get scared when paying a $5 coffee with their trezor and get asked if they really want to send $5000 to "1xyz... Trezor#1".
  • No extra addresses to scan per account, as the look-ahead of all three types would be tracked per account as per the user's use of these.

Mix account types

Here, "Account 1" would actually encompass account 1 as defined by all relevant bips (44, 49 and 84). The user would be able to receive on either segwit (P2SH is compatible with all existing wallets) or bech32 into the "same" account. When sending funds to any address, change could get received into the sub-account of the according type.

Advantages:

  • The user would not have to switch to a completely different account to make use of the new features and when the counter party doesn't support that type, switch back to a compatible account.
  • Chain analysis would have an harder time figuring out which is the change output as not the input dictates the change output type but the spend output.

Status

In our (still private) segwit branch we took the mixed mode approach, valuing ease of use and privacy higher than slightly higher resource consumption and potentially harder migration to other standard wallets, especially as other wallets seam to also have taken this approach. Our main obstacle is hardware wallets and we are evaluating if there was a way to both have the privacy benefits and the change output not scare the user.

@Giszmo
Copy link
Contributor Author

Giszmo commented Oct 23, 2018

This issue depends on #379 and #425

@Giszmo
Copy link
Contributor Author

Giszmo commented Oct 23, 2018

hardwarewallet

Here is how Trezor and Keepkey deal with change outputs in the different scenarios.
(Sorry for the poor quality but I guess the gist of it is easy to read.)

  • Send from p2sh to p2sh with change to p2sh: No problem
  • Send from one type (or a mix of types) to another type: User gets scared

Actually I'm surprised that in the Trezor software (chrome plugin) bech32/BIP84 seams not to be supported. The tb1 transactions have 2 outputs, sending all the funds. Or is this a bug in our software and these transactions went to the wrong bip32 path (m/84'/1'/1'/1/0)?
screenshot from 2018-10-23 01-56-00

@Giszmo
Copy link
Contributor Author

Giszmo commented Oct 23, 2018

@slush0 @prusnak @pollastri-pierre @keepkeyjon any ideas how to give our users the mentioned privacy while still not scaring them with "Really send 2.8BTC from your wallet" when sending $5 as in the center column above?

@prusnak
Copy link
Contributor

prusnak commented Oct 23, 2018

"Really send 2.8BTC from your wallet" - this is correct. You are sending 2.8BTC from your account to another account. If you don't want to show it, don't send coins across accounts (i.e. don't use mixed transactions).

@sergeylappo
Copy link
Contributor

@prusnak, "You are sending 2.8 BTC from your account" is correct according to the current account implementation. But what if we could merge different address/accounts types into one account? Thus we would (Simplifying what has been said by @Giszmo):

  1. Increase privacy by sending change to corresponding "sub-account". It becomes harder to track funds, for instance, according to the current implementation of BIP if you sent funds from bip44 to bech32 - change must be on the bip44 branch. But if there are only one input and one output + change it becomes clear where change goes.
  2. Prevent user misunderstanding: why should user really care which type of address he want to import? What does it mean legacy? Do end user should really care about protocol improvements? I mean he should feel that things become better, but he shouldn't after updating app see something like "your funds are on legacy". If we want to bring cryptocurrencies to wide masses we must keep things simple.
    The goal of this mixed mode is increased privacy while keeping things simple.

@keepkeyjon
Copy link

keepkeyjon commented Oct 23, 2018

Incompatibility with the existing standards (BIP44, 49 and 84).

It doesn't seem too bad to have this be "enforced" client-side, i.e. only create upgraded/downgraded change outputs when the account exists according to the gap account rules. Device-side, I'd only consider such an output to be change if:

  • It goes to the same account number
  • On an equal or greater account type BIP44 <= BIP49 <= BIP84
  • It goes to the change chain
  • It is the 1st and only change output

We must consider though, how could this be used maliciously (if at all)? My first thought is that it could be used to hide funds from a user since it sends funds to a place not all vendors support. This seems no worse than the current state of client-side segwit support, and feels similar to another case which we can't protect against: sending to a change address well beyond the standard address gap limit. Since both cases need client-side cooperation to DTRT, and given the other benefits, I'm in favor of making this change in our wallet (pun intended).

Edit: correction, I meant BIP84.

@DanielWeigl
Copy link
Contributor

DanielWeigl commented Oct 23, 2018

From a user-perspective the best thing would be to transparently switch over to different transaction- and address types, but my main consideration while defining BIP49 (which was back then when I worked for mycelium) was to also make it simple for different wallet implementation to have the same idea what an account is and also take care about future new address formats.

My main fear was, if we include different address types into one logical account that many wallet will implement a certain sub-set and it will mostly work, but if you move your masterseed (or xPriv) from one wallet which implements (a,b,c) into a wallet wich implements (b,c,d), then you will miss your "a"-UTXOs, but might not notice it.

Im not ultimately happy about it and also not sure what is more important, to be able to move seeds/xPrivs accross wallets and/or to easily migrate to new address formats, but I think the scenario which might lead to monetary loss weights more...

i.e. im rooting for keeping accounts seperated according to their address-type and maybe offer the user a migration assistant that helps you to move your funds to a new account by sending them over.

@keepkeyjon
Copy link

@Giszmo another option, which should work on existing KeepKey firmware, would be to use OutputAddressType_TRANSFER on those change outputs. Less ideal than treating them as change, but you'll at least get the easily grokkable "Transfer 0.0034 TEST to Testnet account #0".

@prusnak
Copy link
Contributor

prusnak commented Oct 23, 2018

Let's face it: Mycelium came late to the Segwit party. If you wanted to shape the future of Segwit-enabled HD accounts, there was a discussion taking place 12-18 months ago, but you were too busy implementing crappy tokens into your wallet back then. You are free to implement whatever strategy you desire, but we won't be changing behavior of Trezor wallet now. Funnily enough, the idea for separated accounts came from Daniel working in Mycelium back then.

@sergeylappo
Copy link
Contributor

sergeylappo commented Oct 23, 2018

@keepkeyjon, why do you want to set such a limitation?

On an equal or greater account type BIP44 <= BIP49 <= BIP89

My main concern is that BIP84 is not so widely used and might be not so good in terms of privacy. IMO it might be better to allow wallet to mask change to at least BIP49.
P.S. thank you for the reference.

OutputAddressType_TRANSFER

We would definitely use it, at least for initial release.

@keepkeyjon
Copy link

keepkeyjon commented Oct 23, 2018

@keepkeyjon, why do you want to set such a limitation?

On an equal or greater account type BIP44 <= BIP49 <= BIP84

I'm inclined to slightly discourage the downgrade-via-change path, though I'm open to persuasion either way if you think it's a valuable use case.

Edit: correction and clarification: I mean that if the vin's have BIP49 paths, then a BIP44 path output would not be considered as a change output. Likewise if all the vin's have BIP84 paths, then a BIP49 or BIP44 path output would not be considered as change.

@Giszmo
Copy link
Contributor Author

Giszmo commented Oct 23, 2018

@keepkeyjon the change having to go to a higher or equal standard than what? If I have UTXOs in all 3 types of addresses, would I be allowed to send change to legacy/BIP44 when sending to legacy according to your idea? I don't understand this limitation as it won't lead to coins accumulate in higher types as long as I can get paid on the external chain using lower types. The privacy benefit depends on being able to pick the change type based on the recipient type, not the sender type.

@keepkeyjon
Copy link

Ohh, I see what you mean now. Yeah, in light of that, that proposed limitation does more harm than good.

@sergeylappo
Copy link
Contributor

After implementing SegWit for Ledger can confirm that our "mixed" mode would work there out of the box. Change to same account with different purpose is treated as change and no additional output appears on screen.

Giszmo pushed a commit that referenced this issue Oct 31, 2018
@sergeylappo sergeylappo mentioned this issue Nov 1, 2018
@Giszmo
Copy link
Contributor Author

Giszmo commented Jan 7, 2019

Mixed mode is a rolled-out feature now

@Giszmo Giszmo closed this as completed Jan 7, 2019
@keepkeyjon
Copy link

sorry I forgot about this for so long. here's a PR for it: keepkey/keepkey-firmware#80

@Giszmo
Copy link
Contributor Author

Giszmo commented Jan 28, 2019

@keepkeyjon thank you! You tested it with Mycelium? Is it seamless or do we need to change anything, too?

@keepkeyjon
Copy link

I've not tested it with mycelium. And in fact, I haven't tried mycelium since we switched over to WebUsb. I'll have to find a friend with an Android phone.

@jandresboston
Copy link

I apologize if I shouldn't be posting here but I am in an urgent situation with Mycelium/Trezor One right now and I have no where to turn but a link given to me by an error code with Mixed spending on Mycelium.

Trezor One support says they don't support Mycelium wallet even though it comes preloaded with Trezor Manager for Android.

I submitted 5 support tickets to Mycelium Zendesk over the course of 4 weeks and have received no response. I will paste the contents of my support ticket:

I was attempting to send some BTC from my Trezor using Mycelium. I got a warning about mix-spend not being supported? by Mycelium/Trezor and that there would be change? The transaction failed and it copied raw transaction data to the clipboard (this has happened 4 more times since then and I think it's eating transactions fees but I can't confirm). It then instructed me to contact tech support with the raw transaction data. Below is the raw transaction data:

01000000016e86516f2d8016974d538c73813627fc081dd58abbc47d08b66a6ee4410b7d86030000006a473044022022a3718bbb728d46de6f04b7cd458a5f4163ee493aaacdd62407e6018c0a7aeb02201b92811e8319efdf645525c0f490aa00618f22c62a432ce729d0ec93a1c7eb56012102835b34cbdde64c11f2a2c48c14ccc54ef30a7c8393f3cf59a7d510821a9a2eabffffffff010a488705000000001976a9145f18bf72b8c477704b984793099e228f8a1170f688ac00000000

After much searching I found this Github issue forum and it's describing the problem I'm having but without a fix or workaround. My BTC is stuck inside my Trezor/Mycelium wallet in a legacy account. Is there a workaround to transferring it somewhere else? I can't see it on the Trezor wallet OR Electrum. Please, any help would be appreciated. I'm in a very difficult situation.

image

@sergeylappo
Copy link
Contributor

sergeylappo commented Apr 5, 2019

@jandresboston, probably wallet is out of sync.
Please try reloading account or cold spending.

This tx seems spending non-existing output.
If Trezor and electrum don't see it... Probably it's already spent?

@jandresboston
Copy link

jandresboston commented Apr 5, 2019 via email

@davotoula
Copy link

@jandresboston Did you resolve your mycelium issue? Thank you

@jandresboston
Copy link

jandresboston commented Jan 25, 2020 via email

@davotoula
Copy link

@jandresboston

Actually, there is nothing private in the workaround so I'll just post it here:

The trick was to create a legacy trezor account in Electrum with the same offset (account number) as my segwit account in Trezor.

Mycelium was showing me derivation path m/49'/0'/1'... for the segwit account where I was missing the change.

So in Electrum I created a new legacy wallet using hardware wallet, I changed the derivation path to m/44'/0'/1'.

2

Electrum showed the missing change immediately and I was able to transfer it to the next receiving address in m/49'/0'/1' which I had generated earlier using wallet.trezor.io.

Happy to have my 3 satoshis back. Let me know if this fixes your problem.

@jandresboston
Copy link

jandresboston commented Jan 26, 2020 via email

@jandresboston
Copy link

jandresboston commented Jan 26, 2020 via email

@davotoula
Copy link

The email you left is not working.

On Sat, Jan 25, 2020, 10:36 AM David Kaspar @.> wrote: @jandresboston https://github.com/jandresboston I have a workaround. Send me your contact details to @. and I'll send instructions. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#483?email_source=notifications&email_token=ALW4DNJRQDTK5VK673ILYQDQ7RL7XA5CNFSM4F6R2F3KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJ463KA#issuecomment-578416040>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALW4DNMSANEIDFIVQNWFXO3Q7RL7XANCNFSM4F6R2F3A .

@jandresboston

h4nfu47dhr83nd@mailinator.com

@keepkeyjon
Copy link

@jandresboston you could try syncing your device with beta.shapeshift.com. We treat the UTXOs under m/44'/0'/a'/{0,1}/i and m/49'/0'/a'/{0,1}/i as separate accounts (so no mixed-mode), but since we scan both, you should see your balance split across the two if you de-select other accounts like so:

image

Click the "Add Account" button if accounts you expect to be there haven't been added automatically.

If you're limited to mobile-only, you might be able to get it to work assuming your device has the latest WebUSB firmware, and you use Chrome as the browser. Desktop will be a better experience, however.

@Shai69bb
Copy link

How to get help with recovering my funds?

@cportofolio
Copy link

@jandresboston I see you haven't fixed your issue. For a fee I will help you out.
E-mail me at cportofolio@proton.me

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

No branches or pull requests

9 participants