diff --git a/app/upgrades/v2_0/validator-proofs/Readme.md b/app/upgrades/v2_0/validator-proofs/Readme.md index 24418ed9..96fc19bc 100644 --- a/app/upgrades/v2_0/validator-proofs/Readme.md +++ b/app/upgrades/v2_0/validator-proofs/Readme.md @@ -25,6 +25,8 @@ all stake is returned to the original delegators during the migration. 6. (Optional) Perform the same steps for the `kaon` directory with your Kaon validators. +7. Run `python3 verify.py` to check if everything is correct. + ## General Upgrade Procedure All pending protocol commission will be claimed and returned to the validators diff --git a/app/upgrades/v2_0/validator-proofs/verify.py b/app/upgrades/v2_0/validator-proofs/verify.py new file mode 100644 index 00000000..41aacaa1 --- /dev/null +++ b/app/upgrades/v2_0/validator-proofs/verify.py @@ -0,0 +1,69 @@ +import os +import json +import sys + +import requests +import bech32 + + +def verify_tx(api_endpoint, tx_hash, expect_from_address, expect_to_address): + x = requests.get(api_endpoint + "/cosmos/tx/v1beta1/txs/" + tx_hash) + if x.status_code != 200: + raise Exception("transaction does not exist: ", tx_hash) + + tx = x.json() + if tx["tx"]["body"]["memo"] != "Shared-Staking": + raise Exception("incorrect memo for transaction: ", tx_hash) + + if tx["tx"]["body"]["messages"][0]["from_address"] != expect_from_address: + raise Exception("Incorrect from_address. Expected: {}, got: {}" + .format(expect_from_address, tx["tx"]["body"]["messages"][0]["from_address"])) + + if tx["tx"]["body"]["messages"][0]["to_address"] != expect_to_address: + raise Exception("Incorrect to_address. Expected: {}, got: {}" + .format(expect_to_address, tx["tx"]["body"]["messages"][0]["to_address"])) + + +def verify_proof(api_endpoint, entry): + x = requests.get(api_endpoint + "/cosmos/staking/v1beta1/validators/" + entry["consensus_address"]) + if x.status_code != 200: + raise Exception("Consensus validator does not exist: ", entry["consensus_address"]) + + x = requests.get(api_endpoint + "/kyve/query/v1beta1/staker/" + entry["protocol_address"]) + if x.status_code != 200: + raise Exception("Protocol validator does not exist: ", entry["protocol_address"]) + + prefix, address_bytes = bech32.bech32_decode(entry["consensus_address"]) + validator_acc_address = bech32.bech32_encode("kyve", address_bytes) + + verify_tx(api_endpoint, entry["proof_1"], entry["protocol_address"], validator_acc_address) + verify_tx(api_endpoint, entry["proof_2"], validator_acc_address, entry["protocol_address"]) + + +def verify_network(name, api_endpoint): + status = {"correct": 0, "error": 0} + for file in os.listdir("./" + name): + try: + proof = json.load(open("./{}/{}".format(name, file))) + verify_proof(api_endpoint, proof) + print("[{}]".format(name.title()), file, "✅") + status["correct"] += 1 + + except Exception as e: + print("[{}]".format(name.title()), file, "❌") + print(e) + status["error"] += 1 + + return status + + +status_kaon = verify_network("kaon", "https://api.kaon.kyve.network") +print("\n[Kaon] Correct: {}, Error: {}".format(status_kaon["correct"], status_kaon["error"])) + +print("\n") + +status_mainnet = verify_network("mainnet", "https://api.kyve.network") +print("\n[Mainnet] Correct: {}, Error: {}".format(status_mainnet["correct"], status_mainnet["error"])) + +if status_kaon["error"] != 0 or status_mainnet["error"] != 0: + sys.exit(1)