diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..558fe49 --- /dev/null +++ b/.env.example @@ -0,0 +1,12 @@ +# URL of the Tendermint RPC node +TENDERMINT_RPC_URL=https://rpc.celestia-mocha.com/ +# URL of the Ethereum RPC node +RPC_URL=https://ethereum-sepolia.publicnode.com/ +# Address of the light client contract +CONTRACT_ADDRESS="CONTRACT-ADDRESS" +# SP1_PROVER={network|local|mock} +SP1_PROVER=network +# Private key with the permission to use the network prover +SP1_PRIVATE_KEY="PRIVATE-KEY" +# Private key which the operator uses to sign the transactions in Eth Sepolia testnet +PRIVATE_KEY="PRIVATE-KEY" diff --git a/Cargo.toml b/Cargo.toml index 32f4d77..bf44950 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,9 +44,6 @@ tendermint = { version = "0.36.0", default-features = false } ibc-core-client-types = { version = "0.53.0", default-features = false } ibc-core-commitment-types = { version = "0.53.0", default-features = false } time = { version = "0.3", default-features = false, features = ["macros", "parsing"] } -# tendermint-light-client-verifier = { version = "0.35.0", default-features = false, features = [ -# "rust-crypto", -# ] } alloy-primitives = "0.7.2" alloy-contract = "0.1.2" alloy-node-bindings = "0.1.2" diff --git a/README.md b/README.md index 0e891fb..b2dabc5 100644 --- a/README.md +++ b/README.md @@ -33,25 +33,22 @@ just build-program ## Run ICS-07 Tendermint Light Client End to End -1. Generate the initialization parameters for the contract. +1. Set the environment variables by filling in the `.env` file with the following: ```sh - TENDERMINT_RPC_URL=https://rpc.celestia-mocha.com/ cargo run --bin genesis --release + cp .env.example .env ``` - This will generate the `contracts/script/genesis.json` file which contains the initialization parameters for the contract. + You need to fill in the `PRIVATE_KEY`, `SP1_PROVER`, `TENDERMINT_RPC_URL`, and `RPC_URL`. You also need the `SP1_PRIVATE_KEY` field if you are using the SP1 prover network. -2. Deploy the `SP1ICS07Tendermint` contract with the initialization parameters: +2. Deploy the `SP1ICS07Tendermint` contract: ```sh - cd ../contracts - - forge install - - forge script script/SP1ICS07Tendermint.s.sol --rpc-url https://ethereum-sepolia.publicnode.com/ --private-key --broadcast + just deploy-contracts ``` - If you see the following error, add `--legacy` to the command. + This will generate the `contracts/script/genesis.json` file which contains the initialization parameters for the contract. And then deploy the contract using `contracts/script/SP1ICS07Tendermint.s.sol`. + If you see the following error, add `--legacy` to the command in the `justfile`: ```text Error: Failed to get EIP-1559 fees ``` @@ -60,26 +57,15 @@ just build-program ```text == Return == - 0: address + 0: address ``` - This will be used when you run the operator in step 5. + This will be used when you run the operator in step 5. So add this to your `.env` file. -4. Export your SP1 Prover Network configuration - ```sh - # Export the PRIVATE_KEY you will use to deploy the contract & relay proofs. - export PRIVATE_KEY= - - # Optional - # If you're using the Succinct network, set SP1_PROVER to "network". Otherwise, set it to "local" or "mock". - export SP1_PROVER={network|local|mock} - # Only required if SP1_PROVER is set to "network". - export SP1_PRIVATE_KEY= - ``` +4. Run the Tendermint operator. -5. Run the Tendermint operator. ```sh - TENDERMINT_RPC_URL=https://rpc.celestia-mocha.com/ RPC_URL=https://ethereum-sepolia.publicnode.com/ CONTRACT_ADDRESS= RUST_LOG=info cargo run --bin operator --release + just operator ``` ## EVM-Compatible Proof Generation & Verification @@ -93,10 +79,10 @@ Here, I will show you how to generate a proof to be used in the fixtures for the RUST_BACKTRACE=full RUST_LOG=info SP1_PROVER="local" TENDERMINT_RPC_URL="https://rpc.celestia-mocha.com/" cargo run --bin fixture --release -- --trusted-block 2110658 --target-block 2110668 ``` -To use the SP1 prover network, you will need to set the `SP1_PROVER` environment variable to `network` and provide your private key. You can do this by running the following command: +To use the SP1 prover network, you will need to set the `SP1_PROVER` environment variable to `network` and provide your private key to `.env`. After this, you can run the following command: ```sh -RUST_BACKTRACE=full RUST_LOG=info SP1_PROVER="network" SP1_PRIVATE_KEY="YOUR_PRIVATE_KEY" TENDERMINT_RPC_URL="https://rpc.celestia-mocha.com/" cargo run --bin fixture --release -- --trusted-block 2110658 --target-block 2110668 +just network-fixtures ``` ### Solidity Proof Verification diff --git a/contracts/abi/SP1ICS07Tendermint.json b/contracts/abi/SP1ICS07Tendermint.json new file mode 100644 index 000000000..6e9a45d --- /dev/null +++ b/contracts/abi/SP1ICS07Tendermint.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[{"name":"_ics07ProgramVkey","type":"bytes32","internalType":"bytes32"},{"name":"_verifier","type":"address","internalType":"address"},{"name":"_clientState","type":"bytes","internalType":"bytes"},{"name":"_consensusState","type":"bytes","internalType":"bytes"}],"stateMutability":"nonpayable"},{"type":"function","name":"ALLOWED_SP1_CLOCK_DRIFT","inputs":[],"outputs":[{"name":"","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"clientState","inputs":[],"outputs":[{"name":"chain_id","type":"string","internalType":"string"},{"name":"trust_level","type":"tuple","internalType":"struct ICS07Tendermint.TrustThreshold","components":[{"name":"numerator","type":"uint64","internalType":"uint64"},{"name":"denominator","type":"uint64","internalType":"uint64"}]},{"name":"latest_height","type":"tuple","internalType":"struct ICS07Tendermint.Height","components":[{"name":"revision_number","type":"uint64","internalType":"uint64"},{"name":"revision_height","type":"uint64","internalType":"uint64"}]},{"name":"trusting_period","type":"uint64","internalType":"uint64"},{"name":"unbonding_period","type":"uint64","internalType":"uint64"},{"name":"is_frozen","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"consensusStates","inputs":[{"name":"","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"timestamp","type":"uint64","internalType":"uint64"},{"name":"root","type":"bytes","internalType":"bytes"},{"name":"next_validators_hash","type":"bytes","internalType":"bytes"}],"stateMutability":"view"},{"type":"function","name":"getClientState","inputs":[],"outputs":[{"name":"","type":"tuple","internalType":"struct ICS07Tendermint.ClientState","components":[{"name":"chain_id","type":"string","internalType":"string"},{"name":"trust_level","type":"tuple","internalType":"struct ICS07Tendermint.TrustThreshold","components":[{"name":"numerator","type":"uint64","internalType":"uint64"},{"name":"denominator","type":"uint64","internalType":"uint64"}]},{"name":"latest_height","type":"tuple","internalType":"struct ICS07Tendermint.Height","components":[{"name":"revision_number","type":"uint64","internalType":"uint64"},{"name":"revision_height","type":"uint64","internalType":"uint64"}]},{"name":"trusting_period","type":"uint64","internalType":"uint64"},{"name":"unbonding_period","type":"uint64","internalType":"uint64"},{"name":"is_frozen","type":"bool","internalType":"bool"}]}],"stateMutability":"view"},{"type":"function","name":"getConsensusState","inputs":[{"name":"revisionHeight","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"","type":"tuple","internalType":"struct ICS07Tendermint.ConsensusState","components":[{"name":"timestamp","type":"uint64","internalType":"uint64"},{"name":"root","type":"bytes","internalType":"bytes"},{"name":"next_validators_hash","type":"bytes","internalType":"bytes"}]}],"stateMutability":"view"},{"type":"function","name":"ics07UpdateClientProgramVkey","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"validatePublicValues","inputs":[{"name":"output","type":"tuple","internalType":"struct SP1ICS07Tendermint.SP1ICS07TendermintOutput","components":[{"name":"trusted_consensus_state","type":"tuple","internalType":"struct ICS07Tendermint.ConsensusState","components":[{"name":"timestamp","type":"uint64","internalType":"uint64"},{"name":"root","type":"bytes","internalType":"bytes"},{"name":"next_validators_hash","type":"bytes","internalType":"bytes"}]},{"name":"new_consensus_state","type":"tuple","internalType":"struct ICS07Tendermint.ConsensusState","components":[{"name":"timestamp","type":"uint64","internalType":"uint64"},{"name":"root","type":"bytes","internalType":"bytes"},{"name":"next_validators_hash","type":"bytes","internalType":"bytes"}]},{"name":"env","type":"tuple","internalType":"struct SP1ICS07Tendermint.Env","components":[{"name":"chain_id","type":"string","internalType":"string"},{"name":"trust_threshold","type":"tuple","internalType":"struct ICS07Tendermint.TrustThreshold","components":[{"name":"numerator","type":"uint64","internalType":"uint64"},{"name":"denominator","type":"uint64","internalType":"uint64"}]},{"name":"trusting_period","type":"uint64","internalType":"uint64"},{"name":"now","type":"uint64","internalType":"uint64"}]},{"name":"trusted_height","type":"tuple","internalType":"struct ICS07Tendermint.Height","components":[{"name":"revision_number","type":"uint64","internalType":"uint64"},{"name":"revision_height","type":"uint64","internalType":"uint64"}]},{"name":"new_height","type":"tuple","internalType":"struct ICS07Tendermint.Height","components":[{"name":"revision_number","type":"uint64","internalType":"uint64"},{"name":"revision_height","type":"uint64","internalType":"uint64"}]}]}],"outputs":[],"stateMutability":"view"},{"type":"function","name":"verifier","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract ISP1Verifier"}],"stateMutability":"view"},{"type":"function","name":"verifyIcs07UpdateClientProof","inputs":[{"name":"proof","type":"bytes","internalType":"bytes"},{"name":"publicValues","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"}],"bytecode":{"object":"0x608060405234801561001057600080fd5b50604051611ecd380380611ecd83398101604081905261002f916102bd565b6000849055600180546001600160a01b0319166001600160a01b038516179055815161006490602090840181019084016103d9565b80516002908190610075908261053d565b506020828101518051600184018054928401516001600160401b039283166001600160801b031994851617680100000000000000009184168202179091556040860151805160028701805492870151918516928616929092179084168302179055606086015160039095018054608088015160a09098015196841694169390931795909116029390931760ff60801b1916600160801b9215159290920291909117909155815160009161012e91840181019084016105fb565b6004546801000000000000000090046001600160401b039081166000908152600660209081526040909120835181546001600160401b031916931692909217825582015191925082916001820190610186908261053d565b506040820151600282019061019b908261053d565b5090505050505050506106a6565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156101e1576101e16101a9565b60405290565b604051606081016001600160401b03811182821017156101e1576101e16101a9565b6000806001600160401b03841115610223576102236101a9565b50604051601f19601f85018116603f011681018181106001600160401b0382111715610251576102516101a9565b60405283815290508082840185101561026957600080fd5b60200160005b8481101561028757838101518282015260200161026f565b50600084820152509392505050565b600082601f8301126102a757600080fd5b6102b683835160208501610209565b9392505050565b600080600080608085870312156102d357600080fd5b845160208601519094506001600160a01b03811681146102f257600080fd5b60408601519093506001600160401b0381111561030e57600080fd5b61031a87828801610296565b606087015190935090506001600160401b0381111561033857600080fd5b61034487828801610296565b91505092959194509250565b80516001600160401b038116811461036757600080fd5b919050565b60006040828403121561037e57600080fd5b604080519081016001600160401b03811182821017156103a0576103a06101a9565b6040529050806103af83610350565b81526103bd60208401610350565b60208201525092915050565b8051801515811461036757600080fd5b6000602082840312156103eb57600080fd5b81516001600160401b0381111561040157600080fd5b8201610100818503121561041457600080fd5b61041c6101bf565b81516001600160401b0381111561043257600080fd5b8201601f8101861361044357600080fd5b61045286825160208401610209565b825250610462856020840161036c565b6020820152610474856060840161036c565b604082015261048560a08301610350565b606082015261049660c08301610350565b60808201526104a760e083016103c9565b60a0820152949350505050565b600181811c908216806104c857607f821691505b6020821081036104e857634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561053857806000526020600020601f840160051c810160208510156105155750805b601f840160051c820191505b818110156105355760008155600101610521565b50505b505050565b81516001600160401b03811115610556576105566101a9565b61056a8161056484546104b4565b846104ee565b6020601f82116001811461059e57600083156105865750848201515b600019600385901b1c1916600184901b178455610535565b600084815260208120601f198516915b828110156105ce57878501518255602094850194600190920191016105ae565b50848210156105ec5786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b60006020828403121561060d57600080fd5b81516001600160401b0381111561062357600080fd5b82016060818503121561063557600080fd5b61063d6101e7565b61064682610350565b815260208201516001600160401b0381111561066157600080fd5b61066d86828501610296565b60208301525060408201516001600160401b0381111561068c57600080fd5b61069886828501610296565b604083015250949350505050565b611818806106b56000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063975c079611610066578063975c079614610115578063bd3ce6b01461012c578063e08322d514610146578063edce8bdc14610168578063ef913a4b1461018857600080fd5b80632b7ac3f3146100985780632c3ee474146100c85780633f01b86f146100ed57806361d311c514610102575b600080fd5b6001546100ab906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d5651b48eb57e00081565b6040516001600160401b0390911681526020016100bf565b6101006100fb366004610f05565b61019d565b005b610100610110366004610fee565b610594565b61011e60005481565b6040519081526020016100bf565b6101346106b7565b6040516100bf969594939291906110a5565b61015961015436600461112d565b6107af565b6040516100bf9392919061114a565b61017b61017636600461112d565b6108ec565b6040516100bf9190611188565b610190610a77565b6040516100bf91906111dd565b600554600160801b900460ff16156102085760405162461bcd60e51b8152602060048201526024808201527f535031494353303754656e6465726d696e743a20636c69656e7420697320667260448201526337bd32b760e11b60648201526084015b60405180910390fd5b651b48eb57e000816040015160600151610222919061129c565b6001600160401b031661023942633b9aca006112c1565b11156102955760405162461bcd60e51b815260206004820152602560248201527f535031494353303754656e6465726d696e743a20696e76616c69642074696d6560448201526407374616d760dc1b60648201526084016101ff565b6040516102a490600290611312565b604051809103902081604001516000015180519060200120146103175760405162461bcd60e51b815260206004820152602560248201527f535031494353303754656e6465726d696e743a20636861696e204944206d69736044820152640dac2e8c6d60db1b60648201526084016101ff565b600354604082015160200151516001600160401b03908116911614801561035f5750600354604082015160209081015101516001600160401b03908116600160401b90920416145b6103c05760405162461bcd60e51b815260206004820152602c60248201527f535031494353303754656e6465726d696e743a2074727573742074687265736860448201526b0ded8c840dad2e6dac2e8c6d60a31b60648201526084016101ff565b60055460408083015101516001600160401b0390811691161461043a5760405162461bcd60e51b815260206004820152602c60248201527f535031494353303754656e6465726d696e743a207472757374696e672070657260448201526b0d2dec840dad2e6dac2e8c6d60a31b60648201526084016101ff565b60055460408083015101516001600160401b03908116600160401b90920416146104bc5760405162461bcd60e51b815260206004820152602d60248201527f535031494353303754656e6465726d696e743a20756e626f6e64696e6720706560448201526c0e4d2dec840dad2e6dac2e8c6d609b1b60648201526084016101ff565b80516040516104ce9190602001611188565b60408051601f19818403018152828252805160209182012060608501518201516001600160401b031660009081526006835292909220919261051192910161140a565b60405160208183030381529060405280519060200120146105915760405162461bcd60e51b815260206004820152603460248201527f535031494353303754656e6465726d696e743a207472757374656420636f6e736044820152730cadce6eae640e6e8c2e8ca40dad2e6dac2e8c6d60631b60648201526084016101ff565b50565b6000818060200190518101906105aa91906115e0565b90506105b58161019d565b60015460005460405163020a49e360e51b81526001600160a01b03909216916341493c60916105ea91869088906004016116bc565b60006040518083038186803b15801561060257600080fd5b505afa158015610616573d6000803e3d6000fd5b5050505060808101518051600480546020938401516001600160401b039384166fffffffffffffffffffffffffffffffff1990921691909117600160401b918416918202179091558284015160009182526006845260409091208151815467ffffffffffffffff1916931692909217825591820151600182019061069a9082611724565b50604082015160028201906106af9082611724565b505050505050565b6002805481906106c6906112d8565b80601f01602080910402602001604051908101604052809291908181526020018280546106f2906112d8565b801561073f5780601f106107145761010080835404028352916020019161073f565b820191906000526020600020905b81548152906001019060200180831161072257829003601f168201915b505060408051808201825260018701546001600160401b038082168352600160401b918290048116602080850191909152845180860190955260028a015480831686528390048216908501526003909801549697919692955082821694508204169150600160801b900460ff1686565b600660205260009081526040902080546001820180546001600160401b0390921692916107db906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610807906112d8565b80156108545780601f1061082957610100808354040283529160200191610854565b820191906000526020600020905b81548152906001019060200180831161083757829003601f168201915b505050505090806002018054610869906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610895906112d8565b80156108e25780601f106108b7576101008083540402835291602001916108e2565b820191906000526020600020905b8154815290600101906020018083116108c557829003601f168201915b5050505050905083565b610919604051806060016040528060006001600160401b0316815260200160608152602001606081525090565b6001600160401b03808316600090815260066020908152604091829020825160608101909352805490931682526001830180549293929184019161095c906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610988906112d8565b80156109d55780601f106109aa576101008083540402835291602001916109d5565b820191906000526020600020905b8154815290600101906020018083116109b857829003601f168201915b505050505081526020016002820180546109ee906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1a906112d8565b8015610a675780601f10610a3c57610100808354040283529160200191610a67565b820191906000526020600020905b815481529060010190602001808311610a4a57829003601f168201915b5050505050815250509050919050565b610a7f610ba6565b60026040518060c0016040529081600082018054610a9c906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610ac8906112d8565b8015610b155780601f10610aea57610100808354040283529160200191610b15565b820191906000526020600020905b815481529060010190602001808311610af857829003601f168201915b505050918352505060408051808201825260018401546001600160401b038082168352600160401b918290048116602080850191909152808601939093528351808501855260028701548083168252839004821693810193909352928401919091526003909301548082166060840152928304166080820152600160801b90910460ff16151560a090910152919050565b6040518060c0016040528060608152602001610be7604051806040016040528060006001600160401b0316815260200160006001600160401b031681525090565b8152602001610c1b604051806040016040528060006001600160401b0316815260200160006001600160401b031681525090565b81526000602082018190526040820181905260609091015290565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715610c6e57610c6e610c36565b60405290565b604080519081016001600160401b0381118282101715610c6e57610c6e610c36565b604051608081016001600160401b0381118282101715610c6e57610c6e610c36565b60405160a081016001600160401b0381118282101715610c6e57610c6e610c36565b604051601f8201601f191681016001600160401b0381118282101715610d0257610d02610c36565b604052919050565b6001600160401b038116811461059157600080fd5b60006001600160401b03821115610d3857610d38610c36565b50601f01601f191660200190565b6000610d59610d5484610d1f565b610cda565b9050828152838383011115610d6d57600080fd5b828260208301376000602084830101529392505050565b600082601f830112610d9557600080fd5b610da483833560208501610d46565b9392505050565b600060608284031215610dbd57600080fd5b610dc5610c4c565b90508135610dd281610d0a565b815260208201356001600160401b03811115610ded57600080fd5b610df984828501610d84565b60208301525060408201356001600160401b03811115610e1857600080fd5b610e2484828501610d84565b60408301525092915050565b600060408284031215610e4257600080fd5b610e4a610c74565b90508135610e5781610d0a565b81526020820135610e6781610d0a565b602082015292915050565b600060a08284031215610e8457600080fd5b610e8c610c96565b905081356001600160401b03811115610ea457600080fd5b8201601f81018413610eb557600080fd5b610ec484823560208401610d46565b825250610ed48360208401610e30565b60208201526060820135610ee781610d0a565b60408201526080820135610efa81610d0a565b606082015292915050565b600060208284031215610f1757600080fd5b81356001600160401b03811115610f2d57600080fd5b820160e08185031215610f3f57600080fd5b610f47610cb8565b81356001600160401b03811115610f5d57600080fd5b610f6986828501610dab565b82525060208201356001600160401b03811115610f8557600080fd5b610f9186828501610dab565b60208301525060408201356001600160401b03811115610fb057600080fd5b610fbc86828501610e72565b604083015250610fcf8560608401610e30565b6060820152610fe18560a08401610e30565b6080820152949350505050565b6000806040838503121561100157600080fd5b82356001600160401b0381111561101757600080fd5b61102385828601610d84565b92505060208301356001600160401b0381111561103f57600080fd5b61104b85828601610d84565b9150509250929050565b60005b83811015611070578181015183820152602001611058565b50506000910152565b60008151808452611091816020860160208601611055565b601f01601f19169290920160200192915050565b610100815260006110ba610100830189611079565b90506110df602083018880516001600160401b03908116835260209182015116910152565b85516001600160401b03908116606084015260208701511660808301526001600160401b03851660a08301526001600160401b03841660c083015282151560e0830152979650505050505050565b60006020828403121561113f57600080fd5b8135610da481610d0a565b6001600160401b038416815260606020820152600061116c6060830185611079565b828103604084015261117e8185611079565b9695505050505050565b602081526001600160401b03825116602082015260006020830151606060408401526111b76080840182611079565b90506040840151601f198483030160608501526111d48282611079565b95945050505050565b602081526000825161010060208401526111fb610120840182611079565b90506020840151611225604085018280516001600160401b03908116835260209182015116910152565b50604084015180516001600160401b03908116608086015260208201511660a0850152506001600160401b0360608501511660c08401526001600160401b0360808501511660e084015260a084015115156101008401528091505092915050565b634e487b7160e01b600052601160045260246000fd5b6001600160401b0381811683821601908111156112bb576112bb611286565b92915050565b80820281158282048414176112bb576112bb611286565b600181811c908216806112ec57607f821691505b60208210810361130c57634e487b7160e01b600052602260045260246000fd5b50919050565b6000808354611320816112d8565b600182168015611337576001811461134c5761137c565b60ff198316865281151582028601935061137c565b86600052602060002060005b8381101561137457815488820152600190910190602001611358565b505081860193505b509195945050505050565b60008154611394816112d8565b8085526001821680156113ae57600181146113ca57611401565b60ff1983166020870152602082151560051b8701019350611401565b84600052602060002060005b838110156113f85781546020828a0101526001820191506020810190506113d6565b87016020019450505b50505092915050565b602081526001600160401b0382541660208201526060604082015260006114376080830160018501611387565b828103601f190160608401526114508160028601611387565b949350505050565b6000611466610d5484610d1f565b905082815283838301111561147a57600080fd5b610da4836020830184611055565b600082601f83011261149957600080fd5b610da483835160208501611458565b6000606082840312156114ba57600080fd5b6114c2610c4c565b905081516114cf81610d0a565b815260208201516001600160401b038111156114ea57600080fd5b6114f684828501611488565b60208301525060408201516001600160401b0381111561151557600080fd5b610e2484828501611488565b60006040828403121561153357600080fd5b61153b610c74565b9050815161154881610d0a565b81526020820151610e6781610d0a565b600060a0828403121561156a57600080fd5b611572610c96565b905081516001600160401b0381111561158a57600080fd5b8201601f8101841361159b57600080fd5b6115aa84825160208401611458565b8252506115ba8360208401611521565b602082015260608201516115cd81610d0a565b60408201526080820151610efa81610d0a565b6000602082840312156115f257600080fd5b81516001600160401b0381111561160857600080fd5b820160e0818503121561161a57600080fd5b611622610cb8565b81516001600160401b0381111561163857600080fd5b611644868285016114a8565b82525060208201516001600160401b0381111561166057600080fd5b61166c868285016114a8565b60208301525060408201516001600160401b0381111561168b57600080fd5b61169786828501611558565b6040830152506116aa8560608401611521565b6060820152610fe18560a08401611521565b83815260606020820152600061116c6060830185611079565b601f82111561171f57806000526020600020601f840160051c810160208510156116fc5750805b601f840160051c820191505b8181101561171c5760008155600101611708565b50505b505050565b81516001600160401b0381111561173d5761173d610c36565b6117518161174b84546112d8565b846116d5565b6020601f821160018114611785576000831561176d5750848201515b600019600385901b1c1916600184901b17845561171c565b600084815260208120601f198516915b828110156117b55787850151825560209485019460019092019101611795565b50848210156117d35786840151600019600387901b60f8161c191681555b50505050600190811b0190555056fea26469706673582212200237231a329df0120d02664206ad69da3d8c41250b5f79345de2d436d376746c64736f6c634300081a0033","sourceMap":"408:5985:29:-:0;;;2424:609;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2587:28;:48;;;2645:8;:34;;-1:-1:-1;;;;;;2645:34:29;-1:-1:-1;;;;;2645:34:29;;;;;2704:55;;;;;;;;;;;;;;:::i;:::-;2690:69;;:11;;;;:69;;:11;:69;:::i;:::-;-1:-1:-1;2690:69:29;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2690:69:29;;;-1:-1:-1;;;;;;2690:69:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;2690:69:29;-1:-1:-1;;;2690:69:29;;;;;;;;;;;;;;2824:95;;-1:-1:-1;;2824:95:29;;;;;;;;;;:::i;:::-;2958:25;:41;;;;-1:-1:-1;;;;;2958:41:29;;;2929:80;;;;:15;:80;;;;;;;;:97;;;;-1:-1:-1;;;;;;2929:97:29;;;;;;;;;;;;;;-1:-1:-1;2929:97:29;;-1:-1:-1;2929:97:29;;;;;;;:::i;:::-;-1:-1:-1;2929:97:29;;;;;;;;;;;;:::i;:::-;;;;;2577:456;2424:609;;;;408:5985;;14:127:32;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:248;213:2;207:9;255:4;243:17;;-1:-1:-1;;;;;275:34:32;;311:22;;;272:62;269:88;;;337:18;;:::i;:::-;373:2;366:22;146:248;:::o;399:253::-;471:2;465:9;513:4;501:17;;-1:-1:-1;;;;;533:34:32;;569:22;;;530:62;527:88;;;595:18;;:::i;657:837::-;732:5;;-1:-1:-1;;;;;777:30:32;;774:56;;;810:18;;:::i;:::-;-1:-1:-1;965:2:32;959:9;-1:-1:-1;;878:2:32;857:15;;853:29;;1023:2;1011:15;1007:29;995:42;;1088:22;;;-1:-1:-1;;;;;1052:34:32;;1049:62;1046:88;;;1114:18;;:::i;:::-;1150:2;1143:22;1198;;;1183:6;-1:-1:-1;1183:6:32;1235:16;;;1232:25;-1:-1:-1;1229:45:32;;;1270:1;1267;1260:12;1229:45;1306:4;1294:17;1329:1;1339:113;1353:6;1350:1;1347:13;1339:113;;;1429:11;;;1423:18;1410:11;;;1403:39;1375:2;1368:10;1339:113;;;1343:3;1486:1;1477:6;1472:3;1468:16;1461:27;;657:837;;;;;:::o;1499:235::-;1552:5;1605:3;1598:4;1590:6;1586:17;1582:27;1572:55;;1623:1;1620;1613:12;1572:55;1645:83;1724:3;1715:6;1709:13;1702:4;1694:6;1690:17;1645:83;:::i;:::-;1636:92;1499:235;-1:-1:-1;;;1499:235:32:o;1739:782::-;1854:6;1862;1870;1878;1931:3;1919:9;1910:7;1906:23;1902:33;1899:53;;;1948:1;1945;1938:12;1899:53;1971:16;;2030:2;2015:18;;2009:25;1971:16;;-1:-1:-1;;;;;;2063:31:32;;2053:42;;2043:70;;2109:1;2106;2099:12;2043:70;2181:2;2166:18;;2160:25;2132:5;;-1:-1:-1;;;;;;2197:30:32;;2194:50;;;2240:1;2237;2230:12;2194:50;2263:60;2315:7;2306:6;2295:9;2291:22;2263:60;:::i;:::-;2369:2;2354:18;;2348:25;2253:70;;-1:-1:-1;2348:25:32;-1:-1:-1;;;;;;2385:32:32;;2382:52;;;2430:1;2427;2420:12;2382:52;2453:62;2507:7;2496:8;2485:9;2481:24;2453:62;:::i;:::-;2443:72;;;1739:782;;;;;;;:::o;2526:175::-;2604:13;;-1:-1:-1;;;;;2646:30:32;;2636:41;;2626:69;;2691:1;2688;2681:12;2626:69;2526:175;;;:::o;2706:546::-;2778:5;2826:4;2814:9;2809:3;2805:19;2801:30;2798:50;;;2844:1;2841;2834:12;2798:50;2897:4;2891:11;;;2929:17;;-1:-1:-1;;;;;2961:34:32;;2997:22;;;2958:62;2955:88;;;3023:18;;:::i;:::-;3059:4;3052:24;3094:6;-1:-1:-1;3094:6:32;3124:39;3153:9;3124:39;:::i;:::-;3116:6;3109:55;3197:48;3241:2;3230:9;3226:18;3197:48;:::i;:::-;3192:2;3184:6;3180:15;3173:73;;2706:546;;;;:::o;3257:164::-;3333:13;;3382;;3375:21;3365:32;;3355:60;;3411:1;3408;3401:12;3426:1160;3526:6;3579:2;3567:9;3558:7;3554:23;3550:32;3547:52;;;3595:1;3592;3585:12;3547:52;3622:16;;-1:-1:-1;;;;;3650:30:32;;3647:50;;;3693:1;3690;3683:12;3647:50;3716:22;;3772:6;3754:16;;;3750:29;3747:49;;;3792:1;3789;3782:12;3747:49;3818:17;;:::i;:::-;3860:9;;-1:-1:-1;;;;;3881:32:32;;3878:52;;;3926:1;3923;3916:12;3878:52;3949:17;;3997:4;3989:13;;3985:27;-1:-1:-1;3975:55:32;;4026:1;4023;4016:12;3975:55;4053:77;4122:7;4117:2;4111:9;4106:2;4102;4098:11;4053:77;:::i;:::-;4046:5;4039:92;;4163:65;4220:7;4215:2;4211;4207:11;4163:65;:::i;:::-;4158:2;4151:5;4147:14;4140:89;4263:65;4320:7;4315:2;4311;4307:11;4263:65;:::i;:::-;4256:4;4249:5;4245:16;4238:91;4361:42;4398:3;4394:2;4390:12;4361:42;:::i;:::-;4356:2;4349:5;4345:14;4338:66;4438:43;4475:4;4471:2;4467:13;4438:43;:::i;:::-;4431:4;4424:5;4420:16;4413:69;4515:40;4550:3;4546:2;4542:12;4515:40;:::i;:::-;4509:3;4498:15;;4491:65;4502:5;3426:1160;-1:-1:-1;;;;3426:1160:32:o;4591:380::-;4670:1;4666:12;;;;4713;;;4734:61;;4788:4;4780:6;4776:17;4766:27;;4734:61;4841:2;4833:6;4830:14;4810:18;4807:38;4804:161;;4887:10;4882:3;4878:20;4875:1;4868:31;4922:4;4919:1;4912:15;4950:4;4947:1;4940:15;4804:161;;4591:380;;;:::o;5102:518::-;5204:2;5199:3;5196:11;5193:421;;;5240:5;5237:1;5230:16;5284:4;5281:1;5271:18;5354:2;5342:10;5338:19;5335:1;5331:27;5325:4;5321:38;5390:4;5378:10;5375:20;5372:47;;;-1:-1:-1;5413:4:32;5372:47;5468:2;5463:3;5459:12;5456:1;5452:20;5446:4;5442:31;5432:41;;5523:81;5541:2;5534:5;5531:13;5523:81;;;5600:1;5586:16;;5567:1;5556:13;5523:81;;;5527:3;;5193:421;5102:518;;;:::o;5796:1299::-;5916:10;;-1:-1:-1;;;;;5938:30:32;;5935:56;;;5971:18;;:::i;:::-;6000:97;6090:6;6050:38;6082:4;6076:11;6050:38;:::i;:::-;6044:4;6000:97;:::i;:::-;6146:4;6177:2;6166:14;;6194:1;6189:649;;;;6882:1;6899:6;6896:89;;;-1:-1:-1;6951:19:32;;;6945:26;6896:89;-1:-1:-1;;5753:1:32;5749:11;;;5745:24;5741:29;5731:40;5777:1;5773:11;;;5728:57;6998:81;;6159:930;;6189:649;5049:1;5042:14;;;5086:4;5073:18;;-1:-1:-1;;6225:20:32;;;6343:222;6357:7;6354:1;6351:14;6343:222;;;6439:19;;;6433:26;6418:42;;6546:4;6531:20;;;;6499:1;6487:14;;;;6373:12;6343:222;;;6347:3;6593:6;6584:7;6581:19;6578:201;;;6654:19;;;6648:26;-1:-1:-1;;6737:1:32;6733:14;;;6749:3;6729:24;6725:37;6721:42;6706:58;6691:74;;6578:201;-1:-1:-1;;;;6825:1:32;6809:14;;;6805:22;6792:36;;-1:-1:-1;5796:1299:32:o;7100:885::-;7203:6;7256:2;7244:9;7235:7;7231:23;7227:32;7224:52;;;7272:1;7269;7262:12;7224:52;7299:16;;-1:-1:-1;;;;;7327:30:32;;7324:50;;;7370:1;7367;7360:12;7324:50;7393:22;;7449:4;7431:16;;;7427:27;7424:47;;;7467:1;7464;7457:12;7424:47;7493:22;;:::i;:::-;7538:32;7567:2;7538:32;:::i;:::-;7524:47;;7610:2;7602:11;;7596:18;-1:-1:-1;;;;;7626:32:32;;7623:52;;;7671:1;7668;7661:12;7623:52;7707:55;7754:7;7743:8;7739:2;7735:17;7707:55;:::i;:::-;7702:2;7691:14;;7684:79;-1:-1:-1;7802:2:32;7794:11;;7788:18;-1:-1:-1;;;;;7818:32:32;;7815:52;;;7863:1;7860;7853:12;7815:52;7899:55;7946:7;7935:8;7931:2;7927:17;7899:55;:::i;:::-;7894:2;7883:14;;7876:79;-1:-1:-1;7887:5:32;7100:885;-1:-1:-1;;;;7100:885:32:o;7990:1297::-;408:5985:29;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063975c079611610066578063975c079614610115578063bd3ce6b01461012c578063e08322d514610146578063edce8bdc14610168578063ef913a4b1461018857600080fd5b80632b7ac3f3146100985780632c3ee474146100c85780633f01b86f146100ed57806361d311c514610102575b600080fd5b6001546100ab906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d5651b48eb57e00081565b6040516001600160401b0390911681526020016100bf565b6101006100fb366004610f05565b61019d565b005b610100610110366004610fee565b610594565b61011e60005481565b6040519081526020016100bf565b6101346106b7565b6040516100bf969594939291906110a5565b61015961015436600461112d565b6107af565b6040516100bf9392919061114a565b61017b61017636600461112d565b6108ec565b6040516100bf9190611188565b610190610a77565b6040516100bf91906111dd565b600554600160801b900460ff16156102085760405162461bcd60e51b8152602060048201526024808201527f535031494353303754656e6465726d696e743a20636c69656e7420697320667260448201526337bd32b760e11b60648201526084015b60405180910390fd5b651b48eb57e000816040015160600151610222919061129c565b6001600160401b031661023942633b9aca006112c1565b11156102955760405162461bcd60e51b815260206004820152602560248201527f535031494353303754656e6465726d696e743a20696e76616c69642074696d6560448201526407374616d760dc1b60648201526084016101ff565b6040516102a490600290611312565b604051809103902081604001516000015180519060200120146103175760405162461bcd60e51b815260206004820152602560248201527f535031494353303754656e6465726d696e743a20636861696e204944206d69736044820152640dac2e8c6d60db1b60648201526084016101ff565b600354604082015160200151516001600160401b03908116911614801561035f5750600354604082015160209081015101516001600160401b03908116600160401b90920416145b6103c05760405162461bcd60e51b815260206004820152602c60248201527f535031494353303754656e6465726d696e743a2074727573742074687265736860448201526b0ded8c840dad2e6dac2e8c6d60a31b60648201526084016101ff565b60055460408083015101516001600160401b0390811691161461043a5760405162461bcd60e51b815260206004820152602c60248201527f535031494353303754656e6465726d696e743a207472757374696e672070657260448201526b0d2dec840dad2e6dac2e8c6d60a31b60648201526084016101ff565b60055460408083015101516001600160401b03908116600160401b90920416146104bc5760405162461bcd60e51b815260206004820152602d60248201527f535031494353303754656e6465726d696e743a20756e626f6e64696e6720706560448201526c0e4d2dec840dad2e6dac2e8c6d609b1b60648201526084016101ff565b80516040516104ce9190602001611188565b60408051601f19818403018152828252805160209182012060608501518201516001600160401b031660009081526006835292909220919261051192910161140a565b60405160208183030381529060405280519060200120146105915760405162461bcd60e51b815260206004820152603460248201527f535031494353303754656e6465726d696e743a207472757374656420636f6e736044820152730cadce6eae640e6e8c2e8ca40dad2e6dac2e8c6d60631b60648201526084016101ff565b50565b6000818060200190518101906105aa91906115e0565b90506105b58161019d565b60015460005460405163020a49e360e51b81526001600160a01b03909216916341493c60916105ea91869088906004016116bc565b60006040518083038186803b15801561060257600080fd5b505afa158015610616573d6000803e3d6000fd5b5050505060808101518051600480546020938401516001600160401b039384166fffffffffffffffffffffffffffffffff1990921691909117600160401b918416918202179091558284015160009182526006845260409091208151815467ffffffffffffffff1916931692909217825591820151600182019061069a9082611724565b50604082015160028201906106af9082611724565b505050505050565b6002805481906106c6906112d8565b80601f01602080910402602001604051908101604052809291908181526020018280546106f2906112d8565b801561073f5780601f106107145761010080835404028352916020019161073f565b820191906000526020600020905b81548152906001019060200180831161072257829003601f168201915b505060408051808201825260018701546001600160401b038082168352600160401b918290048116602080850191909152845180860190955260028a015480831686528390048216908501526003909801549697919692955082821694508204169150600160801b900460ff1686565b600660205260009081526040902080546001820180546001600160401b0390921692916107db906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610807906112d8565b80156108545780601f1061082957610100808354040283529160200191610854565b820191906000526020600020905b81548152906001019060200180831161083757829003601f168201915b505050505090806002018054610869906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610895906112d8565b80156108e25780601f106108b7576101008083540402835291602001916108e2565b820191906000526020600020905b8154815290600101906020018083116108c557829003601f168201915b5050505050905083565b610919604051806060016040528060006001600160401b0316815260200160608152602001606081525090565b6001600160401b03808316600090815260066020908152604091829020825160608101909352805490931682526001830180549293929184019161095c906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610988906112d8565b80156109d55780601f106109aa576101008083540402835291602001916109d5565b820191906000526020600020905b8154815290600101906020018083116109b857829003601f168201915b505050505081526020016002820180546109ee906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1a906112d8565b8015610a675780601f10610a3c57610100808354040283529160200191610a67565b820191906000526020600020905b815481529060010190602001808311610a4a57829003601f168201915b5050505050815250509050919050565b610a7f610ba6565b60026040518060c0016040529081600082018054610a9c906112d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610ac8906112d8565b8015610b155780601f10610aea57610100808354040283529160200191610b15565b820191906000526020600020905b815481529060010190602001808311610af857829003601f168201915b505050918352505060408051808201825260018401546001600160401b038082168352600160401b918290048116602080850191909152808601939093528351808501855260028701548083168252839004821693810193909352928401919091526003909301548082166060840152928304166080820152600160801b90910460ff16151560a090910152919050565b6040518060c0016040528060608152602001610be7604051806040016040528060006001600160401b0316815260200160006001600160401b031681525090565b8152602001610c1b604051806040016040528060006001600160401b0316815260200160006001600160401b031681525090565b81526000602082018190526040820181905260609091015290565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715610c6e57610c6e610c36565b60405290565b604080519081016001600160401b0381118282101715610c6e57610c6e610c36565b604051608081016001600160401b0381118282101715610c6e57610c6e610c36565b60405160a081016001600160401b0381118282101715610c6e57610c6e610c36565b604051601f8201601f191681016001600160401b0381118282101715610d0257610d02610c36565b604052919050565b6001600160401b038116811461059157600080fd5b60006001600160401b03821115610d3857610d38610c36565b50601f01601f191660200190565b6000610d59610d5484610d1f565b610cda565b9050828152838383011115610d6d57600080fd5b828260208301376000602084830101529392505050565b600082601f830112610d9557600080fd5b610da483833560208501610d46565b9392505050565b600060608284031215610dbd57600080fd5b610dc5610c4c565b90508135610dd281610d0a565b815260208201356001600160401b03811115610ded57600080fd5b610df984828501610d84565b60208301525060408201356001600160401b03811115610e1857600080fd5b610e2484828501610d84565b60408301525092915050565b600060408284031215610e4257600080fd5b610e4a610c74565b90508135610e5781610d0a565b81526020820135610e6781610d0a565b602082015292915050565b600060a08284031215610e8457600080fd5b610e8c610c96565b905081356001600160401b03811115610ea457600080fd5b8201601f81018413610eb557600080fd5b610ec484823560208401610d46565b825250610ed48360208401610e30565b60208201526060820135610ee781610d0a565b60408201526080820135610efa81610d0a565b606082015292915050565b600060208284031215610f1757600080fd5b81356001600160401b03811115610f2d57600080fd5b820160e08185031215610f3f57600080fd5b610f47610cb8565b81356001600160401b03811115610f5d57600080fd5b610f6986828501610dab565b82525060208201356001600160401b03811115610f8557600080fd5b610f9186828501610dab565b60208301525060408201356001600160401b03811115610fb057600080fd5b610fbc86828501610e72565b604083015250610fcf8560608401610e30565b6060820152610fe18560a08401610e30565b6080820152949350505050565b6000806040838503121561100157600080fd5b82356001600160401b0381111561101757600080fd5b61102385828601610d84565b92505060208301356001600160401b0381111561103f57600080fd5b61104b85828601610d84565b9150509250929050565b60005b83811015611070578181015183820152602001611058565b50506000910152565b60008151808452611091816020860160208601611055565b601f01601f19169290920160200192915050565b610100815260006110ba610100830189611079565b90506110df602083018880516001600160401b03908116835260209182015116910152565b85516001600160401b03908116606084015260208701511660808301526001600160401b03851660a08301526001600160401b03841660c083015282151560e0830152979650505050505050565b60006020828403121561113f57600080fd5b8135610da481610d0a565b6001600160401b038416815260606020820152600061116c6060830185611079565b828103604084015261117e8185611079565b9695505050505050565b602081526001600160401b03825116602082015260006020830151606060408401526111b76080840182611079565b90506040840151601f198483030160608501526111d48282611079565b95945050505050565b602081526000825161010060208401526111fb610120840182611079565b90506020840151611225604085018280516001600160401b03908116835260209182015116910152565b50604084015180516001600160401b03908116608086015260208201511660a0850152506001600160401b0360608501511660c08401526001600160401b0360808501511660e084015260a084015115156101008401528091505092915050565b634e487b7160e01b600052601160045260246000fd5b6001600160401b0381811683821601908111156112bb576112bb611286565b92915050565b80820281158282048414176112bb576112bb611286565b600181811c908216806112ec57607f821691505b60208210810361130c57634e487b7160e01b600052602260045260246000fd5b50919050565b6000808354611320816112d8565b600182168015611337576001811461134c5761137c565b60ff198316865281151582028601935061137c565b86600052602060002060005b8381101561137457815488820152600190910190602001611358565b505081860193505b509195945050505050565b60008154611394816112d8565b8085526001821680156113ae57600181146113ca57611401565b60ff1983166020870152602082151560051b8701019350611401565b84600052602060002060005b838110156113f85781546020828a0101526001820191506020810190506113d6565b87016020019450505b50505092915050565b602081526001600160401b0382541660208201526060604082015260006114376080830160018501611387565b828103601f190160608401526114508160028601611387565b949350505050565b6000611466610d5484610d1f565b905082815283838301111561147a57600080fd5b610da4836020830184611055565b600082601f83011261149957600080fd5b610da483835160208501611458565b6000606082840312156114ba57600080fd5b6114c2610c4c565b905081516114cf81610d0a565b815260208201516001600160401b038111156114ea57600080fd5b6114f684828501611488565b60208301525060408201516001600160401b0381111561151557600080fd5b610e2484828501611488565b60006040828403121561153357600080fd5b61153b610c74565b9050815161154881610d0a565b81526020820151610e6781610d0a565b600060a0828403121561156a57600080fd5b611572610c96565b905081516001600160401b0381111561158a57600080fd5b8201601f8101841361159b57600080fd5b6115aa84825160208401611458565b8252506115ba8360208401611521565b602082015260608201516115cd81610d0a565b60408201526080820151610efa81610d0a565b6000602082840312156115f257600080fd5b81516001600160401b0381111561160857600080fd5b820160e0818503121561161a57600080fd5b611622610cb8565b81516001600160401b0381111561163857600080fd5b611644868285016114a8565b82525060208201516001600160401b0381111561166057600080fd5b61166c868285016114a8565b60208301525060408201516001600160401b0381111561168b57600080fd5b61169786828501611558565b6040830152506116aa8560608401611521565b6060820152610fe18560a08401611521565b83815260606020820152600061116c6060830185611079565b601f82111561171f57806000526020600020601f840160051c810160208510156116fc5750805b601f840160051c820191505b8181101561171c5760008155600101611708565b50505b505050565b81516001600160401b0381111561173d5761173d610c36565b6117518161174b84546112d8565b846116d5565b6020601f821160018114611785576000831561176d5750848201515b600019600385901b1c1916600184901b17845561171c565b600084815260208120601f198516915b828110156117b55787850151825560209485019460019092019101611795565b50848210156117d35786840151600019600387901b60f8161c191681555b50505050600190811b0190555056fea26469706673582212200237231a329df0120d02664206ad69da3d8c41250b5f79345de2d436d376746c64736f6c634300081a0033","sourceMap":"408:5985:29:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;588:28;;;;;-1:-1:-1;;;;;588:28:29;;;;;;-1:-1:-1;;;;;200:32:32;;;182:51;;170:2;155:18;588:28:29;;;;;;;;905:67;;954:18;905:67;;;;;-1:-1:-1;;;;;406:31:32;;;388:50;;376:2;361:18;905:67:29;244:200:32;4767:1624:29;;;;;;:::i;:::-;;:::i;:::-;;3892:758;;;;;;:::i;:::-;;:::i;496:43::-;;;;;;;;;6663:25:32;;;6651:2;6636:18;496:43:29;6517:177:32;672:46:29;;;:::i;:::-;;;;;;;;;;;;:::i;783:72::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;3458:179::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3115:146::-;;;:::i;:::-;;;;;;;:::i;4767:1624::-;4894:21;;-1:-1:-1;;;4894:21:29;;;;:30;4873:113;;;;-1:-1:-1;;;4873:113:29;;10717:2:32;4873:113:29;;;10699:21:32;10756:2;10736:18;;;10729:30;10795:34;10775:18;;;10768:62;-1:-1:-1;;;10846:18:32;;;10839:34;10890:19;;4873:113:29;;;;;;;;;954:18;5101:6;:10;;;:14;;;:40;;;;:::i;:::-;-1:-1:-1;;;;;5076:65:29;:21;:15;5094:3;5076:21;:::i;:::-;:65;;5055:149;;;;-1:-1:-1;;;5055:149:29;;11623:2:32;5055:149:29;;;11605:21:32;11662:2;11642:18;;;11635:30;11701:34;11681:18;;;11674:62;-1:-1:-1;;;11752:18:32;;;11745:35;11797:19;;5055:149:29;11421:401:32;5055:149:29;5292:38;;;;5308:11;;5292:38;:::i;:::-;;;;;;;;5251:6;:10;;;:19;;;5235:37;;;;;;:95;5214:179;;;;-1:-1:-1;;;5214:179:29;;13347:2:32;5214:179:29;;;13329:21:32;13386:2;13366:18;;;13359:30;13425:34;13405:18;;;13398:62;-1:-1:-1;;;13476:18:32;;;13469:35;13521:19;;5214:179:29;13145:401:32;5214:179:29;5480:23;:33;5424:10;;;;:26;;;:36;-1:-1:-1;;;;;5424:89:29;;;5480:33;;5424:89;:202;;;;-1:-1:-1;5591:23:29;:35;5533:10;;;;:26;;;;;:38;;-1:-1:-1;;;;;5533:93:29;;;-1:-1:-1;;;5591:35:29;;;;5533:93;5424:202;5403:293;;;;-1:-1:-1;;;5403:293:29;;13753:2:32;5403:293:29;;;13735:21:32;13792:2;13772:18;;;13765:30;13831:34;13811:18;;;13804:62;-1:-1:-1;;;13882:18:32;;;13875:42;13934:19;;5403:293:29;13551:408:32;5403:293:29;5757:27;;5727:10;;;;;:26;;-1:-1:-1;;;;;5727:57:29;;;5757:27;;5727:57;5706:148;;;;-1:-1:-1;;;5706:148:29;;14166:2:32;5706:148:29;;;14148:21:32;14205:2;14185:18;;;14178:30;14244:34;14224:18;;;14217:62;-1:-1:-1;;;14295:18:32;;;14288:42;14347:19;;5706:148:29;13964:408:32;5706:148:29;5915:28;;5885:10;;;;;:26;;-1:-1:-1;;;;;5885:58:29;;;-1:-1:-1;;;5915:28:29;;;;5885:58;5864:150;;;;-1:-1:-1;;;5864:150:29;;14579:2:32;5864:150:29;;;14561:21:32;14618:2;14598:18;;;14591:30;14657:34;14637:18;;;14630:62;-1:-1:-1;;;14708:18:32;;;14701:43;14761:19;;5864:150:29;14377:409:32;5864:150:29;6215:30;;6204:42;;;;6215:30;6204:42;;;:::i;:::-;;;;-1:-1:-1;;6204:42:29;;;;;;;;;6194:53;;6204:42;6194:53;;;;6120:21;;;;:37;;;-1:-1:-1;;;;;6104:54:29;;;;;:15;:54;;;;;;6194:53;;6072:104;;6104:54;6072:104;;:::i;:::-;;;;;;;;;;;;;6045:145;;;;;;:202;6024:301;;;;-1:-1:-1;;;6024:301:29;;16288:2:32;6024:301:29;;;16270:21:32;16327:2;16307:18;;;16300:30;16366:34;16346:18;;;16339:62;-1:-1:-1;;;16417:18:32;;;16410:50;16477:19;;6024:301:29;16086:416:32;6024:301:29;4767:1624;:::o;3892:758::-;4016:38;4081:12;4057:86;;;;;;;;;;;;:::i;:::-;4016:127;;4154:28;4175:6;4154:20;:28::i;:::-;4357:8;;;4378:28;4357:71;;-1:-1:-1;;;4357:71:29;;-1:-1:-1;;;;;4357:8:29;;;;:20;;:71;;4408:12;;4422:5;;4357:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;4524:17:29;;;;4496:45;;:25;:45;;;;;;;-1:-1:-1;;;;;4496:45:29;;;-1:-1:-1;;4496:45:29;;;;;;;-1:-1:-1;;;4496:45:29;;;;;;;;;;4604:39;;;;-1:-1:-1;4551:50:29;;;:15;:50;;;;;;:92;;;;-1:-1:-1;;4551:92:29;;;;;;;;;;;;;-1:-1:-1;4551:92:29;;;;;;;:::i;:::-;-1:-1:-1;4551:92:29;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;3892:758:29:o;672:46::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;672:46:29;;;;;;;;;;;;-1:-1:-1;;;;;672:46:29;;;;;-1:-1:-1;;;672:46:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;672:46:29;;;;-1:-1:-1;672:46:29;;;;-1:-1:-1;;;;672:46:29;;;;;:::o;783:72::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;783:72:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3458:179::-;3543:37;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3543:37:29;-1:-1:-1;;;;;3599:31:29;;;;;;;:15;:31;;;;;;;;;3592:38;;;;;;;;;;;;;;;;;;;;;;3599:31;3592:38;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3458:179;;;:::o;3115:146::-;3186:34;;:::i;:::-;3243:11;3236:18;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;3236:18:29;;;-1:-1:-1;;3236:18:29;;;;;;;;;;;;-1:-1:-1;;;;;3236:18:29;;;;;-1:-1:-1;;;3236:18:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;3236:18:29;;;;;;;;;;;;;;-1:-1:-1;3115:146:29:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;449:127:32:-;510:10;505:3;501:20;498:1;491:31;541:4;538:1;531:15;565:4;562:1;555:15;581:253;653:2;647:9;695:4;683:17;;-1:-1:-1;;;;;715:34:32;;751:22;;;712:62;709:88;;;777:18;;:::i;:::-;813:2;806:22;581:253;:::o;839:257::-;911:4;905:11;;;943:17;;-1:-1:-1;;;;;975:34:32;;1011:22;;;972:62;969:88;;;1037:18;;:::i;1101:253::-;1173:2;1167:9;1215:4;1203:17;;-1:-1:-1;;;;;1235:34:32;;1271:22;;;1232:62;1229:88;;;1297:18;;:::i;1359:253::-;1431:2;1425:9;1473:4;1461:17;;-1:-1:-1;;;;;1493:34:32;;1529:22;;;1490:62;1487:88;;;1555:18;;:::i;1617:275::-;1688:2;1682:9;1753:2;1734:13;;-1:-1:-1;;1730:27:32;1718:40;;-1:-1:-1;;;;;1773:34:32;;1809:22;;;1770:62;1767:88;;;1835:18;;:::i;:::-;1871:2;1864:22;1617:275;;-1:-1:-1;1617:275:32:o;1897:129::-;-1:-1:-1;;;;;1975:5:32;1971:30;1964:5;1961:41;1951:69;;2016:1;2013;2006:12;2031:186;2079:4;-1:-1:-1;;;;;2104:6:32;2101:30;2098:56;;;2134:18;;:::i;:::-;-1:-1:-1;2200:2:32;2179:15;-1:-1:-1;;2175:29:32;2206:4;2171:40;;2031:186::o;2222:336::-;2286:5;2315:52;2331:35;2359:6;2331:35;:::i;:::-;2315:52;:::i;:::-;2306:61;;2390:6;2383:5;2376:21;2430:3;2421:6;2416:3;2412:16;2409:25;2406:45;;;2447:1;2444;2437:12;2406:45;2496:6;2491:3;2484:4;2477:5;2473:16;2460:43;2550:1;2543:4;2534:6;2527:5;2523:18;2519:29;2512:40;2222:336;;;;;:::o;2563:220::-;2605:5;2658:3;2651:4;2643:6;2639:17;2635:27;2625:55;;2676:1;2673;2666:12;2625:55;2698:79;2773:3;2764:6;2751:20;2744:4;2736:6;2732:17;2698:79;:::i;:::-;2689:88;2563:220;-1:-1:-1;;;2563:220:32:o;2788:686::-;2849:5;2897:4;2885:9;2880:3;2876:19;2872:30;2869:50;;;2915:1;2912;2905:12;2869:50;2937:22;;:::i;:::-;2928:31;;2996:9;2983:23;3015:32;3039:7;3015:32;:::i;:::-;3056:22;;3129:2;3114:18;;3101:32;-1:-1:-1;;;;;3145:30:32;;3142:50;;;3188:1;3185;3178:12;3142:50;3224:45;3265:3;3256:6;3245:9;3241:22;3224:45;:::i;:::-;3219:2;3212:5;3208:14;3201:69;;3323:2;3312:9;3308:18;3295:32;-1:-1:-1;;;;;3342:8:32;3339:32;3336:52;;;3384:1;3381;3374:12;3336:52;3420:47;3463:3;3452:8;3441:9;3437:24;3420:47;:::i;:::-;3415:2;3408:5;3404:14;3397:71;;2788:686;;;;:::o;3479:433::-;3540:5;3588:4;3576:9;3571:3;3567:19;3563:30;3560:50;;;3606:1;3603;3596:12;3560:50;3628:22;;:::i;:::-;3619:31;;3687:9;3674:23;3706:32;3730:7;3706:32;:::i;:::-;3747:22;;3821:2;3806:18;;3793:32;3834;3793;3834;:::i;:::-;3893:2;3882:14;;3875:31;3886:5;3479:433;-1:-1:-1;;3479:433:32:o;3917:839::-;3967:5;4015:4;4003:9;3998:3;3994:19;3990:30;3987:50;;;4033:1;4030;4023:12;3987:50;4055:22;;:::i;:::-;4046:31;;4113:9;4100:23;-1:-1:-1;;;;;4138:6:32;4135:30;4132:50;;;4178:1;4175;4168:12;4132:50;4201:22;;4254:4;4246:13;;4242:23;-1:-1:-1;4232:51:32;;4279:1;4276;4269:12;4232:51;4306:71;4373:3;4368:2;4355:16;4348:4;4344:2;4340:13;4306:71;:::i;:::-;4299:5;4292:86;;4412:59;4467:3;4460:4;4449:9;4445:20;4412:59;:::i;:::-;4405:4;4398:5;4394:16;4387:85;4524:2;4513:9;4509:18;4496:32;4537;4561:7;4537:32;:::i;:::-;4596:4;4585:16;;4578:33;4663:4;4648:20;;4635:34;4678:32;4635:34;4678:32;:::i;:::-;4737:2;4726:14;;4719:31;4730:5;3917:839;-1:-1:-1;;3917:839:32:o;4761:1212::-;4863:6;4916:2;4904:9;4895:7;4891:23;4887:32;4884:52;;;4932:1;4929;4922:12;4884:52;4972:9;4959:23;-1:-1:-1;;;;;4997:6:32;4994:30;4991:50;;;5037:1;5034;5027:12;4991:50;5060:22;;5116:4;5098:16;;;5094:27;5091:47;;;5134:1;5131;5124:12;5091:47;5160:22;;:::i;:::-;5220:2;5207:16;-1:-1:-1;;;;;5238:8:32;5235:32;5232:52;;;5280:1;5277;5270:12;5232:52;5307:60;5359:7;5348:8;5344:2;5340:17;5307:60;:::i;:::-;5300:5;5293:75;;5414:2;5410;5406:11;5393:25;-1:-1:-1;;;;;5433:8:32;5430:32;5427:52;;;5475:1;5472;5465:12;5427:52;5511:60;5563:7;5552:8;5548:2;5544:17;5511:60;:::i;:::-;5506:2;5499:5;5495:14;5488:84;;5618:2;5614;5610:11;5597:25;-1:-1:-1;;;;;5637:8:32;5634:32;5631:52;;;5679:1;5676;5669:12;5631:52;5715:49;5756:7;5745:8;5741:2;5737:17;5715:49;:::i;:::-;5710:2;5703:5;5699:14;5692:73;;5797:54;5843:7;5838:2;5834;5830:11;5797:54;:::i;:::-;5792:2;5785:5;5781:14;5774:78;5886:56;5934:7;5927:4;5923:2;5919:13;5886:56;:::i;:::-;5879:4;5868:16;;5861:82;5872:5;4761:1212;-1:-1:-1;;;;4761:1212:32:o;5978:534::-;6064:6;6072;6125:2;6113:9;6104:7;6100:23;6096:32;6093:52;;;6141:1;6138;6131:12;6093:52;6181:9;6168:23;-1:-1:-1;;;;;6206:6:32;6203:30;6200:50;;;6246:1;6243;6236:12;6200:50;6269:49;6310:7;6301:6;6290:9;6286:22;6269:49;:::i;:::-;6259:59;;;6371:2;6360:9;6356:18;6343:32;-1:-1:-1;;;;;6390:8:32;6387:32;6384:52;;;6432:1;6429;6422:12;6384:52;6455:51;6498:7;6487:8;6476:9;6472:24;6455:51;:::i;:::-;6445:61;;;5978:534;;;;;:::o;6699:250::-;6784:1;6794:113;6808:6;6805:1;6802:13;6794:113;;;6884:11;;;6878:18;6865:11;;;6858:39;6830:2;6823:10;6794:113;;;-1:-1:-1;;6941:1:32;6923:16;;6916:27;6699:250::o;6954:271::-;6996:3;7034:5;7028:12;7061:6;7056:3;7049:19;7077:76;7146:6;7139:4;7134:3;7130:14;7123:4;7116:5;7112:16;7077:76;:::i;:::-;7207:2;7186:15;-1:-1:-1;;7182:29:32;7173:39;;;;7214:4;7169:50;;6954:271;-1:-1:-1;;6954:271:32:o;7440:804::-;7835:3;7824:9;7817:22;7798:4;7856:46;7897:3;7886:9;7882:19;7874:6;7856:46;:::i;:::-;7848:54;;7911:60;7967:2;7956:9;7952:18;7944:6;7314:12;;-1:-1:-1;;;;;7310:37:32;;;7298:50;;7401:4;7390:16;;;7384:23;7380:48;7364:14;;7357:72;7230:205;7911:60;7314:12;;-1:-1:-1;;;;;7310:37:32;;;8036:2;8021:18;;7298:50;7401:4;7390:16;;7384:23;7380:48;7364:14;;;7357:72;-1:-1:-1;;;;;8081:6:32;8077:31;8071:3;8060:9;8056:19;8049:60;-1:-1:-1;;;;;8150:6:32;8146:31;8140:3;8129:9;8125:19;8118:60;8229:6;8222:14;8215:22;8209:3;8198:9;8194:19;8187:51;7440:804;;;;;;;;;:::o;8249:245::-;8307:6;8360:2;8348:9;8339:7;8335:23;8331:32;8328:52;;;8376:1;8373;8366:12;8328:52;8415:9;8402:23;8434:30;8458:5;8434:30;:::i;8499:473::-;-1:-1:-1;;;;;8722:6:32;8718:31;8707:9;8700:50;8786:2;8781;8770:9;8766:18;8759:30;8681:4;8812:45;8853:2;8842:9;8838:18;8830:6;8812:45;:::i;:::-;8905:9;8897:6;8893:22;8888:2;8877:9;8873:18;8866:50;8933:33;8959:6;8951;8933:33;:::i;:::-;8925:41;8499:473;-1:-1:-1;;;;;;8499:473:32:o;8977:632::-;9172:2;9161:9;9154:21;-1:-1:-1;;;;;9221:6:32;9215:13;9211:38;9206:2;9195:9;9191:18;9184:66;9135:4;9297:2;9289:6;9285:15;9279:22;9337:4;9332:2;9321:9;9317:18;9310:32;9365:52;9412:3;9401:9;9397:19;9383:12;9365:52;:::i;:::-;9351:66;;9466:2;9458:6;9454:15;9448:22;9540:2;9536:7;9524:9;9516:6;9512:22;9508:36;9501:4;9490:9;9486:20;9479:66;9562:41;9596:6;9580:14;9562:41;:::i;:::-;9554:49;8977:632;-1:-1:-1;;;;;8977:632:32:o;9614:896::-;9803:2;9792:9;9785:21;9766:4;9841:6;9835:13;9884:6;9879:2;9868:9;9864:18;9857:34;9914:52;9961:3;9950:9;9946:19;9932:12;9914:52;:::i;:::-;9900:66;;10015:2;10007:6;10003:15;9997:22;10028:68;10092:2;10081:9;10077:18;10061:14;7314:12;;-1:-1:-1;;;;;7310:37:32;;;7298:50;;7401:4;7390:16;;;7384:23;7380:48;7364:14;;7357:72;7230:205;10028:68;-1:-1:-1;10145:2:32;10133:15;;10127:22;7314:12;;-1:-1:-1;;;;;7310:37:32;;;10222:3;10207:19;;7298:50;7401:4;7390:16;;7384:23;7380:48;7364:14;;;7357:72;10158:69;-1:-1:-1;;;;;10286:4:32;10278:6;10274:17;10268:24;10264:49;10258:3;10247:9;10243:19;10236:78;-1:-1:-1;;;;;10373:3:32;10365:6;10361:16;10355:23;10351:48;10345:3;10334:9;10330:19;10323:77;10472:4;10464:6;10460:17;10454:24;10447:32;10440:40;10431:6;10420:9;10416:22;10409:72;10498:6;10490:14;;;9614:896;;;;:::o;10920:127::-;10981:10;10976:3;10972:20;10969:1;10962:31;11012:4;11009:1;11002:15;11036:4;11033:1;11026:15;11052:191;-1:-1:-1;;;;;11120:26:32;;;11148;;;11116:59;;11187:27;;11184:53;;;11217:18;;:::i;:::-;11052:191;;;;:::o;11248:168::-;11321:9;;;11352;;11369:15;;;11363:22;;11349:37;11339:71;;11390:18;;:::i;11827:380::-;11906:1;11902:12;;;;11949;;;11970:61;;12024:4;12016:6;12012:17;12002:27;;11970:61;12077:2;12069:6;12066:14;12046:18;12043:38;12040:161;;12123:10;12118:3;12114:20;12111:1;12104:31;12158:4;12155:1;12148:15;12186:4;12183:1;12176:15;12040:161;;11827:380;;;:::o;12341:799::-;12471:3;12500:1;12533:6;12527:13;12563:36;12589:9;12563:36;:::i;:::-;12630:1;12615:17;;12641:133;;;;12788:1;12783:332;;;;12608:507;;12641:133;-1:-1:-1;;12674:24:32;;12662:37;;12747:14;;12740:22;12728:35;;12719:45;;;-1:-1:-1;12641:133:32;;12783:332;12814:6;12811:1;12804:17;12862:4;12859:1;12849:18;12889:1;12903:166;12917:6;12914:1;12911:13;12903:166;;;12997:14;;12984:11;;;12977:35;13053:1;13040:15;;;;12939:4;12932:12;12903:166;;;12907:3;;13098:6;13093:3;13089:16;13082:23;;12608:507;-1:-1:-1;13131:3:32;;12341:799;-1:-1:-1;;;;;12341:799:32:o;14791:738::-;14840:3;14881:5;14875:12;14910:36;14936:9;14910:36;:::i;:::-;14955:19;;;15005:1;14990:17;;15016:150;;;;15180:1;15175:348;;;;14983:540;;15016:150;15079:3;15075:8;15064:9;15060:24;15053:4;15048:3;15044:14;15037:48;15151:4;15139:6;15132:14;15125:22;15122:1;15118:30;15113:3;15109:40;15105:51;15098:58;;15016:150;;15175:348;15206:5;15203:1;15196:16;15253:4;15250:1;15240:18;15280:1;15294:177;15308:6;15305:1;15302:13;15294:177;;;15405:7;15399:14;15392:4;15388:1;15383:3;15379:11;15375:22;15368:46;15455:1;15446:7;15442:15;15431:26;;15330:4;15327:1;15323:12;15318:17;;15294:177;;;15495:11;;15508:4;15491:22;;-1:-1:-1;;14983:540:32;;;;14791:738;;;;:::o;15534:547::-;15726:2;15715:9;15708:21;-1:-1:-1;;;;;15775:6:32;15769:13;15765:38;15760:2;15749:9;15745:18;15738:66;15840:4;15835:2;15824:9;15820:18;15813:32;15689:4;15868:64;15927:3;15916:9;15912:19;15905:4;15897:6;15893:17;15868:64;:::i;:::-;15974:22;;;-1:-1:-1;;15970:36:32;15963:4;15948:20;;15941:66;16024:51;15978:6;16061:4;16049:17;;16024:51;:::i;:::-;16016:59;15534:547;-1:-1:-1;;;;15534:547:32:o;16507:320::-;16582:5;16611:52;16627:35;16655:6;16627:35;:::i;16611:52::-;16602:61;;16686:6;16679:5;16672:21;16726:3;16717:6;16712:3;16708:16;16705:25;16702:45;;;16743:1;16740;16733:12;16702:45;16756:65;16814:6;16807:4;16800:5;16796:16;16791:3;16756:65;:::i;16832:235::-;16885:5;16938:3;16931:4;16923:6;16919:17;16915:27;16905:55;;16956:1;16953;16946:12;16905:55;16978:83;17057:3;17048:6;17042:13;17035:4;17027:6;17023:17;16978:83;:::i;17072:698::-;17144:5;17192:4;17180:9;17175:3;17171:19;17167:30;17164:50;;;17210:1;17207;17200:12;17164:50;17232:22;;:::i;:::-;17223:31;;17284:9;17278:16;17303:32;17327:7;17303:32;:::i;:::-;17344:22;;17410:2;17395:18;;17389:25;-1:-1:-1;;;;;17426:30:32;;17423:50;;;17469:1;17466;17459:12;17423:50;17505:56;17557:3;17548:6;17537:9;17533:22;17505:56;:::i;:::-;17500:2;17493:5;17489:14;17482:80;;17608:2;17597:9;17593:18;17587:25;-1:-1:-1;;;;;17627:8:32;17624:32;17621:52;;;17669:1;17666;17659:12;17621:52;17705:58;17759:3;17748:8;17737:9;17733:24;17705:58;:::i;17775:430::-;17847:5;17895:4;17883:9;17878:3;17874:19;17870:30;17867:50;;;17913:1;17910;17903:12;17867:50;17935:22;;:::i;:::-;17926:31;;17987:9;17981:16;18006:32;18030:7;18006:32;:::i;:::-;18047:22;;18114:2;18099:18;;18093:25;18127:32;18093:25;18127:32;:::i;18210:844::-;18271:5;18319:4;18307:9;18302:3;18298:19;18294:30;18291:50;;;18337:1;18334;18327:12;18291:50;18359:22;;:::i;:::-;18350:31;;18410:9;18404:16;-1:-1:-1;;;;;18435:6:32;18432:30;18429:50;;;18475:1;18472;18465:12;18429:50;18498:22;;18551:4;18543:13;;18539:23;-1:-1:-1;18529:51:32;;18576:1;18573;18566:12;18529:51;18603:75;18674:3;18669:2;18663:9;18656:4;18652:2;18648:13;18603:75;:::i;:::-;18596:5;18589:90;;18713:70;18779:3;18772:4;18761:9;18757:20;18713:70;:::i;:::-;18706:4;18699:5;18695:16;18688:96;18829:2;18818:9;18814:18;18808:25;18842:32;18866:7;18842:32;:::i;:::-;18901:4;18890:16;;18883:33;18961:4;18946:20;;18940:27;18976:32;18940:27;18976:32;:::i;19059:1250::-;19172:6;19225:2;19213:9;19204:7;19200:23;19196:32;19193:52;;;19241:1;19238;19231:12;19193:52;19274:9;19268:16;-1:-1:-1;;;;;19299:6:32;19296:30;19293:50;;;19339:1;19336;19329:12;19293:50;19362:22;;19418:4;19400:16;;;19396:27;19393:47;;;19436:1;19433;19426:12;19393:47;19462:22;;:::i;:::-;19515:2;19509:9;-1:-1:-1;;;;;19533:8:32;19530:32;19527:52;;;19575:1;19572;19565:12;19527:52;19602:71;19665:7;19654:8;19650:2;19646:17;19602:71;:::i;:::-;19595:5;19588:86;;19713:2;19709;19705:11;19699:18;-1:-1:-1;;;;;19732:8:32;19729:32;19726:52;;;19774:1;19771;19764:12;19726:52;19810:71;19873:7;19862:8;19858:2;19854:17;19810:71;:::i;:::-;19805:2;19798:5;19794:14;19787:95;;19921:2;19917;19913:11;19907:18;-1:-1:-1;;;;;19940:8:32;19937:32;19934:52;;;19982:1;19979;19972:12;19934:52;20018:60;20070:7;20059:8;20055:2;20051:17;20018:60;:::i;:::-;20013:2;20006:5;20002:14;19995:84;;20111:65;20168:7;20163:2;20159;20155:11;20111:65;:::i;:::-;20106:2;20099:5;20095:14;20088:89;20211:67;20270:7;20263:4;20259:2;20255:13;20211:67;:::i;20314:450::-;20535:6;20524:9;20517:25;20578:2;20573;20562:9;20558:18;20551:30;20498:4;20604:45;20645:2;20634:9;20630:18;20622:6;20604:45;:::i;20769:517::-;20870:2;20865:3;20862:11;20859:421;;;20906:5;20903:1;20896:16;20950:4;20947:1;20937:18;21020:2;21008:10;21004:19;21001:1;20997:27;20991:4;20987:38;21056:4;21044:10;21041:20;21038:47;;;-1:-1:-1;21079:4:32;21038:47;21134:2;21129:3;21125:12;21122:1;21118:20;21112:4;21108:31;21098:41;;21189:81;21207:2;21200:5;21197:13;21189:81;;;21266:1;21252:16;;21233:1;21222:13;21189:81;;;21193:3;;20859:421;20769:517;;;:::o;21462:1299::-;21586:3;21580:10;-1:-1:-1;;;;;21605:6:32;21602:30;21599:56;;;21635:18;;:::i;:::-;21664:96;21753:6;21713:38;21745:4;21739:11;21713:38;:::i;:::-;21707:4;21664:96;:::i;:::-;21809:4;21840:2;21829:14;;21857:1;21852:652;;;;22548:1;22565:6;22562:89;;;-1:-1:-1;22617:19:32;;;22611:26;22562:89;-1:-1:-1;;21419:1:32;21415:11;;;21411:24;21407:29;21397:40;21443:1;21439:11;;;21394:57;22664:81;;21822:933;;21852:652;12288:1;12281:14;;;12325:4;12312:18;;-1:-1:-1;;21888:20:32;;;22009:222;22023:7;22020:1;22017:14;22009:222;;;22105:19;;;22099:26;22084:42;;22212:4;22197:20;;;;22165:1;22153:14;;;;22039:12;22009:222;;;22013:3;22259:6;22250:7;22247:19;22244:201;;;22320:19;;;22314:26;-1:-1:-1;;22403:1:32;22399:14;;;22415:3;22395:24;22391:37;22387:42;22372:58;22357:74;;22244:201;-1:-1:-1;;;;22491:1:32;22475:14;;;22471:22;22458:36;;-1:-1:-1;21462:1299:32:o","linkReferences":{}},"methodIdentifiers":{"ALLOWED_SP1_CLOCK_DRIFT()":"2c3ee474","clientState()":"bd3ce6b0","consensusStates(uint64)":"e08322d5","getClientState()":"ef913a4b","getConsensusState(uint64)":"edce8bdc","ics07UpdateClientProgramVkey()":"975c0796","validatePublicValues(((uint64,bytes,bytes),(uint64,bytes,bytes),(string,(uint64,uint64),uint64,uint64),(uint64,uint64),(uint64,uint64)))":"3f01b86f","verifier()":"2b7ac3f3","verifyIcs07UpdateClientProof(bytes,bytes)":"61d311c5"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.26+commit.8a97fa7a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_ics07ProgramVkey\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_verifier\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_clientState\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_consensusState\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"clientState\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"chain_id\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"numerator\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"denominator\",\"type\":\"uint64\"}],\"internalType\":\"struct ICS07Tendermint.TrustThreshold\",\"name\":\"trust_level\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"revision_number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"revision_height\",\"type\":\"uint64\"}],\"internalType\":\"struct ICS07Tendermint.Height\",\"name\":\"latest_height\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"trusting_period\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"unbonding_period\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"is_frozen\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"consensusStates\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"root\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"next_validators_hash\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getClientState\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"chain_id\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"numerator\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"denominator\",\"type\":\"uint64\"}],\"internalType\":\"struct ICS07Tendermint.TrustThreshold\",\"name\":\"trust_level\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"revision_number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"revision_height\",\"type\":\"uint64\"}],\"internalType\":\"struct ICS07Tendermint.Height\",\"name\":\"latest_height\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"trusting_period\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"unbonding_period\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"is_frozen\",\"type\":\"bool\"}],\"internalType\":\"struct ICS07Tendermint.ClientState\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"revisionHeight\",\"type\":\"uint64\"}],\"name\":\"getConsensusState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"root\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"next_validators_hash\",\"type\":\"bytes\"}],\"internalType\":\"struct ICS07Tendermint.ConsensusState\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ics07UpdateClientProgramVkey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"root\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"next_validators_hash\",\"type\":\"bytes\"}],\"internalType\":\"struct ICS07Tendermint.ConsensusState\",\"name\":\"trusted_consensus_state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"root\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"next_validators_hash\",\"type\":\"bytes\"}],\"internalType\":\"struct ICS07Tendermint.ConsensusState\",\"name\":\"new_consensus_state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"chain_id\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"numerator\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"denominator\",\"type\":\"uint64\"}],\"internalType\":\"struct ICS07Tendermint.TrustThreshold\",\"name\":\"trust_threshold\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"trusting_period\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"now\",\"type\":\"uint64\"}],\"internalType\":\"struct SP1ICS07Tendermint.Env\",\"name\":\"env\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"revision_number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"revision_height\",\"type\":\"uint64\"}],\"internalType\":\"struct ICS07Tendermint.Height\",\"name\":\"trusted_height\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"revision_number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"revision_height\",\"type\":\"uint64\"}],\"internalType\":\"struct ICS07Tendermint.Height\",\"name\":\"new_height\",\"type\":\"tuple\"}],\"internalType\":\"struct SP1ICS07Tendermint.SP1ICS07TendermintOutput\",\"name\":\"output\",\"type\":\"tuple\"}],\"name\":\"validatePublicValues\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifier\",\"outputs\":[{\"internalType\":\"contract ISP1Verifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"publicValues\",\"type\":\"bytes\"}],\"name\":\"verifyIcs07UpdateClientProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"srdtrk\",\"custom:poc\":\"This is a proof of concept implementation.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_clientState\":\"The encoded initial client state.\",\"_consensusState\":\"The encoded initial consensus state.\",\"_ics07ProgramVkey\":\"The verification key for the program.\",\"_verifier\":\"The address of the SP1 verifier contract.\"}},\"getClientState()\":{\"returns\":{\"_0\":\"The client state.\"}},\"getConsensusState(uint64)\":{\"params\":{\"revisionHeight\":\"The revision height.\"},\"returns\":{\"_0\":\"The consensus state at the given revision height.\"}},\"validatePublicValues(((uint64,bytes,bytes),(uint64,bytes,bytes),(string,(uint64,uint64),uint64,uint64),(uint64,uint64),(uint64,uint64)))\":{\"params\":{\"output\":\"The public values.\"}},\"verifyIcs07UpdateClientProof(bytes,bytes)\":{\"details\":\"This function verifies the public values and forwards the proof to the SP1 verifier.\",\"params\":{\"proof\":\"The encoded proof.\",\"publicValues\":\"The encoded public values.\"}}},\"title\":\"SP1ICS07Tendermint\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"ALLOWED_SP1_CLOCK_DRIFT()\":{\"notice\":\"Allowed clock drift in nanoseconds\"},\"clientState()\":{\"notice\":\"The ICS07Tendermint client state\"},\"consensusStates(uint64)\":{\"notice\":\"The mapping from height to consensus state\"},\"constructor\":{\"notice\":\"The constructor sets the program verification key and the initial client and consensus states.\"},\"getClientState()\":{\"notice\":\"Returns the client state.\"},\"getConsensusState(uint64)\":{\"notice\":\"Returns the consensus state at the given revision height.\"},\"ics07UpdateClientProgramVkey()\":{\"notice\":\"The verification key for the program.\"},\"validatePublicValues(((uint64,bytes,bytes),(uint64,bytes,bytes),(string,(uint64,uint64),uint64,uint64),(uint64,uint64),(uint64,uint64)))\":{\"notice\":\"Validates the SP1ICS07TendermintOutput public values.\"},\"verifier()\":{\"notice\":\"The SP1 verifier contract.\"},\"verifyIcs07UpdateClientProof(bytes,bytes)\":{\"notice\":\"The entrypoint for verifying the proof.\"}},\"notice\":\"This contract implements an ICS07 IBC tendermint light client.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/SP1ICS07Tendermint.sol\":\"SP1ICS07Tendermint\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@sp1-contracts/=lib/sp1-contracts/contracts/src/\",\":forge-std/=lib/forge-std/src/\",\":sp1-contracts/=lib/sp1-contracts/contracts/\"]},\"sources\":{\"lib/forge-std/src/console.sol\":{\"keccak256\":\"0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70\",\"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec\"]},\"lib/sp1-contracts/contracts/src/ISP1Verifier.sol\":{\"keccak256\":\"0x113e46723af8a93f6d8332b3ee1fa7175d7ad09e757b1e6744bdcefcd86c3561\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0bad3cf8458e43f252862a414152b8c69236421bab6cb8382d58d283af76a585\",\"dweb:/ipfs/QmUP6q4yUsNYJjJhLp97hxn3vFgGHauLySdAiLDQMyNDrK\"]},\"src/SP1ICS07Tendermint.sol\":{\"keccak256\":\"0x053535a99444e9708e9f6c623da87a5762b3ed029ab626461e7127c7bc18e2ff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc70c8e5e9314c06e902be5bbb90ac601434dad3e206b00a8286f57d60255623\",\"dweb:/ipfs/QmRA1G5868WgAc6NcxysdUj4NoXo37DREHSxQZT1Yr14up\"]},\"src/ics07-tendermint/ICS07Tendermint.sol\":{\"keccak256\":\"0x9b0d92e1cfbad854aa5dabee1320b40e4bb24c44e163da3cb9a95a33d9259841\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://12532197776b96bb4ffb45149aeffc56afe6ffcadf5114a67c0e68bb4963978f\",\"dweb:/ipfs/QmaXZQKBQUamChXHKoZb95jY53SHgWnA28WavuZzUryX8M\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.26+commit.8a97fa7a"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"bytes32","name":"_ics07ProgramVkey","type":"bytes32"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"bytes","name":"_clientState","type":"bytes"},{"internalType":"bytes","name":"_consensusState","type":"bytes"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"stateMutability":"view","type":"function","name":"ALLOWED_SP1_CLOCK_DRIFT","outputs":[{"internalType":"uint64","name":"","type":"uint64"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"clientState","outputs":[{"internalType":"string","name":"chain_id","type":"string"},{"internalType":"struct ICS07Tendermint.TrustThreshold","name":"trust_level","type":"tuple","components":[{"internalType":"uint64","name":"numerator","type":"uint64"},{"internalType":"uint64","name":"denominator","type":"uint64"}]},{"internalType":"struct ICS07Tendermint.Height","name":"latest_height","type":"tuple","components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}]},{"internalType":"uint64","name":"trusting_period","type":"uint64"},{"internalType":"uint64","name":"unbonding_period","type":"uint64"},{"internalType":"bool","name":"is_frozen","type":"bool"}]},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function","name":"consensusStates","outputs":[{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"bytes","name":"root","type":"bytes"},{"internalType":"bytes","name":"next_validators_hash","type":"bytes"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getClientState","outputs":[{"internalType":"struct ICS07Tendermint.ClientState","name":"","type":"tuple","components":[{"internalType":"string","name":"chain_id","type":"string"},{"internalType":"struct ICS07Tendermint.TrustThreshold","name":"trust_level","type":"tuple","components":[{"internalType":"uint64","name":"numerator","type":"uint64"},{"internalType":"uint64","name":"denominator","type":"uint64"}]},{"internalType":"struct ICS07Tendermint.Height","name":"latest_height","type":"tuple","components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}]},{"internalType":"uint64","name":"trusting_period","type":"uint64"},{"internalType":"uint64","name":"unbonding_period","type":"uint64"},{"internalType":"bool","name":"is_frozen","type":"bool"}]}]},{"inputs":[{"internalType":"uint64","name":"revisionHeight","type":"uint64"}],"stateMutability":"view","type":"function","name":"getConsensusState","outputs":[{"internalType":"struct ICS07Tendermint.ConsensusState","name":"","type":"tuple","components":[{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"bytes","name":"root","type":"bytes"},{"internalType":"bytes","name":"next_validators_hash","type":"bytes"}]}]},{"inputs":[],"stateMutability":"view","type":"function","name":"ics07UpdateClientProgramVkey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"struct SP1ICS07Tendermint.SP1ICS07TendermintOutput","name":"output","type":"tuple","components":[{"internalType":"struct ICS07Tendermint.ConsensusState","name":"trusted_consensus_state","type":"tuple","components":[{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"bytes","name":"root","type":"bytes"},{"internalType":"bytes","name":"next_validators_hash","type":"bytes"}]},{"internalType":"struct ICS07Tendermint.ConsensusState","name":"new_consensus_state","type":"tuple","components":[{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"bytes","name":"root","type":"bytes"},{"internalType":"bytes","name":"next_validators_hash","type":"bytes"}]},{"internalType":"struct SP1ICS07Tendermint.Env","name":"env","type":"tuple","components":[{"internalType":"string","name":"chain_id","type":"string"},{"internalType":"struct ICS07Tendermint.TrustThreshold","name":"trust_threshold","type":"tuple","components":[{"internalType":"uint64","name":"numerator","type":"uint64"},{"internalType":"uint64","name":"denominator","type":"uint64"}]},{"internalType":"uint64","name":"trusting_period","type":"uint64"},{"internalType":"uint64","name":"now","type":"uint64"}]},{"internalType":"struct ICS07Tendermint.Height","name":"trusted_height","type":"tuple","components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}]},{"internalType":"struct ICS07Tendermint.Height","name":"new_height","type":"tuple","components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}]}]}],"stateMutability":"view","type":"function","name":"validatePublicValues"},{"inputs":[],"stateMutability":"view","type":"function","name":"verifier","outputs":[{"internalType":"contract ISP1Verifier","name":"","type":"address"}]},{"inputs":[{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"bytes","name":"publicValues","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"verifyIcs07UpdateClientProof"}],"devdoc":{"kind":"dev","methods":{"constructor":{"params":{"_clientState":"The encoded initial client state.","_consensusState":"The encoded initial consensus state.","_ics07ProgramVkey":"The verification key for the program.","_verifier":"The address of the SP1 verifier contract."}},"getClientState()":{"returns":{"_0":"The client state."}},"getConsensusState(uint64)":{"params":{"revisionHeight":"The revision height."},"returns":{"_0":"The consensus state at the given revision height."}},"validatePublicValues(((uint64,bytes,bytes),(uint64,bytes,bytes),(string,(uint64,uint64),uint64,uint64),(uint64,uint64),(uint64,uint64)))":{"params":{"output":"The public values."}},"verifyIcs07UpdateClientProof(bytes,bytes)":{"details":"This function verifies the public values and forwards the proof to the SP1 verifier.","params":{"proof":"The encoded proof.","publicValues":"The encoded public values."}}},"version":1},"userdoc":{"kind":"user","methods":{"ALLOWED_SP1_CLOCK_DRIFT()":{"notice":"Allowed clock drift in nanoseconds"},"clientState()":{"notice":"The ICS07Tendermint client state"},"consensusStates(uint64)":{"notice":"The mapping from height to consensus state"},"constructor":{"notice":"The constructor sets the program verification key and the initial client and consensus states."},"getClientState()":{"notice":"Returns the client state."},"getConsensusState(uint64)":{"notice":"Returns the consensus state at the given revision height."},"ics07UpdateClientProgramVkey()":{"notice":"The verification key for the program."},"validatePublicValues(((uint64,bytes,bytes),(uint64,bytes,bytes),(string,(uint64,uint64),uint64,uint64),(uint64,uint64),(uint64,uint64)))":{"notice":"Validates the SP1ICS07TendermintOutput public values."},"verifier()":{"notice":"The SP1 verifier contract."},"verifyIcs07UpdateClientProof(bytes,bytes)":{"notice":"The entrypoint for verifying the proof."}},"version":1}},"settings":{"remappings":["@sp1-contracts/=lib/sp1-contracts/contracts/src/","forge-std/=lib/forge-std/src/","sp1-contracts/=lib/sp1-contracts/contracts/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/SP1ICS07Tendermint.sol":"SP1ICS07Tendermint"},"evmVersion":"paris","libraries":{}},"sources":{"lib/forge-std/src/console.sol":{"keccak256":"0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba","urls":["bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70","dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"],"license":"MIT"},"lib/sp1-contracts/contracts/src/ISP1Verifier.sol":{"keccak256":"0x113e46723af8a93f6d8332b3ee1fa7175d7ad09e757b1e6744bdcefcd86c3561","urls":["bzz-raw://0bad3cf8458e43f252862a414152b8c69236421bab6cb8382d58d283af76a585","dweb:/ipfs/QmUP6q4yUsNYJjJhLp97hxn3vFgGHauLySdAiLDQMyNDrK"],"license":"MIT"},"src/SP1ICS07Tendermint.sol":{"keccak256":"0x053535a99444e9708e9f6c623da87a5762b3ed029ab626461e7127c7bc18e2ff","urls":["bzz-raw://cc70c8e5e9314c06e902be5bbb90ac601434dad3e206b00a8286f57d60255623","dweb:/ipfs/QmRA1G5868WgAc6NcxysdUj4NoXo37DREHSxQZT1Yr14up"],"license":"MIT"},"src/ics07-tendermint/ICS07Tendermint.sol":{"keccak256":"0x9b0d92e1cfbad854aa5dabee1320b40e4bb24c44e163da3cb9a95a33d9259841","urls":["bzz-raw://12532197776b96bb4ffb45149aeffc56afe6ffcadf5114a67c0e68bb4963978f","dweb:/ipfs/QmaXZQKBQUamChXHKoZb95jY53SHgWnA28WavuZzUryX8M"],"license":"UNLICENSED"}},"version":1},"id":29} \ No newline at end of file diff --git a/contracts/fixtures/fixture.json b/contracts/fixtures/fixture.json index 64b710e..ef4d3f1 100644 --- a/contracts/fixtures/fixture.json +++ b/contracts/fixtures/fixture.json @@ -3,7 +3,7 @@ "trustedConsensusState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017db9605c70f5a75000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", "targetConsensusState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017db962167923e1a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fd0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", "targetHeight": 2110668, - "vkey": "0x004ac9cd92d0a05a01903f9f62b3c271ba861e2cd6b615c4c081394cbaf123f3", - "publicValues": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034cc00000000000000000000000000000000000000000000000017db9605c70f5a75000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c41900000000000000000000000000000000000000000000000017db962167923e1a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fd0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c41900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000044c1ff252000000000000000000000000000000000000000000000000000017dbb9d861d9c38000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "proof": "0x28192d1ec8d20562142ae5ed4b621a04cf6871187db21b0991e4732d470d7b5a17e6b1c037a5e75fc275e8bae644060d82c70050b6c695bbc4efe534db3f99c62c37e3e49930156a62b2743c054c463a789181b3ade6be54b8108e2afaebc1900f30a937736a0566bda5e72e11ede01e5a9f4cc54e45deb12b5a913415df51c30d5b991991f73942bb25c07444eabf989fe86dcf09874ff7c168a6a52a5d7cf52e46af4a99e227fec9990646781353e3c35a2b6303db59f2dd6c89c6e8b7f61a1e1a5bb75660dd8a914abb6ab7fa24f6ece69b87738b39066a720617707515892dbe014e002a1b859eef8de16ec36b2adfe95d44598853412f9f8c15e6574c732902911a34c720778d381fde493150f3582e412832bc5dfd7c9769a47c6f7c310ecaccac1d8701e743aecff4f8954bda594dc60cd124491bad0b5422abe5f8c60d19b48760f8d8a4243af71ea83c67b56a0c77aa559ff686c493d55a21c83ebb25aba42a65fa9eebde9c6b23b65870cdb0f0b6ed5162042f2f76ff7c63b617861c32723bff3020c91a5a0215d7cc43c59b151909075ddc78ec46895df1c9068f1bb77a4feae837abbbf959af7348b003cd2acbb825cbaf0c1e58db57bb454ddf186666c0a1459c4a578558d46e9b02cb541b173e96e7225e1e91b80c203203001831d51c0423869cefb63f2b346df6b138bd747b1335f48d6e0fe46d6683eda110aa73735e712cc3a921134713d07f839dbd582c2b3174bcc6d2b5b6926447ca190ed214ed8fa55fffb6b850bc6b3eeaa60790c84cfaaf6d31300ed796302e6c2d42eb241dac89b1723e736da9f8c4d897c2da6c2f3b76eda7faf94d4e930d8f1e3ebb0d58ca7c0164e82a7e86724f4a12b6051a5c51d9974d3f1756d1674bd91a1a9c8d5eea30c21cfef32aba24fb9ceb9b2f543871a5855c1c7b7deeed1aac013a6be382d092b3ba9645659e1f9c8d4953e50628a55d6552183a703fca9b330f41c0ce092b8305eea6516531dd98749945178fa5fb0dabe5e6f26a4e7d0a112238b8154ad17fca7edab2c51275d5a0d06496266811912cf9b0fdc2cc14d37924dfc2a17ea46cee7f66cce4883490c7c0abcd51ae339264faf39600bfb256c926620ea8e3d6b8f3babe6ebaee3cc0d48dbbffaf9798ddffdc78cfaa7f07969f141fb667d4790be0b9ef1f503a90c41610f0cc3a6913c69049aa5ab69466dec4" + "vkey": "0x0027abf663673bd7da77aa0839ef4afb57aca485b0da85b02f53a39b8bc1991f", + "publicValues": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034cc00000000000000000000000000000000000000000000000017db9605c70f5a75000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c41900000000000000000000000000000000000000000000000017db962167923e1a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fd0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c41900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000044c1ff252000000000000000000000000000000000000000000000000000017dc7a857543e24800000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "proof": "0x2b425f9ae65f69e332c01056aa13bdb0d7d0808250ceb1f1a6f38e8bf3e7222d22c64db06f748d50bf8e9604f0db8fbf9ba3a84c00e54d0268d4704462b436fe0781c1a6e15b7940c259bd37e5e0e2a85935addc2bc7a297dc878ece0639f08e12782f85c76cdddadf9511712a88a79c475190e7c35b9170e98e1e2945f522691e313e360ee82434b1e10436eaa6a90d806906d8d991d856d66e620b83609bdf00e9da5062e86da85df360875e9b7319e8b7978a099be02d2c253b284833c470049675ec44837a9642996afe235fd13053f97f82858a0f1ecf1f79f6a39636dc2a593c2f478099757e00c2c9c58545c00c9ad80e7603fed15ff8baf9395f768f195d62e5b9628c5df2c3c917bafc5bdd9a7ccb15a893d6067546a465397d425517a7f320ae3b17d033e0b89f3e981109b8aa4f72678ab2db52ba7a444b51d6361228222c659b59d328a72458777f2665c41eb5b4c2cfdc3a5b2bb665ce38303c0e2d7f0717d060d041a2d7474be52ac0b033ba1c92c031efcb69c753da048ed12d0997b4294fb87d66022cb6845ad27931166b5e8ec9af0bbf46c61a087c4dcf02790eff080b6ffe540bfd442b9d74d4b3bdf2278fa85b2052fadf655720129a2c2ecf0c56e8aa5f565082f01b794f67d12aa3cb49a0e140a2ef42a64a4636a12439471d43b855456e73546565e045fa209bf3701c24cfbd75d5050968a473ac286b725dbb63faa9a79c02d408f60e6d0a01631af5c814b06075679806f3019e0f3e81fdad4025a02122fda64253bd01a4863c6b29d5a008858b1f39ded2e5050ec8b88f634fd03f3e96909c5d10e90cbfdc7178162f8abf83672cd32db911731f26dad46ffbf7d24cbc2699825f05a365e7f95e26c799dc9b7f626a99e545681844d13f330008104c9c33646d37cd30d4e165c64dc195448d2c549ac596a9221368e7e02e8ba4169c868099f272f31c1021a8ce3409297431427356f90e53461e27e7de438e87326f84082403098c140709055ce05304abd556ab5c39f08a330e4048ed10395889d1fc7b12ed2ecce5c76b7a545a27203c0b51884b58b91bb82aab20dc88728956da6ac4c7aebbd801744f5d278b4b40daba7195a2686ccff012d215d3f892675230ebce15e7d8ccf76b2128532361d793e8ac57a3fe02a30a1695394a0a7cfdee422dcc0d346c7ecb403c610c13b9b28c758142c61f39dfbe" } \ No newline at end of file diff --git a/contracts/fixtures/mock_fixture.json b/contracts/fixtures/mock_fixture.json index 7fd0504..f0d1f59 100644 --- a/contracts/fixtures/mock_fixture.json +++ b/contracts/fixtures/mock_fixture.json @@ -3,7 +3,7 @@ "trustedConsensusState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017db9605c70f5a75000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", "targetConsensusState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017db962167923e1a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fd0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", "targetHeight": 2110668, - "vkey": "0x00084515d81830c3fd44b21efbbe0ba9251ebcf47bf084734054f9d0c267449f", - "publicValues": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034cc00000000000000000000000000000000000000000000000017db9605c70f5a75000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c41900000000000000000000000000000000000000000000000017db962167923e1a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fd0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c41900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000044c1ff252000000000000000000000000000000000000000000000000000017dbec604d35b0a000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "vkey": "0x0027abf663673bd7da77aa0839ef4afb57aca485b0da85b02f53a39b8bc1991f", + "publicValues": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034cc00000000000000000000000000000000000000000000000017db9605c70f5a75000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c41900000000000000000000000000000000000000000000000017db962167923e1a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fd0000000000000000000000000000000000000000000000000000000000000020b73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c41900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000044c1ff252000000000000000000000000000000000000000000000000000017dc78a886422ed000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", "proof": "0x" } \ No newline at end of file diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index d349d21..ce3138e 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,5 +1,5 @@ { - "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000020535900000000000000000000000000000000000000000000000000044c1ff252000000000000000000000000000000000000000000000000000000044c1ff2520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017dbeb51fec7221f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002015b5bf975fc2b484959b53b99271125f5e0b8091b2522c72166d3331862865330000000000000000000000000000000000000000000000000000000000000020303e2edb2ed12152025d4257ff4515b83d4aae62e4a9f12c2f31f99c5cb38914", - "vkey": "0x00084515d81830c3fd44b21efbbe0ba9251ebcf47bf084734054f9d0c267449f" + "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000020865600000000000000000000000000000000000000000000000000044c1ff252000000000000000000000000000000000000000000000000000000044c1ff2520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017dc7a1c98e1b796000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020b04986d8301923791582e4af9b7c54303e36f7ea417022c0872ad1cc5308d0ef0000000000000000000000000000000000000000000000000000000000000020cb1cd32f5c9e6a4140b6917e9a0d7826dbfec13ddee20c091c63ff8fda2e3275", + "vkey": "0x0027abf663673bd7da77aa0839ef4afb57aca485b0da85b02f53a39b8bc1991f" } \ No newline at end of file diff --git a/contracts/src/SP1ICS07Tendermint.sol b/contracts/src/SP1ICS07Tendermint.sol index a2b5d13..b14d64f 100644 --- a/contracts/src/SP1ICS07Tendermint.sol +++ b/contracts/src/SP1ICS07Tendermint.sol @@ -23,6 +23,33 @@ contract SP1ICS07Tendermint { /// Allowed clock drift in nanoseconds uint64 public constant ALLOWED_SP1_CLOCK_DRIFT = 30_000_000_000_000; // 30000 seconds + /// @notice The public value output for the sp1 program. + struct SP1ICS07TendermintOutput { + /// The trusted consensus state. + ICS07Tendermint.ConsensusState trusted_consensus_state; + /// The new consensus state with the verified header. + ICS07Tendermint.ConsensusState new_consensus_state; + /// The validation environment. + Env env; + /// trusted height + ICS07Tendermint.Height trusted_height; + /// new height + ICS07Tendermint.Height new_height; + } + + /// @notice The environment output for the sp1 program. + struct Env { + /// The chain ID of the chain that the client is tracking. + string chain_id; + /// Fraction of validator overlap needed to update header + ICS07Tendermint.TrustThreshold trust_threshold; + /// Duration of the period since the `LatestTimestamp` during which the + /// submitted headers are valid for upgrade + uint64 trusting_period; + /// Timestamp in nanoseconds + uint64 now; + } + /// @notice The constructor sets the program verification key and the initial client and consensus states. /// @param _ics07ProgramVkey The verification key for the program. /// @param _verifier The address of the SP1 verifier contract. @@ -79,6 +106,23 @@ contract SP1ICS07Tendermint { (SP1ICS07TendermintOutput) ); + validatePublicValues(output); + + // TODO: Make sure that other checks have been made in the proof verification + // such as the consensus state not being outside the trusting period. + verifier.verifyProof(ics07UpdateClientProgramVkey, publicValues, proof); + + // adding the new consensus state to the mapping + clientState.latest_height = output.new_height; + consensusStates[output.new_height.revision_height] = output + .new_consensus_state; + } + + /// @notice Validates the SP1ICS07TendermintOutput public values. + /// @param output The public values. + function validatePublicValues( + SP1ICS07TendermintOutput memory output + ) public view { require( clientState.is_frozen == false, "SP1ICS07Tendermint: client is frozen" @@ -116,42 +160,6 @@ contract SP1ICS07Tendermint { ) == keccak256(abi.encode(output.trusted_consensus_state)), "SP1ICS07Tendermint: trusted consensus state mismatch" ); - // TODO: Make sure that we don't need more checks here. - - // TODO: Make sure that other checks have been made in the proof verification - // such as the consensus state not being outside the trusting period. - verifier.verifyProof(ics07UpdateClientProgramVkey, publicValues, proof); - - // adding the new consensus state to the mapping - clientState.latest_height = output.new_height; - consensusStates[output.new_height.revision_height] = output - .new_consensus_state; - } - - /// @notice The public value output for the sp1 program. - struct SP1ICS07TendermintOutput { - /// The trusted consensus state. - ICS07Tendermint.ConsensusState trusted_consensus_state; - /// The new consensus state with the verified header. - ICS07Tendermint.ConsensusState new_consensus_state; - /// The validation environment. - Env env; - /// trusted height - ICS07Tendermint.Height trusted_height; - /// new height - ICS07Tendermint.Height new_height; - } - - /// @notice The environment output for the sp1 program. - struct Env { - /// The chain ID of the chain that the client is tracking. - string chain_id; - /// Fraction of validator overlap needed to update header - ICS07Tendermint.TrustThreshold trust_threshold; - /// Duration of the period since the `LatestTimestamp` during which the - /// submitted headers are valid for upgrade - uint64 trusting_period; - /// Timestamp in nanoseconds - uint64 now; + // TODO: Make sure that we don't need more checks. } } diff --git a/elf/riscv32im-succinct-zkvm-elf b/elf/riscv32im-succinct-zkvm-elf index a7f11b8..a9246d2 100755 Binary files a/elf/riscv32im-succinct-zkvm-elf and b/elf/riscv32im-succinct-zkvm-elf differ diff --git a/justfile b/justfile index 7d7819d..dc5f037 100644 --- a/justfile +++ b/justfile @@ -1,3 +1,5 @@ +set dotenv-load + # Build riscv elf file using `cargo prove build` command build-program: cd programs/update-client && cargo prove build @@ -11,10 +13,48 @@ test-foundry: test-cargo: cargo test --workspace --exclude sp1-ics07-tendermint-update-client --locked --all-features -# Generate the `genesis.json` file for the Celestia Mocha testnet -mocha-genesis: - RUST_LOG=info TENDERMINT_RPC_URL="https://rpc.celestia-mocha.com/" cargo run --bin genesis --release +# 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-program + @echo "Generating the genesis file..." + RUST_LOG=info cargo run --bin genesis --release # Generate the `mock_fixture.json` file for the Celestia Mocha testnet using the mock prover mock-fixtures: + @echo "Generating mock fixtures for the Celestia Mocha testnet" + @echo "Building the program..." + just build-program + @echo "Generating the mock fixtures..." RUST_BACKTRACE=full RUST_LOG=info SP1_PROVER="mock" TENDERMINT_RPC_URL="https://rpc.celestia-mocha.com/" cargo run --bin fixture --release -- --trusted-block 2110658 --target-block 2110668 + @echo "Mock fixtures generated at 'contracts/fixtures/mock_fixture.json'" + +# Generate the `fixture.json` file for the Celestia Mocha testnet using the network prover. +# This command requires the `.env` file to be present in the root directory. +network-fixtures: + @echo "Generating fixtures for the Celestia Mocha testnet" + @echo "Building the program..." + just build-program + @echo "Generating fixtures... This may take a while (up to 20 minutes)" + RUST_BACKTRACE=full RUST_LOG=info SP1_PROVER="network" TENDERMINT_RPC_URL="https://rpc.celestia-mocha.com/" cargo run --bin fixture --release -- --trusted-block 2110658 --target-block 2110668 + @echo "Fixtures generated at 'contracts/fixtures/fixture.json'" + +# Generate the `SP1ICS07Tendermint.json` file containing the ABI of the SP1ICS07Tendermint contract +generate-abi: + cd contracts && forge install && forge build + cp contracts/out/SP1ICS07Tendermint.sol/SP1ICS07Tendermint.json contracts/abi/ + @echo "ABI file created at 'contracts/abi/SP1ICS07Tendermint.json'" + +# Deploy the SP1ICS07Tendermint contract to the Eth Sepolia testnet if the `.env` file is present +deploy-contracts: + @echo "Deploying the SP1ICS07Tendermint contract to the Sepolia testnet" + 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. +# This command requires the `.env` file to be present in the root directory. +operator: + RUST_LOG=info cargo run --bin operator --release diff --git a/operator/bin/fixture.rs b/operator/bin/fixture.rs index e196451..9b8352d 100644 --- a/operator/bin/fixture.rs +++ b/operator/bin/fixture.rs @@ -6,12 +6,10 @@ use ibc_core_commitment_types::commitment::CommitmentRoot; use ibc_core_host_types::identifiers::ChainId; use serde::{Deserialize, Serialize}; use sp1_ics07_tendermint_operator::{util::TendermintRPCClient, SP1ICS07TendermintProver}; -use sp1_ics07_tendermint_shared::types::ics07_tendermint::{ +use sp1_ics07_tendermint_shared::types::sp1_ics07_tendermint::{ ClientState, ConsensusState as SolConsensusState, Height, TrustThreshold, }; -use sp1_ics07_tendermint_update_client::types::{ - output::SP1ICS07TendermintOutput, validation::Env, -}; +use sp1_ics07_tendermint_shared::types::sp1_ics07_tendermint::{Env, SP1ICS07TendermintOutput}; use sp1_sdk::{utils::setup_logger, HashableKey}; use std::{env, path::PathBuf, str::FromStr}; diff --git a/operator/bin/genesis.rs b/operator/bin/genesis.rs index a731cf8..e73757b 100644 --- a/operator/bin/genesis.rs +++ b/operator/bin/genesis.rs @@ -4,7 +4,7 @@ use ibc_client_tendermint::types::ConsensusState; use ibc_core_commitment_types::commitment::CommitmentRoot; use ibc_core_host_types::identifiers::ChainId; use sp1_ics07_tendermint_operator::{util::TendermintRPCClient, TENDERMINT_ELF}; -use sp1_ics07_tendermint_shared::types::ics07_tendermint::{ +use sp1_ics07_tendermint_shared::types::sp1_ics07_tendermint::{ ClientState, ConsensusState as SolConsensusState, Height, TrustThreshold, }; use sp1_sdk::{utils::setup_logger, HashableKey, MockProver, Prover}; diff --git a/operator/bin/operator.rs b/operator/bin/operator.rs index f2dcbe3..1ef5a01 100644 --- a/operator/bin/operator.rs +++ b/operator/bin/operator.rs @@ -8,8 +8,7 @@ use ibc_core_client_types::Height as IbcHeight; use log::{debug, info}; use reqwest::Url; use sp1_ics07_tendermint_operator::{util::TendermintRPCClient, SP1ICS07TendermintProver}; -use sp1_ics07_tendermint_shared::types::ics07_tendermint::SP1ICS07Tendermint; -use sp1_ics07_tendermint_update_client::types::validation::Env; +use sp1_ics07_tendermint_shared::types::sp1_ics07_tendermint::{self, Env}; use sp1_sdk::utils::setup_logger; /// An implementation of a Tendermint Light Client operator that will poll an onchain Tendermint @@ -39,7 +38,7 @@ async fn main() -> anyhow::Result<()> { let tendermint_rpc_client = TendermintRPCClient::default(); let prover = SP1ICS07TendermintProver::new(); - let contract = SP1ICS07Tendermint::new(contract_address.parse()?, provider); + let contract = sp1_ics07_tendermint::new(contract_address.parse()?, provider); loop { let contract_client_state = contract.getClientState().call().await?._0; diff --git a/operator/src/lib.rs b/operator/src/lib.rs index cb06587..6821057 100644 --- a/operator/src/lib.rs +++ b/operator/src/lib.rs @@ -1,7 +1,7 @@ use alloy_sol_types::SolValue; use ibc_client_tendermint::types::Header; -use sp1_ics07_tendermint_shared::types::ics07_tendermint::ConsensusState; -use sp1_ics07_tendermint_update_client::types::validation::Env; +use sp1_ics07_tendermint_shared::types::sp1_ics07_tendermint::ConsensusState; +use sp1_ics07_tendermint_shared::types::sp1_ics07_tendermint::Env; use sp1_sdk::{ProverClient, SP1PlonkBn254Proof, SP1ProvingKey, SP1Stdin, SP1VerifyingKey}; mod types; diff --git a/packages/shared/Cargo.toml b/packages/shared/Cargo.toml index d77afed..06873a1 100644 --- a/packages/shared/Cargo.toml +++ b/packages/shared/Cargo.toml @@ -10,7 +10,7 @@ license = { workspace = true } rpc = ["dep:alloy-contract"] [dependencies] -alloy-sol-types = { workspace = true } +alloy-sol-types = { workspace = true, features = ["json"] } alloy-contract = { workspace = true, optional = true } tendermint-light-client-verifier = { workspace = true } serde = { workspace = true } diff --git a/packages/shared/src/types/ics07_tendermint.rs b/packages/shared/src/types/ics07_tendermint.rs index f40e9d8..9c8f8d2 100644 --- a/packages/shared/src/types/ics07_tendermint.rs +++ b/packages/shared/src/types/ics07_tendermint.rs @@ -6,94 +6,35 @@ use tendermint::{hash::Algorithm, Time}; use tendermint_light_client_verifier::types::{Hash, TrustThreshold as TendermintTrustThreshold}; use time::OffsetDateTime; -alloy_sol_types::sol! { - /// Height of the counterparty chain - struct Height { - /// Previously known as "epoch" - uint64 revision_number; - /// The height of a block - uint64 revision_height; - } - - /// Fraction of validator overlap needed to update header - #[derive(Debug, serde::Deserialize, serde::Serialize)] - struct TrustThreshold { - /// Numerator of the fraction - uint64 numerator; - /// Denominator of the fraction - uint64 denominator; - } - - /// Defines the ICS07Tendermint ClientState for ibc-lite - struct ClientState { - /// Chain ID - string chain_id; - /// Fraction of validator overlap needed to update header - TrustThreshold trust_level; - /// Latest height the client was updated to - Height latest_height; - /// duration of the period since the LatestTimestamp during which the - /// submitted headers are valid for upgrade - uint64 trusting_period; - /// duration of the staking unbonding period - uint64 unbonding_period; - /// whether or not client is frozen (due to misbehavior) - bool is_frozen; - } - - /// Defines the Tendermint light client's consensus state at some height. - struct ConsensusState { - /// timestamp that corresponds to the block height in which the ConsensusState - /// was stored. - uint64 timestamp; - /// commitment root (i.e app hash) - bytes root; - /// next validators hash - bytes next_validators_hash; - } - -/// @title SP1ICS07Tendermint -/// @author srdtrk -/// @notice This contract implements an ICS07 IBC tendermint light client. #[cfg(feature = "rpc")] -#[allow(missing_docs, clippy::pub_underscore_fields)] -#[sol(rpc)] -contract SP1ICS07Tendermint { - /// @notice The verification key for the program. - bytes32 public ics07UpdateClientProgramVkey; - // @notice The SP1 verifier contract. - address public verifier; - - /// @notice The ICS07Tendermint client state - ClientState public clientState; - /// @notice The mapping from height to consensus state - mapping(uint64 => ConsensusState) public consensusStates; - - function getClientState() public view returns (ClientState memory); +alloy_sol_types::sol!( + #[sol(rpc)] + #[derive(serde::Deserialize, serde::Serialize)] + #[allow(missing_docs, clippy::pedantic)] + sp1_ics07_tendermint, + "../../contracts/abi/SP1ICS07Tendermint.json" +); - function getConsensusState(uint64 revisionHeight) - public - view - returns (ConsensusState memory); - - /// @notice The entrypoint for verifying the proof. - /// @param proof The encoded proof. - /// @param publicValues The encoded public values. - function verifyIcs07UpdateClientProof( - bytes memory proof, - bytes memory publicValues - ) public; -} -} +// NOTE: The riscv program won't compile with the `rpc` features. +// NOTE: Using the entire `SP1ICS07Tendermint.json` file for the `sol!` macro increases +// the riscv program size significantly, so we can consider using the `sol!` macro with +// manually defined structs for the required types when `rpc` feature is disabled. +#[cfg(not(feature = "rpc"))] +alloy_sol_types::sol!( + #[derive(serde::Deserialize, serde::Serialize)] + #[allow(missing_docs, clippy::pedantic)] + sp1_ics07_tendermint, + "../../contracts/abi/SP1ICS07Tendermint.json" +); #[allow(clippy::fallible_impl_from)] -impl From for TendermintTrustThreshold { - fn from(trust_threshold: TrustThreshold) -> Self { +impl From for TendermintTrustThreshold { + fn from(trust_threshold: sp1_ics07_tendermint::TrustThreshold) -> Self { Self::new(trust_threshold.numerator, trust_threshold.denominator).unwrap() } } -impl From for ConsensusState { +impl From for sp1_ics07_tendermint::ConsensusState { fn from(ics07_tendermint_consensus_state: ICS07TendermintConsensusState) -> Self { Self { #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] @@ -111,8 +52,8 @@ impl From for ConsensusState { } #[allow(clippy::fallible_impl_from)] -impl From for ICS07TendermintConsensusState { - fn from(consensus_state: ConsensusState) -> Self { +impl From for ICS07TendermintConsensusState { + fn from(consensus_state: sp1_ics07_tendermint::ConsensusState) -> Self { let time = OffsetDateTime::from_unix_timestamp_nanos(i128::from(consensus_state.timestamp)) .unwrap(); let seconds = time.unix_timestamp(); diff --git a/packages/shared/src/types/mod.rs b/packages/shared/src/types/mod.rs index 5ed8146..c92d076 100644 --- a/packages/shared/src/types/mod.rs +++ b/packages/shared/src/types/mod.rs @@ -1,3 +1,5 @@ //! This module contains the shared types for `sp1-ibc-lite`. -pub mod ics07_tendermint; +mod ics07_tendermint; + +pub use ics07_tendermint::sp1_ics07_tendermint; diff --git a/programs/update-client/src/main.rs b/programs/update-client/src/main.rs index 6a4ed59..13ab68f 100644 --- a/programs/update-client/src/main.rs +++ b/programs/update-client/src/main.rs @@ -19,8 +19,8 @@ use ibc_client_tendermint::{ types::{ConsensusState, Header, TENDERMINT_CLIENT_TYPE}, }; use ibc_core_host_types::identifiers::{ChainId, ClientId}; -use sp1_ics07_tendermint_shared::types::ics07_tendermint::{ - self, ConsensusState as SolConsensusState, +use sp1_ics07_tendermint_shared::types::sp1_ics07_tendermint::{ + self, ConsensusState as SolConsensusState, Env, SP1ICS07TendermintOutput, }; use sp1_ics07_tendermint_update_client::types; use tendermint_light_client_verifier::{options::Options, ProdVerifier}; @@ -35,7 +35,7 @@ pub fn main() { let encoded_3 = sp1_zkvm::io::read_vec(); // input 3: environment - let env = serde_cbor::from_slice::(&encoded_3).unwrap(); + let env = serde_cbor::from_slice::(&encoded_3).unwrap(); // input 2: the proposed header let proposed_header = serde_cbor::from_slice::
(&encoded_2).unwrap(); // input 1: the trusted consensus state @@ -63,17 +63,17 @@ pub fn main() { ) .unwrap(); - let trusted_height = ics07_tendermint::Height { + let trusted_height = sp1_ics07_tendermint::Height { revision_number: proposed_header.trusted_height.revision_number(), revision_height: proposed_header.trusted_height.revision_height(), }; - let new_height = ics07_tendermint::Height { + let new_height = sp1_ics07_tendermint::Height { revision_number: proposed_header.height().revision_number(), revision_height: proposed_header.height().revision_height(), }; let new_consensus_state = ConsensusState::from(proposed_header); - let output = types::output::SP1ICS07TendermintOutput { + let output = SP1ICS07TendermintOutput { trusted_consensus_state, new_consensus_state: new_consensus_state.into(), env, diff --git a/programs/update-client/src/types/mod.rs b/programs/update-client/src/types/mod.rs index 904ca0a..c63405d 100644 --- a/programs/update-client/src/types/mod.rs +++ b/programs/update-client/src/types/mod.rs @@ -1,4 +1,3 @@ //! Containes types used in the program. -pub mod output; pub mod validation; diff --git a/programs/update-client/src/types/output.rs b/programs/update-client/src/types/output.rs deleted file mode 100644 index b323713..000000000 --- a/programs/update-client/src/types/output.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Contains the public value output for the sp1 program. - -use super::validation::Env; -use sp1_ics07_tendermint_shared::types::ics07_tendermint::{ConsensusState, Height}; - -alloy_sol_types::sol! { - /// The public value output for the sp1 program. - struct SP1ICS07TendermintOutput { - /// The trusted consensus state. - ConsensusState trusted_consensus_state; - /// The new consensus state with the verified header. - ConsensusState new_consensus_state; - /// The validation environment. - Env env; - /// Trusted height. - Height trusted_height; - /// The height of the new consensus state. - Height new_height; - } -} diff --git a/programs/update-client/src/types/validation.rs b/programs/update-client/src/types/validation.rs index debb779..07d400b 100644 --- a/programs/update-client/src/types/validation.rs +++ b/programs/update-client/src/types/validation.rs @@ -7,23 +7,7 @@ use ibc_client_tendermint::{ use ibc_core_client::context::{ClientValidationContext, ExtClientValidationContext}; use ibc_core_handler_types::error::ContextError; use ibc_primitives::Timestamp; -use sp1_ics07_tendermint_shared::types::ics07_tendermint::TrustThreshold; - -alloy_sol_types::sol! { - /// The environment output for the sp1 program. - #[derive(Debug, serde::Deserialize, serde::Serialize)] - struct Env { - /// The chain ID of the chain that the client is tracking. - string chain_id; - /// Fraction of validator overlap needed to update header - TrustThreshold trust_threshold; - /// Duration of the period since the `LatestTimestamp` during which the - /// submitted headers are valid for upgrade - uint64 trusting_period; - /// Timestamp in nanoseconds - uint64 now; - } -} +use sp1_ics07_tendermint_shared::types::sp1_ics07_tendermint::Env; /// The client validation context. pub struct ClientValidationCtx {