Misbehaviour
Table of Contents
Monitoring Misbehaviour and Evidence Submission
Use the misbehaviour command to monitor the updates for a given client, detect certain types of misbehaviour and
submit evidence to the chain. If the evidence passes the on-chain validation, the client is frozen. Further packets
cannot be relayed using the frozen client.
DESCRIPTION:
Listen to client update IBC events and handle misbehaviour
USAGE:
hermes misbehaviour --chain <CHAIN_ID> --client <CLIENT_ID>
OPTIONS:
-h, --help Print help information
REQUIRED:
--chain <CHAIN_ID> Identifier of the chain where client updates are monitored for
misbehaviour
--client <CLIENT_ID> Identifier of the client to be monitored for misbehaviour
The misbehaviour monitor starts by analyzing all headers used in prior client updates. Once finished it registers for update client events and checks any new headers for misbehaviour. If evidence of misbehaviour is found, it submits:
- the tendermint evidence to the reference chain
- the IBC Misbehaviour message with the evidence to the host chain If the chain validates the transaction then the monitor exits.
The following types of misbehaviour are handled:
-
Fork
Assumes at least one consensus state before the fork point exists. Let existing consensus states on chain B be:
[Sn,.., Sf, Sf-1, S0]withSf-1being the most recent state before the fork. Chain A is queried for a headerHf'atSf.heightand if it is different from theHfin the event for the client update (the one that has generatedSfon chain), then the two headers are included in the evidence and submitted. Note that in this case the headers are different but have the same height. -
BFT time violation for an unavailable header
Some header with a height that is higher than the latest height on chain
Ahas been accepted and, a consensus state was created onB. Note that this implies that the timestamp of this header must be within theclock_driftof the client. Assume the client onBhas been updated withh2(not present on/ produced by chainA) and it has a timestamp oft2that is at mostclock_driftin the future. Then the latest header fromAis fetched, let it beh1, with a timestamp oft1. Ift1 >= t2then evidence of misbehavior is submitted to A.
Example
The misbehaviour command outputs an error message displaying MISBEHAVIOUR DETECTED:
hermes misbehaviour --chain ibc-0 --client 07-tendermint-0
Apr 13 20:04:03.347 INFO ibc_relayer::foreign_client: checking misbehaviour for consensus state heights [Height { revision: 1, height: 195 }, Height { revision: 1, height: 85 }, Height { revision: 1, height: 28 }]
Apr 13 20:04:04.425 ERROR ibc_relayer::foreign_client: MISBEHAVIOUR DETECTED ClientId("07-tendermint-0") h1: Height { revision: 1, height: 195 }-Height { revision: 1, height: 85 } h2: Height { revision: 1, height: 195 }-Height { revision: 1, height: 85 }, sending evidence
Apr 13 20:04:05.070 INFO ibc_relayer_cli::commands::misbehaviour: evidence submission result [ClientMisbehaviour(ClientMisbehaviour(Attributes { height: Height { revision: 0, height: 1521 }, client_id: ClientId("07-tendermint-0"), client_type: Tendermint, consensus_height: Height { revision: 1, height: 195 } }))]
Success: Some(
ClientMisbehaviour(
ClientMisbehaviour(
Attributes {
height: Height {
revision: 0,
height: 1521,
},
client_id: ClientId(
"07-tendermint-0",
),
client_type: Tendermint,
consensus_height: Height {
revision: 1,
height: 195,
},
},
),
),
)
Querying client state from this point will show the client is in frozen state, with frozen_height indicating the height at which the client was frozen:
hermes query client state --chain ibc-0 --client 07-tendermint-0
| jq
Which should output:
{
"result": {
"allow_update_after_expiry": true,
"allow_update_after_misbehaviour": true,
"chain_id": "ibc-1",
"frozen_height": {
"revision_height": 16,
"revision_number": 1
},
"latest_height": {
"revision_height": 16,
"revision_number": 1
},
"max_clock_drift": {
"nanos": 0,
"secs": 3
},
"trust_threshold": {
"denominator": "3",
"numerator": "1"
},
"trusting_period": {
"nanos": 0,
"secs": 1209600
},
"unbonding_period": {
"nanos": 0,
"secs": 1814400
},
"upgrade_path": [
"upgrade",
"upgradedIBCState"
]
},
"status": "success"
}