I started replying to the quote below:
and then realised that topic was mis-named (it is actually proposing a specific solution, not discussing the general question), so I’m creating this topic for the general discussion.
Someone asked me some similar questions a few weeks ago:
If 10 million people tried at the same time to make a transaction what would happen?
I responded with the following rough arithmetic, which assumes 2-in 2-out transactions (400 bytes for transparent, 2800 bytes for Sapling), as that seems more reasonable than 1-in 2-out (since it allows for merging notes as well as splitting them). I assume that all 10 million transactions are either only-transparent, or only-Sapling.
- A block can fit 5000 transparent txs, or around 714 Sapling txs. So that’s around 67 transparent txs per second, or 9.5 Sapling txs per second.
- If 10 million transactions were created at once, and sent to a node with the default for
-mempooltxcostlimit
, all but 20,000 transactions would be dropped.- The mempool size limit exists for DoS mitigation, per ZIP 401. Individual node operators can bump this limit, but the default is set such that the mempool can hold 40 block’s worth of transactions, which is the default expiry height.
- At these transaction sizes, both transparent and Sapling txs have the minimum mempool cost, under current cost weightings (that were selected to ensure Sapling transactions were not evicted from the mempool preferentially over transparent transactions).
- If spread uniquely across the 150-200 good
zcashd
nodes we have, that could be up to 3-4 million txs in the global mempool.
Now assume no mempool size restrictions; all 10 million transactions are in the mempool.
- If they were all Sapling, it would take around 14,000 blocks to mine them all (over 12 days).
- The default transaction expiry is 40 blocks, and almost all Sapling transactions use the default, so we could realistically only mine around 28,500 transactions before the remainder expired. This is intentional behaviour, per ZIP 203.
- If they were all transparent, it would take around 2000 blocks to mine them all (a bit under 2 days).
- AFAIK transparent transactions usually don’t bother to set a transaction expiry (because they are created with Bitcoin libraries for which expiry is a foreign concept, and we didn’t make transaction expiry a required field), so the funds would be stuck in the mempool until the transactions were mined.
You are correct: because detection of inbound notes cannot currently be performed without trial-decrypting every output in the chain, the time to sync a wallet to its fully-accurate balance are linear in the number of new Sapling outputs (and thus will increase both with length-of-time since last sync, and with more Sapling transactions per block).
One way around this is to move detection out-of-band, by having the sender tell the recipient where on-chain the transaction is mined (and optionally give them the note directly, though the recipient still needs to have the chain data to create a witness). But that requires an interactive channel, and doesn’t help for non-interactive payments.
Another way around this, at least from a usability perspective, is to not require wallet balances to always be fully-accurate. I have a design I’m working on for a way to sync wallets that should be orders of magnitude faster in the average case, at the expense of a slightly more complex UX (which I believe @geffen can handle ). It still doesn’t avoid the linear scan for detecting new notes, however.
Moving to ideas that require network upgrades: if we can figure out a way to make detection keys usable, this would allow light clients to offload detection to a third party. The third party would learn which transactions belong to the user (possibly with some noise depending on the protocol), but would not learn transaction contents. If the protocol were efficient enough and suitably compatible, it might be possible to execute it in a PIR scheme to greatly reduce what the third party learns.
None of this addresses the on-chain scaling issue: there’s a limit to how much data we can shove into blocks, and how long a block can take to verify. I’m not going to go into that right now though, because it’s 1:20am