#Cross contract calls, metering and fees

39 messages · Page 1 of 1 (latest)

torpid mason
#

I've been further examining ERC4337 (Ethereum's chosen Account Abstraction model, following up on #1095061621497409626 message) to try and understand if there's anything we can do to enable this type of transaction "Bundling" in the future and allow for custom accounts to pay fees.

One category of EVM functionality that seems to be important, and is present in abundance in the ERC4337's EntryPoint contract spec relates to cross contract calls, resouce consumption and fees. The EVM allows contracts to:

  1. Specify a resource limit when making a cross contract call
  2. Check the resource consumption of a completed cross contract call (not exactly but you can check how much gas was consumed before and after)
  3. Translate resources consumed to fees in eth (using tx.gasprice)

Obviously this is much easier in ethereum given that resources are uni-dimensional - just gas.

With that said, how much of this is possible in Soroban and what would be the cost to implement what's not?

topaz void
#

I don't think we need to go ETH route implementation-wise. what is the actual goal this is trying to achieve?

#

IIUC the point here is that the contract can compute the fee for the subcontract call... but how would that help us with custom accounts paying the fees?

#

the issue we've mentioned before is that it's hard to validate the fee payment made by a custom account, not necessarily apply it. like even if there is some pooling mechanism that covers a subtree of a contract call, it doesn't solve an issue of whether we should apply this tx in the first place; it still would require a classic account as a fee source

torpid mason
#

ERC4337 allows for the creation of bundlers which bundle groups of invocations off chain and submits them on chain through an entrypoint contract that does a bunch of bookkeeping and collects fees from custom accounts. None of this was a consensus change in Ethereum

topaz void
#

right, but the bundler payment would need to still be performed by a classic account

torpid mason
#

Yeah it's the same in eth. An EOA submits the tx

#

But my point here is not so much about ERC4337 but rather the bigger picture. They were able to build this type of execution meta protocol because the vm provides sufficient context to do that. We don't provide that execution context

topaz void
#

right... what is not clear to me is what is the benefit of doing this on-chain

#

this = limiting the resource requirements

#

I guess it provides a better way of batching the operations together, at cost of more complex APIs and overhead of running an additional contract. also the per-tx limits could be relatively strict in soroban, so not sure how efficient the bundling could be

#

basically currently you can achieve the similar goal without batching; using the channel accounts on the bundler could help with compensating for that (channel accounts might be required in any case, given even volume). the benefit is that the resource consumption would be limited and enforced by conventional mechanisms. need to think through the details though

#

not using on-chain batching also allows to be more smart about the inclusion fees; batching these is not really fair

amber hazel
topaz void
#

I'm still not sure if this is useful outside of the mentioned use case and even for that use case it doesn't really solve all the fee-related questions...

amber hazel
#

I think the ability to control the spend of sub-calls seems useful to other cases. The concept of executing someone elses invocation and wanting to cap the spend seems like a pretty generic problem / need that isn't specific to ERC4337.

#

For example, a bridge or other form of L2 that collects work to be done off-chain, or on some other chain, which gets prepaid by off-Stellar. The bridge / L2 would need to isolate each tx they process on Stellar as a separate top-level invocation to cap the spend. But the bridge might benefit from bundling. Or the L2 might require bundling.

#

Especially if the bridge wants to do rebates. But I don't know if any bridge actually does that.

topaz void
#

yeah, that's a very similar use case. the issue with both is that the fee doesn't just include the instructions and some things that influence the fees are external to the host (like e.g. the transaction size). hence while bundling might be useful in concept, just limiting the subcontract call to a certain number of instructions is incomplete

amber hazel
#

The budgeting system equates inputs to a cpu and memory cost. Couldn't the calling contract cap on that?

topaz void
#

cpu might be capped indeed and we could provide a way to get the cpu usage out of the subcontract call. probably memory is the same. but that can't be used to infer the full fee

#

so I think if we are solving a problem of the fee payments we might need to approach it in a more holistic fashion. I'm not really opposed to just limiting the budget for the subcontract calls, but I really don't see a good use case for that w.r.t. fees (or worse, it can be misused with intent of limiting the fees and then still not get the proper results because of another resources involved)

#

I also don't feel like there is a good way to pool the inclusion fee; as of now it's really tough to tell which part of the fee is going to be larger (inclusion or resource fee) and how much larger

amber hazel
#

the issue with both is that the fee doesn't just include the instructions and some things that influence the fees are external to the host

Is it correct that the host has access to all this other information, or at least could be given this information such that it could expose it to contracts, or help calculate a fee.

topaz void
#

not quite... ledger reads are external to the host and are not tied to any contract invocations. ledger writes are measured at the time they're being written to the ledger (in theory we could look at the upper bound here, but that would also complicate storage significantly and make it more expensive). transaction size is external to host and it's hard to attribute it to the subcontract calls

#

it seems like what we really want here is a multi-operation transaction that doesn't fail if any one of the operations fails... we don't support that, but I feel like it really would be cleaner if we went this route in some fashion

#

the paying party could use preflight to compute the expected resource consumption for a given invocation and ask for the respective fee. this may run into some edge cases if there is a sudden ledger change that also affects the fee significantly, but probably that's not too bad.

amber hazel
#

I thought ledger reads are tied to the footprint. i.e. The footprint will cause everything in it to be loaded.

topaz void
#

right, and the footprint is external to the host (i.e. it's not being dynamically computed during the execution). it's not clear how it can be attributed to a subcontract call

torpid mason
#

what we really want here is a multi-operation transaction that doesn't fail if any one of the operations fails
Thats' one way to look at it and maybe it's worth adding. With that said I think we need to build Soroban bottom up and build something that's generalizable enough for developers to write their own multi invoke execution models that we can't nesscarily put our fingers on right now.

topaz void
#

it is hard to design something that doesn't have requirements and use cases. it probably would be nice to wait and see what the demand is for

torpid mason
#

I gave the use case of erc4337 and leigh gave an example of a bridge. This is already much more than the evm authors had in 2015 when they introduced these relevant opcodes. What they did have is the foresight and intuition that contracts might want to control the way they spend fees and that turned out well. Why not learn from them?

topaz void
#

the same can be said about a lot of features - e.g. we decided to drop the temp storage even though it's already implemented and also has some valid use cases... but in this scenarios there is no straightforward way of doing the same thing as evm does and there are also seemingly another ways of solving the problem, both based on what is already available as well as potential new features.

upper sequoia
#

We do not have time for this. If we want to spend a bit extra time on something fee related, I'd suggest looking into how to make "Fee Bump" work on Soroban transactions (or at least give guidance on how to make this work), This seems higher priority than this (we can always add special "invoke" calls that enforce metering differently if that's what we need -- but even then I am not sure this will actually allow to do bundling)

leaden robin
# amber hazel This is an interesting find. I don't think we considered the possibility that co...

From the host<->VM interaction perspective, yes this is the direction we wanna go. The new charging model of giving the VM a preallocated budget (cpu and mem) and let it perform accounting and limit-checking will happen fairly soon when we migrate to wasmi upstream (https://github.com/stellar/rs-soroban-env/issues/683). Then it should be fairly straightforward for an entry point contract to manage resources of its subcontract calls (though we'll still need to enhance the hostfn call api to pass down the budget info).
I also concur with @topaz void to decouple the total fee for each call is much harder, due to most of the fee components being outside of the host and also needing to support multi-operation and allowing partial operation failure in a tx.

GitHub

Rust environment for Soroban Contracts. Contribute to stellar/rs-soroban-env development by creating an account on GitHub.

topaz void
#

Then it should be fairly straightforward for an entry point contract to manage resources of its subcontract calls (though we'll still need to enhance the hostfn call api to pass down the budget info).
I'm not very familiar with these upcoming wasmi changes, but how would that interact with host fns and built-in contracts?

leaden robin
#

The details are still being worked out. It's not a trivial switch since it requires a different metering pattern we currently have. E.g. if the VM calls a host fn the host needs to tell it how much budget is to be consumed by this call.
I haven't thought much about built-in contracts. If we were to make it consistent we might have to add some budget managing component to it (even though it is part of the native host).

topaz void
#

hmm, that would be weird. built-in contract call is basically just a host fn call (it doesn't need to instantiate the vm), but yeah, if we want to control the budget, then we'd need some duplicate logic... but honestly I'm still not sure if limiting budget on such a granular level should be a requirement at all

upper sequoia
#

What is the update on this? Switching to this other model should not be that bad assuming we can query how much credit is left at the end of an invocation/add to the balance