adityapk00/zecwallet-light-cli

Client should download all blocks by default, not just ones with relevant tx's (PRIVACY)

holmesworcester opened this issue · 8 comments

According to the wallet app threat model, the fact that zecwallet-light-cli downloads compressed blocks and then download full blocks in cases where there are tx's that interest them reveals, over time, what tx's are interesting to a given zecwallet-light-cli user:

  • The wallet fetches the memo from lightwalletd separately, which uses more bandwidth, and that is visible even though the connection is encrypted.
  • If the bandwidth side channels are fixed, the act of sending and receiving transactions is visible to the lightwalletd server, so this would become a known weakness in the Typical scenario.

In desktop apps like Zecwallet and Zbay, where the user is likely on an unmetered broadband connection, bandwidth savings cannot plausibly justify this loss of privacy to the user.

So we propose a flag where zecwallet-light-cli will download full blocks for every transaction, in such a way that all blocks are treated equally.

Note: there must not be any difference in the logic for fetching interesting / uninteresting blocks, because if there is this would likely be detectable to a malicious lightwalletd, even if the difference is subtle. That is, zecwallet should fetch all full blocks in the most naive way possible, and then process them locally, to avoid leaking information to a malicious lightwalletd.

(To zoom out a bit, I don't think a 70% bandwidth reduction is ever worth a significant decrease in privacy even in mobile. Maybe if it 10-100x, perhaps it would be. But 3x? no way! We should probably make this the default behavior across all apps, desktop and mobile. But at the very least let's make it an option so that desktop light wallet apps can offer similar levels of privacy to receivers as their full node counterparts. It's a shame to take such a big step backward in privacy when going from full node to light node, and it's entirely unnecessary / self-inflicted.)

Related Zbay issue: TryQuiet/zbay#452

If there's a way for us to solve this on our end such that zecwallet won't leak which tx's are ours, we'd be happy to do that in lieu of changes to zecwallet!

Can you help me understand why doing this would be preferable to simply using the full node? LightwalletD/zecwallet-light-cli was not designed for this usecase, and doing this in the light client will be worse on multiple dimensions vs using a full node

  • Bandwidth will be worse, downloading all txns will consume ~110% of a fullnode's. Because of the way the light client protocol works, some bytes will be downloaded twice
  • Privacy will be worse, since now you still have to trust lightwalletd to give you the correct data, vs using the p2p network with the full node
  • Latency will be way worse - Lightwalletd doesn't index the individual txns, and it will hammer the underlying zcashd, relying on it's on-disk index, making latency way worse
  • Compute will be worse - A lot of CPU will be duplicated on lightwalletd and on the lightclient

Also, I don't think the number is 70% for bandwidth saving - I checked the last 100k blocks, and the reduction is over 95%.

There are several engineering problems with the approach as well. Note that the lightwallet protocol doesn't "download blocks", it downloads individual txns, so what you are really suggesting is to download all txns (contained in all blocks). Caching / Indexing this in lightwalletd is difficult (and worse than using a full node). In the full node's case, there is a wallet, so it can effectively cache and index all txns it cares about, while lightwalletd won't be able to do this, since it doesn't know what txns are interesting to the client. This will also make the trust in lightwalletd way worse, since a compromised lightwalletd can still mislead the client (by withholding txns, by reodering them, or by simply inserting unmined txns - For details, check the threat model).

Finally, there are financial considerations. A lightwalletd that serves all blocks/txns is going to be very expensive to run. By my calculations, Zecwallet's web hosting costs will be 20x (Because of the additional bandwidth and to a smaller extent the worse latency/compute)

It seems like if you want to offer this, you should simply run the full node on the user's desktop. Doing this via lightwalletd is fraught with problems - primarily because this is not what the light client was designed for.

This is why Zecwallet offers both the full node version and the light client version, allowing users to chose what model they want to use.

To be fair, the actual bandwidth savings are variable, dependent on

  • The checkpoint the wallet is using
  • The relative density of txns in the blocks
  • How many memos the client downloads.

We'll test to see what the typical bandwidth savings are for our users and revisit this.

See this comment: https://github.com/zcash/zcash-android-wallet/issues/166#issuecomment-703777524 tl;dr while it's true not downloading all the memos saves ~85% bandwidth theoretically, in absolute terms that only works out to ~300MB to sync a wallet starting at Sapling activation, given the current usage level.

@adityapk00 it looks like the consensus emerging in the thread @defuse links to is that PIR + Tor is the best approach for memo retrieval, but that it is difficult to implement, so it might make sense to deliver all data to all lightwallet users even if this is costly and requires some engineering work to be efficient.

Another idea posted to the thread is to use a CDN to address the speed issues with downloading that data. I think this also increases the cost but it could decrease the server load.

Thoughts?