Skip to content

Instantly share code, notes, and snippets.

@clemensgg
Last active February 13, 2023 15:31
Show Gist options
  • Save clemensgg/2f7719b5299e6411046ba2289c08283b to your computer and use it in GitHub Desktop.
Save clemensgg/2f7719b5299e6411046ba2289c08283b to your computer and use it in GitHub Desktop.
Validate IBC client update proposal
#!/bin/bash
# needs the given block height states available on the reference chain (RPC)
PROP_ID=$1
HOST_CHAIN_LCD=$2
REF_CHAIN_RPC=$3
COL_RED='\033[0;31m'
COL_GREEN='\033[0;32m'
COL_NC='\033[0m'
echo "running validate_ibc_client_update_proposal.sh..."
HELP=false
while getopts ":h" option ; do
case $option in
h) HELP=true ;;
\?) echo "Invalid option -$OPTARG" >&2 && HELP=true ;;
esac
done
# check input, remove trailing slashes
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] ; then
HELP=true;
fi
if [[ "${HOST_CHAIN_LCD: -1}" == "/" ]] ; then
HOST_CHAIN_LCD="${HOST_CHAIN_LCD::-1}"
fi
if [[ "${REF_CHAIN_RPC: -1}" == "/" ]] ; then
REF_CHAIN_RPC="${REF_CHAIN_RPC::-1}"
fi
if $HELP ; then
echo 'Usage: ./validate_ibc_client_update_proposal.sh <PROPOSAL_ID> <HOST_CHAIN_REST_ENDPOINT> <REFERENCE_CHAIN_RPC_ENDPOINT>
-h print help message'
exit
fi
check_endpoints() {
TEST_LCD=$(curl -s --connect-timeout 3 $HOST_CHAIN_LCD)
if [ -z "$TEST_LCD" ] ; then
echo "error fetching HOST_CHAIN_REST_ENDPOINT: $HOST_CHAIN_LCD" >&2
exit 1
fi
TEST_RPC=$(curl -s --connect-timeout 3 $REF_CHAIN_RPC)
if [ -z "$TEST_RPC" ] ; then
echo "error fetching REFERENCE_CHAIN_RPC_ENDPOINT: $REF_CHAIN_RPC" >&2
exit 1
fi
}
fetch_prop_data() {
PROP_DATA=$(curl --connect-timeout 3 -s $HOST_CHAIN_LCD/cosmos/gov/v1beta1/proposals/$PROP_ID)
TITLE=$(echo $PROP_DATA | jq -r '.proposal.content.title')
if [ ! -z "$TITLE" ] ; then
SUBJ_CLIENT_ID=$(echo $PROP_DATA | jq -r '.proposal.content.subject_client_id')
SUBS_CLIENT_ID=$(echo $PROP_DATA | jq -r '.proposal.content.substitute_client_id')
else
echo "error fetching proposal, check proposal ID: $PROP_ID" >&2
exit 1
fi
}
fetch_client_states() {
echo "fetching ibc client states..."
SUBJ_CLIENT_HEIGHT=$(curl --connect-timeout 3 -s $HOST_CHAIN_LCD/ibc/core/client/v1/client_states/$SUBJ_CLIENT_ID | jq -r '.client_state.latest_height.revision_height')
SUBJ_CLIENT_REVNUM=$(curl --connect-timeout 3 -s $HOST_CHAIN_LCD/ibc/core/client/v1/client_states/$SUBJ_CLIENT_ID | jq -r '.client_state.latest_height.revision_number')
SUBJ_CLIENT_VALSET_NEXTHASH=$(curl --connect-timeout 3 -s $HOST_CHAIN_LCD/ibc/core/client/v1/consensus_states/$SUBJ_CLIENT_ID/revision/$SUBJ_CLIENT_REVNUM/height/$SUBJ_CLIENT_HEIGHT | jq -r '.consensus_state.next_validators_hash')
SUBS_CLIENT_HEIGHT=$(curl --connect-timeout 3 -s $HOST_CHAIN_LCD/ibc/core/client/v1/client_states/$SUBS_CLIENT_ID | jq -r '.client_state.latest_height.revision_height')
SUBS_CLIENT_REVNUM=$(curl --connect-timeout 3 -s $HOST_CHAIN_LCD/ibc/core/client/v1/client_states/$SUBS_CLIENT_ID | jq -r '.client_state.latest_height.revision_number')
SUBS_CLIENT_VALSET_NEXTHASH=$(curl --connect-timeout 3 -s $HOST_CHAIN_LCD/ibc/core/client/v1/consensus_states/$SUBS_CLIENT_ID/revision/$SUBS_CLIENT_REVNUM/height/$SUBS_CLIENT_HEIGHT | jq -r '.consensus_state.next_validators_hash')
}
fetch_valsets() {
echo "fetching block data on reference chain..."
REF_SUBJ_CLIENT_VALSET_NEXTHASH=$(curl --connect-timeout 3 -s $REF_CHAIN_RPC'/block?height='$SUBJ_CLIENT_HEIGHT | jq -r '.result.block.header.next_validators_hash')
REF_SUBS_CLIENT_VALSET_NEXTHASH=$(curl --connect-timeout 3 -s $REF_CHAIN_RPC'/block?height='$SUBS_CLIENT_HEIGHT | jq -r '.result.block.header.next_validators_hash')
}
print_results() {
echo "----------------------------------"
echo "title: $TITLE"
echo ">>> subject client id: $SUBJ_CLIENT_ID - last revision: $SUBJ_CLIENT_REVNUM height: $SUBJ_CLIENT_HEIGHT"
echo "host: $SUBJ_CLIENT_VALSET_NEXTHASH | reference: $REF_SUBJ_CLIENT_VALSET_NEXTHASH"
echo "<<< substit client id: $SUBS_CLIENT_ID - last revision: $SUBS_CLIENT_REVNUM height: $SUBS_CLIENT_HEIGHT"
echo "host: $SUBS_CLIENT_VALSET_NEXTHASH | reference: $REF_SUBS_CLIENT_VALSET_NEXTHASH"
echo "----------------------------------"
}
validate_hashes() {
VAL_SUBJ_CLIENT=$(diff -s <(echo $SUBJ_CLIENT_VALSET_NEXTHASH) <(echo $REF_SUBJ_CLIENT_VALSET_NEXTHASH))
VAL_SUBS_CLIENT=$(diff -s <(echo $SUBS_CLIENT_VALSET_NEXTHASH) <(echo $REF_SUBS_CLIENT_VALSET_NEXTHASH))
if [[ $VAL_SUBJ_CLIENT == *"are identical"* ]] ; then
echo -e "${COL_GREEN}\U2705 subject client valid! ${COL_NC}"
else
echo -e "${COL_RED}\U274C subject client NOT VALID! \U274C ${COL_NC}"
fi
if [[ $VAL_SUBS_CLIENT == *"are identical"* ]] ; then
echo -e "${COL_GREEN}\U2705 substitute client valid! ${COL_NC}"
else
echo -e "${COL_RED}\U274C substitute client NOT VALID! \U274C ${COL_NC}"
fi
}
main() {
check_endpoints
fetch_prop_data
fetch_client_states
fetch_valsets
print_results
validate_hashes
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment