librustzcash
librustzcash copied to clipboard
Make Sapling spend and output arity configurable in transaction builder
This enables the caller to specify a preferred policy for padding Sapling spends or outputs to a specific arity. The existing default (no padding of spends, padding to 2 outputs if there are any spends) is maintained.
I'm interested in feedback around both the API itself and the way we expose and suggest using this functionality. In particular, how much free control should callers have over this? Currently this PR enables specifying quite granular policies, but perhaps instead we should have pre-defined "levels of padding" that the caller chooses from?
I have very high level opinionated feedback. ;-)
In my opinion there should be three layers of wallet design and implementation: "core functionality", "safe-and-convenient-layer", and "everything above the other two".
Every wallet implementer should use the safe-and-convenient-layer API unless they are consulting with privacy / security experts focused on Zcash domain.
The flipside: Very few teams should write directly atop the core functionality API.
So my opinion here is to have those two bottom layers extremely well segregated, and >95% of applications using "safe-and-convenient". If I understand this PR, it blurs those two layers, because a field like spend_arity: Option<Arity>
seems to mean "hey, we provide a good default, but if you know what you are doing, you can provide your own arity specification". Is that correct?
The problem I see with this approach is that there is then "one layer" in the API and there will end up being many different cases like this for different features/behaviors where there may be an easy-to-override safe default. My experience leads me to believe with that kind of approach many wallets will not use the safe defaults, and overall the ecosystem will have less security & privacy. For example, it may be very easy to distinguish wallets by an intersection attack of all the non-default behaviors those wallets do, such as if each wallet (or each wallet version) specifies a different arity specification.
By contrast, if there were a "safe-and-convenient" layer then we could scrutinize and chastize any wallets not using that layer.
One nice thing is that this can simplify the "experts-only core layer" because, for example, that layer can require the caller to specify exactly how arity works without providing a default or allowing optionality.
I'm not saying it's easy to make a good "safe-and-convenient" layer! Every app developer will want to pull its functionality in different directions, and it will never cover 100% use cases. I believe to do a "safe-and-convenient" layer successfully requires saying "no" to app developers for various use case requests. It requires introducing a forcing function on app developers that constrains their use cases, which is difficult to do successfully.
Another issue is that such a layer separation cannot just pop out of no-where since the safe-but-convenient layer is very hard to get right, so I think it has to be a long-running consistent intention to introduce this separation.
A "safe-and-convenient layer" has two crucial design goals: work well for 80% (or maybe 95%) of use cases, and design that layer with systemic security in mind. Some example systemic security considerations:
- what is the standard dummy arity selection?
- which notes should be selected for the user's request?
- should "background" note join/split activity happen? When/how?
- what anchor should be selected?
- (light wallets) when should I request information from the blockchain service provider and what information should I request?
Answering all of those, I believe, leads to a fairly high level API, since it has to access a notes database, schedule networking operations, etc…
So in summary, my high level opinion is that instead of providing a single API with many cases of "safe defaults that are easy to override" split into two layers: low-level experts only, and a less flexible "safe-but-convenient" layer. For example, I believe a safe-but-convenient layer would not allow the application developer to specify anything about arity.