-
Notifications
You must be signed in to change notification settings - Fork 374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add eth_batchCall
#312
base: main
Are you sure you want to change the base?
Add eth_batchCall
#312
Changes from 7 commits
cb23322
d7bb95f
f8c2444
9bf4970
7aba9c3
9861fd8
12e530f
57697c3
4e680a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,112 @@ | ||||||
MulticallArgs: | ||||||
title: Arguments for multi call | ||||||
type: object | ||||||
required: | ||||||
- block | ||||||
- calls | ||||||
properties: | ||||||
block: | ||||||
title: Block tag | ||||||
$ref: '#/components/schemas/BlockNumberOrTag' | ||||||
stateOverrides: | ||||||
title: State overrides | ||||||
$ref: '#/components/schemas/StateOverrides' | ||||||
blockOverrides: | ||||||
title: Overrides for block metadata | ||||||
$ref: '#/components/schemas/BlockOverrides' | ||||||
calls: | ||||||
title: List of calls | ||||||
$ref: '#/components/schemas/Calls' | ||||||
Calls: | ||||||
title: List of message calls | ||||||
type: array | ||||||
items: | ||||||
$ref: '#/components/schemas/GenericTransaction' | ||||||
StateOverrides: | ||||||
title: Accounts in state to be overridden | ||||||
type: object | ||||||
additionalProperties: | ||||||
$ref: '#/components/schemas/AccountOverride' | ||||||
AccountOverride: | ||||||
title: Details of an account to be overridden | ||||||
type: object | ||||||
oneOf: | ||||||
- $ref: '#/components/schemas/AccountOverrideState' | ||||||
- $ref: '#/components/schemas/AccountOverrideStateDiff' | ||||||
AccountOverrideState: | ||||||
title: Account override with whole storage replacement | ||||||
properties: | ||||||
nonce: | ||||||
title: Nonce | ||||||
$ref: '#/components/schemas/uint64' | ||||||
balance: | ||||||
title: Balance | ||||||
$ref: '#/components/schemas/uint256' | ||||||
code: | ||||||
title: Code | ||||||
$ref: '#/components/schemas/bytes' | ||||||
state: | ||||||
title: Storage | ||||||
$ref: '#/components/schemas/AccountStorage' | ||||||
AccountOverrideStateDiff: | ||||||
title: Account override with partial storage modification | ||||||
properties: | ||||||
nonce: | ||||||
title: Nonce | ||||||
$ref: '#/components/schemas/uint64' | ||||||
balance: | ||||||
title: Balance | ||||||
$ref: '#/components/schemas/uint256' | ||||||
code: | ||||||
title: Code | ||||||
$ref: '#/components/schemas/bytes' | ||||||
stateDiff: | ||||||
title: Storage difference | ||||||
$ref: '#/components/schemas/AccountStorage' | ||||||
AccountStorage: | ||||||
title: Storage slots for an account | ||||||
type: object | ||||||
additionalProperties: | ||||||
- $ref: '#/components/schemas/hash32' | ||||||
BlockOverrides: | ||||||
title: Context fields related to the block being executed | ||||||
type: object | ||||||
properties: | ||||||
number: | ||||||
title: Number | ||||||
$ref: '#/components/schemas/uint256' | ||||||
difficulty: | ||||||
title: Difficulty | ||||||
$ref: '#/components/schemas/uint256' | ||||||
s1na marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
time: | ||||||
title: Time | ||||||
$ref: '#/components/schemas/uint256' | ||||||
gasLimit: | ||||||
title: Gas limit | ||||||
$ref: '#/components/schemas/uint64' | ||||||
coinbase: | ||||||
title: Coinbase | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I believe |
||||||
$ref: '#/components/schemas/address' | ||||||
random: | ||||||
title: Random | ||||||
$ref: '#/components/schemas/hash32' | ||||||
baseFee: | ||||||
title: Base fee | ||||||
$ref: '#/components/schemas/uint256' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have a mechanism for indicating optionality? I feel like all of these should be optional and have reasonable defaults provided by the execution client. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also feel like these should be constrained to values that otherwise pass validation so clients don't have to write code that skips over any more validation than necessary (skipping block signature for example is necessary). For example, block number must be monotonically increasing, time must be strictly greater than previous block, gasLimit cannot change more than 1/1024 from previous block, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The default value will be taken from the
Is this still a concern now that there's one set of block overrides for the whole batch? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be clearly indicated in this specification, perhaps in a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think these are still relevant. If you are building off of block There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: On Gas limit there may be value in expressly allowing changes that are against consensus rules so that people can do series of calls that are more than the current gas limit. |
||||||
CallResults: | ||||||
title: Results of multi call | ||||||
type: array | ||||||
items: | ||||||
$ref: '#/components/schemas/CallResult' | ||||||
CallResult: | ||||||
title: Result of a call | ||||||
type: object | ||||||
required: | ||||||
- return | ||||||
properties: | ||||||
return: | ||||||
title: Return data | ||||||
$ref: '#/components/schemas/bytes' | ||||||
error: | ||||||
title: Execution error | ||||||
type: string | ||||||
Comment on lines
+110
to
+112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does I think this should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify this is not directly evm revert error. It encompasses other errors such as OOG. If call reverts the error will be "execution reverted" and the Happy to change the description of the field if it is confusing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be good to indicate that in the case of an EVM revert, Is there a way in this schema to express that
Comment on lines
+101
to
+112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The result for each transaction should include logs and gas spent as well. I suspect that all clients are generating this information anyway, and throwing it away is a waste when we could just return it all. In many cases, this will also make it so the caller doesn't need to do multiple round trips (e.g., once for gas estimate and again for speculative execution and again to read a deterministic event like contract creation details). If the call is a contract creation ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@s1na mentioned an argument against including gas spent in the return interface (here). The intention I mentioned was to use the gas spent as is for gas limits, which I agree would fail when tx. However, including gas spent in the response could still be useful if utilized with care (passing a factor of more gas for e.g. to account for 63/64 gas passed to child msg calls). And in the documentation, a note can be mentioned that gas spent is not accurate to be used as gas limit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally don't think it is worth trying to optimize the edge case where someone does I think the value add of returning gas used far outweighs the downsides of it being wrong in a handful of esoteric scenarios. I do recommend that we standardize on the amount of gas provided to each call in This would prevent people from using this to do mega gas operations, but I think we can address that by simply having There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still think Re There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting an upper bound on the gas able to be used by an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify: what I meant was there is a CLI flag anyway that will set a limit for all
Adding a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Such a setting feels like it is out of scope of this standard? I might be able to be convinced that it is relevant, but rate limiting features and DoS protection generally aren't standardized. What we need to standardize is "how much gas is given when the parameter is missing" and picking something "reasonable" (e.g., not 2^256, and not 30,000) as a default feels like the right way to go to me. If a particular client has limits that are lower than that (such as from configuration) then they should return an appropriate rate limiting error and require the user to explicitly set the gas limits in their requests I think if the user exceeds those limits. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that the However, there's really two uses for gas that should be handled: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels out of place here. What is the reasoning for having this as a parameter? It also greatly complicates implementation in some clients I believe compared to not including it so I would like to see a compelling reason for its inclusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a greatly used feature of eth_call. I agree it is less necessary in multicall since you can build up the state in previous calls. However not all state mutations are possible (e.g. simply replacing a contract code).
I agree this is extra work for client devs. However I would like to hear from them if this is indeed a complication. It seems to me all have a way to build a temporary state for serving eth_call. This goes a step further to modify parts of that state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the state override feature is probably useful enough to warrant the complexity. I can imagine a security researcher breaking a problem down into two parts. If this value ever can become X, there is a vulnerability to report. They could research that aspect first (as it might be simpler) then research "can this value ever become X".
Could also fake signers of a multi-sig that use store approvals (as many do).