For some use cases this is still perfectly safe behavior, even if it changes values e.g. meta-transactions.
The problem is not that it is safe in some behaviour, the problem is that it can be easily used wrongly. If an application use it wrongly by assuming that simply checking chainID for equality is enough and a hardfork that change the chainID happen, the application get broken.
On that note contrary to what you say, meta transactions themselves would benefit from accepting past chainID. I would actually argue that is indeed unsafe to not do it as there are scenarios where the user will be unavailable to resubmit the meta tx in time. The fact that you do not see it prove that it is easy to used that opcode wrongly.
When users send metatx, they assume the tx will be executed. They don’t expect to have to sign it again (not just resubmitting, as a relayer could do it) later. If the meta-tx smart contract do not allow for past chainID, this assumption break easily at fork transition. A fork should ideally not bother the users. A no downtime solution should always be the goal. So if we can achieve this, we should do it.
It could be argued that around the fork time, wallet could already force the use of future chainID (and relayer would then wait that time before publishing the metatx) but this assume they know what the message is destined to be use for.
A minority-led fork is a special case of the scenario where one side changes chain ID and the other side doesn’t. This scenario is already mentioned.
As mentioned, that special case (which you agreed was an important concern in EIP-1959 discussion. You even pointed that as the weak point of EIP-1959 since it simply return a boolean) can’t be handled properly via the opcode proposed here (see below). As such it should be mentioned in the EIP.
- If the minority fork doesn’t implement replay protection, then yes replays are possible. That should be obvious.
- A properly-implemented caching mechanism can be purely trustless in this scenario, as anyone can operate it (it may even be included within the application’s user flow)
These 2 points show a misunderstanding of the issue.
The smart Contract in question would have replay protection using the caching solution mentioned in the rationale. It thus receive the chainId from the message (and let say it also receive the block number representing the time at which the message was signed) and check it against the cache.
Now let say a minority-led hardfork happen at block X so the minority fork has a new chainID from that time onward while the majority chain keep the same chainID (since it did not fork)
Now let say a user of both majority and minority chain signs a message for that smart contract at block X+1 and want it to be applied to the majority chain only (the purpose of replay protection). Unfortunately the user has no choice but to use the majority chainID which turn out to also be a past chainID of the minority chain (It would already be cached there).
As you can see, a replay is possible. Now the way to prevent the problem is to use the blockNumber provided as part of the message to check if the message block number happen after the fork (if it does then it should not be replayable). Unfortunately since the cache has a delay inherent due to being implemented as a normal smart contract the replay will still be possible for message signed at blockNumber smaller than the blockNumber at which the cache was updated with the latest chain ID.
EIP1965 does not have this issue and allow thus minority-led hard fork to happen without being exposed to replays, This preserves an important decentralisation component of blockchain where we should give equal opportunities to every communities that want to fork away. Of course, in the case of EIP-1344 the replay window is small but that could be critical in some situation.
Also, there may be application-specific scenarios where forcing the use of fork block height to differentiate changes in chain ID would be unnecessary, and potentially even harmful. The example given in the other thread was that of Plasma’s message structure (a fairly large use case for EIP-712 and this proposal).
You simply showed there that plasma did not need to use the precise block number at which the chainID changed.
As for forcing the use of a block number, this is not true. You can always provide your own. In other words both can be used, the application specific block number and the block number assigned by EIP-712. The point is that in order to guarantee replay protection for those application that require the strict version of it, EIP-712 will need to be modified so wallet ensure correct values to protect their users.
messages don’t fall into corner cases, which would not be possible with a strictly fork block height-based mechanism.
As mentioned above, nothing prevent you from using a different mechanism for blockNumber. EIP1965 will still allow you to verify that a chainID was valid at a specific block no matter how you came up with that number.
To conclude, while I agree that not all points mentioned need to be added/ expanded in the rationale. the point about minority-led hard fork need to be addressed, (like EIP-1959 does for example)
I would also still strongly advise you to clarify better why a naive chainID equality check is dangerous.