EIP-1985: Sane limits for certain EVM parameters

I actually thought uncles are also fully verified.

Anyway, we intentionally assigned the limits to the EVM only, but consequences of these are also outside of EVM because a node will have to make sure the numbers being passed can fit.

That’s easy to think, and normally they would be, as an uncle generally exists as a head somewhere before it becomes uncled. However, on the blockchain, uncles are only headers without bodies, so it’s impossible to actually execute transactions in an uncle given only the chain of canon blocks – the transactions are missing (hashes too, only the combined txhash remain).

And it would be a problem of recursion. In order to validate a block, you’d need to validate the uncles. In order to validate an uncle, you’d neeed to validate it’s uncles, and so on indefinitely.

Right, but that’s a simpler thing to fix within the node, just to make sure that whatever environment struct that’s passed to the evm uses only 63 bits. Just as long as the node does not enforce that for uncle timestamps we’re fine.

1 Like

Cannot we just go with this to simplify everyone’s life in the long term (while making it worse in the short term)?

Side-note: @winsvega called for a similar clarification https://github.com/ethereum/EIPs/issues/604

In 2016, EIP-92 by @chfast proposed a similar limit. There is a long discussion there about other limits, all of which (with the exception of balance/values) are covered.

I updated EIP-1985 with PC: https://github.com/ethereum/EIPs/pull/2179

It has been also suggested that the buffer limit (2^32 - 1) should also cap the EVM memory.

Although not strictly related to EVM semantics, it seems reasonable to include clarifying the range of other transaction related parameters in this EIP.
There is currently a discrepancy in what geth does and what the TransactionTests enforce when it comes to nonce and gasPrice:
geth uses uint64 for transaction nonces while the TransactionTests use uint256
geth uses uint256 for gas price while the TransactionTests use uint64.

It seems reasonable to me to restrict both nonce and gasPrice to uint64 for transactions.

This EIP originally aimed to describe these restrictions throughout the systems, but we’ve decided to focus on the EVM only to make the EIP simpler to argue about (change was made here).

I’m open to making it more comprehensive as long as we can get it accepted and implemented by clients (hopefully without a “hard fork” aka. enforcing it starting from genesis).

1 Like

A 64-bit size for Chain ID was proposed during discussion of EIP-1344, but ultimately dropped for brevity of implementation during the upcoming fork. This EIP could make that limit explicit without any issues to existing choices of Chain ID of different networks.

I believe my previous claim about gasPrice is incorrect. It seems both the transaction tests and geth uses uint256 for gasPrice so I guess it cannot be restricted here. For nonce the question remains though (in the transaction validation process)

Someone on the chat list on https://www.youtube.com/watch?v=aZ0S_oLSwhE suggested:

For 1985 I would like to have clarity on the GASPRICE opcode as well

Recommend changing all of the 264-1 limits to 252. I believe there would be no pragmatic difference, and by fitting in 52-bits it means you can store all possible values precisely in a double. Since a lot of Ethereum dapp work (almost all of it) happens in JavaScript at the moment, and since JS only has double and bigint, it would be helpful to limit where we can to 2**52.

I think this is useful insight.

I would have been in favour of this much more 1-2 years ago, but now with the advent of the native bigint API in browsers this seems to be a lesser problem.

2^52 seems like an awkward limit for any machine/language outside of JavaScript. @chfast what do you think?

What would code look like that checks to see if a number is less than 2^63-1 that would be “awkward” to check against 2^52 instead? The obvious (to me) solution would be something simple like if (value > 2^63-1) throw new Error(), in which case `2^52 is actually 2 characters less typing! Are you imagining some sort of signed-int overflow check that would be simpler or faster or something?

Clarifications first.

  1. The max integer you can store in double float type is 2^53-1. Not 2^52 nor 2^52-1.
  2. We definitely want to express this in number of bits required, so it must be in form of 2^N-1.

In general, I think we can lower the upper bound for gas. We were considering this previously in context of EIP-2045: Particle gas costs for EVM opcodes: the 2^53-1 would give as exactly space for 1000 particles per gas unit. However, I was thinking as low as 2^32-1 or even 2^31-1 — these seem to be enough for the current block gas limits. This is to be discussed.

For quantities and indexes around memories / buffers we were also considering 32-bit range.

For TIMESTAMP the 2^53-1 looks fine while 2^31-1 not so much.

That was in my mind.

Can you describe how that would work in a modern language (Rust, Go, Katlin, C#, TypeScript, etc.)? I didn’t think that any of those languages exposed the CPU level overflow bit, and instead all of them would bubble an exception/error that is almost certainly more expensive than comparing two numbers.

This is now handled by EIP-2681: Limit account nonce to 2^64-1

I wonder what is the best approach here:

  1. Rewriting EIP-1985 in a way that it addresses all the discussed limits on the protocol/state level and clarifies the EVM opcodes.

  2. Creating a handful of independent EIPs for the protocol clarification (could be merged where it makes sense) to get them discussed and accepted quicker. Then once those go through, apply EIP-1985 only dealing with EVM, but depending on those protocol clarifications. One example of this approach is EIP-2681 for nonces.

@MicahZoltu brought up under the EIP-2971 discussions that the number of logs in a transaction has no defined limit. It would be nice to have it explicitly limited to something like 2^32-1 or 2^64-1 logs.

In practice of course it is highly unlikely to hit any of those limits.