It seems this proposal requires that both sides of a contentious fork adopt different values from what occurred before the fork in order to be considered safe. Failure to do so would break the replay protection in at least one direction. Since there is currently no process for changing chain ID after a fork (such as the one @fulldecent suggested), such process cannot be assumed to occur, and thus this proposal is not safe by itself without additional application-level considerations (similar to EIP 1344). I think this should be made more clear under Rationale.
This is not a situation specific to the particular solution provided here but simply a consequence of the requirement to support older message (signed before the hardfork). This situation is present as soon as a contract need to accept message signed with an older chainID, which as both rationale concur, is a must-have. This is thus also present in the solution presented as part of EIP-1344 rationale to deal with that.
But again, there is no need for any established process. Similarly to how a chain will change its chainID to not have its transaction replayed on another, we can assume that the community that disagree with the changes made as part of an hardfork, will make their own hardfork that simply change the chainID.
I have a paragraph on that situation but I ll see what I can add to the rationale to make this more clear.
Anyways, here are my questions:
How do you protect against a new message signed against an older chain ID? (Signed after the fork occurred)
We don’t do that at the contract level. This is the responsibility of wallets to only sign message that use the latest chainID. this is similar to how this is their responsibility today to use the proper chainID for the chain in question. As such the behaviour of wallet do not need to change : they should reject message attempting to be signed with a different value than the current chainID.
But again here, this is not a situation unique to that opcode, it is simply a consequence of requiring smart contract to support messages with older chainID for the obvious reason mentioned in both rationale (EIP-1344, EIP-1959).
What kinds of application-level effects might occur if all chain IDs in the history are considered valid with differentiating based on time?
There is no extra effects except for the inability for contract to reject messages because they were signed before a hardfork. Assuming wallet do their job, replay protection is guaranteed.
Would it make more sense to emit what block height the chain ID fork occurred at for time-ordering of messages where chain ID update occurred?
We could indeed return the block number at which the chainID was introduced but it does not bring any benefit for the goal of protecting users of off-chain messages against replay attacks.
contrary to EIP-1344, which requires only that the user of such an opcode be aware of and implement a simple strategy to handle many of these scenarios (if required by their application).
As mentioned, your concerns (except for EIP-1959 return values which can stay to be true or false) apply to EIP-1344 too. The important differences is that EIP-1344 can be easily misused and require a contract based solution to be used correctly.