From 16df45a72258eb2ee53e3cf75ca8bbf8562c3b92 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Sun, 28 Jul 2024 12:39:14 +0200 Subject: [PATCH 01/22] initial implementation of the misbehaviour program --- Cargo.lock | 19 ++++++++++++ contracts/abi/SP1ICS07Tendermint.json | 12 +++++++ contracts/src/SP1ICS07Tendermint.sol | 13 +++++--- .../ics07-tendermint/MisbehaviourProgram.sol | 14 +++++++++ .../types/sp1ics07tendermint/contract.go | 31 +++++++++++-------- justfile | 7 ++++- programs/misbehaviour/Cargo.toml | 23 ++++++++++++++ programs/misbehaviour/src/lib.rs | 21 +++++++++++++ programs/misbehaviour/src/main.rs | 29 +++++++++++++++++ 9 files changed, 150 insertions(+), 19 deletions(-) create mode 100644 contracts/src/ics07-tendermint/MisbehaviourProgram.sol create mode 100644 programs/misbehaviour/Cargo.toml create mode 100644 programs/misbehaviour/src/lib.rs create mode 100644 programs/misbehaviour/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 7ad2c8d..241b3e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5685,6 +5685,25 @@ dependencies = [ "sp1-zkvm", ] +[[package]] +name = "sp1-ics07-tendermint-misbehaviour" +version = "0.1.0" +dependencies = [ + "alloy-sol-types", + "bincode", + "ibc-client-tendermint", + "ibc-core-client", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives", + "serde", + "serde_cbor", + "sha2 0.10.8", + "sp1-ics07-tendermint-solidity", + "sp1-zkvm", + "tendermint-light-client-verifier", +] + [[package]] name = "sp1-ics07-tendermint-operator" version = "0.1.0" diff --git a/contracts/abi/SP1ICS07Tendermint.json b/contracts/abi/SP1ICS07Tendermint.json index 6faa133..4a9d63c 100644 --- a/contracts/abi/SP1ICS07Tendermint.json +++ b/contracts/abi/SP1ICS07Tendermint.json @@ -228,6 +228,18 @@ ] } ] + }, + { + "name": "output3", + "type": "tuple", + "internalType": "struct MisbehaviourProgram.MisbehaviourOutput", + "components": [ + { + "name": "isMisbehaviour", + "type": "bool", + "internalType": "bool" + } + ] } ], "outputs": [], diff --git a/contracts/src/SP1ICS07Tendermint.sol b/contracts/src/SP1ICS07Tendermint.sol index 071b186..76973fb 100644 --- a/contracts/src/SP1ICS07Tendermint.sol +++ b/contracts/src/SP1ICS07Tendermint.sol @@ -5,6 +5,7 @@ import { ICS07Tendermint } from "./ics07-tendermint/ICS07Tendermint.sol"; import { UpdateClientProgram } from "./ics07-tendermint/UpdateClientProgram.sol"; import { MembershipProgram } from "./ics07-tendermint/MembershipProgram.sol"; import { UpdateClientAndMembershipProgram } from "./ics07-tendermint/UcAndMembershipProgram.sol"; +import { MisbehaviourProgram } from "./ics07-tendermint/MisbehaviourProgram.sol"; import { ISP1Verifier } from "@sp1-contracts/ISP1Verifier.sol"; import { ISP1ICS07Tendermint } from "./ISP1ICS07Tendermint.sol"; @@ -263,8 +264,8 @@ contract SP1ICS07Tendermint is ISP1ICS07Tendermint { } /// @notice Checks for basic misbehaviour. - /// @dev This function checks if the consensus state at the new height is different than the one in the mapping. - /// @dev This function does not check timestamp misbehaviour (a niche case). + /// @dev This function checks if the consensus state at the new height is different than the one in the mapping + /// @dev or if the timestamp is not increasing. If any of these conditions are met, it returns a Misbehaviour UpdateResult. /// @param output The public values of the update client program. function checkUpdateResult(UpdateClientProgram.UpdateClientOutput memory output) private @@ -276,8 +277,9 @@ contract SP1ICS07Tendermint is ISP1ICS07Tendermint { // No consensus state at the new height, so no misbehaviour return UpdateClientProgram.UpdateResult.Update; } - if (consensusStateHash != keccak256(abi.encode(output.newConsensusState))) { - // The consensus state at the new height is different than the one in the mapping + 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 UpdateClientProgram.UpdateResult.Misbehaviour; } else { // The consensus state at the new height is the same as the one in the mapping @@ -288,7 +290,8 @@ contract SP1ICS07Tendermint is ISP1ICS07Tendermint { /// @notice A dummy function to generate the ABI for the parameters. function abiPublicTypes( MembershipProgram.MembershipOutput memory output, - UpdateClientAndMembershipProgram.UcAndMembershipOutput memory output2 + UpdateClientAndMembershipProgram.UcAndMembershipOutput memory output2, + MisbehaviourProgram.MisbehaviourOutput memory output3 ) public pure diff --git a/contracts/src/ics07-tendermint/MisbehaviourProgram.sol b/contracts/src/ics07-tendermint/MisbehaviourProgram.sol new file mode 100644 index 000000000..090642e --- /dev/null +++ b/contracts/src/ics07-tendermint/MisbehaviourProgram.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.25; + +import { ICS07Tendermint } from "./ICS07Tendermint.sol"; + +/// @title MisbehaviourProgram +/// @author gjermundgaraba +/// @notice Defines shared types for the misbehaviour program. +contract MisbehaviourProgram { + /// @notice The public value output for the sp1 misbehaviour program. + struct MisbehaviourOutput { + bool isMisbehaviour; + } +} \ No newline at end of file diff --git a/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go b/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go index 99e571d..9d616ab 100644 --- a/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go +++ b/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go @@ -70,6 +70,11 @@ type MembershipProgramMembershipOutput struct { KvPairs []MembershipProgramKVPair } +// MisbehaviourProgramMisbehaviourOutput is an auto generated low-level Go binding around an user-defined struct. +type MisbehaviourProgramMisbehaviourOutput struct { + IsMisbehaviour bool +} + // UpdateClientAndMembershipProgramUcAndMembershipOutput is an auto generated low-level Go binding around an user-defined struct. type UpdateClientAndMembershipProgramUcAndMembershipOutput struct { UpdateClientOutput UpdateClientProgramUpdateClientOutput @@ -95,7 +100,7 @@ type UpdateClientProgramUpdateClientOutput struct { // ContractMetaData contains all meta data concerning the Contract contract. var ContractMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"updateClientProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"membershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"updateClientAndMembershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifier\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_clientState\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_consensusState\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"abiPublicTypes\",\"inputs\":[{\"name\":\"output\",\"type\":\"tuple\",\"internalType\":\"structMembershipProgram.MembershipOutput\",\"components\":[{\"name\":\"commitmentRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structMembershipProgram.KVPair[]\",\"components\":[{\"name\":\"key\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"output2\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientAndMembershipProgram.UcAndMembershipOutput\",\"components\":[{\"name\":\"updateClientOutput\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.UpdateClientOutput\",\"components\":[{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"newConsensusState\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.Env\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustThreshold\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trustedHeight\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"newHeight\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structMembershipProgram.KVPair[]\",\"components\":[{\"name\":\"key\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"batchVerifyMembership\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proofHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"trustedConsensusStateBz\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"kvPairHashes\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getClientState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ClientState\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustLevel\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"latestHeight\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"isFrozen\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConsensusStateHash\",\"inputs\":[{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getVerifierInfo\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateClient\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumUpdateClientProgram.UpdateResult\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateClientAndBatchVerifyMembership\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"kvPairHashes\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumUpdateClientProgram.UpdateResult\"}],\"stateMutability\":\"nonpayable\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"updateClientProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"membershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"updateClientAndMembershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifier\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_clientState\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_consensusState\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"abiPublicTypes\",\"inputs\":[{\"name\":\"output\",\"type\":\"tuple\",\"internalType\":\"structMembershipProgram.MembershipOutput\",\"components\":[{\"name\":\"commitmentRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structMembershipProgram.KVPair[]\",\"components\":[{\"name\":\"key\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"output2\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientAndMembershipProgram.UcAndMembershipOutput\",\"components\":[{\"name\":\"updateClientOutput\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.UpdateClientOutput\",\"components\":[{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"newConsensusState\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.Env\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustThreshold\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trustedHeight\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"newHeight\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structMembershipProgram.KVPair[]\",\"components\":[{\"name\":\"key\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"output3\",\"type\":\"tuple\",\"internalType\":\"structMisbehaviourProgram.MisbehaviourOutput\",\"components\":[{\"name\":\"isMisbehaviour\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"batchVerifyMembership\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proofHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"trustedConsensusStateBz\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"kvPairHashes\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getClientState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ClientState\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustLevel\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"latestHeight\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"isFrozen\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConsensusStateHash\",\"inputs\":[{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getVerifierInfo\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateClient\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumUpdateClientProgram.UpdateResult\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateClientAndBatchVerifyMembership\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"kvPairHashes\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumUpdateClientProgram.UpdateResult\"}],\"stateMutability\":\"nonpayable\"}]", } // ContractABI is the input ABI used to generate the binding from. @@ -275,12 +280,12 @@ func (_Contract *ContractCallerSession) ALLOWEDSP1CLOCKDRIFT() (uint16, error) { return _Contract.Contract.ALLOWEDSP1CLOCKDRIFT(&_Contract.CallOpts) } -// AbiPublicTypes is a free data retrieval call binding the contract method 0x31debad4. +// AbiPublicTypes is a free data retrieval call binding the contract method 0x887389cb. // -// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2) pure returns() -func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput) error { +// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2, (bool) output3) pure returns() +func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput, output3 MisbehaviourProgramMisbehaviourOutput) error { var out []interface{} - err := _Contract.contract.Call(opts, &out, "abiPublicTypes", output, output2) + err := _Contract.contract.Call(opts, &out, "abiPublicTypes", output, output2, output3) if err != nil { return err @@ -290,18 +295,18 @@ func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, output Memb } -// AbiPublicTypes is a free data retrieval call binding the contract method 0x31debad4. +// AbiPublicTypes is a free data retrieval call binding the contract method 0x887389cb. // -// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2) pure returns() -func (_Contract *ContractSession) AbiPublicTypes(output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput) error { - return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, output, output2) +// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2, (bool) output3) pure returns() +func (_Contract *ContractSession) AbiPublicTypes(output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput, output3 MisbehaviourProgramMisbehaviourOutput) error { + return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, output, output2, output3) } -// AbiPublicTypes is a free data retrieval call binding the contract method 0x31debad4. +// AbiPublicTypes is a free data retrieval call binding the contract method 0x887389cb. // -// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2) pure returns() -func (_Contract *ContractCallerSession) AbiPublicTypes(output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput) error { - return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, output, output2) +// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2, (bool) output3) pure returns() +func (_Contract *ContractCallerSession) AbiPublicTypes(output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput, output3 MisbehaviourProgramMisbehaviourOutput) error { + return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, output, output2, output3) } // BatchVerifyMembership is a free data retrieval call binding the contract method 0xa3b16959. diff --git a/justfile b/justfile index e6564c5..57bc212 100644 --- a/justfile +++ b/justfile @@ -54,7 +54,7 @@ fixtures prover: # Generate the `SP1ICS07Tendermint.json` file containing the ABI of the SP1ICS07Tendermint contract # Requires `jq` to be installed on the system # Requires `abigen` to be installed on the system to generate the go bindings for e2e tests -generate-abi: +generate-abi: clean cd contracts && forge install && forge build jq '.abi' contracts/out/SP1ICS07Tendermint.sol/SP1ICS07Tendermint.json > contracts/abi/SP1ICS07Tendermint.json @echo "ABI file created at 'contracts/abi/SP1ICS07Tendermint.json'" @@ -88,3 +88,8 @@ lint: forge fmt @echo "Linting the Go code..." cd e2e/interchaintestv8 && golangci-lint run --fix + +clean: + @echo "Cleaning up cache and build artifacts..." + cargo clean + cd contracts && rm -rf cache out diff --git a/programs/misbehaviour/Cargo.toml b/programs/misbehaviour/Cargo.toml new file mode 100644 index 000000000..c10f183 --- /dev/null +++ b/programs/misbehaviour/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "sp1-ics07-tendermint-misbehaviour" +description = "Check for misbehaviour program for sp1-ics07-tendermint" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +repository = { workspace = true } +license = { workspace = true } + +[dependencies] +sp1-zkvm = { workspace = true } +sp1-ics07-tendermint-solidity = { workspace = true } +tendermint-light-client-verifier = { workspace = true } +ibc-client-tendermint = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-client = { workspace = true } +ibc-primitives = { workspace = true } +ibc-core-handler-types = { workspace = true } +serde = { workspace = true } +sha2 = { workspace = true } +alloy-sol-types = { workspace = true } +serde_cbor = { workspace = true } +bincode = { workspace = true } diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs new file mode 100644 index 000000000..2abc44c --- /dev/null +++ b/programs/misbehaviour/src/lib.rs @@ -0,0 +1,21 @@ +//! The crate that contains the types and utilities for `sp1-ics07-tendermint-update-client` +//! program. +#![deny(missing_docs, clippy::nursery, clippy::pedantic, warnings)] + +use ibc_client_tendermint::client_state::check_for_misbehaviour_on_misbehavior; +use ibc_client_tendermint::types::Misbehaviour; + +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::MisbehaviourOutput; + +/// The main function of the program without the zkVM wrapper. +#[allow(clippy::missing_panics_doc)] +#[must_use] +pub fn check_for_misbehaviour( + misbehaviour: Misbehaviour, +) -> MisbehaviourOutput { + let is_misbehaviour = check_for_misbehaviour_on_misbehavior(misbehaviour.header1(), misbehaviour.header2()).unwrap(); + + MisbehaviourOutput { + isMisbehaviour: is_misbehaviour + } +} diff --git a/programs/misbehaviour/src/main.rs b/programs/misbehaviour/src/main.rs new file mode 100644 index 000000000..5031696 --- /dev/null +++ b/programs/misbehaviour/src/main.rs @@ -0,0 +1,29 @@ +//! A program that verifies a misbehaviour evidence. + +#![deny(missing_docs, clippy::nursery, clippy::pedantic, warnings)] +#![allow(clippy::no_mangle_with_rust_abi)] +// These two lines are necessary for the program to properly compile. +// +// Under the hood, we wrap your main function with some extra code so that it behaves properly +// inside the zkVM. +#![no_main] + +use ibc_client_tendermint::types::Misbehaviour; +use sp1_ics07_tendermint_misbehaviour::check_for_misbehaviour; + +sp1_zkvm::entrypoint!(main); + +/// The main function of the program. +/// +/// # Panics +/// Panics if the verification fails. +pub fn main() { + let encoded_1 = sp1_zkvm::io::read_vec(); + + // input 1: the misbehaviour evidence + let misbehaviour = serde_cbor::from_slice::(&encoded_1).unwrap(); + + let output = check_for_misbehaviour(misbehaviour); + + sp1_zkvm::io::commit_slice(&output.abi_encode()); +} From 269bb6a9c81e801e6c14fd6cd9db84b78c1cea3b Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 21 Aug 2024 20:34:01 +0200 Subject: [PATCH 02/22] misbehaviour program with operator integration with fixture output --- contracts/abi/SP1ICS07Tendermint.json | 73 +++++++++ contracts/fixtures/misbehaviour_fixture.json | 8 + contracts/script/genesis.json | 8 +- contracts/src/SP1ICS07Tendermint.sol | 4 +- contracts/src/msgs/IMisbehaviourMsgs.sol | 13 +- contracts/test/MisbehaviourTest.t.sol | 49 ++++++ e2e/interchaintestv8/operator/operator.go | 145 +++++++++++++++++ e2e/interchaintestv8/sp1_ics07_test.go | 149 ++++++++++++++++++ .../types/sp1ics07tendermint/contract.go | 35 ++-- justfile | 2 + operator/src/bin/operator.rs | 3 +- operator/src/cli/command.rs | 19 +++ operator/src/programs.rs | 7 + operator/src/prover.rs | 47 +++++- operator/src/runners/fixtures/misbehaviour.rs | 110 +++++++++++++ operator/src/runners/fixtures/mod.rs | 1 + programs/misbehaviour/src/lib.rs | 46 +++++- programs/misbehaviour/src/main.rs | 27 +++- programs/misbehaviour/src/types/mod.rs | 3 + programs/misbehaviour/src/types/validation.rs | 101 ++++++++++++ 20 files changed, 818 insertions(+), 32 deletions(-) create mode 100644 contracts/fixtures/misbehaviour_fixture.json create mode 100644 contracts/test/MisbehaviourTest.t.sol create mode 100644 operator/src/runners/fixtures/misbehaviour.rs create mode 100644 programs/misbehaviour/src/types/mod.rs create mode 100644 programs/misbehaviour/src/types/validation.rs diff --git a/contracts/abi/SP1ICS07Tendermint.json b/contracts/abi/SP1ICS07Tendermint.json index a72e17b..03d5489 100644 --- a/contracts/abi/SP1ICS07Tendermint.json +++ b/contracts/abi/SP1ICS07Tendermint.json @@ -416,6 +416,79 @@ "name": "isMisbehaviour", "type": "bool", "internalType": "bool" + }, + { + "name": "trustedConsensusState1", + "type": "tuple", + "internalType": "struct IICS07TendermintMsgs.ConsensusState", + "components": [ + { + "name": "timestamp", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "root", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "nextValidatorsHash", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "trustedConsensusState2", + "type": "tuple", + "internalType": "struct IICS07TendermintMsgs.ConsensusState", + "components": [ + { + "name": "timestamp", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "root", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "nextValidatorsHash", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ] + }, + { + "name": "o8", + "type": "tuple", + "internalType": "struct IMisbehaviourMsgs.MsgSubmitMisbehaviour", + "components": [ + { + "name": "sp1Proof", + "type": "tuple", + "internalType": "struct ISP1Msgs.SP1Proof", + "components": [ + { + "name": "vKey", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "publicValues", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "proof", + "type": "bytes", + "internalType": "bytes" + } + ] } ] } diff --git a/contracts/fixtures/misbehaviour_fixture.json b/contracts/fixtures/misbehaviour_fixture.json new file mode 100644 index 000000000..92839e8 --- /dev/null +++ b/contracts/fixtures/misbehaviour_fixture.json @@ -0,0 +1,8 @@ +{ + "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066c5f6653a7a0169b19e1d7e93e2856ed3e94f63d9329e59efdd681c519cc49ea750db59a9fdc69f863ff399f0f25beb3cfbb9d6c9a0f8628a2a0fea1d46b8a1cd5bc8c6", + "updateClientVkey": "0x006421f924828320ce4f10c34daf79e0c361c5720d02dff12844604996acff10", + "membershipVkey": "0x00b9581944af28ba1501054b2da49d563a2a81b40a6676a4123c130368f94fda", + "ucAndMembershipVkey": "0x00e3b81a5f0fd284314a86f39a56832064aef3864ba2f8adb34dd2cf40a9aea7", + "submitMsg": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000491ce01c2c24739655babf33fe9c9a691f9efe389d067a67706c023e44960e0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000066c5f6653a7a0169b19e1d7e93e2856ed3e94f63d9329e59efdd681c519cc49ea750db59a9fdc69f863ff399f0f25beb3cfbb9d6c9a0f8628a2a0fea1d46b8a1cd5bc8c60000000000000000000000000000000000000000000000000000000066c5f6653a7a0169b19e1d7e93e2856ed3e94f63d9329e59efdd681c519cc49ea750db59a9fdc69f863ff399f0f25beb3cfbb9d6c9a0f8628a2a0fea1d46b8a1cd5bc8c60000000000000000000000000000000000000000000000000000000000000364c430ff7f007f13e2a22a413363e129a434cf1ebebcb8744ace0469713e83f8d63e1c2b3a03cd0e2c12655a3e8f9f94915d683b962c856164c7017e51f6e6c5e8629095441ddc26614fd9dfc1e732935204e382ca70045a6d421a40bdb573dcd8e4e7eb662133c16ee78b6bfe85c200ab8e8fcf9e7baf9531f95c5c9eccce34c9085e7cde00b19979c55f2c29c77000c9dfc844856dbe3e85d7ccad8aa05b517a223afdce2ae2571e396c79397fb7c0b5fe1b767f4d4647adedf310643a8e18c9bcdf20a029439f3eafef20412089b5a18413c862889b89ba6abf28ae95ad8a587de2252e174057ac0d416a2470742388dd81e517ab62b95344e9037268422d2c3d94aabd05c76cbbd992670bc0fc4676d41d93b3b1d0de8695533a6f11281619c7a157f01487ecc1b1b7e7fed1f85dd73080de64128079657a717fdb786af5205c93b30f1cc62ca519c9073e2d156005946e500c0c98f796d1a0b46df3a5d3964bce64d416a0b0e57173a3b9f460a46b8e2f738645fe5ceb98377cbda6cd9f260727a5b90790b513f58b20992f5efd00418686634bf76a56edce609cc0003bdc818480620188bbb370d10f72376da72875b14e3e60799006db8017210fe6bba16ddbc46924c39590f7181e74f06e1d99271d261bb4072155c0e09560b01caa61dc14e8472304d140b10d6c4435ab1b52d54756d956d86854a13969538d8d45cef771bff11b9cc280808e4c1f2497358d24a6c3fad091203114062519999ed00e40e30de73032b4aecfa344c370e232aefe264b6e867f44947c4729b86825b55148b8849223b5aae80a5d4f84e355df1c0b54dc3744115f27908d0488681fbff79595b0ff14fb5fb0d5afef31c852bab648c69fd7e729fc357891a8842373eacf57a52a181a0a0fe19810af7750aaa734acb7c2a5116f14e831089b37555ab05afaf84a921511d12d5ba14c7524727644f895de810075e93e0bb5d58b69a4c59ad48ee1ba070a89040a253aab5a49ae1be936d4620aed07a3728d6d4718ff9d5caadbb2c9251aeadf99d9c7937acc48ff2d86f6568d836d1f35e203d00ee5358f3a507ae5212e5e5d1990a79397611acd6928a62b4c9ab306312f423f88859982464d63282f8327ed45323f20251edd305da8e8a693339a37b272de7226d53ca2b3cfb4a705d0dd5454921cc6a7cde421472e72ac4cb59da3973836953d32a8d6f5486b1a00000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index 28ecab2..e8ff03f 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,7 +1,7 @@ { "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066afad81234b002d78b03df426a7e156ffe511253e9f874ed7feccc14d8d0002b1deba3a3e100db17d609c05af9bb099133aeea97349259ce45c581128ac8ffb51662a5a", - "updateClientVkey": "0x00d8ae8feed5fd1f82dbf7862b219cd74c516e5d09ee5ec9024b439e95f5a3e2", - "membershipVkey": "0x001ae64fb3c0ac2e5a62e4941b26edf05798f0dc3417ae105e4bd1c443de6188", - "ucAndMembershipVkey": "0x008ddefe335385fdfe8e6eefcebe2f9519cb27e95afd392537657bb4525883f9" + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066c5f6653a7a0169b19e1d7e93e2856ed3e94f63d9329e59efdd681c519cc49ea750db59a9fdc69f863ff399f0f25beb3cfbb9d6c9a0f8628a2a0fea1d46b8a1cd5bc8c6", + "updateClientVkey": "0x006421f924828320ce4f10c34daf79e0c361c5720d02dff12844604996acff10", + "membershipVkey": "0x00b9581944af28ba1501054b2da49d563a2a81b40a6676a4123c130368f94fda", + "ucAndMembershipVkey": "0x00e3b81a5f0fd284314a86f39a56832064aef3864ba2f8adb34dd2cf40a9aea7" } \ No newline at end of file diff --git a/contracts/src/SP1ICS07Tendermint.sol b/contracts/src/SP1ICS07Tendermint.sol index a2e5039..6f6d8a0 100644 --- a/contracts/src/SP1ICS07Tendermint.sol +++ b/contracts/src/SP1ICS07Tendermint.sol @@ -404,6 +404,7 @@ contract SP1ICS07Tendermint is /// @param o5 The SP1MembershipProof. /// @param o6 The SP1MembershipAndUpdateClientProof. /// @param o7 The MisbehaviourOutput. + /// @param o8 The MsgSubmitMisbehaviour. function abiPublicTypes( MembershipOutput memory o1, UcAndMembershipOutput memory o2, @@ -411,7 +412,8 @@ contract SP1ICS07Tendermint is MembershipProof memory o4, SP1MembershipProof memory o5, SP1MembershipAndUpdateClientProof memory o6, - IMisbehaviourMsgs.MisbehaviourOutput memory o7 + IMisbehaviourMsgs.MisbehaviourOutput memory o7, + IMisbehaviourMsgs.MsgSubmitMisbehaviour memory o8 ) public pure diff --git a/contracts/src/msgs/IMisbehaviourMsgs.sol b/contracts/src/msgs/IMisbehaviourMsgs.sol index 5e29193..cb8ea22 100644 --- a/contracts/src/msgs/IMisbehaviourMsgs.sol +++ b/contracts/src/msgs/IMisbehaviourMsgs.sol @@ -1,13 +1,24 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.25; +import { IICS07TendermintMsgs } from "./IICS07TendermintMsgs.sol"; +import { ISP1Msgs } from "./ISP1Msgs.sol"; + /// @title Misbehaviour Program Messages /// @author gjermundgaraba /// @notice Defines shared types for the misbehaviour program. -interface IMisbehaviourMsgs { +interface IMisbehaviourMsgs is IICS07TendermintMsgs, ISP1Msgs { + /// @notice The message that is submitted to the updateClient function. + /// @param sp1Proof The SP1 proof for updating the client. + struct MsgSubmitMisbehaviour { + SP1Proof sp1Proof; + } + /// @notice The public value output for the sp1 misbehaviour program. /// @param isMisbehaviour The flag indicating if there is misbehaviour. struct MisbehaviourOutput { bool isMisbehaviour; + ConsensusState trustedConsensusState1; + ConsensusState trustedConsensusState2; } } diff --git a/contracts/test/MisbehaviourTest.t.sol b/contracts/test/MisbehaviourTest.t.sol new file mode 100644 index 000000000..f917897 --- /dev/null +++ b/contracts/test/MisbehaviourTest.t.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.25; + +// solhint-disable-next-line no-global-import +import { SP1ICS07TendermintTest } from "./SP1ICS07TendermintTest.sol"; +import { IMisbehaviourMsgs } from "../src/msgs/IMisbehaviourMsgs.sol"; +import { stdJson } from "forge-std/StdJson.sol"; + +struct SP1ICS07MisbehaviourFixtureJson { + bytes trustedClientState; + bytes trustedConsensusState; + bytes submitMsg; +} + +contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { + SP1ICS07MisbehaviourFixtureJson public fixture; + + using stdJson for string; + + function setUp() public { + fixture = loadFixture("misbehaviour_fixture.json"); + + setUpTest("misbehaviour_fixture.json"); + } + + function loadFixture(string memory fileName) public view returns (SP1ICS07MisbehaviourFixtureJson memory) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/contracts/fixtures/", fileName); + string memory json = vm.readFile(path); + bytes memory trustedClientState = json.readBytes(".trustedClientState"); + bytes memory trustedConsensusState = json.readBytes(".trustedConsensusState"); + bytes memory submitMsg = json.readBytes(".submitMsg"); + + SP1ICS07MisbehaviourFixtureJson memory fix = SP1ICS07MisbehaviourFixtureJson({ + trustedClientState: trustedClientState, + trustedConsensusState: trustedConsensusState, + submitMsg: submitMsg + }); + + return fix; + } + + function test_ValidMisbehaviour() public { + IMisbehaviourMsgs.MsgSubmitMisbehaviour memory submitMsg = abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); + IMisbehaviourMsgs.MisbehaviourOutput memory output = abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); + + // TODO: Write the actual test :P + } +} \ No newline at end of file diff --git a/e2e/interchaintestv8/operator/operator.go b/e2e/interchaintestv8/operator/operator.go index 5246653..1acbdf7 100644 --- a/e2e/interchaintestv8/operator/operator.go +++ b/e2e/interchaintestv8/operator/operator.go @@ -1,9 +1,13 @@ package operator import ( + "encoding/base64" "encoding/hex" "encoding/json" "errors" + "fmt" + "github.com/cosmos/cosmos-sdk/codec" + tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "os" "os/exec" "strconv" @@ -99,3 +103,144 @@ func UpdateClientAndMembershipProof(trusted_height, target_height uint64, paths return height, proofBz, nil } + +func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) error { + misbehaviourFileName := "misbehaviour.json" + args := append([]string{"fixtures", "misbehaviour", "--misbehaviour-path", misbehaviourFileName}) + + misbehaviour.ClientId = "07-tendermint-0" // We just have to set it to something to make the unmarshalling to work :P + bzIntermediary, err := cdc.MarshalJSON(&misbehaviour) + if err != nil { + return err + } + var jsonIntermediary map[string]interface{} + if err := json.Unmarshal(bzIntermediary, &jsonIntermediary); err != nil { + return err + } + headerHexPaths := []string{ + "validator_set.proposer.address", + "trusted_validators.proposer.address", + "signed_header.header.last_block_id.hash", + "signed_header.header.last_block_id.part_set_header.hash", + "signed_header.header.app_hash", + "signed_header.header.consensus_hash", + "signed_header.header.data_hash", + "signed_header.header.evidence_hash", + "signed_header.header.last_commit_hash", + "signed_header.header.last_results_hash", + "signed_header.header.next_validators_hash", + "signed_header.header.proposer_address", + "signed_header.header.validators_hash", + "signed_header.commit.block_id.hash", + "signed_header.commit.block_id.part_set_header.hash", + } + + var hexPaths []string + for _, path := range headerHexPaths { + hexPaths = append(hexPaths, "header_1."+path) + hexPaths = append(hexPaths, "header_2."+path) + } + + for _, path := range hexPaths { + pathParts := strings.Split(path, ".") + tmpIntermediary := jsonIntermediary + for i := 0; i < len(pathParts)-1; i++ { + var ok bool + tmpIntermediary, ok = tmpIntermediary[pathParts[i]].(map[string]interface{}) + if !ok { + fmt.Printf("path not found: %s\n", path) + continue + } + } + base64str, ok := tmpIntermediary[pathParts[len(pathParts)-1]].(string) + if !ok { + return fmt.Errorf("path not found: %s", path) + } + bz, err := base64.StdEncoding.DecodeString(base64str) + if err != nil { + return err + } + tmpIntermediary[pathParts[len(pathParts)-1]] = hex.EncodeToString(bz) + } + + validators1 := jsonIntermediary["header_1"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) + validators2 := jsonIntermediary["header_2"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) + validators3 := jsonIntermediary["header_1"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) + validators4 := jsonIntermediary["header_2"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) + validators := append(validators1, validators2...) + validators = append(validators, validators3...) + validators = append(validators, validators4...) + for _, val := range validators { + val := val.(map[string]interface{}) + valAddressBase64Str, ok := val["address"].(string) + if !ok { + return fmt.Errorf("address not found in path: %s", val) + } + valAddressBz, err := base64.StdEncoding.DecodeString(valAddressBase64Str) + if err != nil { + return err + } + val["address"] = hex.EncodeToString(valAddressBz) + + pubKey, ok := val["pub_key"].(map[string]interface{}) + if !ok { + return fmt.Errorf("pub_key not found in path: %s", val) + } + ed25519PubKey := pubKey["ed25519"].(string) + pubKey["type"] = "tendermint/PubKeyEd25519" + pubKey["value"] = ed25519PubKey + } + + var pubKeys []map[string]interface{} + pubKeys = append(pubKeys, jsonIntermediary["header_1"].(map[string]interface{})["validator_set"].(map[string]interface{})["proposer"].(map[string]interface{})["pub_key"].(map[string]interface{})) + pubKeys = append(pubKeys, jsonIntermediary["header_1"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["proposer"].(map[string]interface{})["pub_key"].(map[string]interface{})) + pubKeys = append(pubKeys, jsonIntermediary["header_2"].(map[string]interface{})["validator_set"].(map[string]interface{})["proposer"].(map[string]interface{})["pub_key"].(map[string]interface{})) + pubKeys = append(pubKeys, jsonIntermediary["header_2"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["proposer"].(map[string]interface{})["pub_key"].(map[string]interface{})) + + for _, proposerPubKey := range pubKeys { + ed25519PubKey := proposerPubKey["ed25519"].(string) + proposerPubKey["type"] = "tendermint/PubKeyEd25519" + proposerPubKey["value"] = ed25519PubKey + } + + header1Sigs := jsonIntermediary["header_1"].(map[string]interface{})["signed_header"].(map[string]interface{})["commit"].(map[string]interface{})["signatures"].([]interface{}) + header2Sigs := jsonIntermediary["header_2"].(map[string]interface{})["signed_header"].(map[string]interface{})["commit"].(map[string]interface{})["signatures"].([]interface{}) + sigs := append(header1Sigs, header2Sigs...) + for _, sig := range sigs { + sig := sig.(map[string]interface{}) + if sig["block_id_flag"] == "BLOCK_ID_FLAG_COMMIT" { + sig["block_id_flag"] = 2 + } else { + return fmt.Errorf("unexpected block_id_flag: %s", sig["block_id_flag"]) + } + + valAddressBase64Str, ok := sig["validator_address"].(string) + if !ok { + return fmt.Errorf("validator_address not found") + } + valAddressBz, err := base64.StdEncoding.DecodeString(valAddressBase64Str) + if err != nil { + return err + } + sig["validator_address"] = hex.EncodeToString(valAddressBz) + } + + misbehaviourBz, err := json.Marshal(jsonIntermediary) + if err != nil { + return err + } + + // TODO: Make file temporary and delete it after use + if err := os.WriteFile(misbehaviourFileName, misbehaviourBz, 0644); err != nil { + return err + } + + stdout, err := exec.Command("target/release/operator", args...).CombinedOutput() + fmt.Println(string(stdout)) + // TODO: Read in the fixture and return something that can be used against the contract + if err != nil { + return err + } + + return nil +} diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index 768ade2..5381426 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -3,10 +3,23 @@ package main import ( "context" "crypto/ecdsa" + "encoding/base64" "encoding/hex" + "encoding/json" + "github.com/cometbft/cometbft/crypto/tmhash" + cometproto "github.com/cometbft/cometbft/proto/tendermint/types" + comettypes "github.com/cometbft/cometbft/types" + comettime "github.com/cometbft/cometbft/types/time" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + ibcclientutils "github.com/cosmos/ibc-go/v8/modules/core/02-client/client/utils" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibcmocks "github.com/cosmos/ibc-go/v8/testing/mock" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "os" "strconv" "testing" + "time" "github.com/stretchr/testify/suite" @@ -214,3 +227,139 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership() { s.Require().False(clientState.IsFrozen) })) } + +func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { + ctx := context.Background() + + s.SetupSuite(ctx) + + eth, simd := s.ChainA, s.ChainB + _ = eth + + s.Require().True(s.Run("Misbehave", func() { + // Based off of: https://github.com/cosmos/relayer/blob/f9aaf3dd0ebfe99fbe98d190a145861d7df93804/interchaintest/misbehaviour_test.go#L38 + oldHeader, latestHeight, err := ibcclientutils.QueryTendermintHeader(simd.Validators[0].CliContext()) + s.Require().NoError(err) + s.Require().NotZero(latestHeight) + + height := clienttypes.NewHeight(clienttypes.ParseChainID(simd.Config().ChainID), uint64(latestHeight)) + + clientState, err := s.contract.GetClientState(nil) + s.Require().NoError(err) + trustedHeight := clienttypes.NewHeight(uint64(clientState.LatestHeight.RevisionNumber), uint64(clientState.LatestHeight.RevisionHeight)) + + oldHeader.TrustedHeight = trustedHeight + oldHeader.TrustedValidators = oldHeader.ValidatorSet // ? + s.Require().NoError(err) + + // create a duplicate header + newHeader := s.createTMClientHeader( + ctx, + simd, + int64(height.RevisionHeight), + oldHeader.GetTime().Add(time.Minute), + oldHeader, + ) + _ = newHeader + + misbehaviour := tmclient.Misbehaviour{ + Header1: &newHeader, + Header2: &oldHeader, + } + + err = operator.Misbehaviour(simd.GetCodec(), misbehaviour) + s.Require().NoError(err) + })) +} + +func (s *SP1ICS07TendermintTestSuite) createTMClientHeader( + ctx context.Context, + chain *cosmos.CosmosChain, + blockHeight int64, + timestamp time.Time, + oldHeader tmclient.Header, +) tmclient.Header { + keyBz, err := chain.Validators[0].ReadFile(ctx, "config/priv_validator_key.json") + s.Require().NoError(err) + var privValidatorKeyFile cosmos.PrivValidatorKeyFile + err = json.Unmarshal(keyBz, &privValidatorKeyFile) + s.Require().NoError(err) + decodedKeyBz, err := base64.StdEncoding.DecodeString(privValidatorKeyFile.PrivKey.Value) + s.Require().NoError(err) + + privKey := &ed25519.PrivKey{ + Key: decodedKeyBz, + } + + privVal := ibcmocks.PV{PrivKey: privKey} + pubKey, err := privVal.GetPubKey() + s.Require().NoError(err) + + val := comettypes.NewValidator(pubKey, oldHeader.ValidatorSet.Proposer.VotingPower) + valSet := comettypes.NewValidatorSet([]*comettypes.Validator{val}) + signers := []comettypes.PrivValidator{privVal} + + vsetHash := valSet.Hash() + + tmHeader := comettypes.Header{ + Version: oldHeader.Header.Version, + ChainID: oldHeader.Header.ChainID, + Height: blockHeight, + Time: timestamp, + LastBlockID: ibctesting.MakeBlockID(make([]byte, tmhash.Size), 10_000, make([]byte, tmhash.Size)), + LastCommitHash: oldHeader.Header.LastCommitHash, + DataHash: tmhash.Sum([]byte("data_hash")), + ValidatorsHash: vsetHash, + NextValidatorsHash: vsetHash, + ConsensusHash: tmhash.Sum([]byte("consensus_hash")), + AppHash: tmhash.Sum([]byte("app_hash")), + LastResultsHash: tmhash.Sum([]byte("last_results_hash")), + EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + ProposerAddress: valSet.Proposer.Address, + } + + hhash := tmHeader.Hash() + blockID := ibctesting.MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) + voteSet := comettypes.NewVoteSet(oldHeader.Header.ChainID, blockHeight, 1, cometproto.PrecommitType, valSet) + + voteProto := &comettypes.Vote{ + ValidatorAddress: nil, + ValidatorIndex: -1, + Height: blockHeight, + Round: 1, + Timestamp: comettime.Now(), + Type: cometproto.PrecommitType, + BlockID: blockID, + } + + for i, sign := range signers { + pv, err := sign.GetPubKey() + s.Require().NoError(err) + addr := pv.Address() + vote := voteProto.Copy() + vote.ValidatorAddress = addr + vote.ValidatorIndex = int32(i) + _, err = comettypes.SignAndCheckVote(vote, sign, oldHeader.Header.ChainID, false) + s.Require().NoError(err) + added, err := voteSet.AddVote(vote) + s.Require().NoError(err) + s.Require().True(added) + } + extCommit := voteSet.MakeExtendedCommit(comettypes.DefaultABCIParams()) + commit := extCommit.ToCommit() + + signedHeader := &cometproto.SignedHeader{ + Header: tmHeader.ToProto(), + Commit: commit.ToProto(), + } + + valSetProto, err := valSet.ToProto() + s.Require().NoError(err) + + return tmclient.Header{ + SignedHeader: signedHeader, + ValidatorSet: valSetProto, + TrustedHeight: oldHeader.TrustedHeight, + TrustedValidators: oldHeader.TrustedValidators, + } +} diff --git a/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go b/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go index a17d9e5..63cf164 100644 --- a/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go +++ b/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go @@ -97,7 +97,14 @@ type IMembershipMsgsSP1MembershipProof struct { // IMisbehaviourMsgsMisbehaviourOutput is an auto generated low-level Go binding around an user-defined struct. type IMisbehaviourMsgsMisbehaviourOutput struct { - IsMisbehaviour bool + IsMisbehaviour bool + TrustedConsensusState1 IICS07TendermintMsgsConsensusState + TrustedConsensusState2 IICS07TendermintMsgsConsensusState +} + +// IMisbehaviourMsgsMsgSubmitMisbehaviour is an auto generated low-level Go binding around an user-defined struct. +type IMisbehaviourMsgsMsgSubmitMisbehaviour struct { + Sp1Proof ISP1MsgsSP1Proof } // ISP1MsgsSP1Proof is an auto generated low-level Go binding around an user-defined struct. @@ -137,7 +144,7 @@ type IUpdateClientMsgsUpdateClientOutput struct { // ContractMetaData contains all meta data concerning the Contract contract. var ContractMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"updateClientProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"membershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"updateClientAndMembershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifier\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_clientState\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_consensusState\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MEMBERSHIP_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPDATE_CLIENT_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VERIFIER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISP1Verifier\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"abiPublicTypes\",\"inputs\":[{\"name\":\"o1\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.MembershipOutput\",\"components\":[{\"name\":\"commitmentRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structIMembershipMsgs.KVPair[]\",\"components\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o2\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientAndMembershipMsgs.UcAndMembershipOutput\",\"components\":[{\"name\":\"updateClientOutput\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.UpdateClientOutput\",\"components\":[{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"newConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.Env\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustThreshold\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trustedHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"newHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structIMembershipMsgs.KVPair[]\",\"components\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o3\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.MsgUpdateClient\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o4\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.MembershipProof\",\"components\":[{\"name\":\"proofType\",\"type\":\"uint8\",\"internalType\":\"enumIMembershipMsgs.MembershipProofType\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"o5\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.SP1MembershipProof\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]},{\"name\":\"o6\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.SP1MembershipAndUpdateClientProof\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o7\",\"type\":\"tuple\",\"internalType\":\"structIMisbehaviourMsgs.MisbehaviourOutput\",\"components\":[{\"name\":\"isMisbehaviour\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getClientState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ClientState\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustLevel\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"latestHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"isFrozen\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConsensusStateHash\",\"inputs\":[{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"membership\",\"inputs\":[{\"name\":\"msgMembership\",\"type\":\"tuple\",\"internalType\":\"structILightClientMsgs.MsgMembership\",\"components\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proofHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"timestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"misbehaviour\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"updateClient\",\"inputs\":[{\"name\":\"updateMsg\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumILightClientMsgs.UpdateResult\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeClient\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"error\",\"name\":\"CannotHandleMisbehavior\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChainIdMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"actual\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"ConsensusStateHashMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ConsensusStateNotFound\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ConsensusStateRootMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"FeatureNotSupported\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FrozenClientState\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"LengthIsOutOfRange\",\"inputs\":[{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"min\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"max\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"MembershipProofKeyNotFound\",\"inputs\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}]},{\"type\":\"error\",\"name\":\"MembershipProofValueMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"actual\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"type\":\"error\",\"name\":\"ProofHeightMismatch\",\"inputs\":[{\"name\":\"expectedRevisionNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"expectedRevisionHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"actualRevisionNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"actualRevisionHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"type\":\"error\",\"name\":\"ProofIsInTheFuture\",\"inputs\":[{\"name\":\"now\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proofTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ProofIsTooOld\",\"inputs\":[{\"name\":\"now\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proofTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustThresholdMismatch\",\"inputs\":[{\"name\":\"expectedNumerator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expectedDenominator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualNumerator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualDenominator\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustingPeriodMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actual\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustingPeriodTooLong\",\"inputs\":[{\"name\":\"trustingPeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"UnknownMembershipProofType\",\"inputs\":[{\"name\":\"proofType\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"type\":\"error\",\"name\":\"VerificationKeyMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"updateClientProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"membershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"updateClientAndMembershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifier\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_clientState\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_consensusState\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MEMBERSHIP_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPDATE_CLIENT_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VERIFIER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISP1Verifier\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"abiPublicTypes\",\"inputs\":[{\"name\":\"o1\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.MembershipOutput\",\"components\":[{\"name\":\"commitmentRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structIMembershipMsgs.KVPair[]\",\"components\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o2\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientAndMembershipMsgs.UcAndMembershipOutput\",\"components\":[{\"name\":\"updateClientOutput\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.UpdateClientOutput\",\"components\":[{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"newConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.Env\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustThreshold\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trustedHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"newHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structIMembershipMsgs.KVPair[]\",\"components\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o3\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.MsgUpdateClient\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o4\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.MembershipProof\",\"components\":[{\"name\":\"proofType\",\"type\":\"uint8\",\"internalType\":\"enumIMembershipMsgs.MembershipProofType\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"o5\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.SP1MembershipProof\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]},{\"name\":\"o6\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.SP1MembershipAndUpdateClientProof\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o7\",\"type\":\"tuple\",\"internalType\":\"structIMisbehaviourMsgs.MisbehaviourOutput\",\"components\":[{\"name\":\"isMisbehaviour\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"trustedConsensusState1\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"trustedConsensusState2\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]},{\"name\":\"o8\",\"type\":\"tuple\",\"internalType\":\"structIMisbehaviourMsgs.MsgSubmitMisbehaviour\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getClientState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ClientState\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustLevel\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"latestHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"isFrozen\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConsensusStateHash\",\"inputs\":[{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"membership\",\"inputs\":[{\"name\":\"msgMembership\",\"type\":\"tuple\",\"internalType\":\"structILightClientMsgs.MsgMembership\",\"components\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proofHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"timestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"misbehaviour\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"updateClient\",\"inputs\":[{\"name\":\"updateMsg\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumILightClientMsgs.UpdateResult\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeClient\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"error\",\"name\":\"CannotHandleMisbehavior\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChainIdMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"actual\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"ConsensusStateHashMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ConsensusStateNotFound\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ConsensusStateRootMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"FeatureNotSupported\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FrozenClientState\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"LengthIsOutOfRange\",\"inputs\":[{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"min\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"max\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"MembershipProofKeyNotFound\",\"inputs\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}]},{\"type\":\"error\",\"name\":\"MembershipProofValueMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"actual\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"type\":\"error\",\"name\":\"ProofHeightMismatch\",\"inputs\":[{\"name\":\"expectedRevisionNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"expectedRevisionHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"actualRevisionNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"actualRevisionHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"type\":\"error\",\"name\":\"ProofIsInTheFuture\",\"inputs\":[{\"name\":\"now\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proofTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ProofIsTooOld\",\"inputs\":[{\"name\":\"now\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proofTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustThresholdMismatch\",\"inputs\":[{\"name\":\"expectedNumerator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expectedDenominator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualNumerator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualDenominator\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustingPeriodMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actual\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustingPeriodTooLong\",\"inputs\":[{\"name\":\"trustingPeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"UnknownMembershipProofType\",\"inputs\":[{\"name\":\"proofType\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"type\":\"error\",\"name\":\"VerificationKeyMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]", } // ContractABI is the input ABI used to generate the binding from. @@ -441,12 +448,12 @@ func (_Contract *ContractCallerSession) VERIFIER() (common.Address, error) { return _Contract.Contract.VERIFIER(&_Contract.CallOpts) } -// AbiPublicTypes is a free data retrieval call binding the contract method 0xb8e0c12e. +// AbiPublicTypes is a free data retrieval call binding the contract method 0xd743b10e. // -// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool) o7) pure returns() -func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput) error { +// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool,(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() +func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput, o8 IMisbehaviourMsgsMsgSubmitMisbehaviour) error { var out []interface{} - err := _Contract.contract.Call(opts, &out, "abiPublicTypes", o1, o2, o3, o4, o5, o6, o7) + err := _Contract.contract.Call(opts, &out, "abiPublicTypes", o1, o2, o3, o4, o5, o6, o7, o8) if err != nil { return err @@ -456,18 +463,18 @@ func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, o1 IMembers } -// AbiPublicTypes is a free data retrieval call binding the contract method 0xb8e0c12e. +// AbiPublicTypes is a free data retrieval call binding the contract method 0xd743b10e. // -// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool) o7) pure returns() -func (_Contract *ContractSession) AbiPublicTypes(o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput) error { - return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, o1, o2, o3, o4, o5, o6, o7) +// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool,(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() +func (_Contract *ContractSession) AbiPublicTypes(o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput, o8 IMisbehaviourMsgsMsgSubmitMisbehaviour) error { + return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, o1, o2, o3, o4, o5, o6, o7, o8) } -// AbiPublicTypes is a free data retrieval call binding the contract method 0xb8e0c12e. +// AbiPublicTypes is a free data retrieval call binding the contract method 0xd743b10e. // -// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool) o7) pure returns() -func (_Contract *ContractCallerSession) AbiPublicTypes(o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput) error { - return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, o1, o2, o3, o4, o5, o6, o7) +// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool,(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() +func (_Contract *ContractCallerSession) AbiPublicTypes(o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput, o8 IMisbehaviourMsgsMsgSubmitMisbehaviour) error { + return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, o1, o2, o3, o4, o5, o6, o7, o8) } // GetClientState is a free data retrieval call binding the contract method 0xef913a4b. diff --git a/justfile b/justfile index 261c766..f14466f 100644 --- a/justfile +++ b/justfile @@ -8,6 +8,8 @@ build-programs: @echo "ELF created at 'elf/membership-riscv32im-succinct-zkvm-elf'" cd programs/uc-and-membership && ~/.sp1/bin/cargo-prove prove build --elf-name uc-and-membership-riscv32im-succinct-zkvm-elf @echo "ELF created at 'elf/uc-and-membership-riscv32im-succinct-zkvm-elf'" + cd programs/misbehaviour && ~/.sp1/bin/cargo-prove prove build --elf-name misbehaviour-riscv32im-succinct-zkvm-elf + @echo "ELF created at 'elf/misbehaviour-riscv32im-succinct-zkvm-elf'" # Build the operator executable using `cargo build` command build-operator: diff --git a/operator/src/bin/operator.rs b/operator/src/bin/operator.rs index 898cb9c..94899f5 100644 --- a/operator/src/bin/operator.rs +++ b/operator/src/bin/operator.rs @@ -3,7 +3,7 @@ use sp1_ics07_tendermint_operator::{ cli::command::{fixtures, Commands, OperatorCli}, runners::{ self, - fixtures::{membership, uc_and_mem, update_client}, + fixtures::{membership, uc_and_mem, update_client, misbehaviour}, }, }; use sp1_sdk::utils::setup_logger; @@ -27,6 +27,7 @@ async fn main() -> anyhow::Result<()> { fixtures::Cmds::UpdateClient(args) => update_client::run(args).await, fixtures::Cmds::Membership(args) => membership::run(args).await, fixtures::Cmds::UpdateClientAndMembership(args) => uc_and_mem::run(args).await, + fixtures::Cmds::Misbehaviour(args) => misbehaviour::run(args).await, }, } } diff --git a/operator/src/cli/command.rs b/operator/src/cli/command.rs index a8d6ec0..f27f910 100644 --- a/operator/src/cli/command.rs +++ b/operator/src/cli/command.rs @@ -107,6 +107,8 @@ pub mod fixtures { Membership(MembershipCmd), /// The subcommand to generate the update client and verify (non)membership fixtures. UpdateClientAndMembership(UpdateClientAndMembershipCmd), + /// The subcommand to generate the misbehaviour fixtures. + Misbehaviour(MisbehaviourCmd), } /// The arguments for the `UpdateClient` fixture executable. @@ -175,6 +177,23 @@ pub mod fixtures { #[clap(flatten)] pub trust_options: super::TrustOptions, } + + /// The arguments for the `Misbehaviour` fixture executable. + #[derive(Parser, Debug, Clone)] + #[command(about = "Generate the misbehaviour fixture")] + pub struct MisbehaviourCmd { + /// Path to the misbehaviour json file. + #[clap(long)] + pub misbehaviour_path: String, + + /// Fixture path. If not provided, the output will be written to stdout. + #[clap(long, short = 'o', value_parser = super::parse_output_path, default_value = "-")] + pub output_path: super::OutputPath, + + /// Trust options + #[clap(flatten)] + pub trust_options: super::TrustOptions, + } } #[allow(clippy::unnecessary_wraps)] diff --git a/operator/src/programs.rs b/operator/src/programs.rs index e9720ba..df7f12e 100644 --- a/operator/src/programs.rs +++ b/operator/src/programs.rs @@ -25,6 +25,9 @@ pub struct MembershipProgram; /// SP1 ICS07 Tendermint update client and verify (non)membership program. pub struct UpdateClientAndMembershipProgram; +/// SP1 ICS07 Tendermint misbehaviour program. +pub struct MisbehaviourProgram; + impl SP1Program for UpdateClientProgram { const ELF: &'static [u8] = include_bytes!("../../elf/update-client-riscv32im-succinct-zkvm-elf"); @@ -38,3 +41,7 @@ impl SP1Program for UpdateClientAndMembershipProgram { const ELF: &'static [u8] = include_bytes!("../../elf/uc-and-membership-riscv32im-succinct-zkvm-elf"); } + +impl SP1Program for MisbehaviourProgram { + const ELF: &'static [u8] = include_bytes!("../../elf/misbehaviour-riscv32im-succinct-zkvm-elf"); +} diff --git a/operator/src/prover.rs b/operator/src/prover.rs index ba6cbb6..ea987e9 100644 --- a/operator/src/prover.rs +++ b/operator/src/prover.rs @@ -1,9 +1,9 @@ //! Prover for SP1 ICS07 Tendermint programs. use crate::programs::{ - MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, + MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, MisbehaviourProgram, }; -use ibc_client_tendermint::types::Header; +use ibc_client_tendermint::types::{Header, Misbehaviour}; use ibc_core_commitment_types::merkle::MerkleProof; use ibc_proto::Protobuf; use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{ @@ -190,3 +190,46 @@ impl SP1ICS07TendermintProver { proof } } + +impl SP1ICS07TendermintProver { + /// Generate a proof of a misbehaviour. + /// + /// # Panics + /// Panics if the proof cannot be generated or the proof is invalid. + #[must_use] + pub fn generate_proof( + &self, + contract_env: &Env, + misbehaviour: &Misbehaviour, + trusted_consensus_state_1: &SolConsensusState, + trusted_consensus_state_2: &SolConsensusState, + ) -> SP1ProofWithPublicValues { + let encoded_1 = bincode::serialize(contract_env).unwrap(); + let encoded_2 = serde_cbor::to_vec(misbehaviour).unwrap(); + let encoded_3 = bincode::serialize(trusted_consensus_state_1).unwrap(); + let encoded_4 = bincode::serialize(trusted_consensus_state_2).unwrap(); + + let mut stdin = SP1Stdin::new(); + stdin.write_vec(encoded_1); + stdin.write_vec(encoded_2); + stdin.write_vec(encoded_3); + stdin.write_vec(encoded_4); + + // Generate the proof. Depending on SP1_PROVER env variable, this may be a mock, local or + // network proof. + let proof = self + .prover_client + .prove(&self.pkey, stdin) + .plonk() + .run() + .expect("proving failed"); + + // Verify proof. + self.prover_client + .verify(&proof, &self.vkey) + .expect("Verification failed"); + + // Return the proof. + proof + } +} diff --git a/operator/src/runners/fixtures/misbehaviour.rs b/operator/src/runners/fixtures/misbehaviour.rs new file mode 100644 index 000000000..4d43d76 --- /dev/null +++ b/operator/src/runners/fixtures/misbehaviour.rs @@ -0,0 +1,110 @@ +//! Runner for generating `misbehaviour` fixtures + +use std::path::PathBuf; +use crate::cli::command::fixtures::MisbehaviourCmd; +use crate::programs::MisbehaviourProgram; +use crate::prover::SP1ICS07TendermintProver; +use crate::runners::genesis::SP1ICS07TendermintGenesis; +use alloy_sol_types::SolValue; +use ibc_client_tendermint::types::Misbehaviour; +use ibc_proto::ibc::lightclients::tendermint::v1::Misbehaviour as RawMisbehaviour; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; +use tendermint_rpc::HttpClient; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{ + Env, ClientState, ConsensusState, SP1Proof, MsgSubmitMisbehaviour, +}; +use sp1_sdk::HashableKey; +use crate::cli::command::OutputPath; +use crate::helpers::light_block::LightBlockExt; +use crate::rpc::TendermintRpcExt; + +/// The fixture data to be used in [`SP1ICS07SubmitMisbehaviourFixture`] tests. +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct SP1ICS07SubmitMisbehaviourFixture { + /// The genesis data. + #[serde(flatten)] + genesis: SP1ICS07TendermintGenesis, + + /// The encoded submit misbehaviour client message. + #[serde_as(as = "serde_with::hex::Hex")] + submit_msg: Vec, +} + +/// Writes the proof data for misbehaviour to the given fixture path. +#[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] +pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { + let path = args.misbehaviour_path; + let misbehaviour_bz = std::fs::read(path)?; + // deserialize from json + let raw_misbehaviour: RawMisbehaviour = serde_json::from_slice(&misbehaviour_bz)?; + + let tm_rpc_client = HttpClient::from_env(); + let trusted_light_block_1 = tm_rpc_client + .get_light_block(Some(raw_misbehaviour.clone().header_1.unwrap().trusted_height.unwrap().revision_height as u32)) + .await?; + let trusted_light_block_2 = tm_rpc_client + .get_light_block(Some(raw_misbehaviour.clone().header_2.unwrap().trusted_height.unwrap().revision_height as u32)) + .await?; + + let genesis_1 = SP1ICS07TendermintGenesis::from_env( + &trusted_light_block_1, + args.trust_options.trusting_period, + args.trust_options.trust_level, + ).await?; + let genesis_2 = SP1ICS07TendermintGenesis::from_env( + &trusted_light_block_2, + args.trust_options.trusting_period, + args.trust_options.trust_level, + ).await?; + + let trusted_consensus_state_1 = + ConsensusState::abi_decode(&genesis_1.trusted_consensus_state, false)?; + let trusted_consensus_state_2 = + ConsensusState::abi_decode(&genesis_2.trusted_consensus_state, false)?; + let trusted_client_state_2 = ClientState::abi_decode(&genesis_2.trusted_client_state, false)?; + + let verify_misbehaviour_prover = SP1ICS07TendermintProver::::default(); + + let contract_env = Env { + chainId: trusted_light_block_2.chain_id()?.to_string(), + trustThreshold: trusted_client_state_2.trustLevel, + trustingPeriod: trusted_client_state_2.trustingPeriod, + now: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH)? + .as_secs(), + }; + + let misbehaviour: Misbehaviour = Misbehaviour::try_from(raw_misbehaviour).unwrap(); + let proof_data = verify_misbehaviour_prover.generate_proof(&contract_env, &misbehaviour, &trusted_consensus_state_1, &trusted_consensus_state_2); + + let submit_msg = MsgSubmitMisbehaviour { + sp1Proof: SP1Proof::new( + &verify_misbehaviour_prover.vkey.bytes32(), + proof_data.bytes(), + proof_data.public_values.to_vec(), + ), + }; + + let fixture = SP1ICS07SubmitMisbehaviourFixture { + genesis: genesis_2, + submit_msg: submit_msg.abi_encode(), + }; + + match args.output_path { + OutputPath::File(path) => { + // Save the proof data to the file path. + std::fs::write( + PathBuf::from(path), + serde_json::to_string_pretty(&fixture)?, + )?; + } + OutputPath::Stdout => { + println!("{}", serde_json::to_string_pretty(&fixture)?); + } + } + + Ok(()) +} \ No newline at end of file diff --git a/operator/src/runners/fixtures/mod.rs b/operator/src/runners/fixtures/mod.rs index 7e40869..2de23ec 100644 --- a/operator/src/runners/fixtures/mod.rs +++ b/operator/src/runners/fixtures/mod.rs @@ -3,3 +3,4 @@ pub mod membership; pub mod uc_and_mem; pub mod update_client; +pub mod misbehaviour; diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index 1a3a21d..bbc872f 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -2,20 +2,58 @@ //! program. #![deny(missing_docs, clippy::nursery, clippy::pedantic, warnings)] -use ibc_client_tendermint::client_state::check_for_misbehaviour_on_misbehavior; -use ibc_client_tendermint::types::Misbehaviour; +pub mod types; -use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::MisbehaviourOutput; +use std::collections::HashMap; +use std::time::Duration; +use ibc_client_tendermint::client_state::{verify_misbehaviour, check_for_misbehaviour_on_misbehavior}; +use ibc_client_tendermint::types::{ConsensusState, Misbehaviour, TENDERMINT_CLIENT_TYPE}; +use ibc_core_host_types::identifiers::{ChainId, ClientId}; +use tendermint_light_client_verifier::options::Options; +use tendermint_light_client_verifier::ProdVerifier; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{Env, MisbehaviourOutput}; /// The main function of the program without the zkVM wrapper. #[allow(clippy::missing_panics_doc)] #[must_use] -pub fn check_for_misbehaviour(misbehaviour: Misbehaviour) -> MisbehaviourOutput { +pub fn check_for_misbehaviour( + env: Env, + misbehaviour: Misbehaviour, + trusted_consensus_state_1: ConsensusState, + trusted_consensus_state_2: ConsensusState +) -> MisbehaviourOutput { + + let client_id = ClientId::new(TENDERMINT_CLIENT_TYPE, 0).unwrap(); + let chain_id = env.clone().chainId; + assert_eq!(chain_id, misbehaviour.header1().signed_header.header.chain_id.to_string()); + + let mut trusted_consensus_state_map = HashMap::new(); + trusted_consensus_state_map.insert(misbehaviour.header1().trusted_height.revision_height(), &trusted_consensus_state_1); + trusted_consensus_state_map.insert(misbehaviour.header2().trusted_height.revision_height(), &trusted_consensus_state_2); + let ctx = types::validation::MisbehaviourValidationContext::new(&env, trusted_consensus_state_map); + + let options = Options { + trust_threshold: env.trustThreshold.clone().into(), + trusting_period: Duration::from_secs(env.trustingPeriod.into()), + clock_drift: Duration::default(), + }; + + verify_misbehaviour::<_, sha2::Sha256>( + &ctx, + &misbehaviour, + &client_id, + &ChainId::new(chain_id.as_str()).unwrap(), + &options, + &ProdVerifier::default(), + ).unwrap(); + let is_misbehaviour = check_for_misbehaviour_on_misbehavior(misbehaviour.header1(), misbehaviour.header2()) .unwrap(); MisbehaviourOutput { isMisbehaviour: is_misbehaviour, + trustedConsensusState1: trusted_consensus_state_1.into(), + trustedConsensusState2: trusted_consensus_state_2.into(), } } diff --git a/programs/misbehaviour/src/main.rs b/programs/misbehaviour/src/main.rs index 5031696..1fbfa8e 100644 --- a/programs/misbehaviour/src/main.rs +++ b/programs/misbehaviour/src/main.rs @@ -7,11 +7,14 @@ // Under the hood, we wrap your main function with some extra code so that it behaves properly // inside the zkVM. #![no_main] +sp1_zkvm::entrypoint!(main); +use alloy_sol_types::SolValue; use ibc_client_tendermint::types::Misbehaviour; use sp1_ics07_tendermint_misbehaviour::check_for_misbehaviour; - -sp1_zkvm::entrypoint!(main); +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{ + ConsensusState as SolConsensusState, Env, +}; /// The main function of the program. /// @@ -19,11 +22,25 @@ sp1_zkvm::entrypoint!(main); /// Panics if the verification fails. pub fn main() { let encoded_1 = sp1_zkvm::io::read_vec(); + let encoded_2 = sp1_zkvm::io::read_vec(); + let encoded_3 = sp1_zkvm::io::read_vec(); + let encoded_4 = sp1_zkvm::io::read_vec(); - // input 1: the misbehaviour evidence - let misbehaviour = serde_cbor::from_slice::(&encoded_1).unwrap(); + // input 1: environment + let env = bincode::deserialize::(&encoded_1).unwrap(); + // input 2: the misbehaviour evidence + let misbehaviour = serde_cbor::from_slice::(&encoded_2).unwrap(); + // input 3: header 1 trusted consensus state + let trusted_consensus_state_1 = bincode::deserialize::(&encoded_3) + .unwrap() + .into(); + // input 4: header 2 trusted consensus state + let trusted_consensus_state_2 = bincode::deserialize::(&encoded_4) + .unwrap() + .into(); + - let output = check_for_misbehaviour(misbehaviour); + let output = check_for_misbehaviour(env, misbehaviour, trusted_consensus_state_1, trusted_consensus_state_2); sp1_zkvm::io::commit_slice(&output.abi_encode()); } diff --git a/programs/misbehaviour/src/types/mod.rs b/programs/misbehaviour/src/types/mod.rs new file mode 100644 index 000000000..c63405d --- /dev/null +++ b/programs/misbehaviour/src/types/mod.rs @@ -0,0 +1,3 @@ +//! Containes types used in the program. + +pub mod validation; diff --git a/programs/misbehaviour/src/types/validation.rs b/programs/misbehaviour/src/types/validation.rs new file mode 100644 index 000000000..35987db --- /dev/null +++ b/programs/misbehaviour/src/types/validation.rs @@ -0,0 +1,101 @@ +//! Contains types and traits for `verify_misbehaviour` validation within the program. + +use std::collections::HashMap; +use ibc_client_tendermint::{ + client_state::ClientState as ClientStateWrapper, + consensus_state::ConsensusState as ConsensusStateWrapper, types::ConsensusState, +}; +use ibc_core_client::context::{ClientValidationContext, ExtClientValidationContext}; +use ibc_core_handler_types::error::ContextError; +use ibc_primitives::Timestamp; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::Env; + +/// The client validation context. +pub struct MisbehaviourValidationContext<'a, 'b> { + env: &'a Env, + trusted_consensus_states: HashMap, +} + +impl<'a, 'b> MisbehaviourValidationContext<'a, 'b> { + /// Create a new instance of the client validation context. + #[must_use] + pub const fn new( + env: &'a Env, + trusted_consensus_states: HashMap, + ) -> Self { + Self { + env, + trusted_consensus_states, + } + } +} + +impl<'a, 'b> ClientValidationContext for MisbehaviourValidationContext<'a, 'b> { + type ClientStateRef = ClientStateWrapper; + type ConsensusStateRef = ConsensusStateWrapper; + + fn consensus_state( + &self, + client_cons_state_path: &ibc_core_host_types::path::ClientConsensusStatePath, + ) -> Result { + let height = client_cons_state_path.revision_height; + let trusted_consensus_state = self + .trusted_consensus_states[&height]; + + Ok(trusted_consensus_state.clone().into()) + } + + fn client_state( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + ) -> Result { + // not needed by the `verify_header` function + unimplemented!() + } + + fn client_update_meta( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: &ibc_core_client::types::Height, + ) -> Result<(Timestamp, ibc_core_client::types::Height), ContextError> { + // not needed by the `verify_header` function + unimplemented!() + } +} + +impl<'a, 'b> ExtClientValidationContext for MisbehaviourValidationContext<'a, 'b> { + fn host_timestamp(&self) -> Result { + Ok(Timestamp::from_nanoseconds(self.env.now * 1_000_000_000)) + } + + fn host_height(&self) -> Result { + // not needed by the `verify_header` function + unimplemented!() + } + + fn consensus_state_heights( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + ) -> Result, ContextError> { + // not needed by the `verify_header` function + unimplemented!() + } + + fn next_consensus_state( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: &ibc_core_client::types::Height, + ) -> Result, ContextError> { + // not needed by the `verify_header` function + unimplemented!() + } + + fn prev_consensus_state( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: &ibc_core_client::types::Height, + ) -> Result, ContextError> { + // not needed by the `verify_header` function + unimplemented!() + } +} From 4ac34e9d8bfb4021a7105bf207fab2fbcccfa1aa Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 21 Aug 2024 22:27:06 +0200 Subject: [PATCH 03/22] lint --- contracts/script/genesis.json | 8 +-- contracts/src/msgs/IMisbehaviourMsgs.sol | 4 +- contracts/test/MisbehaviourTest.t.sol | 9 ++- e2e/interchaintestv8/operator/operator.go | 16 ++++-- e2e/interchaintestv8/sp1_ics07_test.go | 25 +++++---- operator/src/bin/operator.rs | 2 +- operator/src/prover.rs | 3 +- operator/src/runners/fixtures/misbehaviour.rs | 56 +++++++++++++------ operator/src/runners/fixtures/mod.rs | 2 +- programs/misbehaviour/src/lib.rs | 49 ++++++++++------ programs/misbehaviour/src/main.rs | 10 +++- programs/misbehaviour/src/types/validation.rs | 7 +-- 12 files changed, 122 insertions(+), 69 deletions(-) diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index e8ff03f..a7eb7c7 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,7 +1,7 @@ { - "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066c5f6653a7a0169b19e1d7e93e2856ed3e94f63d9329e59efdd681c519cc49ea750db59a9fdc69f863ff399f0f25beb3cfbb9d6c9a0f8628a2a0fea1d46b8a1cd5bc8c6", + "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066c64c13bde2e49088fa7da21364dc8b818a70a29ec3670cb557041d06654bb83a07abcadbd14b0e2076f203b2481a8da160c6b5fea4746739d4abdd79be8b42a52a18f0", "updateClientVkey": "0x006421f924828320ce4f10c34daf79e0c361c5720d02dff12844604996acff10", - "membershipVkey": "0x00b9581944af28ba1501054b2da49d563a2a81b40a6676a4123c130368f94fda", - "ucAndMembershipVkey": "0x00e3b81a5f0fd284314a86f39a56832064aef3864ba2f8adb34dd2cf40a9aea7" + "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", + "ucAndMembershipVkey": "0x00c9ebf0be8701d530f4f344e8e9ee8d75faaa05fc8621c91e8611db29483b0b" } \ No newline at end of file diff --git a/contracts/src/msgs/IMisbehaviourMsgs.sol b/contracts/src/msgs/IMisbehaviourMsgs.sol index cb8ea22..cbf7715 100644 --- a/contracts/src/msgs/IMisbehaviourMsgs.sol +++ b/contracts/src/msgs/IMisbehaviourMsgs.sol @@ -8,7 +8,7 @@ import { ISP1Msgs } from "./ISP1Msgs.sol"; /// @author gjermundgaraba /// @notice Defines shared types for the misbehaviour program. interface IMisbehaviourMsgs is IICS07TendermintMsgs, ISP1Msgs { - /// @notice The message that is submitted to the updateClient function. + /// @notice The message that is submitted to the misbehaviour function. /// @param sp1Proof The SP1 proof for updating the client. struct MsgSubmitMisbehaviour { SP1Proof sp1Proof; @@ -16,6 +16,8 @@ interface IMisbehaviourMsgs is IICS07TendermintMsgs, ISP1Msgs { /// @notice The public value output for the sp1 misbehaviour program. /// @param isMisbehaviour The flag indicating if there is misbehaviour. + /// @param trustedConsensusState1 The trusted consensus state of header 1 + /// @param trustedConsensusState2 The trusted consensus state of header 2 struct MisbehaviourOutput { bool isMisbehaviour; ConsensusState trustedConsensusState1; diff --git a/contracts/test/MisbehaviourTest.t.sol b/contracts/test/MisbehaviourTest.t.sol index f917897..7deca40 100644 --- a/contracts/test/MisbehaviourTest.t.sol +++ b/contracts/test/MisbehaviourTest.t.sol @@ -41,9 +41,12 @@ contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { } function test_ValidMisbehaviour() public { - IMisbehaviourMsgs.MsgSubmitMisbehaviour memory submitMsg = abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); - IMisbehaviourMsgs.MisbehaviourOutput memory output = abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); + IMisbehaviourMsgs.MsgSubmitMisbehaviour memory submitMsg = + abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); + IMisbehaviourMsgs.MisbehaviourOutput memory output = + abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); + assertTrue(output.isMisbehaviour); // TODO: Write the actual test :P } -} \ No newline at end of file +} diff --git a/e2e/interchaintestv8/operator/operator.go b/e2e/interchaintestv8/operator/operator.go index 1acbdf7..0df36f6 100644 --- a/e2e/interchaintestv8/operator/operator.go +++ b/e2e/interchaintestv8/operator/operator.go @@ -6,8 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/cosmos/cosmos-sdk/codec" - tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "os" "os/exec" "strconv" @@ -15,6 +13,10 @@ import ( abi "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/cosmos/cosmos-sdk/codec" + + tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + "github.com/srdtrk/sp1-ics07-tendermint/e2e/v8/types/sp1ics07tendermint" ) @@ -106,7 +108,7 @@ func UpdateClientAndMembershipProof(trusted_height, target_height uint64, paths func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) error { misbehaviourFileName := "misbehaviour.json" - args := append([]string{"fixtures", "misbehaviour", "--misbehaviour-path", misbehaviourFileName}) + args := []string{"fixtures", "misbehaviour", "--misbehaviour-path", misbehaviourFileName} misbehaviour.ClientId = "07-tendermint-0" // We just have to set it to something to make the unmarshalling to work :P bzIntermediary, err := cdc.MarshalJSON(&misbehaviour) @@ -167,7 +169,8 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) error { validators2 := jsonIntermediary["header_2"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) validators3 := jsonIntermediary["header_1"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) validators4 := jsonIntermediary["header_2"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) - validators := append(validators1, validators2...) + validators := validators1 + validators = append(validators, validators2...) validators = append(validators, validators3...) validators = append(validators, validators4...) for _, val := range validators { @@ -205,7 +208,8 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) error { header1Sigs := jsonIntermediary["header_1"].(map[string]interface{})["signed_header"].(map[string]interface{})["commit"].(map[string]interface{})["signatures"].([]interface{}) header2Sigs := jsonIntermediary["header_2"].(map[string]interface{})["signed_header"].(map[string]interface{})["commit"].(map[string]interface{})["signatures"].([]interface{}) - sigs := append(header1Sigs, header2Sigs...) + sigs := header1Sigs + sigs = append(sigs, header2Sigs...) for _, sig := range sigs { sig := sig.(map[string]interface{}) if sig["block_id_flag"] == "BLOCK_ID_FLAG_COMMIT" { @@ -231,7 +235,7 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) error { } // TODO: Make file temporary and delete it after use - if err := os.WriteFile(misbehaviourFileName, misbehaviourBz, 0644); err != nil { + if err := os.WriteFile(misbehaviourFileName, misbehaviourBz, 0o600); err != nil { return err } diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index 5381426..9b0c4b4 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -6,16 +6,6 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" - "github.com/cometbft/cometbft/crypto/tmhash" - cometproto "github.com/cometbft/cometbft/proto/tendermint/types" - comettypes "github.com/cometbft/cometbft/types" - comettime "github.com/cometbft/cometbft/types/time" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - ibcclientutils "github.com/cosmos/ibc-go/v8/modules/core/02-client/client/utils" - clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" - tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" - ibcmocks "github.com/cosmos/ibc-go/v8/testing/mock" - "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "os" "strconv" "testing" @@ -27,11 +17,23 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + + "github.com/cometbft/cometbft/crypto/tmhash" + cometproto "github.com/cometbft/cometbft/proto/tendermint/types" + comettypes "github.com/cometbft/cometbft/types" + comettime "github.com/cometbft/cometbft/types/time" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibcclientutils "github.com/cosmos/ibc-go/v8/modules/core/02-client/client/utils" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" ibchost "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" + tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v8/testing" + ibcmocks "github.com/cosmos/ibc-go/v8/testing/mock" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testutil" @@ -252,7 +254,7 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { oldHeader.TrustedValidators = oldHeader.ValidatorSet // ? s.Require().NoError(err) - // create a duplicate header + // create a duplicate header (with a different hash) newHeader := s.createTMClientHeader( ctx, simd, @@ -267,6 +269,7 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { Header2: &oldHeader, } + // TODO: Get fixture from operator and use it with the contract err = operator.Misbehaviour(simd.GetCodec(), misbehaviour) s.Require().NoError(err) })) diff --git a/operator/src/bin/operator.rs b/operator/src/bin/operator.rs index 94899f5..0b06c62 100644 --- a/operator/src/bin/operator.rs +++ b/operator/src/bin/operator.rs @@ -3,7 +3,7 @@ use sp1_ics07_tendermint_operator::{ cli::command::{fixtures, Commands, OperatorCli}, runners::{ self, - fixtures::{membership, uc_and_mem, update_client, misbehaviour}, + fixtures::{membership, misbehaviour, uc_and_mem, update_client}, }, }; use sp1_sdk::utils::setup_logger; diff --git a/operator/src/prover.rs b/operator/src/prover.rs index ea987e9..079bcd1 100644 --- a/operator/src/prover.rs +++ b/operator/src/prover.rs @@ -1,7 +1,8 @@ //! Prover for SP1 ICS07 Tendermint programs. use crate::programs::{ - MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, MisbehaviourProgram, + MembershipProgram, MisbehaviourProgram, SP1Program, UpdateClientAndMembershipProgram, + UpdateClientProgram, }; use ibc_client_tendermint::types::{Header, Misbehaviour}; use ibc_core_commitment_types::merkle::MerkleProof; diff --git a/operator/src/runners/fixtures/misbehaviour.rs b/operator/src/runners/fixtures/misbehaviour.rs index 4d43d76..3b9e244 100644 --- a/operator/src/runners/fixtures/misbehaviour.rs +++ b/operator/src/runners/fixtures/misbehaviour.rs @@ -1,23 +1,23 @@ //! Runner for generating `misbehaviour` fixtures -use std::path::PathBuf; use crate::cli::command::fixtures::MisbehaviourCmd; +use crate::cli::command::OutputPath; +use crate::helpers::light_block::LightBlockExt; use crate::programs::MisbehaviourProgram; use crate::prover::SP1ICS07TendermintProver; +use crate::rpc::TendermintRpcExt; use crate::runners::genesis::SP1ICS07TendermintGenesis; use alloy_sol_types::SolValue; use ibc_client_tendermint::types::Misbehaviour; use ibc_proto::ibc::lightclients::tendermint::v1::Misbehaviour as RawMisbehaviour; use serde::{Deserialize, Serialize}; use serde_with::serde_as; -use tendermint_rpc::HttpClient; use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{ - Env, ClientState, ConsensusState, SP1Proof, MsgSubmitMisbehaviour, + ClientState, ConsensusState, Env, MsgSubmitMisbehaviour, SP1Proof, }; use sp1_sdk::HashableKey; -use crate::cli::command::OutputPath; -use crate::helpers::light_block::LightBlockExt; -use crate::rpc::TendermintRpcExt; +use std::path::PathBuf; +use tendermint_rpc::HttpClient; /// The fixture data to be used in [`SP1ICS07SubmitMisbehaviourFixture`] tests. #[serde_as] @@ -27,7 +27,7 @@ struct SP1ICS07SubmitMisbehaviourFixture { /// The genesis data. #[serde(flatten)] genesis: SP1ICS07TendermintGenesis, - + /// The encoded submit misbehaviour client message. #[serde_as(as = "serde_with::hex::Hex")] submit_msg: Vec, @@ -43,22 +43,40 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { let tm_rpc_client = HttpClient::from_env(); let trusted_light_block_1 = tm_rpc_client - .get_light_block(Some(raw_misbehaviour.clone().header_1.unwrap().trusted_height.unwrap().revision_height as u32)) + .get_light_block(Some( + raw_misbehaviour + .clone() + .header_1 + .unwrap() + .trusted_height + .unwrap() + .revision_height as u32, + )) .await?; let trusted_light_block_2 = tm_rpc_client - .get_light_block(Some(raw_misbehaviour.clone().header_2.unwrap().trusted_height.unwrap().revision_height as u32)) + .get_light_block(Some( + raw_misbehaviour + .clone() + .header_2 + .unwrap() + .trusted_height + .unwrap() + .revision_height as u32, + )) .await?; let genesis_1 = SP1ICS07TendermintGenesis::from_env( &trusted_light_block_1, args.trust_options.trusting_period, args.trust_options.trust_level, - ).await?; + ) + .await?; let genesis_2 = SP1ICS07TendermintGenesis::from_env( &trusted_light_block_2, args.trust_options.trusting_period, args.trust_options.trust_level, - ).await?; + ) + .await?; let trusted_consensus_state_1 = ConsensusState::abi_decode(&genesis_1.trusted_consensus_state, false)?; @@ -78,7 +96,12 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { }; let misbehaviour: Misbehaviour = Misbehaviour::try_from(raw_misbehaviour).unwrap(); - let proof_data = verify_misbehaviour_prover.generate_proof(&contract_env, &misbehaviour, &trusted_consensus_state_1, &trusted_consensus_state_2); + let proof_data = verify_misbehaviour_prover.generate_proof( + &contract_env, + &misbehaviour, + &trusted_consensus_state_1, + &trusted_consensus_state_2, + ); let submit_msg = MsgSubmitMisbehaviour { sp1Proof: SP1Proof::new( @@ -90,16 +113,13 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { let fixture = SP1ICS07SubmitMisbehaviourFixture { genesis: genesis_2, - submit_msg: submit_msg.abi_encode(), + submit_msg: submit_msg.abi_encode(), }; match args.output_path { OutputPath::File(path) => { // Save the proof data to the file path. - std::fs::write( - PathBuf::from(path), - serde_json::to_string_pretty(&fixture)?, - )?; + std::fs::write(PathBuf::from(path), serde_json::to_string_pretty(&fixture)?)?; } OutputPath::Stdout => { println!("{}", serde_json::to_string_pretty(&fixture)?); @@ -107,4 +127,4 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { } Ok(()) -} \ No newline at end of file +} diff --git a/operator/src/runners/fixtures/mod.rs b/operator/src/runners/fixtures/mod.rs index 2de23ec..898d44b 100644 --- a/operator/src/runners/fixtures/mod.rs +++ b/operator/src/runners/fixtures/mod.rs @@ -1,6 +1,6 @@ //! Runners for generating fixtures for testing of the programs. pub mod membership; +pub mod misbehaviour; pub mod uc_and_mem; pub mod update_client; -pub mod misbehaviour; diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index bbc872f..34d0472 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -4,33 +4,49 @@ pub mod types; -use std::collections::HashMap; -use std::time::Duration; -use ibc_client_tendermint::client_state::{verify_misbehaviour, check_for_misbehaviour_on_misbehavior}; +use ibc_client_tendermint::client_state::{ + check_for_misbehaviour_on_misbehavior, verify_misbehaviour, +}; use ibc_client_tendermint::types::{ConsensusState, Misbehaviour, TENDERMINT_CLIENT_TYPE}; use ibc_core_host_types::identifiers::{ChainId, ClientId}; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{Env, MisbehaviourOutput}; +use std::collections::HashMap; +use std::time::Duration; use tendermint_light_client_verifier::options::Options; use tendermint_light_client_verifier::ProdVerifier; -use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{Env, MisbehaviourOutput}; /// The main function of the program without the zkVM wrapper. #[allow(clippy::missing_panics_doc)] #[must_use] pub fn check_for_misbehaviour( env: Env, - misbehaviour: Misbehaviour, - trusted_consensus_state_1: ConsensusState, - trusted_consensus_state_2: ConsensusState + misbehaviour: Misbehaviour, + trusted_consensus_state_1: ConsensusState, + trusted_consensus_state_2: ConsensusState, ) -> MisbehaviourOutput { - let client_id = ClientId::new(TENDERMINT_CLIENT_TYPE, 0).unwrap(); let chain_id = env.clone().chainId; - assert_eq!(chain_id, misbehaviour.header1().signed_header.header.chain_id.to_string()); - + assert_eq!( + chain_id, + misbehaviour + .header1() + .signed_header + .header + .chain_id + .to_string() + ); + let mut trusted_consensus_state_map = HashMap::new(); - trusted_consensus_state_map.insert(misbehaviour.header1().trusted_height.revision_height(), &trusted_consensus_state_1); - trusted_consensus_state_map.insert(misbehaviour.header2().trusted_height.revision_height(), &trusted_consensus_state_2); - let ctx = types::validation::MisbehaviourValidationContext::new(&env, trusted_consensus_state_map); + trusted_consensus_state_map.insert( + misbehaviour.header1().trusted_height.revision_height(), + &trusted_consensus_state_1, + ); + trusted_consensus_state_map.insert( + misbehaviour.header2().trusted_height.revision_height(), + &trusted_consensus_state_2, + ); + let ctx = + types::validation::MisbehaviourValidationContext::new(&env, trusted_consensus_state_map); let options = Options { trust_threshold: env.trustThreshold.clone().into(), @@ -44,9 +60,10 @@ pub fn check_for_misbehaviour( &client_id, &ChainId::new(chain_id.as_str()).unwrap(), &options, - &ProdVerifier::default(), - ).unwrap(); - + &ProdVerifier::default(), + ) + .unwrap(); + let is_misbehaviour = check_for_misbehaviour_on_misbehavior(misbehaviour.header1(), misbehaviour.header2()) .unwrap(); diff --git a/programs/misbehaviour/src/main.rs b/programs/misbehaviour/src/main.rs index 1fbfa8e..7aee4b7 100644 --- a/programs/misbehaviour/src/main.rs +++ b/programs/misbehaviour/src/main.rs @@ -30,7 +30,7 @@ pub fn main() { let env = bincode::deserialize::(&encoded_1).unwrap(); // input 2: the misbehaviour evidence let misbehaviour = serde_cbor::from_slice::(&encoded_2).unwrap(); - // input 3: header 1 trusted consensus state + // input 3: header 1 trusted consensus state let trusted_consensus_state_1 = bincode::deserialize::(&encoded_3) .unwrap() .into(); @@ -38,9 +38,13 @@ pub fn main() { let trusted_consensus_state_2 = bincode::deserialize::(&encoded_4) .unwrap() .into(); - - let output = check_for_misbehaviour(env, misbehaviour, trusted_consensus_state_1, trusted_consensus_state_2); + let output = check_for_misbehaviour( + env, + misbehaviour, + trusted_consensus_state_1, + trusted_consensus_state_2, + ); sp1_zkvm::io::commit_slice(&output.abi_encode()); } diff --git a/programs/misbehaviour/src/types/validation.rs b/programs/misbehaviour/src/types/validation.rs index 35987db..8fd0ce5 100644 --- a/programs/misbehaviour/src/types/validation.rs +++ b/programs/misbehaviour/src/types/validation.rs @@ -1,6 +1,5 @@ //! Contains types and traits for `verify_misbehaviour` validation within the program. -use std::collections::HashMap; use ibc_client_tendermint::{ client_state::ClientState as ClientStateWrapper, consensus_state::ConsensusState as ConsensusStateWrapper, types::ConsensusState, @@ -9,6 +8,7 @@ use ibc_core_client::context::{ClientValidationContext, ExtClientValidationConte use ibc_core_handler_types::error::ContextError; use ibc_primitives::Timestamp; use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::Env; +use std::collections::HashMap; /// The client validation context. pub struct MisbehaviourValidationContext<'a, 'b> { @@ -39,9 +39,8 @@ impl<'a, 'b> ClientValidationContext for MisbehaviourValidationContext<'a, 'b> { client_cons_state_path: &ibc_core_host_types::path::ClientConsensusStatePath, ) -> Result { let height = client_cons_state_path.revision_height; - let trusted_consensus_state = self - .trusted_consensus_states[&height]; - + let trusted_consensus_state = self.trusted_consensus_states[&height]; + Ok(trusted_consensus_state.clone().into()) } From 849d0205c605ea3f7fd0ea3fdd961cadee5ac8da Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Mon, 26 Aug 2024 12:41:27 +0200 Subject: [PATCH 04/22] output misbehaviour fixture from e2e test --- contracts/abi/SP1ICS07Tendermint.json | 98 ++++++++++++++- .../fixtures/e2e_misbehaviour_fixture.json | 9 ++ contracts/fixtures/misbehaviour_fixture.json | 8 -- contracts/script/SP1ICS07Tendermint.s.sol | 6 +- contracts/script/genesis.json | 9 +- contracts/src/ISP1ICS07Tendermint.sol | 4 + contracts/src/SP1ICS07Tendermint.sol | 95 ++++++++++---- contracts/src/msgs/IICS07TendermintMsgs.sol | 13 ++ contracts/src/msgs/IMisbehaviourMsgs.sol | 8 +- contracts/src/msgs/IUpdateClientMsgs.sol | 13 -- contracts/test/MisbehaviourTest.t.sol | 5 +- contracts/test/SP1ICS07TendermintTest.sol | 7 +- e2e/interchaintestv8/operator/operator.go | 43 ++++++- e2e/interchaintestv8/sp1_ics07_test.go | 16 ++- e2e/interchaintestv8/testvalues/values.go | 4 + .../types/sp1ics07tendermint/contract.go | 117 +++++++++++------- operator/src/runners/genesis.rs | 4 + programs/misbehaviour/src/lib.rs | 18 ++- 18 files changed, 362 insertions(+), 115 deletions(-) create mode 100644 contracts/fixtures/e2e_misbehaviour_fixture.json delete mode 100644 contracts/fixtures/misbehaviour_fixture.json diff --git a/contracts/abi/SP1ICS07Tendermint.json b/contracts/abi/SP1ICS07Tendermint.json index 03d5489..a9c7e67 100644 --- a/contracts/abi/SP1ICS07Tendermint.json +++ b/contracts/abi/SP1ICS07Tendermint.json @@ -17,6 +17,11 @@ "type": "bytes32", "internalType": "bytes32" }, + { + "name": "misbehaviourProgramVkey", + "type": "bytes32", + "internalType": "bytes32" + }, { "name": "verifier", "type": "address", @@ -61,6 +66,19 @@ ], "stateMutability": "view" }, + { + "type": "function", + "name": "MISBEHAVIOUR_PROGRAM_VKEY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, { "type": "function", "name": "UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY", @@ -190,7 +208,7 @@ { "name": "env", "type": "tuple", - "internalType": "struct IUpdateClientMsgs.Env", + "internalType": "struct IICS07TendermintMsgs.Env", "components": [ { "name": "chainId", @@ -413,9 +431,77 @@ "internalType": "struct IMisbehaviourMsgs.MisbehaviourOutput", "components": [ { - "name": "isMisbehaviour", - "type": "bool", - "internalType": "bool" + "name": "env", + "type": "tuple", + "internalType": "struct IICS07TendermintMsgs.Env", + "components": [ + { + "name": "chainId", + "type": "string", + "internalType": "string" + }, + { + "name": "trustThreshold", + "type": "tuple", + "internalType": "struct IICS07TendermintMsgs.TrustThreshold", + "components": [ + { + "name": "numerator", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "denominator", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "name": "trustingPeriod", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "now", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "name": "trustedHeight1", + "type": "tuple", + "internalType": "struct IICS02ClientMsgs.Height", + "components": [ + { + "name": "revisionNumber", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "revisionHeight", + "type": "uint32", + "internalType": "uint32" + } + ] + }, + { + "name": "trustedHeight2", + "type": "tuple", + "internalType": "struct IICS02ClientMsgs.Height", + "components": [ + { + "name": "revisionNumber", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "revisionHeight", + "type": "uint32", + "internalType": "uint32" + } + ] }, { "name": "trustedConsensusState1", @@ -642,13 +728,13 @@ "name": "misbehaviour", "inputs": [ { - "name": "", + "name": "misbehaviourMsg", "type": "bytes", "internalType": "bytes" } ], "outputs": [], - "stateMutability": "pure" + "stateMutability": "nonpayable" }, { "type": "function", diff --git a/contracts/fixtures/e2e_misbehaviour_fixture.json b/contracts/fixtures/e2e_misbehaviour_fixture.json new file mode 100644 index 000000000..2f64fe6 --- /dev/null +++ b/contracts/fixtures/e2e_misbehaviour_fixture.json @@ -0,0 +1,9 @@ +{ + "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cc5a4a76ffd7c0f7b019c80dc3b2d9e05e1bc803074277ad8fd836edf4208cb0093c491d7bacd36d73696f4ab07a9813837ffedd342ec024c91b929ee0652e9931c517", + "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", + "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", + "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", + "misbehaviourVkey": "0x0064ffd659dfc4aef854ad17da8ab2be54ac95b2826d0acb94d4740380eebdcc", + "submitMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200064ffd659dfc4aef854ad17da8ab2be54ac95b2826d0acb94d4740380eebdcc000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066cc5a4a76ffd7c0f7b019c80dc3b2d9e05e1bc803074277ad8fd836edf4208cb0093c491d7bacd36d73696f4ab07a9813837ffedd342ec024c91b929ee0652e9931c5170000000000000000000000000000000000000000000000000000000066cc5a4a76ffd7c0f7b019c80dc3b2d9e05e1bc803074277ad8fd836edf4208cb0093c491d7bacd36d73696f4ab07a9813837ffedd342ec024c91b929ee0652e9931c51700000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066cc5a87000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f02a9fef18efbee1f8151fbe720e342674eae980314fe79e82ab9825047ac666f2f25ecb426599aa1480a74677d497f352d0e243559b19f24dc88d6f4a6402cf121422d16c85f76091f4894603fb1ae416f820cfef830d5c6cf662b4d8da9101a0f1033ff4d972b479f6cda388872260c3792c4aa3ba587d54bf903a0e0aa76ad236136c44d680ab675b6166b18eab7100141dec0b4abb8619c675985b271edf6275f07d04fe73633b42bb3192207c929b68e895d5e7ea3da7b313e27ab6f4ee312b1a2f39690c49b7a8c41e584757df59b804dfaa177bb66ef7eeb54410ede102baa5d752ef5bc4f580d70f24d4ea24121def5eec0b4904ddb4b083088b506bb022d35801c6cd2e1a9ff287af427cad7374b88d51d417486c84d8c7411c6ad7c251728a8a64514a96a08f03ac4c6409c4b3ff3912d3c0bddd621190f7210ad46210f34c427992b824c3966c8a877e84121a2b96bf04d7bbce5da9be6a2fc36d404c2fa239deb6227dfb2b926dff7e8abc9486555b7771b8d510bfce0758af1d80a89ea071e0c8b3f3fa0537ed87bc25818e864fa0431ea160a1d0ba4d791ffa42231608f9e93149396b3c10528d7ec6f478120cf33961a6022d4cb083ef090ef0192de5e3899168ad60e4ea355129f21bdcc150a1da3b1da12033630485176070ae34c0ad57dda550d07651356fa34ddd2f16669a0ce14f0d8b056615acfb02c215aefe753c01a48f993ac9233e41376cc2dfd51b39c120f97b76ccb6abc2a1f0efe8f0c5cbbce4cbe10d10c4366d3db926d273350dd38f8d9e68c38f580d02e1d2881b27fbdbaad0d0a8c7b21c530632391e4a6dc60795fdcf4996121f8546c2a932ef2a9e48709aa7d67bd527c37d1c2071b81f22664f16b859d9ff6101fe102157f751528e1e3198a02fdb144da871bab35ed982adb0a1042cfae66a4faac0a46e285f371a542f4ddf68fa5e319b6f8b83f90773099f66dd8b0d5992b054117ee5d1b97c67b4309d36d7e1c5e796f5c98850f0754b9e84910d91c327c540d1f8b10b48d7e411862d7424c5ca526754465ac879083aece917cae64dbd9f85105280b81ccf5c8cec4f550ad568adcc39c7274c6d3c065678731385e62a335a72971d07c1947d6e6a55a6e80e936555ece6d4cc85ae2dfe53b566c40203d63c817f42a6c75c5c1ac7288b0f738908373bc8dd0b543a7422e68eb3aa20dc10e9d00000000000000000000000000000000000000000000000000000000" +} diff --git a/contracts/fixtures/misbehaviour_fixture.json b/contracts/fixtures/misbehaviour_fixture.json deleted file mode 100644 index 92839e8..000000000 --- a/contracts/fixtures/misbehaviour_fixture.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066c5f6653a7a0169b19e1d7e93e2856ed3e94f63d9329e59efdd681c519cc49ea750db59a9fdc69f863ff399f0f25beb3cfbb9d6c9a0f8628a2a0fea1d46b8a1cd5bc8c6", - "updateClientVkey": "0x006421f924828320ce4f10c34daf79e0c361c5720d02dff12844604996acff10", - "membershipVkey": "0x00b9581944af28ba1501054b2da49d563a2a81b40a6676a4123c130368f94fda", - "ucAndMembershipVkey": "0x00e3b81a5f0fd284314a86f39a56832064aef3864ba2f8adb34dd2cf40a9aea7", - "submitMsg": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000491ce01c2c24739655babf33fe9c9a691f9efe389d067a67706c023e44960e0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000066c5f6653a7a0169b19e1d7e93e2856ed3e94f63d9329e59efdd681c519cc49ea750db59a9fdc69f863ff399f0f25beb3cfbb9d6c9a0f8628a2a0fea1d46b8a1cd5bc8c60000000000000000000000000000000000000000000000000000000066c5f6653a7a0169b19e1d7e93e2856ed3e94f63d9329e59efdd681c519cc49ea750db59a9fdc69f863ff399f0f25beb3cfbb9d6c9a0f8628a2a0fea1d46b8a1cd5bc8c60000000000000000000000000000000000000000000000000000000000000364c430ff7f007f13e2a22a413363e129a434cf1ebebcb8744ace0469713e83f8d63e1c2b3a03cd0e2c12655a3e8f9f94915d683b962c856164c7017e51f6e6c5e8629095441ddc26614fd9dfc1e732935204e382ca70045a6d421a40bdb573dcd8e4e7eb662133c16ee78b6bfe85c200ab8e8fcf9e7baf9531f95c5c9eccce34c9085e7cde00b19979c55f2c29c77000c9dfc844856dbe3e85d7ccad8aa05b517a223afdce2ae2571e396c79397fb7c0b5fe1b767f4d4647adedf310643a8e18c9bcdf20a029439f3eafef20412089b5a18413c862889b89ba6abf28ae95ad8a587de2252e174057ac0d416a2470742388dd81e517ab62b95344e9037268422d2c3d94aabd05c76cbbd992670bc0fc4676d41d93b3b1d0de8695533a6f11281619c7a157f01487ecc1b1b7e7fed1f85dd73080de64128079657a717fdb786af5205c93b30f1cc62ca519c9073e2d156005946e500c0c98f796d1a0b46df3a5d3964bce64d416a0b0e57173a3b9f460a46b8e2f738645fe5ceb98377cbda6cd9f260727a5b90790b513f58b20992f5efd00418686634bf76a56edce609cc0003bdc818480620188bbb370d10f72376da72875b14e3e60799006db8017210fe6bba16ddbc46924c39590f7181e74f06e1d99271d261bb4072155c0e09560b01caa61dc14e8472304d140b10d6c4435ab1b52d54756d956d86854a13969538d8d45cef771bff11b9cc280808e4c1f2497358d24a6c3fad091203114062519999ed00e40e30de73032b4aecfa344c370e232aefe264b6e867f44947c4729b86825b55148b8849223b5aae80a5d4f84e355df1c0b54dc3744115f27908d0488681fbff79595b0ff14fb5fb0d5afef31c852bab648c69fd7e729fc357891a8842373eacf57a52a181a0a0fe19810af7750aaa734acb7c2a5116f14e831089b37555ab05afaf84a921511d12d5ba14c7524727644f895de810075e93e0bb5d58b69a4c59ad48ee1ba070a89040a253aab5a49ae1be936d4620aed07a3728d6d4718ff9d5caadbb2c9251aeadf99d9c7937acc48ff2d86f6568d836d1f35e203d00ee5358f3a507ae5212e5e5d1990a79397611acd6928a62b4c9ab306312f423f88859982464d63282f8327ed45323f20251edd305da8e8a693339a37b272de7226d53ca2b3cfb4a705d0dd5454921cc6a7cde421472e72ac4cb59da3973836953d32a8d6f5486b1a00000000000000000000000000000000000000000000000000000000" -} \ No newline at end of file diff --git a/contracts/script/SP1ICS07Tendermint.s.sol b/contracts/script/SP1ICS07Tendermint.s.sol index 9a199d1..f959f3e 100644 --- a/contracts/script/SP1ICS07Tendermint.s.sol +++ b/contracts/script/SP1ICS07Tendermint.s.sol @@ -13,6 +13,7 @@ struct SP1ICS07TendermintGenesisJson { bytes32 updateClientVkey; bytes32 membershipVkey; bytes32 ucAndMembershipVkey; + bytes32 misbehaviourVkey; } contract SP1TendermintScript is Script, IICS07TendermintMsgs { @@ -36,6 +37,7 @@ contract SP1TendermintScript is Script, IICS07TendermintMsgs { genesis.updateClientVkey, genesis.membershipVkey, genesis.ucAndMembershipVkey, + genesis.misbehaviourVkey, address(verifier), genesis.trustedClientState, trustedConsensusHash @@ -61,13 +63,15 @@ contract SP1TendermintScript is Script, IICS07TendermintMsgs { bytes32 updateClientVkey = json.readBytes32(".updateClientVkey"); bytes32 membershipVkey = json.readBytes32(".membershipVkey"); bytes32 ucAndMembershipVkey = json.readBytes32(".ucAndMembershipVkey"); + bytes32 misbehaviourVkey = json.readBytes32(".misbehaviourVkey"); SP1ICS07TendermintGenesisJson memory fixture = SP1ICS07TendermintGenesisJson({ trustedClientState: trustedClientState, trustedConsensusState: trustedConsensusState, updateClientVkey: updateClientVkey, membershipVkey: membershipVkey, - ucAndMembershipVkey: ucAndMembershipVkey + ucAndMembershipVkey: ucAndMembershipVkey, + misbehaviourVkey: misbehaviourVkey }); return fixture; diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index a7eb7c7..cf6264e 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,7 +1,8 @@ { - "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066c64c13bde2e49088fa7da21364dc8b818a70a29ec3670cb557041d06654bb83a07abcadbd14b0e2076f203b2481a8da160c6b5fea4746739d4abdd79be8b42a52a18f0", - "updateClientVkey": "0x006421f924828320ce4f10c34daf79e0c361c5720d02dff12844604996acff10", + "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cc5a4a76ffd7c0f7b019c80dc3b2d9e05e1bc803074277ad8fd836edf4208cb0093c491d7bacd36d73696f4ab07a9813837ffedd342ec024c91b929ee0652e9931c517", + "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", - "ucAndMembershipVkey": "0x00c9ebf0be8701d530f4f344e8e9ee8d75faaa05fc8621c91e8611db29483b0b" + "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", + "misbehaviourVkey": "0x0064ffd659dfc4aef854ad17da8ab2be54ac95b2826d0acb94d4740380eebdcc" } \ No newline at end of file diff --git a/contracts/src/ISP1ICS07Tendermint.sol b/contracts/src/ISP1ICS07Tendermint.sol index b90496f..519f11c 100644 --- a/contracts/src/ISP1ICS07Tendermint.sol +++ b/contracts/src/ISP1ICS07Tendermint.sol @@ -20,6 +20,10 @@ interface ISP1ICS07Tendermint is ILightClient { /// @return The verification key for the update client and membership program. function UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY() external view returns (bytes32); + /// @notice Immutable misbehaviour program verification key. + /// @return The verification key for the misbehaviour program. + function MISBEHAVIOUR_PROGRAM_VKEY() external view returns (bytes32); + /// @notice Immutable SP1 verifier contract address. /// @return The SP1 verifier contract. function VERIFIER() external view returns (ISP1Verifier); diff --git a/contracts/src/SP1ICS07Tendermint.sol b/contracts/src/SP1ICS07Tendermint.sol index 6f6d8a0..03e7f91 100644 --- a/contracts/src/SP1ICS07Tendermint.sol +++ b/contracts/src/SP1ICS07Tendermint.sol @@ -22,6 +22,7 @@ contract SP1ICS07Tendermint is IUpdateClientMsgs, IMembershipMsgs, IUpdateClientAndMembershipMsgs, + IMisbehaviourMsgs, ISP1ICS07TendermintErrors, ILightClientMsgs, ISP1ICS07Tendermint @@ -33,6 +34,8 @@ contract SP1ICS07Tendermint is /// @inheritdoc ISP1ICS07Tendermint bytes32 public immutable UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY; /// @inheritdoc ISP1ICS07Tendermint + bytes32 public immutable MISBEHAVIOUR_PROGRAM_VKEY; + /// @inheritdoc ISP1ICS07Tendermint ISP1Verifier public immutable VERIFIER; /// @notice The ICS07Tendermint client state @@ -48,6 +51,7 @@ contract SP1ICS07Tendermint is /// @param updateClientProgramVkey The verification key for the update client program. /// @param membershipProgramVkey The verification key for the verify (non)membership program. /// @param updateClientAndMembershipProgramVkey The verification key for the update client and membership program. + /// @param misbehaviourProgramVkey The verification key for the misbehaviour program. /// @param verifier The address of the SP1 verifier contract. /// @param _clientState The encoded initial client state. /// @param _consensusState The encoded initial consensus state. @@ -55,6 +59,7 @@ contract SP1ICS07Tendermint is bytes32 updateClientProgramVkey, bytes32 membershipProgramVkey, bytes32 updateClientAndMembershipProgramVkey, + bytes32 misbehaviourProgramVkey, address verifier, bytes memory _clientState, bytes32 _consensusState @@ -62,6 +67,7 @@ contract SP1ICS07Tendermint is UPDATE_CLIENT_PROGRAM_VKEY = updateClientProgramVkey; MEMBERSHIP_PROGRAM_VKEY = membershipProgramVkey; UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY = updateClientAndMembershipProgramVkey; + MISBEHAVIOUR_PROGRAM_VKEY = misbehaviourProgramVkey; VERIFIER = ISP1Verifier(verifier); clientState = abi.decode(_clientState, (ClientState)); @@ -136,9 +142,40 @@ contract SP1ICS07Tendermint is /// @notice The entrypoint for misbehaviour. /// @inheritdoc ILightClient - function misbehaviour(bytes calldata) public pure { - // TODO: Not yet implemented. (#56) - revert FeatureNotSupported(); + function misbehaviour(bytes calldata misbehaviourMsg) public { + MsgSubmitMisbehaviour memory msgSubmitMisbehaviour = abi.decode(misbehaviourMsg, (MsgSubmitMisbehaviour)); + if (msgSubmitMisbehaviour.sp1Proof.vKey != MISBEHAVIOUR_PROGRAM_VKEY) { + revert VerificationKeyMismatch(MISBEHAVIOUR_PROGRAM_VKEY, msgSubmitMisbehaviour.sp1Proof.vKey); + } + + MisbehaviourOutput memory output = abi.decode(msgSubmitMisbehaviour.sp1Proof.publicValues, (MisbehaviourOutput)); + validateMisbehaviourOutput(output); + + verifySP1Proof(msgSubmitMisbehaviour.sp1Proof); + + // If the misbehaviour is valid, the client is frozen + clientState.isFrozen = true; + } + + /// @notice Validates the SP1ICS07MisbehaviourOutput public values. + /// @param output The public values. + function validateMisbehaviourOutput(MisbehaviourOutput memory output) private view { + if (clientState.isFrozen) { + revert FrozenClientState(); + } + validateEnv(output.env); + + bytes32 outputConsensusStateHash1 = keccak256(abi.encode(output.trustedConsensusState1)); + bytes32 trustedConsensusState1 = getConsensusStateHash(output.trustedHeight1.revisionHeight); + if (outputConsensusStateHash1 != trustedConsensusState1) { + revert ConsensusStateHashMismatch(trustedConsensusState1, outputConsensusStateHash1); + } + + bytes32 outputConsensusStateHash2 = keccak256(abi.encode(output.trustedConsensusState2)); + bytes32 trustedConsensusState2 = getConsensusStateHash(output.trustedHeight2.revisionHeight); + if (outputConsensusStateHash2 != trustedConsensusState2) { + revert ConsensusStateHashMismatch(trustedConsensusState2, outputConsensusStateHash2); + } } /// @notice The entrypoint for upgrading the client. @@ -332,37 +369,43 @@ contract SP1ICS07Tendermint is if (clientState.isFrozen) { revert FrozenClientState(); } - if (output.env.now > block.timestamp) { - revert ProofIsInTheFuture(block.timestamp, output.env.now); + validateEnv(output.env); + + bytes32 outputConsensusStateHash = keccak256(abi.encode(output.trustedConsensusState)); + bytes32 trustedConsensusStateHash = getConsensusStateHash(output.trustedHeight.revisionHeight); + if (outputConsensusStateHash != trustedConsensusStateHash) { + revert ConsensusStateHashMismatch(trustedConsensusStateHash, outputConsensusStateHash); } - if (block.timestamp - output.env.now > ALLOWED_SP1_CLOCK_DRIFT) { - revert ProofIsTooOld(block.timestamp, output.env.now); + } + + /// @notice Validates the Env public values. + /// @param env The public values. + function validateEnv(Env memory env) private view { + if (env.now > block.timestamp) { + revert ProofIsInTheFuture(block.timestamp, env.now); } - if (keccak256(bytes(output.env.chainId)) != keccak256(bytes(clientState.chainId))) { - revert ChainIdMismatch(clientState.chainId, output.env.chainId); + if (block.timestamp - env.now > ALLOWED_SP1_CLOCK_DRIFT) { + revert ProofIsTooOld(block.timestamp, env.now); + } + if (keccak256(bytes(env.chainId)) != keccak256(bytes(clientState.chainId))) { + revert ChainIdMismatch(clientState.chainId, env.chainId); } if ( - output.env.trustThreshold.numerator != clientState.trustLevel.numerator - || output.env.trustThreshold.denominator != clientState.trustLevel.denominator + env.trustThreshold.numerator != clientState.trustLevel.numerator + || env.trustThreshold.denominator != clientState.trustLevel.denominator ) { revert TrustThresholdMismatch( clientState.trustLevel.numerator, clientState.trustLevel.denominator, - output.env.trustThreshold.numerator, - output.env.trustThreshold.denominator + env.trustThreshold.numerator, + env.trustThreshold.denominator ); } - if (output.env.trustingPeriod != clientState.trustingPeriod) { - revert TrustingPeriodMismatch(clientState.trustingPeriod, output.env.trustingPeriod); - } - if (output.env.trustingPeriod > clientState.unbondingPeriod) { - revert TrustingPeriodTooLong(output.env.trustingPeriod, clientState.unbondingPeriod); + if (env.trustingPeriod != clientState.trustingPeriod) { + revert TrustingPeriodMismatch(clientState.trustingPeriod, env.trustingPeriod); } - - bytes32 outputConsensusStateHash = keccak256(abi.encode(output.trustedConsensusState)); - bytes32 trustedConsensusStateHash = getConsensusStateHash(output.trustedHeight.revisionHeight); - if (outputConsensusStateHash != trustedConsensusStateHash) { - revert ConsensusStateHashMismatch(trustedConsensusStateHash, outputConsensusStateHash); + if (env.trustingPeriod > clientState.unbondingPeriod) { + revert TrustingPeriodTooLong(env.trustingPeriod, clientState.unbondingPeriod); } } @@ -412,14 +455,14 @@ contract SP1ICS07Tendermint is MembershipProof memory o4, SP1MembershipProof memory o5, SP1MembershipAndUpdateClientProof memory o6, - IMisbehaviourMsgs.MisbehaviourOutput memory o7, - IMisbehaviourMsgs.MsgSubmitMisbehaviour memory o8 + MisbehaviourOutput memory o7, + MsgSubmitMisbehaviour memory o8 ) public pure // solhint-disable-next-line no-empty-blocks { - // This is a dummy function to generate the ABI for MembershipOutput + // This is a dummy function to generate the ABI for outputs // so that it can be used in the SP1 verifier contract. // The function is not used in the contract. } diff --git a/contracts/src/msgs/IICS07TendermintMsgs.sol b/contracts/src/msgs/IICS07TendermintMsgs.sol index 09958b7..dbc4a45 100644 --- a/contracts/src/msgs/IICS07TendermintMsgs.sol +++ b/contracts/src/msgs/IICS07TendermintMsgs.sol @@ -42,4 +42,17 @@ interface IICS07TendermintMsgs is IICS02ClientMsgs { bytes32 root; bytes32 nextValidatorsHash; } + + /// @notice The environment output for the sp1 program. + /// @param chainId The chain ID of the chain that the client is tracking. + /// @param trustThreshold Fraction of validator overlap needed to update header + /// @param trustingPeriod Duration of the period since the `LatestTimestamp` during which the + /// submitted headers are valid for upgrade in seconds. + /// @param now Timestamp in seconds. + struct Env { + string chainId; + TrustThreshold trustThreshold; + uint32 trustingPeriod; + uint64 now; + } } diff --git a/contracts/src/msgs/IMisbehaviourMsgs.sol b/contracts/src/msgs/IMisbehaviourMsgs.sol index cbf7715..b08458d 100644 --- a/contracts/src/msgs/IMisbehaviourMsgs.sol +++ b/contracts/src/msgs/IMisbehaviourMsgs.sol @@ -15,11 +15,15 @@ interface IMisbehaviourMsgs is IICS07TendermintMsgs, ISP1Msgs { } /// @notice The public value output for the sp1 misbehaviour program. - /// @param isMisbehaviour The flag indicating if there is misbehaviour. + /// @param env The validation environment. + /// @param trustedHeight1 The trusted height of header 1 + /// @param trustedHeight2 The trusted height of header 2 /// @param trustedConsensusState1 The trusted consensus state of header 1 /// @param trustedConsensusState2 The trusted consensus state of header 2 struct MisbehaviourOutput { - bool isMisbehaviour; + Env env; + Height trustedHeight1; + Height trustedHeight2; ConsensusState trustedConsensusState1; ConsensusState trustedConsensusState2; } diff --git a/contracts/src/msgs/IUpdateClientMsgs.sol b/contracts/src/msgs/IUpdateClientMsgs.sol index 3738ba0..ba44b85 100644 --- a/contracts/src/msgs/IUpdateClientMsgs.sol +++ b/contracts/src/msgs/IUpdateClientMsgs.sol @@ -27,17 +27,4 @@ interface IUpdateClientMsgs is IICS07TendermintMsgs, ISP1Msgs { Height trustedHeight; Height newHeight; } - - /// @notice The environment output for the sp1 program. - /// @param chainId The chain ID of the chain that the client is tracking. - /// @param trustThreshold Fraction of validator overlap needed to update header - /// @param trustingPeriod Duration of the period since the `LatestTimestamp` during which the - /// submitted headers are valid for upgrade in seconds. - /// @param now Timestamp in seconds. - struct Env { - string chainId; - TrustThreshold trustThreshold; - uint32 trustingPeriod; - uint64 now; - } } diff --git a/contracts/test/MisbehaviourTest.t.sol b/contracts/test/MisbehaviourTest.t.sol index 7deca40..4a2afda 100644 --- a/contracts/test/MisbehaviourTest.t.sol +++ b/contracts/test/MisbehaviourTest.t.sol @@ -40,12 +40,13 @@ contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { return fix; } - function test_ValidMisbehaviour() public { + function test_ValidMisbehaviour() public view { IMisbehaviourMsgs.MsgSubmitMisbehaviour memory submitMsg = abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); IMisbehaviourMsgs.MisbehaviourOutput memory output = abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); - assertTrue(output.isMisbehaviour); + assertNotEq(output.trustedHeight1.revisionHeight, 0); + assertNotEq(output.trustedHeight2.revisionHeight, 0); // TODO: Write the actual test :P } diff --git a/contracts/test/SP1ICS07TendermintTest.sol b/contracts/test/SP1ICS07TendermintTest.sol index a01bdac..7c66dd9 100644 --- a/contracts/test/SP1ICS07TendermintTest.sol +++ b/contracts/test/SP1ICS07TendermintTest.sol @@ -20,6 +20,7 @@ struct SP1ICS07GenesisFixtureJson { bytes32 updateClientVkey; bytes32 membershipVkey; bytes32 ucAndMembershipVkey; + bytes32 misbehaviourVkey; } abstract contract SP1ICS07TendermintTest is @@ -51,6 +52,7 @@ abstract contract SP1ICS07TendermintTest is genesisFixture.updateClientVkey, genesisFixture.membershipVkey, genesisFixture.ucAndMembershipVkey, + genesisFixture.misbehaviourVkey, address(verifier), genesisFixture.trustedClientState, trustedConsensusHash @@ -61,6 +63,7 @@ abstract contract SP1ICS07TendermintTest is genesisFixture.updateClientVkey, genesisFixture.membershipVkey, genesisFixture.ucAndMembershipVkey, + genesisFixture.misbehaviourVkey, address(mockVerifier), genesisFixture.trustedClientState, trustedConsensusHash @@ -82,13 +85,15 @@ abstract contract SP1ICS07TendermintTest is bytes32 updateClientVkey = json.readBytes32(".updateClientVkey"); bytes32 membershipVkey = json.readBytes32(".membershipVkey"); bytes32 ucAndMembershipVkey = json.readBytes32(".ucAndMembershipVkey"); + bytes32 misbehaviourVkey = json.readBytes32(".misbehaviourVkey"); SP1ICS07GenesisFixtureJson memory fix = SP1ICS07GenesisFixtureJson({ trustedClientState: trustedClientState, trustedConsensusState: trustedConsensusState, updateClientVkey: updateClientVkey, membershipVkey: membershipVkey, - ucAndMembershipVkey: ucAndMembershipVkey + ucAndMembershipVkey: ucAndMembershipVkey, + misbehaviourVkey: misbehaviourVkey }); return fix; diff --git a/e2e/interchaintestv8/operator/operator.go b/e2e/interchaintestv8/operator/operator.go index 0df36f6..74b7c0f 100644 --- a/e2e/interchaintestv8/operator/operator.go +++ b/e2e/interchaintestv8/operator/operator.go @@ -28,6 +28,20 @@ type membershipFixture struct { MembershipProof string `json:"membershipProof"` } +type GenesisFixture struct { + TrustedClientState string `json:"trustedClientState"` + TrustedConsensusState string `json:"trustedConsensusState"` + UpdateClientVkey string `json:"updateClientVkey"` + MembershipVkey string `json:"membershipVkey"` + UcAndMembershipVkey string `json:"ucAndMembershipVkey"` + MisbehaviourVKey string `json:"misbehaviourVKey"` +} + +type MisbehaviourFixture struct { + GenesisFixture + SubmitMsg string `json:"submitMsg"` +} + // RunGenesis is a function that runs the genesis script to generate genesis.json func RunGenesis(args ...string) error { args = append([]string{"genesis"}, args...) @@ -106,7 +120,7 @@ func UpdateClientAndMembershipProof(trusted_height, target_height uint64, paths return height, proofBz, nil } -func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) error { +func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixture bool) error { misbehaviourFileName := "misbehaviour.json" args := []string{"fixtures", "misbehaviour", "--misbehaviour-path", misbehaviourFileName} @@ -239,12 +253,33 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) error { return err } - stdout, err := exec.Command("target/release/operator", args...).CombinedOutput() - fmt.Println(string(stdout)) - // TODO: Read in the fixture and return something that can be used against the contract + stdout, err := exec.Command("target/release/operator", args...).Output() if err != nil { return err } + // NOTE: writing stdout to os.Stdout after execution due to how `.Output()` works + os.Stdout.Write(stdout) + + // eliminate non-json characters + jsonStartIdx := strings.Index(string(stdout), "{") + if jsonStartIdx == -1 { + panic("no json found in output") + } + stdout = stdout[jsonStartIdx:] + + var misbehaviourFixture MisbehaviourFixture + err = json.Unmarshal(stdout, &misbehaviour) + if err != nil { + return err + } + fmt.Println(misbehaviourFixture) + + if writeFixture { + if err := os.WriteFile("contracts/fixtures/e2e_misbehaviour_fixture.json", stdout, 0o600); err != nil { + return err + } + } + return nil } diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index 9b0c4b4..a7c3f7b 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -49,6 +49,9 @@ import ( type SP1ICS07TendermintTestSuite struct { e2esuite.TestSuite + // Whether to generate fixtures for the solidity tests + generateFixtures bool + // The private key of a test account key *ecdsa.PrivateKey // The SP1ICS07Tendermint contract @@ -77,6 +80,9 @@ func (s *SP1ICS07TendermintTestSuite) SetupSuite(ctx context.Context) { os.Setenv(testvalues.EnvKeyTendermintRPC, simd.GetHostRPCAddress()) os.Setenv(testvalues.EnvKeySp1Prover, "network") os.Setenv(testvalues.EnvKeyPrivateKey, hexPrivateKey) + if os.Getenv(testvalues.EnvKeyGenerateFixtures) == testvalues.EnvValueGenerateFixtures_True { + s.generateFixtures = true + } // make sure that the SP1_PRIVATE_KEY is set. s.Require().NotEmpty(os.Getenv(testvalues.EnvKeySp1PrivateKey)) @@ -153,6 +159,10 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClient() { _, simd := s.ChainA, s.ChainB + if s.generateFixtures { + s.T().Log("Generate fixtures is set to true, but TestUpdateClient does not support it (yet)") + } + s.Require().True(s.Run("Update client", func() { clientState, err := s.contract.GetClientState(nil) s.Require().NoError(err) @@ -185,6 +195,10 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership() { eth, simd := s.ChainA, s.ChainB + if s.generateFixtures { + s.T().Log("Generate fixtures is set to true, but TestUpdateClient does not support it (yet)") + } + s.Require().True(s.Run("Update and verify non-membership", func() { s.Require().NoError(testutil.WaitForBlocks(ctx, 5, simd)) @@ -270,7 +284,7 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { } // TODO: Get fixture from operator and use it with the contract - err = operator.Misbehaviour(simd.GetCodec(), misbehaviour) + err = operator.Misbehaviour(simd.GetCodec(), misbehaviour, s.generateFixtures) s.Require().NoError(err) })) } diff --git a/e2e/interchaintestv8/testvalues/values.go b/e2e/interchaintestv8/testvalues/values.go index baad74c..8d72475 100644 --- a/e2e/interchaintestv8/testvalues/values.go +++ b/e2e/interchaintestv8/testvalues/values.go @@ -26,11 +26,15 @@ const ( EnvKeySp1Prover = "SP1_PROVER" // Private key for the prover network. EnvKeySp1PrivateKey = "SP1_PRIVATE_KEY" + // EnvKeyGenerateFixtures Generate fixtures for the solidity tests if set to true. + EnvKeyGenerateFixtures = "GENERATE_FIXTURES" // The log level for the Rust logger. EnvKeyRustLog = "RUST_LOG" // Log level for the Rust logger. EnvValueRustLog_Info = "info" + // EnvValueGenerateFixtures_True is the value to set to generate fixtures for the solidity tests. + EnvValueGenerateFixtures_True = "true" ) var ( diff --git a/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go b/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go index 63cf164..9f6ae13 100644 --- a/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go +++ b/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go @@ -52,6 +52,14 @@ type IICS07TendermintMsgsConsensusState struct { NextValidatorsHash [32]byte } +// IICS07TendermintMsgsEnv is an auto generated low-level Go binding around an user-defined struct. +type IICS07TendermintMsgsEnv struct { + ChainId string + TrustThreshold IICS07TendermintMsgsTrustThreshold + TrustingPeriod uint32 + Now uint64 +} + // IICS07TendermintMsgsTrustThreshold is an auto generated low-level Go binding around an user-defined struct. type IICS07TendermintMsgsTrustThreshold struct { Numerator uint8 @@ -97,7 +105,9 @@ type IMembershipMsgsSP1MembershipProof struct { // IMisbehaviourMsgsMisbehaviourOutput is an auto generated low-level Go binding around an user-defined struct. type IMisbehaviourMsgsMisbehaviourOutput struct { - IsMisbehaviour bool + Env IICS07TendermintMsgsEnv + TrustedHeight1 IICS02ClientMsgsHeight + TrustedHeight2 IICS02ClientMsgsHeight TrustedConsensusState1 IICS07TendermintMsgsConsensusState TrustedConsensusState2 IICS07TendermintMsgsConsensusState } @@ -120,14 +130,6 @@ type IUpdateClientAndMembershipMsgsUcAndMembershipOutput struct { KvPairs []IMembershipMsgsKVPair } -// IUpdateClientMsgsEnv is an auto generated low-level Go binding around an user-defined struct. -type IUpdateClientMsgsEnv struct { - ChainId string - TrustThreshold IICS07TendermintMsgsTrustThreshold - TrustingPeriod uint32 - Now uint64 -} - // IUpdateClientMsgsMsgUpdateClient is an auto generated low-level Go binding around an user-defined struct. type IUpdateClientMsgsMsgUpdateClient struct { Sp1Proof ISP1MsgsSP1Proof @@ -137,14 +139,14 @@ type IUpdateClientMsgsMsgUpdateClient struct { type IUpdateClientMsgsUpdateClientOutput struct { TrustedConsensusState IICS07TendermintMsgsConsensusState NewConsensusState IICS07TendermintMsgsConsensusState - Env IUpdateClientMsgsEnv + Env IICS07TendermintMsgsEnv TrustedHeight IICS02ClientMsgsHeight NewHeight IICS02ClientMsgsHeight } // ContractMetaData contains all meta data concerning the Contract contract. var ContractMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"updateClientProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"membershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"updateClientAndMembershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifier\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_clientState\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_consensusState\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MEMBERSHIP_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPDATE_CLIENT_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VERIFIER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISP1Verifier\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"abiPublicTypes\",\"inputs\":[{\"name\":\"o1\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.MembershipOutput\",\"components\":[{\"name\":\"commitmentRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structIMembershipMsgs.KVPair[]\",\"components\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o2\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientAndMembershipMsgs.UcAndMembershipOutput\",\"components\":[{\"name\":\"updateClientOutput\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.UpdateClientOutput\",\"components\":[{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"newConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.Env\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustThreshold\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trustedHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"newHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structIMembershipMsgs.KVPair[]\",\"components\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o3\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.MsgUpdateClient\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o4\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.MembershipProof\",\"components\":[{\"name\":\"proofType\",\"type\":\"uint8\",\"internalType\":\"enumIMembershipMsgs.MembershipProofType\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"o5\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.SP1MembershipProof\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]},{\"name\":\"o6\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.SP1MembershipAndUpdateClientProof\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o7\",\"type\":\"tuple\",\"internalType\":\"structIMisbehaviourMsgs.MisbehaviourOutput\",\"components\":[{\"name\":\"isMisbehaviour\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"trustedConsensusState1\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"trustedConsensusState2\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]},{\"name\":\"o8\",\"type\":\"tuple\",\"internalType\":\"structIMisbehaviourMsgs.MsgSubmitMisbehaviour\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getClientState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ClientState\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustLevel\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"latestHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"isFrozen\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConsensusStateHash\",\"inputs\":[{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"membership\",\"inputs\":[{\"name\":\"msgMembership\",\"type\":\"tuple\",\"internalType\":\"structILightClientMsgs.MsgMembership\",\"components\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proofHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"timestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"misbehaviour\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"updateClient\",\"inputs\":[{\"name\":\"updateMsg\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumILightClientMsgs.UpdateResult\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeClient\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"error\",\"name\":\"CannotHandleMisbehavior\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChainIdMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"actual\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"ConsensusStateHashMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ConsensusStateNotFound\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ConsensusStateRootMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"FeatureNotSupported\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FrozenClientState\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"LengthIsOutOfRange\",\"inputs\":[{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"min\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"max\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"MembershipProofKeyNotFound\",\"inputs\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}]},{\"type\":\"error\",\"name\":\"MembershipProofValueMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"actual\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"type\":\"error\",\"name\":\"ProofHeightMismatch\",\"inputs\":[{\"name\":\"expectedRevisionNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"expectedRevisionHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"actualRevisionNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"actualRevisionHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"type\":\"error\",\"name\":\"ProofIsInTheFuture\",\"inputs\":[{\"name\":\"now\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proofTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ProofIsTooOld\",\"inputs\":[{\"name\":\"now\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proofTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustThresholdMismatch\",\"inputs\":[{\"name\":\"expectedNumerator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expectedDenominator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualNumerator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualDenominator\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustingPeriodMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actual\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustingPeriodTooLong\",\"inputs\":[{\"name\":\"trustingPeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"UnknownMembershipProofType\",\"inputs\":[{\"name\":\"proofType\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"type\":\"error\",\"name\":\"VerificationKeyMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"updateClientProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"membershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"updateClientAndMembershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"misbehaviourProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifier\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_clientState\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_consensusState\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MEMBERSHIP_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MISBEHAVIOUR_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPDATE_CLIENT_PROGRAM_VKEY\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VERIFIER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISP1Verifier\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"abiPublicTypes\",\"inputs\":[{\"name\":\"o1\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.MembershipOutput\",\"components\":[{\"name\":\"commitmentRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structIMembershipMsgs.KVPair[]\",\"components\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o2\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientAndMembershipMsgs.UcAndMembershipOutput\",\"components\":[{\"name\":\"updateClientOutput\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.UpdateClientOutput\",\"components\":[{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"newConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.Env\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustThreshold\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trustedHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"newHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]},{\"name\":\"kvPairs\",\"type\":\"tuple[]\",\"internalType\":\"structIMembershipMsgs.KVPair[]\",\"components\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o3\",\"type\":\"tuple\",\"internalType\":\"structIUpdateClientMsgs.MsgUpdateClient\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o4\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.MembershipProof\",\"components\":[{\"name\":\"proofType\",\"type\":\"uint8\",\"internalType\":\"enumIMembershipMsgs.MembershipProofType\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"o5\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.SP1MembershipProof\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"trustedConsensusState\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]},{\"name\":\"o6\",\"type\":\"tuple\",\"internalType\":\"structIMembershipMsgs.SP1MembershipAndUpdateClientProof\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"o7\",\"type\":\"tuple\",\"internalType\":\"structIMisbehaviourMsgs.MisbehaviourOutput\",\"components\":[{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.Env\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustThreshold\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trustedHeight1\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trustedHeight2\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trustedConsensusState1\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"trustedConsensusState2\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nextValidatorsHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]},{\"name\":\"o8\",\"type\":\"tuple\",\"internalType\":\"structIMisbehaviourMsgs.MsgSubmitMisbehaviour\",\"components\":[{\"name\":\"sp1Proof\",\"type\":\"tuple\",\"internalType\":\"structISP1Msgs.SP1Proof\",\"components\":[{\"name\":\"vKey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getClientState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.ClientState\",\"components\":[{\"name\":\"chainId\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trustLevel\",\"type\":\"tuple\",\"internalType\":\"structIICS07TendermintMsgs.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"latestHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trustingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"isFrozen\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConsensusStateHash\",\"inputs\":[{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"membership\",\"inputs\":[{\"name\":\"msgMembership\",\"type\":\"tuple\",\"internalType\":\"structILightClientMsgs.MsgMembership\",\"components\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proofHeight\",\"type\":\"tuple\",\"internalType\":\"structIICS02ClientMsgs.Height\",\"components\":[{\"name\":\"revisionNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"timestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"misbehaviour\",\"inputs\":[{\"name\":\"misbehaviourMsg\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateClient\",\"inputs\":[{\"name\":\"updateMsg\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumILightClientMsgs.UpdateResult\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeClient\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"error\",\"name\":\"CannotHandleMisbehavior\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChainIdMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"actual\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"ConsensusStateHashMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"ConsensusStateNotFound\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ConsensusStateRootMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"type\":\"error\",\"name\":\"FeatureNotSupported\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FrozenClientState\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"LengthIsOutOfRange\",\"inputs\":[{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"min\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"max\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"MembershipProofKeyNotFound\",\"inputs\":[{\"name\":\"path\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}]},{\"type\":\"error\",\"name\":\"MembershipProofValueMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"actual\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"type\":\"error\",\"name\":\"ProofHeightMismatch\",\"inputs\":[{\"name\":\"expectedRevisionNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"expectedRevisionHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"actualRevisionNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"actualRevisionHeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"type\":\"error\",\"name\":\"ProofIsInTheFuture\",\"inputs\":[{\"name\":\"now\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proofTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ProofIsTooOld\",\"inputs\":[{\"name\":\"now\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proofTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustThresholdMismatch\",\"inputs\":[{\"name\":\"expectedNumerator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"expectedDenominator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualNumerator\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualDenominator\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustingPeriodMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actual\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"TrustingPeriodTooLong\",\"inputs\":[{\"name\":\"trustingPeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"unbondingPeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"UnknownMembershipProofType\",\"inputs\":[{\"name\":\"proofType\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"type\":\"error\",\"name\":\"VerificationKeyMismatch\",\"inputs\":[{\"name\":\"expected\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"actual\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]", } // ContractABI is the input ABI used to generate the binding from. @@ -355,6 +357,37 @@ func (_Contract *ContractCallerSession) MEMBERSHIPPROGRAMVKEY() ([32]byte, error return _Contract.Contract.MEMBERSHIPPROGRAMVKEY(&_Contract.CallOpts) } +// MISBEHAVIOURPROGRAMVKEY is a free data retrieval call binding the contract method 0x314d4dff. +// +// Solidity: function MISBEHAVIOUR_PROGRAM_VKEY() view returns(bytes32) +func (_Contract *ContractCaller) MISBEHAVIOURPROGRAMVKEY(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "MISBEHAVIOUR_PROGRAM_VKEY") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// MISBEHAVIOURPROGRAMVKEY is a free data retrieval call binding the contract method 0x314d4dff. +// +// Solidity: function MISBEHAVIOUR_PROGRAM_VKEY() view returns(bytes32) +func (_Contract *ContractSession) MISBEHAVIOURPROGRAMVKEY() ([32]byte, error) { + return _Contract.Contract.MISBEHAVIOURPROGRAMVKEY(&_Contract.CallOpts) +} + +// MISBEHAVIOURPROGRAMVKEY is a free data retrieval call binding the contract method 0x314d4dff. +// +// Solidity: function MISBEHAVIOUR_PROGRAM_VKEY() view returns(bytes32) +func (_Contract *ContractCallerSession) MISBEHAVIOURPROGRAMVKEY() ([32]byte, error) { + return _Contract.Contract.MISBEHAVIOURPROGRAMVKEY(&_Contract.CallOpts) +} + // UPDATECLIENTANDMEMBERSHIPPROGRAMVKEY is a free data retrieval call binding the contract method 0x0225293e. // // Solidity: function UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY() view returns(bytes32) @@ -448,9 +481,9 @@ func (_Contract *ContractCallerSession) VERIFIER() (common.Address, error) { return _Contract.Contract.VERIFIER(&_Contract.CallOpts) } -// AbiPublicTypes is a free data retrieval call binding the contract method 0xd743b10e. +// AbiPublicTypes is a free data retrieval call binding the contract method 0x4ad51d79. // -// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool,(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() +// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, ((string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32),(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput, o8 IMisbehaviourMsgsMsgSubmitMisbehaviour) error { var out []interface{} err := _Contract.contract.Call(opts, &out, "abiPublicTypes", o1, o2, o3, o4, o5, o6, o7, o8) @@ -463,16 +496,16 @@ func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, o1 IMembers } -// AbiPublicTypes is a free data retrieval call binding the contract method 0xd743b10e. +// AbiPublicTypes is a free data retrieval call binding the contract method 0x4ad51d79. // -// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool,(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() +// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, ((string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32),(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() func (_Contract *ContractSession) AbiPublicTypes(o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput, o8 IMisbehaviourMsgsMsgSubmitMisbehaviour) error { return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, o1, o2, o3, o4, o5, o6, o7, o8) } -// AbiPublicTypes is a free data retrieval call binding the contract method 0xd743b10e. +// AbiPublicTypes is a free data retrieval call binding the contract method 0x4ad51d79. // -// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, (bool,(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() +// Solidity: function abiPublicTypes((bytes32,(bytes[],bytes)[]) o1, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(bytes[],bytes)[]) o2, ((bytes32,bytes,bytes)) o3, (uint8,bytes) o4, ((bytes32,bytes,bytes),(uint64,bytes32,bytes32)) o5, ((bytes32,bytes,bytes)) o6, ((string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32),(uint64,bytes32,bytes32),(uint64,bytes32,bytes32)) o7, ((bytes32,bytes,bytes)) o8) pure returns() func (_Contract *ContractCallerSession) AbiPublicTypes(o1 IMembershipMsgsMembershipOutput, o2 IUpdateClientAndMembershipMsgsUcAndMembershipOutput, o3 IUpdateClientMsgsMsgUpdateClient, o4 IMembershipMsgsMembershipProof, o5 IMembershipMsgsSP1MembershipProof, o6 IMembershipMsgsSP1MembershipAndUpdateClientProof, o7 IMisbehaviourMsgsMisbehaviourOutput, o8 IMisbehaviourMsgsMsgSubmitMisbehaviour) error { return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, o1, o2, o3, o4, o5, o6, o7, o8) } @@ -539,35 +572,6 @@ func (_Contract *ContractCallerSession) GetConsensusStateHash(revisionHeight uin return _Contract.Contract.GetConsensusStateHash(&_Contract.CallOpts, revisionHeight) } -// Misbehaviour is a free data retrieval call binding the contract method 0xddba6537. -// -// Solidity: function misbehaviour(bytes ) pure returns() -func (_Contract *ContractCaller) Misbehaviour(opts *bind.CallOpts, arg0 []byte) error { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "misbehaviour", arg0) - - if err != nil { - return err - } - - return err - -} - -// Misbehaviour is a free data retrieval call binding the contract method 0xddba6537. -// -// Solidity: function misbehaviour(bytes ) pure returns() -func (_Contract *ContractSession) Misbehaviour(arg0 []byte) error { - return _Contract.Contract.Misbehaviour(&_Contract.CallOpts, arg0) -} - -// Misbehaviour is a free data retrieval call binding the contract method 0xddba6537. -// -// Solidity: function misbehaviour(bytes ) pure returns() -func (_Contract *ContractCallerSession) Misbehaviour(arg0 []byte) error { - return _Contract.Contract.Misbehaviour(&_Contract.CallOpts, arg0) -} - // UpgradeClient is a free data retrieval call binding the contract method 0x8a8e4c5d. // // Solidity: function upgradeClient(bytes ) pure returns() @@ -618,6 +622,27 @@ func (_Contract *ContractTransactorSession) Membership(msgMembership ILightClien return _Contract.Contract.Membership(&_Contract.TransactOpts, msgMembership) } +// Misbehaviour is a paid mutator transaction binding the contract method 0xddba6537. +// +// Solidity: function misbehaviour(bytes misbehaviourMsg) returns() +func (_Contract *ContractTransactor) Misbehaviour(opts *bind.TransactOpts, misbehaviourMsg []byte) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "misbehaviour", misbehaviourMsg) +} + +// Misbehaviour is a paid mutator transaction binding the contract method 0xddba6537. +// +// Solidity: function misbehaviour(bytes misbehaviourMsg) returns() +func (_Contract *ContractSession) Misbehaviour(misbehaviourMsg []byte) (*types.Transaction, error) { + return _Contract.Contract.Misbehaviour(&_Contract.TransactOpts, misbehaviourMsg) +} + +// Misbehaviour is a paid mutator transaction binding the contract method 0xddba6537. +// +// Solidity: function misbehaviour(bytes misbehaviourMsg) returns() +func (_Contract *ContractTransactorSession) Misbehaviour(misbehaviourMsg []byte) (*types.Transaction, error) { + return _Contract.Contract.Misbehaviour(&_Contract.TransactOpts, misbehaviourMsg) +} + // UpdateClient is a paid mutator transaction binding the contract method 0x0bece356. // // Solidity: function updateClient(bytes updateMsg) returns(uint8) diff --git a/operator/src/runners/genesis.rs b/operator/src/runners/genesis.rs index d8fc6b5..1fa1354 100644 --- a/operator/src/runners/genesis.rs +++ b/operator/src/runners/genesis.rs @@ -15,6 +15,7 @@ use sp1_sdk::{utils::setup_logger, HashableKey}; use std::path::PathBuf; use tendermint_light_client_verifier::types::{LightBlock, TrustThreshold}; use tendermint_rpc::HttpClient; +use crate::programs::MisbehaviourProgram; /// The genesis data for the SP1 ICS07 Tendermint contract. #[serde_as] @@ -34,6 +35,8 @@ pub struct SP1ICS07TendermintGenesis { membership_vkey: String, /// The encoded key for [`UpdateClientAndMembershipProgram`]. uc_and_membership_vkey: String, + /// The encoded key for [`MisbehaviourProgram`]. + misbehaviour_vkey: String, } impl SP1ICS07TendermintGenesis { @@ -81,6 +84,7 @@ impl SP1ICS07TendermintGenesis { update_client_vkey: UpdateClientProgram::get_vkey().bytes32(), membership_vkey: MembershipProgram::get_vkey().bytes32(), uc_and_membership_vkey: UpdateClientAndMembershipProgram::get_vkey().bytes32(), + misbehaviour_vkey: MisbehaviourProgram::get_vkey().bytes32(), }) } } diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index 34d0472..d28f153 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -14,6 +14,7 @@ use std::collections::HashMap; use std::time::Duration; use tendermint_light_client_verifier::options::Options; use tendermint_light_client_verifier::ProdVerifier; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint; /// The main function of the program without the zkVM wrapper. #[allow(clippy::missing_panics_doc)] @@ -67,9 +68,24 @@ pub fn check_for_misbehaviour( let is_misbehaviour = check_for_misbehaviour_on_misbehavior(misbehaviour.header1(), misbehaviour.header2()) .unwrap(); + + if !is_misbehaviour { + panic!("Misbehaviour is not detected"); + } + + let output_trusted_header_1 = sp1_ics07_tendermint::Height { + revisionNumber: misbehaviour.header1().trusted_height.revision_height().try_into().unwrap(), + revisionHeight: misbehaviour.header1().trusted_height.revision_height().try_into().unwrap(), + }; + let output_trusted_header_2 = sp1_ics07_tendermint::Height { + revisionNumber: misbehaviour.header2().trusted_height.revision_height().try_into().unwrap(), + revisionHeight: misbehaviour.header2().trusted_height.revision_height().try_into().unwrap(), + }; MisbehaviourOutput { - isMisbehaviour: is_misbehaviour, + env, + trustedHeight1: output_trusted_header_1, + trustedHeight2: output_trusted_header_2, trustedConsensusState1: trusted_consensus_state_1.into(), trustedConsensusState2: trusted_consensus_state_2.into(), } From dcb3e73f49daee6319e92e8f09fa657edcfd7b59 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 28 Aug 2024 13:41:38 +0200 Subject: [PATCH 05/22] misbehaviour tests (unit and e2e) --- .env.example | 2 +- .github/workflows/e2e.yml | 10 +- README.md | 6 + .../fixtures/e2e_misbehaviour_fixture.json | 8 +- contracts/fixtures/memberships_fixture.json | 15 +- .../fixtures/uc_and_memberships_fixture.json | 15 +- contracts/fixtures/update_client_fixture.json | 17 +- contracts/script/genesis.json | 4 +- contracts/src/SP1ICS07Tendermint.sol | 47 ++--- contracts/test/Misbehaviour.t.sol | 169 ++++++++++++++++++ contracts/test/MisbehaviourTest.t.sol | 53 ------ contracts/test/SP1ICS07TendermintTest.sol | 4 + e2e/interchaintestv8/.golangci.yml | 7 +- .../chainconfig/chain_config.go | 4 +- e2e/interchaintestv8/e2esuite/suite.go | 7 +- e2e/interchaintestv8/e2esuite/utils.go | 3 + e2e/interchaintestv8/go.mod | 57 +++--- e2e/interchaintestv8/go.sum | 60 +++++++ e2e/interchaintestv8/operator/operator.go | 76 ++++---- e2e/interchaintestv8/sp1_ics07_test.go | 83 ++++++--- e2e/interchaintestv8/testvalues/values.go | 4 +- justfile | 30 ++-- operator/src/runners/genesis.rs | 4 +- programs/misbehaviour/src/lib.rs | 34 +++- 24 files changed, 485 insertions(+), 234 deletions(-) create mode 100644 contracts/test/Misbehaviour.t.sol delete mode 100644 contracts/test/MisbehaviourTest.t.sol diff --git a/.env.example b/.env.example index b1e2e27..1d7518f 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ # URL of the Tendermint RPC node -TENDERMINT_RPC_URL=https://rpc.celestia-mocha.com/ +TENDERMINT_RPC_URL=http://public-celestia-mocha4-consensus.numia.xyz/ # URL of the Ethereum RPC node # use https://ethereum-sepolia.publicnode.com/ for the Eth Sepolia testnet RPC_URL=https://ethereum-holesky-rpc.publicnode.com diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c9787ad..3078f48 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -22,14 +22,14 @@ jobs: name: lint runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: "1.22" - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v3.7.0 + uses: golangci/golangci-lint-action@v6.1.0 with: - version: v1.59 + version: v1.60 args: --timeout 5m working-directory: e2e/interchaintestv8 e2e: @@ -47,7 +47,7 @@ jobs: - name: Checkout sources uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: "1.22" check-latest: true diff --git a/README.md b/README.md index 130fa59..96852dc 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,12 @@ After generating the verify the proof with the SP1 EVM verifier. just test-foundry ``` +The recipe also accepts a `testname` argument that will only run the test with the given name. For example: + +```shell +just test-foundry test_success_sendTransfer +``` + ## End to End Testing There are several end-to-end tests in the `e2e/interchaintestv8` directory. These tests are written in Go and use the [`interchaintest`](https://github.com/strangelove-ventures/interchaintest) library. It spins up a local Ethereum and a Tendermint network and runs the tests found in [`e2e/interchaintestv8/sp1_ics07_test.go`](e2e/interchaintestv8/sp1_ics07_test.go). Some of the tests use the prover network to generate the proofs, so you need to provide your SP1 network private key to `.env` for these tests to pass. diff --git a/contracts/fixtures/e2e_misbehaviour_fixture.json b/contracts/fixtures/e2e_misbehaviour_fixture.json index 2f64fe6..15fd929 100644 --- a/contracts/fixtures/e2e_misbehaviour_fixture.json +++ b/contracts/fixtures/e2e_misbehaviour_fixture.json @@ -1,9 +1,9 @@ { - "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cc5a4a76ffd7c0f7b019c80dc3b2d9e05e1bc803074277ad8fd836edf4208cb0093c491d7bacd36d73696f4ab07a9813837ffedd342ec024c91b929ee0652e9931c517", + "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf09678cae2908ce2eb6a969c64272dc4cea298152ea9b491e22f86705272fe3850847ae649bfac04d409aff0ff1dd38c4a9d69817ad288472dc21a1a6fc518bf0dd5a", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", - "misbehaviourVkey": "0x0064ffd659dfc4aef854ad17da8ab2be54ac95b2826d0acb94d4740380eebdcc", - "submitMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200064ffd659dfc4aef854ad17da8ab2be54ac95b2826d0acb94d4740380eebdcc000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066cc5a4a76ffd7c0f7b019c80dc3b2d9e05e1bc803074277ad8fd836edf4208cb0093c491d7bacd36d73696f4ab07a9813837ffedd342ec024c91b929ee0652e9931c5170000000000000000000000000000000000000000000000000000000066cc5a4a76ffd7c0f7b019c80dc3b2d9e05e1bc803074277ad8fd836edf4208cb0093c491d7bacd36d73696f4ab07a9813837ffedd342ec024c91b929ee0652e9931c51700000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066cc5a87000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f02a9fef18efbee1f8151fbe720e342674eae980314fe79e82ab9825047ac666f2f25ecb426599aa1480a74677d497f352d0e243559b19f24dc88d6f4a6402cf121422d16c85f76091f4894603fb1ae416f820cfef830d5c6cf662b4d8da9101a0f1033ff4d972b479f6cda388872260c3792c4aa3ba587d54bf903a0e0aa76ad236136c44d680ab675b6166b18eab7100141dec0b4abb8619c675985b271edf6275f07d04fe73633b42bb3192207c929b68e895d5e7ea3da7b313e27ab6f4ee312b1a2f39690c49b7a8c41e584757df59b804dfaa177bb66ef7eeb54410ede102baa5d752ef5bc4f580d70f24d4ea24121def5eec0b4904ddb4b083088b506bb022d35801c6cd2e1a9ff287af427cad7374b88d51d417486c84d8c7411c6ad7c251728a8a64514a96a08f03ac4c6409c4b3ff3912d3c0bddd621190f7210ad46210f34c427992b824c3966c8a877e84121a2b96bf04d7bbce5da9be6a2fc36d404c2fa239deb6227dfb2b926dff7e8abc9486555b7771b8d510bfce0758af1d80a89ea071e0c8b3f3fa0537ed87bc25818e864fa0431ea160a1d0ba4d791ffa42231608f9e93149396b3c10528d7ec6f478120cf33961a6022d4cb083ef090ef0192de5e3899168ad60e4ea355129f21bdcc150a1da3b1da12033630485176070ae34c0ad57dda550d07651356fa34ddd2f16669a0ce14f0d8b056615acfb02c215aefe753c01a48f993ac9233e41376cc2dfd51b39c120f97b76ccb6abc2a1f0efe8f0c5cbbce4cbe10d10c4366d3db926d273350dd38f8d9e68c38f580d02e1d2881b27fbdbaad0d0a8c7b21c530632391e4a6dc60795fdcf4996121f8546c2a932ef2a9e48709aa7d67bd527c37d1c2071b81f22664f16b859d9ff6101fe102157f751528e1e3198a02fdb144da871bab35ed982adb0a1042cfae66a4faac0a46e285f371a542f4ddf68fa5e319b6f8b83f90773099f66dd8b0d5992b054117ee5d1b97c67b4309d36d7e1c5e796f5c98850f0754b9e84910d91c327c540d1f8b10b48d7e411862d7424c5ca526754465ac879083aece917cae64dbd9f85105280b81ccf5c8cec4f550ad568adcc39c7274c6d3c065678731385e62a335a72971d07c1947d6e6a55a6e80e936555ece6d4cc85ae2dfe53b566c40203d63c817f42a6c75c5c1ac7288b0f738908373bc8dd0b543a7422e68eb3aa20dc10e9d00000000000000000000000000000000000000000000000000000000" + "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", + "submitMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066cf09678cae2908ce2eb6a969c64272dc4cea298152ea9b491e22f86705272fe3850847ae649bfac04d409aff0ff1dd38c4a9d69817ad288472dc21a1a6fc518bf0dd5a0000000000000000000000000000000000000000000000000000000066cf09678cae2908ce2eb6a969c64272dc4cea298152ea9b491e22f86705272fe3850847ae649bfac04d409aff0ff1dd38c4a9d69817ad288472dc21a1a6fc518bf0dd5a00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275450000000000000000000000000000000000000000000000000000000066cf099e000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f2c475d6489bf52367abded5d9a63c1a7075f0e66cc15c803c6eb3759fdb84b97118825092de09b63f1877b0870201421acb8956d26ebad000d8fd96da15e5de520eaa4e3d3b35d56ae7b041c89fa2e4c743353e39f01b58a832acfe6bfc4efa406e82a0d7a712e50d5ebab7469b2aba030b2c7de5695417ee82f5edc858f35a11f29e6dcc9221e7a58fa309824faf18048ded2359602c4cb3350e5c81a8874171b4987b1b0161459631f893586c5c7ae5547dea84afc2064f506f6f397c4303b0079cb924277caba8533291edf5d8b27e83f6c6eeada73d16eeb387c14ef3dd01e179936800605ec63d19c9232c984988bcc0d50a6bb1c1698f2bddc5110e76305da22b6092fc44b6322ca976bfbef390027a840cc1846fa024eba75245e310601b847d2f4b4512d6b1c7c3498bb001695914decd521a3c42da901f36a31947f0875d57f7907daa8ac23aff39bc29c0a1fe926b348d22a775ba8935e115dd3712094d970d187141bca9e7e9130b09996699d54bc5ee5720f6cce777abddb5e9c1b3b67772f85d6ffd1ae7e1ecfba86e23c395733c140cb379f0efc79228f98e724cd2be63588e0f19d41ced2b09246f3d2df2c7570044a65ca21f6c8a883e3721ae42e23e7f573cb8c10c6d678fa71c75c2772563b4ec85890254b54997084092d53e0e8d91b652b084fbbc3970b69e7f990a0eac67ed1ab8806c28eb131856c2303b89495575664ed58dada3054425ee94218bc1c11ae89ca732c8a8beb36e82a5a6250c20baa64244129e234b3326e33d6ed1ee1310b3da1ae98134512a9e22a406b494a5a80cc156477fab07c2751f327e6eff977b3555a705c0de1278b011d81f76cc17ed256455139dd561bc7301882f215a39c5998f8d6f33d11c8e6c208bde0a3871f4aa6ac38035393090c979797a4d72958cc09767357b2a5a6653c0d74d9203227e0e9115547fe4f1d797df809d93d1917121acccbc9b3d851ee410d239333c1d1cf3ccf1ca8f2b2cfa32707f1eb414f709930dfe2b06a491f17d10946ff835b571d465d20f80402820f2d0c0b41f0f78ddb4ba4f3edf3d534ee0815b4c2f83a54b9df01f1273830e95f3c641502c81f80d06eb0738c1bf7b0ae441e0c47b262e203e07c35ba0e09547629b89a597dbbfe19d7c51c44b4488325441612380aa6955cd91ed698d7f351dadebc7ed2392904bf4aff482bda69978ee800000000000000000000000000000000000000000000000000000000" } diff --git a/contracts/fixtures/memberships_fixture.json b/contracts/fixtures/memberships_fixture.json index f14209b..0ea170f 100644 --- a/contracts/fixtures/memberships_fixture.json +++ b/contracts/fixtures/memberships_fixture.json @@ -1,9 +1,10 @@ { - "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000253370000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066b4386ddd61735333d38ba62f9c8edb7d41b399ce6a0a0ed10d1aeaec708afec8d40472a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb", - "updateClientVkey": "0x0029ce4b0512b5c4254fb11a189799cddb28254f7177d549cf2dc860bc31519e", - "membershipVkey": "0x005f30ecbba088f6f6eede4ca8d4ff6ffc2b7e5f59de38edd1574aefb937afdb", - "ucAndMembershipVkey": "0x00cf1fa1df1f491548e84e88a6b617a70b7abd0c017bc7115ed08f329e05026a", - "proofHeight": "00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000253370", - "membershipProof": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000066b4386ddd61735333d38ba62f9c8edb7d41b399ce6a0a0ed10d1aeaec708afec8d40472a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb005f30ecbba088f6f6eede4ca8d4ff6ffc2b7e5f59de38edd1574aefb937afdb000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000020dd61735333d38ba62f9c8edb7d41b399ce6a0a0ed10d1aeaec708afec8d40472000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a10757067726164656449424353746174655001580100000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e74537461746500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f22ef7a7f130f690abd7fd33eed4da6fdfa7c6a4b8899c728a92a835269e05f802e5ca7f9ae355d672f60de8d45b106b4f60dafa46269146bd7179801700e0e8e0d85da862ba83f7e70febb376a092cf2f0a92911ac55c4c9ea01bfd293ca455506ad0535abd962a10ebf6114068bf037469a5b1b1d243296e84b47d31c05311614cf8be0507f992322e5f4a51a88624bd612ea3aa446bb38f34fed2e777b4b1401852f214ba716ed1b5241f2e21e2540105b25dad1e0e5c951e6c4201df162d800cad20e1460dc785d47b1143c281831a977f28be50fa83ea8463968d4e5d61f0d1995988279ba999d275a8101b3172be15588c4b779b5f9d177b49d640d52991821d38d3882ca14d10d64e7aff76d796c586ba257249169d069b236e02809ba01517acc1e0409ddd08c344f4fb4faeb1e20d5b00c0000389a3b96a94401980f211d9e1f438cd2cb922c503bccc61cff175ba0cd0a96ff6963d3a833530834b7062e538bf6c914e907f6b2b1e7181d1bdc1b45eb7defae4ea732cb11802584e826c23895796d70adaaf3d75d93bff55efb2559978ec25df6316e0bad0ce074f52332bf1420e201e1efc9d467428ff402de800943be7648d915b2e5f5386790820a15bb2065022fc1087703967b292efb12444d2a504145c6caab7209196f18c22a98a2ca941973cb2b128fe25a3ada9e073dc99fa681445482e91ee0809bbe5d200ff347e1d290ed1214f83d06c2ccc5209b3edf382487c051e4bbdfbe01e64c182af205ad392ea60b6e8d1d615085d2e0e10caa574e4336110eaef08e3e97da2fd6c192efb126c9a1213da6264781332ba9550986d6fd31e0ca7904ae2fc5072e7643157ae8201b5eca53db900e8400f67c60cf3fe0f91c86c9202e46d815011b5a74477473924a722805c6ca8b27edadd0b105c6efa1b00074f6f6906e8b861281bdce6e75e1547811721ab291058d6beecfc277e72ac8a0d454d6f29dbbbb06a114650a25e053afa051faed46790974486313712b568ab8bbcf4fff54cf8a0f05d01d8c93cc76d67ded54fac134e5aef437d66ce2d66cf880c2be56ca10451922802b647b63e61e1bf54bb755f15ee2230f43ca6299c7af01927f5d2c69891d0e0659dc75e8ee4b507be85114e620d53091cdcb39591cd42c5f3c6d16b87e1c82db4c7af87950952c3e4ad9acfa0984ce6f41b35e40e5449807437cc207ae00000000000000000000000000000000000000000000000000000000" + "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a57000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1", + "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", + "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", + "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", + "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", + "proofHeight": "00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a57", + "membershipProof": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a100eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000020fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbba000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a10757067726164656449424353746174655001580100000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e74537461746500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f005fc16693f877979a166688d9245fdc80585f6f4186b3f7914fc9cb743ac91f255d96c893ab97cd082ac07908d31de8c175918ddf709c60da391746ca36316414f3867d694fb41c7fbf0993266a41b4f2089cd0e051f3f0d819aa9c5755a8cf06791d296423bcad853a4187eb9ecb7cc893a92b1bb7b6ce06a18db18ecd81cb17b1d4cf2b0af48ebc45140a443bcc0de0bea0b411240e81e036bb5e1d78ba360ca6c9203c5dcb7183acc7cbfb52d94cdeb3d2659ee05510c7f394284ccbea37090916d56be6897dee8903a0ffcd7eb85ac30aff0adf75c0200c8bca41efc6f528774e90eb301e986291e88ca6265dd77e00c80844caac8eedd9011127c0fef10385acdbc43155c8bef20ac6a2e99c8f14cc67a25a180c75090dc9f93612cbf40abb54ad70e59c0b2215d99daa6f52f01d525c2138b1ff1abebf6888e1c7b26918579afeee750306b89898d515ae29802c321f6d8bc8b04df624363c2e10238b100a0489dbd9052521c97b31a270da2584c2facc89c7570de21545db6169bb4525be12335b4789907d05a50a0ddd363f8a25c606a57b2d7f16970b3b282bd2b205dc9918bdf4e2027dac0d9447b600fe7756e212018097c468f62185c5b02a660b8bdb7a69972df3186e2f1b96040131358952fad7c217a081a5e3dea013f2531a96bc0c7fc00daaa4f099bb897e9632ba6cb52beda4dcd513b1313e5615ec960a3fed2f803d5363aa80b5bbe4702fd72a1b4db762c3d6c0b2f411ea8a5770d72089d43def6d349632d41786c5163353ed732128ef88a86109b370403fdfe7960008e6c364f845c4952339eea89e5e935b72ec786a4ba856a1ea5c7fdf24c08d1fdd88732b971a7c1b8404fe3b3565c25a35e12fd2597672689ee95afaeb8db22b540ce5068a65689a3591fb79207c5045383ed5429e585dea61fde0f526eb8c28370881e39e7388a925cd6bb09387bbc18177df42fa1d84a3f7f566e93e4ee61c593aec9baa722f1594524e0b4a6793a5cee2a31155f5520f585390e6cf8f21088f1f879bda3a36bf56811e6011a521e2bf9dda09ee9a3bb0c3c77a5ef7a3b729a7812cb79a28b786554097a4513d431937aafde464d7abfd699d017c035a001b01dd2b657e1296d2b1a986fd80fee2834ed77ce84502b22620f788c822568226d5fcac4483af266f7c7e8684b6283c981440323f0e50acdd75fece02fa9ccf00000000000000000000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/contracts/fixtures/uc_and_memberships_fixture.json b/contracts/fixtures/uc_and_memberships_fixture.json index 322ab52..67c11fe 100644 --- a/contracts/fixtures/uc_and_memberships_fixture.json +++ b/contracts/fixtures/uc_and_memberships_fixture.json @@ -1,9 +1,10 @@ { - "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000253370000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066b4386ddd61735333d38ba62f9c8edb7d41b399ce6a0a0ed10d1aeaec708afec8d40472a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb", - "updateClientVkey": "0x0029ce4b0512b5c4254fb11a189799cddb28254f7177d549cf2dc860bc31519e", - "membershipVkey": "0x005f30ecbba088f6f6eede4ca8d4ff6ffc2b7e5f59de38edd1574aefb937afdb", - "ucAndMembershipVkey": "0x00cf1fa1df1f491548e84e88a6b617a70b7abd0c017bc7115ed08f329e05026a", - "proofHeight": "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000025337a", - "membershipProof": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000cf1fa1df1f491548e84e88a6b617a70b7abd0c017bc7115ed08f329e05026a0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000066b4386ddd61735333d38ba62f9c8edb7d41b399ce6a0a0ed10d1aeaec708afec8d40472a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb0000000000000000000000000000000000000000000000000000000066b438e572e20e3f7c806f0b63f0ad2b0b4bc471e73911b1be2b9436ec1dfdc7aa322365a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb0000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002533700000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000025337a00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066c02d7400000000000000000000000000000000000000000000000000000000000000076d6f6368612d340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a10757067726164656449424353746174655001580100000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e74537461746500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f2f300a5c9ce81ee98fc05aa41664722f195f603cf49ff420538b68baabe49dfd0ba5655f6f7293f8b89946efd0fbf9bbd4a617d73ebac5c2ecf3f481886ade3e178a4bf674bf3b4b9524b214c48ed568c7abdb60d09f090ced61dd3fd1147f331d1e90742e7cb2ec21fbb045e99f0fd98c6aebc76c9618d44543a2d5b21844cb18a2318ec7182be01c74cbfeba7f56cd7e30d32f16b76f988645d82be718f293124298e3f866553ebf1012ab2ef7e0a20c26aabd3eddd6645ec3b6f844b261a6018124eb0cd7a9cbd61f3acc47a6845bceab6c0f9a97e6bab551f408b6af575b2e263f0adce3d506bc56a91842dd75eb5c119924b399e0a6fe7377e12f7f9e1e1a25eaa55ff29060c0bb29788364236c38ca01d821a40794b278ce8f2afd8c2428c01df3b5af81892ddfc2d78e4f8bfa504e9481fb39b694fdf0ed53ea72687b0e0b691b8e31a22533be7510872cf4d58043b5ed4223fe72f356677431c9f7e41ca670820e72b8eaa4d98c80d44e85c62d9636e46320f242f91a9fe8e218a8791dc745303b10490e2710514c2f28b5babbc614740d2a75a988207346ad277218010d2c4b1bb73838e518bfdeff2eab34d2bbe9c5b7f4a81fd33c35789c8f08b42954dd268f916bbc875394562990483335747b169ca43b916f3f15ae8c14e2042b54f58973c8c47a1c67635bbf4adea7d6bf1e75240bbf554f77d57ba6c36f542a5d86876496bdb2a3638ab836629374134f4e436e61aaf023c94e7451d348aa07d02058eb4443217c7b830d64b9d63ba7898fe44786d1a63ff2041498a9effa0429ebb6377d912d8b70a53b7fb1bd8540d7cc20d886628e7514dce7a3eea5e81cc1d552e8c15f0b5348dc845e25f4cacf9bffd7066d2fcaeadba30d79eb201d0084214aa2e1a4c019a3ec2fe51b288039c07ab78a6cfe25a85fdc64c4264e1803c22b45e43777a3a12626cfb23f13054521c78f8fa884be2d5a1a31e94ca9bf2f98049cd3151680c838ced9a810ae6558d63cc4a324826e583f6eeee62f42cd140a780c088a09bd17dfb2f0033ec3c342d2bfd8eed625502aa8517f930917ec07a3012f39b39a91ca765b5ed0165a114f502d14e76a6573183ecef273e275fd1c643cdaa7b5c639c98aa2bdcf2b394558331fd19f49e2283b9d4cfde16d05e522e70b4738c76a5f019ae80d17b0e5fd521b652f8acd7b690a57c1ebffdceed500000000000000000000000000000000000000000000000000000000" + "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a57000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1", + "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", + "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", + "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", + "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", + "proofHeight": "00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276ab1", + "membershipProof": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd70110000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a10000000000000000000000000000000000000000000000000000000066cf0789d26229b6c70fe138eccbd82cc28f66a77c371a89a680f3c6f62435f63ad2a9fbf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a5700000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276ab100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066cf083700000000000000000000000000000000000000000000000000000000000000076d6f6368612d340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a10757067726164656449424353746174655001580100000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e74537461746500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f05684b12648a7bf93f35525e336edfe0da8074eb8ac9c206c6e324beed7373521d66c91bf6ecbe92e7ec93c8f9b9f4442647edf156b6a8d278d835abf45ddfcb15a1300dfd5350f7c06f40bbf8aa6b8e9941e2c4d7630bdb4cf5e0835d9a2dd31616149326a19a7da53f0d124b84ed7be2613edaa6ba595db2f51e6d2396b917050ce47653cce623b87224bc9f1054049f92bf9937596fb2c6034acc4c84abe21baa87db049a109828cc39a5ed1be053c2a01fb52038719005a9489f8b37b8af2a93f224e750ca5f21ca89ba38dc570a131c9e503e3ff564c3d32fdccdd3a47b147c03d8525bf65ec9729ba5ddfe4fe37d58ab1d5d283752854c2742fd45998822f6e613577924bcd3257b0ff5c29772a48b5b3d6642cb9fff2fbc0521cdf1e7031b828fbbe5400d4e55690978ab3450ea568edf9896bdb57628e4ef1aee098a068a668b19a65b60f499af016e46603e24fd5b197744ba910fda444b5a2a5587026736b342b53e72c914aacc33fa59fdcebfd16371f5af70c217d5522d31e474140a3ed13ab82df364a3d92bb1c1d78f43acdca73eb290ec37cd8105c9368996112886cd95f70d150b827ee0883d17ab2a3a6f4d7a5909a931dc6d996b9d4c521f9d737548e8b56de6f105c7d7d7f6cffd05639e40327570da8719ab71c5cdf21d90893fd1a5c3eec67bb72d7f2bb59e699c65398e4bea39fd67a2f21f79ab1e0b5b080e0821e1a9aaf7d05f5c06ffb519788207a6cebf40a90b70be2408aa101be20be9ec1f138e89c89dcd8b9dc3ee9b4eadfb4eeec95ed33c639eee68745216af51422bf27d625740494962e41870fcef8fa1598ca1394ef984d108978649303b33d466518358a310fef8245d4137aef3b0e8117f568df165b9269c434c0c20ec690a507966e03100c375206b7f987845326d031518b03ee74f8e5e8e225c0ebd295dc4a46438baada51b8b0867ed1989b2284ee4fffb27b5e27381adddfb0a3217b92247b3d4363a89b65d03af54605a552a48874a145ab55273687bccee00671525d01707724a78f5822a5416d3f901a6657b49c072fa2685088de709a21a72f411dd656c98ce950f71162e21d0d217220dfcdc6477d3282092c38f1d91058b9244d1453e400de71e86a488562bc18acb544d794bd847b55a038cbc25cc0927ed49b373ceb444d87a64869b4435408c335e49fefd002147b9263a4fafab00000000000000000000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/contracts/fixtures/update_client_fixture.json b/contracts/fixtures/update_client_fixture.json index 332b029..297bfae 100644 --- a/contracts/fixtures/update_client_fixture.json +++ b/contracts/fixtures/update_client_fixture.json @@ -1,10 +1,11 @@ { - "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000253370000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066b4386ddd61735333d38ba62f9c8edb7d41b399ce6a0a0ed10d1aeaec708afec8d40472a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb", - "updateClientVkey": "0x0029ce4b0512b5c4254fb11a189799cddb28254f7177d549cf2dc860bc31519e", - "membershipVkey": "0x005f30ecbba088f6f6eede4ca8d4ff6ffc2b7e5f59de38edd1574aefb937afdb", - "ucAndMembershipVkey": "0x00cf1fa1df1f491548e84e88a6b617a70b7abd0c017bc7115ed08f329e05026a", - "targetConsensusState": "0000000000000000000000000000000000000000000000000000000066b438e572e20e3f7c806f0b63f0ad2b0b4bc471e73911b1be2b9436ec1dfdc7aa322365a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb", - "targetHeight": 2438010, - "updateMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200029ce4b0512b5c4254fb11a189799cddb28254f7177d549cf2dc860bc31519e000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000066b4386ddd61735333d38ba62f9c8edb7d41b399ce6a0a0ed10d1aeaec708afec8d40472a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb0000000000000000000000000000000000000000000000000000000066b438e572e20e3f7c806f0b63f0ad2b0b4bc471e73911b1be2b9436ec1dfdc7aa322365a1d4cdbc90487e9cf127cf745c0ce4e8f72e4babc77eb53db3729b8d848125cb0000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002533700000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000025337a00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066c0310400000000000000000000000000000000000000000000000000000000000000076d6f6368612d34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f23fd82c38803280265012deb0bc076758cd7d02490abe787dfc84994bbab081c0c6a671f76af10d0667e77d9eb9f62877c9ce0870d17744af1c91708397fc65a0cd8f2f2e1f39af403949da3213d23c077f5db7c605fd866d189eb7d4292409611f420f9625387e7c522c38d64b0a0c505241fb765699b1fbf793fe6edcd4368266499ab7a835c308bec1044143073087712b2cc1bec0976ea0ae14b128c7d02209bba3f1976fe6f67634f45f7165d87a3d972a7a5630e1797adf430602378bb2225fe941e6a209c59d2c080a562682d75a35560ff2b3e0ffa7e5f564ea4468f192fbfb8bd8a90a8fe245658b76addac1373a80d550100a8fb831ba1762362ae0a52e7a3964f7144246944974cd472728e6e02d7489ed5756bb3533a96229042120cd8e706ddf8cba1c52686d3972eee7a9c793a2fb9a42a2f8c7559dafc650123a278f3c33b05b53e3724533eadd8ed9326484352fd340726ef1d5281ddb4b422519f7a98eba7b0fc184f434099e4106b9a9f6428984dfe5412bcdfc121d55b22c6706a2778ee45109417bee2815d8d7e92ebfcd4853eaf339dd6743181f29e2f7c76e23676aaef9cadc6a425e59ee4df21ca478d147980ed9e0519edf96aad20b604e0a556795e128c878471ffb7ca80aabbacaed628904c82789fb158a61d2e6366790c5ad14021fe534a83ec0fc13ceaf307995f953912cac69023872f2d1af35818730e7d2fdb11710c39e5900d46a7dee67943c33e05562ed7fc21e5531ef48441cfff6cdaf3802d31098e1b25c094d49ef530eb67954ca1ca43db7e0000fe30b126685b07c11fbafd4410ffa6e59ab343a5d3d4c4e369cf9b55872c262aab2788d99515348ece3565f657464f6fa5485c49c8b70359070b8c57e15ef81bdd711c614a5a89163dd168b20aeb8d09c665d69ca9971974bc536bf39078b52cc6dbabd2cd28a611c5b84f26c8f0af2c90ee1dc64cea90b18b18600ebe0a6c001156e59cefa490db457bd9a6712699f6e5879f81ae0a791ea45f7206eced5304aa244302683cb5e8105ecf5f8a57a52de17a3b39abde4371f31c9559415c6c0f61cbd1f3d99f0028a1efd1e4cc2262e4f6b1ddb5cc980b51f3f1736509d4f92774b8b36d1b2164da1047123612c4aff26c1d13fa93f337aa319f9e2308d0a314f4f36ec649c267db8b9fb1de19a864204079c5acce53922cdd3dfc7f874a5e00000000000000000000000000000000000000000000000000000000" + "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a57000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1", + "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", + "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", + "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", + "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", + "targetConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0789d26229b6c70fe138eccbd82cc28f66a77c371a89a680f3c6f62435f63ad2a9fbf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1", + "targetHeight": 2583217, + "updateMsg": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a10000000000000000000000000000000000000000000000000000000066cf0789d26229b6c70fe138eccbd82cc28f66a77c371a89a680f3c6f62435f63ad2a9fbf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a5700000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276ab100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066cf082800000000000000000000000000000000000000000000000000000000000000076d6f6368612d34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f06171485b883f5d959805cd7de83029af4324e25079b4c7e624cf0976cbc4db30bc39c45c46cc5cbc3432065a1a4b6ba871b5913b0161f9a68a5d53296f7671d0b52c02cc82a8bc6ee1d0e8088bd0f297776e638b385d5639de465f9a87471ee2d0cfbbbcf29ce774c0aa5c9030d19fb8e0d750033de56cb23ec262bff9b215d2782f8472c2b4215f2d9e0eb2d8b01f7a5b124656343a91e3fcfcd2dfb0bfb7f2ab9201ad6946ba478e8917835caa25f29d436730f377d27c92fc38c0ec5aa750f08fd222cf715ec2ccd13b8eee9356bfcd9cc1b3db0612d2ed9a03158a435e5270171a1cec7ee2be70da7e7f6248dd99097d3bbe2572cc88d5adae8ba870c951fc4e6dc593ab927ee1fa80b417f1c8e05c6063ce29a8526128fbf6cbed62f171b09e320a974da3109e932d9eb5acade29f57cb4be8d0f9df4c1b90907a68c7b1a1f583fdd25076af41276ae463e90dfaf1cdd58fb8977a743d06f889ee0b2cb27edccd7691e13fa902f7a6dd4c4fa70623132d0bf1428935fefa7ac2c79358215f2024e6dba1511b271e20dfbfe3606237d291f537db68a92096a2bd62388b82f4e6517b4379dbac562c4e2526f381341dc3fbdfcba0be3d6e0ebb1f5cc0381048f339bbfe3be43d6425c4d7b7f862c7c9f88cce3835ed8c104bbc9170e1cc92bdebc6150b7b8a9b40bb1f79abcc1b82924f7020f0bc9a753ff7faa98350c5129e8023163bd3a10254a648e6f82b9e8553f3e802de32915f200c94b6c3d899427da8854518d037b0e8ec532b3e8dcc89350ef31cc3655508079bc457d095f2023cde883c6020efe315acdb0a710a6458ca6a87baf0769565a43bbdd4092fb72239e45d1b496aa89926e582341df46540f1d7afd406cb2cd269aa19b2752bd4b1de32029ae493eb18b433dd637dbafebab0e4286090a8013643de917cab352c51916f766ec26245fc25592dabebd424a0acafafbd26429b8f42cc78bcd0c33340fb5d794424b1905aa1cec7b59be4580f88ff7d1cce186980f421d97347769850c962118eff95b7768ef657c6a606a203a0b47c3904b7b3d6c6d89aeed1e6301258cfdee53f4c314503d80469e267a60597c444266d3507d1dafb5f7d5c85045096be9606738bb141eea61131bf7520db797ba59c310cec293593d77a8825a82153087665f9e041d251db18cfee69e18c6c95af3fb9d7eee04dd818839e6be4400000000000000000000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index cf6264e..9be412c 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,8 +1,8 @@ { "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cc5a4a76ffd7c0f7b019c80dc3b2d9e05e1bc803074277ad8fd836edf4208cb0093c491d7bacd36d73696f4ab07a9813837ffedd342ec024c91b929ee0652e9931c517", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0b40a268415ab138fceb78fb0b92a248b6b1780501936886b86aa6c13afd3bc179cb9b904acfe3b78177cea7f6f6264b55c12e3c086f40ed9ab8e30983519a8376d5", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", - "misbehaviourVkey": "0x0064ffd659dfc4aef854ad17da8ab2be54ac95b2826d0acb94d4740380eebdcc" + "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9" } \ No newline at end of file diff --git a/contracts/src/SP1ICS07Tendermint.sol b/contracts/src/SP1ICS07Tendermint.sol index 03e7f91..e140820 100644 --- a/contracts/src/SP1ICS07Tendermint.sol +++ b/contracts/src/SP1ICS07Tendermint.sol @@ -149,35 +149,15 @@ contract SP1ICS07Tendermint is } MisbehaviourOutput memory output = abi.decode(msgSubmitMisbehaviour.sp1Proof.publicValues, (MisbehaviourOutput)); + validateMisbehaviourOutput(output); verifySP1Proof(msgSubmitMisbehaviour.sp1Proof); - // If the misbehaviour is valid, the client is frozen + // If the misbehaviour and proof is valid, the client needs to be frozen clientState.isFrozen = true; } - /// @notice Validates the SP1ICS07MisbehaviourOutput public values. - /// @param output The public values. - function validateMisbehaviourOutput(MisbehaviourOutput memory output) private view { - if (clientState.isFrozen) { - revert FrozenClientState(); - } - validateEnv(output.env); - - bytes32 outputConsensusStateHash1 = keccak256(abi.encode(output.trustedConsensusState1)); - bytes32 trustedConsensusState1 = getConsensusStateHash(output.trustedHeight1.revisionHeight); - if (outputConsensusStateHash1 != trustedConsensusState1) { - revert ConsensusStateHashMismatch(trustedConsensusState1, outputConsensusStateHash1); - } - - bytes32 outputConsensusStateHash2 = keccak256(abi.encode(output.trustedConsensusState2)); - bytes32 trustedConsensusState2 = getConsensusStateHash(output.trustedHeight2.revisionHeight); - if (outputConsensusStateHash2 != trustedConsensusState2) { - revert ConsensusStateHashMismatch(trustedConsensusState2, outputConsensusStateHash2); - } - } - /// @notice The entrypoint for upgrading the client. /// @inheritdoc ILightClient function upgradeClient(bytes calldata) public pure { @@ -378,6 +358,27 @@ contract SP1ICS07Tendermint is } } + /// @notice Validates the SP1ICS07MisbehaviourOutput public values. + /// @param output The public values. + function validateMisbehaviourOutput(MisbehaviourOutput memory output) private view { + if (clientState.isFrozen) { + revert FrozenClientState(); + } + validateEnv(output.env); + + bytes32 outputConsensusStateHash1 = keccak256(abi.encode(output.trustedConsensusState1)); + bytes32 trustedConsensusState1 = getConsensusStateHash(output.trustedHeight1.revisionHeight); + if (outputConsensusStateHash1 != trustedConsensusState1) { + revert ConsensusStateHashMismatch(trustedConsensusState1, outputConsensusStateHash1); + } + + bytes32 outputConsensusStateHash2 = keccak256(abi.encode(output.trustedConsensusState2)); + bytes32 trustedConsensusState2 = getConsensusStateHash(output.trustedHeight2.revisionHeight); + if (outputConsensusStateHash2 != trustedConsensusState2) { + revert ConsensusStateHashMismatch(trustedConsensusState2, outputConsensusStateHash2); + } + } + /// @notice Validates the Env public values. /// @param env The public values. function validateEnv(Env memory env) private view { @@ -392,7 +393,7 @@ contract SP1ICS07Tendermint is } if ( env.trustThreshold.numerator != clientState.trustLevel.numerator - || env.trustThreshold.denominator != clientState.trustLevel.denominator + || env.trustThreshold.denominator != clientState.trustLevel.denominator ) { revert TrustThresholdMismatch( clientState.trustLevel.numerator, diff --git a/contracts/test/Misbehaviour.t.sol b/contracts/test/Misbehaviour.t.sol new file mode 100644 index 000000000..9d19189 --- /dev/null +++ b/contracts/test/Misbehaviour.t.sol @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.25; + +// solhint-disable-next-line no-global-import +import "forge-std/console.sol"; +import { SP1ICS07TendermintTest } from "./SP1ICS07TendermintTest.sol"; +import { IMisbehaviourMsgs } from "../src/msgs/IMisbehaviourMsgs.sol"; +import { SP1Verifier } from "@sp1-contracts/v1.1.0/SP1Verifier.sol"; +import { stdJson } from "forge-std/StdJson.sol"; + +struct SP1ICS07MisbehaviourFixtureJson { + bytes trustedClientState; + bytes trustedConsensusState; + bytes submitMsg; +} + +contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { + using stdJson for string; + + SP1ICS07MisbehaviourFixtureJson public fixture; + MsgSubmitMisbehaviour public submitMsg; + MisbehaviourOutput public output; + + Env public env; + + function setUp() public { + fixture = loadFixture("e2e_misbehaviour_fixture.json"); + + setUpTest("e2e_misbehaviour_fixture.json"); + + submitMsg = abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); + output = abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); + env = output.env; + } + + function loadFixture(string memory fileName) public view returns (SP1ICS07MisbehaviourFixtureJson memory) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/contracts/fixtures/", fileName); + string memory json = vm.readFile(path); + bytes memory trustedClientStateBz = json.readBytes(".trustedClientState"); + bytes memory trustedConsensusStateBz = json.readBytes(".trustedConsensusState"); + bytes memory submitMsgBz = json.readBytes(".submitMsg"); + + SP1ICS07MisbehaviourFixtureJson memory fix = SP1ICS07MisbehaviourFixtureJson({ + trustedClientState: trustedClientStateBz, + trustedConsensusState: trustedConsensusStateBz, + submitMsg: submitMsgBz + }); + + return fix; + } + + function test_ValidMisbehaviour() public { + // set a correct timestamp + vm.warp(env.now + 300); + ics07Tendermint.misbehaviour(fixture.submitMsg); + + // to console + console.log("Misbehaviour gas used: ", vm.lastCallGas().gasTotalUsed); + + // verify that the client is frozen + ClientState memory clientState = ics07Tendermint.getClientState(); + assertTrue(clientState.isFrozen); + } + + function test_InvalidMisbehaviour() public { + // proof is in the future + vm.warp(env.now - 300); + vm.expectRevert(abi.encodeWithSelector(ProofIsInTheFuture.selector, block.timestamp, env.now)); + ics07Tendermint.misbehaviour(fixture.submitMsg); + + // proof is too old + vm.warp(env.now + ics07Tendermint.ALLOWED_SP1_CLOCK_DRIFT() + 300); + vm.expectRevert(abi.encodeWithSelector(ProofIsTooOld.selector, block.timestamp, env.now)); + ics07Tendermint.misbehaviour(fixture.submitMsg); + + // set a correct timestamp + vm.warp(env.now + 300); + + // wrong vkey + MsgSubmitMisbehaviour memory badSubmitMsg = cloneSubmitMsg(); + badSubmitMsg.sp1Proof.vKey = bytes32(0); + bytes memory submitMsgBz = abi.encode(badSubmitMsg); + vm.expectRevert( + abi.encodeWithSelector( + VerificationKeyMismatch.selector, + ics07Tendermint.MISBEHAVIOUR_PROGRAM_VKEY(), + badSubmitMsg.sp1Proof.vKey + ) + ); + ics07Tendermint.misbehaviour(submitMsgBz); + + // chain id mismatch + badSubmitMsg = cloneSubmitMsg(); + MisbehaviourOutput memory badOutput = cloneOutput(); + badOutput.env.chainId = "bad-chain-id"; + badSubmitMsg.sp1Proof.publicValues = abi.encode(badOutput); + submitMsgBz = abi.encode(badSubmitMsg); + vm.expectRevert(abi.encodeWithSelector(ChainIdMismatch.selector, output.env.chainId, badOutput.env.chainId)); + ics07Tendermint.misbehaviour(submitMsgBz); + + // trust threshold mismatch + badSubmitMsg = cloneSubmitMsg(); + badOutput = cloneOutput(); + badOutput.env.trustThreshold = TrustThreshold({ numerator: 1, denominator: 2 }); + badSubmitMsg.sp1Proof.publicValues = abi.encode(badOutput); + submitMsgBz = abi.encode(badSubmitMsg); + vm.expectRevert( + abi.encodeWithSelector( + TrustThresholdMismatch.selector, output.env.trustThreshold, badOutput.env.trustThreshold + ) + ); + ics07Tendermint.misbehaviour(submitMsgBz); + + // trusting period mismatch + badSubmitMsg = cloneSubmitMsg(); + badOutput = cloneOutput(); + badOutput.env.trustingPeriod = 1; + badSubmitMsg.sp1Proof.publicValues = abi.encode(badOutput); + submitMsgBz = abi.encode(badSubmitMsg); + vm.expectRevert( + abi.encodeWithSelector( + TrustingPeriodMismatch.selector, output.env.trustingPeriod, badOutput.env.trustingPeriod + ) + ); + ics07Tendermint.misbehaviour(submitMsgBz); + + // invalid proof + badSubmitMsg = cloneSubmitMsg(); + badOutput = cloneOutput(); + badOutput.env.now = badOutput.env.now + 1; + badSubmitMsg.sp1Proof.publicValues = abi.encode(badOutput); + submitMsgBz = abi.encode(badSubmitMsg); + vm.expectRevert(abi.encodeWithSelector(SP1Verifier.InvalidProof.selector)); + ics07Tendermint.misbehaviour(submitMsgBz); + + // client state is frozen + ics07Tendermint.misbehaviour(fixture.submitMsg); // freeze the client + vm.expectRevert(abi.encodeWithSelector(FrozenClientState.selector)); + ics07Tendermint.misbehaviour(fixture.submitMsg); + } + + function cloneSubmitMsg() private view returns (MsgSubmitMisbehaviour memory) { + MsgSubmitMisbehaviour memory clone = MsgSubmitMisbehaviour({ + sp1Proof: SP1Proof({ + vKey: submitMsg.sp1Proof.vKey, + publicValues: submitMsg.sp1Proof.publicValues, + proof: submitMsg.sp1Proof.proof + }) + }); + return clone; + } + + function cloneOutput() private view returns (MisbehaviourOutput memory) { + MisbehaviourOutput memory clone = MisbehaviourOutput({ + env: Env({ + chainId: output.env.chainId, + trustThreshold: output.env.trustThreshold, + trustingPeriod: output.env.trustingPeriod, + now: output.env.now + }), + trustedHeight1: output.trustedHeight1, + trustedHeight2: output.trustedHeight2, + trustedConsensusState1: output.trustedConsensusState1, + trustedConsensusState2: output.trustedConsensusState2 + }); + return clone; + } +} diff --git a/contracts/test/MisbehaviourTest.t.sol b/contracts/test/MisbehaviourTest.t.sol deleted file mode 100644 index 4a2afda..000000000 --- a/contracts/test/MisbehaviourTest.t.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.25; - -// solhint-disable-next-line no-global-import -import { SP1ICS07TendermintTest } from "./SP1ICS07TendermintTest.sol"; -import { IMisbehaviourMsgs } from "../src/msgs/IMisbehaviourMsgs.sol"; -import { stdJson } from "forge-std/StdJson.sol"; - -struct SP1ICS07MisbehaviourFixtureJson { - bytes trustedClientState; - bytes trustedConsensusState; - bytes submitMsg; -} - -contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { - SP1ICS07MisbehaviourFixtureJson public fixture; - - using stdJson for string; - - function setUp() public { - fixture = loadFixture("misbehaviour_fixture.json"); - - setUpTest("misbehaviour_fixture.json"); - } - - function loadFixture(string memory fileName) public view returns (SP1ICS07MisbehaviourFixtureJson memory) { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/contracts/fixtures/", fileName); - string memory json = vm.readFile(path); - bytes memory trustedClientState = json.readBytes(".trustedClientState"); - bytes memory trustedConsensusState = json.readBytes(".trustedConsensusState"); - bytes memory submitMsg = json.readBytes(".submitMsg"); - - SP1ICS07MisbehaviourFixtureJson memory fix = SP1ICS07MisbehaviourFixtureJson({ - trustedClientState: trustedClientState, - trustedConsensusState: trustedConsensusState, - submitMsg: submitMsg - }); - - return fix; - } - - function test_ValidMisbehaviour() public view { - IMisbehaviourMsgs.MsgSubmitMisbehaviour memory submitMsg = - abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); - IMisbehaviourMsgs.MisbehaviourOutput memory output = - abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); - assertNotEq(output.trustedHeight1.revisionHeight, 0); - assertNotEq(output.trustedHeight2.revisionHeight, 0); - - // TODO: Write the actual test :P - } -} diff --git a/contracts/test/SP1ICS07TendermintTest.sol b/contracts/test/SP1ICS07TendermintTest.sol index 7c66dd9..7726c32 100644 --- a/contracts/test/SP1ICS07TendermintTest.sol +++ b/contracts/test/SP1ICS07TendermintTest.sol @@ -9,7 +9,9 @@ import { IICS07TendermintMsgs } from "../src/msgs/IICS07TendermintMsgs.sol"; import { IUpdateClientMsgs } from "../src/msgs/IUpdateClientMsgs.sol"; import { IMembershipMsgs } from "../src/msgs/IMembershipMsgs.sol"; import { IUpdateClientAndMembershipMsgs } from "../src/msgs/IUcAndMembershipMsgs.sol"; +import { IMisbehaviourMsgs } from "../src/msgs/IMisbehaviourMsgs.sol"; import { SP1ICS07Tendermint } from "../src/SP1ICS07Tendermint.sol"; +import { ISP1ICS07TendermintErrors } from "../src/errors/ISP1ICS07TendermintErrors.sol"; import { SP1Verifier } from "@sp1-contracts/v1.1.0/SP1Verifier.sol"; import { SP1MockVerifier } from "@sp1-contracts/SP1MockVerifier.sol"; import { ILightClientMsgs } from "solidity-ibc/msgs/ILightClientMsgs.sol"; @@ -29,6 +31,8 @@ abstract contract SP1ICS07TendermintTest is IUpdateClientMsgs, IMembershipMsgs, IUpdateClientAndMembershipMsgs, + IMisbehaviourMsgs, + ISP1ICS07TendermintErrors, ILightClientMsgs { using stdJson for string; diff --git a/e2e/interchaintestv8/.golangci.yml b/e2e/interchaintestv8/.golangci.yml index 8396ad4..f3ce579 100644 --- a/e2e/interchaintestv8/.golangci.yml +++ b/e2e/interchaintestv8/.golangci.yml @@ -7,7 +7,7 @@ linters: disable-all: true enable: - dogsled - - exportloopref + - copyloopvar - errcheck - gci - goconst @@ -51,6 +51,10 @@ issues: max-same-issues: 10000 linters-settings: + gosec: + excludes: + # Flags for potentially-unsafe casting of ints, similar problem to globally-disabled G103 + - G115 gci: sections: - standard # Standard section: captures all standard packages. @@ -65,7 +69,6 @@ linters-settings: - prefix(github.com/CosmWasm/wasmd) - prefix(github.com/strangelove-ventures/interchaintest) - prefix(github.com/srdtrk/sp1-ics07-tendermint/e2e/v8) - custom-order: true dogsled: max-blank-identifiers: 3 diff --git a/e2e/interchaintestv8/chainconfig/chain_config.go b/e2e/interchaintestv8/chainconfig/chain_config.go index 6fd0b19..78f117f 100644 --- a/e2e/interchaintestv8/chainconfig/chain_config.go +++ b/e2e/interchaintestv8/chainconfig/chain_config.go @@ -2,13 +2,13 @@ package chainconfig import ( interchaintest "github.com/strangelove-ventures/interchaintest/v8" - "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum" + "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum/foundry" "github.com/strangelove-ventures/interchaintest/v8/ibc" ) var DefaultChainSpecs = []*interchaintest.ChainSpec{ // -- ETH -- - {ChainConfig: ethereum.DefaultEthereumAnvilChainConfig("ethereum")}, + {ChainConfig: foundry.DefaultEthereumAnvilChainConfig("ethereum")}, // -- IBC-Go -- { ChainConfig: ibc.ChainConfig{ diff --git a/e2e/interchaintestv8/e2esuite/suite.go b/e2e/interchaintestv8/e2esuite/suite.go index 973c66f..f56814f 100644 --- a/e2e/interchaintestv8/e2esuite/suite.go +++ b/e2e/interchaintestv8/e2esuite/suite.go @@ -12,7 +12,7 @@ import ( interchaintest "github.com/strangelove-ventures/interchaintest/v8" "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum" + "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum/foundry" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testreporter" @@ -24,7 +24,7 @@ import ( type TestSuite struct { suite.Suite - ChainA *ethereum.EthereumChain + ChainA *foundry.AnvilChain ChainB *cosmos.CosmosChain UserA ibc.Wallet UserB ibc.Wallet @@ -37,6 +37,7 @@ type TestSuite struct { // SetupSuite sets up the chains, relayer, user accounts, clients, and connections func (s *TestSuite) SetupSuite(ctx context.Context) { chainSpecs := chainconfig.DefaultChainSpecs + chainSpecs[0].AdditionalStartArgs = append(chainSpecs[0].AdditionalStartArgs, "--steps-tracing") if len(chainSpecs) != 2 { panic("TestSuite requires exactly 2 chain specs") @@ -51,7 +52,7 @@ func (s *TestSuite) SetupSuite(ctx context.Context) { chains, err := cf.Chains(t.Name()) s.Require().NoError(err) - s.ChainA = chains[0].(*ethereum.EthereumChain) + s.ChainA = chains[0].(*foundry.AnvilChain) s.ChainB = chains[1].(*cosmos.CosmosChain) s.ExecRep = testreporter.NewNopReporter().RelayerExecReporter(t) diff --git a/e2e/interchaintestv8/e2esuite/utils.go b/e2e/interchaintestv8/e2esuite/utils.go index 1d68741..b5214c8 100644 --- a/e2e/interchaintestv8/e2esuite/utils.go +++ b/e2e/interchaintestv8/e2esuite/utils.go @@ -133,6 +133,9 @@ func (s *TestSuite) GetTxReciept(ctx context.Context, chain *ethereum.EthereumCh return receipt != nil, nil }) + + // TODO: This should check if the tx was actually successful and return a bool or err on that basis + s.Require().NoError(err) return receipt } diff --git a/e2e/interchaintestv8/go.mod b/e2e/interchaintestv8/go.mod index decac5d..6673cbd 100644 --- a/e2e/interchaintestv8/go.mod +++ b/e2e/interchaintestv8/go.mod @@ -8,24 +8,24 @@ require ( cosmossdk.io/api v0.7.5 cosmossdk.io/math v1.3.0 cosmossdk.io/x/tx v0.13.3 - cosmossdk.io/x/upgrade v0.1.2 + cosmossdk.io/x/upgrade v0.1.3 github.com/CosmWasm/wasmd v0.50.0 - github.com/cosmos/cosmos-sdk v0.50.7 - github.com/cosmos/gogoproto v1.4.12 + github.com/cosmos/cosmos-sdk v0.50.8 + github.com/cosmos/gogoproto v1.5.0 github.com/cosmos/ibc-go/v8 v8.4.0 github.com/docker/docker v24.0.9+incompatible github.com/ethereum/go-ethereum v1.14.6 - github.com/strangelove-ventures/interchaintest/v8 v8.3.0 + github.com/strangelove-ventures/interchaintest/v8 v8.7.0 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 - google.golang.org/grpc v1.64.0 + google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.1 ) require ( cloud.google.com/go v0.112.1 // indirect cloud.google.com/go/compute v1.25.1 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/storage v1.38.0 // indirect cosmossdk.io/client/v2 v2.0.0-beta.1 // indirect @@ -41,7 +41,7 @@ require ( filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect - github.com/BurntSushi/toml v1.3.2 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/ChainSafe/go-schnorrkel/1 v0.0.0-00010101000000-000000000000 // indirect github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 // indirect @@ -71,7 +71,7 @@ require ( github.com/cockroachdb/pebble v1.1.1 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.7 // indirect + github.com/cometbft/cometbft v0.38.10 // indirect github.com/cometbft/cometbft-db v0.10.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect @@ -119,7 +119,7 @@ require ( github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect - github.com/golang/glog v1.2.0 // indirect + github.com/golang/glog v1.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -141,13 +141,13 @@ require ( github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.3 // indirect + github.com/hashicorp/go-getter v1.7.4 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -163,7 +163,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.17.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.7 // indirect @@ -177,7 +177,7 @@ require ( github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect - github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2 // indirect + github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20240603204351-26b456ae3afe // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -198,7 +198,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.2.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect github.com/pierrec/xxHash v0.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -228,6 +228,9 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.7.0 // indirect + github.com/tidwall/gjson v1.17.1 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/tyler-smith/go-bip32 v1.0.0 // indirect @@ -243,22 +246,22 @@ require ( go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.22.0 // indirect + golang.org/x/crypto v0.24.0 // indirect golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/tools v0.22.0 // indirect google.golang.org/api v0.169.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect @@ -266,10 +269,10 @@ require ( gotest.tools/v3 v3.5.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect - modernc.org/libc v1.41.0 // indirect + modernc.org/libc v1.52.1 // indirect modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.7.2 // indirect - modernc.org/sqlite v1.29.5 // indirect + modernc.org/memory v1.8.0 // indirect + modernc.org/sqlite v1.30.1 // indirect modernc.org/strutil v1.2.0 // indirect modernc.org/token v1.1.0 // indirect nhooyr.io/websocket v1.8.7 // indirect diff --git a/e2e/interchaintestv8/go.sum b/e2e/interchaintestv8/go.sum index 7874d6c..bff6797 100644 --- a/e2e/interchaintestv8/go.sum +++ b/e2e/interchaintestv8/go.sum @@ -72,6 +72,8 @@ cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJd cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= @@ -212,6 +214,8 @@ cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= cosmossdk.io/x/upgrade v0.1.2 h1:O2FGb0mVSXl7P6BQm9uV3hRVKom1zBLDGhd4G8jysJg= cosmossdk.io/x/upgrade v0.1.2/go.mod h1:P+e4/ZNd8km7lTAX5hC2pXz/042YDcB7gzKTHuY53nc= +cosmossdk.io/x/upgrade v0.1.3 h1:q4XpXc6zp0dX6x74uBtfN6+J7ikaQev5Bla6Q0ADLK8= +cosmossdk.io/x/upgrade v0.1.3/go.mod h1:jOdQhnaY5B8CDUoUbed23/Lre0Dk+r6BMQE40iKlVVQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -224,6 +228,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= @@ -365,6 +371,8 @@ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1: github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/cometbft/cometbft v0.38.7 h1:ULhIOJ9+LgSy6nLekhq9ae3juX3NnQUMMPyVdhZV6Hk= github.com/cometbft/cometbft v0.38.7/go.mod h1:HIyf811dFMI73IE0F7RrnY/Fr+d1+HuJAgtkEpQjCMY= +github.com/cometbft/cometbft v0.38.10 h1:2ePuglchT+j0Iao+cfmt/nw5U7K2lnGDzXSUPGVdXaU= +github.com/cometbft/cometbft v0.38.10/go.mod h1:jHPx9vQpWzPHEAiYI/7EDKaB1NXhK6o3SArrrY8ExKc= github.com/cometbft/cometbft-db v0.10.0 h1:VMBQh88zXn64jXVvj39tlu/IgsGR84T7ImjS523DCiU= github.com/cometbft/cometbft-db v0.10.0/go.mod h1:7RR7NRv99j7keWJ5IkE9iZibUTKYdtepXTp7Ra0FxKk= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -387,6 +395,8 @@ github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+R github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= github.com/cosmos/cosmos-sdk v0.50.7 h1:LsBGKxifENR/DN4E1RZaitsyL93HU44x0p8EnMHp4V4= github.com/cosmos/cosmos-sdk v0.50.7/go.mod h1:84xDDJEHttRT7NDGwBaUOLVOMN0JNE9x7NbsYIxXs1s= +github.com/cosmos/cosmos-sdk v0.50.8 h1:2UJHssUaGHTl4/dFp8xyREKAnfiRU6VVfqtKG9n8w5g= +github.com/cosmos/cosmos-sdk v0.50.8/go.mod h1:Zb+DgHtiByNwgj71IlJBXwOq6dLhtyAq3AgqpXm/jHo= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -395,6 +405,8 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= github.com/cosmos/gogoproto v1.4.12 h1:vB6Lbe/rtnYGjQuFxkPiPYiCybqFT8QvLipDZP8JpFE= github.com/cosmos/gogoproto v1.4.12/go.mod h1:LnZob1bXRdUoqMMtwYlcR3wjiElmlC+FkjaZRv1/eLY= +github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o= +github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I= github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= @@ -580,6 +592,8 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -735,6 +749,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.4 h1:3yQjWuxICvSpYwqSayAdKRFcvBl1y/vogCxczWSmix0= +github.com/hashicorp/go-getter v1.7.4/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -759,6 +775,8 @@ github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -839,6 +857,8 @@ github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLA github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -902,6 +922,8 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2 h1:G/cVeTAbB9S/6FSWWqpFV0v49hiuHLbJPu9hTZ0UR2A= github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2/go.mod h1:Q5BxOd9FxJqYp4vCiLGVdetecPcWTmUQIu0bRigYosU= +github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20240603204351-26b456ae3afe h1:0fcCSfvBgbagEsEMkZuxgA3Ex7IN9i1Hon0fwgMLpQw= +github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20240603204351-26b456ae3afe/go.mod h1:Q5BxOd9FxJqYp4vCiLGVdetecPcWTmUQIu0bRigYosU= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -1015,6 +1037,8 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 h1:jik8PHtAIsPlCRJjJzl4udgEf7hawInF9texMeO2jrU= @@ -1142,6 +1166,8 @@ github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobt github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/strangelove-ventures/interchaintest/v8 v8.3.0 h1:1XyATc0JkvzDhBS71CdpM5z1t6bmO9PgH/5/nffoM9Q= github.com/strangelove-ventures/interchaintest/v8 v8.3.0/go.mod h1:5goHQtgWO9khoUO/SfR//w3uaw/uYVriDR1OY6PyydM= +github.com/strangelove-ventures/interchaintest/v8 v8.7.0 h1:MAs3mCLQUHJELUa4nm+ZKkKMKQUV34icHUdlt2QVpfc= +github.com/strangelove-ventures/interchaintest/v8 v8.7.0/go.mod h1:d20jXQmPAzE4U9zop+nkMPk40l21CJzi/ZqwrgAixwU= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -1175,6 +1201,12 @@ github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2l github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= @@ -1276,6 +1308,8 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1317,6 +1351,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1378,6 +1414,8 @@ golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1405,6 +1443,8 @@ golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1524,11 +1564,15 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1542,6 +1586,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1610,6 +1656,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1792,8 +1840,12 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1837,6 +1889,8 @@ google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1911,12 +1965,18 @@ modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQX modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= +modernc.org/libc v1.52.1 h1:uau0VoiT5hnR+SpoWekCKbLqm7v6dhRL3hI+NQhgN3M= +modernc.org/libc v1.52.1/go.mod h1:HR4nVzFDSDizP620zcMCgjb1/8xk2lg5p/8yjfGv1IQ= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE= modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= +modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk= +modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/e2e/interchaintestv8/operator/operator.go b/e2e/interchaintestv8/operator/operator.go index 74b7c0f..3bcb2c0 100644 --- a/e2e/interchaintestv8/operator/operator.go +++ b/e2e/interchaintestv8/operator/operator.go @@ -29,12 +29,12 @@ type membershipFixture struct { } type GenesisFixture struct { - TrustedClientState string `json:"trustedClientState"` + TrustedClientState string `json:"trustedClientState"` TrustedConsensusState string `json:"trustedConsensusState"` - UpdateClientVkey string `json:"updateClientVkey"` - MembershipVkey string `json:"membershipVkey"` - UcAndMembershipVkey string `json:"ucAndMembershipVkey"` - MisbehaviourVKey string `json:"misbehaviourVKey"` + UpdateClientVkey string `json:"updateClientVkey"` + MembershipVkey string `json:"membershipVkey"` + UcAndMembershipVkey string `json:"ucAndMembershipVkey"` + MisbehaviourVKey string `json:"misbehaviourVKey"` } type MisbehaviourFixture struct { @@ -62,23 +62,20 @@ func StartOperator(args ...string) error { func UpdateClientAndMembershipProof(trusted_height, target_height uint64, paths string, args ...string) (*sp1ics07tendermint.IICS02ClientMsgsHeight, []byte, error) { args = append([]string{"fixtures", "update-client-and-membership", "--trusted-block", strconv.FormatUint(trusted_height, 10), "--target-block", strconv.FormatUint(target_height, 10), "--key-paths", paths}, args...) - stdout, err := exec.Command("target/release/operator", args...).Output() + output, err := exec.Command("target/release/operator", args...).CombinedOutput() if err != nil { return nil, nil, err } - // NOTE: writing stdout to os.Stdout after execution due to how `.Output()` works - os.Stdout.Write(stdout) - // eliminate non-json characters - jsonStartIdx := strings.Index(string(stdout), "{") + jsonStartIdx := strings.Index(string(output), "{") if jsonStartIdx == -1 { panic("no json found in output") } - stdout = stdout[jsonStartIdx:] + output = output[jsonStartIdx:] var membership membershipFixture - err = json.Unmarshal(stdout, &membership) + err = json.Unmarshal(output, &membership) if err != nil { return nil, nil, err } @@ -120,18 +117,18 @@ func UpdateClientAndMembershipProof(trusted_height, target_height uint64, paths return height, proofBz, nil } -func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixture bool) error { +func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixture bool, args ...string) ([]byte, error) { misbehaviourFileName := "misbehaviour.json" - args := []string{"fixtures", "misbehaviour", "--misbehaviour-path", misbehaviourFileName} + args = append([]string{"fixtures", "misbehaviour", "--misbehaviour-path", misbehaviourFileName}, args...) misbehaviour.ClientId = "07-tendermint-0" // We just have to set it to something to make the unmarshalling to work :P bzIntermediary, err := cdc.MarshalJSON(&misbehaviour) if err != nil { - return err + return nil, err } var jsonIntermediary map[string]interface{} if err := json.Unmarshal(bzIntermediary, &jsonIntermediary); err != nil { - return err + return nil, err } headerHexPaths := []string{ "validator_set.proposer.address", @@ -170,11 +167,11 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixt } base64str, ok := tmpIntermediary[pathParts[len(pathParts)-1]].(string) if !ok { - return fmt.Errorf("path not found: %s", path) + return nil, fmt.Errorf("path not found: %s", path) } bz, err := base64.StdEncoding.DecodeString(base64str) if err != nil { - return err + return nil, err } tmpIntermediary[pathParts[len(pathParts)-1]] = hex.EncodeToString(bz) } @@ -191,17 +188,17 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixt val := val.(map[string]interface{}) valAddressBase64Str, ok := val["address"].(string) if !ok { - return fmt.Errorf("address not found in path: %s", val) + return nil, fmt.Errorf("address not found in path: %s", val) } valAddressBz, err := base64.StdEncoding.DecodeString(valAddressBase64Str) if err != nil { - return err + return nil, err } val["address"] = hex.EncodeToString(valAddressBz) pubKey, ok := val["pub_key"].(map[string]interface{}) if !ok { - return fmt.Errorf("pub_key not found in path: %s", val) + return nil, fmt.Errorf("pub_key not found in path: %s", val) } ed25519PubKey := pubKey["ed25519"].(string) pubKey["type"] = "tendermint/PubKeyEd25519" @@ -229,57 +226,58 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixt if sig["block_id_flag"] == "BLOCK_ID_FLAG_COMMIT" { sig["block_id_flag"] = 2 } else { - return fmt.Errorf("unexpected block_id_flag: %s", sig["block_id_flag"]) + return nil, fmt.Errorf("unexpected block_id_flag: %s", sig["block_id_flag"]) } valAddressBase64Str, ok := sig["validator_address"].(string) if !ok { - return fmt.Errorf("validator_address not found") + return nil, fmt.Errorf("validator_address not found") } valAddressBz, err := base64.StdEncoding.DecodeString(valAddressBase64Str) if err != nil { - return err + return nil, err } sig["validator_address"] = hex.EncodeToString(valAddressBz) } misbehaviourBz, err := json.Marshal(jsonIntermediary) if err != nil { - return err + return nil, err } // TODO: Make file temporary and delete it after use if err := os.WriteFile(misbehaviourFileName, misbehaviourBz, 0o600); err != nil { - return err + return nil, err } - stdout, err := exec.Command("target/release/operator", args...).Output() + output, err := exec.Command("target/release/operator", args...).CombinedOutput() if err != nil { - return err + return nil, fmt.Errorf("operator misbehaviour failed: %w, output: %s", err, output) } - // NOTE: writing stdout to os.Stdout after execution due to how `.Output()` works - os.Stdout.Write(stdout) - // eliminate non-json characters - jsonStartIdx := strings.Index(string(stdout), "{") + jsonStartIdx := strings.Index(string(output), "{") if jsonStartIdx == -1 { panic("no json found in output") } - stdout = stdout[jsonStartIdx:] + output = output[jsonStartIdx:] var misbehaviourFixture MisbehaviourFixture - err = json.Unmarshal(stdout, &misbehaviour) + err = json.Unmarshal(output, &misbehaviourFixture) if err != nil { - return err + return nil, err } - fmt.Println(misbehaviourFixture) if writeFixture { - if err := os.WriteFile("contracts/fixtures/e2e_misbehaviour_fixture.json", stdout, 0o600); err != nil { - return err + if err := os.WriteFile("contracts/fixtures/e2e_misbehaviour_fixture.json", output, 0o600); err != nil { + return nil, err } } - return nil + submitMsgBz, err := hex.DecodeString(misbehaviourFixture.SubmitMsg) + if err != nil { + return nil, err + } + + return submitMsgBz, nil } diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index a7c3f7b..879903a 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -23,7 +23,6 @@ import ( cometproto "github.com/cometbft/cometbft/proto/tendermint/types" comettypes "github.com/cometbft/cometbft/types" comettime "github.com/cometbft/cometbft/types/time" - transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" ibcclientutils "github.com/cosmos/ibc-go/v8/modules/core/02-client/client/utils" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" @@ -34,7 +33,7 @@ import ( ibcmocks "github.com/cosmos/ibc-go/v8/testing/mock" "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum" + "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum/foundry" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testutil" @@ -99,7 +98,7 @@ func (s *SP1ICS07TendermintTestSuite) SetupSuite(ctx context.Context) { "-o", "contracts/script/genesis.json", )) - stdout, _, err := eth.ForgeScript(ctx, s.UserA.KeyName(), ethereum.ForgeScriptOpts{ + stdout, _, err := eth.ForgeScript(ctx, s.UserA.KeyName(), foundry.ForgeScriptOpts{ ContractRootDir: ".", SolidityContract: "contracts/script/SP1ICS07Tendermint.s.sol", RawOptions: []string{"--json"}, @@ -232,7 +231,7 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership() { s.Require().NoError(err) // wait until transaction is included in a block - _ = s.GetTxReciept(ctx, eth, tx.Hash()) + _ = s.GetTxReciept(ctx, eth.EthereumChain, tx.Hash()) clientState, err = s.contract.GetClientState(nil) s.Require().NoError(err) @@ -283,9 +282,20 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { Header2: &oldHeader, } - // TODO: Get fixture from operator and use it with the contract - err = operator.Misbehaviour(simd.GetCodec(), misbehaviour, s.generateFixtures) + submitMsg, err := operator.Misbehaviour(simd.GetCodec(), misbehaviour, s.generateFixtures, + "--trust-level", testvalues.DefaultTrustLevel.String(), + "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod)) + s.Require().NoError(err) + + tx, err := s.contract.Misbehaviour(s.GetTransactOpts(s.key), submitMsg) s.Require().NoError(err) + + // wait until transaction is included in a block + _ = s.GetTxReciept(ctx, eth.EthereumChain, tx.Hash()) + + clientState, err = s.contract.GetClientState(nil) + s.Require().NoError(err) + s.Require().True(clientState.IsFrozen) })) } @@ -296,28 +306,55 @@ func (s *SP1ICS07TendermintTestSuite) createTMClientHeader( timestamp time.Time, oldHeader tmclient.Header, ) tmclient.Header { - keyBz, err := chain.Validators[0].ReadFile(ctx, "config/priv_validator_key.json") - s.Require().NoError(err) - var privValidatorKeyFile cosmos.PrivValidatorKeyFile - err = json.Unmarshal(keyBz, &privValidatorKeyFile) - s.Require().NoError(err) - decodedKeyBz, err := base64.StdEncoding.DecodeString(privValidatorKeyFile.PrivKey.Value) - s.Require().NoError(err) + var privVals []comettypes.PrivValidator + var validators []*comettypes.Validator + for _, chainVal := range chain.Validators { + keyBz, err := chainVal.ReadFile(ctx, "config/priv_validator_key.json") + s.Require().NoError(err) + var privValidatorKeyFile cosmos.PrivValidatorKeyFile + err = json.Unmarshal(keyBz, &privValidatorKeyFile) + s.Require().NoError(err) + decodedKeyBz, err := base64.StdEncoding.DecodeString(privValidatorKeyFile.PrivKey.Value) + s.Require().NoError(err) - privKey := &ed25519.PrivKey{ - Key: decodedKeyBz, - } + privKey := &ed25519.PrivKey{ + Key: decodedKeyBz, + } - privVal := ibcmocks.PV{PrivKey: privKey} - pubKey, err := privVal.GetPubKey() - s.Require().NoError(err) + privVal := ibcmocks.PV{PrivKey: privKey} + privVals = append(privVals, privVal) - val := comettypes.NewValidator(pubKey, oldHeader.ValidatorSet.Proposer.VotingPower) - valSet := comettypes.NewValidatorSet([]*comettypes.Validator{val}) - signers := []comettypes.PrivValidator{privVal} + pubKey, err := privVal.GetPubKey() + s.Require().NoError(err) + + val := comettypes.NewValidator(pubKey, oldHeader.ValidatorSet.Proposer.VotingPower) + validators = append(validators, val) + + } + valSet := comettypes.NewValidatorSet(validators) vsetHash := valSet.Hash() + // Make sure all the signers are in the correct order as expected by the validator set + signers := make([]comettypes.PrivValidator, valSet.Size()) + for i, _ := range signers { + _, val := valSet.GetByIndex(int32(i)) + + for _, pv := range privVals { + pk, err := pv.GetPubKey() + s.Require().NoError(err) + + if pk.Equals(val.PubKey) { + signers[i] = pv + break + } + } + + if signers[i] == nil { + s.Require().FailNow("could not find signer for validator") + } + } + tmHeader := comettypes.Header{ Version: oldHeader.Header.Version, ChainID: oldHeader.Header.ChainID, @@ -336,7 +373,7 @@ func (s *SP1ICS07TendermintTestSuite) createTMClientHeader( } hhash := tmHeader.Hash() - blockID := ibctesting.MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) + blockID := ibctesting.MakeBlockID(hhash, oldHeader.Commit.BlockID.PartSetHeader.Total, tmhash.Sum([]byte("part_set"))) voteSet := comettypes.NewVoteSet(oldHeader.Header.ChainID, blockHeight, 1, cometproto.PrecommitType, valSet) voteProto := &comettypes.Vote{ diff --git a/e2e/interchaintestv8/testvalues/values.go b/e2e/interchaintestv8/testvalues/values.go index 8d72475..0f7d609 100644 --- a/e2e/interchaintestv8/testvalues/values.go +++ b/e2e/interchaintestv8/testvalues/values.go @@ -3,8 +3,6 @@ package testvalues import ( "time" - "cosmossdk.io/math" - ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum" @@ -46,7 +44,7 @@ var ( VotingPeriod = time.Second * 30 // StartingEthBalance is the amount of ETH to give to each user at the start of the test. - StartingEthBalance = math.NewInt(5 * ethereum.ETHER) + StartingEthBalance = ethereum.ETHER.MulRaw(5) // DefaultTrustLevel is the trust level used by the SP1ICS07Tendermint contract. DefaultTrustLevel = ibctm.Fraction{Numerator: 2, Denominator: 3}.ToTendermint() diff --git a/justfile b/justfile index f14466f..82260fc 100644 --- a/justfile +++ b/justfile @@ -31,18 +31,15 @@ install-operator: @echo "Installed the operator executable" # Run the Solidity tests using `forge test` command -test-foundry: - forge test -vvv +test-foundry testname=".\\*": + forge test -vvv --match-test ^{{testname}}\(.\*\)\$ # Run the Rust tests using `cargo test` command (excluding the sp1-ics07-tendermint-update-client crate) test-cargo: cargo test --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership --exclude sp1-ics07-tendermint-uc-and-membership --locked --all-features # Generate the `genesis.json` file using $TENDERMINT_RPC_URL in the `.env` file -genesis: - @echo "Generating the genesis file for the Celestia Mocha testnet" - @echo "Building the program..." - just build-programs +genesis: build-programs @echo "Generating the genesis file..." RUST_LOG=info cargo run --bin operator --release -- genesis -o contracts/script/genesis.json @@ -50,15 +47,18 @@ genesis: # The prover parameter should be one of: ["mock", "network", "local"] # This generates the fixtures for all programs in parallel using GNU parallel. # If prover is set to network, this command requires the `SP1_PRIVATE_KEY` environment variable to be set. -fixtures prover: - @echo "Generating fixtures for the Celestia Mocha testnet" - @echo "Building the operator..." - just build-operator +fixtures prover: build-operator @echo "Generating fixtures... This may take a while (up to 20 minutes)" + TENDERMINT_RPC_URL="${TENDERMINT_RPC_URL%/}" && \ + CURRENT_HEIGHT=$(curl "$TENDERMINT_RPC_URL"/block | jq -r ".result.block.header.height") && \ + TRUSTED_HEIGHT=$(($CURRENT_HEIGHT-100)) && \ + TARGET_HEIGHT=$(($CURRENT_HEIGHT-10)) && \ + echo "For celestia fixtures, trusted block: $TRUSTED_HEIGHT, target block: $TARGET_HEIGHT, from $TENDERMINT_RPC_URL" && \ parallel --progress --shebang --ungroup -j 4 ::: \ - "RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures update-client --trusted-block 2438000 --target-block 2438010 -o 'contracts/fixtures/update_client_fixture.json'" \ - "sleep 15 && RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures update-client-and-membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block 2438000 --target-block 2438010 -o 'contracts/fixtures/uc_and_memberships_fixture.json'" \ - "sleep 30 && RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block 2438000 -o 'contracts/fixtures/memberships_fixture.json'" + "RUST_LOG=info SP1_PROVER={{prover}} ./target/release/operator fixtures update-client --trusted-block $TRUSTED_HEIGHT --target-block $TARGET_HEIGHT -o 'contracts/fixtures/update_client_fixture.json'" \ + "sleep 15 && RUST_LOG=info SP1_PROVER={{prover}} ./target/release/operator fixtures update-client-and-membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block $TRUSTED_HEIGHT --target-block $TARGET_HEIGHT -o 'contracts/fixtures/uc_and_memberships_fixture.json'" \ + "sleep 30 && RUST_LOG=info SP1_PROVER={{prover}} ./target/release/operator fixtures membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block $TRUSTED_HEIGHT -o 'contracts/fixtures/memberships_fixture.json'" + cd e2e/interchaintestv8 && RUST_LOG=info SP1_PROVER=network GENERATE_FIXTURES=true go test -v -run '^TestWithSP1ICS07TendermintTestSuite/TestMisbehaviour$' -timeout 40m @echo "Fixtures generated at 'contracts/fixtures'" # Generate the `SP1ICS07Tendermint.json` file containing the ABI of the SP1ICS07Tendermint contract @@ -73,11 +73,9 @@ generate-abi: clean @echo "Done." # Deploy the SP1ICS07Tendermint contract to the Eth Sepolia testnet if the `.env` file is present -deploy-contracts: +deploy-contracts: genesis @echo "Deploying the SP1ICS07Tendermint contract" - just genesis cd contracts && forge install - @echo "Deploying the contract..." cd contracts && forge script script/SP1ICS07Tendermint.s.sol --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast # Run the operator using the `cargo run --bin operator` command. diff --git a/operator/src/runners/genesis.rs b/operator/src/runners/genesis.rs index 1fa1354..a11a9e9 100644 --- a/operator/src/runners/genesis.rs +++ b/operator/src/runners/genesis.rs @@ -4,7 +4,8 @@ use crate::{ cli::command::{genesis::Args, OutputPath}, helpers::light_block::LightBlockExt, programs::{ - MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, + MembershipProgram, MisbehaviourProgram, SP1Program, UpdateClientAndMembershipProgram, + UpdateClientProgram, }, rpc::TendermintRpcExt, }; @@ -15,7 +16,6 @@ use sp1_sdk::{utils::setup_logger, HashableKey}; use std::path::PathBuf; use tendermint_light_client_verifier::types::{LightBlock, TrustThreshold}; use tendermint_rpc::HttpClient; -use crate::programs::MisbehaviourProgram; /// The genesis data for the SP1 ICS07 Tendermint contract. #[serde_as] diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index d28f153..cf0725c 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -9,12 +9,12 @@ use ibc_client_tendermint::client_state::{ }; use ibc_client_tendermint::types::{ConsensusState, Misbehaviour, TENDERMINT_CLIENT_TYPE}; use ibc_core_host_types::identifiers::{ChainId, ClientId}; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint; use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{Env, MisbehaviourOutput}; use std::collections::HashMap; use std::time::Duration; use tendermint_light_client_verifier::options::Options; use tendermint_light_client_verifier::ProdVerifier; -use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint; /// The main function of the program without the zkVM wrapper. #[allow(clippy::missing_panics_doc)] @@ -68,18 +68,38 @@ pub fn check_for_misbehaviour( let is_misbehaviour = check_for_misbehaviour_on_misbehavior(misbehaviour.header1(), misbehaviour.header2()) .unwrap(); - + if !is_misbehaviour { panic!("Misbehaviour is not detected"); } - + let output_trusted_header_1 = sp1_ics07_tendermint::Height { - revisionNumber: misbehaviour.header1().trusted_height.revision_height().try_into().unwrap(), - revisionHeight: misbehaviour.header1().trusted_height.revision_height().try_into().unwrap(), + revisionNumber: misbehaviour + .header1() + .trusted_height + .revision_height() + .try_into() + .unwrap(), + revisionHeight: misbehaviour + .header1() + .trusted_height + .revision_height() + .try_into() + .unwrap(), }; let output_trusted_header_2 = sp1_ics07_tendermint::Height { - revisionNumber: misbehaviour.header2().trusted_height.revision_height().try_into().unwrap(), - revisionHeight: misbehaviour.header2().trusted_height.revision_height().try_into().unwrap(), + revisionNumber: misbehaviour + .header2() + .trusted_height + .revision_height() + .try_into() + .unwrap(), + revisionHeight: misbehaviour + .header2() + .trusted_height + .revision_height() + .try_into() + .unwrap(), }; MisbehaviourOutput { From 91aee687eebeb5506945120ea65967599c85f819 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 28 Aug 2024 14:17:33 +0200 Subject: [PATCH 06/22] some code cleanup --- .../fixtures/e2e_misbehaviour_fixture.json | 4 +- contracts/script/genesis.json | 2 +- e2e/interchaintestv8/operator/operator.go | 109 ++++++++++-------- e2e/interchaintestv8/sp1_ics07_test.go | 3 +- 4 files changed, 65 insertions(+), 53 deletions(-) diff --git a/contracts/fixtures/e2e_misbehaviour_fixture.json b/contracts/fixtures/e2e_misbehaviour_fixture.json index 15fd929..0698896 100644 --- a/contracts/fixtures/e2e_misbehaviour_fixture.json +++ b/contracts/fixtures/e2e_misbehaviour_fixture.json @@ -1,9 +1,9 @@ { "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf09678cae2908ce2eb6a969c64272dc4cea298152ea9b491e22f86705272fe3850847ae649bfac04d409aff0ff1dd38c4a9d69817ad288472dc21a1a6fc518bf0dd5a", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf10409a19ec0cae58f031797a0711efb75bdc8def4964f312bc154f08886b2969015b2e93fcf42a1d4e68c154e0cea2644ecb7f9b64d7da2a3c34dbc68ab13e124898", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", - "submitMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066cf09678cae2908ce2eb6a969c64272dc4cea298152ea9b491e22f86705272fe3850847ae649bfac04d409aff0ff1dd38c4a9d69817ad288472dc21a1a6fc518bf0dd5a0000000000000000000000000000000000000000000000000000000066cf09678cae2908ce2eb6a969c64272dc4cea298152ea9b491e22f86705272fe3850847ae649bfac04d409aff0ff1dd38c4a9d69817ad288472dc21a1a6fc518bf0dd5a00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275450000000000000000000000000000000000000000000000000000000066cf099e000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f2c475d6489bf52367abded5d9a63c1a7075f0e66cc15c803c6eb3759fdb84b97118825092de09b63f1877b0870201421acb8956d26ebad000d8fd96da15e5de520eaa4e3d3b35d56ae7b041c89fa2e4c743353e39f01b58a832acfe6bfc4efa406e82a0d7a712e50d5ebab7469b2aba030b2c7de5695417ee82f5edc858f35a11f29e6dcc9221e7a58fa309824faf18048ded2359602c4cb3350e5c81a8874171b4987b1b0161459631f893586c5c7ae5547dea84afc2064f506f6f397c4303b0079cb924277caba8533291edf5d8b27e83f6c6eeada73d16eeb387c14ef3dd01e179936800605ec63d19c9232c984988bcc0d50a6bb1c1698f2bddc5110e76305da22b6092fc44b6322ca976bfbef390027a840cc1846fa024eba75245e310601b847d2f4b4512d6b1c7c3498bb001695914decd521a3c42da901f36a31947f0875d57f7907daa8ac23aff39bc29c0a1fe926b348d22a775ba8935e115dd3712094d970d187141bca9e7e9130b09996699d54bc5ee5720f6cce777abddb5e9c1b3b67772f85d6ffd1ae7e1ecfba86e23c395733c140cb379f0efc79228f98e724cd2be63588e0f19d41ced2b09246f3d2df2c7570044a65ca21f6c8a883e3721ae42e23e7f573cb8c10c6d678fa71c75c2772563b4ec85890254b54997084092d53e0e8d91b652b084fbbc3970b69e7f990a0eac67ed1ab8806c28eb131856c2303b89495575664ed58dada3054425ee94218bc1c11ae89ca732c8a8beb36e82a5a6250c20baa64244129e234b3326e33d6ed1ee1310b3da1ae98134512a9e22a406b494a5a80cc156477fab07c2751f327e6eff977b3555a705c0de1278b011d81f76cc17ed256455139dd561bc7301882f215a39c5998f8d6f33d11c8e6c208bde0a3871f4aa6ac38035393090c979797a4d72958cc09767357b2a5a6653c0d74d9203227e0e9115547fe4f1d797df809d93d1917121acccbc9b3d851ee410d239333c1d1cf3ccf1ca8f2b2cfa32707f1eb414f709930dfe2b06a491f17d10946ff835b571d465d20f80402820f2d0c0b41f0f78ddb4ba4f3edf3d534ee0815b4c2f83a54b9df01f1273830e95f3c641502c81f80d06eb0738c1bf7b0ae441e0c47b262e203e07c35ba0e09547629b89a597dbbfe19d7c51c44b4488325441612380aa6955cd91ed698d7f351dadebc7ed2392904bf4aff482bda69978ee800000000000000000000000000000000000000000000000000000000" + "submitMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066cf10409a19ec0cae58f031797a0711efb75bdc8def4964f312bc154f08886b2969015b2e93fcf42a1d4e68c154e0cea2644ecb7f9b64d7da2a3c34dbc68ab13e1248980000000000000000000000000000000000000000000000000000000066cf10409a19ec0cae58f031797a0711efb75bdc8def4964f312bc154f08886b2969015b2e93fcf42a1d4e68c154e0cea2644ecb7f9b64d7da2a3c34dbc68ab13e12489800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275450000000000000000000000000000000000000000000000000000000066cf1078000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f1c303274c8e9d100c523417568eae554714a2652908710949e97fa6ae4cf31342efa1f2be87b456da9d6751fa612456e734c45f26bab77ef83e35a5a04de7b1a297b7dbc52729b1e92c203cb213053a7ddc6d512220f5c9006b652b107a67f021da702e963c0e7ba5cf4b3ab8725eee4753f27a7e967f1f6965e22e0224932661608e8ea662753313617ddfca5c0c361e83d3a3fa679d3209a219806ce8b7a65137f99444ba6b892aeb524a90b002305748a8f8fe2c4e72788c264769c8da21e13f1f9db9b5b1b326a63fdba9bf9ecffc6d898ec36df3b218bbcdc80f95978a60e15ab95476f974275e0e7708c73ea11e5a9487c4522e880200ea08d86810ba2124a486d6f0933cf481b44fc630454a24aa53436459afbc00ec7044ccc52f88e037361fbca83deb1e70d235a8e1d157263c608f06bad36f5a41331f151fbb86a131cf54bc2508ebd86fc1d533af1e7f1c253e87c2150ffec711f617e2c9029d815492a19d808e60679c6b92cae129c79f7c12560b9be794edff19595a7a9b35804edad6b8cee444822bbf4c0cec68f075e551b2612e75a575e45d36ccfca99fe2daf93d588bdb76fe98e69bd9a00df7b366c3a6358b6feca2e538f508bfb04e0142f1ea7642ff0da4ed766f00f70a50a16fd8b52b864684ef2dc02b5abfb6b0501146383fac2d08b9cc8c2371f571f27715c62d078500f9157911ebbd2147a6613c396b9229b868b72a11df1b1de87ac98f18b465fe925d5cd32fd07ba21ec302216b8c4d678e2da1e837bc2acf30030828b40f8e42da64f479a6636af289c1b22a6234749a13a5ab898fa1d79ffb3d567d129838bd95749d0884518d59a3e2f1561886cae462421e88d5b84ac5533dd72912e3c97a6d5b7afd393f246471d052678afcbc38fc52fae9fab3d70ca5e98bd32a2c1c0c275633a164c2b1f3a16161e47a62ab1886e9854cd795f7e5304f11935a6ceed332d181c2ca72ce6a1626c04789770ec0b2af31af078152067284f39b54bbebf4b3c53ef4c504c6875a8de13f65909aa6686b08ec38d466adda74a0aa5b2cd8c7ea89bbb2a8dfe8129a4a408b5f57a5038501c2724feb16a74077d5f4c6f475ccfa08fbd10a9626ec756420ff17a72170c8db16fb313aceb86e1f92bd26d2427282afa733c9f42783255923007b5b270972b6c10a3375ced3f7b5a89ef3cec145614a5fad0d1a837631c3e00000000000000000000000000000000000000000000000000000000" } diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index 9be412c..7d753e6 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,6 +1,6 @@ { "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0b40a268415ab138fceb78fb0b92a248b6b1780501936886b86aa6c13afd3bc179cb9b904acfe3b78177cea7f6f6264b55c12e3c086f40ed9ab8e30983519a8376d5", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf12d36de12352127b0ec4fc7b0b9288b9fe334e02ae24f4ed30c5bbefd739340a7219cf35fc3d539859ab32e51dfd1a36aa90046b162bf813abbec81facf0fc8cd480", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", diff --git a/e2e/interchaintestv8/operator/operator.go b/e2e/interchaintestv8/operator/operator.go index 3bcb2c0..fc7663d 100644 --- a/e2e/interchaintestv8/operator/operator.go +++ b/e2e/interchaintestv8/operator/operator.go @@ -20,14 +20,6 @@ import ( "github.com/srdtrk/sp1-ics07-tendermint/e2e/v8/types/sp1ics07tendermint" ) -// membershipFixture is a struct that contains the membership proof and proof height -type membershipFixture struct { - // hex encoded height - ProofHeight string `json:"proofHeight"` - // hex encoded proof - MembershipProof string `json:"membershipProof"` -} - type GenesisFixture struct { TrustedClientState string `json:"trustedClientState"` TrustedConsensusState string `json:"trustedConsensusState"` @@ -37,7 +29,16 @@ type GenesisFixture struct { MisbehaviourVKey string `json:"misbehaviourVKey"` } -type MisbehaviourFixture struct { +// membershipFixture is a struct that contains the membership proof and proof height +type membershipFixture struct { + GenesisFixture + // hex encoded height + ProofHeight string `json:"proofHeight"` + // hex encoded proof + MembershipProof string `json:"membershipProof"` +} + +type misbehaviourFixture struct { GenesisFixture SubmitMsg string `json:"submitMsg"` } @@ -117,10 +118,59 @@ func UpdateClientAndMembershipProof(trusted_height, target_height uint64, paths return height, proofBz, nil } +// Misbehaviour is a function that generates a misbehaviour proof and returns the submit message func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixture bool, args ...string) ([]byte, error) { + misbehaviourBz, err := marshalMisbehaviour(cdc, misbehaviour) + if err != nil { + return nil, err + } + + // write misbehaviour to file for the operator to use misbehaviourFileName := "misbehaviour.json" + if err := os.WriteFile(misbehaviourFileName, misbehaviourBz, 0o600); err != nil { + return nil, err + } + defer os.Remove(misbehaviourFileName) + args = append([]string{"fixtures", "misbehaviour", "--misbehaviour-path", misbehaviourFileName}, args...) + output, err := exec.Command("target/release/operator", args...).CombinedOutput() + if err != nil { + return nil, fmt.Errorf("operator misbehaviour failed: %w, output: %s", err, output) + } + + // eliminate non-json characters + jsonStartIdx := strings.Index(string(output), "{") + if jsonStartIdx == -1 { + panic("no json found in output") + } + output = output[jsonStartIdx:] + + var misbehaviourFixture misbehaviourFixture + err = json.Unmarshal(output, &misbehaviourFixture) + if err != nil { + return nil, err + } + + if writeFixture { + if err := os.WriteFile("contracts/fixtures/e2e_misbehaviour_fixture.json", output, 0o600); err != nil { + return nil, err + } + } + + submitMsgBz, err := hex.DecodeString(misbehaviourFixture.SubmitMsg) + if err != nil { + return nil, err + } + return submitMsgBz, nil +} + +// TODO: This is a mighty ugly piece of code. Hopefully there is a better way to do this. +// marshalMisbehaviour takes a Misbehaviour struct and marshals it into a JSON byte slice that can be unmarshalled by the operator. +// It first marshals to JSON directly, and then modifies all the incompatible types (mostly base64 encoded bytes) to be hex encoded. +// Ideally, we can update the types in the operator to be more compatible with the type we have here. +// It might be enough to get out a new version of the rust crate "ibc-proto" and update the operator to use it. +func marshalMisbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) ([]byte, error) { misbehaviour.ClientId = "07-tendermint-0" // We just have to set it to something to make the unmarshalling to work :P bzIntermediary, err := cdc.MarshalJSON(&misbehaviour) if err != nil { @@ -240,44 +290,5 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixt sig["validator_address"] = hex.EncodeToString(valAddressBz) } - misbehaviourBz, err := json.Marshal(jsonIntermediary) - if err != nil { - return nil, err - } - - // TODO: Make file temporary and delete it after use - if err := os.WriteFile(misbehaviourFileName, misbehaviourBz, 0o600); err != nil { - return nil, err - } - - output, err := exec.Command("target/release/operator", args...).CombinedOutput() - if err != nil { - return nil, fmt.Errorf("operator misbehaviour failed: %w, output: %s", err, output) - } - - // eliminate non-json characters - jsonStartIdx := strings.Index(string(output), "{") - if jsonStartIdx == -1 { - panic("no json found in output") - } - output = output[jsonStartIdx:] - - var misbehaviourFixture MisbehaviourFixture - err = json.Unmarshal(output, &misbehaviourFixture) - if err != nil { - return nil, err - } - - if writeFixture { - if err := os.WriteFile("contracts/fixtures/e2e_misbehaviour_fixture.json", output, 0o600); err != nil { - return nil, err - } - } - - submitMsgBz, err := hex.DecodeString(misbehaviourFixture.SubmitMsg) - if err != nil { - return nil, err - } - - return submitMsgBz, nil + return json.Marshal(jsonIntermediary) } diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index 879903a..91113ae 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -23,6 +23,7 @@ import ( cometproto "github.com/cometbft/cometbft/proto/tendermint/types" comettypes "github.com/cometbft/cometbft/types" comettime "github.com/cometbft/cometbft/types/time" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" ibcclientutils "github.com/cosmos/ibc-go/v8/modules/core/02-client/client/utils" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" @@ -337,7 +338,7 @@ func (s *SP1ICS07TendermintTestSuite) createTMClientHeader( // Make sure all the signers are in the correct order as expected by the validator set signers := make([]comettypes.PrivValidator, valSet.Size()) - for i, _ := range signers { + for i := range signers { _, val := valSet.GetByIndex(int32(i)) for _, pv := range privVals { From bf39613282d1c73a5ef0c6af1b74a8073e43ba61 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 28 Aug 2024 15:45:08 +0200 Subject: [PATCH 07/22] code cleanup --- .../fixtures/e2e_misbehaviour_fixture.json | 4 +- contracts/script/genesis.json | 2 +- e2e/interchaintestv8/e2esuite/utils.go | 135 ++++++++++++++ e2e/interchaintestv8/sp1_ics07_test.go | 176 ++++-------------- 4 files changed, 175 insertions(+), 142 deletions(-) diff --git a/contracts/fixtures/e2e_misbehaviour_fixture.json b/contracts/fixtures/e2e_misbehaviour_fixture.json index 0698896..074613d 100644 --- a/contracts/fixtures/e2e_misbehaviour_fixture.json +++ b/contracts/fixtures/e2e_misbehaviour_fixture.json @@ -1,9 +1,9 @@ { "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf10409a19ec0cae58f031797a0711efb75bdc8def4964f312bc154f08886b2969015b2e93fcf42a1d4e68c154e0cea2644ecb7f9b64d7da2a3c34dbc68ab13e124898", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf2589d6f58e945fde7fddc86e50aee4d66e9bdf8363621eb6fc2344567d77ce669999fb1ffbd155bc4f1ae1474837ad85ed946c0af8d7f4dec0590cddc6c4fcc2a0f8", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", - "submitMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066cf10409a19ec0cae58f031797a0711efb75bdc8def4964f312bc154f08886b2969015b2e93fcf42a1d4e68c154e0cea2644ecb7f9b64d7da2a3c34dbc68ab13e1248980000000000000000000000000000000000000000000000000000000066cf10409a19ec0cae58f031797a0711efb75bdc8def4964f312bc154f08886b2969015b2e93fcf42a1d4e68c154e0cea2644ecb7f9b64d7da2a3c34dbc68ab13e12489800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275450000000000000000000000000000000000000000000000000000000066cf1078000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f1c303274c8e9d100c523417568eae554714a2652908710949e97fa6ae4cf31342efa1f2be87b456da9d6751fa612456e734c45f26bab77ef83e35a5a04de7b1a297b7dbc52729b1e92c203cb213053a7ddc6d512220f5c9006b652b107a67f021da702e963c0e7ba5cf4b3ab8725eee4753f27a7e967f1f6965e22e0224932661608e8ea662753313617ddfca5c0c361e83d3a3fa679d3209a219806ce8b7a65137f99444ba6b892aeb524a90b002305748a8f8fe2c4e72788c264769c8da21e13f1f9db9b5b1b326a63fdba9bf9ecffc6d898ec36df3b218bbcdc80f95978a60e15ab95476f974275e0e7708c73ea11e5a9487c4522e880200ea08d86810ba2124a486d6f0933cf481b44fc630454a24aa53436459afbc00ec7044ccc52f88e037361fbca83deb1e70d235a8e1d157263c608f06bad36f5a41331f151fbb86a131cf54bc2508ebd86fc1d533af1e7f1c253e87c2150ffec711f617e2c9029d815492a19d808e60679c6b92cae129c79f7c12560b9be794edff19595a7a9b35804edad6b8cee444822bbf4c0cec68f075e551b2612e75a575e45d36ccfca99fe2daf93d588bdb76fe98e69bd9a00df7b366c3a6358b6feca2e538f508bfb04e0142f1ea7642ff0da4ed766f00f70a50a16fd8b52b864684ef2dc02b5abfb6b0501146383fac2d08b9cc8c2371f571f27715c62d078500f9157911ebbd2147a6613c396b9229b868b72a11df1b1de87ac98f18b465fe925d5cd32fd07ba21ec302216b8c4d678e2da1e837bc2acf30030828b40f8e42da64f479a6636af289c1b22a6234749a13a5ab898fa1d79ffb3d567d129838bd95749d0884518d59a3e2f1561886cae462421e88d5b84ac5533dd72912e3c97a6d5b7afd393f246471d052678afcbc38fc52fae9fab3d70ca5e98bd32a2c1c0c275633a164c2b1f3a16161e47a62ab1886e9854cd795f7e5304f11935a6ceed332d181c2ca72ce6a1626c04789770ec0b2af31af078152067284f39b54bbebf4b3c53ef4c504c6875a8de13f65909aa6686b08ec38d466adda74a0aa5b2cd8c7ea89bbb2a8dfe8129a4a408b5f57a5038501c2724feb16a74077d5f4c6f475ccfa08fbd10a9626ec756420ff17a72170c8db16fb313aceb86e1f92bd26d2427282afa733c9f42783255923007b5b270972b6c10a3375ced3f7b5a89ef3cec145614a5fad0d1a837631c3e00000000000000000000000000000000000000000000000000000000" + "submitMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066cf2589d6f58e945fde7fddc86e50aee4d66e9bdf8363621eb6fc2344567d77ce669999fb1ffbd155bc4f1ae1474837ad85ed946c0af8d7f4dec0590cddc6c4fcc2a0f80000000000000000000000000000000000000000000000000000000066cf2589d6f58e945fde7fddc86e50aee4d66e9bdf8363621eb6fc2344567d77ce669999fb1ffbd155bc4f1ae1474837ad85ed946c0af8d7f4dec0590cddc6c4fcc2a0f800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275450000000000000000000000000000000000000000000000000000000066cf25dd000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f1618d63a7e81bc96ba1ff0c537303708a96487a86cfae76053de08107abfcc0b108959f6bb5e16c70e0bf23dd999b3a3ef57336eed567d4430e41d4e954bde451ffa2e267944b7a238d42b3397203741f60870299c1fbb62a9022821506c942f033ba20256323b52d8aca13aab53b13a1e1c1fe1e5d55841a40fcc3217f50c162a8a43b5d17026545e1c66d40a5fddeb4ef08d2dae84242bd8d28881738b61362886ee779d9c6696ac1efb08f5f8e65cca5b806a2c8747ef1b7c712f65cbd35e088fc691143855d0bf646101cd0629632cb15c5f7b715d217761375d3194c44218ec8baf68ff0bd00485f348ea683e7e97368ba25be64ca17019e7307ef42b2d1d323c1a7a3b4ec84c112b02901ed7718f77ba35e02609deda4bb7b31d6119f414bef6804964fdac85418afcaeb2765bab4859100d84cb5ae2e0a1a7c56a44e211dbf869ad20f3b3ce16f69ea43278b3a0512ba09fea020f176990961e0f50f711e23ea32ea1963897b4f00ace029f37548f5eb3dfce595969d9b1bd154633712012bb578bbecd6519b4f2a15c1b2b9dff937c2976a54b1f1bddddf1c8178c382bc98a5b88d8f5a1ada806e538068a5b553bf1cc0078600ab653da886b9b83292e8ac25980d9b6febbd7c478e5f9a16d1066d14999127c6980d8f24428e948f722b425bd4fb2ecbe564ba6a1245111e1e1c1d6aff6afcf5379f25c5e20334afd153782b4de31ece69a899170c7807ac1c847c679c00337fb07c4861615d1ef320fc5b4075f4c45c9d0a9f1b97222e7c44044419c02cfedbd56ba36fa62e6d237011cb71c1ed583ea5f4569ba98e7f5e28a83bab983bfb55d3a5e8719ede8930516bd5082e2e6ce691bbc6f91eed08f2b4a86bc81becc7dda176dff3dc27c4fe91d804d197fc02fc3338d1e164275741f602c2489b702968060811247c2bb583e0ad1ac9ff5f59d5dfd454ca3542fb74135eaf6d0bb1ec01b52968db9a2aee5d40cc55f63f54ddd950d21052ceb02c8cdccf56524264812ab68dcf9641d2de9ad047586b7b74699783e2baf4dc320a930ebe50d06cad5110a4b75d5fd132d83dd01d00c2699a7c822e38e6e5546d5c3b6d0485d447d19b88d7ffe8753c697f58f1a541099f74bacb1d9670d9d19add724be7c73109a227e030713b0c6c6fe31ca04feabc7bdc03ba56d1d3836d80c2fa56cc81465fbc945a8c32a9e0a27b632ec00000000000000000000000000000000000000000000000000000000" } diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index 7d753e6..272efb7 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,6 +1,6 @@ { "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf12d36de12352127b0ec4fc7b0b9288b9fe334e02ae24f4ed30c5bbefd739340a7219cf35fc3d539859ab32e51dfd1a36aa90046b162bf813abbec81facf0fc8cd480", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf2589d6f58e945fde7fddc86e50aee4d66e9bdf8363621eb6fc2344567d77ce669999fb1ffbd155bc4f1ae1474837ad85ed946c0af8d7f4dec0590cddc6c4fcc2a0f8", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", diff --git a/e2e/interchaintestv8/e2esuite/utils.go b/e2e/interchaintestv8/e2esuite/utils.go index b5214c8..0a18e13 100644 --- a/e2e/interchaintestv8/e2esuite/utils.go +++ b/e2e/interchaintestv8/e2esuite/utils.go @@ -3,6 +3,8 @@ package e2esuite import ( "context" "crypto/ecdsa" + "encoding/base64" + "encoding/json" "fmt" "math/big" "regexp" @@ -18,8 +20,18 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cometbft/cometbft/crypto/tmhash" + cometproto "github.com/cometbft/cometbft/proto/tendermint/types" + comettypes "github.com/cometbft/cometbft/types" + comettime "github.com/cometbft/cometbft/types/time" + + tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + ibcmocks "github.com/cosmos/ibc-go/v8/testing/mock" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum" "github.com/strangelove-ventures/interchaintest/v8/ibc" @@ -139,3 +151,126 @@ func (s *TestSuite) GetTxReciept(ctx context.Context, chain *ethereum.EthereumCh s.Require().NoError(err) return receipt } + +// CreateTMClientHeader creates a new tendermint client header for the given chain, block height, and timestamp. +// It uses the given oldHeader as a base to create the new header with a new hash, and sign using the existing validators +// It can be used to for instance test misbehaviour +// Partially based on https://github.com/cosmos/relayer/blob/f9aaf3dd0ebfe99fbe98d190a145861d7df93804/interchaintest/misbehaviour_test.go#L38 +func (s *TestSuite) CreateTMClientHeader( + ctx context.Context, + chain *cosmos.CosmosChain, + blockHeight int64, + timestamp time.Time, + oldHeader tmclient.Header, +) tmclient.Header { + var privVals []comettypes.PrivValidator + var validators []*comettypes.Validator + for _, chainVal := range chain.Validators { + keyBz, err := chainVal.ReadFile(ctx, "config/priv_validator_key.json") + s.Require().NoError(err) + var privValidatorKeyFile cosmos.PrivValidatorKeyFile + err = json.Unmarshal(keyBz, &privValidatorKeyFile) + s.Require().NoError(err) + decodedKeyBz, err := base64.StdEncoding.DecodeString(privValidatorKeyFile.PrivKey.Value) + s.Require().NoError(err) + + privKey := &ed25519.PrivKey{ + Key: decodedKeyBz, + } + + privVal := ibcmocks.PV{PrivKey: privKey} + privVals = append(privVals, privVal) + + pubKey, err := privVal.GetPubKey() + s.Require().NoError(err) + + val := comettypes.NewValidator(pubKey, oldHeader.ValidatorSet.Proposer.VotingPower) + validators = append(validators, val) + + } + + valSet := comettypes.NewValidatorSet(validators) + vsetHash := valSet.Hash() + + // Make sure all the signers are in the correct order as expected by the validator set + signers := make([]comettypes.PrivValidator, valSet.Size()) + for i := range signers { + _, val := valSet.GetByIndex(int32(i)) + + for _, pv := range privVals { + pk, err := pv.GetPubKey() + s.Require().NoError(err) + + if pk.Equals(val.PubKey) { + signers[i] = pv + break + } + } + + if signers[i] == nil { + s.Require().FailNow("could not find signer for validator") + } + } + + tmHeader := comettypes.Header{ + Version: oldHeader.Header.Version, + ChainID: oldHeader.Header.ChainID, + Height: blockHeight, + Time: timestamp, + LastBlockID: ibctesting.MakeBlockID(make([]byte, tmhash.Size), 10_000, make([]byte, tmhash.Size)), + LastCommitHash: oldHeader.Header.LastCommitHash, + DataHash: tmhash.Sum([]byte("data_hash")), + ValidatorsHash: vsetHash, + NextValidatorsHash: vsetHash, + ConsensusHash: tmhash.Sum([]byte("consensus_hash")), + AppHash: tmhash.Sum([]byte("app_hash")), + LastResultsHash: tmhash.Sum([]byte("last_results_hash")), + EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + ProposerAddress: valSet.Proposer.Address, + } + + hhash := tmHeader.Hash() + blockID := ibctesting.MakeBlockID(hhash, oldHeader.Commit.BlockID.PartSetHeader.Total, tmhash.Sum([]byte("part_set"))) + voteSet := comettypes.NewVoteSet(oldHeader.Header.ChainID, blockHeight, 1, cometproto.PrecommitType, valSet) + + voteProto := &comettypes.Vote{ + ValidatorAddress: nil, + ValidatorIndex: -1, + Height: blockHeight, + Round: 1, + Timestamp: comettime.Now(), + Type: cometproto.PrecommitType, + BlockID: blockID, + } + + for i, sign := range signers { + pv, err := sign.GetPubKey() + s.Require().NoError(err) + addr := pv.Address() + vote := voteProto.Copy() + vote.ValidatorAddress = addr + vote.ValidatorIndex = int32(i) + _, err = comettypes.SignAndCheckVote(vote, sign, oldHeader.Header.ChainID, false) + s.Require().NoError(err) + added, err := voteSet.AddVote(vote) + s.Require().NoError(err) + s.Require().True(added) + } + extCommit := voteSet.MakeExtendedCommit(comettypes.DefaultABCIParams()) + commit := extCommit.ToCommit() + + signedHeader := &cometproto.SignedHeader{ + Header: tmHeader.ToProto(), + Commit: commit.ToProto(), + } + + valSetProto, err := valSet.ToProto() + s.Require().NoError(err) + + return tmclient.Header{ + SignedHeader: signedHeader, + ValidatorSet: valSetProto, + TrustedHeight: oldHeader.TrustedHeight, + TrustedValidators: oldHeader.TrustedValidators, + } +} diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index 91113ae..195f4fd 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -3,9 +3,7 @@ package main import ( "context" "crypto/ecdsa" - "encoding/base64" "encoding/hex" - "encoding/json" "os" "strconv" "testing" @@ -17,13 +15,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - - "github.com/cometbft/cometbft/crypto/tmhash" - cometproto "github.com/cometbft/cometbft/proto/tendermint/types" - comettypes "github.com/cometbft/cometbft/types" - comettime "github.com/cometbft/cometbft/types/time" - transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" ibcclientutils "github.com/cosmos/ibc-go/v8/modules/core/02-client/client/utils" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" @@ -31,9 +22,7 @@ import ( ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v8/testing" - ibcmocks "github.com/cosmos/ibc-go/v8/testing/mock" - "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/chain/ethereum/foundry" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testutil" @@ -188,6 +177,7 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClient() { })) } +// TestUpdateClientAndMembership tests the update client and membership functionality func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership() { ctx := context.Background() @@ -244,6 +234,8 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership() { })) } +// TestMisbehaviour tests the misbehaviour functionality +// Partially based on https://github.com/cosmos/relayer/blob/f9aaf3dd0ebfe99fbe98d190a145861d7df93804/interchaintest/misbehaviour_test.go#L38 func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { ctx := context.Background() @@ -252,31 +244,56 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { eth, simd := s.ChainA, s.ChainB _ = eth - s.Require().True(s.Run("Misbehave", func() { - // Based off of: https://github.com/cosmos/relayer/blob/f9aaf3dd0ebfe99fbe98d190a145861d7df93804/interchaintest/misbehaviour_test.go#L38 - oldHeader, latestHeight, err := ibcclientutils.QueryTendermintHeader(simd.Validators[0].CliContext()) + var height clienttypes.Height + var oldHeader tmclient.Header + s.Require().True(s.Run("Get old header", func() { + var latestHeight int64 + var err error + oldHeader, latestHeight, err = ibcclientutils.QueryTendermintHeader(simd.Validators[0].CliContext()) s.Require().NoError(err) s.Require().NotZero(latestHeight) - height := clienttypes.NewHeight(clienttypes.ParseChainID(simd.Config().ChainID), uint64(latestHeight)) + height = clienttypes.NewHeight(clienttypes.ParseChainID(simd.Config().ChainID), uint64(latestHeight)) clientState, err := s.contract.GetClientState(nil) s.Require().NoError(err) trustedHeight := clienttypes.NewHeight(uint64(clientState.LatestHeight.RevisionNumber), uint64(clientState.LatestHeight.RevisionHeight)) oldHeader.TrustedHeight = trustedHeight - oldHeader.TrustedValidators = oldHeader.ValidatorSet // ? - s.Require().NoError(err) + oldHeader.TrustedValidators = oldHeader.ValidatorSet + })) + + s.Require().True(s.Run("Invalid misbehaviour", func() { + // Create a new valid header + newHeader := s.CreateTMClientHeader( + ctx, + simd, + int64(height.RevisionHeight+1), + oldHeader.GetTime().Add(time.Minute), + oldHeader, + ) + + invalidMisbehaviour := tmclient.Misbehaviour{ + Header1: &newHeader, + Header2: &oldHeader, + } + // The proof should fail because this is not misbehaviour (valid header for a new block) + _, err := operator.Misbehaviour(simd.GetCodec(), invalidMisbehaviour, false, + "--trust-level", testvalues.DefaultTrustLevel.String(), + "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod)) + s.Require().ErrorContains(err, "Misbehaviour is not detected") + })) + + s.Require().True(s.Run("Valid misbehaviour", func() { // create a duplicate header (with a different hash) - newHeader := s.createTMClientHeader( + newHeader := s.CreateTMClientHeader( ctx, simd, int64(height.RevisionHeight), oldHeader.GetTime().Add(time.Minute), oldHeader, ) - _ = newHeader misbehaviour := tmclient.Misbehaviour{ Header1: &newHeader, @@ -294,127 +311,8 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { // wait until transaction is included in a block _ = s.GetTxReciept(ctx, eth.EthereumChain, tx.Hash()) - clientState, err = s.contract.GetClientState(nil) + clientState, err := s.contract.GetClientState(nil) s.Require().NoError(err) s.Require().True(clientState.IsFrozen) })) } - -func (s *SP1ICS07TendermintTestSuite) createTMClientHeader( - ctx context.Context, - chain *cosmos.CosmosChain, - blockHeight int64, - timestamp time.Time, - oldHeader tmclient.Header, -) tmclient.Header { - var privVals []comettypes.PrivValidator - var validators []*comettypes.Validator - for _, chainVal := range chain.Validators { - keyBz, err := chainVal.ReadFile(ctx, "config/priv_validator_key.json") - s.Require().NoError(err) - var privValidatorKeyFile cosmos.PrivValidatorKeyFile - err = json.Unmarshal(keyBz, &privValidatorKeyFile) - s.Require().NoError(err) - decodedKeyBz, err := base64.StdEncoding.DecodeString(privValidatorKeyFile.PrivKey.Value) - s.Require().NoError(err) - - privKey := &ed25519.PrivKey{ - Key: decodedKeyBz, - } - - privVal := ibcmocks.PV{PrivKey: privKey} - privVals = append(privVals, privVal) - - pubKey, err := privVal.GetPubKey() - s.Require().NoError(err) - - val := comettypes.NewValidator(pubKey, oldHeader.ValidatorSet.Proposer.VotingPower) - validators = append(validators, val) - - } - - valSet := comettypes.NewValidatorSet(validators) - vsetHash := valSet.Hash() - - // Make sure all the signers are in the correct order as expected by the validator set - signers := make([]comettypes.PrivValidator, valSet.Size()) - for i := range signers { - _, val := valSet.GetByIndex(int32(i)) - - for _, pv := range privVals { - pk, err := pv.GetPubKey() - s.Require().NoError(err) - - if pk.Equals(val.PubKey) { - signers[i] = pv - break - } - } - - if signers[i] == nil { - s.Require().FailNow("could not find signer for validator") - } - } - - tmHeader := comettypes.Header{ - Version: oldHeader.Header.Version, - ChainID: oldHeader.Header.ChainID, - Height: blockHeight, - Time: timestamp, - LastBlockID: ibctesting.MakeBlockID(make([]byte, tmhash.Size), 10_000, make([]byte, tmhash.Size)), - LastCommitHash: oldHeader.Header.LastCommitHash, - DataHash: tmhash.Sum([]byte("data_hash")), - ValidatorsHash: vsetHash, - NextValidatorsHash: vsetHash, - ConsensusHash: tmhash.Sum([]byte("consensus_hash")), - AppHash: tmhash.Sum([]byte("app_hash")), - LastResultsHash: tmhash.Sum([]byte("last_results_hash")), - EvidenceHash: tmhash.Sum([]byte("evidence_hash")), - ProposerAddress: valSet.Proposer.Address, - } - - hhash := tmHeader.Hash() - blockID := ibctesting.MakeBlockID(hhash, oldHeader.Commit.BlockID.PartSetHeader.Total, tmhash.Sum([]byte("part_set"))) - voteSet := comettypes.NewVoteSet(oldHeader.Header.ChainID, blockHeight, 1, cometproto.PrecommitType, valSet) - - voteProto := &comettypes.Vote{ - ValidatorAddress: nil, - ValidatorIndex: -1, - Height: blockHeight, - Round: 1, - Timestamp: comettime.Now(), - Type: cometproto.PrecommitType, - BlockID: blockID, - } - - for i, sign := range signers { - pv, err := sign.GetPubKey() - s.Require().NoError(err) - addr := pv.Address() - vote := voteProto.Copy() - vote.ValidatorAddress = addr - vote.ValidatorIndex = int32(i) - _, err = comettypes.SignAndCheckVote(vote, sign, oldHeader.Header.ChainID, false) - s.Require().NoError(err) - added, err := voteSet.AddVote(vote) - s.Require().NoError(err) - s.Require().True(added) - } - extCommit := voteSet.MakeExtendedCommit(comettypes.DefaultABCIParams()) - commit := extCommit.ToCommit() - - signedHeader := &cometproto.SignedHeader{ - Header: tmHeader.ToProto(), - Commit: commit.ToProto(), - } - - valSetProto, err := valSet.ToProto() - s.Require().NoError(err) - - return tmclient.Header{ - SignedHeader: signedHeader, - ValidatorSet: valSetProto, - TrustedHeight: oldHeader.TrustedHeight, - TrustedValidators: oldHeader.TrustedValidators, - } -} From 5f750fa3c84154b4f9dc4af9bc85eb7d2cb5a709 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 28 Aug 2024 16:29:05 +0200 Subject: [PATCH 08/22] added clippy linting --- justfile | 2 ++ operator/src/runners/fixtures/misbehaviour.rs | 2 ++ packages/solidity/src/lib.rs | 2 +- programs/misbehaviour/src/lib.rs | 8 +++----- programs/misbehaviour/src/main.rs | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/justfile b/justfile index 82260fc..a182351 100644 --- a/justfile +++ b/justfile @@ -94,6 +94,7 @@ test-e2e testname: lint: @echo "Linting the Rust code..." cargo fmt --all -- --check + cargo clippy @echo "Linting the Solidity code..." forge fmt --check && bun solhint -w 0 -c .solhint.json 'contracts/**/*.sol' && bun natspec-smells --enforceInheritdoc false --include 'contracts/src/**/*.sol' @echo "Linting the Go code..." @@ -103,6 +104,7 @@ lint: lint-fix: @echo "Fixing the Rust code..." cargo fmt --all + cargo clippy --fix @echo "Fixing the Solidity code..." forge fmt && bun solhint -w 0 -c .solhint.json 'contracts/**/*.sol' && bun natspec-smells --enforceInheritdoc false --include 'contracts/src/**/*.sol' @echo "Fixing the Go code..." diff --git a/operator/src/runners/fixtures/misbehaviour.rs b/operator/src/runners/fixtures/misbehaviour.rs index 3b9e244..7adc521 100644 --- a/operator/src/runners/fixtures/misbehaviour.rs +++ b/operator/src/runners/fixtures/misbehaviour.rs @@ -42,6 +42,7 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { let raw_misbehaviour: RawMisbehaviour = serde_json::from_slice(&misbehaviour_bz)?; let tm_rpc_client = HttpClient::from_env(); + #[allow(clippy::cast_possible_truncation)] let trusted_light_block_1 = tm_rpc_client .get_light_block(Some( raw_misbehaviour @@ -53,6 +54,7 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { .revision_height as u32, )) .await?; + #[allow(clippy::cast_possible_truncation)] let trusted_light_block_2 = tm_rpc_client .get_light_block(Some( raw_misbehaviour diff --git a/packages/solidity/src/lib.rs b/packages/solidity/src/lib.rs index accf8f2..b0cdd32 100644 --- a/packages/solidity/src/lib.rs +++ b/packages/solidity/src/lib.rs @@ -13,7 +13,7 @@ use time::OffsetDateTime; alloy_sol_types::sol!( #[sol(rpc)] #[derive(serde::Deserialize, serde::Serialize)] - #[allow(missing_docs, clippy::pedantic)] + #[allow(missing_docs, clippy::pedantic, warnings)] sp1_ics07_tendermint, "../../contracts/abi/SP1ICS07Tendermint.json" ); diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index cf0725c..62bad0f 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -21,7 +21,7 @@ use tendermint_light_client_verifier::ProdVerifier; #[must_use] pub fn check_for_misbehaviour( env: Env, - misbehaviour: Misbehaviour, + misbehaviour: &Misbehaviour, trusted_consensus_state_1: ConsensusState, trusted_consensus_state_2: ConsensusState, ) -> MisbehaviourOutput { @@ -57,7 +57,7 @@ pub fn check_for_misbehaviour( verify_misbehaviour::<_, sha2::Sha256>( &ctx, - &misbehaviour, + misbehaviour, &client_id, &ChainId::new(chain_id.as_str()).unwrap(), &options, @@ -69,9 +69,7 @@ pub fn check_for_misbehaviour( check_for_misbehaviour_on_misbehavior(misbehaviour.header1(), misbehaviour.header2()) .unwrap(); - if !is_misbehaviour { - panic!("Misbehaviour is not detected"); - } + assert!(is_misbehaviour, "Misbehaviour is not detected"); let output_trusted_header_1 = sp1_ics07_tendermint::Height { revisionNumber: misbehaviour diff --git a/programs/misbehaviour/src/main.rs b/programs/misbehaviour/src/main.rs index 7aee4b7..4963f1b 100644 --- a/programs/misbehaviour/src/main.rs +++ b/programs/misbehaviour/src/main.rs @@ -41,7 +41,7 @@ pub fn main() { let output = check_for_misbehaviour( env, - misbehaviour, + &misbehaviour, trusted_consensus_state_1, trusted_consensus_state_2, ); From c9cbfb30b8c89929855604343802f7431acb05d5 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 28 Aug 2024 16:29:23 +0200 Subject: [PATCH 09/22] Added misbehaviour program to ci build pipeline --- .github/workflows/programs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/programs.yml b/.github/workflows/programs.yml index d7ea617..921c1d1 100644 --- a/.github/workflows/programs.yml +++ b/.github/workflows/programs.yml @@ -16,6 +16,7 @@ jobs: - programs/update-client - programs/membership - programs/uc-and-membership + - programs/misbehaviour name: 'build: ${{ matrix.programs }}' runs-on: ubuntu-latest steps: From 4f3864e0ef1ab2dc3415a0d0521467c876535362 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 28 Aug 2024 16:49:15 +0200 Subject: [PATCH 10/22] fix cargo setups for misbehaviour --- .github/workflows/rust.yml | 2 +- Cargo.toml | 2 ++ justfile | 2 +- operator/build.rs | 8 ++++++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8a6129f..8ccc5bc 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -87,4 +87,4 @@ jobs: uses: actions-rs/cargo@v1 with: command: build - args: --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership --exclude sp1-ics07-tendermint-uc-and-membership --all-features --locked + args: --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership --exclude sp1-ics07-tendermint-uc-and-membership --exclude sp1-ics07-tendermint-misbehaviour --all-features --locked diff --git a/Cargo.toml b/Cargo.toml index e5d3b85..f7d5ba4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,8 @@ sp1-zkvm = "1.1" sp1-ics07-tendermint-solidity = { path = "./packages/solidity/" } sp1-ics07-tendermint-update-client = { path = "./programs/update-client/" } sp1-ics07-tendermint-membership = { path = "./programs/membership/" } +sp1-ics07-tendermint-uc-and-membership = { path = "./programs/uc-and-membership/" } +sp1-ics07-tendermint-misbehaviour = { path = "./programs/misbehaviour/" } # ibc-proto ibc-proto = { version = "0.47", default-features = false } diff --git a/justfile b/justfile index a182351..d1ce2a6 100644 --- a/justfile +++ b/justfile @@ -36,7 +36,7 @@ test-foundry testname=".\\*": # Run the Rust tests using `cargo test` command (excluding the sp1-ics07-tendermint-update-client crate) test-cargo: - cargo test --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership --exclude sp1-ics07-tendermint-uc-and-membership --locked --all-features + cargo test --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership --exclude sp1-ics07-tendermint-uc-and-membership --exclude sp1-ics07-tendermint-misbehaviour --locked --all-features # Generate the `genesis.json` file using $TENDERMINT_RPC_URL in the `.env` file genesis: build-programs diff --git a/operator/build.rs b/operator/build.rs index 40e6607..737257a 100644 --- a/operator/build.rs +++ b/operator/build.rs @@ -29,4 +29,12 @@ fn main() { ..Default::default() }, ); + + build_program_with_args( + "../programs/misbehaviour", + BuildArgs { + elf_name: "misbehaviour-riscv32im-succinct-zkvm-elf".to_string(), + ..Default::default() + }, + ) } From 46dfe66e60a679cdc066f661933d473e1d205303 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 28 Aug 2024 17:24:22 +0200 Subject: [PATCH 11/22] lint and add e2e test to ci --- .github/workflows/e2e.yml | 1 + operator/build.rs | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 3078f48..9607972 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -41,6 +41,7 @@ jobs: - TestWithSP1ICS07TendermintTestSuite/TestDeploy - TestWithSP1ICS07TendermintTestSuite/TestUpdateClient - TestWithSP1ICS07TendermintTestSuite/TestUpdateClientAndMembership + - TestWithSP1ICS07TendermintTestSuite/TestMisbehaviour name: ${{ matrix.test }} runs-on: ubuntu-latest steps: diff --git a/operator/build.rs b/operator/build.rs index 737257a..6e764ba 100644 --- a/operator/build.rs +++ b/operator/build.rs @@ -11,7 +11,6 @@ fn main() { ..Default::default() }, ); - // Build the membership program. build_program_with_args( "../programs/membership", @@ -20,7 +19,6 @@ fn main() { ..Default::default() }, ); - // Build the uc-and-membership program. build_program_with_args( "../programs/uc-and-membership", @@ -29,7 +27,7 @@ fn main() { ..Default::default() }, ); - + // Build the misbehaviour program. build_program_with_args( "../programs/misbehaviour", BuildArgs { From 588f5800f8dd19298b11b7eb4b138fbe3f0c4063 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Fri, 30 Aug 2024 12:27:44 +0200 Subject: [PATCH 12/22] Update programs/misbehaviour/src/lib.rs Co-authored-by: Aditya <14364734+AdityaSripal@users.noreply.github.com> --- programs/misbehaviour/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index 62bad0f..0cb4577 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -37,6 +37,8 @@ pub fn check_for_misbehaviour( .to_string() ); + // Insert the two trusted consensus states into the trusted consensus state map that exists in the ClientValidationContext that is expected by verifyMisbehaviour + // Since we are mocking the existence of prior trusted consensus states, we are only filling in the two consensus states that are passed in into the map let mut trusted_consensus_state_map = HashMap::new(); trusted_consensus_state_map.insert( misbehaviour.header1().trusted_height.revision_height(), From df06cd898ef79e8d9805a09af6e964047bcd0339 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Fri, 30 Aug 2024 12:28:01 +0200 Subject: [PATCH 13/22] Update programs/misbehaviour/src/lib.rs Co-authored-by: Aditya <14364734+AdityaSripal@users.noreply.github.com> --- programs/misbehaviour/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index 0cb4577..6e28b0f 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -57,6 +57,7 @@ pub fn check_for_misbehaviour( clock_drift: Duration::default(), }; + // Call into ibc-rs verify_misbehaviour function to verify that both headers are valid given their respective trusted consensus states verify_misbehaviour::<_, sha2::Sha256>( &ctx, misbehaviour, From f36b5967a4ea631fdfee6cefa5ebffb889af95bc Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Fri, 30 Aug 2024 12:28:15 +0200 Subject: [PATCH 14/22] Update programs/misbehaviour/src/lib.rs Co-authored-by: Aditya <14364734+AdityaSripal@users.noreply.github.com> --- programs/misbehaviour/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index 6e28b0f..cf0f293 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -68,6 +68,8 @@ pub fn check_for_misbehaviour( ) .unwrap(); + // Call into ibc-rs check_for_misbehaviour_on_misbehaviour method to ensure that the misbehaviour is valid + // i.e. the headers are same height but different commits, or headers are not monotonically increasing in time let is_misbehaviour = check_for_misbehaviour_on_misbehavior(misbehaviour.header1(), misbehaviour.header2()) .unwrap(); From f0d9b708f35eef3ab967a791585a6215670fb70e Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Fri, 30 Aug 2024 12:28:37 +0200 Subject: [PATCH 15/22] Update programs/misbehaviour/src/lib.rs Co-authored-by: Aditya <14364734+AdityaSripal@users.noreply.github.com> --- programs/misbehaviour/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index cf0f293..a579917 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -105,6 +105,9 @@ pub fn check_for_misbehaviour( .unwrap(), }; + // The prover takes in the trusted headers as an input but does not maintain its own internal state + // Thus, the verifier must ensure that the trusted headers that were used in the proof are trusted consensus + // states stored in its own internal state before it can accept the misbehaviour proof as valid. MisbehaviourOutput { env, trustedHeight1: output_trusted_header_1, From aff47ccd685d58fb3a83cfbd0bdf699c1709127e Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Fri, 30 Aug 2024 12:41:53 +0200 Subject: [PATCH 16/22] pr review fixes --- contracts/src/SP1ICS07Tendermint.sol | 4 ++++ justfile | 4 ++-- operator/src/runners/fixtures/misbehaviour.rs | 9 +++++++++ programs/misbehaviour/src/lib.rs | 12 ++++++------ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/contracts/src/SP1ICS07Tendermint.sol b/contracts/src/SP1ICS07Tendermint.sol index e140820..ea02b4d 100644 --- a/contracts/src/SP1ICS07Tendermint.sol +++ b/contracts/src/SP1ICS07Tendermint.sol @@ -366,12 +366,16 @@ contract SP1ICS07Tendermint is } validateEnv(output.env); + // make sure the trusted consensus state from header 1 is known (trusted) by matching it with the the one in the + // mapping bytes32 outputConsensusStateHash1 = keccak256(abi.encode(output.trustedConsensusState1)); bytes32 trustedConsensusState1 = getConsensusStateHash(output.trustedHeight1.revisionHeight); if (outputConsensusStateHash1 != trustedConsensusState1) { revert ConsensusStateHashMismatch(trustedConsensusState1, outputConsensusStateHash1); } + // make sure the trusted consensus state from header 2 is known (trusted) by matching it with the the one in the + // mapping bytes32 outputConsensusStateHash2 = keccak256(abi.encode(output.trustedConsensusState2)); bytes32 trustedConsensusState2 = getConsensusStateHash(output.trustedHeight2.revisionHeight); if (outputConsensusStateHash2 != trustedConsensusState2) { diff --git a/justfile b/justfile index d1ce2a6..b14a056 100644 --- a/justfile +++ b/justfile @@ -100,11 +100,11 @@ lint: @echo "Linting the Go code..." cd e2e/interchaintestv8 && golangci-lint run -# Fix the Rust, Solidity, and Go code using `cargo fmt`, `forge fmt`, and `golanci-lint` commands +# Fix the Rust, Solidity, and Go code using `cargo fmt`, `forge fmt`, 'clippy' and `golanci-lint` commands lint-fix: @echo "Fixing the Rust code..." cargo fmt --all - cargo clippy --fix + cargo clippy --fix --allow-dirty @echo "Fixing the Solidity code..." forge fmt && bun solhint -w 0 -c .solhint.json 'contracts/**/*.sol' && bun natspec-smells --enforceInheritdoc false --include 'contracts/src/**/*.sol' @echo "Fixing the Go code..." diff --git a/operator/src/runners/fixtures/misbehaviour.rs b/operator/src/runners/fixtures/misbehaviour.rs index 7adc521..eaa9fe2 100644 --- a/operator/src/runners/fixtures/misbehaviour.rs +++ b/operator/src/runners/fixtures/misbehaviour.rs @@ -42,6 +42,8 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { let raw_misbehaviour: RawMisbehaviour = serde_json::from_slice(&misbehaviour_bz)?; let tm_rpc_client = HttpClient::from_env(); + + // get light block for trusted height of header 1 #[allow(clippy::cast_possible_truncation)] let trusted_light_block_1 = tm_rpc_client .get_light_block(Some( @@ -55,6 +57,7 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { )) .await?; #[allow(clippy::cast_possible_truncation)] + // get light block for trusted height of header 2 let trusted_light_block_2 = tm_rpc_client .get_light_block(Some( raw_misbehaviour @@ -67,12 +70,14 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { )) .await?; + // use trusted light block 1 to instantiate a new SP1 tendermint client with light block 1 as initial trusted consensus state let genesis_1 = SP1ICS07TendermintGenesis::from_env( &trusted_light_block_1, args.trust_options.trusting_period, args.trust_options.trust_level, ) .await?; + // use trusted light block 2 to instantiate a new SP1 tendermint client with light block 2 as initial trusted consensus state let genesis_2 = SP1ICS07TendermintGenesis::from_env( &trusted_light_block_2, args.trust_options.trusting_period, @@ -80,14 +85,18 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { ) .await?; + // use the clients to convert the Tendermint light blocks into the IBC Tendermint trusted consensus states let trusted_consensus_state_1 = ConsensusState::abi_decode(&genesis_1.trusted_consensus_state, false)?; let trusted_consensus_state_2 = ConsensusState::abi_decode(&genesis_2.trusted_consensus_state, false)?; + + // ise the client state from genesis_2 as the client state since they will both be the same let trusted_client_state_2 = ClientState::abi_decode(&genesis_2.trusted_client_state, false)?; let verify_misbehaviour_prover = SP1ICS07TendermintProver::::default(); + // construct contract env from the client state, which will be used by the light client contract let contract_env = Env { chainId: trusted_light_block_2.chain_id()?.to_string(), trustThreshold: trusted_client_state_2.trustLevel, diff --git a/programs/misbehaviour/src/lib.rs b/programs/misbehaviour/src/lib.rs index a579917..ea36766 100644 --- a/programs/misbehaviour/src/lib.rs +++ b/programs/misbehaviour/src/lib.rs @@ -37,8 +37,8 @@ pub fn check_for_misbehaviour( .to_string() ); - // Insert the two trusted consensus states into the trusted consensus state map that exists in the ClientValidationContext that is expected by verifyMisbehaviour - // Since we are mocking the existence of prior trusted consensus states, we are only filling in the two consensus states that are passed in into the map + // Insert the two trusted consensus states into the trusted consensus state map that exists in the ClientValidationContext that is expected by verifyMisbehaviour + // Since we are mocking the existence of prior trusted consensus states, we are only filling in the two consensus states that are passed in into the map let mut trusted_consensus_state_map = HashMap::new(); trusted_consensus_state_map.insert( misbehaviour.header1().trusted_height.revision_height(), @@ -76,7 +76,7 @@ pub fn check_for_misbehaviour( assert!(is_misbehaviour, "Misbehaviour is not detected"); - let output_trusted_header_1 = sp1_ics07_tendermint::Height { + let output_trusted_height_1 = sp1_ics07_tendermint::Height { revisionNumber: misbehaviour .header1() .trusted_height @@ -90,7 +90,7 @@ pub fn check_for_misbehaviour( .try_into() .unwrap(), }; - let output_trusted_header_2 = sp1_ics07_tendermint::Height { + let output_trusted_height_2 = sp1_ics07_tendermint::Height { revisionNumber: misbehaviour .header2() .trusted_height @@ -110,8 +110,8 @@ pub fn check_for_misbehaviour( // states stored in its own internal state before it can accept the misbehaviour proof as valid. MisbehaviourOutput { env, - trustedHeight1: output_trusted_header_1, - trustedHeight2: output_trusted_header_2, + trustedHeight1: output_trusted_height_1, + trustedHeight2: output_trusted_height_2, trustedConsensusState1: trusted_consensus_state_1.into(), trustedConsensusState2: trusted_consensus_state_2.into(), } From b7b8d0ef2afb8e1a89acbc118922ddc6e7b1a459 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Tue, 3 Sep 2024 10:18:10 +0200 Subject: [PATCH 17/22] Update operator/src/runners/fixtures/misbehaviour.rs Co-authored-by: Aditya <14364734+AdityaSripal@users.noreply.github.com> --- operator/src/runners/fixtures/misbehaviour.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operator/src/runners/fixtures/misbehaviour.rs b/operator/src/runners/fixtures/misbehaviour.rs index eaa9fe2..d4dc29c 100644 --- a/operator/src/runners/fixtures/misbehaviour.rs +++ b/operator/src/runners/fixtures/misbehaviour.rs @@ -91,7 +91,7 @@ pub async fn run(args: MisbehaviourCmd) -> anyhow::Result<()> { let trusted_consensus_state_2 = ConsensusState::abi_decode(&genesis_2.trusted_consensus_state, false)?; - // ise the client state from genesis_2 as the client state since they will both be the same + // use the client state from genesis_2 as the client state since they will both be the same let trusted_client_state_2 = ClientState::abi_decode(&genesis_2.trusted_client_state, false)?; let verify_misbehaviour_prover = SP1ICS07TendermintProver::::default(); From 5676c8e9a3ff0cecb2708a5dafbe78e1fc61214c Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Tue, 3 Sep 2024 12:36:00 +0200 Subject: [PATCH 18/22] Update e2e/interchaintestv8/sp1_ics07_test.go Co-authored-by: Carlos Rodriguez --- e2e/interchaintestv8/sp1_ics07_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index 195f4fd..e685a32 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -186,7 +186,7 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership() { eth, simd := s.ChainA, s.ChainB if s.generateFixtures { - s.T().Log("Generate fixtures is set to true, but TestUpdateClient does not support it (yet)") + s.T().Log("Generate fixtures is set to true, but TestUpdateClientAndMembership does not support it (yet)") } s.Require().True(s.Run("Update and verify non-membership", func() { From 894781597e6e92a5b4ce56d40405ddf9911897b9 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Tue, 3 Sep 2024 12:39:39 +0200 Subject: [PATCH 19/22] code review fixes --- ...fixture.json => misbehaviour_fixture.json} | 0 contracts/test/Misbehaviour.t.sol | 6 ++-- e2e/interchaintestv8/operator/operator.go | 26 ++++++++--------- e2e/interchaintestv8/sp1_ics07_test.go | 28 +++++++++---------- 4 files changed, 30 insertions(+), 30 deletions(-) rename contracts/fixtures/{e2e_misbehaviour_fixture.json => misbehaviour_fixture.json} (100%) diff --git a/contracts/fixtures/e2e_misbehaviour_fixture.json b/contracts/fixtures/misbehaviour_fixture.json similarity index 100% rename from contracts/fixtures/e2e_misbehaviour_fixture.json rename to contracts/fixtures/misbehaviour_fixture.json diff --git a/contracts/test/Misbehaviour.t.sol b/contracts/test/Misbehaviour.t.sol index 9d19189..6291008 100644 --- a/contracts/test/Misbehaviour.t.sol +++ b/contracts/test/Misbehaviour.t.sol @@ -24,9 +24,9 @@ contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { Env public env; function setUp() public { - fixture = loadFixture("e2e_misbehaviour_fixture.json"); + fixture = loadFixture("misbehaviour_fixture.json"); - setUpTest("e2e_misbehaviour_fixture.json"); + setUpTest("misbehaviour_fixture.json"); submitMsg = abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); output = abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); @@ -52,7 +52,7 @@ contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { function test_ValidMisbehaviour() public { // set a correct timestamp - vm.warp(env.now + 300); + vm.warp(env.now); ics07Tendermint.misbehaviour(fixture.submitMsg); // to console diff --git a/e2e/interchaintestv8/operator/operator.go b/e2e/interchaintestv8/operator/operator.go index fc7663d..2e87269 100644 --- a/e2e/interchaintestv8/operator/operator.go +++ b/e2e/interchaintestv8/operator/operator.go @@ -118,8 +118,8 @@ func UpdateClientAndMembershipProof(trusted_height, target_height uint64, paths return height, proofBz, nil } -// Misbehaviour is a function that generates a misbehaviour proof and returns the submit message -func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixture bool, args ...string) ([]byte, error) { +// MisbehaviourProof is a function that generates a misbehaviour proof and returns the submit message +func MisbehaviourProof(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixture bool, args ...string) ([]byte, error) { misbehaviourBz, err := marshalMisbehaviour(cdc, misbehaviour) if err != nil { return nil, err @@ -152,7 +152,7 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixt } if writeFixture { - if err := os.WriteFile("contracts/fixtures/e2e_misbehaviour_fixture.json", output, 0o600); err != nil { + if err := os.WriteFile("contracts/fixtures/misbehaviour_fixture.json", output, 0o600); err != nil { return nil, err } } @@ -166,7 +166,7 @@ func Misbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixt } // TODO: This is a mighty ugly piece of code. Hopefully there is a better way to do this. -// marshalMisbehaviour takes a Misbehaviour struct and marshals it into a JSON byte slice that can be unmarshalled by the operator. +// marshalMisbehaviour takes a MisbehaviourProof struct and marshals it into a JSON byte slice that can be unmarshalled by the operator. // It first marshals to JSON directly, and then modifies all the incompatible types (mostly base64 encoded bytes) to be hex encoded. // Ideally, we can update the types in the operator to be more compatible with the type we have here. // It might be enough to get out a new version of the rust crate "ibc-proto" and update the operator to use it. @@ -226,15 +226,15 @@ func marshalMisbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) ([ tmpIntermediary[pathParts[len(pathParts)-1]] = hex.EncodeToString(bz) } - validators1 := jsonIntermediary["header_1"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) - validators2 := jsonIntermediary["header_2"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) - validators3 := jsonIntermediary["header_1"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) - validators4 := jsonIntermediary["header_2"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) - validators := validators1 - validators = append(validators, validators2...) - validators = append(validators, validators3...) - validators = append(validators, validators4...) - for _, val := range validators { + trustedValidators1 := jsonIntermediary["header_1"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) + trustedValidators2 := jsonIntermediary["header_2"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) + trustedValidators3 := jsonIntermediary["header_1"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) + trustedValidators4 := jsonIntermediary["header_2"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) + trustedValidators := trustedValidators1 + trustedValidators = append(trustedValidators, trustedValidators2...) + trustedValidators = append(trustedValidators, trustedValidators3...) + trustedValidators = append(trustedValidators, trustedValidators4...) + for _, val := range trustedValidators { val := val.(map[string]interface{}) valAddressBase64Str, ok := val["address"].(string) if !ok { diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index e685a32..fd29396 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -245,11 +245,11 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { _ = eth var height clienttypes.Height - var oldHeader tmclient.Header - s.Require().True(s.Run("Get old header", func() { + var trustedHeader tmclient.Header + s.Require().True(s.Run("Get trusted header", func() { var latestHeight int64 var err error - oldHeader, latestHeight, err = ibcclientutils.QueryTendermintHeader(simd.Validators[0].CliContext()) + trustedHeader, latestHeight, err = ibcclientutils.QueryTendermintHeader(simd.Validators[0].CliContext()) s.Require().NoError(err) s.Require().NotZero(latestHeight) @@ -259,8 +259,8 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { s.Require().NoError(err) trustedHeight := clienttypes.NewHeight(uint64(clientState.LatestHeight.RevisionNumber), uint64(clientState.LatestHeight.RevisionHeight)) - oldHeader.TrustedHeight = trustedHeight - oldHeader.TrustedValidators = oldHeader.ValidatorSet + trustedHeader.TrustedHeight = trustedHeight + trustedHeader.TrustedValidators = trustedHeader.ValidatorSet })) s.Require().True(s.Run("Invalid misbehaviour", func() { @@ -269,20 +269,20 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { ctx, simd, int64(height.RevisionHeight+1), - oldHeader.GetTime().Add(time.Minute), - oldHeader, + trustedHeader.GetTime().Add(time.Minute), + trustedHeader, ) invalidMisbehaviour := tmclient.Misbehaviour{ Header1: &newHeader, - Header2: &oldHeader, + Header2: &trustedHeader, } // The proof should fail because this is not misbehaviour (valid header for a new block) - _, err := operator.Misbehaviour(simd.GetCodec(), invalidMisbehaviour, false, + _, err := operator.MisbehaviourProof(simd.GetCodec(), invalidMisbehaviour, false, "--trust-level", testvalues.DefaultTrustLevel.String(), "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod)) - s.Require().ErrorContains(err, "Misbehaviour is not detected") + s.Require().ErrorContains(err, "MisbehaviourProof is not detected") })) s.Require().True(s.Run("Valid misbehaviour", func() { @@ -291,16 +291,16 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { ctx, simd, int64(height.RevisionHeight), - oldHeader.GetTime().Add(time.Minute), - oldHeader, + trustedHeader.GetTime().Add(time.Minute), + trustedHeader, ) misbehaviour := tmclient.Misbehaviour{ Header1: &newHeader, - Header2: &oldHeader, + Header2: &trustedHeader, } - submitMsg, err := operator.Misbehaviour(simd.GetCodec(), misbehaviour, s.generateFixtures, + submitMsg, err := operator.MisbehaviourProof(simd.GetCodec(), misbehaviour, s.generateFixtures, "--trust-level", testvalues.DefaultTrustLevel.String(), "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod)) s.Require().NoError(err) From 4b8e72b39d17d0c5d1ad7efc3318c09a79ece552 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Tue, 3 Sep 2024 17:26:59 +0200 Subject: [PATCH 20/22] added test for misbehaviour breaking time monotonicity --- .github/workflows/e2e.yml | 3 +- contracts/fixtures/memberships_fixture.json | 10 +-- ...ur_breaking_time_monotonicity_fixture.json | 9 ++ .../misbehaviour_double_sign_fixture.json | 9 ++ contracts/fixtures/misbehaviour_fixture.json | 9 -- .../fixtures/uc_and_memberships_fixture.json | 10 +-- contracts/fixtures/update_client_fixture.json | 12 +-- contracts/script/genesis.json | 4 +- contracts/test/Misbehaviour.t.sol | 41 +++++---- e2e/interchaintestv8/operator/operator.go | 7 +- e2e/interchaintestv8/sp1_ics07_test.go | 84 +++++++++++++++++-- justfile | 5 +- 12 files changed, 151 insertions(+), 52 deletions(-) create mode 100644 contracts/fixtures/misbehaviour_breaking_time_monotonicity_fixture.json create mode 100644 contracts/fixtures/misbehaviour_double_sign_fixture.json delete mode 100644 contracts/fixtures/misbehaviour_fixture.json diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9607972..83691f0 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -41,7 +41,8 @@ jobs: - TestWithSP1ICS07TendermintTestSuite/TestDeploy - TestWithSP1ICS07TendermintTestSuite/TestUpdateClient - TestWithSP1ICS07TendermintTestSuite/TestUpdateClientAndMembership - - TestWithSP1ICS07TendermintTestSuite/TestMisbehaviour + - TestWithSP1ICS07TendermintTestSuite/TestDoubleSignMisbehaviour + - TestWithSP1ICS07TendermintTestSuite/TestBreakingTimeMonotonicityMisbehaviour name: ${{ matrix.test }} runs-on: ubuntu-latest steps: diff --git a/contracts/fixtures/memberships_fixture.json b/contracts/fixtures/memberships_fixture.json index 0ea170f..9eecc79 100644 --- a/contracts/fixtures/memberships_fixture.json +++ b/contracts/fixtures/memberships_fixture.json @@ -1,10 +1,10 @@ { - "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a57000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1", + "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000277162000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf585bf53cf5b309a255dd7562f62d797d6a2acc937c77b6e1ede11573df67166e2c4c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d99", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", - "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", - "proofHeight": "00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a57", - "membershipProof": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a100eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000020fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbba000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a10757067726164656449424353746174655001580100000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e74537461746500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f005fc16693f877979a166688d9245fdc80585f6f4186b3f7914fc9cb743ac91f255d96c893ab97cd082ac07908d31de8c175918ddf709c60da391746ca36316414f3867d694fb41c7fbf0993266a41b4f2089cd0e051f3f0d819aa9c5755a8cf06791d296423bcad853a4187eb9ecb7cc893a92b1bb7b6ce06a18db18ecd81cb17b1d4cf2b0af48ebc45140a443bcc0de0bea0b411240e81e036bb5e1d78ba360ca6c9203c5dcb7183acc7cbfb52d94cdeb3d2659ee05510c7f394284ccbea37090916d56be6897dee8903a0ffcd7eb85ac30aff0adf75c0200c8bca41efc6f528774e90eb301e986291e88ca6265dd77e00c80844caac8eedd9011127c0fef10385acdbc43155c8bef20ac6a2e99c8f14cc67a25a180c75090dc9f93612cbf40abb54ad70e59c0b2215d99daa6f52f01d525c2138b1ff1abebf6888e1c7b26918579afeee750306b89898d515ae29802c321f6d8bc8b04df624363c2e10238b100a0489dbd9052521c97b31a270da2584c2facc89c7570de21545db6169bb4525be12335b4789907d05a50a0ddd363f8a25c606a57b2d7f16970b3b282bd2b205dc9918bdf4e2027dac0d9447b600fe7756e212018097c468f62185c5b02a660b8bdb7a69972df3186e2f1b96040131358952fad7c217a081a5e3dea013f2531a96bc0c7fc00daaa4f099bb897e9632ba6cb52beda4dcd513b1313e5615ec960a3fed2f803d5363aa80b5bbe4702fd72a1b4db762c3d6c0b2f411ea8a5770d72089d43def6d349632d41786c5163353ed732128ef88a86109b370403fdfe7960008e6c364f845c4952339eea89e5e935b72ec786a4ba856a1ea5c7fdf24c08d1fdd88732b971a7c1b8404fe3b3565c25a35e12fd2597672689ee95afaeb8db22b540ce5068a65689a3591fb79207c5045383ed5429e585dea61fde0f526eb8c28370881e39e7388a925cd6bb09387bbc18177df42fa1d84a3f7f566e93e4ee61c593aec9baa722f1594524e0b4a6793a5cee2a31155f5520f585390e6cf8f21088f1f879bda3a36bf56811e6011a521e2bf9dda09ee9a3bb0c3c77a5ef7a3b729a7812cb79a28b786554097a4513d431937aafde464d7abfd699d017c035a001b01dd2b657e1296d2b1a986fd80fee2834ed77ce84502b22620f788c822568226d5fcac4483af266f7c7e8684b6283c981440323f0e50acdd75fece02fa9ccf00000000000000000000000000000000000000000000000000000000" + "misbehaviourVkey": "0x005e69d660bf31e9fb874c16897a71852b137d53659c24c3e3530537b59b176d", + "proofHeight": "00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000277162", + "membershipProof": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000066cf585bf53cf5b309a255dd7562f62d797d6a2acc937c77b6e1ede11573df67166e2c4c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d9900eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000020f53cf5b309a255dd7562f62d797d6a2acc937c77b6e1ede11573df67166e2c4c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a10757067726164656449424353746174655001580100000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e74537461746500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f234f53222d8502af4fd629aeec8261d24dfe541cdca7c061647efcb09b469c601ba9068821ee74d5a538b0e234296f2ba80c9756ae56aa48f8ee3d9a897c5e690a3888a16715f963169301bccce5d0a957550da35b4e76ef7f8d2b278f7d028c290ae3b068e39c921a5e4f005e6f33ac5761c792597a73fb09203b1b19aa39e51b6019c45bb08fe8fe7876f3f038fdefe94bc20d8938c44bc08d8558232bc1731ef80c44d517987c19d57a81f72c8c3577a65b48bf0b61c92746a443f877a5aa09cc6c25236fd212a14fbdb3868a932f93b4010916a9e671dafcf1133fdc568724a818fde5393416bd1bdc2b2e2e371222577fcd72e5890f990958e51fe5727d209899fc6861814069191abfea066f376ffdade6d5e8aba03d2a4ad1ca2ed71f071f610d2e707cea34c37d0ea5ce4a3a45650353ff2b556f714af8f8aef05fb41ec7a518d2b7cd556e836c49bbe4da22f7fcc4dd60adace0ca0868e3ba91210e02ea8d56a1e6ba0b934de522ac63a7a921a6f2238c871ac85c7e4f503ff92b1208e44006fbc3ce9001c0bf1b80a67b4a636e1fddf3d997920e30e0c382c08cc12fc8064aa0628c2f1d12c3e5c4e790484bdc5e171a4457f5de784897f22de7b2061bdc6f628a191e0243dabd880cd83a38eea095ee5e8e4c82ad5aed20e70ef8018fbd7157d655c80af64d3310d36bc900f57fd28644f4374fdb7aa954fa9de1153875eb7152f3d36b065cad4eca5da4fe504bbf3a9190e85fdaff626b6b94331b4026135d35e8ac5b79be64c46e1352ea94d42bcfcc0b63cc955fe4af1585a508b39235a7498060e47b14dff26f7e5edb46d74fdb3629672ae5c6d51c81a48316726a21b7b06a07d995af2321edbdeec2b766d076d5c2f07aece27716ad86b221b0d5f1628a30c5c5f28c34e4fa860b28c6116bbc35acf3d7a9b0afccdf30da1acffb99f7f8d20aad035b932bd68b7e8aeda7189901c30d25cbd9a43d37bad90ce033066e460798eda62d04c341d56012fea502af8158f6334838a07543672d185794a382adf8a0e61233765bb83d18e721b4ce8647209986fdf8baffffc9f0109039557ce9298a33eb65bedc69b68b86cab0c22b45e31e513575486ebac66e1fd56b12cb72a812122f8360e50c0848b705dfaf4827e3408e0e6d2fb366daa60ce77cdba11d8bc23e1daae77a5bfceec21570ac5670de48ee785558c4e2c55c00000000000000000000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/contracts/fixtures/misbehaviour_breaking_time_monotonicity_fixture.json b/contracts/fixtures/misbehaviour_breaking_time_monotonicity_fixture.json new file mode 100644 index 000000000..c6bebf0 --- /dev/null +++ b/contracts/fixtures/misbehaviour_breaking_time_monotonicity_fixture.json @@ -0,0 +1,9 @@ +{ + "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066d7298c18e36de14e99f7c090cfc07840e0d0d49406b46fe270c26bfa46d6facca6b631c23ec958f6b9a5e92347e1c118a571e4ef5b4a626ba839ccf58d0f5d1d36136c", + "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", + "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", + "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", + "misbehaviourVkey": "0x005e69d660bf31e9fb874c16897a71852b137d53659c24c3e3530537b59b176d", + "submitMsg": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020005e69d660bf31e9fb874c16897a71852b137d53659c24c3e3530537b59b176d000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066d7298c18e36de14e99f7c090cfc07840e0d0d49406b46fe270c26bfa46d6facca6b631c23ec958f6b9a5e92347e1c118a571e4ef5b4a626ba839ccf58d0f5d1d36136c0000000000000000000000000000000000000000000000000000000066d7298c18e36de14e99f7c090cfc07840e0d0d49406b46fe270c26bfa46d6facca6b631c23ec958f6b9a5e92347e1c118a571e4ef5b4a626ba839ccf58d0f5d1d36136c00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275450000000000000000000000000000000000000000000000000000000066d729c1000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f1b02ce272ad6d2caee288e6ef8c95878261a0d4b2e60a30fbc0ab1d15725a7c705b49374eba63016ee6f251223c73342f2e02eb0fc0ee60664a60193d82d98aa28672330a7cd1ed1c5f9de13720b87faf947ef525e247057bdc90b422251fe4d100b6dff846daccf23b3aeab7d244f64bd9fe606609cbeed3e4b900fb85b5fc103fdd5a22595bfacb303acb1f4be075bc92046e62dc7c926ebc0291a32fcc8cd2396c8dc7c8113a20483d3f8a659342973575746fdbc552913fd1276bb3300400ff8ff404342ecae8112aeb34760b68dfa0bb204a19ee109e7f620fff18e9fe91bd37daf0402396e08eff93277cc1510890f68f00e50c0f36b2af269719d096f15b6d8eb26ade778b4aebdd19f9fc5d31b9b0694901e3d798c8d47d35af31e292edb84b7a08370fd7251623495702b3aae81ecc1cdf3409d41b4f5e56f8b95871b8478ded39cf295e81909ca376ad8d607e21fc4efc00120c6edcb1e8197943d12dea90069ed1be080ecc2caaec85db0a25f6c1c0d4f89495a57b75463ebe36813424e449801d816aa3b1b8ab72d6dcc26e82349c8d38f3552c83aefd2861c6824ed6e73cbbf5f5f4d21e192425111229cfb0f85442f12a557ecc00c6bea3045119b74e2fa1205eb17749889d53f3d4873f404ae6376379fb05251233a7c34d52a8e80f16a59f1834d47f50abe99fadfe48d51c9c49599bfd226b41be6c19c380dddeec963b7a7b7b812f1ac8770c19688155193bec09fbb879ee3c961010f210a0a4eadddcb15d8ba8769f3097e22e3c9615c579a66a53a8acd811daad51e112712617a1033ed651ddfe7e456a114ee762bcffa9cb09ecfc4a4f9e3821b78a42eb15a151988a70901681c6cefd34e2bba7ddb3f1304b21ceff0472f711c98710116d561496c7c226549eb03b597a970fddf8b0dc8878352761a269f65e0c0de092ac0200500ee3913fd92940ffce829258b11408214faaa3ae9455402cf495d0be05939310a47b4f327bfe759b6a30805ad1132b0aa41f2bd72ed4e367637f9264f119b6e070ffd432b8368d224c3b56a675beef11d9f7c06c7337b4e993a9f034db35978455f264af60967c43bc65290456dc90deb6ecde7f415df8c897e201605b5b682999eaf78b73f0bc8030b9354a4afe53a3621846a2f90d811c1509d1f6599c122ab7d38070ded0f29a22006e9a4ce6aef6af9d945d62c96b278287700000000000000000000000000000000000000000000000000000000" +} diff --git a/contracts/fixtures/misbehaviour_double_sign_fixture.json b/contracts/fixtures/misbehaviour_double_sign_fixture.json new file mode 100644 index 000000000..8ca3591 --- /dev/null +++ b/contracts/fixtures/misbehaviour_double_sign_fixture.json @@ -0,0 +1,9 @@ +{ + "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066d7233497e36c109ac120ded59c994f09f66680ffaee70f5ee6e21e43b73dc4b2b59da8f66aa31770289a81b6b264f76f51a94e47879f9b6046f309131f0b31412e2ae2", + "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", + "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", + "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", + "misbehaviourVkey": "0x005e69d660bf31e9fb874c16897a71852b137d53659c24c3e3530537b59b176d", + "submitMsg": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020005e69d660bf31e9fb874c16897a71852b137d53659c24c3e3530537b59b176d000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066d7233497e36c109ac120ded59c994f09f66680ffaee70f5ee6e21e43b73dc4b2b59da8f66aa31770289a81b6b264f76f51a94e47879f9b6046f309131f0b31412e2ae20000000000000000000000000000000000000000000000000000000066d7233497e36c109ac120ded59c994f09f66680ffaee70f5ee6e21e43b73dc4b2b59da8f66aa31770289a81b6b264f76f51a94e47879f9b6046f309131f0b31412e2ae200000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275450000000000000000000000000000000000000000000000000000000066d72387000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f172babb120bade756474d67e15ee54ff11d1acba1c5aacf38b8db56b8fcb065329cdd7be2e95e4bc703eef7105788d2b757505bd7005f357bf6e5fd29a60a02d2e390f3b2fd3b5b7a8398ff2bff201484142a81ec855aeade601ab495ac3ca142b0731a3d4b1c86eaec8852bd78889f70da95c1df1eb7f5ae77ad5042c6cc15e1a67bd9194e79bf28a67de9f3555dbd6528bc1d2c8db6f5e1d33fd25bc05657a042cb721031613668be99cbe662fc4e22dc756a98babf9bfb907de431f04e2fe07da27797255fc8ffce6b9df0c8f2789f305c00ca87d41fd42b102463ebdd04f0a0a3843783b650205c816790d08c5e17ab9fc36cf57d99eee50793db6c442292aa9f09c73d9d0f9ad885a757111f57c18af7043017e492bd861c8856a24fabd02741ec703a7973b7407fd0132ed07a28f8550d4c14c83a2dd55b34e0456fd982f26e96ea8fcf1d9bf33c4a98db0e2b08239bb7316ffd1189aa86f40497a630d098116b40792182e53f3ac35a883ab0847417428577bffc7ca4e7a3e1941db541234943cd04300a4255381de893e3a9e4e94913015045760527354c29906da5e02f4c2b084f903e7b76e74f6ecf74e9d28b9455adb1439ee988cd40b86e720e206cff3fcdab5018d5fac94647dcb39210a4cffad621c1baf65b54003ab733e470ce79ab384cbe4d5ade75958103543ce071e7ccf41607fed1aca34594d481a58170f5ed919cf9808d8539fcdab607596cce862381ad3b32a26a5b323aab0a0cd0b53529126e20cb8f053bb5bcc66a438fb0bcf7e8b4e54d9102705cb1d7faabc0d2a630f3c1ce5da8690c3ca6fc26df04d23169a787350b7b0d2f376a1e2d5e40089c34c64f539a1642928579e2164853e06a61361b5c4a823c198da1cf8aa7516153a4b319d43c4a85b433a82276b5b209823c50f35579a597287c911badd522bb43d811bdf1498956b6ef25280a6c6d48374d11b84d564935626bc6436ff2b1f986a8620e9bd480f210be615a066b34a76dcf573419c7dbf52f761a07725862d7a0f38d0e59f49808ba016e2d60e9b33b5c84278c3471c9d7cdc9333aacd3a23aa7b2f2f0e303fd05627f597feb94abd32e40f03ae30082656a966c3a6d7db0023a60a84f546040af80fa1380e44b52257fd52abc4ad1b99df70a5f02a01832409e303cb33d82728f2d9f29b3445ec07f0575f1bb9767ed0c777a38a89832300000000000000000000000000000000000000000000000000000000" +} diff --git a/contracts/fixtures/misbehaviour_fixture.json b/contracts/fixtures/misbehaviour_fixture.json deleted file mode 100644 index 074613d..000000000 --- a/contracts/fixtures/misbehaviour_fixture.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf2589d6f58e945fde7fddc86e50aee4d66e9bdf8363621eb6fc2344567d77ce669999fb1ffbd155bc4f1ae1474837ad85ed946c0af8d7f4dec0590cddc6c4fcc2a0f8", - "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", - "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", - "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", - "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", - "submitMsg": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000066cf2589d6f58e945fde7fddc86e50aee4d66e9bdf8363621eb6fc2344567d77ce669999fb1ffbd155bc4f1ae1474837ad85ed946c0af8d7f4dec0590cddc6c4fcc2a0f80000000000000000000000000000000000000000000000000000000066cf2589d6f58e945fde7fddc86e50aee4d66e9bdf8363621eb6fc2344567d77ce669999fb1ffbd155bc4f1ae1474837ad85ed946c0af8d7f4dec0590cddc6c4fcc2a0f800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275450000000000000000000000000000000000000000000000000000000066cf25dd000000000000000000000000000000000000000000000000000000000000000673696d642d3100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f1618d63a7e81bc96ba1ff0c537303708a96487a86cfae76053de08107abfcc0b108959f6bb5e16c70e0bf23dd999b3a3ef57336eed567d4430e41d4e954bde451ffa2e267944b7a238d42b3397203741f60870299c1fbb62a9022821506c942f033ba20256323b52d8aca13aab53b13a1e1c1fe1e5d55841a40fcc3217f50c162a8a43b5d17026545e1c66d40a5fddeb4ef08d2dae84242bd8d28881738b61362886ee779d9c6696ac1efb08f5f8e65cca5b806a2c8747ef1b7c712f65cbd35e088fc691143855d0bf646101cd0629632cb15c5f7b715d217761375d3194c44218ec8baf68ff0bd00485f348ea683e7e97368ba25be64ca17019e7307ef42b2d1d323c1a7a3b4ec84c112b02901ed7718f77ba35e02609deda4bb7b31d6119f414bef6804964fdac85418afcaeb2765bab4859100d84cb5ae2e0a1a7c56a44e211dbf869ad20f3b3ce16f69ea43278b3a0512ba09fea020f176990961e0f50f711e23ea32ea1963897b4f00ace029f37548f5eb3dfce595969d9b1bd154633712012bb578bbecd6519b4f2a15c1b2b9dff937c2976a54b1f1bddddf1c8178c382bc98a5b88d8f5a1ada806e538068a5b553bf1cc0078600ab653da886b9b83292e8ac25980d9b6febbd7c478e5f9a16d1066d14999127c6980d8f24428e948f722b425bd4fb2ecbe564ba6a1245111e1e1c1d6aff6afcf5379f25c5e20334afd153782b4de31ece69a899170c7807ac1c847c679c00337fb07c4861615d1ef320fc5b4075f4c45c9d0a9f1b97222e7c44044419c02cfedbd56ba36fa62e6d237011cb71c1ed583ea5f4569ba98e7f5e28a83bab983bfb55d3a5e8719ede8930516bd5082e2e6ce691bbc6f91eed08f2b4a86bc81becc7dda176dff3dc27c4fe91d804d197fc02fc3338d1e164275741f602c2489b702968060811247c2bb583e0ad1ac9ff5f59d5dfd454ca3542fb74135eaf6d0bb1ec01b52968db9a2aee5d40cc55f63f54ddd950d21052ceb02c8cdccf56524264812ab68dcf9641d2de9ad047586b7b74699783e2baf4dc320a930ebe50d06cad5110a4b75d5fd132d83dd01d00c2699a7c822e38e6e5546d5c3b6d0485d447d19b88d7ffe8753c697f58f1a541099f74bacb1d9670d9d19add724be7c73109a227e030713b0c6c6fe31ca04feabc7bdc03ba56d1d3836d80c2fa56cc81465fbc945a8c32a9e0a27b632ec00000000000000000000000000000000000000000000000000000000" -} diff --git a/contracts/fixtures/uc_and_memberships_fixture.json b/contracts/fixtures/uc_and_memberships_fixture.json index 67c11fe..9f70570 100644 --- a/contracts/fixtures/uc_and_memberships_fixture.json +++ b/contracts/fixtures/uc_and_memberships_fixture.json @@ -1,10 +1,10 @@ { - "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a57000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1", + "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000277162000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf585bf53cf5b309a255dd7562f62d797d6a2acc937c77b6e1ede11573df67166e2c4c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d99", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", - "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", - "proofHeight": "00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276ab1", - "membershipProof": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd70110000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a10000000000000000000000000000000000000000000000000000000066cf0789d26229b6c70fe138eccbd82cc28f66a77c371a89a680f3c6f62435f63ad2a9fbf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a5700000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276ab100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066cf083700000000000000000000000000000000000000000000000000000000000000076d6f6368612d340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a10757067726164656449424353746174655001580100000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e74537461746500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f05684b12648a7bf93f35525e336edfe0da8074eb8ac9c206c6e324beed7373521d66c91bf6ecbe92e7ec93c8f9b9f4442647edf156b6a8d278d835abf45ddfcb15a1300dfd5350f7c06f40bbf8aa6b8e9941e2c4d7630bdb4cf5e0835d9a2dd31616149326a19a7da53f0d124b84ed7be2613edaa6ba595db2f51e6d2396b917050ce47653cce623b87224bc9f1054049f92bf9937596fb2c6034acc4c84abe21baa87db049a109828cc39a5ed1be053c2a01fb52038719005a9489f8b37b8af2a93f224e750ca5f21ca89ba38dc570a131c9e503e3ff564c3d32fdccdd3a47b147c03d8525bf65ec9729ba5ddfe4fe37d58ab1d5d283752854c2742fd45998822f6e613577924bcd3257b0ff5c29772a48b5b3d6642cb9fff2fbc0521cdf1e7031b828fbbe5400d4e55690978ab3450ea568edf9896bdb57628e4ef1aee098a068a668b19a65b60f499af016e46603e24fd5b197744ba910fda444b5a2a5587026736b342b53e72c914aacc33fa59fdcebfd16371f5af70c217d5522d31e474140a3ed13ab82df364a3d92bb1c1d78f43acdca73eb290ec37cd8105c9368996112886cd95f70d150b827ee0883d17ab2a3a6f4d7a5909a931dc6d996b9d4c521f9d737548e8b56de6f105c7d7d7f6cffd05639e40327570da8719ab71c5cdf21d90893fd1a5c3eec67bb72d7f2bb59e699c65398e4bea39fd67a2f21f79ab1e0b5b080e0821e1a9aaf7d05f5c06ffb519788207a6cebf40a90b70be2408aa101be20be9ec1f138e89c89dcd8b9dc3ee9b4eadfb4eeec95ed33c639eee68745216af51422bf27d625740494962e41870fcef8fa1598ca1394ef984d108978649303b33d466518358a310fef8245d4137aef3b0e8117f568df165b9269c434c0c20ec690a507966e03100c375206b7f987845326d031518b03ee74f8e5e8e225c0ebd295dc4a46438baada51b8b0867ed1989b2284ee4fffb27b5e27381adddfb0a3217b92247b3d4363a89b65d03af54605a552a48874a145ab55273687bccee00671525d01707724a78f5822a5416d3f901a6657b49c072fa2685088de709a21a72f411dd656c98ce950f71162e21d0d217220dfcdc6477d3282092c38f1d91058b9244d1453e400de71e86a488562bc18acb544d794bd847b55a038cbc25cc0927ed49b373ceb444d87a64869b4435408c335e49fefd002147b9263a4fafab00000000000000000000000000000000000000000000000000000000" + "misbehaviourVkey": "0x005e69d660bf31e9fb874c16897a71852b137d53659c24c3e3530537b59b176d", + "proofHeight": "000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002771bc", + "membershipProof": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd70110000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000066cf585bf53cf5b309a255dd7562f62d797d6a2acc937c77b6e1ede11573df67166e2c4c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d990000000000000000000000000000000000000000000000000000000066cf5ca0b522cbede226c60cc042ae1c7511d2b646a0618a18077ce7dc37c920e24c6e1c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d99000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000277162000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002771bc00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066d721e800000000000000000000000000000000000000000000000000000000000000076d6f6368612d340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a10757067726164656449424353746174655001580100000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000369626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e74537461746500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f07f86b1730c37c4c9f28fd3c651e22dda0c7a91a19eeae680023c57240cac6d9151a3570d5b2853abd8f4ac3fb5afea189725cdb3758ced75961138d40109e5c1bfad9679d0f2b673314cbc389dc9b6c0373661e88d169a0d736fd98737927a404f3a26096dfd5853726c02f2e5f8f233f2e436a4492b796c3dd39cfdd145a9425f2f826b87a98df3fd053de8fe57f5ca26111449679c60f2e64af67e00b5d160d0d38a91a1e0490d55dfbf49bbfc8cfa83697e93f3040a047cdb500afa34fb20d9973474c8feb0ea8cc44b800fdd955b6200912fd4270fb291d45ac00887eb901a120b4f7c67268a900e5f1a49c9b5841a9caaf5c051b3048fc1c149b5bf5280aee72e15c70b84c9ee18fe709069fad96a94cdbe056ab5a304bfe847c0783e21b74402641a48dce103ca8d9b7797737f825308f4b12f090ef453e024e8fe5c2051dbf320459e6d64ebfda8788e54cdaa7b8cc30cbfa61f973763a738881129b1dbd172daef4bc45c1b1328639837c1366d06789386b6738d54bb1b17ec011df0e461a0b8c0cd09eaba8015aa503c342048b86a19468c97991a7464d54c30d19052f5f8d4eeb4dbaaf160f64e208bbfee04c071569b1fd34cbae41e0bd919bc3304d46c5b1895a2a3a5956d3ed8949ebf5ff5eb30b30e007fa2a7b281ac4b4480c95de28faae106fe89cad3857c6b90532923bb9c04baa395d666a38ef34224c1dffa0df9b3db5a0b237c4bceb250c68ac7d5c1c984d9d5ab4dee6aee35df1b81ba24ee6974e899eeed076374b5ba2fd80f81fed8539104732a4e9d549e71bd6297f1c6c9b2068a39b5511b1e2af7ba677c4b90714b661914154145ad2aa7f722d15b064b8025b6ca48ee94fad56cb9b8d79f07176b9c60118e4813bdcc47ecc0c9bb6112e1579f3ae872b5fe56bd8a3aa289536b688214097a6e6ac33436f512de72ed8eb1eea3271252e445f88dae947df0f6296955008d3ec159433bec9fb17d4bfed84ad2d7a62a72f1f24677d0677835d149fdcdedea070dabc0a56ebf62c5e2def51378a9f0faaface33d941e627d4522709b4eed33873f3852fbdff300a8273b1f7e5be086b9e6b0c23ad9fd6bf13fc1df699a14c32cae0fbcceac52c087288a309939c0bbbe75393138937cf18e4b676efa2b30d4f176c8d14e0bb98019e0375c5fce46b5386042ebeb9b4faab88551196b2f7f3bc2c8ba2104b95d300000000000000000000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/contracts/fixtures/update_client_fixture.json b/contracts/fixtures/update_client_fixture.json index 297bfae..58b136b 100644 --- a/contracts/fixtures/update_client_fixture.json +++ b/contracts/fixtures/update_client_fixture.json @@ -1,11 +1,11 @@ { - "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a57000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1", + "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000277162000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf585bf53cf5b309a255dd7562f62d797d6a2acc937c77b6e1ede11573df67166e2c4c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d99", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", - "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9", - "targetConsensusState": "0000000000000000000000000000000000000000000000000000000066cf0789d26229b6c70fe138eccbd82cc28f66a77c371a89a680f3c6f62435f63ad2a9fbf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1", - "targetHeight": 2583217, - "updateMsg": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000066cf0348fabda107575fa326d9d840dd8bdeb39cdaaa4841f9134c114be417da8ad0dbbaf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a10000000000000000000000000000000000000000000000000000000066cf0789d26229b6c70fe138eccbd82cc28f66a77c371a89a680f3c6f62435f63ad2a9fbf5a9c9e11692b049a074327624ea4b9a29b0a95a521941732c36dd548cf678a1000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276a5700000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000276ab100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066cf082800000000000000000000000000000000000000000000000000000000000000076d6f6368612d34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f06171485b883f5d959805cd7de83029af4324e25079b4c7e624cf0976cbc4db30bc39c45c46cc5cbc3432065a1a4b6ba871b5913b0161f9a68a5d53296f7671d0b52c02cc82a8bc6ee1d0e8088bd0f297776e638b385d5639de465f9a87471ee2d0cfbbbcf29ce774c0aa5c9030d19fb8e0d750033de56cb23ec262bff9b215d2782f8472c2b4215f2d9e0eb2d8b01f7a5b124656343a91e3fcfcd2dfb0bfb7f2ab9201ad6946ba478e8917835caa25f29d436730f377d27c92fc38c0ec5aa750f08fd222cf715ec2ccd13b8eee9356bfcd9cc1b3db0612d2ed9a03158a435e5270171a1cec7ee2be70da7e7f6248dd99097d3bbe2572cc88d5adae8ba870c951fc4e6dc593ab927ee1fa80b417f1c8e05c6063ce29a8526128fbf6cbed62f171b09e320a974da3109e932d9eb5acade29f57cb4be8d0f9df4c1b90907a68c7b1a1f583fdd25076af41276ae463e90dfaf1cdd58fb8977a743d06f889ee0b2cb27edccd7691e13fa902f7a6dd4c4fa70623132d0bf1428935fefa7ac2c79358215f2024e6dba1511b271e20dfbfe3606237d291f537db68a92096a2bd62388b82f4e6517b4379dbac562c4e2526f381341dc3fbdfcba0be3d6e0ebb1f5cc0381048f339bbfe3be43d6425c4d7b7f862c7c9f88cce3835ed8c104bbc9170e1cc92bdebc6150b7b8a9b40bb1f79abcc1b82924f7020f0bc9a753ff7faa98350c5129e8023163bd3a10254a648e6f82b9e8553f3e802de32915f200c94b6c3d899427da8854518d037b0e8ec532b3e8dcc89350ef31cc3655508079bc457d095f2023cde883c6020efe315acdb0a710a6458ca6a87baf0769565a43bbdd4092fb72239e45d1b496aa89926e582341df46540f1d7afd406cb2cd269aa19b2752bd4b1de32029ae493eb18b433dd637dbafebab0e4286090a8013643de917cab352c51916f766ec26245fc25592dabebd424a0acafafbd26429b8f42cc78bcd0c33340fb5d794424b1905aa1cec7b59be4580f88ff7d1cce186980f421d97347769850c962118eff95b7768ef657c6a606a203a0b47c3904b7b3d6c6d89aeed1e6301258cfdee53f4c314503d80469e267a60597c444266d3507d1dafb5f7d5c85045096be9606738bb141eea61131bf7520db797ba59c310cec293593d77a8825a82153087665f9e041d251db18cfee69e18c6c95af3fb9d7eee04dd818839e6be4400000000000000000000000000000000000000000000000000000000" + "misbehaviourVkey": "0x005e69d660bf31e9fb874c16897a71852b137d53659c24c3e3530537b59b176d", + "targetConsensusState": "0000000000000000000000000000000000000000000000000000000066cf5ca0b522cbede226c60cc042ae1c7511d2b646a0618a18077ce7dc37c920e24c6e1c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d99", + "targetHeight": 2585020, + "updateMsg": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000066cf585bf53cf5b309a255dd7562f62d797d6a2acc937c77b6e1ede11573df67166e2c4c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d990000000000000000000000000000000000000000000000000000000066cf5ca0b522cbede226c60cc042ae1c7511d2b646a0618a18077ce7dc37c920e24c6e1c424ee8cf84c0fa35a3eaf862ff1a633eb83be1022827498a79d4b6ac64310d99000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000277162000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002771bc00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000066d721d800000000000000000000000000000000000000000000000000000000000000076d6f6368612d34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364c430ff7f2d986b6928dbc1587da304bec2f4c45bded50226699915dc2c8f438275ec68691747e1e2c1781013305e645ed5e00c6e4498ffc8d19fdd42e7f2803a5d39681e2e46db956a99c244fc5984c35fbe713eac0c082c57a0d90f1e736637395c1d6c04a28b968cbb24ebe2edceb32a2dbf16d1c21ea02b450683c5c5fd313c72ff9029cd9bb5687bc315e11e0a510f402ef9ec977b4348b4bfe61471ab0230774f0324270af8d654f41e64515587b6f1e395b4d57bfc8de21559ff74e365d634510a01b6ede065fd0d1a9f165e69f2c90712dc92eb0149da55a14a93ef2c5ca352f8110d744c8bee1f00aa18a80de216a907be90154aa6e5841898b10d7e533fc06203dcc0247527f54636da37a6c698e14cc976ad5e5fa839e9be8d3b81b154006f24f5090149ad868cad85d86e524330a84362d7fda16e7d60f0bd8295967bbd6a184e7245dfbbec20808cb470c957d8c9abe73fe2bb3c54d42c2f49a2e8b07bcd0f9b9a712442188237670a29de7beca01ccd7b26dc91bf747ac056a9979a8c1028e28c2023ef5115b0273b8fa49e20d1ef6263ca2dda842690b67fd432f5f4152231ff11e3048ba1f6ca6182a1a552496388497e1feab2d4bf88583892be817a160cefd71022f2948ff230a73b5f8dd55c86d9c8b6095dc2ce04eb1e06698cd11e863d544de887e774415221922f84b996b8ab5b69e09976a242f7ab58e91e45154ce5831857e413e775a5289fa6b7c87a98ea011247bcb9fe56d13ca34f0f230827c0b5d781a262aef096bcad47a6623bb533520ffb42afc65c19172437d95224e14cd5e7a0a178edb04266900eb96e21887d3b1de168c2d51316ed3d2bb9730b9962b7dc67a1ec59a8aba738a619039ae5eea800343f11ce90b7e24cc00d170c88e6d980d7802f6ae1ae7c0ea4b8caf07d31b2ea0a7fee059ad9d0f722ef7c26ed0e3b53a5d14ff4d6d693a5a68045330e9954dd30dcd6048043b371cb99040ac0ee37bcb18e7533a36df26c37ca54c937868cdde8214e17c81c83d059a33e1409d02ab77553f0ade78e10d5e9e9a501e2b4dccc05b502606025b24aec5f9f00f5703682b2201f32ca25886cefad088764025ae18149b320899bdac88aa7262398b888b9ab920e49db0f8838f8c99ba09a4723e006aabea54cf3646d34467e2cdc3bd525502d5355237d910be627b476927fdd6846c28559630d9842a7a30e00000000000000000000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index 272efb7..25744b6 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,8 +1,8 @@ { "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000012754500000000000000000000000000000000000000000000000000000000001baf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673696d642d310000000000000000000000000000000000000000000000000000", - "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066cf2589d6f58e945fde7fddc86e50aee4d66e9bdf8363621eb6fc2344567d77ce669999fb1ffbd155bc4f1ae1474837ad85ed946c0af8d7f4dec0590cddc6c4fcc2a0f8", + "trustedConsensusState": "0000000000000000000000000000000000000000000000000000000066d7298c18e36de14e99f7c090cfc07840e0d0d49406b46fe270c26bfa46d6facca6b631c23ec958f6b9a5e92347e1c118a571e4ef5b4a626ba839ccf58d0f5d1d36136c", "updateClientVkey": "0x00aae7c6a541134ce5c556dd8bb23516240292e127321b5de81bc27892355622", "membershipVkey": "0x00eae02a2c448b3242c5b37cef161b94e908fc12d861c481cff9d10217648697", "ucAndMembershipVkey": "0x00a477c762e91e1e004d9362b4bd6a69b0f577f24b0e6db30f1b57ea87bd7011", - "misbehaviourVkey": "0x0030026e0e957529c07b87a560fd345b72ea926853c5d871384f86caaac707b9" + "misbehaviourVkey": "0x005e69d660bf31e9fb874c16897a71852b137d53659c24c3e3530537b59b176d" } \ No newline at end of file diff --git a/contracts/test/Misbehaviour.t.sol b/contracts/test/Misbehaviour.t.sol index 6291008..98dd948 100644 --- a/contracts/test/Misbehaviour.t.sol +++ b/contracts/test/Misbehaviour.t.sol @@ -23,17 +23,7 @@ contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { Env public env; - function setUp() public { - fixture = loadFixture("misbehaviour_fixture.json"); - - setUpTest("misbehaviour_fixture.json"); - - submitMsg = abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); - output = abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); - env = output.env; - } - - function loadFixture(string memory fileName) public view returns (SP1ICS07MisbehaviourFixtureJson memory) { + function setUpMisbehaviour(string memory fileName) public { string memory root = vm.projectRoot(); string memory path = string.concat(root, "/contracts/fixtures/", fileName); string memory json = vm.readFile(path); @@ -41,16 +31,37 @@ contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { bytes memory trustedConsensusStateBz = json.readBytes(".trustedConsensusState"); bytes memory submitMsgBz = json.readBytes(".submitMsg"); - SP1ICS07MisbehaviourFixtureJson memory fix = SP1ICS07MisbehaviourFixtureJson({ + fixture = SP1ICS07MisbehaviourFixtureJson({ trustedClientState: trustedClientStateBz, trustedConsensusState: trustedConsensusStateBz, submitMsg: submitMsgBz }); - return fix; + setUpTest(fileName); + + submitMsg = abi.decode(fixture.submitMsg, (IMisbehaviourMsgs.MsgSubmitMisbehaviour)); + output = abi.decode(submitMsg.sp1Proof.publicValues, (IMisbehaviourMsgs.MisbehaviourOutput)); + env = output.env; + } + + function test_ValidDoubleSignMisbehaviour() public { + setUpMisbehaviour("misbehaviour_double_sign_fixture.json"); + + // set a correct timestamp + vm.warp(env.now); + ics07Tendermint.misbehaviour(fixture.submitMsg); + + // to console + console.log("Misbehaviour gas used: ", vm.lastCallGas().gasTotalUsed); + + // verify that the client is frozen + ClientState memory clientState = ics07Tendermint.getClientState(); + assertTrue(clientState.isFrozen); } - function test_ValidMisbehaviour() public { + function test_ValidBreakingTimeMonotonicityMisbehaviour() public { + setUpMisbehaviour("misbehaviour_breaking_time_monotonicity_fixture.json"); + // set a correct timestamp vm.warp(env.now); ics07Tendermint.misbehaviour(fixture.submitMsg); @@ -64,6 +75,8 @@ contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { } function test_InvalidMisbehaviour() public { + setUpMisbehaviour("misbehaviour_double_sign_fixture.json"); + // proof is in the future vm.warp(env.now - 300); vm.expectRevert(abi.encodeWithSelector(ProofIsInTheFuture.selector, block.timestamp, env.now)); diff --git a/e2e/interchaintestv8/operator/operator.go b/e2e/interchaintestv8/operator/operator.go index 2e87269..aa9cf75 100644 --- a/e2e/interchaintestv8/operator/operator.go +++ b/e2e/interchaintestv8/operator/operator.go @@ -119,7 +119,7 @@ func UpdateClientAndMembershipProof(trusted_height, target_height uint64, paths } // MisbehaviourProof is a function that generates a misbehaviour proof and returns the submit message -func MisbehaviourProof(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixture bool, args ...string) ([]byte, error) { +func MisbehaviourProof(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writeFixtureName string, args ...string) ([]byte, error) { misbehaviourBz, err := marshalMisbehaviour(cdc, misbehaviour) if err != nil { return nil, err @@ -151,8 +151,9 @@ func MisbehaviourProof(cdc codec.Codec, misbehaviour tmclient.Misbehaviour, writ return nil, err } - if writeFixture { - if err := os.WriteFile("contracts/fixtures/misbehaviour_fixture.json", output, 0o600); err != nil { + if writeFixtureName != "" { + fixtureFileName := fmt.Sprintf("contracts/fixtures/misbehaviour_%s_fixture.json", writeFixtureName) + if err := os.WriteFile(fixtureFileName, output, 0o600); err != nil { return nil, err } } diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index fd29396..25bc867 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -234,9 +234,9 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership() { })) } -// TestMisbehaviour tests the misbehaviour functionality +// TestDoubleSignMisbehaviour tests the misbehaviour functionality // Partially based on https://github.com/cosmos/relayer/blob/f9aaf3dd0ebfe99fbe98d190a145861d7df93804/interchaintest/misbehaviour_test.go#L38 -func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { +func (s *SP1ICS07TendermintTestSuite) TestDoubleSignMisbehaviour() { ctx := context.Background() s.SetupSuite(ctx) @@ -279,10 +279,10 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { } // The proof should fail because this is not misbehaviour (valid header for a new block) - _, err := operator.MisbehaviourProof(simd.GetCodec(), invalidMisbehaviour, false, + _, err := operator.MisbehaviourProof(simd.GetCodec(), invalidMisbehaviour, "", "--trust-level", testvalues.DefaultTrustLevel.String(), "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod)) - s.Require().ErrorContains(err, "MisbehaviourProof is not detected") + s.Require().ErrorContains(err, "Misbehaviour is not detected") })) s.Require().True(s.Run("Valid misbehaviour", func() { @@ -300,7 +300,81 @@ func (s *SP1ICS07TendermintTestSuite) TestMisbehaviour() { Header2: &trustedHeader, } - submitMsg, err := operator.MisbehaviourProof(simd.GetCodec(), misbehaviour, s.generateFixtures, + submitMsg, err := operator.MisbehaviourProof(simd.GetCodec(), misbehaviour, "double_sign", + "--trust-level", testvalues.DefaultTrustLevel.String(), + "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod)) + s.Require().NoError(err) + + tx, err := s.contract.Misbehaviour(s.GetTransactOpts(s.key), submitMsg) + s.Require().NoError(err) + + // wait until transaction is included in a block + _ = s.GetTxReciept(ctx, eth.EthereumChain, tx.Hash()) + + clientState, err := s.contract.GetClientState(nil) + s.Require().NoError(err) + s.Require().True(clientState.IsFrozen) + })) +} + +// TestBreakingTimeMonotonicityMisbehaviour tests the misbehaviour functionality +// Partially based on https://github.com/cosmos/relayer/blob/f9aaf3dd0ebfe99fbe98d190a145861d7df93804/interchaintest/misbehaviour_test.go#L38 +func (s *SP1ICS07TendermintTestSuite) TestBreakingTimeMonotonicityMisbehaviour() { + ctx := context.Background() + + s.SetupSuite(ctx) + + eth, simd := s.ChainA, s.ChainB + _ = eth + + var height clienttypes.Height + var trustedHeader tmclient.Header + s.Require().True(s.Run("Get trusted header", func() { + var latestHeight int64 + var err error + trustedHeader, latestHeight, err = ibcclientutils.QueryTendermintHeader(simd.Validators[0].CliContext()) + s.Require().NoError(err) + s.Require().NotZero(latestHeight) + + height = clienttypes.NewHeight(clienttypes.ParseChainID(simd.Config().ChainID), uint64(latestHeight)) + + clientState, err := s.contract.GetClientState(nil) + s.Require().NoError(err) + trustedHeight := clienttypes.NewHeight(uint64(clientState.LatestHeight.RevisionNumber), uint64(clientState.LatestHeight.RevisionHeight)) + + trustedHeader.TrustedHeight = trustedHeight + trustedHeader.TrustedValidators = trustedHeader.ValidatorSet + })) + + s.Require().True(s.Run("Valid misbehaviour", func() { + // we have a trusted height n from trustedHeader + // we now create two new headers n+1 and n+2 where both have time later than n + // but n+2 has time earlier than n+1, which breaks time monotonicity + + // n+1 + header2 := s.CreateTMClientHeader( + ctx, + simd, + int64(height.RevisionHeight+1), + trustedHeader.GetTime().Add(time.Minute), + trustedHeader, + ) + + // n+2 (with time earlier than n+1 and still after n) + header1 := s.CreateTMClientHeader( + ctx, + simd, + int64(height.RevisionHeight+2), + trustedHeader.GetTime().Add(time.Minute).Add(-30*time.Second), + trustedHeader, + ) + + misbehaviour := tmclient.Misbehaviour{ + Header1: &header1, + Header2: &header2, + } + + submitMsg, err := operator.MisbehaviourProof(simd.GetCodec(), misbehaviour, "breaking_time_monotonicity", "--trust-level", testvalues.DefaultTrustLevel.String(), "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod)) s.Require().NoError(err) diff --git a/justfile b/justfile index b14a056..e04d617 100644 --- a/justfile +++ b/justfile @@ -58,7 +58,8 @@ fixtures prover: build-operator "RUST_LOG=info SP1_PROVER={{prover}} ./target/release/operator fixtures update-client --trusted-block $TRUSTED_HEIGHT --target-block $TARGET_HEIGHT -o 'contracts/fixtures/update_client_fixture.json'" \ "sleep 15 && RUST_LOG=info SP1_PROVER={{prover}} ./target/release/operator fixtures update-client-and-membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block $TRUSTED_HEIGHT --target-block $TARGET_HEIGHT -o 'contracts/fixtures/uc_and_memberships_fixture.json'" \ "sleep 30 && RUST_LOG=info SP1_PROVER={{prover}} ./target/release/operator fixtures membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block $TRUSTED_HEIGHT -o 'contracts/fixtures/memberships_fixture.json'" - cd e2e/interchaintestv8 && RUST_LOG=info SP1_PROVER=network GENERATE_FIXTURES=true go test -v -run '^TestWithSP1ICS07TendermintTestSuite/TestMisbehaviour$' -timeout 40m + cd e2e/interchaintestv8 && RUST_LOG=info SP1_PROVER=network GENERATE_FIXTURES=true go test -v -run '^TestWithSP1ICS07TendermintTestSuite/TestDoubleSignMisbehaviour$' -timeout 40m + cd e2e/interchaintestv8 && RUST_LOG=info SP1_PROVER=network GENERATE_FIXTURES=true go test -v -run '^TestWithSP1ICS07TendermintTestSuite/TestBreakingTimeMonotonicityMisbehaviour' -timeout 40m @echo "Fixtures generated at 'contracts/fixtures'" # Generate the `SP1ICS07Tendermint.json` file containing the ABI of the SP1ICS07Tendermint contract @@ -104,7 +105,7 @@ lint: lint-fix: @echo "Fixing the Rust code..." cargo fmt --all - cargo clippy --fix --allow-dirty + cargo clippy --fix --allow-dirty --allow-staged @echo "Fixing the Solidity code..." forge fmt && bun solhint -w 0 -c .solhint.json 'contracts/**/*.sol' && bun natspec-smells --enforceInheritdoc false --include 'contracts/src/**/*.sol' @echo "Fixing the Go code..." From e6ae78fb8528f9231467a5be87ba0ae790fd46e6 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Tue, 3 Sep 2024 17:56:02 +0200 Subject: [PATCH 21/22] added unit test for TrustingPeriodTooLong --- contracts/test/Misbehaviour.t.sol | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/contracts/test/Misbehaviour.t.sol b/contracts/test/Misbehaviour.t.sol index 98dd948..9a6816d 100644 --- a/contracts/test/Misbehaviour.t.sol +++ b/contracts/test/Misbehaviour.t.sol @@ -3,6 +3,7 @@ pragma solidity >=0.8.25; // solhint-disable-next-line no-global-import import "forge-std/console.sol"; +import { SP1ICS07Tendermint } from "../src/SP1ICS07Tendermint.sol"; import { SP1ICS07TendermintTest } from "./SP1ICS07TendermintTest.sol"; import { IMisbehaviourMsgs } from "../src/msgs/IMisbehaviourMsgs.sol"; import { SP1Verifier } from "@sp1-contracts/v1.1.0/SP1Verifier.sol"; @@ -138,6 +139,39 @@ contract SP1ICS07MisbehaviourTest is SP1ICS07TendermintTest { ); ics07Tendermint.misbehaviour(submitMsgBz); + // trusting period too long + // we need to set up a new misconfigured client where the trusting period is longer than the unbonding period + ClientState memory clientState = ics07Tendermint.getClientState(); + ClientState memory badClientState = ClientState({ + chainId: clientState.chainId, + trustLevel: clientState.trustLevel, + latestHeight: clientState.latestHeight, + trustingPeriod: clientState.unbondingPeriod + 1, + unbondingPeriod: clientState.unbondingPeriod, + isFrozen: clientState.isFrozen + }); + bytes32 trustedConsensusState = ics07Tendermint.getConsensusStateHash(clientState.latestHeight.revisionHeight); + SP1ICS07Tendermint badClient = new SP1ICS07Tendermint( + ics07Tendermint.UPDATE_CLIENT_PROGRAM_VKEY(), + ics07Tendermint.MEMBERSHIP_PROGRAM_VKEY(), + ics07Tendermint.UPDATE_CLIENT_AND_MEMBERSHIP_PROGRAM_VKEY(), + ics07Tendermint.MISBEHAVIOUR_PROGRAM_VKEY(), + address(ics07Tendermint.VERIFIER()), + abi.encode(badClientState), + trustedConsensusState + ); + badOutput = cloneOutput(); + badOutput.env.trustingPeriod = badClientState.trustingPeriod; + badSubmitMsg = cloneSubmitMsg(); + badSubmitMsg.sp1Proof.publicValues = abi.encode(badOutput); + submitMsgBz = abi.encode(badSubmitMsg); + vm.expectRevert( + abi.encodeWithSelector( + TrustingPeriodTooLong.selector, badClientState.trustingPeriod, badClientState.unbondingPeriod + ) + ); + badClient.misbehaviour(submitMsgBz); + // invalid proof badSubmitMsg = cloneSubmitMsg(); badOutput = cloneOutput(); From 0e641cee86d84e376c826bc4fe357490c5b4b571 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Wed, 4 Sep 2024 14:27:09 +0200 Subject: [PATCH 22/22] rename validators correctly --- e2e/interchaintestv8/operator/operator.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/e2e/interchaintestv8/operator/operator.go b/e2e/interchaintestv8/operator/operator.go index aa9cf75..deb35df 100644 --- a/e2e/interchaintestv8/operator/operator.go +++ b/e2e/interchaintestv8/operator/operator.go @@ -227,15 +227,15 @@ func marshalMisbehaviour(cdc codec.Codec, misbehaviour tmclient.Misbehaviour) ([ tmpIntermediary[pathParts[len(pathParts)-1]] = hex.EncodeToString(bz) } - trustedValidators1 := jsonIntermediary["header_1"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) - trustedValidators2 := jsonIntermediary["header_2"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) - trustedValidators3 := jsonIntermediary["header_1"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) - trustedValidators4 := jsonIntermediary["header_2"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) - trustedValidators := trustedValidators1 - trustedValidators = append(trustedValidators, trustedValidators2...) - trustedValidators = append(trustedValidators, trustedValidators3...) - trustedValidators = append(trustedValidators, trustedValidators4...) - for _, val := range trustedValidators { + validators1 := jsonIntermediary["header_1"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) + validators2 := jsonIntermediary["header_2"].(map[string]interface{})["validator_set"].(map[string]interface{})["validators"].([]interface{}) + trustedValidators1 := jsonIntermediary["header_1"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) + trustedValidators2 := jsonIntermediary["header_2"].(map[string]interface{})["trusted_validators"].(map[string]interface{})["validators"].([]interface{}) + validators := validators1 + validators = append(validators, validators2...) + validators = append(validators, trustedValidators1...) + validators = append(validators, trustedValidators2...) + for _, val := range validators { val := val.(map[string]interface{}) valAddressBase64Str, ok := val["address"].(string) if !ok {