diff --git a/zebra-utils/README.md b/zebra-utils/README.md index 06841f18b..f08f2cbbd 100644 --- a/zebra-utils/README.md +++ b/zebra-utils/README.md @@ -7,6 +7,7 @@ This crate contains tools for zebra maintainers. - [zebra-checkpoints](#zebra-checkpoints) - [zebrad-hash-lookup](#zebrad-hash-lookup) - [zebrad-log-filter](#zebrad-log-filter) +- [zcash-rpc-diff](#zcash-rpc-diff) Binaries are easier to use if they are located in your system execution path. @@ -70,3 +71,63 @@ next: 00000001436277884eef900772f0fcec9566becccebaab4713fd665b60fab309 "))) max_checkpoint_height=Height(419581) ... ``` + +### zcash-rpc-diff + +This program compares `zebrad` and `zcashd` RPC responses. + +Make sure you have zcashd and zebrad installed and synced. + +The script: +1. gets the `zebrad` and `zcashd` tip height and network +2. sends the RPC request to both of them using `zcash-cli` +3. compares the responses using `diff` +4. leaves the full responses in files in a temporary directory, so you can check them in detail + +Assuming `zebrad`'s RPC port is 28232, you should be able to run: +```sh +$ zebra-utils/zcash-rpc-diff 28232 getinfo +Checking zebrad network and tip height... +Checking zcashd network and tip height... + +Request: +getinfo + +Querying zebrad main chain at height 1649797... +Querying zcashd main chain at height 1649797... + +Response diff (between zcashd port and port 28232): +--- /run/user/1000/tmp.g9CJecu2Wo/zebrad-main-1649797-getinfo.json 2022-04-29 14:08:46.766240355 +1000 ++++ /run/user/1000/tmp.g9CJecu2Wo/zcashd-main-1649797-getinfo.json 2022-04-29 14:08:46.769240315 +1000 +@@ -1,4 +1,16 @@ + { +- "build": "1.0.0-beta.8+54.ge83e93a", +- "subversion": "/Zebra:1.0.0-beta.8/" ++ "version": 4070050, ++ "build": "v4.7.0-gitian", ++ "subversion": "/MagicBean:4.7.0/", +... more extra zcashd fields ... + } +``` + +Sometimes zcashd will have extra fields (`+`) or different data (`-` and `+`). +And sometimes it will have the same data, but in a different order. + +The script will warn you if the heights or networks are different, +then display the results of querying the mismatched node states. + +The script accepts any RPC, with any number of arguments. +If a node doesn't implement an RPC, the script will exit with an error. + +#### Configuration + +The script uses the configured `zcash-cli` RPC port, +and the `zebrad` port supplied on the command-line. + +It doesn't actually check what kind of node it is talking to, +so you can compare two `zcashd` or `zebrad` nodes if you want. +(Just edit the `zcash.conf` file used by `zcash-cli`, or edit the script.) + +You can override the binaries the script calls using these environmental variables: +- `$ZCASH_CLI` +- `$DIFF` diff --git a/zebra-utils/zcash-rpc-diff b/zebra-utils/zcash-rpc-diff new file mode 100755 index 000000000..e7d72ae63 --- /dev/null +++ b/zebra-utils/zcash-rpc-diff @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# Sends a `zcash-cli` command to a Zebra and zcashd instance, +# and compares the results. +# +# Uses the configured `zcash-cli` RPC port, +# and the `zebrad` port supplied on the command-line. + +function usage() +{ + echo "Usage:" + echo "$0 zebra-rpc-port rpc-name [rpc-args... ]" +} + +# Override the commands used by this script using these environmental variables: +ZCASH_CLI="${ZCASH_CLI:-zcash-cli}" +DIFF="${DIFF:-diff --unified --color}" + +if [ $# -lt 2 ]; then + usage + exit 1 +fi + +ZEBRAD_RPC_PORT=$1 +shift + +ZCASH_RPC_TMP_DIR=$(mktemp -d) + +ZEBRAD_BLOCKCHAIN_INFO="$ZCASH_RPC_TMP_DIR/zebrad-check-getblockchaininfo.json" +ZCASHD_BLOCKCHAIN_INFO="$ZCASH_RPC_TMP_DIR/zcashd-check-getblockchaininfo.json" + +echo "Checking zebrad network and tip height..." +$ZCASH_CLI -rpcport="$ZEBRAD_RPC_PORT" getblockchaininfo > "$ZEBRAD_BLOCKCHAIN_INFO" + +ZEBRAD_NET=$(cat "$ZEBRAD_BLOCKCHAIN_INFO" | grep '"chain"' | cut -d: -f2 | tr -d ' ,"') +ZEBRAD_HEIGHT=$(cat "$ZEBRAD_BLOCKCHAIN_INFO" | grep '"blocks"' | cut -d: -f2 | tr -d ' ,"') + +echo "Checking zcashd network and tip height..." +$ZCASH_CLI getblockchaininfo > "$ZCASHD_BLOCKCHAIN_INFO" + +ZCASHD_NET=$(cat "$ZCASHD_BLOCKCHAIN_INFO" | grep '"chain"' | cut -d: -f2 | tr -d ' ,"') +ZCASHD_HEIGHT=$(cat "$ZCASHD_BLOCKCHAIN_INFO" | grep '"blocks"' | cut -d: -f2 | tr -d ' ,"') + +echo + +if [ "$ZEBRAD_NET" != "$ZCASHD_NET" ]; then + echo "WARNING: comparing RPC responses from different networks:" + echo "zcashd is on: $ZCASHD_NET" + echo "zebrad is on: $ZEBRAD_NET" + echo +fi + +if [ "$ZEBRAD_HEIGHT" -ne "$ZCASHD_HEIGHT" ]; then + echo "WARNING: comparing RPC responses from different heights:" + echo "zcashd is at: $ZCASHD_HEIGHT" + echo "zebrad is at: $ZEBRAD_HEIGHT" + echo +fi + +ZEBRAD_RESPONSE="$ZCASH_RPC_TMP_DIR/zebrad-$ZEBRAD_NET-$ZEBRAD_HEIGHT-$1.json" +ZCASHD_RESPONSE="$ZCASH_RPC_TMP_DIR/zcashd-$ZCASHD_NET-$ZCASHD_HEIGHT-$1.json" + +echo "Request:" +echo "$@" +echo + +echo "Querying zebrad $ZEBRAD_NET chain at height $ZEBRAD_HEIGHT..." +$ZCASH_CLI -rpcport="$ZEBRAD_RPC_PORT" "$@" > "$ZEBRAD_RESPONSE" + +echo "Querying zcashd $ZCASHD_NET chain at height $ZCASHD_HEIGHT..." +$ZCASH_CLI "$@" > "$ZCASHD_RESPONSE" + +echo + +echo "Response diff (between zcashd port and port $ZEBRAD_RPC_PORT):" +$DIFF "$ZEBRAD_RESPONSE" "$ZCASHD_RESPONSE" \ + && ( \ + echo "RPC responses were identical"; \ + echo ; \ + echo "$ZEBRAD_RESPONSE:"; \ + cat "$ZEBRAD_RESPONSE"; \ + )