EIP-1352: Restricted address range for precompiles/system contracts

These are the points I raised at the allcoredev-call today…

It’s currently possible to configure a genesis with code at arbitrary addresses. For example, to place a faucet at 0x00...0010.
So if we accept 1352, then implement some other EIP which makes calls to precompiles cheaper, the question is of calls to 0x00...10 should, or should not, be included in that (I think they shouldn’t be, since they are stored on disk like any other code, whereas ‘true’ precompiles are already in-memory)

Dangerous. Next you know, someone files a claim that their money should have been given back to them instead of being ‘donated’. I agree that it’s wasted money, but I also see difficulties in picking it up and using it, as opposed to shipping it back to wherever it came from (which would be a technical nightmare to implement)

Right, but the 700 might also already be factored in. If it was substantially lowered, perhaps the actual cost would also have to be raised (in some cases)?

1 Like

I don’t agree. The call should be cheaper for the whole range. Otherwise, the cost of the call depends on the current configuration (not only the EVM revision) and EVM is not able to compute the cost on its own.

From a technical standpoint, i don’t agree, since gas should correlate to work, and it’s more work to fetch the code from disk than invoke an actual compiled method.
From an architectural standpoint, I kind of agree it might be nicer.
From a practical standpoint, I don’t really care, since it’s not an issue for mainnet.

I’m really just saying that the EIP would do well to specify the behaviour.

More quirks:

  • What about extcodesize of a contract in this range? What about extcodehash? All normal precompile addresses return 0 and zerohash respectively.

I think these are really valuable comments. Before going through to answer them, I do have one simple question: how do you define what is a precompile?

Extended questions:
“Hardforks” have a list of precompiles, so does the Yellow Paper. But private chains are free to do whatever they wish with the address range. If they move sha256 from address 0x2 to 0x4242...4242, does it remain a precompile? How do you specify what a precompile is for example in EIP-1109? Would that specify the precompile addresses as 0x1 to 0x8? Would it specify that an address is a precompile when the client says so (because precompiles are not represented in the genesis)?

So the hard fork impact might be

  • Any contract that would wind up deploying to the reserved range fails with an out-of-gas exception.
  • Any TX “from” the reserved range is invalid and should not be seen in blocks.
    • “To” or beneficiary addresses are valid - that ship sailed with Spurious Dragon and ENS.
  • Any call into the reserved range is at the precompiled price (for EIP-2046/EIP-1109)

And this would be across all Istanbul compatible chains, regardless of what precompiles are configured.

Note that EEA now formally plans to require that precompiles in EEA clients are registered using this mechanism…

My thinking is that we might see people who want to note that they have used an address and provide zero information about what they put there, just letting everyone else know there is someone who expects something (so you reduce accidental collision risk). But others will quite probably put a specification.

EEA client spec mandates the presence of, and some requirements for a permissioning contract, which would be an example of something we might give an address and provide a specification of some kind (probably not an actual contract since there are things that can vary from chain to chain).

1 Like

Follow up to my discission on this from AllCore Devs #120 (https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%20120.md)

I brought this up as the scope of precompiles is growing for L2 and alt-eth chains. In particular all L2 chains have at least one system precompile to initiate exits back to L1.

The proposal was to make this proposal impactful by making the whole range “warm”. Martin pointed out this would re-open the broken metre attack.

After thinking about it for two weeks I think the way forward may be to re-open EIP-1109, which is a PRECOMPILEDCALL opcode, that would fail if it called anything but a precompile, and mix it with EIP-2046, which wanted to reduce precompile costs but not make them zero. The proposed fee would be the same as all other CALL series for warm calls, and any call to a non-precompile (as determined by the chain, so hard forks and other-chain additions like L1 exit precompiles would adjust that set) would fail consuming all gas.

As far as when… the next “open” hard fork. It’s not important enough to drive a hard fork and not essential to the merge.

I think making it warm while avoiding the issues with the tree could be accomplished with more drastic changes:

  1. Allocate the range 1…256 for “precompiles”.
  2. Remove these accounts from the tree.
  3. Any account access to this range would just return fixed values (i.e. the null code hash, 0 balance, 0 nonce, etc.)
  4. A call to this range outside of the activated precompiles instantly returns with empty bytes. (This in practice means that the behaviour is the same as today.)
  5. If a call has a value attached, allow the call to be successful, but do not change the account balance.

The critical part is point 5), which ensures that contracts which relied on using one of these addresses for burning can still operate. Important that I omitted the zero address (0x0000000000000000000000000000000000000000 ) as that was never a precompile and is the ultimate “burner address”. (Is this actually a problem worth solving?)

Point 2) is optional, but given point 3) would shadow them, it may as well make sense removing them.

I would be interested what are @holiman’s thoughts on the above?