Closed evan-gray closed 1 year ago
I propose allocating the entire range of 200-255 (inclusive) of consistency_level for magic numbers and have the guardians not process any messages with consistency_level in that range where a magic number has not been allocated. (on all chains). We should also check if there are any xApps who are actively using values in that range (I hope not). I also propose not using the same magic number across multiple chains, e.g. if 201 means "safe" on Ethereum, guardians should not process messages with the value 201 originating on other chains.
What do you think of adding a special magic value (maybe zero) that is valid across all chains and would default to the Wormhole recommendations for ensured consensus specific to each chain, i.e. the values here: https://book.wormhole.com/reference/contracts.html#blockchain-finality-recommendations.
That way, integrators have a secure default, which is very convenient for deploying the same code on multiple chains.
Q: I'm curious what you think consistency_level in the range of 1-32 should map to after making this change. I think it should map to the amount of blocks after "latest", i.e. not wait for eth "safe" to be reached. This could have unintended consequences for xApps already deployed, so we'd need to announce this change well in advance and give time to xApps to upgrade.
In summary I'm proposing the following course of action:
What do you think of adding a special magic value (maybe zero) that is valid across all chains and would default to the Wormhole recommendations for ensured consensus specific to each chain, i.e. the values here: https://book.wormhole.com/reference/contracts.html#blockchain-finality-recommendations.
That way, integrators have a secure default, which is very convenient for deploying the same code on multiple chains.
Personally, I'd prefer any non-reserved value to be safe - the only tricky one is BSC 🤔
Q: I'm curious what you think consistency_level in the range of 1-32 should map to after making this change. I think it should map to the amount of blocks after "latest", i.e. not wait for eth "safe" to be reached. This could have unintended consequences for xApps already deployed, so we'd need to announce this change well in advance and give time to xApps to upgrade.
Quick note, Eth waits for "finalized" not "safe". Outside of BSC, setting any number here is rather irrelevant or wouldn't do the right thing, so I'm not keen on maintaining the existing functionality. Instead, I suggest all values should simply be treated as 'finalized + 0`
I believe there was a reason that 0 should not be set for consistency
(maybe because it's a default uninitialized value) and it's also kinda odd to me that 0
would be finalized but 1
wouldn't be. @hendrikhofstadt can opine.
But do you think there are xApps who might want to go even faster on Ethereum than "safe", i.e. n
blocks where 0<=n<32
.
I could think of a scenario where an xApp only cares about making sure that the message was validated on chain and doesn't care about consensus.
An example would be Pyth, although Pyth is not emitting from Ethereum.
But do you think there are xApps who might want to go even faster on Ethereum than "safe", i.e.
n
blocks where0<=n<32
. I could think of a scenario where an xApp only cares about making sure that the message was validated on chain and doesn't care about consensus. An example would be Pyth, although Pyth is not emitting from Ethereum.
I assume you're using 32 here because that's an epoch? Absolutely folks want to go faster, that's why my original suggestion here was 200
= "as soon as the watcher sees it". I honestly don't see a great cause for waiting, like, 3 blocks instead of just 1. Seems like on Eth today you want your options to be:
which would map to
I propose allocating the entire range of 200-255 (inclusive) of consistency_level for magic numbers and have the guardians not process any messages with consistency_level in that range where a magic number has not been allocated. (on all chains). We should also check if there are any xApps who are actively using values in that range (I hope not). I also propose not using the same magic number across multiple chains, e.g. if 201 means "safe" on Ethereum, guardians should not process messages with the value 201 originating on other chains.
I wonder if 55 levels may not be enough if we are reserving, potentially, 2+ per chain. I wonder if we can group chains together. eg. 200 => immediate for Eth and all EVMs, 210 => immediate for all cosmwasm chains?
I propose allocating the entire range of 200-255 (inclusive) of consistency_level for magic numbers and have the guardians not process any messages with consistency_level in that range where a magic number has not been allocated. (on all chains). We should also check if there are any xApps who are actively using values in that range (I hope not). I also propose not using the same magic number across multiple chains, e.g. if 201 means "safe" on Ethereum, guardians should not process messages with the value 201 originating on other chains.
I wonder if 55 levels may not be enough if we are reserving, potentially, 2+ per chain. I wonder if we can group chains together. eg. 200 => immediate for Eth and all EVMs, 210 => immediate for all cosmwasm chains?
@panoel this is only applicable to EVM chains, since this is specific to the EVM watcher. The core Solidity contract has this consistencyLevel
parameter on the publishMessage
function, which does not exist on every implementation (e.g. cosmwasm's PostMessage
has no equivalent as Tendermint has instant finality). Similarly, Solana has its own enum system where 0
is confirmed
and 1
is finalized
. That said, I expect most EVM chains will not have that many permutations of these concepts and we can certainly reuse the enums across chains - so 200
would mean publish immediately on all chains that use the EVM watcher / Solidity contracts, and 201
would mean safe
for all chains that have that concept (currently only Ethereum, though more may follow this RPC API) and default to finalized
if not.
Expected Behavior
For chains which feature finality but not instant finality (Ethereum, Moonbeam, Polygon, etc), I should have the option to accept the risk of emitting a message prior to finality. For chains that have explicit block statuses, e.g. how post-merge Ethereum has Unfinalized and Unfinalized (Safe), I should be able to specify at which status I want my message emitted.
Furthermore, the default
postMessage
behavior should be to wait for finality and not longer. It doesn't make sense to wait for 1 block after a finalized block. This would make explainer pages like https://book.wormhole.com/reference/contracts.html#blockchain-finality-recommendations only necessary for advanced integrators who want to go faster, into unsafe territory.Current Behavior
The EVM watcher puts all messages into a pending queue, which only releases messages after their block + consistency has been finalized. Even on the lowest consistency, 1, chains in which blocks are final require waiting until the following final block.
Possible Solution
Given that the existing EVM spec has
consistency
as a uint8, a 'magic number' could be specified to represent these special state exceptions for chains. For example:200
= Unfinalized201
= Unfinalized (Safe), only applicable to EthereumThen, when the watcher receives a message with the
consistency
set to200
, it could instantly publish it instead of adding it to the pending queue. To handle achieving faster finality without unnecessarily waiting additional blocks, for any other values the watcher could useminConfirmations
(and probably rename thatfinalityConfirmations
or something). This could be set to 0 for all chains except for BSC which 15 is recommended.That leaves the only odd case of
201
on Ethereum. Since every epoch should yield a new final batch and a safe batch, the watcher could leave the "Safe" number201
which could be checked in the pending loop on new blocks and fall into a new, special path which usesgetBlock("safe")
.