Category: Business Logic
IBC does not work with chains that generate subsecond blocks
Critical Severity
High Impact
High Likelihood
Description
The _checkUpdateResult
function ensures that the timestamp of the new valid submitted consensus state (newConsensusState.timestamp
) is greater than the last trusted consensus state, trustedConsensusState.timestamp
.
function _checkUpdateResult(IUpdateClientMsgs.UpdateClientOutput memory output)
private
view
returns (ILightClientMsgs.UpdateResult)
{
bytes32 consensusStateHash = _consensusStateHashes[output.newHeight.revisionHeight];
if (consensusStateHash == bytes32(0)) {
// No consensus state at the new height, so no misbehaviour
return ILightClientMsgs.UpdateResult.Update;
} else if (
consensusStateHash != keccak256(abi.encode(output.newConsensusState))
|| output.trustedConsensusState.timestamp >= output.newConsensusState.timestamp
) {
// The consensus state at the new height is different than the one in the mapping
// or the timestamp is not increasing
return ILightClientMsgs.UpdateResult.Misbehaviour;
However, this invariant does not hold for chains that can produce more than a block a second.
Impact
IBC clients will be frozen. IBC will not work on chains that generate more than one block a second (subsecond blockchains).
Recommendations
Adjust the timestamp to use finer-grained measures, such as milliseconds or even nanoseconds.
Remediation
This issue has been acknowledged by Interchain Labs, and a fix was implemented in commit b05dea16↗.