Introduce mechanism for service fees #1956
Replies: 4 comments 8 replies
Is this not solveable by proving service specifying a price per unit, and then executing the transaction twice? Once without the note to estimate cycles, and second to add the note back in. We could then optimise this with a partial execution - or blank space for the note asset transfer amount since that's the only missing info.. |
|
Thank you for the well-written issue. I would go with your Approach 2. We can add a piece on fee discovery that I think is missing from the original framing. Potential High-level design Three components, no protocol changes required:
For discoverability of the set of services, a separate lightweight on-chain directory account (we can maintain this) lists active service account IDs. Pricing and capabilities never live in the directory, only in each service's own account. Some Pros:
Addressing the cons Another new con is that we overload the client a bit. It now has to handle network fees and service fees which are being paid in different ways, maybe different assets. |
Service fees: two candidate designs and a requirements-based comparisonFollowing up on the discussion above and a call I had with @bobbinth on Friday. Following the network fee discussion, I want to define what a service-fee mechanism actually has to achieve, and then compare the two designs that we believed were best: (a) service payment channels and (b) the Guardian as fee collector. The fee stack problemMiden is accumulating fee layers: protocol fees (almost live), batch-builder fees (0xMiden/protocol#2899), network-account fees (0xMiden/protocol#2901, 0xMiden/protocol#2968), service fees (this thread), and eventually application fees (a DEX will charge its own fee). Each layer with its own mechanism is quite unique and adds lots of complexity on usability. Not only for users (the client can abstract a lot away, but then the already quite heavy client, holding state and proves, gets even more complex ) but for every wallet and integration that has to learn all of them, and for debugging, since each mechanism widens the surface of "why did my transaction fail". For service fees specifically, we can be quite honest. We will subsidize all services in the beginning anyway, so revenue is not the goal. The goals are:
Requirements
Why the earlier options don't meet the bar
That leaves two designs. Proposal (a): Service payment channelsA standardized "payment channel" between a user and the services, built from existing primitives. Can be added to the standards and can serve as example payment channel for other applications. Mechanism.
The deposit is the API key. Channel ID = identity = spam bond. Rate limits are keyed to it. There is no separate key infrastructure to build and later throw away. Going from "subsidized spam protection" to "real fees" is a price change, not a mechanism change. Pros
Cons
Proposal (b): Guardian as fee collector@bobbinth sketched this above; stating it here as a full proposal. Mechanism.
Pros
Cons
Comparison
They compose — but we have to pick the primary railThe two proposals are not mutually exclusive. Under (a), a Guardian can hold channels to downstream services and present one aggregated quote to its users, recovering most of (b)'s UX on top of (a)'s rails. Under (b), channels are the natural fallback for no-guardian users. The decision is which one we standardize and build first, because that choice determines where the ecosystem's fee plumbing consolidates. Rollout in two phases (either proposal)
My leanI have a soft lean toward (a) payment channels, for one architectural and one empirical reason. Architecturally: (b) makes the fee system assume Guardians. Every service that wants to get paid ends up billing through them, guardian-less users become second-class, and we quietly convert an optional convenience layer into mandatory infrastructure. Empirically: (b) only works if there is a healthy, decentralized supply of Guardian operators. Finding teams willing to run Guardians has already proven harder than (at least I) expected. Every additional responsibility we attach to the Guardian (proving, fee collection and settlement with downstream services) raises the bar for operators further and shrinks that supply. Relying on the Guardian as the network's fee backbone means buying that operator-supply risk into the fee system itself. Channels keep the fee system's liveness independent of it. Open questions
|
|
Hey @bobbinth @PhilippGackstatter @mmagician Any updates here? Any info or analysis that would help you to come to a conclusion? |
Uh oh!
There was an error while loading. Please reload this page.
We want the delegated prover and guardian and similar services to be paid for their work and this discussion explores ideas for doing that.
Approach 1
One idea that was discussed is to let these services sign a receipt when they are called. That receipt is attached to the transaction and submitted to the node by the client. The node then allows the service to claim a part of the fee that the user paid as part of the transaction.
These may both be acceptable for now, as we're okay with subsidizing. But it's not an ideal mid/long-term solution, and we'd be creating some technical debt for the future to switch to something else. Ideally, we have a solution that works in the long run.
Approach 2
Another approach is to make the services check that the transaction they are about to prove or sign creates a private P2ID note with a flat fee as payment for the service. If not, the service rejects the request. The "service fee notes" are added automatically by the client in a tx script to a note that uses delegated proving or the guardian.
Thanks to @partylikeits1983 and @Keinberger for the session to think through the second approach!
Note: This issue was discussed in the context of protocol fees, but seems most applicable to the client, since it would need to integrate most of this, afaict. If this is incorrect, we can move it to the protocol repo.
cc @Dominik1999
All reactions