From 365d35d65c2a8e00f1d8f3145ae71d66849990cd Mon Sep 17 00:00:00 2001 From: Ryo Sato Date: Fri, 29 Sep 2023 15:24:04 +0900 Subject: [PATCH 1/2] Parlia light client spec (#28) Add parlia spec. --------- Signed-off-by: Naohiro Yoshida Signed-off-by: Ryo Sato Co-authored-by: Naohiro Yoshida --- README.md | 10 +- SPEC.md | 340 +++++++++++++++++++++++++++++++++++++ light-client/src/client.rs | 2 +- 3 files changed, 349 insertions(+), 3 deletions(-) create mode 100644 SPEC.md diff --git a/README.md b/README.md index 2c71a8a..74aa86c 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,17 @@ [![test](https://github.com/datachainlab/lcp-parlia/actions/workflows/ci.yaml/badge.svg)](https://github.com/datachainlab/lcp-parlia/actions/workflows/ci.yaml) -ELC implementation for BSC. +[ELC](https://docs.lcp.network/protocol/elc) implementation for [BNB Smart Chain](https://github.com/bnb-chain/bsc). + +NOTE: This project is currently under heavy development. Features may change or break. + +## Documents + +- [Parlia light client spec](./SPEC.md) ## Configuration -Environment variables can be used to change settings. +Environment variables can be used to change settings. Each configuration must be determined at build time, not at run time. ### Blocks per epoch diff --git a/SPEC.md b/SPEC.md new file mode 100644 index 0000000..fabc902 --- /dev/null +++ b/SPEC.md @@ -0,0 +1,340 @@ +# Parlia Light Client + +This specification document describes a client (verification algorithm) for a blockchain using Parlia consensus with a fast finality mechanism. + +# About Parlia + +Parlia is a consensus proposed by BNB Smart Chain(BSC), combining DPoS and PoA: +- Blocks are produced by a limited set of validators +- Validators take turns to produce blocks in a PoA manner, similar to Ethereum's Clique consensus design +- Validator set are elected in and out based on a staking based governance +- Every epoch block, a validator will query the validator set and fill it in the extra_data field of the block header + +Ref. https://docs.bnbchain.org/docs/learn/consensus + +## Target Environment + +This client spec assumes that [BEP-126](https://github.com/bnb-chain/BEPs/blob/bfe4fdb90b732af2e25c9581c5e5391aa00c8246/BEPs/BEP126.md) is valid and activated on the target blockchain. +It introduces a fast finality mechanism to finalize a block. + +# Technical Specification + +We have borrowed the basic terms from [ICS-02](https://github.com/cosmos/ibc/tree/main/spec/core/ics-002-client-semantics). + +## Client state + +The Parlia client state tracks the current revision, the IBC store address, the trusting period, the latest height, and the freeze status. +The IBC store address refers to the contract that stores the commitments. + +```typescript +interface ClientState { + chainId: string, + ibcStoreAddress: Address, + ibcCommitmentsSlot: []byte, + trustingPeriod: uint64, + maxClockDrift: uin64, + latestHeight: Height, + frozen: bool +} +``` + +## Consensus state + +The Parlia client tracks the timestamp (block time), the hashes of the validator sets for the current and previous epochs, and the commitment root for all previously verified consensus states. +The commitment root is a storage root of the account corresponding to the IBC store address in the client state. + +```typescript +interface ConsensusState { + // the storage root(commitment root) of the IBC contract + stateRoot: []byte, + timestamp: uint64, + // the hash of the current epoch validator set + currentValidatorsHash: []byte, + // the hash of the previous epoch validator set + previousValidatorsHash: []byte +} +``` + +## Height + +The height of a Parlia client consists of two `uint64`s: the revision number, and the height in the revision. + +```typescript +interface Height { + revisionNumber: uint64 + revisionNumber: uint64 +} +``` + +Comparison between heights is implemented as follows: + +```typescript +function compare(a: Height, b: Height): Ord { + if (a.revisionNumber < b.revisionNumber) + return LT + else if (a.revisionNumber === b.revisionNumber) + if (a.revisionHeight < b.revisionHeight) + return LT + else if (a.revisionHeight === b.revisionHeight) + return EQ + return GT +} +``` + +## Headers + +The Header submitted to the on-chain client includes the target header for submission, the descendant headers for finality verification, account proofs, a trusted height, and the validator sets for verification. + +The validator sets pertain to the "current" and the "previous" epoch, as seen from the target header. +Each element in the validator set contains a validator's address and its BLS public key. + +```typescript +type ETHHeaders = List +type Validtors = List<[]byte> + +interface Header { + accountProof: []byte, + headers: ETHHeaders, + trustedHeight: Height, + currentValidators: Validators, + previousValidators: Validators, +} + +function (Header) getHeight(): Height { + return Height{0, self.headers[0].number} +} + +function (Header) getTimestamp(): uint64 { + return self.headers[0].timestamp +} + +function (Header) getHash(): []byte { + return hash(rlp(self.headers[0])) +} + +function (Header) stateRoot(): []byte { + return self.headers[0].root +} +``` + +ETHHeader contains information from block headers. + +```typescript +interface ETHHeader { + parentHash: []byte, + uncleHash: []byte, + coinbase: []byte, + root: []byte, + txHash: []byte, + receiptHash: []byte, + bloom: []byte, + difficulty: uint64, + number: uint64, + gasLimit: uint64, + gasUsed: uint64, + timestamp: uint64, + extraData: []byte, + mixDigest: []byte, + nonce: []byte, + baseFee: Maybe +} +``` + +## Misbehavior + +The `Misbehaviour` type is used for detecting misbehaviour and freezing the client - to prevent further packet flow - if applicable. Parlia client `Misbehaviour` consists of two headers at the same height both of which the light client would have considered valid. + +```typescript +interface Misbehaviour { + clientId: string, + header1: Header, + header2: Header, +} +``` + +## Client initialisation + +The Parlia client initialization requires a (subjectively chosen) latest consensus state, including the validator sets. + +```typescript +function createClient( + clientId: string, + clientState: ClientSate, + consensusState: ConsensusState +) { + assert(clientState.height > 0) + setClientState(clientState, clientId) + setConsensusState(consensusState, clientId, height) +} +``` + +## Validity Predicate + +The Parlia client validity checking uses specs described in the [Parlia Consensus](https://docs.bnbchain.org/docs/learn/consensus) and [BEP-126](https://github.com/bnb-chain/BEPs/blob/bfe4fdb90b732af2e25c9581c5e5391aa00c8246/BEPs/BEP126.md). +If the provided header is valid, the client state is updated, and the newly verified storage root, the hashes of the validator sets written to the store. + +```typescript +function verifyHeader( + clientId: string, + header: Header +) { + clientState = getClientState(clientId) + trustedConsensusState = getConsensusState(header.trustedHeight) + + // assert trusting period has not yet passed + assert(currentTimestamp() - trustedConsensusState.timestamp < clientState.trustingPeriod) + // assert header timestamp is past latest stored consensus state timestamp + assert(header.getTimestamp() < currentTimestamp() + clientState.max_clock_drift) + // trusted height revision must be the same as header revision + // trusted height must be less than header height + assert(header.getHeight().revisionNumber == header.trustedHeight.revisionNumber) + assert(header.getHeight().revisionHeight > header.trustedHeight.revisionHeight) + + // assert header validator sets are valid + if header.getHeight() % BLOCK_PER_EPOCH == 0 { + // extractValidtors gets the validator set of the epoch from 'extraData' of the epoch ETHHeader + assert(hash(header.currentValidators)) == hash(extractValidators(header.headers[0]))) + assert(hash(header.previousValidators)) == trustedConsensusState.currentValidatorsHash) + } else { + assert(hash(header.currentValidators) == trustedConsensusState.currentValidatorsHash) + assert(hash(header.previousValidators) == trustedConsensusState.previousValidatorsHash) + } + + // verifies all the header fields that are not standalone, + // rather depend on a batch of previous header: + // - The number and block hash are consecutive. + // - The timestamp order is correct. + // - The difference in gas limit is within the upper limit. + assert(verifyCascadingFields(headers)) + + assert(verifySeals(headers, currentValidators, previousValidators)) + + // verifies the header adheres to the BEP126 finality rule. + // Ref. https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP126.md#413-finality-rules + assert(verifyFinalized(headers, currentValidators, previousValidators)) +} + +function verifySeals( + headers: ETHHeaders, + currentValidators: Validators, + previousValidators: Validators +) { + chainId = getChainId() + epoch = headers[0].number / BLOCK_PER_EPOCH + // Validator set changes take place at the (epoch+N/2) blocks. (N is the size of validatorset before epoch block) + checkpoint = epoch * headers[0].number + checkpoint(previousValidators) + for header in headers { + // verifySeal checks whether the signature contained in the header satisfies the consensus protocol requirements + if header.number >= checkpoint { + verifySeal(header, currentValidators, chainId) + } else { + verifySeal(header, previousValidators, chainId) + } + } +} +``` + +Primary verification according to BEP-126's finality rule involves: +- Ensuring the correctness of the BLS signature. +- Verifying the relationships of the VoteAttestation: + - The `target` of the direct child header should match the submitted header. + - The `source` of the direct grandchild header should match the submitted header. + - The `target` of the direct grandchild header should match the direct child header. + +However, there may be cases where the VoteAttestation cannot directly determin the finality of the submitted header. +In such cases, a valid descendant header is verified, which is included in the `headers` and can directly confirm its finality through VoteAttestation. + +## Misbehavior predicate + +The predicate will check if a submission contains evidence of Misbehavior. +If there are two different valid headers for the same height, the client will be frozen, preventing any further state updates. + +```typescript +function submitMisbehaviour( + clientId: ClientId, + misbehaviour: Misbehavior +): ClientState { + // assert heights are equal + assert(misbehaviour.header1.getHeight() == misbehaviour.header2.getHeight()) + // assert target headers are different + assert(misbehaviour.header1.getHash() != misbehaviour.header2.getHash()) + + // assert each header is valid + verifyHeader(clientId, misbehaviour.header1) + verifyHeader(clientId, misbehaviour.header2) + + clientState = getClientState(clientId) + clientState.frozen = true + return clientState +} +``` + +## Update state + +The function will perform a regular update for the Parlia client. +It will add a consensus state to the client store. +If the header is higher than the latest height on the client state, then the client state will be updated. + +```typescript +function updateState( + clientState: ClientState, + header: Header) { + newClientState = clientState.clone() + if newClientState.latestHeight < header.getHeight() { + newClientState.latestHeight = header.getHeight() + } + + newStateRoot = resolve(header.stateRoot(), header.accountProof, clientState.ibcStoreAddress) + + newConsensusState = ConsensusState{ + newStateRoot, + header.timestamp(), + hash(header.currentValidators), + hash(header.previousValidators) + } + + setClientState(newClientState, clientId) + setConsensusState(newConsensusState, clientId, header.getHeight()) +} +``` + +## State verification functions + +Parlia client state verification functions check a Merkle proof against a previously validated commitment root. + +The Merkle proof is based on [Merkle Patricia Trie in Ethereum](https://eth.wiki/en/fundamentals/patricia-tree#main-specification-merkle-patricia-trie). + +```typescript +function verifyMembership( + clientState: ClientState, + height: Height, + proof: []byte, + path: String, + value: []byte +) { + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen + assert(!clientState.frozen) + // fetch the previously verified commitment root & verify membership + consensusState = getConsensusState(height) + // verify that has been stored + assert(verifyMembership(consensusState.stateRoot, proof, path, value)) +} + +function verifyNonMembership( + clientState: ClientState, + height: Height, + proof: []byte, + path: String, +) { + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen + assert(!clientState.frozen) + // fetch the previously verified commitment root & verify membership + consensusState = getConsensusState(height) + // verify that nothing has been stored + assert(verifyNonMembership(consensusState.stateRoot, proof, path)) +} +``` diff --git a/light-client/src/client.rs b/light-client/src/client.rs index cc1dfc5..2007d13 100644 --- a/light-client/src/client.rs +++ b/light-client/src/client.rs @@ -255,7 +255,7 @@ impl ParliaLightClient { return Err(Error::ClientFrozen(client_id).into()); } let proof_height = *proof_height; - if client_state.latest_height != proof_height { + if client_state.latest_height < proof_height { return Err( Error::UnexpectedLatestHeight(proof_height, client_state.latest_height).into(), ); From ffd92b9b1f058958dae53af499ba21a99f381710 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Fri, 29 Sep 2023 15:57:01 +0900 Subject: [PATCH 2/2] Conservative Fast Finalize (#27) Conservative Fast Finalize Signed-off-by: Naohiro Yoshida --- LICENSE | 201 ++++++++ README.md | 14 +- light-client/src/client.rs | 212 ++++----- light-client/src/client_state.rs | 5 +- light-client/src/errors.rs | 116 +++-- light-client/src/header/eth_header.rs | 23 +- light-client/src/header/eth_headers.rs | 323 +++++++++++++ light-client/src/header/mod.rs | 137 +++--- light-client/src/header/testdata.rs | 441 +++++++++++++++++- light-client/src/header/validator_set.rs | 10 +- light-client/src/header/vote_attestation.rs | 14 +- light-client/tests/ibc-parlia-relay | 2 +- .../ibc/lightclients/parlia/v1/parlia.proto | 12 +- proto/src/prost/ibc.lightclients.parlia.v1.rs | 18 +- 14 files changed, 1212 insertions(+), 316 deletions(-) create mode 100644 LICENSE create mode 100644 light-client/src/header/eth_headers.rs diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d1d58d8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 Datachain, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 74aa86c..d7d7562 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# lcp-parlia +# parlia-elc -[![test](https://github.com/datachainlab/lcp-parlia/actions/workflows/ci.yaml/badge.svg)](https://github.com/datachainlab/lcp-parlia/actions/workflows/ci.yaml) +[![test](https://github.com/datachainlab/parlia-elc/actions/workflows/ci.yaml/badge.svg)](https://github.com/datachainlab/parlia-elc/actions/workflows/ci.yaml) [ELC](https://docs.lcp.network/protocol/elc) implementation for [BNB Smart Chain](https://github.com/bnb-chain/bsc). @@ -21,12 +21,4 @@ This is available in dev feature only. ```sh BSC_BLOCKS_PER_EPOCH=20 cargo build --features=dev -``` - -### Fork height -You can change the fork height for each net. - -```sh -BSC_LUBAN_FORK=1000000 cargo build -``` - +``` \ No newline at end of file diff --git a/light-client/src/client.rs b/light-client/src/client.rs index 2007d13..cd26035 100644 --- a/light-client/src/client.rs +++ b/light-client/src/client.rs @@ -19,8 +19,7 @@ use crate::commitment::{ }; use crate::consensus_state::ConsensusState; use crate::errors::Error; -use crate::header::constant::BLOCKS_PER_EPOCH; -use crate::header::validator_set::ValidatorSet; + use crate::header::Header; use crate::misbehaviour::Misbehaviour; @@ -93,14 +92,7 @@ impl LightClient for ParliaLightClient { } // Ensure valid validator set - self.verify_validator_set( - ctx, - &client_id, - header.height(), - header.target_validators(), - header.parent_validators(), - header.previous_target_validators(), - )?; + self.verify_validator_set(ctx, &client_id, &header)?; // Create new state and ensure header is valid let latest_trusted_consensus_state = ConsensusState::try_from(any_consensus_state)?; @@ -210,22 +202,8 @@ impl ParliaLightClient { return Err(Error::ClientFrozen(client_id).into()); } - self.verify_validator_set( - ctx, - &client_id, - misbehaviour.header_1.height(), - misbehaviour.header_1.target_validators(), - misbehaviour.header_1.parent_validators(), - misbehaviour.header_1.previous_target_validators(), - )?; - self.verify_validator_set( - ctx, - &client_id, - misbehaviour.header_2.height(), - misbehaviour.header_2.target_validators(), - misbehaviour.header_2.parent_validators(), - misbehaviour.header_2.previous_target_validators(), - )?; + self.verify_validator_set(ctx, &client_id, &misbehaviour.header_1)?; + self.verify_validator_set(ctx, &client_id, &misbehaviour.header_2)?; let trusted_consensus_state1 = ConsensusState::try_from(any_consensus_state1)?; let trusted_consensus_state2 = ConsensusState::try_from(any_consensus_state2)?; @@ -280,67 +258,35 @@ impl ParliaLightClient { &self, ctx: &dyn HostClientReader, client_id: &ClientId, - target: Height, - target_validators: &ValidatorSet, - parent_validators: &ValidatorSet, - previous_target_validators: &ValidatorSet, + header: &Header, ) -> Result<(), LightClientError> { - let epoch_count = target.revision_height() / BLOCKS_PER_EPOCH; - let previous_epoch = if epoch_count == 0 { 0 } else { epoch_count - 1 }; - let previous_epoch = - Height::new(target.revision_number(), previous_epoch * BLOCKS_PER_EPOCH); - let current_epoch = Height::new(target.revision_number(), epoch_count * BLOCKS_PER_EPOCH); - let previous_cs: ConsensusState = ctx - .consensus_state(client_id, &previous_epoch)? - .try_into()?; - - let previous_validator_size = previous_target_validators.validators.len(); - if previous_cs.validators_hash != previous_target_validators.hash { - return Err(Error::UnexpectedPreviousTargetValidatorsHash( - target, - previous_validator_size, - parent_validators.hash, - previous_cs.validators_hash, - ) - .into()); - } - - let checkpoint = current_epoch.revision_height() + (previous_validator_size as u64) / 2 + 1; - - // Ensure parent validators are valid - if checkpoint == target.revision_height() { - // The parent is checkpoint - 1 when the target is checkpoint - if previous_cs.validators_hash != parent_validators.hash { - return Err(Error::UnexpectedParentValidatorsHash( - target, - previous_validator_size, - parent_validators.hash, - previous_cs.validators_hash, + // Ensure trusted validator set is valid. + // If the submission target is epoch block, the validator set is included in the header and not in the consensus_state. + if !header.is_target_epoch() { + let (current_epoch_height, current_validators_hash) = header.current_epoch_validators(); + let current_trusted_validators_hash = + ConsensusState::try_from(ctx.consensus_state(client_id, ¤t_epoch_height)?)? + .validators_hash; + if current_validators_hash != current_trusted_validators_hash { + return Err(Error::UnexpectedCurrentValidatorsHash( + current_epoch_height, + current_validators_hash, + current_trusted_validators_hash, ) .into()); } - } else if target_validators.hash != parent_validators.hash { - return Err(Error::UnexpectedParentValidatorsHash( - target, - previous_validator_size, - parent_validators.hash, - target_validators.hash, - ) - .into()); } - // Ensure target validators are valid - let cs = if checkpoint <= target.revision_height() { - ConsensusState::try_from(ctx.consensus_state(client_id, ¤t_epoch)?)? - } else { - previous_cs - }; - if cs.validators_hash != target_validators.hash { - return Err(Error::UnexpectedTargetValidatorsHash( - target, - previous_validator_size, - target_validators.hash, - cs.validators_hash, + // Ensure previous trusted validator set is valid + let (previous_epoch_height, previous_validators_hash) = header.previous_epoch_validators(); + let previous_trusted_validators_hash = + ConsensusState::try_from(ctx.consensus_state(client_id, &previous_epoch_height)?)? + .validators_hash; + if previous_validators_hash != previous_trusted_validators_hash { + return Err(Error::UnexpectedPreviousValidatorsHash( + previous_epoch_height, + previous_validators_hash, + previous_trusted_validators_hash, ) .into()); } @@ -390,7 +336,7 @@ mod test { ibc_commitments_slot: hex!( "0000000000000000000000000000000000000000000000000000000000000000" ), - trusting_period: core::time::Duration::new(86400 * 365, 0), + trusting_period: core::time::Duration::new(86400 * 365 * 100, 0), max_clock_drift: core::time::Duration::new(1, 0), latest_height: Default::default(), frozen: false, @@ -418,10 +364,7 @@ mod test { impl HostContext for MockClientReader { fn host_timestamp(&self) -> Time { - Time::from_unix_timestamp_nanos( - datetime!(2023-09-14 9:00 UTC).unix_timestamp_nanos() as u128 - ) - .unwrap() + Time::now() } } @@ -497,46 +440,46 @@ mod test { #[test] fn test_success_update_client_epoch() { - let header = hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ae570ab2110aaf11f908aca08aca8431ab5aeff6cbb57f16341a771251d9bbc717d70157b8bfbd556160cec8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940bac492386862ad3df4b666bc096b0505bb694daa062361a3085acc8d5943195b2384b92a8f98a38378742b3517f59120ab7eb2202a0c5e1298077c43760d67b955e4d6bdf407b7eeb5933a163d549dcde8421a19194a0af8299fddfd5c12712406fcfade62105d99f0296636f6af32ad5f185b6b0bed1b901008e2613120a7890df62d86844d400265006098a09cda2093d733019b176f6fb618a13d1f641c29654939a1a690003d2e4b91f933542172b4f4966cb12efad17f1448ce3c423650ca4bfb280f902a2b73ebc1eb5a30fd64b30b47d10dd98380009efb81c37da5aa92c945bbfd2e9296f79ed41d17bc949d5c8ae386610d93d6db35b08f2323f63ab7d1ade14ccad15bda0083ea6ad0811146807ad11ef09a75da44bdaa918d079471867824c68a64f29429eed11a12217d3825201b5a1e3c732ca6832ee6ea50750174502c4c97a86fc342371b308000e3a184df27c7207c0a42e3175720b6d346b3bcf9216d5e0bf23237b15ae80fa25ed6ee82f6502ec310692028401e41cd084084fe2c683b223ec8465029ce2b906add88301020b846765746888676f312e32302e35856c696e7578000000b19df4a2150bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c816295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a61dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d257ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e8b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d78869485a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b741b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de7b4dd66d7c2c7e57f628210187192fb89d4b99dd4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf9be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cdcc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a419ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbbd1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce739e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d21e9ae3261a475a27bb1028f140bc2a7c843318afd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5bef0274e31810c9df02f98fafde0f841f4e66a1cd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8b5830d7fffb860a6051bc8aa5105d03a38815326cde697223e84c41129e828e815d52652d7e3ad072440df980f9bb4a59ea8540ec7c47d13955f21b040f085f4c7e02c1e4a8abcfe6609e93ec873e1cc1b24f179ff4a66d2f6d64e0ccd545ea02d73c7c581cca8f84c8401e41ccea02d87d98f9b48596c7b3f5159f497870d7f5451f8a0427b6300e4511210d47cd38401e41ccfa08aca8431ab5aeff6cbb57f16341a771251d9bbc717d70157b8bfbd556160cec880e66b6ab812b2b0933f3fa4736521465cd3848f88b9061657dba2a718135dfe7229f3db84de7e8ab6ef4d62b2e4121d24293c83d2c17f7f01a5992095bea6300f01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080129d060a9a06f90317a02d87d98f9b48596c7b3f5159f497870d7f5451f8a0427b6300e4511210d47cd3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ef0274e31810c9df02f98fafde0f841f4e66a1cda088d1c007b7fd6366eff2fa6d3dd7e5eb073ded9d39783595909485e32db69a0fa01fc3d774842d20f30837cda4bd61cc6905a88e0246e6f25c57db36769d1dcc02a0b98c96fd2ccefcf1bf668dabd93b9882c2f77b64e4ed4424a5cff2c51a8ca2c7b90100032623831c605e1d488622e58e0a24fa2180644db1090f251a2e0b033048a330ef83106341c114818763d8481214670283028510a04af18ad5d040c66c6237c8d140c480299141480758202d8434e469e8d2484229c74818a42e300890120180831ca0367ac2e504085d1e1051ec090808a0147a7cd94cc04b8023300c0c480011eaa8cc2a378209008c64081c0028a8702d87b539800d7cc10841c18483406a8f82e10057bc6350282d4586a3a20a54bcad0aa9058b64074f2a70a270049c46e2191c5726021b4290e290a9c3ce10722f42e304001071740791f45b3022a448b0d3ca25fcb06829d5910ac4e701af01b3e624722e3500c09d4ed340e2792c4a028401e41ccf8408583b0083976c3c8465029cdfb90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b583057fffb86093e9476571bc5bf9a5e342e87aa9128a3f6ce8268a38d76aa2137901a91c31248b76049aae5a9ca917ebff673f5fd032042d8c505f66238bcb2849fcb618f5ec12df1dd98b669ad7c2b50febf722a090b99dc353e196285e9874b5b18ebb700bf84c8401e41ccda062caf1bd0f4478d01e7b7f86a347f101008b2df97fe9c2e6db6a34766ac39f078401e41ccea02d87d98f9b48596c7b3f5159f497870d7f5451f8a0427b6300e4511210d47cd3806e648aeafd4de991b5c50e877b32981c47de152ac281caef55772f6ebf379d8314961a93960127fc912d5cb2c19fa2483d082600c39de503acb808874be8053a00a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801a0510cfb9900f22951df90e92f90211a078682f5623941ca4443d42a2d59354b95fca79130e106972e29bf7ab42a4e6aea017c06595294e527b70999c32b5ae7ad6df586bf726e3fe404bfbd5c8384aaaafa072eb79c3f1b0459b8d943ac097fbdd898ea0d85cd643b00359aa6dddd6a859cca015cbbe38bb45622da8a17ea08304674e66349240f6681aedd8fcc0fa67d37211a0fc9fd25e79319231adb1e029720bb89d4d7c4ff82399508e0bfd6859c1d70571a0119a0f17ff6fedc4a6140b0a6428ba93e7eb7acb5bb4ea104c1ea97004feb3dba097de23e902407cbeacdaa1ce04867123637ea7cc5eec7c6ef7b31548eb9b389aa0d24fcc67fbd0beb5a108ad4d39c0a29936fb42ed0ed4317b5b67acbe74df49f3a0a44f108f152ab751ffdc5e95631eb335bfe9727fa94e56c712059ef15c5649b9a0a0f2c03f3047d162a92774d03c12f4f8cd79249c565339418d9b02cfe14ea631a0b1350fc61ae8cacb38bb9ffba9dd15d5b7f878b3e797edb1d5a8a61e2a1b463da00beb9ae62019d6906b959124b6c8c8fb4482fd8c6a9e07b6f75008ede8910d2ea0c109353d46e65a835ce8d7d22947d7095babc4394af8f5b3dc0d635732529d4fa091b0f50757e7aaf9a3550412f76e64a201577f346b8464d20bff0154a9eca27ea027716cd094393455a2ee7f4dc6d6ca310bb0a917328fdc81206bd0bf7b2ede64a07d18775eae42452a5bf56a243ce2f4a26702b85fb2279a156f1eb34e105610a180f90211a074b2e69b5131b3d46a6eae8c2228388a8d3a5072b02ab069b8dc05cf45683b63a08877997be7f0f5c2825e67f0090f332dd2f00901d0015d8867afaa3dd760cc62a0e6bbc4ed9203078c0c65e1b2f06b7378bd00fefd8dfdfb7849888d4b47d8aef9a0aafa44c14e7ed7d3d60b0b7baf5cb6240755d553c744ecd69c372214a88051a4a088e7b0a66cb02d57f9bc1caa49219af851c176084b85e9a81eacc2e4491a1ce2a03a2191549804dc71450920c4fbb155da2223ceb22a4016e5fb5fc788d7b858ffa0ec9710e161df3a4e339fc2f4dfbbe6b67e431c4a9535928df3866c383efa9ccfa0aac6c142446d15d760d5adbefb58e2342575d115246315f852b067113cf6a273a00652e3b635bbf47518e49d96d98fcb32d5357765db4adcc445ab9c252b60dc94a050c3727303f45793d4dcd44befdfa1cb0d37789654b654752d5656a64e34cd67a0fe24cc78faed1f4debc5e42693b727b22b285811d9c3d718a0c5176630010874a04516259c2f6e7be5c6a875325f38ada0c170e80a2a056a1cfc019c49b63bad81a04fe395f80c8d15e7a38ab270ed23e3825b50c2b70f7dfa6e8e0456d6a0088c70a0699056a4ea871ec3b46cfc6a92d3a9eba2b59f2fae516f9a087157eca27c64b7a0873567010438f3c38519fa06bd1addd7a0884a7793586f00b270d9b7ef643788a0dfcd10bb4a0dfac1adf5c38e9f52ca08029739d22d90547047bc0017395f644380f90211a09f1dd03fcdb993d49756357271d052599c58f04bc64006f9a8b4469a0e6a07c8a052e6f63aff710f9b54d0f30c24a0394da114c908d909454d1c65dfd592102c44a03609f37ff4e54b4d6521ea0fb9a51dbdf2fb3c849571fc665e5a4ed61402bb72a00495c4ba0e87fe3ecb9e7b04c57f44e139acac06ed5bebc7a2deb64baac09947a026b5feb48f9097f126aad87706aad7949cfb1101878da1e82fadd537d4d31204a031d41490cbd7686405a5e3e27f687bba44b7c1610da21c85eb8fcd58c92c7e55a0c771eb336c16af1daef09b6fbedd3d6d64eda4f2200578ea66f84e17eb3e6b29a07dfd260f0501087c5d41767fe6eae820bbcc989db66ef7919d52c441801055e5a0d208a359ece6c14fccdd608ea67b0cb4aa692413d60c42fd6360ff1c4c1a3071a0567f31df4f6e7ba71cf751a829847a20db9c51028ec5465da8eb2dfa0238eb85a0072c90b0675572aa5d1670d7a9cf48d0aeb2b8a9dfc0a29683877a231ae6a110a0b0c2cd4918c64e830d3a9d0cdd4721405ba41c0ea6ea7b5e4f719063caf8e1eea046c893b61c7dcccf84b7ba8b5ff3179e094721fbd17eea67e6916a4f0a05a80ea03313e62caa98dcdb0ddea9a268c0c7600de661bbfe93031f48a6f2048aecd8f2a0a14250c7b873925d6f2dcd449d66c494c630d8dc0c22faaf8a4426a9c174c25ca02afdb4a07667673dff709af74945acd71e9b323b58150daa66843b1730c0900680f90211a0f3930469f8a8e57bc8b4f29c630174f6510144c334a185f2493817c81a55c624a0e20a4b8912ee792417ec7d03ba3496b81c50600ab20cbe96766647cb01ddf314a07f11c590a0283af81d54659084c94c5de50154f109fccf259a08af0f9a3f4cc2a0ef7214916dd7079f1050b22b193df0c669933d950e494707da5ff8938133f877a0ddeacc442d98146bdf1ab21eb9f2616e310baf330675ddf54048f3cc0372860ba0c3b1d3a0fb6af742e424a22ef29b2b8e924b878da3111b557006b1027ec89383a0508b4e32597bd3de6f682d9bcd31785585ab2c2880d6532f7eef87872473aa73a027b3ee9a3baa394e446e437f74054517ff84258ea9d7acfe790aeb5ecf585ccaa046cc03d1ee2ee491891f43dfed7c90e6250d53b012853d095c630c46221206d8a0f2b0c3c39d22ca62e0ddc30121e4616db7a4b50504486d6b3c5327853576df0ca0e39d05da42fdbe1648cd4f80e59a1d391dade7c6f0636ce8b3221037c7eac578a06a3d2c5ea2f9b02452ce153cb10cb8c1ad1c16fbbf2b77eb89f022fe8f850746a03b2e472720e11235bc3ed475f96bdcb82eb7b2b90ae4c44d72568c6b66761397a003396a318468f7db7183cb71c04193c6e70b990d15d7560a6748e2b2e755152fa0f3ad9eaad7a6351c85aa13de3314018c2dfb82c12dfd5613468217f0bbe68747a0831fd06a3d63affbdefa75fc6a542596f5e72a2d3267d0667b0d0a4eed72c4b180f90211a0e484c57f98d9dcb3981e79fec1fcdd4e9ade6b50a8763821faa52d6e9c40e515a09784bb9273fa7f29beefb8fe8c68dd148c164549aa1551cb8c69a4701af3d94ea064ddce91ada26c9916cd903f21c5b6008bf2a865ef9d3fc24bcd423bd02d9a93a0b4a7c85096f6d7016f1834bc01e1ed6c4314ebfbde73f80bce360a2f03e3cedfa053ecf424b86f3d97a054b057590cecb1e5e2878fb83d86cb7730b3dbecc4fd46a02d2bdccfe1586cd1692479a75d2b97a4d135e3dbab564ed3b6855113c62af598a07ab54330ecf7eb9e02720897d0380dc07eb2665892627451d174d1d87fdc2067a0d3d35f8b3ffa8c8c98cb34e89432b6157a148c4da14f868f97c9404d985850e0a07506b051d3f02f382730e2012e93b65addfccc9c962afbbbcdbd141b66c495daa0718f9d6c2bbf55d70c80a5decc2f49ed78026afc27de294dd28167f0e41786dfa072ae72e1a94cba48ff51cfc05f405af5931cebd85881e7767b4ea1884b87e4dea089d6433224364f6d40dd7d438ec7d1c924d70209ac8dbda89ccf5a39d1f031b3a0fe834ecb338a4b03a894fb36f2d0442ea48e6d0fccac2a45f0ea2e6abef6487fa0ce3c2a783bf9aff7764d32910d594a110f549367ee6b94d157ef949a2c33e65ca0f9f8490546b48f4dd548bef52d9fe8aa827d214940ce1842d139a94f341b611fa0d4b4fc09aaa8c6317c2060ef5ebaadc9bc211742296c8a80511b7ee0cd03417280f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea0c6c70650f6edd7057de9a8d7aeb5a52bc40dffb8a9cb71d55990a628f1596402a03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a09592d731bffb4d9b9ed4cf697f24f55ca7075c66a021aaa9f0ce119bea344411a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a0fa59d52ce31992709b7380abb4db6a33327763297b3c94791f348d886c7125faa08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a0253e402e9d5665c986423a2518d345b0c4d184d36562df4736dc28c3a51b60e2a05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a0dc34a817b1795244d58bb1b03cb361fbc68a3bb4a66ba3d891bfc0490d59115ca0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a08c81335ba79260e105491d1226e33dec334014016614983701be7b7fb10af9b7808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a44733fda7714a05960b7536330be4dbb135bef0ed6b0245c33bc556cfeb013cd3643b30dbdef6df61a0be3ba00cae104b3c587083852e28f8911689c7033f7021a8a1774c92a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44d93dbfb27e027f5e9e6da52b9e1c413ce35adc110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2a44ef0274e31810c9df02f98fafde0f841f4e66a1cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e32442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9132442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab0324461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d25324470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba7324472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a513244733fda7714a05960b7536330be4dbb135bef0ed6b0245c33bc556cfeb013cd3643b30dbdef6df61a0be3ba00cae104b3c587083852e28f8911689c7033f7021a8a1774c932447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e32448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193244d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393244d93dbfb27e027f5e9e6da52b9e1c413ce35adc110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3244ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e3a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e913a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d253a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba73a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a513a44733fda7714a05960b7536330be4dbb135bef0ed6b0245c33bc556cfeb013cd3643b30dbdef6df61a0be3ba00cae104b3c587083852e28f8911689c7033f7021a8a1774c93a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e3a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393a44d93dbfb27e027f5e9e6da52b9e1c413ce35adc110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3a44ef0274e31810c9df02f98fafde0f841f4e66a1cd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").to_vec(); - let height = 31726800; - let trusted_height = 31726799; - let c_epoch_height = 31726800; - let target_validator_hash = - hex!("d887eebd41d2e3e41fc584712ebcca8e7d0d506a7dbee98d385a5c4a612dec95"); + let header = hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d2460ab2110aaf11f908aca07b325363b3680051fbb4021dbdde32872a162350b3fb14d5b85eb42fa3f82c8fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da0b3a831bd97ae656b53bc849f785d067b75f9b897887fcec789c5e3f03e67bd6da002b419da6c5a8c34648455e32c9c69fa6e3af07b6561afba4fb046db794f2a57a0b02dbfd462d1f79d6917f78c4049db41d8e53d157997238031a41181e18cccf4b9010070bed650874c9919054904d58a0a2a8e061040b00509822a4a1d25059a2b11f8852373220603166498e7b43ec01a0ac48853c61810a921746c208ada6066662d3e42ef05a7d018ad3312f9c99716142c35117169636ea8078905f490c6a03a819fbdf1670f86282141482210026a4f62b8d184c300e8ef7e4400301dca0a24a694b7a614039a08b5a8a21ca44094a84a96ac35d56eee05aa2755f345d05bfdf023b0e0200365f3320448640d3a86170b4967158991809e03d6bb80b14d512268c1261553380548c712c182a610efdb2432d7a46098486074219b7b768234e5143db6f5aab24443c28b9438c43f03a3865b099c088da9894238692344c4eddaca028401eab3888408583b0083b1c4318465166f86b906add88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2150bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a7cdd959bfe8d9487b2a43b33565295a698f7e20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a70f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba772b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a517ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e8b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694859f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c3a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b741b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de7b4dd66d7c2c7e57f628210187192fb89d4b99dd4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf9be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cdcc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a419e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d21e9ae3261a475a27bb1028f140bc2a7c843318afd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5bef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0f8b5831bd7ffb860b5ee8c88d43deb61c9f44cd47b8c6209e8eaec93673e0125ea07ac82562c4c841970adee6d3351f55cd2fc686228fde0071c1eefaa87f275d0af9aba7973e24af1f86f8264eef64aafd6aa09c4cb8fc45602cd106fe5535368495e64e77ab9d3f84c8401eab386a041267ccf06a6543ace9cd0a1ea7e527619b74eaaf71958d5354e62c1aa10e8918401eab387a07b325363b3680051fbb4021dbdde32872a162350b3fb14d5b85eb42fa3f82c8f8037556341e6c5a2bde382a3c7c304ab1998df3a9ad30153827145f3bc274609947c940db8a70264366196622b72b504d659bef82e68b8be444121c7b30e90b60200a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a03e13a15d33736dc00e91c112940d4d15b8cd24cbe476d33a465c920321f8af63a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ef0274e31810c9df02f98fafde0f841f4e66a1cda08be37ce63563ff0222d8ce1a86200026615c38e8273a12281041e7f39146b138a0682945a71dd35f4709be1a9d56b8b1c1a66ab88de106dcc58a44d63ab4637214a0422a6c25944bba2964e786f166268f1e9b969733148e662e8d154b5f5dbae932b9010008a602460080341c0030846c980817421100c08961c04d11e90f9101541a01188a6710291084942833282981861d0325c392bd09080a001248584c7060742028d14845110fe818008d00082db139f97669102130974f18940344050781126413982c90a72b162a0510d32a30070bc9668a2e0a50320bccf432a0c59098002153840eb418465048c84c98258096084c9cd4a566c7f938ec0af38003d822d46a206e20f0bb32872202a44d52442a92131a04b90b4029b44673b56000a0244800c4e3c91d22130a2d4611a114b63432e02422e000e298283215c975f046c0f4e4e57298bb851b347921190a8286034a214a13a434e1166240f8130a8b843a2500c6028401eab3898408583b008397b01d8465166f89b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5831bd7dfb860803ca04cb904f6f3f58e9747221dfa675c4f92f87ef89bf2ae2c3e27082e8edc8b36ad4e095278cc18d58613963676ed15633da90d6f668e9f2bf3eb2f6387367abb427505c8c0563f505c069f02b11177f7f28458b6baa6d102d9eef4a2cca0f84c8401eab387a07b325363b3680051fbb4021dbdde32872a162350b3fb14d5b85eb42fa3f82c8f8401eab388a03e13a15d33736dc00e91c112940d4d15b8cd24cbe476d33a465c920321f8af63800cc38cf19e3a5a8372dd446f531026e7e7cc48f99a6c2520ed58c3018c704e8f534f3e235ac67246a487812963e5a8c3a652ba4a372f1c7f8fc5cfbc8f92a08500a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a054b25577a2132fca7050e5638eb453129a72e58979fba7f0a9b058fc260ec8d5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940bac492386862ad3df4b666bc096b0505bb694daa0ec07aa9aff014d0b743dcb1ca314491a87d6f671b4407551f8a58f832f9e887ca032699e6e74973ea7a3b63dbd34a871c7acdf6c8f4f3c9054d7b8f58385b03cdfa0869b0ba5791398541998ff6c3bced9ffc521d0a7df463f7faf90ab4a66a8d658b90100c82c062a752a969800f47e66d21840f010850848b001c9c31af089a25611a1989445d142206891480225981f4c0272aad886de08a13e42c8622fa418e7b4e9230642ddd847785412af0f021c890c49a26831924a0454294e889c1942a06742218a2aac237f63815064014860e9002f430a19c9ff88c86db64694d73761101f36ba4ca7942a1b7d91248a342a166a0c3c24a43e45b1c502186b081dd26b690b22a792842906bc6ba301337f145ace8572ecca003a24806183918031f2288fb048b007257a9057c8ce5012443704067316a9d24942718e61750b186c432b0aec24821230190120ab38bfce064e270b0186828da58d44b8c344ba03a8041e79289a028401eab38a84084fe2c683ac46788465166f8cb90118d88301020b846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831bd7ffb860b189ec1081a5cb0d76565d38ba3c7eb53f430c2c8c31cd99cca2388cb51c83da404f5db7c2ff75197b3098738d9f062e18abecc6d20e74a85b746e3b48e482f0b31cf3956d2a0b1999613631027014a941405d24b5ed1cb74515abbe60cdc464f84c8401eab388a03e13a15d33736dc00e91c112940d4d15b8cd24cbe476d33a465c920321f8af638401eab389a054b25577a2132fca7050e5638eb453129a72e58979fba7f0a9b058fc260ec8d58093a433cc01e2177d16730b941be9f1ad37affaed51a130dca3df7557012e6fa63ed56593da89e2a18504815b663070ed92da4c5b93ee458b02703294d0ccdff001a000000000000000000000000000000000000000000000000000000000000000008800000000000000008012051087e7aa0f1a951df90e92f90211a04bf76c23e52c557622ec5787af5301db12601d3817721b9e474c9f64d391d225a0d6f03ce823c4f6f1ea0ed82ed08e1e171d1f1744d3b616d04d8a0426167969bda0bc14789a692411e447e4dc81f8870ca28e0af9eb0d666796e3e36e7f638dec1ba02722bfd4c4f6e9d1d4e0f47aeafe2375ff0cfdd2fa6134009a45f8cfbb3c075aa0db1ea480149accc8358d1aaeefb26d8c83c499a9231530953b1b2a882f1b3446a05849252c24de1a63cd238768734ba31af91b76864060989d4998dc86fffd4b9aa05b252ddd28b025178a6e08d5084fd67c86f8fe8016f393599723cbbbe46f66a7a081dc56eedce81156678f0653a5cd8e1b738ded218dea768699dc3c13a0202080a01a28d97bdb0b103eff207fa4e213cec5de402d776634779e97152f7cab40faa6a09aecf5ea0a64b1b473e9c6347712a8b2ae098c8caf7d0f2b94a8656f7f261348a0b7117bf6a6cc2d8f456bfc0fdf9b55f22fce7f84d2038ed1996e4ef245739d58a0daa046b127ab4cf4cdd0a5e1c17b47766384b259ef9c1d7d8ad9799e0258a1a2a0864e14b7fc20ac11ae82af013514cd77b44596f0f7df7eb5de5d079d43bf873ca093524f079d3712837487d17a25d1e74e76a6d157476799a21d0249bfa9f4651fa04d763a7737a33bfa44885f986e6cbc24b75ba6cb2a5217a0757095721fc8d4a9a0bf6e47720c0ad8c635310ef9a8ec516e67c97462eb099069109db1aa4daa2eb780f90211a07a4e74fee097e91c497b222f10265b386f1dd3be32fbc433246618f407948adda0bc0d641cde19cfcd5edc4411ededefc7a5baacd4caa7ef7451f2f7a9cd44efbda004f525a8ac557569854fd81baa01297a98e94846373d7af6b0d9ac256c0f2e7ca02972a6b1b1442c73ef9a8ad925f88aabda8827805e53311bcf57a51e37bbc38aa00952d0166212ae0627ead53a95c251c8312f4786e48ee8f9bbf77dc4c3be9dcda09360c69f6998b61d7f6d23cfead44a5814d0b7af1c6f1d362998f5f3b29f90e2a03100f14f6b528b0b53510f4526839951d93b7a753a992d4583b253074e3ed082a04658d4dc5eab15eb45e898a274271e6d12c6114598603728ae191446536ec183a050f1a66d3e9552e72cd7faeeedfde5ab39bb28955e46dc03f0673f71c353c3e3a04715f7f1a5a0bd9e186ef3af0fde6e15cdf837b0e5a1ce621b51749494334e6aa067bfa3983e9301e53ff4ae330c8594c6129187c58a79198b17079734dd1ec879a08ff30871605fea4f745531c82037ea4582aeec15c78685b4ecc583dd414c94d8a04638c957c6846698d46d64e89b9883b619ebe02b015017c674b964a29a080e20a087da73fbcce7081770fd90fa826c34bf5016185ae5e2fef179692eb76bd25f43a0201b33e4ee27a52f0a659a823bcc628013361bf7ab67edc0a4bc20221962f264a0109425f25547d6b8ba9a29b1f2e958b40d0d24ab0061b212572ff2fdf4268f5380f90211a04468d59772b31ed47edab5a1978e753a562995b5b6e0d8e331213adb70534126a0479aedf007ca0055c38dbaeb8bae709053cd56a75e476dc235bd845bc4de1e1ca012bf1034b013754c93547a73297bf63f644d0b956dda3add244b30cd4db6c2eca0051d86682daa9729dac254a6ae7131befe80e0195bd41aac55b7b29a37e27384a041dc4cc0f1c3fedfa78e01f59847d8886987b283b8a93f426f7abafee6652af5a009cecf24cf8807310cf64244d74541bb032b9bcca23dad3e2917a99711aba69da0b4e6a3d54460ac2199bd297dde34ae748319914c27646d21ab013bab3c973cf9a0885436aaebd1c58d05e8d8e2944edfb260a8046c79a0d53b607704283d45b0aba099aa510d75157c04c2122e84756ddeb0b9dded2be610320eb12da9c3c5c379d9a09a81a6a3fd00dcfacdd88fd7c7644e16d85d70b8ae47125ccb0ebdc13b9120cea0ff9dda2e5f6eaff2005e2a0185b848f6e7c3ceeee6452771017eecde995f236ba08c011c9a9073a5f43c0f7bee922a6d84b4ac8eb9519549809aef288dcbaf858da0a9ef32f44367093f2333d7abe3cba0e2f71d7015a08c80823510839b6f8d92f4a012b8028b754de4f402f329bb30551282b60e3c68b6df6fb510a4a165c6643f68a0f2c261a4b79153246652df6290e83541ea7073521d4856a3fb5cd891de01b403a06f12422f817055760fed126f6a3e6248c32ce4dfec6bcb6c8b2029495a1fcfd980f90211a039a1af4570c801d62fdfe4674f02510e117eae6330facc959df997fa8e4d6c0da0969897f77040974812fdc243499998d5a2f808b010e3e743fff5bb1cf06701b7a072a62f95c81d3849bc02102bcb66b5be775ad3b68cae7967451e6a13c48b6c43a0cfc8c720a4884862f62b300dd876e77a1c703e6ae830af70ae71a6e519000e59a0b432a588f41a59491ec16126330cbe15a7e6aa261e05dda3d613dfee571cb9e0a010a5bc475676f1918918b0aac9ba7cdb4d2bd575963db26617e8245abce47cada0e62b04415ce8e7a5e17bddb2ab421a54c1095137c60127066ea495e56dcd26f6a010c1d3ed8e096233c3fa24d0e6604b2272497f25c388bf55cf1f2fbede09c424a020915f443baa11cfe88623086f95a4fec54633d2dd4788b4fe5aacb54e433be4a050782c9e3ad300153d05fe63cb83cefe69345d522fbf2e148430f665f90c74b2a02a1bdf5679c646407f898eecb449053dd3f1b5ad7d104dee3d8d01674bafa747a07e4527336a6fe45d71c98c0274515d11279e5d8c0d21bee7c63e5ee1f23426e1a045f3cafdbd08257bee895fc3f4cd8c7db2dc04a430b8e33bed28e2d117010837a0fb219648890e649741ec78e85f4550de81839cc5a4ece0b98f868ae5ad92458aa0b2d85e9be8807bae98dfe9520d739703aa23eab1fe6764196844d4afad2a819ba00c1369efa246a68459c9465394abf698221c2f6c62c2c159ab5e89e7c16d2bae80f90211a011ff0a2d404fd7ed97509ebaa806f2a5ba09c5cde5ff596903c4313783487509a014931c578b05f5948939281aa31d2bc8b05b01c6932c45bf7a70972a430575c2a0d85789a4b9f2eec599bde9e5e9946fe9f7a613de910aebbd1bb681d718d422c8a092b17ad714173ec4787f0b3b9d2dfa96680861e093b5121441ffcde64183d074a0de881616657bd4c300116254ef39e2622f52faebe1b06b4fc9d3daed9dc76c06a07ce695737ab0d4bf9003a06ce83b11e75d81fbeb47c013b41f9c2e00a97cb87aa0dfe63771f833e98a5aeff54d9dd5a8dcfd89ca43c23644b18ec8e29ab8ccc287a0a327c817dc8a8ea3a5d3ca3cb55169777a1bfa30fe9f0df842eb3978dbd6737ba053683114bdaed7819b30ab8baec1fb9a2a96fee4dabc72f319cec9869da3b0b0a04d98297a896312d18da40240ed9a527f4c01c73edd3ea1f7c28338d1d863d97ca070451b5f2a402b497659eb18e648ac46f39c0068cc91436eb0b082b1d06dd63da066e866f800200512b0d3e534c547f4d2012429152cc9693bf1553cc22361627ba003fc4e648aafdadd7a9fa7cb534103f08dc699413ecda22bda46898bfb792429a0b46a167c66b50c74227d03a68971e124fdd011d6c90f5a08f6fe30ae34de603ca0a7ced66271235bc27b154f37bee6d9a1366cd253176c96de707d124fcc593c35a0f4f09b104a86cefc5c282d393b415e6c224eb8a463386448ebebfad9f9f53c9680f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea05dd8c13b1b83485911f5e1185669f7d5559c260193a72e52597a3e80736c248ca03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a0ebb2cbf0c3314ddf681f21a29fa17b320094684ba35e725bc36bbc407821cfa3a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a046c10b0c15aa83973ea4b108f50bad2638941550fce7c9308c8b968abee271f8a08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a04539a99793f29484fdbd39b606f27265499acb3c24461f48858655f07166f0dfa05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a05c170d685d29417781f678b746174c7500e7c228b4bd71bcfe9f5421742a0b67a0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a0a10cfa51ae290afebd64a5b530db7088fa0b02f22ce9b0838135b422b885dee5808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a4435ebb5849518aff370ca25e19e1072cc1a9fabcaa7f3e2c0b4b16ad183c473bafe30a36e39fa4a143657e229cd23c77f8fbc8e4e4e241695dd3d248d1e51521eee6619142a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a44685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d3582a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0").to_vec(); + let height = 32158600; + let trusted_height = 32158599; + let c_epoch_height = 32158600; + let current_validator_hash = + hex!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); // empty validator set + let previous_validator_hash = + hex!("2d1eb63e4be97ec3506ac5a847e875523bc2caa3d96158d3ca15fd9c554c6a00"); let new_validators_hash = - hex!("bc4b672cd2acd42f2ef5116aeac330817278836eaa97b412d4ab5d07451f77c5"); - let previous_target_validator_hash = - hex!("d887eebd41d2e3e41fc584712ebcca8e7d0d506a7dbee98d385a5c4a612dec95"); + hex!("021b6af8efa138e87fa1819cf173d7e06fec46cfdf88cfe96b73ce0e514b89af"); do_test_success_update_client( header, height, trusted_height, c_epoch_height, - target_validator_hash, + current_validator_hash, new_validators_hash, - previous_target_validator_hash, + previous_validator_hash, ) } #[test] fn test_success_update_client_non_epoch() { - let header = hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e486561646572129a4c0a9d060a9a06f90317a0bc74f06e055575c6aa51276ac688158f453391d51a4f900a7151f9483395f0e8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da03c926fdd72ad181e335a4883b4f2244ef10315e3a5569436a6acd15490f01516a049f03b73d8f4e0733c41bfcf99fe433cfa5e5b67e0b02b31f652779eca94bbbaa09473fcca031aa648470dc44f16a59a4d50f648bdb98f35db982cf21483e5495cb9010030e106462864189c82400845c75a180205052f5081ac0d29485d890342700000868170104a90522102014567b402c184d9c2005a8443e01358de550341388204349f4048034427088919f1b90cc003302d11a23517406a0301ce0111c2001c00823881ae9a86043d00a901882167e92a5c009441086624020a425e175108f52000ea8082498be21386e9660180200a0c003ead2d92057c28353098cab08c52e00290f33c2ec858082114ec884b466580f0a001800e014025480b15a941702a83c0012d52451a0463404ac42e1216d0c2a692b28452880114419a404a8485a2a12012221021a1082101805466801583020c08acaa00b2605e8988313492330540028401e41d368408583b00837fda078465029e14b90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830dfbffb8608259664d4a0a018e958ca0f235f3e49794154c77ee5e6fd66ffb02bcdcc66e7bafd8b4b6149100e3d77eaf763bfea3400f52b2f72d98a7bd19f34b762e09ace9f8b2b902f1c5ed1d2925bb61ddc05fb23a47db645caaa3d4a3d3ce29678f6ccaf84c8401e41d34a0309809853d36cec54f42f167d95bd982bd38f4c1f6b4984680bc27e5d9899af58401e41d35a0bc74f06e055575c6aa51276ac688158f453391d51a4f900a7151f9483395f0e880cfc2b74404e3ba2f0fad16a53ea8c63db397fe55f9eb113a79e8badf6a0c03051647cd0c5cb37936c9e872b5f1db21ed8fc84aa0e4ff73405f48f29c319f99a100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080129e060a9b06f90318a0309809853d36cec54f42f167d95bd982bd38f4c1f6b4984680bc27e5d9899af5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e9ae3261a475a27bb1028f140bc2a7c843318afda06dad742e9085ccec81bcbe92465c93bac73489b1da0f4078454f9952d6c05377a09ec1fab3ddfd2a7e99a8606e6ec991ff8b4fe8a8d15761d2747e7544418e08cca037a054726017b693a96f671002a1e23b080b22dcf52112b800472665afd74af6b90100feffffdf3d3ef5ffbfff3f7efcf9fd3e76fbfffff7ff3b6ffbff27f7f9fe8f9dff9df5effaebc875ebd7fefbbf7f77f1fbbf5dffdfffaffedbff7ef2b77cf7bc5ffeef77596ffeff4df9dfefed3d6fffffdffd6fdffedaefefefddcbf87fdbafef7dbf7e7bfeddfff6ffffd5e54bff3bbbbebeffccfd7f7fbeafaffa5b7f7ff5bfbebdefbeffcf1fdfdff57ef7f77fcc573fefaffaf9bf1f3ff7f7ffa3fffdfecefe8d68fabfe7e76e3fb6f7cbdfbfdbe3bfa8afff7a7fff3ffd7a2feb7fcbdffee7dfd7d6bd7f57bff2e4fffffff8f37fffbffed53efc57b7f7fece37bffdff3efde3ff7ffeede71bffd3def7b69fe7f8f5ffec3bfeebd77e36bd9f9bfff71f028401e41d358408583b0084014aaf9e8465029e11b90118d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5830dfbffb860803f2744074e1c5f07c395c75c2f17ec22d261bbfee50893c250ab8b4176bf03fc8cf9a957fad7ba2b0a64ea259884d71867f9c32860a57588d6be8d30462d356e09a4a2a49dd7d84052e10b14ef001165e94bb536f04e86232eea17d6a4d3fef84c8401e41d33a06190c1a8814f51d33df9c15c26b786e0b03235ca6793a0d9b1c0be51a3086fad8401e41d34a0309809853d36cec54f42f167d95bd982bd38f4c1f6b4984680bc27e5d9899af580194a1dc402088c64c713010ce100cd83fc3914f721f359424d12ab11ac12037254b14f509d5e160a85a104c4ad4a80bf82d3ed4bee65c3988d7abde842d894ec00a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801a0510b5ba900f22951df90e92f90211a0d423a25aab1a08b71e0b11519ed1c69da68e28f8f633d8e021bfd6ee59b3c943a08bd0030b9217d45e5ce4bacebde68198ef525579c719b9ba1447d23db0f0b719a0852ac78ca45bcc3a5300789e6710caa609b084eca1fa2b5f95096e8643f165b1a04635964727b6fc4b75fb2a3ea0ca7d1821ae82e76555f22a9bf9d67874bc20bba03dfada3a1140f930d727259ed22531784d48015323ddf87ea42aacb2c1bcadfda008f14b1c8f00e804cc1e4a6e04a63bceae82f76039535b7a138970578c3e08d4a0f7f7076145fc2c17b6c868202b0bbff380bbf1f2770eb0bccccabd807dac6d8aa0c18bb82fffd7a49048c72260226e62dfd7c0f928db1ce4a26a174e0a862256f8a0f3a2654fee52facd5bc3aa61740359e78b00716fa3df65a634abc93885d617faa095bb1588b95761195a006f867508da3e3677d2c123e864a38aacd439a8aaf334a02cd2fa5b177a4878c72e88c2cd41d19254a05d907871d6118c09ee7f58860733a011c8d5d2b503b5b6c123add5b1bb203ffbbfb1a051dbbbb0ca934ace0c02dbf4a05fc906409e16f0721f8e54f671cbf8a58078ab6467b01b15c98b9b9e371c4956a0e723f5494c4e6d8e2094017b0d5f54b28db10547c0c892c7eed75e6e45512071a0f387ef6334443134b33d070049cd1acc984fba4960d8a80d25a6ed5089f0c8eda00b45667472ce46218e05a0e86c96aaeb5eccd42d561876402c69061ea0a2c1da80f90211a0d68e6729df9a4e44a45824d6ece9ad36c0a8f6ca8affb4832531c8d49d4ddaa8a0626b2a3b353dff2448662d9a0af800aa3fdc78ed17de18cdc2b07a4e586aa5eca048072c3d3e88d61d01976ed56bc5bb7d9f21ad54ba991db7225a541d5e3a010aa0fc08d7257b28c2b3ab5daeb3944660b1b33c9d2a2ac0dc6818fb6e4a3262c624a05c358df8205b5db4dfea7267a74d227b8f34d834dcb1f119e730a02b89d69872a00f4f3946613e74c0939e3253340ed7569d360a97e03ae66183f75177ee464564a011e5f4a02c91cd924e04fa772f824f4e603b1dede5cfd865113fa9155dbbb5b9a07880569cd326c59c1fc8dabf3e439509e3a47fef1761a878151ad4ffcaa9577ca018642e125e0c2a24efc26de54e9979629300d647b81e0399a69742a0d702b247a011adc6a19cac1c573a98108a5fd89e8d11198a996a2bd155262ab43a62eeeef2a093b5155e733a91584bbc748976b089120a6f4e58e5138cb7801c52315ed33fb2a0cd1ea71123bcf854db8015eacbf27326b3d6915e94083e9d460a1c4ce720dabba0f5d325f472868c369e54e7bf2026fd65a1637c849464a1d15bb2d0bb80a6318ca0fc7dc19e369470e138e74e00e00cc6102b799d0379217c41b4d79edf35b3d80ba0c333398436d11c6a6a556df2661aa1464150c165be4ca48e029f5164f31a72d7a0d74b9ef942e3c16925e43c5347d0e906810dcfe7098e52c1b7e669ad5e978f4180f90211a09b3b89fde8d6a61b0bcab14f5104d1181bf51ceda57d8d0080826395f667a6c9a052e6f63aff710f9b54d0f30c24a0394da114c908d909454d1c65dfd592102c44a01d3a8ffc786f9aab3d40d737d81ae78172ca09c022766d13f9d209d271ec7d49a0c668ae01356239e4f48b80f2eef50dfbbb66385c883cd39eeb42ea5c9d96dc5da00107d54b56de7f5c7a24acee36853ba36b38486cd4df47b2b1fe039dc5c85c20a0a4aeef0afaa8405e5492cfb08880a2e099c8df0004f519c3a5c2339f37a5f66aa0b10879d60feec4bc3682056aee586923cea1d6be4d8e1cc73afafb1c983ff096a00cd9429510135ac77aaee9b8348913e62045b682bd1bc3c610885932f65f02b8a042315c24ca71653fb6dad6d68ef01aa154fc42b0365755d6d5e7b81d6e63bf1ea049bef02aff3dec411c5d01dc476d6e10ddc6696bb47b3cc91fbc5328c1ade493a0afe8d3d6268d738291751e9f2da6f6d4360fc427d3b6b8c7dbe956fa704072c0a00bdd6726a109aa17e2543e49554bedcc9e4460db8b4ca743fc805a7b62317759a0a24a3e38af0f9caa6505434426dc847789c1f21ea920cb801705241eeba8c00ca038c3e7024043ee8528ba003b1a86afb1437758e57311e9bb9ddde9f38108ff28a0cde64662262fbe39cadb1430625c0b634143c2ff701816316e40785680c37375a0a4349d2403cbb54221ff6acea9e6227c08887f1470688cf96753d9003eb53beb80f90211a0b5f7db8bf20813c92e223f121f4635beb1192309da0556ed80e5f88a543c445fa0e20a4b8912ee792417ec7d03ba3496b81c50600ab20cbe96766647cb01ddf314a07f11c590a0283af81d54659084c94c5de50154f109fccf259a08af0f9a3f4cc2a099be5cb0942e7216e6d6f38203bfd3440dee2f4c20c65b86fe804fa63609e62ca0ddeacc442d98146bdf1ab21eb9f2616e310baf330675ddf54048f3cc0372860ba06be3b370cf897a6d41fc3c140d3f8c8a9a63c9f437f297473641066af3a095c5a0508b4e32597bd3de6f682d9bcd31785585ab2c2880d6532f7eef87872473aa73a027b3ee9a3baa394e446e437f74054517ff84258ea9d7acfe790aeb5ecf585ccaa046cc03d1ee2ee491891f43dfed7c90e6250d53b012853d095c630c46221206d8a0f2b0c3c39d22ca62e0ddc30121e4616db7a4b50504486d6b3c5327853576df0ca0e39d05da42fdbe1648cd4f80e59a1d391dade7c6f0636ce8b3221037c7eac578a06a3d2c5ea2f9b02452ce153cb10cb8c1ad1c16fbbf2b77eb89f022fe8f850746a03b2e472720e11235bc3ed475f96bdcb82eb7b2b90ae4c44d72568c6b66761397a003396a318468f7db7183cb71c04193c6e70b990d15d7560a6748e2b2e755152fa0f3ad9eaad7a6351c85aa13de3314018c2dfb82c12dfd5613468217f0bbe68747a0831fd06a3d63affbdefa75fc6a542596f5e72a2d3267d0667b0d0a4eed72c4b180f90211a0e484c57f98d9dcb3981e79fec1fcdd4e9ade6b50a8763821faa52d6e9c40e515a09784bb9273fa7f29beefb8fe8c68dd148c164549aa1551cb8c69a4701af3d94ea064ddce91ada26c9916cd903f21c5b6008bf2a865ef9d3fc24bcd423bd02d9a93a0b4a7c85096f6d7016f1834bc01e1ed6c4314ebfbde73f80bce360a2f03e3cedfa053ecf424b86f3d97a054b057590cecb1e5e2878fb83d86cb7730b3dbecc4fd46a02d2bdccfe1586cd1692479a75d2b97a4d135e3dbab564ed3b6855113c62af598a07ab54330ecf7eb9e02720897d0380dc07eb2665892627451d174d1d87fdc2067a0d3d35f8b3ffa8c8c98cb34e89432b6157a148c4da14f868f97c9404d985850e0a07506b051d3f02f382730e2012e93b65addfccc9c962afbbbcdbd141b66c495daa0718f9d6c2bbf55d70c80a5decc2f49ed78026afc27de294dd28167f0e41786dfa072ae72e1a94cba48ff51cfc05f405af5931cebd85881e7767b4ea1884b87e4dea089d6433224364f6d40dd7d438ec7d1c924d70209ac8dbda89ccf5a39d1f031b3a0fe834ecb338a4b03a894fb36f2d0442ea48e6d0fccac2a45f0ea2e6abef6487fa0ce3c2a783bf9aff7764d32910d594a110f549367ee6b94d157ef949a2c33e65ca0f9f8490546b48f4dd548bef52d9fe8aa827d214940ce1842d139a94f341b611fa0d4b4fc09aaa8c6317c2060ef5ebaadc9bc211742296c8a80511b7ee0cd03417280f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea0c6c70650f6edd7057de9a8d7aeb5a52bc40dffb8a9cb71d55990a628f1596402a03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a09592d731bffb4d9b9ed4cf697f24f55ca7075c66a021aaa9f0ce119bea344411a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a0fa59d52ce31992709b7380abb4db6a33327763297b3c94791f348d886c7125faa08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a0253e402e9d5665c986423a2518d345b0c4d184d36562df4736dc28c3a51b60e2a05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a0dc34a817b1795244d58bb1b03cb361fbc68a3bb4a66ba3d891bfc0490d59115ca0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a08c81335ba79260e105491d1226e33dec334014016614983701be7b7fb10af9b7808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a2a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb2a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2a44ef0274e31810c9df02f98fafde0f841f4e66a1cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e32442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9132442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab032443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a324461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d2532447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e32448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193244ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3244d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3244ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e3a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e913a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d253a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba73a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a513a44733fda7714a05960b7536330be4dbb135bef0ed6b0245c33bc556cfeb013cd3643b30dbdef6df61a0be3ba00cae104b3c587083852e28f8911689c7033f7021a8a1774c93a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e3a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393a44d93dbfb27e027f5e9e6da52b9e1c413ce35adc110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3a44ef0274e31810c9df02f98fafde0f841f4e66a1cd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").to_vec(); - let height = 31726902; - let trusted_height = 31726901; - let c_epoch_height = 31726800; - let target_validator_hash = - hex!("bc4b672cd2acd42f2ef5116aeac330817278836eaa97b412d4ab5d07451f77c5"); + let header = hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212fc460a9e060a9b06f90318a01b23c31eeedfa83a89820adac7e9e44a14e0c0c751afe93e5f100df8210e196fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a6f79b60359f141df90a0c745125b131caaffd12a041744851824956cd85c2417a76abed38698c290a94d10d0057e57819c8d57e35a079292be9b41a964b7fb37ac111b83003f3e596d81d423f77aaf5989ccf7fec8da063e850cdf24a6d3317a09e8ce1a772e92a8b1c0e5a7d7c898cedde68c9a95654b901000ca802202280d0da2215407692423c0381cc406080011d488851918611880024de23541472d4800c2023b4d1849a08a38808320a0d02500853a0843020a4a200645228200360062629a338e901246828ad94c71205d6a88eb2161030d241850e80fe81250a4a350005720330a3134da84890a808401e0c210220d218c2204474cc5dd2c0801951db14d83780132a4c0c1026a4a1b800810a20529c4043132522129080183683ca600730514e67c2028916e010080002808c14cb00241c978bc0804d5536d00f0883b03008aa00c05922725a22d49b038e940530c8463524e62618b0a801c8ac28014d1512404103212303c80b9c44a8904c9806a2887eb99003028401eab42784084792e5840195f8758465167163b90118d88301020b846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831deffbb8609947c36e375df2a2b8239997d367ea062673d4b72904ef9b8866589fe777421599b7a88c979a7e4a370f5c11de75dba403d6aefb5868bbef4a18a51efd65305b7dbad97575ac7416f44ccd31d4f41e480ea1b8abea01f25438a4cc35a09c753bf84c8401eab425a02ca6c6ac4e1ff837bf6b9808e126e41e89439de9072a21b7039e2fbd7f1c966f8401eab426a01b23c31eeedfa83a89820adac7e9e44a14e0c0c751afe93e5f100df8210e196f8002088a6d2b88f7e6b585e8cd6b90c342f2e58fd80149f41326d5a637852b3845008fed2da093ba39d289f986102e04b59a2a7148fb6b6a0c62f0c9789b9ccb3c01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a02a916f5aab318f567ee7fda1009c7aa5312bef11d23fe8646ecc78766b8b0b5ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b218c5d6af1f979ac42bc68d98a5a0d796c6ab01a08fde75a051b074f1ce7a9226bab28362747a25b91ec651fd829ceab19be73247a0873e62913ae9f9aa9b404445e6b3cc530a64f803ede4110c9978e77f8e78b97aa0fa4544c552c65918ceba62c550fad4981bb402e7c0da236b3edef9f10cfcd021b901000e3f330001899010280c40e2b1900943b14023826dcc4c83080c11289262032286e2305048a1920c4e21142a9016008089cac59c266a43255108263402ac0c084c6ccde209646821c910a639852b137c2010a32c03d4c90a2616d481e0c0f4184278a6afee0a2204450d80e144808f009a4449714408ae2d0625ce190a180202048eb1c4031340a18299b41954280a29a82d14a5a5c35548615007c112c256a18a99c008d2868460080e014c9a28042eda0a23868ac828a5125014a2fc02295650057586600044ce208a00d70b02d92820e0530618b180bd2112445aa2e0ecac1250a18933fee1404910028341f081c2f146149a92704e4854b6956869416e42028401eab42884083f4b5483cf8c468465167166b90118d88301020b846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831deffbb8608d00bd949077f94e55ddc04e135a952306bf070b9a852d744be47ef0ff3a558a60f51b063193c364cee4456d8f7926d7130c5ee32b451cfe15503b7efcf08c4bcd82b9ca278a1b52aa06abf5736fddb3672af7c670f25fa1d9b2a79b2db89ff7f84c8401eab426a01b23c31eeedfa83a89820adac7e9e44a14e0c0c751afe93e5f100df8210e196f8401eab427a02a916f5aab318f567ee7fda1009c7aa5312bef11d23fe8646ecc78766b8b0b5b8084bc5ec280a6cdd219fdde1daa795288072721705cad76de4e53b97320403aaa125e2a3d9c95cd436700f4aeee2a6e2154b8cb68d882fcb6665697940e90753200a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a08c9420326eb0962b2eec56000e1df27a7aadf8e3e46a3fd9b13dc53c514d20cba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b4dd66d7c2c7e57f628210187192fb89d4b99dd4a07d6820009373a8390789c7a2b4c3fbf67355c1f0d0d2859179c26e5fe99021c0a0857f9c4317bce24213fbe2cee7d8cf2f35731385c07c2eba1b00f3ce74b6fc19a06c32fe236c912eeaafa8848ba9337a2b52a01d457bbdf3bc9af6d00edf70819bb9010080a1120c8029340008040444a081302a00064b80030808848212410010300594808090a544a0800141006200011804408041041c0183420000200030002020c00860e1000b0140140120011d0234403c70b4234101d400420204011080005000402c84234a1600404001a48021004b2008004048004406b8035001184000070298caa18403120802a0d4040000280cb8002604a1284005090012044c0010002002120008522083c0240804940e0000081488a080008a0a041200802000470140a4009c2a4040088c189000c2080251a0a651102810002a142113505a0028b40418988002007c4132810100c202400b0041000010803040721921a41582090041028401eab4298408478a9e835558538465167169b90118d98301020b846765746889676f312e31392e3132856c696e75780000b19df4a2f8b5831deffbb860b11927c0cd1cac187568b32642e4b4f90079bef647479cefac56581efc8202d515e04470155b3f3255a28418d7cfb3701390a24a622e4b6f6272693535240f47172d79595445418823d5c1af41deed8b387253adc55313c333edd35fcab86e11f84c8401eab427a02a916f5aab318f567ee7fda1009c7aa5312bef11d23fe8646ecc78766b8b0b5b8401eab428a08c9420326eb0962b2eec56000e1df27a7aadf8e3e46a3fd9b13dc53c514d20cb803d62b53e64e732d4cab7a8ec4a30973ce04c5bc456eb4e1ec806aa2b9da8fc0e39815e08d8bbca49b8a22daa0bb80ad9e5248e617c934e78baf57f530ed17f4700a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080120510a6e8aa0f1a951df90e92f90211a023dfd4833a9193c9a819cda95efe94937871979a593809f72a5f28615f3f8d60a07df6ac535a9648643b5f3604a6c7b92088e4914d541ee2d1cf81aa65e03b2075a031522228c8ac2cddbde6ea43e189d20222db901713453ff686c80778a719bfe6a027e715d0963a880b7c44e8940c2297f60f256a6eec89242a29a02b9bf8fd877aa08d322186c9b8f92d8577f14795b720eb052c9676d825fa804163bcfe999fb2c8a0cc71661aae5aa61460093369c433d6944013d1062b327a97e9943b01722e4fc8a05f931adbd5832d2753bb1c96ddb384d1f8ee63ba112576d9d2d4f7c8ea872162a0897e5d2e08db176ad0eace9ec3ef4a373c6df47442277e7d75f78addb565ea61a0b79dc87f7dafc7a5b630f20a38d541ace165afa72dce69fb5b17d08e5c1fda62a0c859c89663f3e553ca1e7297bbf9e3a8ae2f1da73a7f03e953b7cd34a93f6e85a02874e6004ad9e84f1f912e4c8a16b53035cb419a8096c06ece728e9e44700738a00662070a4492fe57b6bce97c6d8b50f72e707da7ae90c86294e7d51f7e609e98a0e9e3ae86587f26e027ede61ab77b57a760c225da8b408625d028e1f8fd3a189ca0cfb360c49cf73c10c0f672f584dc255f86ff4ac6ac2d586739591f75598b3934a0d25ff9f10d08d6ec9f66edf4da75ae1e80186ff8b35ec84b349d2ed6a4d95ffea00749ab3f319d13e6c67837f0000afadf8c32e49afb9dd50164ec23cfd6c55e8c80f90211a042363cfe8be5347b81e81827f289950d57637b4709fd1e7655ad7ff4e96a7aa6a057f0ce60ab640f46f925863a4b4bd9b8ed2c5ef20e09d37c571c0d538cee63cba0435ad1a6654337c2957288d14778cc12d2d186cb82949d8e5f81716acc760b3aa0cddd58818dfe7667fdea436f1eca5442c3f186d13d003ec202fa4a510a9bdfe2a03f3f41bf528ccb0de98a973b66d2012aefc393ae8816d03f14ccb19df24cdadca0f2520c12779bc6c12b0aa5ce601bb37e61299b11af33163ba63dd1fb6ee3b858a0afccc83f6cd242c571351bed61d4349a97bcca2d71a527fd67cdb60eabd5ec41a05a877b70dadb245c2170f7a54befae953686bd31206cb5f50920ddbc01238c18a041b33ffdda7d4a4fe3953b1c01466647070db96a53af5f7868fe587f4f9eb9c5a0d5e8a0df8d5dd49d25035bebae9a44b405a9deb49650cee82b2c658011e87111a095998c2e7196c83e79b1f4d0f2e93501a08b0ea9ca1ab2665a7e24a7119dfc90a0cf0ae3c8750bf08ee44a42cf6fb026a6a5c672a6861c94d8af29b6ef12f7d418a07a7e8f2e8d1250d4aa810204ee2630240500139b3ea931354dbcaa66b888a7b0a0e14f6d6af0624c4fdbbad43d9b8aa65d4d946c268c9cb44f239fd86e12e90db4a0673b6833f3765114131b8f24f763a8245a99750daf44bc6b55258e1abc5b8d49a01d8497cb9fdac2cbccc85ffb03798d8d5a681c3bb6f473a97d4edb39a6dff02e80f90211a0f896dd0a7a1c8218701f4c361a84fd6a07f4880118f4c63b4e2014dd9c9e1496a05889af7518058d3f8f1df7be08264cd6f53c67d5e6f5e3ce6e2a2962b6e03dafa046cc6d5154e933981ace44223d1200c3be8ed550d629eeb351518f9b066eb8bba083b07d2e20449a5605d58d88ad161d46153be60a52ce1353688cd2b877f983a9a005c9e5469c5bf48e6c3a2c6b8f339bbe21c51b69f62b2e3d2bb67047ecb3b0a4a050037c4ac608580def78d36b13e56c7986f55789447ca3d6a0ba642bc3bb0c1ba0c7f8aa54645d635d425af7ec5c5412857d3b0c7901375c9b3dd0641c43b466bba019be24ad8bd97f262f89d8b58fa785a153c042524e2d239c9a1a4042b4f5b18da02dafd65fd4a20798890f950321b6ea13a9231ab49bb0990ecea41c205467d12ea054d758f3bc0fc530c4bc2dd9f5dca198aca9121c9063b6e1645fabce15807e2ba08e3fa9bea88e7e38390db8d0be4a312678d427f979ee6a2bd8fb20bea5b20f30a01e5a974cc84117659f28a7b550ba0a00e3f30aa45789426856a1df168b945174a0c6e07bee12f76a23914e5514d6cf11447aeafc93169c705567a3d62b80f09f28a0d883732a9e24b91ef30c4a066e31799d010d818d0c657af2e1b875c4aed8f6a1a0801a3f68a67e16e18cdef3932f09dfecd74b31d71a8074885f65cd72174f4dfea0a74976f3c1568094513dc978e2a75f7aa05b4ca23271f312c6ff8d6b9e16fd0580f90211a039a1af4570c801d62fdfe4674f02510e117eae6330facc959df997fa8e4d6c0da0969897f77040974812fdc243499998d5a2f808b010e3e743fff5bb1cf06701b7a072a62f95c81d3849bc02102bcb66b5be775ad3b68cae7967451e6a13c48b6c43a04a35f1ecab27a8a53e0ec424e0add8045b2c25a4efe354d33fb75246f333eef3a0b432a588f41a59491ec16126330cbe15a7e6aa261e05dda3d613dfee571cb9e0a03e55e7223adcd5dc7ba7a187a0443ce8110cb34ef616883fc3a33cf2cd06947ea0e62b04415ce8e7a5e17bddb2ab421a54c1095137c60127066ea495e56dcd26f6a010c1d3ed8e096233c3fa24d0e6604b2272497f25c388bf55cf1f2fbede09c424a020915f443baa11cfe88623086f95a4fec54633d2dd4788b4fe5aacb54e433be4a0d604d6e74ad8121336fa09e9672eee5239e757e03a0a7e006596479497832c0ba02a1bdf5679c646407f898eecb449053dd3f1b5ad7d104dee3d8d01674bafa747a07e4527336a6fe45d71c98c0274515d11279e5d8c0d21bee7c63e5ee1f23426e1a045f3cafdbd08257bee895fc3f4cd8c7db2dc04a430b8e33bed28e2d117010837a0fb219648890e649741ec78e85f4550de81839cc5a4ece0b98f868ae5ad92458aa0b2d85e9be8807bae98dfe9520d739703aa23eab1fe6764196844d4afad2a819ba00c1369efa246a68459c9465394abf698221c2f6c62c2c159ab5e89e7c16d2bae80f90211a011ff0a2d404fd7ed97509ebaa806f2a5ba09c5cde5ff596903c4313783487509a014931c578b05f5948939281aa31d2bc8b05b01c6932c45bf7a70972a430575c2a0d85789a4b9f2eec599bde9e5e9946fe9f7a613de910aebbd1bb681d718d422c8a092b17ad714173ec4787f0b3b9d2dfa96680861e093b5121441ffcde64183d074a0de881616657bd4c300116254ef39e2622f52faebe1b06b4fc9d3daed9dc76c06a07ce695737ab0d4bf9003a06ce83b11e75d81fbeb47c013b41f9c2e00a97cb87aa0dfe63771f833e98a5aeff54d9dd5a8dcfd89ca43c23644b18ec8e29ab8ccc287a0a327c817dc8a8ea3a5d3ca3cb55169777a1bfa30fe9f0df842eb3978dbd6737ba053683114bdaed7819b30ab8baec1fb9a2a96fee4dabc72f319cec9869da3b0b0a04d98297a896312d18da40240ed9a527f4c01c73edd3ea1f7c28338d1d863d97ca070451b5f2a402b497659eb18e648ac46f39c0068cc91436eb0b082b1d06dd63da066e866f800200512b0d3e534c547f4d2012429152cc9693bf1553cc22361627ba003fc4e648aafdadd7a9fa7cb534103f08dc699413ecda22bda46898bfb792429a0b46a167c66b50c74227d03a68971e124fdd011d6c90f5a08f6fe30ae34de603ca0a7ced66271235bc27b154f37bee6d9a1366cd253176c96de707d124fcc593c35a0f4f09b104a86cefc5c282d393b415e6c224eb8a463386448ebebfad9f9f53c9680f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea05dd8c13b1b83485911f5e1185669f7d5559c260193a72e52597a3e80736c248ca03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a0ebb2cbf0c3314ddf681f21a29fa17b320094684ba35e725bc36bbc407821cfa3a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a046c10b0c15aa83973ea4b108f50bad2638941550fce7c9308c8b968abee271f8a08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a04539a99793f29484fdbd39b606f27265499acb3c24461f48858655f07166f0dfa05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a05c170d685d29417781f678b746174c7500e7c228b4bd71bcfe9f5421742a0b67a0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a0a10cfa51ae290afebd64a5b530db7088fa0b02f22ce9b0838135b422b885dee5808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47022440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9122442a7cdd959bfe8d9487b2a43b33565295a698f7e200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab022443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a224470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba7224472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a5122447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e22448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d7886948522449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2244ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd02a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a4435ebb5849518aff370ca25e19e1072cc1a9fabcaa7f3e2c0b4b16ad183c473bafe30a36e39fa4a143657e229cd23c77f8fbc8e4e4e241695dd3d248d1e51521eee6619142a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a44685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d3582a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0").to_vec(); + let height = 32158759; + let trusted_height = 32158758; + let c_epoch_height = 32158600; + let current_validator_hash = + hex!("021b6af8efa138e87fa1819cf173d7e06fec46cfdf88cfe96b73ce0e514b89af"); + let previous_validator_hash = + hex!("2d1eb63e4be97ec3506ac5a847e875523bc2caa3d96158d3ca15fd9c554c6a00"); let new_validators_hash = keccak_256_vec(&[]); - let previous_target_validator_hash = - hex!("d887eebd41d2e3e41fc584712ebcca8e7d0d506a7dbee98d385a5c4a612dec95"); do_test_success_update_client( header, height, trusted_height, c_epoch_height, - target_validator_hash, + current_validator_hash, new_validators_hash, - previous_target_validator_hash, + previous_validator_hash, ) } @@ -546,9 +489,9 @@ mod test { height: u64, trusted_height: u64, c_epoch_height: u64, - target_validator_hash: Hash, + current_validator_hash: Hash, new_validators_hash: Hash, - previous_target_validator_hash: Hash, + previous_validator_hash: Hash, ) { let any: Any = header.try_into().unwrap(); let header = Header::try_from(any.clone()).unwrap(); @@ -559,11 +502,11 @@ mod test { let trusted_cs = ConsensusState::default(); mock_consensus_state.insert(Height::new(0, trusted_height), trusted_cs.clone()); let epoch_cs = ConsensusState { - validators_hash: target_validator_hash, + validators_hash: current_validator_hash, ..Default::default() }; let previous_epoch_cs = ConsensusState { - validators_hash: previous_target_validator_hash, + validators_hash: previous_validator_hash, ..Default::default() }; mock_consensus_state.insert(Height::new(0, c_epoch_height), epoch_cs); @@ -627,43 +570,42 @@ mod test { #[test] fn test_error_update_client() { - let header= hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e486561646572129b4c0a9e060a9b06f90318a0738c3b15c46449e50055cc12ca8fb48ccf4698c8a089a6ef0c1bd0ae7d10489ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942465176c461afb316ebc773c61faee85a6515daaa00000000000000000000000000000000000000000000000000000000000000000a062fa1692d9fc0d23e38638859d27cef294c78fb39c00fd57619542c2a3dfa5f2a0a116fd0f85c998474f1c62b2191d6ef685016811c70d1ef4b926affff4f2573fb90100a07902400468345a01402ce7946868731441e000110cc2012402452314c20a96c380b5e64880430e0ea13628025b1a828180800b1492d10250821c50313520010654b4a20145c41c031bc1a9c86e0a2821f2bc3045679112804e0154941028820fce0c660b8ed5010c1f08984504ac0a0809aa23088b5c4118006352820612b3cb08680c4355e0e590801c4466000108446e04a36800080c241180c1ec02507002a7e2507213c72217cd170c8a80885832a84d00064220950c08c724e264288fb801d76602430b4710f3802c62bcd120e076005e20883094c716d4021a00e52810b0e00600c8d1514319484045004b102c8400e801786068044018001a294008028401e41df784085832a78401bc82aa846502a057b90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830befffb8608aed397cd37a28316d8b19c4b90eb197d992b1f4206056f427b6c1b26c1f8455776a1c619e78e30be6306d6ad10fa1490e3057f577cd741d3a4669774c62941df36092d286d46f4fa5f68f4990a117d21c211d1b825a71cf1dd386f390541e9af84c8401e41df5a0471dc653150390e3f5db9398f21e134638cbdd128a9db6b60d7485626203332a8401e41df6a0738c3b15c46449e50055cc12ca8fb48ccf4698c8a089a6ef0c1bd0ae7d10489e809233fb9c5bb9533b5aab605edeac068fdc2ff8a6ba8785856b647261a50fb30305dd57572f0aac111503a195b206510931e5a2a67bfafab0f9704b629fdf74e001a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080129e060a9b06f90318a0471dc653150390e3f5db9398f21e134638cbdd128a9db6b60d7485626203332aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940bac492386862ad3df4b666bc096b0505bb694daa05fe41572ba2417ebe58176d4b7b243b284672a58bb5207e1b8f5b14620a332bfa0b8182e3f274f4f8defefced4c88c738a4d4c5e40086102baa01688bd03466660a0cc82530e798ec49e7d9165f18128c23b13d5852cd4e626dce261858cf78380e4b90100d63e674484b959f0f5380877d4d0125b19772413590c02a41252432a58425f2a826613772c80510acb2633b00607089bcda4884c802d744dd40ab123902518e42422042401444502d538108ab2d61af235b89ba0004409861c061c1199282e21024c51328b8bc488065bfd2e23d22e280e1ddfd3892bd4039c619230ee4604951e6e6902ff19d8e91a8caf045041a1ce54bc44ad7324c8083db13b4160e89078d2caa3541a4e1b702bd95145ae9f2d4634a688a1084a196577e2b076710628ea32614662180db366827025bd6c0a15c4acd3a737094d80569bdafaea13a8fc37c0f96083018bfbbec9434aca6d1f2910692b4438782a534a0903e7908a711609028401e41df684084fe2c68401f29ebb846502a054b90118d88301020b846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5830befffb8608985a1eabb659267e7fe8cf98081c8c82c5fae68b529af5c0ca25459b67a170cdb50a151a5df0f9cfe035317399ca81b195ce6f09f8872329017f8c5ea3f210e7a3b55721c09f96b0f32e557930dee9e4d2c314bc78138b2a2e162fd24a6ebdef84c8401e41df4a010cae8797d8991d2e6aa9c2fd247d845ccf53668d286410f0c833f9a3d9ce1b78401e41df5a0471dc653150390e3f5db9398f21e134638cbdd128a9db6b60d7485626203332a80075c3995616702ecc50fb7eac09758b9d5e3427ce97f51ccc7a60104fe8f38cd301f8fcdf58a81bb209c5b24e9dbd61b87d1aaa4a3f8d06923b493af83ac64e000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801a0510f6bb900f22951df90e92f90211a0bdb0a54e8bb5772dc000d4c03bcf4c9e76e6293448091c7647923781082ae78da01e557709607959c5cdc221142de659792fcae36b4abfbadbe651bb2ef138b529a010b878ec62bdea5486d490522a4d3267270bd50127e5941f37b6286c9ce374a7a0f2f609ce1e8e4da9a65e6b4e0127e89704c9bf6e86b9ce75b2bd693c10c7308fa07d1d8dbd80fdf1761bab267c76c8e71060baa474ba393cd9b3d4ea2bed75e108a0c49943212fbf768ff07f520003d8d23396d2fee0967f843efe106b242f1afceea020440283f6fcc813c4f9fff4b6bb525a980ec4e653cc842bd31c70241b83608da0fca56c85092c39da35ed83f3219e2219d6380e6ceedd9510677599884929aff7a04918bc3560be072b5af3ab98fcf764a815b1341ed89acbf5c1fa1a4e6b2f962ea01e08affe2594951916b51f1fe153df44bde6ca9823d3094e423fec4df5f018bfa08759e3842184046c1d4dfc747c906329b752abf77bfb8f7c2fc924bd415269d0a07b7402d322aab1788482827c41c9df57483b46ab2d8acec500755495beb74edda0b02e3935322dcb0287b149df2151b369c2a9e07838795a59d634f3e2856b4d6ba0efd14bc76baa12b6d6d16cc6c604e65f4b1580b243e0281b0c8583bcfbeb943aa01e378537cbb67f57adcbc77b9d540072411a9afdf9de09955c7f212a276751afa074626da7455fd9b381b56dc599831c5cc2bf0a30f0262733a60a4234dad695f980f90211a0c397cd87f943a623aa754a19d0907844bf7a563df6d00e94a30762978573399da068fcb3b6b611a85181324dda7cb34279d12749da8e9475f1bcb4347c2b9e86dea01e9444f24c29a8cf3d1cf78978042cd3a70d7478dbafb8bd7baa22839f127e6ea0c47e357dd49b9bfba4a6636d833dcc0f8b64fa5f80f2596b21504dcad867ab05a0a1661d116dd78b5ac78cfc46b56e0a2f7fe69bbba1fdc2a1e74cc45aa29d6ea0a0b2b39944890ec7991c7ea163ededd4fdc29e7aee1848d75c459b29e1538a7371a0238d9352225eb5aba7e9f00c72f3cfbf5f0154a7bea042bd2b9a0e82b6b99886a063fdae2f1cab14d78331c1e258b39941a3ff20068b5951b3f0a385fd6a800fd4a0497cff8439384cd1140d7efeb476228402387b59ae96f96467b7ffef5305a4eea02f7192bcd5828646621452225b31335983bfe5f615f45fa5c0452af5eedb42a2a0001060c7c4904767462380175342d668c7a56b854156ea215b6be594df028f06a01449e2278a7f831efc678d00a5d934206334e7046ccfbd017e71f2a500d1a9f9a09587780949dbdb0a21f14ac8c06832622ec70ebbe3549cbbd7ee8998e201fc65a05282e73bc9180734730a005c63fa464d25346c7b36c1137b28dc181d1a40ddb8a0f0770dd282e620fd15076711571a3d9e219fb4eff80429b075fa616b691aa59ba0058dca12dd5892e4ecc47f5e9601e3e63f6a67a2497608b3f019ca0fe9a4e76780f90211a001f1f70c9a8c3abbcb949ccd0240364ddae1a99ba296ace7bcb967ec18a21682a0b3a2b4fb5fd0799df2a36c783e7f972ebceb8eb6316433f5de2e095f5d94ecf2a0e0d4c8a883f58b6d060a25648c417634afa2b41c8585def72713e755801fc303a03cb1c57cd2f580c7c8174a9979105e6493fe33b7e6b4a9bd6a8d8812fc97909da05fa51840dfec0f72a8ed36c759ea5fe30cd6e4a8f08ce8d8085d737634fd24dda0360e0b786074c0b349cab6bc311780ec8b9157432f4aacd0998f919171c86c01a0300f91e512772bacf0fd139b78a8dea1997b714ef68d61dab9621b2d20ea9733a0a3dfc63adc44cb276e53e4a0a374eb6616cbc8e36c2efdf2234dff561e7bdb83a05ca4e4d2c66266b915e9f88d1851f0f73cd37b46eeea94fb01e82e95170920dfa09f6ab65f14743ca58c8b1f729677e00df826064a2708616fb5f98508357224c5a0d57ac45f24f517a3ed392940e225320110d815393d38dd0e559aced85533e414a02735ee135ed3c088a1a76fe2d276ddd5a7bb6d68bc7408447045085b186162c7a06fdedc79348485e21a939b50dac883a5489ab4d710178bee044d24c6284bc720a07e4039522e1ade37889500db8841e57679ed73d9e2adceca456254bf6a37d8f7a06382234aa2afa276b572846679c154047ee63713b74ba1c564e88b68d5109faea0dde50935c548be661110dec2e5d76be3d64a1a24889a578c6ab9406419d9c5f680f90211a0d5645bc2e0e0e7cdf3ab09356055ad366bc7fe03cafc9d7e4fa60ddcb7c04b68a0e20a4b8912ee792417ec7d03ba3496b81c50600ab20cbe96766647cb01ddf314a07f11c590a0283af81d54659084c94c5de50154f109fccf259a08af0f9a3f4cc2a0418795313c377ac6fe910624a80c97c2c7e00ee09660fc2f0a97782af9856ff9a0ddeacc442d98146bdf1ab21eb9f2616e310baf330675ddf54048f3cc0372860ba0a163a6a17cf034e93df3584622285a8443b725daa61d769cc35b77d7d73a98c4a0508b4e32597bd3de6f682d9bcd31785585ab2c2880d6532f7eef87872473aa73a027b3ee9a3baa394e446e437f74054517ff84258ea9d7acfe790aeb5ecf585ccaa046cc03d1ee2ee491891f43dfed7c90e6250d53b012853d095c630c46221206d8a0f2b0c3c39d22ca62e0ddc30121e4616db7a4b50504486d6b3c5327853576df0ca0d1ce975b4bb2337a8a1c82c5ddadc150bb6ccba7006d6641cf662865245e35e7a06a3d2c5ea2f9b02452ce153cb10cb8c1ad1c16fbbf2b77eb89f022fe8f850746a03b2e472720e11235bc3ed475f96bdcb82eb7b2b90ae4c44d72568c6b66761397a003396a318468f7db7183cb71c04193c6e70b990d15d7560a6748e2b2e755152fa0f3ad9eaad7a6351c85aa13de3314018c2dfb82c12dfd5613468217f0bbe68747a06a56630feffe30a47a579bd6ada8eff2ab2a0299508107132b09e369bab3bacc80f90211a0e484c57f98d9dcb3981e79fec1fcdd4e9ade6b50a8763821faa52d6e9c40e515a09784bb9273fa7f29beefb8fe8c68dd148c164549aa1551cb8c69a4701af3d94ea064ddce91ada26c9916cd903f21c5b6008bf2a865ef9d3fc24bcd423bd02d9a93a0b4a7c85096f6d7016f1834bc01e1ed6c4314ebfbde73f80bce360a2f03e3cedfa053ecf424b86f3d97a054b057590cecb1e5e2878fb83d86cb7730b3dbecc4fd46a02d2bdccfe1586cd1692479a75d2b97a4d135e3dbab564ed3b6855113c62af598a07ab54330ecf7eb9e02720897d0380dc07eb2665892627451d174d1d87fdc2067a0d3d35f8b3ffa8c8c98cb34e89432b6157a148c4da14f868f97c9404d985850e0a07506b051d3f02f382730e2012e93b65addfccc9c962afbbbcdbd141b66c495daa0718f9d6c2bbf55d70c80a5decc2f49ed78026afc27de294dd28167f0e41786dfa072ae72e1a94cba48ff51cfc05f405af5931cebd85881e7767b4ea1884b87e4dea089d6433224364f6d40dd7d438ec7d1c924d70209ac8dbda89ccf5a39d1f031b3a0fe834ecb338a4b03a894fb36f2d0442ea48e6d0fccac2a45f0ea2e6abef6487fa0ce3c2a783bf9aff7764d32910d594a110f549367ee6b94d157ef949a2c33e65ca0f9f8490546b48f4dd548bef52d9fe8aa827d214940ce1842d139a94f341b611fa0d4b4fc09aaa8c6317c2060ef5ebaadc9bc211742296c8a80511b7ee0cd03417280f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea0c6c70650f6edd7057de9a8d7aeb5a52bc40dffb8a9cb71d55990a628f1596402a03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a09592d731bffb4d9b9ed4cf697f24f55ca7075c66a021aaa9f0ce119bea344411a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a0fa59d52ce31992709b7380abb4db6a33327763297b3c94791f348d886c7125faa08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a0253e402e9d5665c986423a2518d345b0c4d184d36562df4736dc28c3a51b60e2a05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a0dc34a817b1795244d58bb1b03cb361fbc68a3bb4a66ba3d891bfc0490d59115ca0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a08c81335ba79260e105491d1226e33dec334014016614983701be7b7fb10af9b7808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a2a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb2a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2a44ef0274e31810c9df02f98fafde0f841f4e66a1cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e32442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9132442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab032443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a324461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d25324470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba7324472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a5132447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e32448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193244ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3244d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3244ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e3a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e913a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a3a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d253a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e3a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3a44ef0274e31810c9df02f98fafde0f841f4e66a1cd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").to_vec(); + let header= hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212fb460a9d060a9a06f90317a05476de88778ae06433d626a797757b16db593c1ddfe95e7507b0ccb0c7b0bbaca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794295e26495cef6f69dfa69911d9d8e4f3bbadb89ba00000000000000000000000000000000000000000000000000000000000000000a076a175a852506d49b4a9eb9de99e7281b5a1b998f686e56cfd0cac4ebead2390a0ab4e162d0588a8e6121d582047185515784b1d849d64a54cfe267cb6ceae7a52b90100246ec65ee53634f09d4e547d9acd756eb56a50e2999d8efc6d4a31a07c6b21b0ef535cac0bcc734b42b8bcb2175a361188335abe8a2f3352d973e453a065a7edbe5e4c5a8941dd28a1870419f165793fa1da0d215766ea9a009e050dc0dbc622addc8637df4f78655c65027c01cf8bfdaad48cc32a9bde6d6107e73ac938885fa53f2813533d685b9c9934c992324dc8442c2ed7797bbc3e7bb9ddd11e8510e4a2f020db32fee2c916466ac42b640fc8a5bf3ca8c4c3c304df2480af2addca76eb401626d5b52806d0b448bab0d65c72e5ea7745f0c1c0be8b51d5fea362fdbf12d4840798e9eb05437db7ab293d65a7f5e8a5b8e777c6ccb2a76130de8f35ca028401eab40984085832a783d492548465167109b90118d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5831deffbb86092a6780f361d51e0464cce97171ac40abde3ba9b4ee21827e51bbfd5150715d03f970fa6503cee0e3e2f68a53a86c8f1056e386b74403a87bd49d678c0f087456f5ec503d746e9a0609f0477aa499d385b407644421598b98e5ed6c4299a1dc8f84c8401eab407a0c397b31f066df5bce0870dc59c55679595a63fbedca6df40ec5923bdcffcab9a8401eab408a05476de88778ae06433d626a797757b16db593c1ddfe95e7507b0ccb0c7b0bbac80a6305a8d4a5d4c0792359e51109a45f9e300de54887383b0e2788030a8f8ee485db7b5e06759f5cad0592d926a8f7ba1716031584f86d886c87260564f11c4ab01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a0466ed3b0031d1185f3983206cbd37bad845d750e0b31a61a0c1e1ac333e31c94a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a7cdd959bfe8d9487b2a43b33565295a698f7e2a02adbb1a0a6b06b930cd07aae1deb7a9bea8daf0875ba538d4201d364208a3a48a045c8091931f95929ca061c8f1c7e841e8c97dd71241beee58b475423280363fba06530f48090bee862a9eec4b83a9108a4441a6d1d92651a195b2ff1caa6833234b9010064b2022aa125179c281e60e0b40212605000a0b08409160a37884165800151809471590d09009401407238b2041a10388960501b420b26600010606088222a8a6d01c4900552082a031400198330223d203e6d01817e98140284101684246fba8ae8a0350b0a49006041890880581f020c0124510188453d052002154048024204866001220c10cd90a80e2019324a89902414a500601d08111808681e8600206a1050183380c834300e14f51b800e68300a14911043086512b03461ab2204a49086844ac32912c63042542151365116a4dd212392a02036c111d9060602b203811181a500e451381325028a90020120740004014448065d9c838cd482f20940028401eab40a8408583b00836f2229846516710cb90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5831deffbb86084521460c25d38aa7ae7ce7bcdf29bd26b9a976d362b8f09f563a5d10d648bebe72714479b8c1e98f5d7c6f07de728c2175cdc7f29beb6b589a1ea7a385754f75e296e870db5b22e2c5c4723f1fd3a7a94f305af28ffb4f9cbf62f5bcc6c3525f84c8401eab408a05476de88778ae06433d626a797757b16db593c1ddfe95e7507b0ccb0c7b0bbac8401eab409a0466ed3b0031d1185f3983206cbd37bad845d750e0b31a61a0c1e1ac333e31c948039a83c5e365e31006364162a154044d6d6f91fa0b773d9d7daecfb39405a38ab6c240fce26c8174a64ce85be719999120b6f79ff04c563599e1986658737954a00a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a0e0b43ee7529a00865d7b72b81c79b1f6b651987ee2d3ae78dbf409e693f83154a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942d4c407bbe49438ed859fe965b140dcf1aab71a9a03265a2db9c8cd6930605dd02ebdd2ff63460d4946a6b9f6afd5e8234f9d534cba05cde4e2315912ee28671e61d7fb4f135d7582961de005aed9db7c7d56c680349a0bfde64cef310b8d3da73f0a1f7fb1df08b185a7f4dd3748498a0ef4cb572fb44b9010022aee635ca1c5a3c4e490ac793172c70c50b7bf0b994e9801f530b601349a44dc5a8d1c44abc9a0e660424630f1319c3c16d3619a0a27019db6b7186196ce3060770208485e0445089264cd9aaa905f4bd19dc6023564a47a20c0409ac0914119a2fa8250e06400c715f0410c9da2f282a50076d211cdf2a2220cd582c29852013b980820e91201b949c2c2864e00898253584a5cc940318251014e4f0102c370b92aa4d5befed20bc8c005c1b9a9ceb55eb40f09a80271b51a32d293b46208c7502564ac65aa4572192608b80025880af439744f2d2cd5c2513f54ab94cf27c2a3baa681574c930413053c3c3a581a66c3144a8427a5362fca755c02a690553028401eab40b8408583b00839f1151846516710fb90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5831deffbb860a48fcc028ec0352ad6920f1a14f17359b28dcf66eb0a0cf07c5f1b71512c15d69fa7b8816d6e796b965288f0e5fdb3340f230205bfc74836f95c7433d5a48df6524bd3225025d663fc49c910f7bb4357127fba970a2f08d8931107473e025395f84c8401eab409a0466ed3b0031d1185f3983206cbd37bad845d750e0b31a61a0c1e1ac333e31c948401eab40aa0e0b43ee7529a00865d7b72b81c79b1f6b651987ee2d3ae78dbf409e693f831548053e70e1c90b1ff0d04f12e36c028b726617359c965f2e1b5a095b2c5dc11b7c627db7d795a3bdf2023997fc1c99a727a7216d527eb2b5d69167c38b466bcc81e00a000000000000000000000000000000000000000000000000000000000000000008800000000000000008012051088e8aa0f1a951df90e92f90211a06289704113a290f1682d92d0e068b125ffde5a90f99bc6c59b2bd0db2deb39d2a0782e0e6094a4d50304a37aec55d2fe5076eddcf76b61e1d9b1e2539e7cd79207a04d9deb002bdc25168b895fe6e6df49bd2fdaa4f07b04d8dce4fa3c3b3a6fb62aa033260113d4e438f25018bda0e1fd39b887ddb7e819bd609badc6f010839da314a02eed46f377ffc42c0bb193d4aa97ccb3998ac82d1b91dcf2d94a98cf210cde6fa08ff8a55f0832e589e2aa5eece3eb318458f9cee7b3f4548312dadbe626c22464a087d208dd1290b44b8aa4e4b905e9e8787b7addbab02d56207b80912a646746cca049d8da2c29812ea10779b17b3da1d7771926c33411587a465f62b0034f51ca35a0877ca94e3bdbf2d8cd0812d2efa106e8917e04cf6524587c46be587dcb5bb834a0cbdc1c5527223d98d4c1adc2c728aadd8e346c915123192f194e3b1111e56ea8a0a983e6c68313ff23d352e85175b0fb545860b2b39e87938ba64399dda889fc61a0e43edb427ee96dcf073f94711b3df51d35a74b4acf5c768fdab11ab6c2c91b9aa01021561835d0c5f73e6ca147d1b6df2c8e287d5a4dcf908357e63fd8a9fcba10a0a9648da8a484b0058ee84be85c462db545e9bc38bffb477dd3739b30ae823945a060cafa3e1f6be26606fe22918417664d14202630de7c331ff01eabbfad47f468a06d0274adff6267c3a071d648620c79cf8edf2f1d5e412dff004a9ffc957ce79980f90211a03d27cc96201446250bcf02fe1386b1c892922556b666a6cc2fbe92d69c758f25a0e2f85b3099d0d4db408c60da643fc720e25711efee0142719f843f92481b9ccda08442077ceef65a3b83723e8f6a55ae51b2e4b3d2dbd7add10a70dacce4e2ba0ea0d69d61375a4d8f3f5b1cb87ebfbc5005519765b6f0c934fb452435f99e5f09f1a0ca52daa116436ee9e525d4fbb223d5bc1c3cfd46f9364ec4b4f5b5be1461e285a09a6a5d21766905abb903ab3ff5c44d700f0f05e25df68db3b1d53d034e64b2fea04376ddbd0d0317193d821c59be4ed2c8918a6cd595aa35a51d6d09a4f5c57ad0a0284bccc30952ff9058cecd23a9c45705f6634c631f88d3e3ddc2eb28ab85906da05a4a773be44ff300fb9451c35c7e7d55f7813f964334514c06ff492495a94e35a0e22a71f329555336ba55c34a193778b24d5e7e0e198598588fc66cd58d8714a1a0f8046667ecc4760db98a856157ad50834eabe3cf5d8a7168b44419838d223a8ca096785d862263183db9c6ad315e9ec83993f7495d505d3578ab08c807430ea5efa08bedb7f41eb3fb52df6c905ba9972f4d61c4b89b9c3d574c8d790f7390ea3afaa0982687528de7aa616066958f437a80ac5373ebf0c591270c41e5a6a113fb5b62a0e4e796cd180bfdf8c88f6c1ed60cfa9ea0d41fe5d30852393d6442aa21a9166ba0cc9fe56a53ce16cf142cccaac1eceb51130772e3e80a903a9853ab14c651577880f90211a0ff3f126f8d9a683a679a7b3561404588e777e7fb596951b6d622118a7145ac99a05889af7518058d3f8f1df7be08264cd6f53c67d5e6f5e3ce6e2a2962b6e03dafa046cc6d5154e933981ace44223d1200c3be8ed550d629eeb351518f9b066eb8bba0dd68b04485cbbae0b45902d69c72785a84f11c147f28afae8048847ce387dc75a0486c0804086a32ca9d670e5accf633a4a37d434b93c138fb05ce4b6c933c73e9a0e6ee60b28b3a23111c046172b9006a7327433f9198561fbcfc94e1e29aaef69fa0b4e6a3d54460ac2199bd297dde34ae748319914c27646d21ab013bab3c973cf9a02e78501923bfcabe518d9249bb970b44c705a832496b24b58bc0bec107dd2766a011434c912f1771b31b994134d765e405cf9b1973f133478250e39ebba065ee82a054d758f3bc0fc530c4bc2dd9f5dca198aca9121c9063b6e1645fabce15807e2ba0e3f20021d4d389d50bc83d52822aa82a298de130901c2ced3a0c1fe8b90dfeb2a0a602b1f94ee4e60674d1652647ab09acb3880c6137cbfe141c35bc56795d11b1a0c6e07bee12f76a23914e5514d6cf11447aeafc93169c705567a3d62b80f09f28a0d883732a9e24b91ef30c4a066e31799d010d818d0c657af2e1b875c4aed8f6a1a048011480c2eccf6ff256c62e7c8ec69f2e1201541b8ec4cf951d7c8953884bfda0a74976f3c1568094513dc978e2a75f7aa05b4ca23271f312c6ff8d6b9e16fd0580f90211a039a1af4570c801d62fdfe4674f02510e117eae6330facc959df997fa8e4d6c0da0969897f77040974812fdc243499998d5a2f808b010e3e743fff5bb1cf06701b7a072a62f95c81d3849bc02102bcb66b5be775ad3b68cae7967451e6a13c48b6c43a04a35f1ecab27a8a53e0ec424e0add8045b2c25a4efe354d33fb75246f333eef3a0b432a588f41a59491ec16126330cbe15a7e6aa261e05dda3d613dfee571cb9e0a03e55e7223adcd5dc7ba7a187a0443ce8110cb34ef616883fc3a33cf2cd06947ea0e62b04415ce8e7a5e17bddb2ab421a54c1095137c60127066ea495e56dcd26f6a010c1d3ed8e096233c3fa24d0e6604b2272497f25c388bf55cf1f2fbede09c424a020915f443baa11cfe88623086f95a4fec54633d2dd4788b4fe5aacb54e433be4a0d604d6e74ad8121336fa09e9672eee5239e757e03a0a7e006596479497832c0ba02a1bdf5679c646407f898eecb449053dd3f1b5ad7d104dee3d8d01674bafa747a07e4527336a6fe45d71c98c0274515d11279e5d8c0d21bee7c63e5ee1f23426e1a045f3cafdbd08257bee895fc3f4cd8c7db2dc04a430b8e33bed28e2d117010837a0fb219648890e649741ec78e85f4550de81839cc5a4ece0b98f868ae5ad92458aa0b2d85e9be8807bae98dfe9520d739703aa23eab1fe6764196844d4afad2a819ba00c1369efa246a68459c9465394abf698221c2f6c62c2c159ab5e89e7c16d2bae80f90211a011ff0a2d404fd7ed97509ebaa806f2a5ba09c5cde5ff596903c4313783487509a014931c578b05f5948939281aa31d2bc8b05b01c6932c45bf7a70972a430575c2a0d85789a4b9f2eec599bde9e5e9946fe9f7a613de910aebbd1bb681d718d422c8a092b17ad714173ec4787f0b3b9d2dfa96680861e093b5121441ffcde64183d074a0de881616657bd4c300116254ef39e2622f52faebe1b06b4fc9d3daed9dc76c06a07ce695737ab0d4bf9003a06ce83b11e75d81fbeb47c013b41f9c2e00a97cb87aa0dfe63771f833e98a5aeff54d9dd5a8dcfd89ca43c23644b18ec8e29ab8ccc287a0a327c817dc8a8ea3a5d3ca3cb55169777a1bfa30fe9f0df842eb3978dbd6737ba053683114bdaed7819b30ab8baec1fb9a2a96fee4dabc72f319cec9869da3b0b0a04d98297a896312d18da40240ed9a527f4c01c73edd3ea1f7c28338d1d863d97ca070451b5f2a402b497659eb18e648ac46f39c0068cc91436eb0b082b1d06dd63da066e866f800200512b0d3e534c547f4d2012429152cc9693bf1553cc22361627ba003fc4e648aafdadd7a9fa7cb534103f08dc699413ecda22bda46898bfb792429a0b46a167c66b50c74227d03a68971e124fdd011d6c90f5a08f6fe30ae34de603ca0a7ced66271235bc27b154f37bee6d9a1366cd253176c96de707d124fcc593c35a0f4f09b104a86cefc5c282d393b415e6c224eb8a463386448ebebfad9f9f53c9680f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea05dd8c13b1b83485911f5e1185669f7d5559c260193a72e52597a3e80736c248ca03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a0ebb2cbf0c3314ddf681f21a29fa17b320094684ba35e725bc36bbc407821cfa3a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a046c10b0c15aa83973ea4b108f50bad2638941550fce7c9308c8b968abee271f8a08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a04539a99793f29484fdbd39b606f27265499acb3c24461f48858655f07166f0dfa05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a05c170d685d29417781f678b746174c7500e7c228b4bd71bcfe9f5421742a0b67a0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a0a10cfa51ae290afebd64a5b530db7088fa0b02f22ce9b0838135b422b885dee5808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47022440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9122442a7cdd959bfe8d9487b2a43b33565295a698f7e200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab022443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a224470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba7224472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a5122447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e22448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d7886948522449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2244ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd02a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a4435ebb5849518aff370ca25e19e1072cc1a9fabcaa7f3e2c0b4b16ad183c473bafe30a36e39fa4a143657e229cd23c77f8fbc8e4e4e241695dd3d248d1e51521eee6619142a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a44685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d3582a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0").to_vec(); let any: Any = header.try_into().unwrap(); - let _header = Header::try_from(any.clone()).unwrap(); let client = ParliaLightClient::default(); let client_id = ClientId::new(&client.client_type(), 1).unwrap(); let mut mock_consensus_state = BTreeMap::new(); let epoch_cs = ConsensusState { validators_hash: hex!( - "8ee1f2e84ae8c6a95b1af35e7766c2f9fc1f3bf1a4dabb50d829a7ea422fa79b" + "021b6af8efa138e87fa1819cf173d7e06fec46cfdf88cfe96b73ce0e514b89af" ), ..Default::default() }; let previous_epoch_cs = ConsensusState { validators_hash: hex!( - "bc4b672cd2acd42f2ef5116aeac330817278836eaa97b412d4ab5d07451f77c5" + "2d1eb63e4be97ec3506ac5a847e875523bc2caa3d96158d3ca15fd9c554c6a00" ), ..Default::default() }; - mock_consensus_state.insert(Height::new(0, 31727094), ConsensusState::default()); - mock_consensus_state.insert(Height::new(0, 31727000), epoch_cs); + mock_consensus_state.insert(Height::new(0, 32158728), ConsensusState::default()); + mock_consensus_state.insert(Height::new(0, 32158600), epoch_cs); mock_consensus_state.insert( - Height::new(0, 31727000 - BLOCKS_PER_EPOCH), + Height::new(0, 32158600 - BLOCKS_PER_EPOCH), previous_epoch_cs, ); let ctx = MockClientReader { client_state: Some(ClientState { chain_id: ChainId::new(56), ibc_store_address: hex!("151f3951FA218cac426edFe078fA9e5C6dceA500"), - latest_height: Height::new(0, 31727094), + latest_height: Height::new(0, 32158729), ..Default::default() }), consensus_state: mock_consensus_state, }; let err = client.update_client(&ctx, client_id, any).unwrap_err(); assert!( - format!("{:?}", err).contains("UnexpectedCoinbase: 31727095"), + format!("{:?}", err).contains("UnexpectedHeaderRelation: 32158729 32158730"), "{}", err ); @@ -778,9 +720,9 @@ mod test { ), ..Default::default() }; - mock_consensus_state.insert(Height::new(0, 446), ConsensusState::default()); - mock_consensus_state.insert(Height::new(0, 400), epoch_cs); - mock_consensus_state.insert(Height::new(0, 200), previous_epoch_cs); + mock_consensus_state.insert(Height::new(0, 1184), ConsensusState::default()); + mock_consensus_state.insert(Height::new(0, 1000), epoch_cs); + mock_consensus_state.insert(Height::new(0, 800), previous_epoch_cs); let ctx = MockClientReader { client_state: Some(ClientState::default()), consensus_state: mock_consensus_state, @@ -791,7 +733,7 @@ mod test { // Detect misbehavior // header1 = localnet, header2 = localnet(9999) - let any = hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212af2b0a0b78782d7061726c69612d3112ce150a90060a8d06f9030aa0b4304bccb870387220a4c5e473faad744060b4eb4a6e955f231881ce9f2ddd39a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a08ec84d0f3490d40621ef6d4bb31fb05075b2108e8d9ebf08c0af2cb9a8a64ffaa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201c38402625a0080846501b5a9b90111d98301020a846765746889676f312e31392e3133856c696e757800008a73902cf8ae07b8608e62c7b7910b161247752db330d5cc3a20eda304524ac3189fb62176d2dff32c8d57f45d9a4f91fc3b6bfdca26801e3a15e10345942afb7c33dda0fdf728b4a1d3d1816e85d45d2c66a07a1cb33e74d58f9cb3c82190d22da0e7029921ef1a5ff8488201c1a01b6a7207d3bc4969ce0286b3928fad5ed6da5854b2292541c96bdfdf4c97a7fc8201c2a0b4304bccb870387220a4c5e473faad744060b4eb4a6e955f231881ce9f2ddd39803638ff4ff1c190fd4d8f4fa1bf5d4133e655d4338d5d4eab5adce358407183690a647b63de6c7abc8d92c8e83d6bab8d2924fdea545d8f8b860f361a83a830de01a000000000000000000000000000000000000000000000000000000000000000008800000000000000001290060a8d06f9030aa01b6a7207d3bc4969ce0286b3928fad5ed6da5854b2292541c96bdfdf4c97a7fca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a08ec84d0f3490d40621ef6d4bb31fb05075b2108e8d9ebf08c0af2cb9a8a64ffaa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201c28402625a0080846501b5a6b90111d98301020a846765746889676f312e31392e3133856c696e757800008a73902cf8ae07b8608059197e7b7e8192a6608f085d8f8b255f6e51789d5d02641920090d0768d1317315e140fb8b08a0311a7a3c1d642335169201de2102e51a8059016d5b2995b5632d7f7acb00245927a46cd2e15f6affa72f91a0461987578ac2b07d6257d512f8488201c0a0e2e876fdc741369c37e72b4f911fb2ba2343919824e32bcfe01862a72faaf6c68201c1a01b6a7207d3bc4969ce0286b3928fad5ed6da5854b2292541c96bdfdf4c97a7fc803b6e2c6d0ef39a9e2158a8397843b95a9abc9a1fa6bfbc610e3dcefa02cbc2346bc3d9c3b35fec32574470fa51c6fcba722be10f6ed4b29ae97a2f61768602b101a000000000000000000000000000000000000000000000000000000000000000008800000000000000001a0310be0322aa04f90227f901d1a06ed7d26d8a14a9cd8aeb3f01960cae49b7e95dbd549fff6556694ea3ee3dc173a0b72a8e0c72d17fa2d84073eb14233306d8579d003cc1c635d3dc697550205b3aa06c664a574aeaa739d85b114d13a20a15330b02565910dfb142b6715b5742a562a09e8d71308bd38616ac52a39498cee9fcf29c440d9aacfedfc7143772c77ce54480a019977eb86a7f4c991220db91b3be76de8c43b5f5ea5414ad2ae17d27226ff633a0381f8d97517174f4dbbbeeb5d868c0f9b1aeb42bbde735dc836af87c2c602b84a0c993119ba273a56742e6fa6f92bb58a0120a3b3d27200340be21bc37ae8fdce2a02658a732f2cabb46a23ce709ea72ee4261ce28ca5c3bf163ba3ebfaba1107e52a07def82f69a90079ffaeaa69f6fda2b28363547c376948939c06aa8206c51c022a0b84308f4cb54366a086a4fdd936c40ab7ba0429ca9b7a624a6db6c5ac35c0b9ca041feda5565ebddc0a30be2e0fef75fe61729344ec36395f2f1e60865cd434a58a01223a2c45e23b4266f6b786bb346c31ea0c18ac94135d2f5138cc2851f7bf44a80a00d690f6252aa5118f41dce0eb3fdd420419d6d73ef7d51559385cab56a0308e2a0d9fb3060c48ae6a780235b470c1c81c8417c7c91364a8985f9a92b98ef3cbf5e80f8518080808080808080a00f079d6471365442c66c0559bffebac0b429bc330e636338e9c5dac3bd3fbaf7808080a0e2ec5bfa0874d74ec0fdffc07602dab45aa5a426ed8ce5c3f11c957ef5ccecca808080802a448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2072a44a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72512a44d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff32448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2073244a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72513244d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff3a448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2073a44a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72513a44d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff1ace150a90060a8d06f9030aa0b6ec0df3ca2dd709ab7de380f4fc652e640dad39e99203dbf1e1966f4417348fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0353de19e794370e276e7e71594a6e587651aceda4310676cd72b5e6407b027dda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201c38402625a0080846501b596b90111d98301020a846765746889676f312e31392e3133856c696e757800008a73902cf8ae07b8608fa74258df96a23eb9a8a82c18e779b1343c133873176d89fc7055dc822ba1684bb1de621ef3f3d9cd9a94d06b495b730679ca1a8f13fcea0cd36e45e4c056090370ecb7d388550e4b6d72809296f9639539e1e62b57b0d134af2cda900f523ef8488201c1a0ab4e798467c5b2165a59934d5c2257c12e9b069ea41fb66a434114590faf89ef8201c2a0b6ec0df3ca2dd709ab7de380f4fc652e640dad39e99203dbf1e1966f4417348f80c1c4f2b112d74618de38a1682c6b2fb98adb5b1b5ff2514e4896bf119543ca6236fc0b0ba631da6291d5fb14ace79dc4fdc93f8c25764ddb7f166eec923a2b1e01a000000000000000000000000000000000000000000000000000000000000000008800000000000000001290060a8d06f9030aa0ab4e798467c5b2165a59934d5c2257c12e9b069ea41fb66a434114590faf89efa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0353de19e794370e276e7e71594a6e587651aceda4310676cd72b5e6407b027dda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201c28402625a0080846501b593b90111d98301020a846765746889676f312e31392e3133856c696e757800008a73902cf8ae07b8608a471d0e1b7471b2ddf2ec13cafa1ada18a18415c107cf538a183b93149ff144bd8adc8e915bd2fb73842e6fc521e6830d30a70ab64429f2114c2627663fb5ce61d66409c89da040c6077cb28bdcbf19a57fa47135d052f66497d6bbce22c15ff8488201c0a0eede3cbce22d8081c2ae4d4b75b33719a9b2913ce999b69e8f6bb3867bd3983a8201c1a0ab4e798467c5b2165a59934d5c2257c12e9b069ea41fb66a434114590faf89ef80619b8a726f5e50708a1d491b71f56452841bf109a754a931b5538353d3704c586cc8c1527d8593dc8304abc6476902cd73dd148539be066bc6d6570a8967de5801a000000000000000000000000000000000000000000000000000000000000000008800000000000000001a0310be0322aa04f90227f901d1a06ed7d26d8a14a9cd8aeb3f01960cae49b7e95dbd549fff6556694ea3ee3dc173a0af1fc6dc8aee0de1c4844230d31220c33798d54af180037b2571e6be0c935ce5a06c664a574aeaa739d85b114d13a20a15330b02565910dfb142b6715b5742a562a051b92742fd280c4a2285b18197d40134dfe7d903b7d707cea1bd5f442a78a63580a019977eb86a7f4c991220db91b3be76de8c43b5f5ea5414ad2ae17d27226ff633a0a156dae53c5b94e2ea1d02085d28075f5b42b9af13a0b04759b0a4b511dee023a0c993119ba273a56742e6fa6f92bb58a0120a3b3d27200340be21bc37ae8fdce2a02658a732f2cabb46a23ce709ea72ee4261ce28ca5c3bf163ba3ebfaba1107e52a07def82f69a90079ffaeaa69f6fda2b28363547c376948939c06aa8206c51c022a0b84308f4cb54366a086a4fdd936c40ab7ba0429ca9b7a624a6db6c5ac35c0b9ca041feda5565ebddc0a30be2e0fef75fe61729344ec36395f2f1e60865cd434a58a01223a2c45e23b4266f6b786bb346c31ea0c18ac94135d2f5138cc2851f7bf44a80a00d690f6252aa5118f41dce0eb3fdd420419d6d73ef7d51559385cab56a0308e2a08ad62b6962f76ca4a39f319e11e1f806e8606e50703c2636ecdb82643889042d80f8518080808080808080a00f079d6471365442c66c0559bffebac0b429bc330e636338e9c5dac3bd3fbaf7808080a0e2ec5bfa0874d74ec0fdffc07602dab45aa5a426ed8ce5c3f11c957ef5ccecca808080802a448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2072a44a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72512a44d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff32448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2073244a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72513244d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff3a448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2073a44a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72513a44d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff").to_vec(); + let any = hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212b1340a0b78782d7061726c69612d31128f1a0a90060a8d06f9030aa025ffb3920008fd0591adc665132f7296d4d3da213f27ad5f13c29bae6b53b150a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a03feedbe444fcdaeea389d10588435b9657b71aea384266ac09e15c0772ea6bc9a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028204a58402625a00808465122d33b90111d98301020b846765746889676f312e31392e3133856c696e75780000e904d98cf8ae07b8608ce4e95f382e2d06eb6c98641c574069f7c8cfdb482a4c58290f9f2ee86f6d4ce520d7bb6a6be1acd082c07a9d65b45f1334def3c66fc793003cf06f3fcea7ce055b34aa911f6ff7b9bf2eb083f3e7010a34e8c61aa70edd8ad630c82f3d4a8bf8488204a3a02d59fc7d664ae17504839bf6c49ca0e21fa794fe661c86e929a522bd4872d3458204a4a025ffb3920008fd0591adc665132f7296d4d3da213f27ad5f13c29bae6b53b1508022216e66d52050e392e6a6b86f677363e01be8deb6611cab76cada1bfd6c0b7048798c2376f52d8357d8aeb6e6c0109dd802675c849dff145dc3dd470fc7bce400a000000000000000000000000000000000000000000000000000000000000000008800000000000000000a90060a8d06f9030aa09432b9b136e91a12cea5e9cc363bc821e90da6c7b2d7f369533afa746ac21508a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a03feedbe444fcdaeea389d10588435b9657b71aea384266ac09e15c0772ea6bc9a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028204a68402625a00808465122d36b90111d98301020b846765746889676f312e31392e3133856c696e75780000e904d98cf8ae07b8608f21cd736cba2bf8c4af32f237f4851282c77b602f3e5ef48c48e16b36fae2f8a80bdb501d48c235b3409ec53340742919fbab1a54cde9da53886da4e7280a7c450714fbdd1dd5907a9f4990fb99e1badebba671d521d47f1cdd23ce3eec2e90f8488204a4a025ffb3920008fd0591adc665132f7296d4d3da213f27ad5f13c29bae6b53b1508204a5a09432b9b136e91a12cea5e9cc363bc821e90da6c7b2d7f369533afa746ac21508804b8debfb8d55a7f71547fd88e1c40eb0efe960d32d08601589e22a62bb0ebeb26b984bba8f736484ae789567e5d9563104126e78181a293d6ee504e9ad35725801a000000000000000000000000000000000000000000000000000000000000000008800000000000000000a90060a8d06f9030aa086efaa0d95f31de170d88687b07806f3bf271bf842b65f6dd76b326e1575e609a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a03feedbe444fcdaeea389d10588435b9657b71aea384266ac09e15c0772ea6bc9a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028204a78402625a00808465122d39b90111d98301020b846765746889676f312e31392e3133856c696e75780000e904d98cf8ae07b86094c8bc4a6ed9b43a592f7c7a035e27b119ff45ea9e7e6ab149136ab18f268499c6d6d920aab86608315093fffaa354cf0077173664aebe97ca185285e739559a01c96d04a30df92c23ce051b1700c8fabd41e1ac8db8229a3c08a067a60a4ee7f8488204a5a09432b9b136e91a12cea5e9cc363bc821e90da6c7b2d7f369533afa746ac215088204a6a086efaa0d95f31de170d88687b07806f3bf271bf842b65f6dd76b326e1575e6098085641457482587c8687b5e40069f915f48961cad6069305c278fb117d4661cd80c92987afd0b4e44e794945580feeedece4b1b68098b6134de8be2ed2245aa8b01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000120310a0091aaa04f90227f901d1a06ed7d26d8a14a9cd8aeb3f01960cae49b7e95dbd549fff6556694ea3ee3dc173a0c445c1e18313a154c9cfd1a1bdbf2fb6d7513227c59c5cfe4ed6b2f1585ea74ea06c664a574aeaa739d85b114d13a20a15330b02565910dfb142b6715b5742a562a0726016a81a8017e5825a30ad9481c2ea45a35601f9e17a25ef74fb2fcc093ecb80a019977eb86a7f4c991220db91b3be76de8c43b5f5ea5414ad2ae17d27226ff633a075d1dffd2abda435b74cfaccf176f5e0938c60d66068a44727add2ef2df1f3eea0c993119ba273a56742e6fa6f92bb58a0120a3b3d27200340be21bc37ae8fdce2a04f3e6cb5f42f4cfe12e8e586e820edf8460ca87b27b4823c129d986c127e4898a07def82f69a90079ffaeaa69f6fda2b28363547c376948939c06aa8206c51c022a0b84308f4cb54366a086a4fdd936c40ab7ba0429ca9b7a624a6db6c5ac35c0b9ca041feda5565ebddc0a30be2e0fef75fe61729344ec36395f2f1e60865cd434a58a01223a2c45e23b4266f6b786bb346c31ea0c18ac94135d2f5138cc2851f7bf44a80a00d690f6252aa5118f41dce0eb3fdd420419d6d73ef7d51559385cab56a0308e2a054529b9b4e918ca60d7d2c1f1c9104a1442f9dcee09012b637ec7bd7ec46702680f8518080808080808080a00f079d6471365442c66c0559bffebac0b429bc330e636338e9c5dac3bd3fbaf7808080a0e2ec5bfa0874d74ec0fdffc07602dab45aa5a426ed8ce5c3f11c957ef5ccecca8080808022448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2072244a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72512244d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff2a448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2072a44a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72512a44d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff1a8f1a0a90060a8d06f9030aa0312846a6b051a39d1ac8afa16dd707c278c2590b5b5399dd5dbaa2c87e9c6d04a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a049b529cd1d9b70dc216289fe9519c319964f0f7bd9458056da2defcf42743335a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028204a58402625a00808465122d36b90111d98301020b846765746889676f312e31392e3133856c696e75780000e904d98cf8ae07b860a0be31d422b4b017cc814dedd756cafcaff3c871779a6321284cebe91e5e1c2c0cb49b65be2a9bb41eabfc5480c8c75f0906339f62235d0b4352b3af1e38c79986cc1eb16880f26dd9c8f40bd8020890985d59f01bba4dd46df62be6a0c05414f8488204a3a0263c6cea09d25bb460401680cc3142f116c5a377f8ef11060e80f0f612f1c3168204a4a0312846a6b051a39d1ac8afa16dd707c278c2590b5b5399dd5dbaa2c87e9c6d0480f7464a0e50746e1283e82b6ea17ec53c71c61ed86665a300756b53d37dd3991346774d2ac3c242d8f0371f0ebe08f5af80757c6cd3e239212106d05d067064a300a000000000000000000000000000000000000000000000000000000000000000008800000000000000000a90060a8d06f9030aa04f09e6f36be8d56f196ab819ceab4de899dd91ea84d1a579c59cfe8d41f74269a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a049b529cd1d9b70dc216289fe9519c319964f0f7bd9458056da2defcf42743335a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028204a68402625a00808465122d39b90111d98301020b846765746889676f312e31392e3133856c696e75780000e904d98cf8ae07b8608ae8e9f3eeb44fc2ace50cb82e7922ccfad7571f507e89282474c970cd87f2f90cb7e3e22ef872e48cc904015c4792290b172b0e9aef2090a9ee653c0f258c215314c810b42b1a4399378cfeb7e8130082d7048bbc25c56373e4167b25feb51ff8488204a4a0312846a6b051a39d1ac8afa16dd707c278c2590b5b5399dd5dbaa2c87e9c6d048204a5a04f09e6f36be8d56f196ab819ceab4de899dd91ea84d1a579c59cfe8d41f742698048e891fd5b3f1eed759866fe722882c746dab531d47e972732640e42f49365b1348eb77bdc7425486f16a59b5080dd87b9406f1d532c37b8589e4b666cfd855b00a000000000000000000000000000000000000000000000000000000000000000008800000000000000000a90060a8d06f9030aa0ccdadba9c31c3462045f7552ec31591fc033d53cc02f66efe74a7a11527dd886a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a049b529cd1d9b70dc216289fe9519c319964f0f7bd9458056da2defcf42743335a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028204a78402625a00808465122d3cb90111d98301020b846765746889676f312e31392e3133856c696e75780000e904d98cf8ae07b860b5564a5fdce667a739c336d6b07beec17f8afcbc72da74f98e690327c32893b81ff51a6badcb7dfc0af7de042dc3b90e0467fef125d666956f3179b5330fc7a47624858eee5cb9edc93b45677417b742d213d97205770fcd0a36d6c409f551aff8488204a5a04f09e6f36be8d56f196ab819ceab4de899dd91ea84d1a579c59cfe8d41f742698204a6a0ccdadba9c31c3462045f7552ec31591fc033d53cc02f66efe74a7a11527dd88680299e2c8ee9446f79b09078581adec0382f5f0a5f49986493802bc10349e535d71b7e2d734818374617361443398ac0a3e3a343b7ca920586db67a7dcae60018101a00000000000000000000000000000000000000000000000000000000000000000880000000000000000120310a0091aaa04f90227f901d1a06ed7d26d8a14a9cd8aeb3f01960cae49b7e95dbd549fff6556694ea3ee3dc173a010790f90204b51f76a67de8b4bd23f62ea75f921641ff583a3ec5e8d681df975a06c664a574aeaa739d85b114d13a20a15330b02565910dfb142b6715b5742a562a051b92742fd280c4a2285b18197d40134dfe7d903b7d707cea1bd5f442a78a63580a019977eb86a7f4c991220db91b3be76de8c43b5f5ea5414ad2ae17d27226ff633a022a617263a20b5549555a9424a99ea156c9337b4b2009f9274febe93638918aaa0c993119ba273a56742e6fa6f92bb58a0120a3b3d27200340be21bc37ae8fdce2a04f3e6cb5f42f4cfe12e8e586e820edf8460ca87b27b4823c129d986c127e4898a07def82f69a90079ffaeaa69f6fda2b28363547c376948939c06aa8206c51c022a0b84308f4cb54366a086a4fdd936c40ab7ba0429ca9b7a624a6db6c5ac35c0b9ca041feda5565ebddc0a30be2e0fef75fe61729344ec36395f2f1e60865cd434a58a01223a2c45e23b4266f6b786bb346c31ea0c18ac94135d2f5138cc2851f7bf44a80a00d690f6252aa5118f41dce0eb3fdd420419d6d73ef7d51559385cab56a0308e2a09ab965be5ca3cbb09432f80709f918076cbad663afd466131fd184c8bda104c480f8518080808080808080a00f079d6471365442c66c0559bffebac0b429bc330e636338e9c5dac3bd3fbaf7808080a0e2ec5bfa0874d74ec0fdffc07602dab45aa5a426ed8ce5c3f11c957ef5ccecca8080808022448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2072244a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72512244d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff2a448fdaaa7e6631e438625ca25c857a3727ea28e5658bb6a87761d9668637faacae15f907dd813ea1df4f85062fa5535765c198bb9d55293684a75d3a12e65215a8b410f2072a44a7876ea32e7a748c697d01345145485561305b24a4f05ea3dd58373394ba3a7ca3cabec78b69e044b2b09e82171d82e6e3998a9ed1f82226cd4540bcc8c3bafa8c9c72512a44d9a13701eafb76870cb220843b8c6476824bfa15ab63700b5d3f58338176990c8488a7c319480310b5ec39d23453839ff26116b29a91e20f834835c5e6f670961d7df8ff").to_vec(); let any: Any = any.try_into().unwrap(); let result = client.submit_misbehaviour(&ctx, client_id, any); match result { @@ -812,13 +754,15 @@ mod test { let client_id = ClientId::new(client.client_type().as_str(), 1).unwrap(); // Exactly same block - let any = hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212c998010a0b78782d7061726c69612d31129b4c0a9e060a9b06f90318a0d84001c3fe02cfe3947fd5cf493e52faf903c59ef8086dd0dc40a63b19ef28bca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ee226379db83cffc681495730c11fdde79ba4c0ca0bec86da42a2d6415c88cd1504b05eefebea6efeedd5f5a43ba75df9c3eb87d41a062f750ba0331e47ce3e954921894986b7c60a353bf09d9674f5ef242a85eace0a02905c9c64f2a92bd4046530305835f16ac3e9fa708f547cdb67a91b2358a0170b90100b62ce73bcc1c775ed99b1f569e58ac773e6deed4dad8b0aedcbff16fbfebf8379dc631f67cb370937f79739b7616a7bee9bb999a97127649daba387bfb7f2e8fc454db3b1d75d56855baefafb30eadbe2dbf5dfbd7778e2fb45ef859ec952e93cbef6bef9fceeffc7edfece4997aad2b0a5ddedb8b8f34d713c8c530fe32b74c5f9fffa59735cf5392dcf4b63fffcbdf5c7ebfb53f68ff9ab115f14bf5f3c5f6d7f3fdbc7a3e837e6315edefbf8f7eeedf3e1a910e8fe1cd14fb70e6e36ac8fe6ff5f7eeef360a77bff3cbc7fddbf3f4f2bde59fb8ac695cad95d7c297e1f5efdef88ab1bb8cd93e3d5fb7f2e5347b22ff6715735a7a7be98946bf9c6cb98b47028401e41da08408583b0084024be3d18465029f52b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5830dfbffb8608a3b143e1d38f79c92cf89bf07824a94b180bbdd3a6b3c53f66106b28a6b23b70056363b07f1b8477f1a6a04ae15bfec13ce0ffb235b6c8c109d7349dd6d27ac5d91a4ea1a5ff39ffe24543f04a708cb3ec3fca46499f9b4e7c08ef2075cc328f84c8401e41d9ea0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1c8401e41d9fa0d84001c3fe02cfe3947fd5cf493e52faf903c59ef8086dd0dc40a63b19ef28bc8095e738d00317cbaadffe6fd7b6eec1af9a10e2571d2ca59841f9698e229f1d2e4abb92f08e69a87cc9cfbaa6f3a8ff12c04cbb0c754f30b01971fbdff47b33bc00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080129e060a9b06f90318a0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da0a1a11bcdfaad405484b7144f7943d329a869b11413a7a24c0d3e453370c59a70a0e3097fdc2c40a54a53378f3ce53060f71191450bb1561277b6187e7e4590f0daa07658e85bd2a7be68c9c750b3813719b251508fbe45f61bce9bfe9fcc7e44437eb901000028020000001108010c00448040006001008000c800005000000102100000a086001000008200000120300609441000000a40220088540070000008002010400800040001000080010000b8800028b0201848088c00000000060400a410004040680220080e6000080000100980080a080000104002000000000010020004200008200000410001608004080008000800240601012000080000404010008030ea800121024410000100000002000000121010000010000428080020000488822210d4060000080120208002920021402002620408000014455051822a30c00800940000008108000100000240440101011000404008004800400221c2006008028401e41d9f8408583b008401b6a9878465029f4fb90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830dfbffb860a5a9f44fa8d83949c7aaf7e257fa1ea04cfc423039a71753105182f538fa18ac1daf35b7e5ba4e2fa43df65b6b8d738e0dfb905ef44572f99e1eca907bc2cf7dbeb3e901e0237d6120174d52d98c1c605383ffba7916e3f0a8a1d7f3be15b1c9f84c8401e41d9da0c9d8b6bd902571508497240a3458925bec4b24ae0d1f898537fbd168df9c017f8401e41d9ea0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1c80c35a9b87c279e7a13706fafd9beab70029f964f21273555079d045d284c9c96201060cfe1489c9a36864fe7bfbb2330b308eff7d697c3cb54c570d96feb132dd01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801a05109fbb900f22951df90e92f90211a09122e3c73eb8bbb2d72ef63422be51d25a3084914cc8294447eb8f0644b951f5a0cbea64d42ab8468a2b9575275c071a35d3429b72c13331a7567368892b167210a0dcea59e8d94af119e9fedfd1e68a4fd5cd7a6ca1ed0ec235e2fb6a47f044ac52a01d73a02e18acb6b4be57d108b8a9d4c30aa639f9b1a7450d783c06342e7a8206a09c81f45c2006dd1c34772c8a4f8e768bb79a6a833ca1f91742afda58e20e72c7a092932695f9848da612bb9d0d8150309baa94a449fdf9508c1166093916c5e0b2a01b926eb5c0975631309b161092d9a95071d3c94c081828c668c474b8034cec14a0446e005b9784eb3c1f6fe2dd6f1bd196b43ff26aca532689b527f0e8e26708bda097724ff2f732457e74603892c7b434ff814ffe57e21f0915de4e13eb5ad6bfb0a0838dff28471b5aab952fb32027ea88d8874ed011afca33480af7135f0d06b1e0a000d905c013e94122d152e473eefd0f11862b99f5956e3a25d8e98b21b1227d4aa03c956fe0a50adc5b8749be62498c2fbaa2c2b212996534821b0f7cdddd66326ca0f690b86ec62f1d85b3ceec425d469d96a66d6638e49a99d552e71cbcc068c301a08b4e33e6b1bdb0a3a2fcae944a1b80aea7be693fa55b2abd9023b10f44ee3770a093ef503da2a21ac403809298c4e98e6eb3154668ca37a0454b10a98087ae0145a091e9ecf6662afe71d0f3e89247651908dc1abcc4ef85f0ae7c564991ec45b57980f90211a0ceeda5be88f90fad85b5a6b5513ef1775d0870055ed3c5029e9606a4d98048b2a03f5051a53cf3e7a92a4606b62c3316bbc0f4ae882e48c03273d38670fa5b6702a0057a8aa90ea006d11c0a93e35607afa28fc2a7e9fdfd4179421bc077fda736f9a021d5c176c1f49f1680f8b43867187204c1d59d85917f295a2d3b7c5291098dd7a0fc7b13c3b70b9b055c385d37136b07665ed9916fc6b36e7b58164debbcea2164a053914c7686c58461cff5a695a18e9b362228a5c06ad3ba082fa9491ef3f5786aa067974c0e7a756a31a7faa30fcb46509c18204688f784b961982de93e710987c6a026fbd9f3f97befb931b748d0d3d3704810aa0e4372b9fd5de3c2556bc5260baca034f69a69c3a480cc0d8490eb5f9fe5af53820fb830a458469b620476277a1850a0ca492ec078d7054759c81d9efd9417e5b3dd3f8ad1a3017319144a9db227a236a0e85a6d33a17f6f288eee28e8a2b12b4aefcf5178156f371806161b02cc418e02a03484113f53b3608ea5cd038a1a677b80a5b822db3ca298c0c30d2460e5342088a01e45fd36175c706481580cb9dd29869cd6b441384d85b1a57275228dee58e395a094cefedc4d6104cdac931428f3f6ddc9d11c3a247335cadaa14b0e3a83dd6c4da0fdf0fbd1a508c0d7beafc876beedd36356ce94f43f7a0b3b220b9265129f1a78a0460ec673624faaa7cbd45b6e6bac157ee71258d1c7b3d4ec688234abc84d335280f90211a04b7dfc1e81ef33ac034638a356b57102725fd40f070367567c2f0d581099a168a09cea84ae3144fb5169a314960b36d0c17416307ebacc29c3af89b6c61a1e4cc5a05d22ab36da9cd2a9989a707ef8f32421f99f11eaded71706c2c924323ef46dc6a0bd3a7e671bc043465544d89f1b370f90d0411a73c3c3cc6b5d5cf4c2e52a8c3fa0718570eefa9ef447c4d722070b75504d2601df36d67e8c0caa082732bc9afd50a030986bc400b7f9aa4798468920379e814eea80cf4d49a2745ad7c91487dffa75a0f43b5f8bbdaa3f2c1707e0d034b65ba4fe6524eacfcc9c209981c03d5e3bb4eca0a14f05a9cef8721262d7d8c28cd653a77f312a99f7d9ff724b6d79de600938dca0d59c167f9b1edaeae1b2e3b84341ce785cd2ac30c49f4f745af4b743cdb80d01a0058581e9ca91afc6abc27096a932138f9690813c2e5e148712e90f8250ace030a09811053c5e3d1f12901d172e8553b4f271b3764e520aa9d22673e107f760e74da0929d67e133fda44ea5f0b2d64fab75493975b0db5441231f322980a153178f06a06fdedc79348485e21a939b50dac883a5489ab4d710178bee044d24c6284bc720a038c3e7024043ee8528ba003b1a86afb1437758e57311e9bb9ddde9f38108ff28a0531a5bcc1389e9eb84bcdd4ecaab8cf1589f7ccd27a324a25ff1804df226569ea06474a723ef6e3a767254e0df7666a521f65501a727e518bb0379b2e68b19310780f90211a0d5645bc2e0e0e7cdf3ab09356055ad366bc7fe03cafc9d7e4fa60ddcb7c04b68a0e20a4b8912ee792417ec7d03ba3496b81c50600ab20cbe96766647cb01ddf314a07f11c590a0283af81d54659084c94c5de50154f109fccf259a08af0f9a3f4cc2a0418795313c377ac6fe910624a80c97c2c7e00ee09660fc2f0a97782af9856ff9a0ddeacc442d98146bdf1ab21eb9f2616e310baf330675ddf54048f3cc0372860ba0b787570bee5237a50991c2d4c5f97fec81a1269a2565c363b9538542c086d5b6a0508b4e32597bd3de6f682d9bcd31785585ab2c2880d6532f7eef87872473aa73a027b3ee9a3baa394e446e437f74054517ff84258ea9d7acfe790aeb5ecf585ccaa046cc03d1ee2ee491891f43dfed7c90e6250d53b012853d095c630c46221206d8a0f2b0c3c39d22ca62e0ddc30121e4616db7a4b50504486d6b3c5327853576df0ca0d1ce975b4bb2337a8a1c82c5ddadc150bb6ccba7006d6641cf662865245e35e7a06a3d2c5ea2f9b02452ce153cb10cb8c1ad1c16fbbf2b77eb89f022fe8f850746a03b2e472720e11235bc3ed475f96bdcb82eb7b2b90ae4c44d72568c6b66761397a003396a318468f7db7183cb71c04193c6e70b990d15d7560a6748e2b2e755152fa0f3ad9eaad7a6351c85aa13de3314018c2dfb82c12dfd5613468217f0bbe68747a06a56630feffe30a47a579bd6ada8eff2ab2a0299508107132b09e369bab3bacc80f90211a0e484c57f98d9dcb3981e79fec1fcdd4e9ade6b50a8763821faa52d6e9c40e515a09784bb9273fa7f29beefb8fe8c68dd148c164549aa1551cb8c69a4701af3d94ea064ddce91ada26c9916cd903f21c5b6008bf2a865ef9d3fc24bcd423bd02d9a93a0b4a7c85096f6d7016f1834bc01e1ed6c4314ebfbde73f80bce360a2f03e3cedfa053ecf424b86f3d97a054b057590cecb1e5e2878fb83d86cb7730b3dbecc4fd46a02d2bdccfe1586cd1692479a75d2b97a4d135e3dbab564ed3b6855113c62af598a07ab54330ecf7eb9e02720897d0380dc07eb2665892627451d174d1d87fdc2067a0d3d35f8b3ffa8c8c98cb34e89432b6157a148c4da14f868f97c9404d985850e0a07506b051d3f02f382730e2012e93b65addfccc9c962afbbbcdbd141b66c495daa0718f9d6c2bbf55d70c80a5decc2f49ed78026afc27de294dd28167f0e41786dfa072ae72e1a94cba48ff51cfc05f405af5931cebd85881e7767b4ea1884b87e4dea089d6433224364f6d40dd7d438ec7d1c924d70209ac8dbda89ccf5a39d1f031b3a0fe834ecb338a4b03a894fb36f2d0442ea48e6d0fccac2a45f0ea2e6abef6487fa0ce3c2a783bf9aff7764d32910d594a110f549367ee6b94d157ef949a2c33e65ca0f9f8490546b48f4dd548bef52d9fe8aa827d214940ce1842d139a94f341b611fa0d4b4fc09aaa8c6317c2060ef5ebaadc9bc211742296c8a80511b7ee0cd03417280f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea0c6c70650f6edd7057de9a8d7aeb5a52bc40dffb8a9cb71d55990a628f1596402a03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a09592d731bffb4d9b9ed4cf697f24f55ca7075c66a021aaa9f0ce119bea344411a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a0fa59d52ce31992709b7380abb4db6a33327763297b3c94791f348d886c7125faa08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a0253e402e9d5665c986423a2518d345b0c4d184d36562df4736dc28c3a51b60e2a05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a0dc34a817b1795244d58bb1b03cb361fbc68a3bb4a66ba3d891bfc0490d59115ca0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a08c81335ba79260e105491d1226e33dec334014016614983701be7b7fb10af9b7808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a2a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb2a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2a44ef0274e31810c9df02f98fafde0f841f4e66a1cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e32442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9132442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab032443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a324461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d2532447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e32448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193244ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3244d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3244ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e3a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e913a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a3a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d253a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e3a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3a44ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a9b4c0a9e060a9b06f90318a0d84001c3fe02cfe3947fd5cf493e52faf903c59ef8086dd0dc40a63b19ef28bca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ee226379db83cffc681495730c11fdde79ba4c0ca0bec86da42a2d6415c88cd1504b05eefebea6efeedd5f5a43ba75df9c3eb87d41a062f750ba0331e47ce3e954921894986b7c60a353bf09d9674f5ef242a85eace0a02905c9c64f2a92bd4046530305835f16ac3e9fa708f547cdb67a91b2358a0170b90100b62ce73bcc1c775ed99b1f569e58ac773e6deed4dad8b0aedcbff16fbfebf8379dc631f67cb370937f79739b7616a7bee9bb999a97127649daba387bfb7f2e8fc454db3b1d75d56855baefafb30eadbe2dbf5dfbd7778e2fb45ef859ec952e93cbef6bef9fceeffc7edfece4997aad2b0a5ddedb8b8f34d713c8c530fe32b74c5f9fffa59735cf5392dcf4b63fffcbdf5c7ebfb53f68ff9ab115f14bf5f3c5f6d7f3fdbc7a3e837e6315edefbf8f7eeedf3e1a910e8fe1cd14fb70e6e36ac8fe6ff5f7eeef360a77bff3cbc7fddbf3f4f2bde59fb8ac695cad95d7c297e1f5efdef88ab1bb8cd93e3d5fb7f2e5347b22ff6715735a7a7be98946bf9c6cb98b47028401e41da08408583b0084024be3d18465029f52b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5830dfbffb8608a3b143e1d38f79c92cf89bf07824a94b180bbdd3a6b3c53f66106b28a6b23b70056363b07f1b8477f1a6a04ae15bfec13ce0ffb235b6c8c109d7349dd6d27ac5d91a4ea1a5ff39ffe24543f04a708cb3ec3fca46499f9b4e7c08ef2075cc328f84c8401e41d9ea0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1c8401e41d9fa0d84001c3fe02cfe3947fd5cf493e52faf903c59ef8086dd0dc40a63b19ef28bc8095e738d00317cbaadffe6fd7b6eec1af9a10e2571d2ca59841f9698e229f1d2e4abb92f08e69a87cc9cfbaa6f3a8ff12c04cbb0c754f30b01971fbdff47b33bc00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080129e060a9b06f90318a0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da0a1a11bcdfaad405484b7144f7943d329a869b11413a7a24c0d3e453370c59a70a0e3097fdc2c40a54a53378f3ce53060f71191450bb1561277b6187e7e4590f0daa07658e85bd2a7be68c9c750b3813719b251508fbe45f61bce9bfe9fcc7e44437eb901000028020000001108010c00448040006001008000c800005000000102100000a086001000008200000120300609441000000a40220088540070000008002010400800040001000080010000b8800028b0201848088c00000000060400a410004040680220080e6000080000100980080a080000104002000000000010020004200008200000410001608004080008000800240601012000080000404010008030ea800121024410000100000002000000121010000010000428080020000488822210d4060000080120208002920021402002620408000014455051822a30c00800940000008108000100000240440101011000404008004800400221c2006008028401e41d9f8408583b008401b6a9878465029f4fb90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830dfbffb860a5a9f44fa8d83949c7aaf7e257fa1ea04cfc423039a71753105182f538fa18ac1daf35b7e5ba4e2fa43df65b6b8d738e0dfb905ef44572f99e1eca907bc2cf7dbeb3e901e0237d6120174d52d98c1c605383ffba7916e3f0a8a1d7f3be15b1c9f84c8401e41d9da0c9d8b6bd902571508497240a3458925bec4b24ae0d1f898537fbd168df9c017f8401e41d9ea0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1c80c35a9b87c279e7a13706fafd9beab70029f964f21273555079d045d284c9c96201060cfe1489c9a36864fe7bfbb2330b308eff7d697c3cb54c570d96feb132dd01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801a05109fbb900f22951df90e92f90211a09122e3c73eb8bbb2d72ef63422be51d25a3084914cc8294447eb8f0644b951f5a0cbea64d42ab8468a2b9575275c071a35d3429b72c13331a7567368892b167210a0dcea59e8d94af119e9fedfd1e68a4fd5cd7a6ca1ed0ec235e2fb6a47f044ac52a01d73a02e18acb6b4be57d108b8a9d4c30aa639f9b1a7450d783c06342e7a8206a09c81f45c2006dd1c34772c8a4f8e768bb79a6a833ca1f91742afda58e20e72c7a092932695f9848da612bb9d0d8150309baa94a449fdf9508c1166093916c5e0b2a01b926eb5c0975631309b161092d9a95071d3c94c081828c668c474b8034cec14a0446e005b9784eb3c1f6fe2dd6f1bd196b43ff26aca532689b527f0e8e26708bda097724ff2f732457e74603892c7b434ff814ffe57e21f0915de4e13eb5ad6bfb0a0838dff28471b5aab952fb32027ea88d8874ed011afca33480af7135f0d06b1e0a000d905c013e94122d152e473eefd0f11862b99f5956e3a25d8e98b21b1227d4aa03c956fe0a50adc5b8749be62498c2fbaa2c2b212996534821b0f7cdddd66326ca0f690b86ec62f1d85b3ceec425d469d96a66d6638e49a99d552e71cbcc068c301a08b4e33e6b1bdb0a3a2fcae944a1b80aea7be693fa55b2abd9023b10f44ee3770a093ef503da2a21ac403809298c4e98e6eb3154668ca37a0454b10a98087ae0145a091e9ecf6662afe71d0f3e89247651908dc1abcc4ef85f0ae7c564991ec45b57980f90211a0ceeda5be88f90fad85b5a6b5513ef1775d0870055ed3c5029e9606a4d98048b2a03f5051a53cf3e7a92a4606b62c3316bbc0f4ae882e48c03273d38670fa5b6702a0057a8aa90ea006d11c0a93e35607afa28fc2a7e9fdfd4179421bc077fda736f9a021d5c176c1f49f1680f8b43867187204c1d59d85917f295a2d3b7c5291098dd7a0fc7b13c3b70b9b055c385d37136b07665ed9916fc6b36e7b58164debbcea2164a053914c7686c58461cff5a695a18e9b362228a5c06ad3ba082fa9491ef3f5786aa067974c0e7a756a31a7faa30fcb46509c18204688f784b961982de93e710987c6a026fbd9f3f97befb931b748d0d3d3704810aa0e4372b9fd5de3c2556bc5260baca034f69a69c3a480cc0d8490eb5f9fe5af53820fb830a458469b620476277a1850a0ca492ec078d7054759c81d9efd9417e5b3dd3f8ad1a3017319144a9db227a236a0e85a6d33a17f6f288eee28e8a2b12b4aefcf5178156f371806161b02cc418e02a03484113f53b3608ea5cd038a1a677b80a5b822db3ca298c0c30d2460e5342088a01e45fd36175c706481580cb9dd29869cd6b441384d85b1a57275228dee58e395a094cefedc4d6104cdac931428f3f6ddc9d11c3a247335cadaa14b0e3a83dd6c4da0fdf0fbd1a508c0d7beafc876beedd36356ce94f43f7a0b3b220b9265129f1a78a0460ec673624faaa7cbd45b6e6bac157ee71258d1c7b3d4ec688234abc84d335280f90211a04b7dfc1e81ef33ac034638a356b57102725fd40f070367567c2f0d581099a168a09cea84ae3144fb5169a314960b36d0c17416307ebacc29c3af89b6c61a1e4cc5a05d22ab36da9cd2a9989a707ef8f32421f99f11eaded71706c2c924323ef46dc6a0bd3a7e671bc043465544d89f1b370f90d0411a73c3c3cc6b5d5cf4c2e52a8c3fa0718570eefa9ef447c4d722070b75504d2601df36d67e8c0caa082732bc9afd50a030986bc400b7f9aa4798468920379e814eea80cf4d49a2745ad7c91487dffa75a0f43b5f8bbdaa3f2c1707e0d034b65ba4fe6524eacfcc9c209981c03d5e3bb4eca0a14f05a9cef8721262d7d8c28cd653a77f312a99f7d9ff724b6d79de600938dca0d59c167f9b1edaeae1b2e3b84341ce785cd2ac30c49f4f745af4b743cdb80d01a0058581e9ca91afc6abc27096a932138f9690813c2e5e148712e90f8250ace030a09811053c5e3d1f12901d172e8553b4f271b3764e520aa9d22673e107f760e74da0929d67e133fda44ea5f0b2d64fab75493975b0db5441231f322980a153178f06a06fdedc79348485e21a939b50dac883a5489ab4d710178bee044d24c6284bc720a038c3e7024043ee8528ba003b1a86afb1437758e57311e9bb9ddde9f38108ff28a0531a5bcc1389e9eb84bcdd4ecaab8cf1589f7ccd27a324a25ff1804df226569ea06474a723ef6e3a767254e0df7666a521f65501a727e518bb0379b2e68b19310780f90211a0d5645bc2e0e0e7cdf3ab09356055ad366bc7fe03cafc9d7e4fa60ddcb7c04b68a0e20a4b8912ee792417ec7d03ba3496b81c50600ab20cbe96766647cb01ddf314a07f11c590a0283af81d54659084c94c5de50154f109fccf259a08af0f9a3f4cc2a0418795313c377ac6fe910624a80c97c2c7e00ee09660fc2f0a97782af9856ff9a0ddeacc442d98146bdf1ab21eb9f2616e310baf330675ddf54048f3cc0372860ba0b787570bee5237a50991c2d4c5f97fec81a1269a2565c363b9538542c086d5b6a0508b4e32597bd3de6f682d9bcd31785585ab2c2880d6532f7eef87872473aa73a027b3ee9a3baa394e446e437f74054517ff84258ea9d7acfe790aeb5ecf585ccaa046cc03d1ee2ee491891f43dfed7c90e6250d53b012853d095c630c46221206d8a0f2b0c3c39d22ca62e0ddc30121e4616db7a4b50504486d6b3c5327853576df0ca0d1ce975b4bb2337a8a1c82c5ddadc150bb6ccba7006d6641cf662865245e35e7a06a3d2c5ea2f9b02452ce153cb10cb8c1ad1c16fbbf2b77eb89f022fe8f850746a03b2e472720e11235bc3ed475f96bdcb82eb7b2b90ae4c44d72568c6b66761397a003396a318468f7db7183cb71c04193c6e70b990d15d7560a6748e2b2e755152fa0f3ad9eaad7a6351c85aa13de3314018c2dfb82c12dfd5613468217f0bbe68747a06a56630feffe30a47a579bd6ada8eff2ab2a0299508107132b09e369bab3bacc80f90211a0e484c57f98d9dcb3981e79fec1fcdd4e9ade6b50a8763821faa52d6e9c40e515a09784bb9273fa7f29beefb8fe8c68dd148c164549aa1551cb8c69a4701af3d94ea064ddce91ada26c9916cd903f21c5b6008bf2a865ef9d3fc24bcd423bd02d9a93a0b4a7c85096f6d7016f1834bc01e1ed6c4314ebfbde73f80bce360a2f03e3cedfa053ecf424b86f3d97a054b057590cecb1e5e2878fb83d86cb7730b3dbecc4fd46a02d2bdccfe1586cd1692479a75d2b97a4d135e3dbab564ed3b6855113c62af598a07ab54330ecf7eb9e02720897d0380dc07eb2665892627451d174d1d87fdc2067a0d3d35f8b3ffa8c8c98cb34e89432b6157a148c4da14f868f97c9404d985850e0a07506b051d3f02f382730e2012e93b65addfccc9c962afbbbcdbd141b66c495daa0718f9d6c2bbf55d70c80a5decc2f49ed78026afc27de294dd28167f0e41786dfa072ae72e1a94cba48ff51cfc05f405af5931cebd85881e7767b4ea1884b87e4dea089d6433224364f6d40dd7d438ec7d1c924d70209ac8dbda89ccf5a39d1f031b3a0fe834ecb338a4b03a894fb36f2d0442ea48e6d0fccac2a45f0ea2e6abef6487fa0ce3c2a783bf9aff7764d32910d594a110f549367ee6b94d157ef949a2c33e65ca0f9f8490546b48f4dd548bef52d9fe8aa827d214940ce1842d139a94f341b611fa0d4b4fc09aaa8c6317c2060ef5ebaadc9bc211742296c8a80511b7ee0cd03417280f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea0c6c70650f6edd7057de9a8d7aeb5a52bc40dffb8a9cb71d55990a628f1596402a03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a09592d731bffb4d9b9ed4cf697f24f55ca7075c66a021aaa9f0ce119bea344411a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a0fa59d52ce31992709b7380abb4db6a33327763297b3c94791f348d886c7125faa08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a0253e402e9d5665c986423a2518d345b0c4d184d36562df4736dc28c3a51b60e2a05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a0dc34a817b1795244d58bb1b03cb361fbc68a3bb4a66ba3d891bfc0490d59115ca0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a08c81335ba79260e105491d1226e33dec334014016614983701be7b7fb10af9b7808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a2a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb2a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2a44ef0274e31810c9df02f98fafde0f841f4e66a1cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e32442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9132442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab032443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a324461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d2532447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e32448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193244ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3244d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3244ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e3a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e913a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a3a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d253a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e3a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3a44ef0274e31810c9df02f98fafde0f841f4e66a1cd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").to_vec(); + let mut any= hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212b5a4010a0b78782d7061726c69612d311291520a9d060a9a06f90317a041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a78a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347947ae2f5b9e386cd1b50a4550696d957cb4900f03aa0699e5d1062b3cc121615d76c789410c104963e2fcb71646e3aef1ff669ee402da0b55b8d8cdfd97530ae6cd33edcd0d8b5c44aed45a1d6939096c696daf82383afa062349a2e448156e75ec722c3509a0ddde9e005769a8b39ec31f1401851d8e064b901004ca0863002021050660b40569000820632040400071906084842010019000040c0495010189d9441220310408a8271b28ee9a00a88820002882010130a2c7a0224c2802905c00040490380a98134442c6010630303472b0130040007c000c000ca78a2234a422033c449483083000ae0085898c410101da500009034c3420894200d484207194cc900a804804048048870362e8718408d78a10048c6594213223290098256916010066280c92fc01588058e01500a218884b246086221256041134a44367888600205040be4080c7001e1d0670359680a94c11252428406a70406b042038140a0100b16020105830714c0840f42ce30444c92424d1844a5511c028401eab44e84085832a78374da3384651671d8b90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5831deffbb8608b6a581ec2131635027452caef129afd38538a7d5de1c2d2f827b5912eeeebe5ca585f526352798430754a439fe42b36033b36e03140ec017fbec371767c80a77a09316b432259194beeff5d3a8e93c248d71bb9a9f1a971c5be97168c2f46e0f84c8401eab44ca0cc813e16286b6b88dd50c14a2d68d7073cca66f268e4e074e1bce40f5eb3dfa28401eab44da041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a78802f408ab187bcbc4388d26109bc310b87d4a9712b9a71d7afb87ba7ed70f4701963f6a8decab64265d4614522aef74caa46e7e7ac949700c51353a4dfdc996ed300a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9e060a9b06f90318a025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a0ed22f051199516596a15853a4d455810da5ed5e528d1b8cfeb65398ea1f7589da0ad43e4dae7d3bdccb6a0e1a8b9424338d79faf193341a6a48054124872284671a0182840d2f24efd8b7584dbdce1abb23fb5c707ad76cbbcb87877a5e470cbc219b9010099fa964de84c745a283cc54c979c1c7ad9a06bf28f08eea7e813b9029ecc7d0de62e3edc4ad48007032528fb95feb3e688435c1cb7a0f7f0fba6b076716de6c495618fce19f0061a11a3edeca35079bdfff1778947562ec6e5161459b2c36844cfefb97feb16ee0ae16f03b1a3dd0f29084e08c1804e04683228eeddcb7e899ac8de9080dabb436b9cfaa7849ade8cec3e2c9e2569d1cfdf6d553bca0cc3bce33393685527bf83652c0cf1cc9f8e92b130413fac20ca4c8d52fe18a025daabc9faa75e0b15760dcf5ae25d87875ad23565dbc705f140293d471254f6b42ef64d73b1eb2c9feef3c0836bc6e323a425f53abc482c3bf0d87af103159ec8e944c8028401eab44f8408583b0084015691dd84651671dbb90118d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5831deffbb860a8b8a61feb9a56b32ea88c840cca849231ff63218438baacba2d869ae8c82ceda4c840b7ade4c54163a88bf03d6d4bfa16ecdc3e3035134272a0a1736fca3cd77cab8be8e7422ad08ee64d32f1c5db2bac4b3b5b20524a529dba11524437e2fcf84c8401eab44da041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a788401eab44ea025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5d80e49dbc6f6272f92948075f099052215916bf4de4b20f04132ab76e06b367a20a638124754fcb83e2f7d3e7ef7f7064f1f286d6e784755f447feabfc5e18e132701a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800ab2110aaf11f908aca0e2ad1bb270035fc33be7fc17b2013212009c67d23c4f9dc3bac786556514d9c4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949f8ccdafcc39f3c7d6ebf637c9151673cbc36b88a0737846183f791474fb7ad30d3f3f7735af4a0fd26a71cdbc183850257ce4ba80a01865e4b9cc291244c26629a56ffe5c0c3a86a422b9477b9e56636a13283ab3aca056088018f37773ed36357fd4d0aad8d523499f31cb21bd6b719101b8ea1cfc3eb9010042e6aa0c0562542a0059a2d796bf4ea2e72f6c890a4300621f3801a4ee2810109e05bb225000d607903a16ba325f03a2ae584a18040e624020a27592b429f38a5d4044e02755082fc353623fbf34c4f42c95890905746a04ef3c1100c5a50ba944a8fa38ca1280ef48490e90216a1c690c4820d316f2842844018419641406d39f4be06c034a0c1985ba3471187cc88d06b454a5016c150c197554e0011454241b90047a3239e838427e58c43e8e090869120890e9809e8f30aa12ab6d0d2848492516424c0548c4072240871b065280e3c0a7003929a0d5091149328265a12018f5ca250a14c1884b3092c7261053142152840088a0255a98223813aaa31052028401eab45084084fe2c683941fb784651671deb906add98301020c846765746889676f312e31392e3133856c696e75780000b19df4a2150bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c816295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a61dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d25685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d35870f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba772b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a51733fda7714a05960b7536330be4dbb135bef0ed6b0245c33bc556cfeb013cd3643b30dbdef6df61a0be3ba00cae104b3c587083852e28f8911689c7033f7021a8a1774c98b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d78869485b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de7b4dd66d7c2c7e57f628210187192fb89d4b99dd4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cdcc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a419d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce739e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d21e9ae3261a475a27bb1028f140bc2a7c843318afd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5bef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0f8b5831deffbb86087568bd60dc7dfb4172eb13641307639ee36e21369683d5f3703df105cba9fee241d10140d5d9075d89e7835eced7f2b16059f0570b3e33274a47e2b02504e906c7571b771b9645c6a929461b638b37135013cf80a40eede3613d6d005710dc2f84c8401eab44ea025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5d8401eab44fa0e2ad1bb270035fc33be7fc17b2013212009c67d23c4f9dc3bac786556514d9c480debc35c33e3ea7a2879f41210c97f3270d878f131346db393bcb4f4ead70c3267814b40f985dc38c168506bcd868a0a4d5ee10d1fc3e4728f560e17e9cb06ef701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080120510cde8aa0f1a951df90e92f90211a048451379e031bcd60626af8421403d4d18b5b7bf8a64ccdd0fbcaa2171ac9597a0075d0ab91dda5f4dfaa0760c7acbedff68dcb5d158ecf4870296913b1b48ef6ca01659e308b7e29c43fd58db3ec01364edda041b830246df857ea1d0d9eeb8f5cda0c24b58adf81ee009c2510cd2e7c8dfca18413ca6470334ae656eaa416ac75139a004791497b2e3477a697ac00283ecb3a28eb9ad5b15478c271ca99fbe099c96cda019aba8266cb3affd6370a22094c23a724d19cb49606ba1f0deb1354b9d092fc9a0fa577e66c35f4e187a80293754a0ae304077932803520e574991d857841fd54ea00ee17ba839b4ef42b262244177074c64edf6573a900ee451356a1c53568e1697a0d6d3dfb4177f94f2a739fb25a9712bbc89104e99ddd1ccf174d70db5be6715bfa071a15ffb6f707e540655f7886249d74d0c278c5b6fd80f4c47169640d6d2b361a049ce6c2bc1872fbeec7d97de5545da2198b4f4a495c9fccd9d0fae26f55515cca02ddec8926f407b71c6addb27f2bfc99bc305c4cecd9f5b6b66c045b38b8bc538a01741ca8ef2f749f36002f6b77482e940b5a51c257b1332755f2ca4143911d3a7a005b8ee2ca4f1b73115c504b4571b9b2b02ea06813031989de6d275d27e5eebdaa0e471e10a98dfae9f331dcf52b2643d9bc0adcb723d958c16532f62a17583bc37a0e45b9f17b1a2d6da4cf2fa4d58e399b1c7a162819771602a428caabd0134e26780f90211a0c0793f10053ed2c41cfb1e7959fa9d7cced9aace666965cf7a573a459439471ea09a6c4d6061f23eed1a8e11acee27347d1b0419625211034df67a1889b0239a2fa0600b1a06017a4b6b4debdb47344fbe80ea84df61faad75d734e07d8d714cde6aa0b6725f8d33af74ba12cdf08e6fc58ae20704dd4882492dc281a251cd146a6f87a01dce17052d2f6e61d73506ae9a91844a19c58e7683b33915f6af567ebd2c38a8a0b845167d248fa7e47bb7d1ad2b57628c4d2123a23272111bf54da04ee2a74510a0fcb34c796b651b5a4020c097d8511341b5f5bb48e401e070f6a7d12256ffe2cfa077c1e22ffc4e2fbec0d5d43037257aa08c114ef60eb899aa9fe3b0941252833fa01408e6e82662d4f962f88429d3bb45e5d01a2c617c8d1d1fb75ea5059ea04e37a04eea53224ef719e89d96f6e28f0b30b134534cb1cbff564b794ddd51965d9c3ea0541a5041cbfd4498517b4a9eb780f9878cc1ee5c963411e8622dd1b9504b30cea0773b1f6d7b178250d1964040cefd0281d82f40c4a6536fcef01c26828b035c57a09c98f548a2978982ce49095f1c746570304e5d982c3b3f1b653b19ded79fb154a0a3ae58c75b4ae0e1c5ef01578828bbdcae8767456104d892053f7fbf76a2b9c9a05fe5f8e1652162490cc8fffa38f82f00b63fc86e38ccbb35481641aba0fa64bfa06f8b991df607ceaef21247f8535531cc0c12a04eaea11d08113da652e81de75c80f90211a0f896dd0a7a1c8218701f4c361a84fd6a07f4880118f4c63b4e2014dd9c9e1496a05889af7518058d3f8f1df7be08264cd6f53c67d5e6f5e3ce6e2a2962b6e03dafa010ff519911bf19bc43b28a0b9ed9fef5cc43f104c4892b5ee3f67865a4f537bfa083b07d2e20449a5605d58d88ad161d46153be60a52ce1353688cd2b877f983a9a0a350620df8df255fcb99d7d45da85158540f1fbc9525c68cd33431713b2a0752a00420b5733e9d4fba3b1ef4c9b7ee33dbe2d40818f66d4afc185d999d7022d376a0c7f8aa54645d635d425af7ec5c5412857d3b0c7901375c9b3dd0641c43b466bba0c5fa441716971965985dbb1c0f9c3cf5a519a2fa714524c167c31fee28506bc4a07d8da77127e270a9d5ee89f6f31f624229ae2753a5fa72d5616d5d27d056cd65a09aea1aa1c9363eacdc7e514c732a8b5f72d84d07547a07cad1c5ae357f10e437a095373e654bdec2ce20fbaaac26cf003eecad3d51b70151708d17122f3cdee26aa085830dc2d405e64c9ed8c427c2c2e98370f58873f3db7dba81d5125beb02da51a0b6a3a8b3abe15006dc8e25dde51f7aa30d958d0736d3baf1e0201276ffe6b7c7a0d883732a9e24b91ef30c4a066e31799d010d818d0c657af2e1b875c4aed8f6a1a06b92e79407e8c59592197ffdb77cfb0b8253a2f30febc4d6fd3247deb2cff568a0a74976f3c1568094513dc978e2a75f7aa05b4ca23271f312c6ff8d6b9e16fd0580f90211a039a1af4570c801d62fdfe4674f02510e117eae6330facc959df997fa8e4d6c0da0969897f77040974812fdc243499998d5a2f808b010e3e743fff5bb1cf06701b7a072a62f95c81d3849bc02102bcb66b5be775ad3b68cae7967451e6a13c48b6c43a0b76215fccceed3ae9731ccda9fedc68c32d509f70d88f78625d90a45999dae47a0b432a588f41a59491ec16126330cbe15a7e6aa261e05dda3d613dfee571cb9e0a03e55e7223adcd5dc7ba7a187a0443ce8110cb34ef616883fc3a33cf2cd06947ea0e62b04415ce8e7a5e17bddb2ab421a54c1095137c60127066ea495e56dcd26f6a010c1d3ed8e096233c3fa24d0e6604b2272497f25c388bf55cf1f2fbede09c424a020915f443baa11cfe88623086f95a4fec54633d2dd4788b4fe5aacb54e433be4a0d604d6e74ad8121336fa09e9672eee5239e757e03a0a7e006596479497832c0ba02a1bdf5679c646407f898eecb449053dd3f1b5ad7d104dee3d8d01674bafa747a07e4527336a6fe45d71c98c0274515d11279e5d8c0d21bee7c63e5ee1f23426e1a045f3cafdbd08257bee895fc3f4cd8c7db2dc04a430b8e33bed28e2d117010837a0fb219648890e649741ec78e85f4550de81839cc5a4ece0b98f868ae5ad92458aa0b2d85e9be8807bae98dfe9520d739703aa23eab1fe6764196844d4afad2a819ba00c1369efa246a68459c9465394abf698221c2f6c62c2c159ab5e89e7c16d2bae80f90211a011ff0a2d404fd7ed97509ebaa806f2a5ba09c5cde5ff596903c4313783487509a014931c578b05f5948939281aa31d2bc8b05b01c6932c45bf7a70972a430575c2a0d85789a4b9f2eec599bde9e5e9946fe9f7a613de910aebbd1bb681d718d422c8a092b17ad714173ec4787f0b3b9d2dfa96680861e093b5121441ffcde64183d074a0de881616657bd4c300116254ef39e2622f52faebe1b06b4fc9d3daed9dc76c06a07ce695737ab0d4bf9003a06ce83b11e75d81fbeb47c013b41f9c2e00a97cb87aa0dfe63771f833e98a5aeff54d9dd5a8dcfd89ca43c23644b18ec8e29ab8ccc287a0a327c817dc8a8ea3a5d3ca3cb55169777a1bfa30fe9f0df842eb3978dbd6737ba053683114bdaed7819b30ab8baec1fb9a2a96fee4dabc72f319cec9869da3b0b0a04d98297a896312d18da40240ed9a527f4c01c73edd3ea1f7c28338d1d863d97ca070451b5f2a402b497659eb18e648ac46f39c0068cc91436eb0b082b1d06dd63da066e866f800200512b0d3e534c547f4d2012429152cc9693bf1553cc22361627ba003fc4e648aafdadd7a9fa7cb534103f08dc699413ecda22bda46898bfb792429a0b46a167c66b50c74227d03a68971e124fdd011d6c90f5a08f6fe30ae34de603ca0a7ced66271235bc27b154f37bee6d9a1366cd253176c96de707d124fcc593c35a0f4f09b104a86cefc5c282d393b415e6c224eb8a463386448ebebfad9f9f53c9680f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea05dd8c13b1b83485911f5e1185669f7d5559c260193a72e52597a3e80736c248ca03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a0ebb2cbf0c3314ddf681f21a29fa17b320094684ba35e725bc36bbc407821cfa3a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a046c10b0c15aa83973ea4b108f50bad2638941550fce7c9308c8b968abee271f8a08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a04539a99793f29484fdbd39b606f27265499acb3c24461f48858655f07166f0dfa05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a05c170d685d29417781f678b746174c7500e7c228b4bd71bcfe9f5421742a0b67a0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a0a10cfa51ae290afebd64a5b530db7088fa0b02f22ce9b0838135b422b885dee5808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47022440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9122442a7cdd959bfe8d9487b2a43b33565295a698f7e200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab022443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a224470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba7224472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a5122447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e22448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d7886948522449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2244ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd02a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a4435ebb5849518aff370ca25e19e1072cc1a9fabcaa7f3e2c0b4b16ad183c473bafe30a36e39fa4a143657e229cd23c77f8fbc8e4e4e241695dd3d248d1e51521eee6619142a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a44685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d3582a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd075").to_vec(); + let any2= hex!("6e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd01a91520a9d060a9a06f90317a041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a78a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347947ae2f5b9e386cd1b50a4550696d957cb4900f03aa0699e5d1062b3cc121615d76c789410c104963e2fcb71646e3aef1ff669ee402da0b55b8d8cdfd97530ae6cd33edcd0d8b5c44aed45a1d6939096c696daf82383afa062349a2e448156e75ec722c3509a0ddde9e005769a8b39ec31f1401851d8e064b901004ca0863002021050660b40569000820632040400071906084842010019000040c0495010189d9441220310408a8271b28ee9a00a88820002882010130a2c7a0224c2802905c00040490380a98134442c6010630303472b0130040007c000c000ca78a2234a422033c449483083000ae0085898c410101da500009034c3420894200d484207194cc900a804804048048870362e8718408d78a10048c6594213223290098256916010066280c92fc01588058e01500a218884b246086221256041134a44367888600205040be4080c7001e1d0670359680a94c11252428406a70406b042038140a0100b16020105830714c0840f42ce30444c92424d1844a5511c028401eab44e84085832a78374da3384651671d8b90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5831deffbb8608b6a581ec2131635027452caef129afd38538a7d5de1c2d2f827b5912eeeebe5ca585f526352798430754a439fe42b36033b36e03140ec017fbec371767c80a77a09316b432259194beeff5d3a8e93c248d71bb9a9f1a971c5be97168c2f46e0f84c8401eab44ca0cc813e16286b6b88dd50c14a2d68d7073cca66f268e4e074e1bce40f5eb3dfa28401eab44da041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a78802f408ab187bcbc4388d26109bc310b87d4a9712b9a71d7afb87ba7ed70f4701963f6a8decab64265d4614522aef74caa46e7e7ac949700c51353a4dfdc996ed300a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9e060a9b06f90318a025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a0ed22f051199516596a15853a4d455810da5ed5e528d1b8cfeb65398ea1f7589da0ad43e4dae7d3bdccb6a0e1a8b9424338d79faf193341a6a48054124872284671a0182840d2f24efd8b7584dbdce1abb23fb5c707ad76cbbcb87877a5e470cbc219b9010099fa964de84c745a283cc54c979c1c7ad9a06bf28f08eea7e813b9029ecc7d0de62e3edc4ad48007032528fb95feb3e688435c1cb7a0f7f0fba6b076716de6c495618fce19f0061a11a3edeca35079bdfff1778947562ec6e5161459b2c36844cfefb97feb16ee0ae16f03b1a3dd0f29084e08c1804e04683228eeddcb7e899ac8de9080dabb436b9cfaa7849ade8cec3e2c9e2569d1cfdf6d553bca0cc3bce33393685527bf83652c0cf1cc9f8e92b130413fac20ca4c8d52fe18a025daabc9faa75e0b15760dcf5ae25d87875ad23565dbc705f140293d471254f6b42ef64d73b1eb2c9feef3c0836bc6e323a425f53abc482c3bf0d87af103159ec8e944c8028401eab44f8408583b0084015691dd84651671dbb90118d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5831deffbb860a8b8a61feb9a56b32ea88c840cca849231ff63218438baacba2d869ae8c82ceda4c840b7ade4c54163a88bf03d6d4bfa16ecdc3e3035134272a0a1736fca3cd77cab8be8e7422ad08ee64d32f1c5db2bac4b3b5b20524a529dba11524437e2fcf84c8401eab44da041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a788401eab44ea025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5d80e49dbc6f6272f92948075f099052215916bf4de4b20f04132ab76e06b367a20a638124754fcb83e2f7d3e7ef7f7064f1f286d6e784755f447feabfc5e18e132701a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800ab2110aaf11f908aca0e2ad1bb270035fc33be7fc17b2013212009c67d23c4f9dc3bac786556514d9c4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949f8ccdafcc39f3c7d6ebf637c9151673cbc36b88a0737846183f791474fb7ad30d3f3f7735af4a0fd26a71cdbc183850257ce4ba80a01865e4b9cc291244c26629a56ffe5c0c3a86a422b9477b9e56636a13283ab3aca056088018f37773ed36357fd4d0aad8d523499f31cb21bd6b719101b8ea1cfc3eb9010042e6aa0c0562542a0059a2d796bf4ea2e72f6c890a4300621f3801a4ee2810109e05bb225000d607903a16ba325f03a2ae584a18040e624020a27592b429f38a5d4044e02755082fc353623fbf34c4f42c95890905746a04ef3c1100c5a50ba944a8fa38ca1280ef48490e90216a1c690c4820d316f2842844018419641406d39f4be06c034a0c1985ba3471187cc88d06b454a5016c150c197554e0011454241b90047a3239e838427e58c43e8e090869120890e9809e8f30aa12ab6d0d2848492516424c0548c4072240871b065280e3c0a7003929a0d5091149328265a12018f5ca250a14c1884b3092c7261053142152840088a0255a98223813aaa31052028401eab45084084fe2c683941fb784651671deb906add98301020c846765746889676f312e31392e3133856c696e75780000b19df4a2150bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c816295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a61dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d25685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d35870f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba772b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a51733fda7714a05960b7536330be4dbb135bef0ed6b0245c33bc556cfeb013cd3643b30dbdef6df61a0be3ba00cae104b3c587083852e28f8911689c7033f7021a8a1774c98b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d78869485b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de7b4dd66d7c2c7e57f628210187192fb89d4b99dd4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cdcc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a419d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce739e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d21e9ae3261a475a27bb1028f140bc2a7c843318afd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5bef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0f8b5831deffbb86087568bd60dc7dfb4172eb13641307639ee36e21369683d5f3703df105cba9fee241d10140d5d9075d89e7835eced7f2b16059f0570b3e33274a47e2b02504e906c7571b771b9645c6a929461b638b37135013cf80a40eede3613d6d005710dc2f84c8401eab44ea025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5d8401eab44fa0e2ad1bb270035fc33be7fc17b2013212009c67d23c4f9dc3bac786556514d9c480debc35c33e3ea7a2879f41210c97f3270d878f131346db393bcb4f4ead70c3267814b40f985dc38c168506bcd868a0a4d5ee10d1fc3e4728f560e17e9cb06ef701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080120510cde8aa0f1a951df90e92f90211a048451379e031bcd60626af8421403d4d18b5b7bf8a64ccdd0fbcaa2171ac9597a0075d0ab91dda5f4dfaa0760c7acbedff68dcb5d158ecf4870296913b1b48ef6ca01659e308b7e29c43fd58db3ec01364edda041b830246df857ea1d0d9eeb8f5cda0c24b58adf81ee009c2510cd2e7c8dfca18413ca6470334ae656eaa416ac75139a004791497b2e3477a697ac00283ecb3a28eb9ad5b15478c271ca99fbe099c96cda019aba8266cb3affd6370a22094c23a724d19cb49606ba1f0deb1354b9d092fc9a0fa577e66c35f4e187a80293754a0ae304077932803520e574991d857841fd54ea00ee17ba839b4ef42b262244177074c64edf6573a900ee451356a1c53568e1697a0d6d3dfb4177f94f2a739fb25a9712bbc89104e99ddd1ccf174d70db5be6715bfa071a15ffb6f707e540655f7886249d74d0c278c5b6fd80f4c47169640d6d2b361a049ce6c2bc1872fbeec7d97de5545da2198b4f4a495c9fccd9d0fae26f55515cca02ddec8926f407b71c6addb27f2bfc99bc305c4cecd9f5b6b66c045b38b8bc538a01741ca8ef2f749f36002f6b77482e940b5a51c257b1332755f2ca4143911d3a7a005b8ee2ca4f1b73115c504b4571b9b2b02ea06813031989de6d275d27e5eebdaa0e471e10a98dfae9f331dcf52b2643d9bc0adcb723d958c16532f62a17583bc37a0e45b9f17b1a2d6da4cf2fa4d58e399b1c7a162819771602a428caabd0134e26780f90211a0c0793f10053ed2c41cfb1e7959fa9d7cced9aace666965cf7a573a459439471ea09a6c4d6061f23eed1a8e11acee27347d1b0419625211034df67a1889b0239a2fa0600b1a06017a4b6b4debdb47344fbe80ea84df61faad75d734e07d8d714cde6aa0b6725f8d33af74ba12cdf08e6fc58ae20704dd4882492dc281a251cd146a6f87a01dce17052d2f6e61d73506ae9a91844a19c58e7683b33915f6af567ebd2c38a8a0b845167d248fa7e47bb7d1ad2b57628c4d2123a23272111bf54da04ee2a74510a0fcb34c796b651b5a4020c097d8511341b5f5bb48e401e070f6a7d12256ffe2cfa077c1e22ffc4e2fbec0d5d43037257aa08c114ef60eb899aa9fe3b0941252833fa01408e6e82662d4f962f88429d3bb45e5d01a2c617c8d1d1fb75ea5059ea04e37a04eea53224ef719e89d96f6e28f0b30b134534cb1cbff564b794ddd51965d9c3ea0541a5041cbfd4498517b4a9eb780f9878cc1ee5c963411e8622dd1b9504b30cea0773b1f6d7b178250d1964040cefd0281d82f40c4a6536fcef01c26828b035c57a09c98f548a2978982ce49095f1c746570304e5d982c3b3f1b653b19ded79fb154a0a3ae58c75b4ae0e1c5ef01578828bbdcae8767456104d892053f7fbf76a2b9c9a05fe5f8e1652162490cc8fffa38f82f00b63fc86e38ccbb35481641aba0fa64bfa06f8b991df607ceaef21247f8535531cc0c12a04eaea11d08113da652e81de75c80f90211a0f896dd0a7a1c8218701f4c361a84fd6a07f4880118f4c63b4e2014dd9c9e1496a05889af7518058d3f8f1df7be08264cd6f53c67d5e6f5e3ce6e2a2962b6e03dafa010ff519911bf19bc43b28a0b9ed9fef5cc43f104c4892b5ee3f67865a4f537bfa083b07d2e20449a5605d58d88ad161d46153be60a52ce1353688cd2b877f983a9a0a350620df8df255fcb99d7d45da85158540f1fbc9525c68cd33431713b2a0752a00420b5733e9d4fba3b1ef4c9b7ee33dbe2d40818f66d4afc185d999d7022d376a0c7f8aa54645d635d425af7ec5c5412857d3b0c7901375c9b3dd0641c43b466bba0c5fa441716971965985dbb1c0f9c3cf5a519a2fa714524c167c31fee28506bc4a07d8da77127e270a9d5ee89f6f31f624229ae2753a5fa72d5616d5d27d056cd65a09aea1aa1c9363eacdc7e514c732a8b5f72d84d07547a07cad1c5ae357f10e437a095373e654bdec2ce20fbaaac26cf003eecad3d51b70151708d17122f3cdee26aa085830dc2d405e64c9ed8c427c2c2e98370f58873f3db7dba81d5125beb02da51a0b6a3a8b3abe15006dc8e25dde51f7aa30d958d0736d3baf1e0201276ffe6b7c7a0d883732a9e24b91ef30c4a066e31799d010d818d0c657af2e1b875c4aed8f6a1a06b92e79407e8c59592197ffdb77cfb0b8253a2f30febc4d6fd3247deb2cff568a0a74976f3c1568094513dc978e2a75f7aa05b4ca23271f312c6ff8d6b9e16fd0580f90211a039a1af4570c801d62fdfe4674f02510e117eae6330facc959df997fa8e4d6c0da0969897f77040974812fdc243499998d5a2f808b010e3e743fff5bb1cf06701b7a072a62f95c81d3849bc02102bcb66b5be775ad3b68cae7967451e6a13c48b6c43a0b76215fccceed3ae9731ccda9fedc68c32d509f70d88f78625d90a45999dae47a0b432a588f41a59491ec16126330cbe15a7e6aa261e05dda3d613dfee571cb9e0a03e55e7223adcd5dc7ba7a187a0443ce8110cb34ef616883fc3a33cf2cd06947ea0e62b04415ce8e7a5e17bddb2ab421a54c1095137c60127066ea495e56dcd26f6a010c1d3ed8e096233c3fa24d0e6604b2272497f25c388bf55cf1f2fbede09c424a020915f443baa11cfe88623086f95a4fec54633d2dd4788b4fe5aacb54e433be4a0d604d6e74ad8121336fa09e9672eee5239e757e03a0a7e006596479497832c0ba02a1bdf5679c646407f898eecb449053dd3f1b5ad7d104dee3d8d01674bafa747a07e4527336a6fe45d71c98c0274515d11279e5d8c0d21bee7c63e5ee1f23426e1a045f3cafdbd08257bee895fc3f4cd8c7db2dc04a430b8e33bed28e2d117010837a0fb219648890e649741ec78e85f4550de81839cc5a4ece0b98f868ae5ad92458aa0b2d85e9be8807bae98dfe9520d739703aa23eab1fe6764196844d4afad2a819ba00c1369efa246a68459c9465394abf698221c2f6c62c2c159ab5e89e7c16d2bae80f90211a011ff0a2d404fd7ed97509ebaa806f2a5ba09c5cde5ff596903c4313783487509a014931c578b05f5948939281aa31d2bc8b05b01c6932c45bf7a70972a430575c2a0d85789a4b9f2eec599bde9e5e9946fe9f7a613de910aebbd1bb681d718d422c8a092b17ad714173ec4787f0b3b9d2dfa96680861e093b5121441ffcde64183d074a0de881616657bd4c300116254ef39e2622f52faebe1b06b4fc9d3daed9dc76c06a07ce695737ab0d4bf9003a06ce83b11e75d81fbeb47c013b41f9c2e00a97cb87aa0dfe63771f833e98a5aeff54d9dd5a8dcfd89ca43c23644b18ec8e29ab8ccc287a0a327c817dc8a8ea3a5d3ca3cb55169777a1bfa30fe9f0df842eb3978dbd6737ba053683114bdaed7819b30ab8baec1fb9a2a96fee4dabc72f319cec9869da3b0b0a04d98297a896312d18da40240ed9a527f4c01c73edd3ea1f7c28338d1d863d97ca070451b5f2a402b497659eb18e648ac46f39c0068cc91436eb0b082b1d06dd63da066e866f800200512b0d3e534c547f4d2012429152cc9693bf1553cc22361627ba003fc4e648aafdadd7a9fa7cb534103f08dc699413ecda22bda46898bfb792429a0b46a167c66b50c74227d03a68971e124fdd011d6c90f5a08f6fe30ae34de603ca0a7ced66271235bc27b154f37bee6d9a1366cd253176c96de707d124fcc593c35a0f4f09b104a86cefc5c282d393b415e6c224eb8a463386448ebebfad9f9f53c9680f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea05dd8c13b1b83485911f5e1185669f7d5559c260193a72e52597a3e80736c248ca03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a0ebb2cbf0c3314ddf681f21a29fa17b320094684ba35e725bc36bbc407821cfa3a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a046c10b0c15aa83973ea4b108f50bad2638941550fce7c9308c8b968abee271f8a08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a04539a99793f29484fdbd39b606f27265499acb3c24461f48858655f07166f0dfa05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a05c170d685d29417781f678b746174c7500e7c228b4bd71bcfe9f5421742a0b67a0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a0a10cfa51ae290afebd64a5b530db7088fa0b02f22ce9b0838135b422b885dee5808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47022440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9122442a7cdd959bfe8d9487b2a43b33565295a698f7e200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab022443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a224470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba7224472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a5122447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e22448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d7886948522449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2244ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd02a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a4435ebb5849518aff370ca25e19e1072cc1a9fabcaa7f3e2c0b4b16ad183c473bafe30a36e39fa4a143657e229cd23c77f8fbc8e4e4e241695dd3d248d1e51521eee6619142a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a44685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d3582a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0").to_vec(); + any.extend(any2); let any: Any = any.try_into().unwrap(); let err = client .submit_misbehaviour(&ctx, client_id.clone(), any) .unwrap_err(); assert!( - format!("{:?}", err).contains("UnexpectedSameBlockHash : 0-31727008"), + format!("{:?}", err).contains("UnexpectedSameBlockHash : 0-32158798"), "{}", err ); @@ -827,19 +771,19 @@ mod test { let mut mock_consensus_state = BTreeMap::new(); let cs = ConsensusState { validators_hash: hex!( - "bc4b672cd2acd42f2ef5116aeac330817278836eaa97b412d4ab5d07451f77c5" + "021b6af8efa138e87fa1819cf173d7e06fec46cfdf88cfe96b73ce0e514b89af" ), ..Default::default() }; let prev_cs = ConsensusState { validators_hash: hex!( - "bc4b672cd2acd42f2ef5116aeac330817278836eaa97b412d4ab5d07451f77c5" + "2d1eb63e4be97ec3506ac5a847e875523bc2caa3d96158d3ca15fd9c554c6a00" ), ..Default::default() }; - mock_consensus_state.insert(Height::new(0, 31727007), trusted_cs); - mock_consensus_state.insert(Height::new(0, 31726800), cs); - mock_consensus_state.insert(Height::new(0, 31726600), prev_cs); + mock_consensus_state.insert(Height::new(0, 32158797), trusted_cs); + mock_consensus_state.insert(Height::new(0, 32158600), cs); + mock_consensus_state.insert(Height::new(0, 32158400), prev_cs); let ctx = MockClientReader { client_state: Some(ClientState { chain_id: mainnet(), @@ -848,13 +792,15 @@ mod test { consensus_state: mock_consensus_state, }; - let any = hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212c998010a0b78782d7061726c69612d31129b4c0a9e060a9b06f90318a0d84001c3fe02cfe3947fd5cf493e52faf903c59ef8086dd0dc40a63b19ef28bca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ee226379db83cffc681495730c11fdde79ba4c0ca0bec86da42a2d6415c88cd1504b05eefebea6efeedd5f5a43ba75df9c3eb87d41a062f750ba0331e47ce3e954921894986b7c60a353bf09d9674f5ef242a85eace0a02905c9c64f2a92bd4046530305835f16ac3e9fa708f547cdb67a91b2358a0170b90100b62ce73bcc1c775ed99b1f569e58ac773e6deed4dad8b0aedcbff16fbfebf8379dc631f67cb370937f79739b7616a7bee9bb999a97127649daba387bfb7f2e8fc454db3b1d75d56855baefafb30eadbe2dbf5dfbd7778e2fb45ef859ec952e93cbef6bef9fceeffc7edfece4997aad2b0a5ddedb8b8f34d713c8c530fe32b74c5f9fffa59735cf5392dcf4b63fffcbdf5c7ebfb53f68ff9ab115f14bf5f3c5f6d7f3fdbc7a3e837e6315edefbf8f7eeedf3e1a910e8fe1cd14fb70e6e36ac8fe6ff5f7eeef360a77bff3cbc7fddbf3f4f2bde59fb8ac695cad95d7c297e1f5efdef88ab1bb8cd93e3d5fb7f2e5347b22ff6715735a7a7be98946bf9c6cb98b47028401e41da08408583b0084024be3d18465029f52b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5830dfbffb8608a3b143e1d38f79c92cf89bf07824a94b180bbdd3a6b3c53f66106b28a6b23b70056363b07f1b8477f1a6a04ae15bfec13ce0ffb235b6c8c109d7349dd6d27ac5d91a4ea1a5ff39ffe24543f04a708cb3ec3fca46499f9b4e7c08ef2075cc328f84c8401e41d9ea0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1c8401e41d9fa0d84001c3fe02cfe3947fd5cf493e52faf903c59ef8086dd0dc40a63b19ef28bc8095e738d00317cbaadffe6fd7b6eec1af9a10e2571d2ca59841f9698e229f1d2e4abb92f08e69a87cc9cfbaa6f3a8ff12c04cbb0c754f30b01971fbdff47b33bc00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080129e060a9b06f90318a0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da0a1a11bcdfaad405484b7144f7943d329a869b11413a7a24c0d3e453370c59a70a0e3097fdc2c40a54a53378f3ce53060f71191450bb1561277b6187e7e4590f0daa07658e85bd2a7be68c9c750b3813719b251508fbe45f61bce9bfe9fcc7e44437eb901000028020000001108010c00448040006001008000c800005000000102100000a086001000008200000120300609441000000a40220088540070000008002010400800040001000080010000b8800028b0201848088c00000000060400a410004040680220080e6000080000100980080a080000104002000000000010020004200008200000410001608004080008000800240601012000080000404010008030ea800121024410000100000002000000121010000010000428080020000488822210d4060000080120208002920021402002620408000014455051822a30c00800940000008108000100000240440101011000404008004800400221c2006008028401e41d9f8408583b008401b6a9878465029f4fb90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830dfbffb860a5a9f44fa8d83949c7aaf7e257fa1ea04cfc423039a71753105182f538fa18ac1daf35b7e5ba4e2fa43df65b6b8d738e0dfb905ef44572f99e1eca907bc2cf7dbeb3e901e0237d6120174d52d98c1c605383ffba7916e3f0a8a1d7f3be15b1c9f84c8401e41d9da0c9d8b6bd902571508497240a3458925bec4b24ae0d1f898537fbd168df9c017f8401e41d9ea0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1c80c35a9b87c279e7a13706fafd9beab70029f964f21273555079d045d284c9c96201060cfe1489c9a36864fe7bfbb2330b308eff7d697c3cb54c570d96feb132dd01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801a05109fbb900f22951df90e92f90211a09122e3c73eb8bbb2d72ef63422be51d25a3084914cc8294447eb8f0644b951f5a0cbea64d42ab8468a2b9575275c071a35d3429b72c13331a7567368892b167210a0dcea59e8d94af119e9fedfd1e68a4fd5cd7a6ca1ed0ec235e2fb6a47f044ac52a01d73a02e18acb6b4be57d108b8a9d4c30aa639f9b1a7450d783c06342e7a8206a09c81f45c2006dd1c34772c8a4f8e768bb79a6a833ca1f91742afda58e20e72c7a092932695f9848da612bb9d0d8150309baa94a449fdf9508c1166093916c5e0b2a01b926eb5c0975631309b161092d9a95071d3c94c081828c668c474b8034cec14a0446e005b9784eb3c1f6fe2dd6f1bd196b43ff26aca532689b527f0e8e26708bda097724ff2f732457e74603892c7b434ff814ffe57e21f0915de4e13eb5ad6bfb0a0838dff28471b5aab952fb32027ea88d8874ed011afca33480af7135f0d06b1e0a000d905c013e94122d152e473eefd0f11862b99f5956e3a25d8e98b21b1227d4aa03c956fe0a50adc5b8749be62498c2fbaa2c2b212996534821b0f7cdddd66326ca0f690b86ec62f1d85b3ceec425d469d96a66d6638e49a99d552e71cbcc068c301a08b4e33e6b1bdb0a3a2fcae944a1b80aea7be693fa55b2abd9023b10f44ee3770a093ef503da2a21ac403809298c4e98e6eb3154668ca37a0454b10a98087ae0145a091e9ecf6662afe71d0f3e89247651908dc1abcc4ef85f0ae7c564991ec45b57980f90211a0ceeda5be88f90fad85b5a6b5513ef1775d0870055ed3c5029e9606a4d98048b2a03f5051a53cf3e7a92a4606b62c3316bbc0f4ae882e48c03273d38670fa5b6702a0057a8aa90ea006d11c0a93e35607afa28fc2a7e9fdfd4179421bc077fda736f9a021d5c176c1f49f1680f8b43867187204c1d59d85917f295a2d3b7c5291098dd7a0fc7b13c3b70b9b055c385d37136b07665ed9916fc6b36e7b58164debbcea2164a053914c7686c58461cff5a695a18e9b362228a5c06ad3ba082fa9491ef3f5786aa067974c0e7a756a31a7faa30fcb46509c18204688f784b961982de93e710987c6a026fbd9f3f97befb931b748d0d3d3704810aa0e4372b9fd5de3c2556bc5260baca034f69a69c3a480cc0d8490eb5f9fe5af53820fb830a458469b620476277a1850a0ca492ec078d7054759c81d9efd9417e5b3dd3f8ad1a3017319144a9db227a236a0e85a6d33a17f6f288eee28e8a2b12b4aefcf5178156f371806161b02cc418e02a03484113f53b3608ea5cd038a1a677b80a5b822db3ca298c0c30d2460e5342088a01e45fd36175c706481580cb9dd29869cd6b441384d85b1a57275228dee58e395a094cefedc4d6104cdac931428f3f6ddc9d11c3a247335cadaa14b0e3a83dd6c4da0fdf0fbd1a508c0d7beafc876beedd36356ce94f43f7a0b3b220b9265129f1a78a0460ec673624faaa7cbd45b6e6bac157ee71258d1c7b3d4ec688234abc84d335280f90211a04b7dfc1e81ef33ac034638a356b57102725fd40f070367567c2f0d581099a168a09cea84ae3144fb5169a314960b36d0c17416307ebacc29c3af89b6c61a1e4cc5a05d22ab36da9cd2a9989a707ef8f32421f99f11eaded71706c2c924323ef46dc6a0bd3a7e671bc043465544d89f1b370f90d0411a73c3c3cc6b5d5cf4c2e52a8c3fa0718570eefa9ef447c4d722070b75504d2601df36d67e8c0caa082732bc9afd50a030986bc400b7f9aa4798468920379e814eea80cf4d49a2745ad7c91487dffa75a0f43b5f8bbdaa3f2c1707e0d034b65ba4fe6524eacfcc9c209981c03d5e3bb4eca0a14f05a9cef8721262d7d8c28cd653a77f312a99f7d9ff724b6d79de600938dca0d59c167f9b1edaeae1b2e3b84341ce785cd2ac30c49f4f745af4b743cdb80d01a0058581e9ca91afc6abc27096a932138f9690813c2e5e148712e90f8250ace030a09811053c5e3d1f12901d172e8553b4f271b3764e520aa9d22673e107f760e74da0929d67e133fda44ea5f0b2d64fab75493975b0db5441231f322980a153178f06a06fdedc79348485e21a939b50dac883a5489ab4d710178bee044d24c6284bc720a038c3e7024043ee8528ba003b1a86afb1437758e57311e9bb9ddde9f38108ff28a0531a5bcc1389e9eb84bcdd4ecaab8cf1589f7ccd27a324a25ff1804df226569ea06474a723ef6e3a767254e0df7666a521f65501a727e518bb0379b2e68b19310780f90211a0d5645bc2e0e0e7cdf3ab09356055ad366bc7fe03cafc9d7e4fa60ddcb7c04b68a0e20a4b8912ee792417ec7d03ba3496b81c50600ab20cbe96766647cb01ddf314a07f11c590a0283af81d54659084c94c5de50154f109fccf259a08af0f9a3f4cc2a0418795313c377ac6fe910624a80c97c2c7e00ee09660fc2f0a97782af9856ff9a0ddeacc442d98146bdf1ab21eb9f2616e310baf330675ddf54048f3cc0372860ba0b787570bee5237a50991c2d4c5f97fec81a1269a2565c363b9538542c086d5b6a0508b4e32597bd3de6f682d9bcd31785585ab2c2880d6532f7eef87872473aa73a027b3ee9a3baa394e446e437f74054517ff84258ea9d7acfe790aeb5ecf585ccaa046cc03d1ee2ee491891f43dfed7c90e6250d53b012853d095c630c46221206d8a0f2b0c3c39d22ca62e0ddc30121e4616db7a4b50504486d6b3c5327853576df0ca0d1ce975b4bb2337a8a1c82c5ddadc150bb6ccba7006d6641cf662865245e35e7a06a3d2c5ea2f9b02452ce153cb10cb8c1ad1c16fbbf2b77eb89f022fe8f850746a03b2e472720e11235bc3ed475f96bdcb82eb7b2b90ae4c44d72568c6b66761397a003396a318468f7db7183cb71c04193c6e70b990d15d7560a6748e2b2e755152fa0f3ad9eaad7a6351c85aa13de3314018c2dfb82c12dfd5613468217f0bbe68747a06a56630feffe30a47a579bd6ada8eff2ab2a0299508107132b09e369bab3bacc80f90211a0e484c57f98d9dcb3981e79fec1fcdd4e9ade6b50a8763821faa52d6e9c40e515a09784bb9273fa7f29beefb8fe8c68dd148c164549aa1551cb8c69a4701af3d94ea064ddce91ada26c9916cd903f21c5b6008bf2a865ef9d3fc24bcd423bd02d9a93a0b4a7c85096f6d7016f1834bc01e1ed6c4314ebfbde73f80bce360a2f03e3cedfa053ecf424b86f3d97a054b057590cecb1e5e2878fb83d86cb7730b3dbecc4fd46a02d2bdccfe1586cd1692479a75d2b97a4d135e3dbab564ed3b6855113c62af598a07ab54330ecf7eb9e02720897d0380dc07eb2665892627451d174d1d87fdc2067a0d3d35f8b3ffa8c8c98cb34e89432b6157a148c4da14f868f97c9404d985850e0a07506b051d3f02f382730e2012e93b65addfccc9c962afbbbcdbd141b66c495daa0718f9d6c2bbf55d70c80a5decc2f49ed78026afc27de294dd28167f0e41786dfa072ae72e1a94cba48ff51cfc05f405af5931cebd85881e7767b4ea1884b87e4dea089d6433224364f6d40dd7d438ec7d1c924d70209ac8dbda89ccf5a39d1f031b3a0fe834ecb338a4b03a894fb36f2d0442ea48e6d0fccac2a45f0ea2e6abef6487fa0ce3c2a783bf9aff7764d32910d594a110f549367ee6b94d157ef949a2c33e65ca0f9f8490546b48f4dd548bef52d9fe8aa827d214940ce1842d139a94f341b611fa0d4b4fc09aaa8c6317c2060ef5ebaadc9bc211742296c8a80511b7ee0cd03417280f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea0c6c70650f6edd7057de9a8d7aeb5a52bc40dffb8a9cb71d55990a628f1596402a03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a09592d731bffb4d9b9ed4cf697f24f55ca7075c66a021aaa9f0ce119bea344411a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a0fa59d52ce31992709b7380abb4db6a33327763297b3c94791f348d886c7125faa08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a0253e402e9d5665c986423a2518d345b0c4d184d36562df4736dc28c3a51b60e2a05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a0dc34a817b1795244d58bb1b03cb361fbc68a3bb4a66ba3d891bfc0490d59115ca0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a08c81335ba79260e105491d1226e33dec334014016614983701be7b7fb10af9b7808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a2a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb2a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2a44ef0274e31810c9df02f98fafde0f841f4e66a1cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e32442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9132442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab032443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a324461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d2532447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e32448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193244ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3244d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3244ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e3a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e913a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a3a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d253a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e3a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3a44ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a9b4c0a9e060a9b06f90318a0d84001c3fe02cfe3947fd5cf493e52faf903c59ef8086dd0dc40a63b19ef28bca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ee226379db83cffc681495730c11fdde79ba4c0ca00000000000000000000000000000000000000000000000000000000000000000a062f750ba0331e47ce3e954921894986b7c60a353bf09d9674f5ef242a85eace0a02905c9c64f2a92bd4046530305835f16ac3e9fa708f547cdb67a91b2358a0170b90100b62ce73bcc1c775ed99b1f569e58ac773e6deed4dad8b0aedcbff16fbfebf8379dc631f67cb370937f79739b7616a7bee9bb999a97127649daba387bfb7f2e8fc454db3b1d75d56855baefafb30eadbe2dbf5dfbd7778e2fb45ef859ec952e93cbef6bef9fceeffc7edfece4997aad2b0a5ddedb8b8f34d713c8c530fe32b74c5f9fffa59735cf5392dcf4b63fffcbdf5c7ebfb53f68ff9ab115f14bf5f3c5f6d7f3fdbc7a3e837e6315edefbf8f7eeedf3e1a910e8fe1cd14fb70e6e36ac8fe6ff5f7eeef360a77bff3cbc7fddbf3f4f2bde59fb8ac695cad95d7c297e1f5efdef88ab1bb8cd93e3d5fb7f2e5347b22ff6715735a7a7be98946bf9c6cb98b47028401e41da08408583b0084024be3d18465029f52b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5830dfbffb8608a3b143e1d38f79c92cf89bf07824a94b180bbdd3a6b3c53f66106b28a6b23b70056363b07f1b8477f1a6a04ae15bfec13ce0ffb235b6c8c109d7349dd6d27ac5d91a4ea1a5ff39ffe24543f04a708cb3ec3fca46499f9b4e7c08ef2075cc328f84c8401e41d9ea0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1c8401e41d9fa0d84001c3fe02cfe3947fd5cf493e52faf903c59ef8086dd0dc40a63b19ef28bc8095e738d00317cbaadffe6fd7b6eec1af9a10e2571d2ca59841f9698e229f1d2e4abb92f08e69a87cc9cfbaa6f3a8ff12c04cbb0c754f30b01971fbdff47b33bc00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080129e060a9b06f90318a0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da0a1a11bcdfaad405484b7144f7943d329a869b11413a7a24c0d3e453370c59a70a0e3097fdc2c40a54a53378f3ce53060f71191450bb1561277b6187e7e4590f0daa07658e85bd2a7be68c9c750b3813719b251508fbe45f61bce9bfe9fcc7e44437eb901000028020000001108010c00448040006001008000c800005000000102100000a086001000008200000120300609441000000a40220088540070000008002010400800040001000080010000b8800028b0201848088c00000000060400a410004040680220080e6000080000100980080a080000104002000000000010020004200008200000410001608004080008000800240601012000080000404010008030ea800121024410000100000002000000121010000010000428080020000488822210d4060000080120208002920021402002620408000014455051822a30c00800940000008108000100000240440101011000404008004800400221c2006008028401e41d9f8408583b008401b6a9878465029f4fb90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830dfbffb860a5a9f44fa8d83949c7aaf7e257fa1ea04cfc423039a71753105182f538fa18ac1daf35b7e5ba4e2fa43df65b6b8d738e0dfb905ef44572f99e1eca907bc2cf7dbeb3e901e0237d6120174d52d98c1c605383ffba7916e3f0a8a1d7f3be15b1c9f84c8401e41d9da0c9d8b6bd902571508497240a3458925bec4b24ae0d1f898537fbd168df9c017f8401e41d9ea0531538d17c8aecd090eb20bd39fb66ba09576a528c110f7951498822f8b54a1c80c35a9b87c279e7a13706fafd9beab70029f964f21273555079d045d284c9c96201060cfe1489c9a36864fe7bfbb2330b308eff7d697c3cb54c570d96feb132dd01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801a05109fbb900f22951df90e92f90211a09122e3c73eb8bbb2d72ef63422be51d25a3084914cc8294447eb8f0644b951f5a0cbea64d42ab8468a2b9575275c071a35d3429b72c13331a7567368892b167210a0dcea59e8d94af119e9fedfd1e68a4fd5cd7a6ca1ed0ec235e2fb6a47f044ac52a01d73a02e18acb6b4be57d108b8a9d4c30aa639f9b1a7450d783c06342e7a8206a09c81f45c2006dd1c34772c8a4f8e768bb79a6a833ca1f91742afda58e20e72c7a092932695f9848da612bb9d0d8150309baa94a449fdf9508c1166093916c5e0b2a01b926eb5c0975631309b161092d9a95071d3c94c081828c668c474b8034cec14a0446e005b9784eb3c1f6fe2dd6f1bd196b43ff26aca532689b527f0e8e26708bda097724ff2f732457e74603892c7b434ff814ffe57e21f0915de4e13eb5ad6bfb0a0838dff28471b5aab952fb32027ea88d8874ed011afca33480af7135f0d06b1e0a000d905c013e94122d152e473eefd0f11862b99f5956e3a25d8e98b21b1227d4aa03c956fe0a50adc5b8749be62498c2fbaa2c2b212996534821b0f7cdddd66326ca0f690b86ec62f1d85b3ceec425d469d96a66d6638e49a99d552e71cbcc068c301a08b4e33e6b1bdb0a3a2fcae944a1b80aea7be693fa55b2abd9023b10f44ee3770a093ef503da2a21ac403809298c4e98e6eb3154668ca37a0454b10a98087ae0145a091e9ecf6662afe71d0f3e89247651908dc1abcc4ef85f0ae7c564991ec45b57980f90211a0ceeda5be88f90fad85b5a6b5513ef1775d0870055ed3c5029e9606a4d98048b2a03f5051a53cf3e7a92a4606b62c3316bbc0f4ae882e48c03273d38670fa5b6702a0057a8aa90ea006d11c0a93e35607afa28fc2a7e9fdfd4179421bc077fda736f9a021d5c176c1f49f1680f8b43867187204c1d59d85917f295a2d3b7c5291098dd7a0fc7b13c3b70b9b055c385d37136b07665ed9916fc6b36e7b58164debbcea2164a053914c7686c58461cff5a695a18e9b362228a5c06ad3ba082fa9491ef3f5786aa067974c0e7a756a31a7faa30fcb46509c18204688f784b961982de93e710987c6a026fbd9f3f97befb931b748d0d3d3704810aa0e4372b9fd5de3c2556bc5260baca034f69a69c3a480cc0d8490eb5f9fe5af53820fb830a458469b620476277a1850a0ca492ec078d7054759c81d9efd9417e5b3dd3f8ad1a3017319144a9db227a236a0e85a6d33a17f6f288eee28e8a2b12b4aefcf5178156f371806161b02cc418e02a03484113f53b3608ea5cd038a1a677b80a5b822db3ca298c0c30d2460e5342088a01e45fd36175c706481580cb9dd29869cd6b441384d85b1a57275228dee58e395a094cefedc4d6104cdac931428f3f6ddc9d11c3a247335cadaa14b0e3a83dd6c4da0fdf0fbd1a508c0d7beafc876beedd36356ce94f43f7a0b3b220b9265129f1a78a0460ec673624faaa7cbd45b6e6bac157ee71258d1c7b3d4ec688234abc84d335280f90211a04b7dfc1e81ef33ac034638a356b57102725fd40f070367567c2f0d581099a168a09cea84ae3144fb5169a314960b36d0c17416307ebacc29c3af89b6c61a1e4cc5a05d22ab36da9cd2a9989a707ef8f32421f99f11eaded71706c2c924323ef46dc6a0bd3a7e671bc043465544d89f1b370f90d0411a73c3c3cc6b5d5cf4c2e52a8c3fa0718570eefa9ef447c4d722070b75504d2601df36d67e8c0caa082732bc9afd50a030986bc400b7f9aa4798468920379e814eea80cf4d49a2745ad7c91487dffa75a0f43b5f8bbdaa3f2c1707e0d034b65ba4fe6524eacfcc9c209981c03d5e3bb4eca0a14f05a9cef8721262d7d8c28cd653a77f312a99f7d9ff724b6d79de600938dca0d59c167f9b1edaeae1b2e3b84341ce785cd2ac30c49f4f745af4b743cdb80d01a0058581e9ca91afc6abc27096a932138f9690813c2e5e148712e90f8250ace030a09811053c5e3d1f12901d172e8553b4f271b3764e520aa9d22673e107f760e74da0929d67e133fda44ea5f0b2d64fab75493975b0db5441231f322980a153178f06a06fdedc79348485e21a939b50dac883a5489ab4d710178bee044d24c6284bc720a038c3e7024043ee8528ba003b1a86afb1437758e57311e9bb9ddde9f38108ff28a0531a5bcc1389e9eb84bcdd4ecaab8cf1589f7ccd27a324a25ff1804df226569ea06474a723ef6e3a767254e0df7666a521f65501a727e518bb0379b2e68b19310780f90211a0d5645bc2e0e0e7cdf3ab09356055ad366bc7fe03cafc9d7e4fa60ddcb7c04b68a0e20a4b8912ee792417ec7d03ba3496b81c50600ab20cbe96766647cb01ddf314a07f11c590a0283af81d54659084c94c5de50154f109fccf259a08af0f9a3f4cc2a0418795313c377ac6fe910624a80c97c2c7e00ee09660fc2f0a97782af9856ff9a0ddeacc442d98146bdf1ab21eb9f2616e310baf330675ddf54048f3cc0372860ba0b787570bee5237a50991c2d4c5f97fec81a1269a2565c363b9538542c086d5b6a0508b4e32597bd3de6f682d9bcd31785585ab2c2880d6532f7eef87872473aa73a027b3ee9a3baa394e446e437f74054517ff84258ea9d7acfe790aeb5ecf585ccaa046cc03d1ee2ee491891f43dfed7c90e6250d53b012853d095c630c46221206d8a0f2b0c3c39d22ca62e0ddc30121e4616db7a4b50504486d6b3c5327853576df0ca0d1ce975b4bb2337a8a1c82c5ddadc150bb6ccba7006d6641cf662865245e35e7a06a3d2c5ea2f9b02452ce153cb10cb8c1ad1c16fbbf2b77eb89f022fe8f850746a03b2e472720e11235bc3ed475f96bdcb82eb7b2b90ae4c44d72568c6b66761397a003396a318468f7db7183cb71c04193c6e70b990d15d7560a6748e2b2e755152fa0f3ad9eaad7a6351c85aa13de3314018c2dfb82c12dfd5613468217f0bbe68747a06a56630feffe30a47a579bd6ada8eff2ab2a0299508107132b09e369bab3bacc80f90211a0e484c57f98d9dcb3981e79fec1fcdd4e9ade6b50a8763821faa52d6e9c40e515a09784bb9273fa7f29beefb8fe8c68dd148c164549aa1551cb8c69a4701af3d94ea064ddce91ada26c9916cd903f21c5b6008bf2a865ef9d3fc24bcd423bd02d9a93a0b4a7c85096f6d7016f1834bc01e1ed6c4314ebfbde73f80bce360a2f03e3cedfa053ecf424b86f3d97a054b057590cecb1e5e2878fb83d86cb7730b3dbecc4fd46a02d2bdccfe1586cd1692479a75d2b97a4d135e3dbab564ed3b6855113c62af598a07ab54330ecf7eb9e02720897d0380dc07eb2665892627451d174d1d87fdc2067a0d3d35f8b3ffa8c8c98cb34e89432b6157a148c4da14f868f97c9404d985850e0a07506b051d3f02f382730e2012e93b65addfccc9c962afbbbcdbd141b66c495daa0718f9d6c2bbf55d70c80a5decc2f49ed78026afc27de294dd28167f0e41786dfa072ae72e1a94cba48ff51cfc05f405af5931cebd85881e7767b4ea1884b87e4dea089d6433224364f6d40dd7d438ec7d1c924d70209ac8dbda89ccf5a39d1f031b3a0fe834ecb338a4b03a894fb36f2d0442ea48e6d0fccac2a45f0ea2e6abef6487fa0ce3c2a783bf9aff7764d32910d594a110f549367ee6b94d157ef949a2c33e65ca0f9f8490546b48f4dd548bef52d9fe8aa827d214940ce1842d139a94f341b611fa0d4b4fc09aaa8c6317c2060ef5ebaadc9bc211742296c8a80511b7ee0cd03417280f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea0c6c70650f6edd7057de9a8d7aeb5a52bc40dffb8a9cb71d55990a628f1596402a03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a09592d731bffb4d9b9ed4cf697f24f55ca7075c66a021aaa9f0ce119bea344411a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a0fa59d52ce31992709b7380abb4db6a33327763297b3c94791f348d886c7125faa08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a0253e402e9d5665c986423a2518d345b0c4d184d36562df4736dc28c3a51b60e2a05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a0dc34a817b1795244d58bb1b03cb361fbc68a3bb4a66ba3d891bfc0490d59115ca0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a08c81335ba79260e105491d1226e33dec334014016614983701be7b7fb10af9b7808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4702a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a2a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb2a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2a44ef0274e31810c9df02f98fafde0f841f4e66a1cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e32442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9132442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab032443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a324461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d2532447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e32448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193244ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3244d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3244ef0274e31810c9df02f98fafde0f841f4e66a1cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e3a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8163a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e913a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a3a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d253a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e3a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694853a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7413a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de73a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf93a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd3a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4193a44ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb3a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7393a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d213a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921833a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b3a44ef0274e31810c9df02f98fafde0f841f4e66a1cd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").to_vec(); + let mut any = hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212b5a4010a0b78782d7061726c69612d311291520a9d060a9a06f90317a041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a78a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347947ae2f5b9e386cd1b50a4550696d957cb4900f03aa0699e5d1062b3cc121615d76c789410c104963e2fcb71646e3aef1ff669ee402da0b55b8d8cdfd97530ae6cd33edcd0d8b5c44aed45a1d6939096c696daf82383afa062349a2e448156e75ec722c3509a0ddde9e005769a8b39ec31f1401851d8e064b901004ca0863002021050660b40569000820632040400071906084842010019000040c0495010189d9441220310408a8271b28ee9a00a88820002882010130a2c7a0224c2802905c00040490380a98134442c6010630303472b0130040007c000c000ca78a2234a422033c449483083000ae0085898c410101da500009034c3420894200d484207194cc900a804804048048870362e8718408d78a10048c6594213223290098256916010066280c92fc01588058e01500a218884b246086221256041134a44367888600205040be4080c7001e1d0670359680a94c11252428406a70406b042038140a0100b16020105830714c0840f42ce30444c92424d1844a5511c028401eab44e84085832a78374da3384651671d8b90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5831deffbb8608b6a581ec2131635027452caef129afd38538a7d5de1c2d2f827b5912eeeebe5ca585f526352798430754a439fe42b36033b36e03140ec017fbec371767c80a77a09316b432259194beeff5d3a8e93c248d71bb9a9f1a971c5be97168c2f46e0f84c8401eab44ca0cc813e16286b6b88dd50c14a2d68d7073cca66f268e4e074e1bce40f5eb3dfa28401eab44da041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a78802f408ab187bcbc4388d26109bc310b87d4a9712b9a71d7afb87ba7ed70f4701963f6a8decab64265d4614522aef74caa46e7e7ac949700c51353a4dfdc996ed300a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9e060a9b06f90318a025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a0ed22f051199516596a15853a4d455810da5ed5e528d1b8cfeb65398ea1f7589da0ad43e4dae7d3bdccb6a0e1a8b9424338d79faf193341a6a48054124872284671a0182840d2f24efd8b7584dbdce1abb23fb5c707ad76cbbcb87877a5e470cbc219b9010099fa964de84c745a283cc54c979c1c7ad9a06bf28f08eea7e813b9029ecc7d0de62e3edc4ad48007032528fb95feb3e688435c1cb7a0f7f0fba6b076716de6c495618fce19f0061a11a3edeca35079bdfff1778947562ec6e5161459b2c36844cfefb97feb16ee0ae16f03b1a3dd0f29084e08c1804e04683228eeddcb7e899ac8de9080dabb436b9cfaa7849ade8cec3e2c9e2569d1cfdf6d553bca0cc3bce33393685527bf83652c0cf1cc9f8e92b130413fac20ca4c8d52fe18a025daabc9faa75e0b15760dcf5ae25d87875ad23565dbc705f140293d471254f6b42ef64d73b1eb2c9feef3c0836bc6e323a425f53abc482c3bf0d87af103159ec8e944c8028401eab44f8408583b0084015691dd84651671dbb90118d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5831deffbb860a8b8a61feb9a56b32ea88c840cca849231ff63218438baacba2d869ae8c82ceda4c840b7ade4c54163a88bf03d6d4bfa16ecdc3e3035134272a0a1736fca3cd77cab8be8e7422ad08ee64d32f1c5db2bac4b3b5b20524a529dba11524437e2fcf84c8401eab44da041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a788401eab44ea025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5d80e49dbc6f6272f92948075f099052215916bf4de4b20f04132ab76e06b367a20a638124754fcb83e2f7d3e7ef7f7064f1f286d6e784755f447feabfc5e18e132701a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800ab2110aaf11f908aca0e2ad1bb270035fc33be7fc17b2013212009c67d23c4f9dc3bac786556514d9c4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949f8ccdafcc39f3c7d6ebf637c9151673cbc36b88a0737846183f791474fb7ad30d3f3f7735af4a0fd26a71cdbc183850257ce4ba80a01865e4b9cc291244c26629a56ffe5c0c3a86a422b9477b9e56636a13283ab3aca056088018f37773ed36357fd4d0aad8d523499f31cb21bd6b719101b8ea1cfc3eb9010042e6aa0c0562542a0059a2d796bf4ea2e72f6c890a4300621f3801a4ee2810109e05bb225000d607903a16ba325f03a2ae584a18040e624020a27592b429f38a5d4044e02755082fc353623fbf34c4f42c95890905746a04ef3c1100c5a50ba944a8fa38ca1280ef48490e90216a1c690c4820d316f2842844018419641406d39f4be06c034a0c1985ba3471187cc88d06b454a5016c150c197554e0011454241b90047a3239e838427e58c43e8e090869120890e9809e8f30aa12ab6d0d2848492516424c0548c4072240871b065280e3c0a7003929a0d5091149328265a12018f5ca250a14c1884b3092c7261053142152840088a0255a98223813aaa31052028401eab45084084fe2c683941fb784651671deb906add98301020c846765746889676f312e31392e3133856c696e75780000b19df4a2150bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c816295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a61dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d25685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d35870f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba772b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a51733fda7714a05960b7536330be4dbb135bef0ed6b0245c33bc556cfeb013cd3643b30dbdef6df61a0be3ba00cae104b3c587083852e28f8911689c7033f7021a8a1774c98b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d78869485b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de7b4dd66d7c2c7e57f628210187192fb89d4b99dd4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cdcc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a419d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce739e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d21e9ae3261a475a27bb1028f140bc2a7c843318afd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5bef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0f8b5831deffbb86087568bd60dc7dfb4172eb13641307639ee36e21369683d5f3703df105cba9fee241d10140d5d9075d89e7835eced7f2b16059f0570b3e33274a47e2b02504e906c7571b771b9645c6a929461b638b37135013cf80a40eede3613d6d005710dc2f84c8401eab44ea025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5d8401eab44fa0e2ad1bb270035fc33be7fc17b2013212009c67d23c4f9dc3bac786556514d9c480debc35c33e3ea7a2879f41210c97f3270d878f131346db393bcb4f4ead70c3267814b40f985dc38c168506bcd868a0a4d5ee10d1fc3e4728f560e17e9cb06ef701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080120510cde8aa0f1a951df90e92f90211a048451379e031bcd60626af8421403d4d18b5b7bf8a64ccdd0fbcaa2171ac9597a0075d0ab91dda5f4dfaa0760c7acbedff68dcb5d158ecf4870296913b1b48ef6ca01659e308b7e29c43fd58db3ec01364edda041b830246df857ea1d0d9eeb8f5cda0c24b58adf81ee009c2510cd2e7c8dfca18413ca6470334ae656eaa416ac75139a004791497b2e3477a697ac00283ecb3a28eb9ad5b15478c271ca99fbe099c96cda019aba8266cb3affd6370a22094c23a724d19cb49606ba1f0deb1354b9d092fc9a0fa577e66c35f4e187a80293754a0ae304077932803520e574991d857841fd54ea00ee17ba839b4ef42b262244177074c64edf6573a900ee451356a1c53568e1697a0d6d3dfb4177f94f2a739fb25a9712bbc89104e99ddd1ccf174d70db5be6715bfa071a15ffb6f707e540655f7886249d74d0c278c5b6fd80f4c47169640d6d2b361a049ce6c2bc1872fbeec7d97de5545da2198b4f4a495c9fccd9d0fae26f55515cca02ddec8926f407b71c6addb27f2bfc99bc305c4cecd9f5b6b66c045b38b8bc538a01741ca8ef2f749f36002f6b77482e940b5a51c257b1332755f2ca4143911d3a7a005b8ee2ca4f1b73115c504b4571b9b2b02ea06813031989de6d275d27e5eebdaa0e471e10a98dfae9f331dcf52b2643d9bc0adcb723d958c16532f62a17583bc37a0e45b9f17b1a2d6da4cf2fa4d58e399b1c7a162819771602a428caabd0134e26780f90211a0c0793f10053ed2c41cfb1e7959fa9d7cced9aace666965cf7a573a459439471ea09a6c4d6061f23eed1a8e11acee27347d1b0419625211034df67a1889b0239a2fa0600b1a06017a4b6b4debdb47344fbe80ea84df61faad75d734e07d8d714cde6aa0b6725f8d33af74ba12cdf08e6fc58ae20704dd4882492dc281a251cd146a6f87a01dce17052d2f6e61d73506ae9a91844a19c58e7683b33915f6af567ebd2c38a8a0b845167d248fa7e47bb7d1ad2b57628c4d2123a23272111bf54da04ee2a74510a0fcb34c796b651b5a4020c097d8511341b5f5bb48e401e070f6a7d12256ffe2cfa077c1e22ffc4e2fbec0d5d43037257aa08c114ef60eb899aa9fe3b0941252833fa01408e6e82662d4f962f88429d3bb45e5d01a2c617c8d1d1fb75ea5059ea04e37a04eea53224ef719e89d96f6e28f0b30b134534cb1cbff564b794ddd51965d9c3ea0541a5041cbfd4498517b4a9eb780f9878cc1ee5c963411e8622dd1b9504b30cea0773b1f6d7b178250d1964040cefd0281d82f40c4a6536fcef01c26828b035c57a09c98f548a2978982ce49095f1c746570304e5d982c3b3f1b653b19ded79fb154a0a3ae58c75b4ae0e1c5ef01578828bbdcae8767456104d892053f7fbf76a2b9c9a05fe5f8e1652162490cc8fffa38f82f00b63fc86e38ccbb35481641aba0fa64bfa06f8b991df607ceaef21247f8535531cc0c12a04eaea11d08113da652e81de75c80f90211a0f896dd0a7a1c8218701f4c361a84fd6a07f4880118f4c63b4e2014dd9c9e1496a05889af7518058d3f8f1df7be08264cd6f53c67d5e6f5e3ce6e2a2962b6e03dafa010ff519911bf19bc43b28a0b9ed9fef5cc43f104c4892b5ee3f67865a4f537bfa083b07d2e20449a5605d58d88ad161d46153be60a52ce1353688cd2b877f983a9a0a350620df8df255fcb99d7d45da85158540f1fbc9525c68cd33431713b2a0752a00420b5733e9d4fba3b1ef4c9b7ee33dbe2d40818f66d4afc185d999d7022d376a0c7f8aa54645d635d425af7ec5c5412857d3b0c7901375c9b3dd0641c43b466bba0c5fa441716971965985dbb1c0f9c3cf5a519a2fa714524c167c31fee28506bc4a07d8da77127e270a9d5ee89f6f31f624229ae2753a5fa72d5616d5d27d056cd65a09aea1aa1c9363eacdc7e514c732a8b5f72d84d07547a07cad1c5ae357f10e437a095373e654bdec2ce20fbaaac26cf003eecad3d51b70151708d17122f3cdee26aa085830dc2d405e64c9ed8c427c2c2e98370f58873f3db7dba81d5125beb02da51a0b6a3a8b3abe15006dc8e25dde51f7aa30d958d0736d3baf1e0201276ffe6b7c7a0d883732a9e24b91ef30c4a066e31799d010d818d0c657af2e1b875c4aed8f6a1a06b92e79407e8c59592197ffdb77cfb0b8253a2f30febc4d6fd3247deb2cff568a0a74976f3c1568094513dc978e2a75f7aa05b4ca23271f312c6ff8d6b9e16fd0580f90211a039a1af4570c801d62fdfe4674f02510e117eae6330facc959df997fa8e4d6c0da0969897f77040974812fdc243499998d5a2f808b010e3e743fff5bb1cf06701b7a072a62f95c81d3849bc02102bcb66b5be775ad3b68cae7967451e6a13c48b6c43a0b76215fccceed3ae9731ccda9fedc68c32d509f70d88f78625d90a45999dae47a0b432a588f41a59491ec16126330cbe15a7e6aa261e05dda3d613dfee571cb9e0a03e55e7223adcd5dc7ba7a187a0443ce8110cb34ef616883fc3a33cf2cd06947ea0e62b04415ce8e7a5e17bddb2ab421a54c1095137c60127066ea495e56dcd26f6a010c1d3ed8e096233c3fa24d0e6604b2272497f25c388bf55cf1f2fbede09c424a020915f443baa11cfe88623086f95a4fec54633d2dd4788b4fe5aacb54e433be4a0d604d6e74ad8121336fa09e9672eee5239e757e03a0a7e006596479497832c0ba02a1bdf5679c646407f898eecb449053dd3f1b5ad7d104dee3d8d01674bafa747a07e4527336a6fe45d71c98c0274515d11279e5d8c0d21bee7c63e5ee1f23426e1a045f3cafdbd08257bee895fc3f4cd8c7db2dc04a430b8e33bed28e2d117010837a0fb219648890e649741ec78e85f4550de81839cc5a4ece0b98f868ae5ad92458aa0b2d85e9be8807bae98dfe9520d739703aa23eab1fe6764196844d4afad2a819ba00c1369efa246a68459c9465394abf698221c2f6c62c2c159ab5e89e7c16d2bae80f90211a011ff0a2d404fd7ed97509ebaa806f2a5ba09c5cde5ff596903c4313783487509a014931c578b05f5948939281aa31d2bc8b05b01c6932c45bf7a70972a430575c2a0d85789a4b9f2eec599bde9e5e9946fe9f7a613de910aebbd1bb681d718d422c8a092b17ad714173ec4787f0b3b9d2dfa96680861e093b5121441ffcde64183d074a0de881616657bd4c300116254ef39e2622f52faebe1b06b4fc9d3daed9dc76c06a07ce695737ab0d4bf9003a06ce83b11e75d81fbeb47c013b41f9c2e00a97cb87aa0dfe63771f833e98a5aeff54d9dd5a8dcfd89ca43c23644b18ec8e29ab8ccc287a0a327c817dc8a8ea3a5d3ca3cb55169777a1bfa30fe9f0df842eb3978dbd6737ba053683114bdaed7819b30ab8baec1fb9a2a96fee4dabc72f319cec9869da3b0b0a04d98297a896312d18da40240ed9a527f4c01c73edd3ea1f7c28338d1d863d97ca070451b5f2a402b497659eb18e648ac46f39c0068cc91436eb0b082b1d06dd63da066e866f800200512b0d3e534c547f4d2012429152cc9693bf1553cc22361627ba003fc4e648aafdadd7a9fa7cb534103f08dc699413ecda22bda46898bfb792429a0b46a167c66b50c74227d03a68971e124fdd011d6c90f5a08f6fe30ae34de603ca0a7ced66271235bc27b154f37bee6d9a1366cd253176c96de707d124fcc593c35a0f4f09b104a86cefc5c282d393b415e6c224eb8a463386448ebebfad9f9f53c9680f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea05dd8c13b1b83485911f5e1185669f7d5559c260193a72e52597a3e80736c248ca03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a0ebb2cbf0c3314ddf681f21a29fa17b320094684ba35e725bc36bbc407821cfa3a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a046c10b0c15aa83973ea4b108f50bad2638941550fce7c9308c8b968abee271f8a08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a04539a99793f29484fdbd39b606f27265499acb3c24461f48858655f07166f0dfa05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a05c170d685d29417781f678b746174c7500e7c228b4bd71bcfe9f5421742a0b67a0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a0a10cfa51ae290afebd64a5b530db7088fa0b02f22ce9b0838135b422b885dee5808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47022440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9122442a7cdd959bfe8d9487b2a43b33565295a698f7e200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab022443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a224470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba7224472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a5122447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e22448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d7886948522449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2244ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd02a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a4435ebb5849518aff370ca25e19e1072cc1a9fabcaa7f3e2c0b4b16ad183c473bafe30a36e39fa4a143657e229cd23c77f8fbc8e4e4e241695dd3d248d1e51521eee6619142a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a44685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d3582a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd075").to_vec(); + let any2 = hex!("6e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd01a91520a9d060a9a06f90317a041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a78a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347947ae2f5b9e386cd1b50a4550696d957cb4900f03aa00000000000000000000000000000000000000000000000000000000000000000a0b55b8d8cdfd97530ae6cd33edcd0d8b5c44aed45a1d6939096c696daf82383afa062349a2e448156e75ec722c3509a0ddde9e005769a8b39ec31f1401851d8e064b901004ca0863002021050660b40569000820632040400071906084842010019000040c0495010189d9441220310408a8271b28ee9a00a88820002882010130a2c7a0224c2802905c00040490380a98134442c6010630303472b0130040007c000c000ca78a2234a422033c449483083000ae0085898c410101da500009034c3420894200d484207194cc900a804804048048870362e8718408d78a10048c6594213223290098256916010066280c92fc01588058e01500a218884b246086221256041134a44367888600205040be4080c7001e1d0670359680a94c11252428406a70406b042038140a0100b16020105830714c0840f42ce30444c92424d1844a5511c028401eab44e84085832a78374da3384651671d8b90118d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5831deffbb8608b6a581ec2131635027452caef129afd38538a7d5de1c2d2f827b5912eeeebe5ca585f526352798430754a439fe42b36033b36e03140ec017fbec371767c80a77a09316b432259194beeff5d3a8e93c248d71bb9a9f1a971c5be97168c2f46e0f84c8401eab44ca0cc813e16286b6b88dd50c14a2d68d7073cca66f268e4e074e1bce40f5eb3dfa28401eab44da041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a78802f408ab187bcbc4388d26109bc310b87d4a9712b9a71d7afb87ba7ed70f4701963f6a8decab64265d4614522aef74caa46e7e7ac949700c51353a4dfdc996ed300a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9e060a9b06f90318a025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a0ed22f051199516596a15853a4d455810da5ed5e528d1b8cfeb65398ea1f7589da0ad43e4dae7d3bdccb6a0e1a8b9424338d79faf193341a6a48054124872284671a0182840d2f24efd8b7584dbdce1abb23fb5c707ad76cbbcb87877a5e470cbc219b9010099fa964de84c745a283cc54c979c1c7ad9a06bf28f08eea7e813b9029ecc7d0de62e3edc4ad48007032528fb95feb3e688435c1cb7a0f7f0fba6b076716de6c495618fce19f0061a11a3edeca35079bdfff1778947562ec6e5161459b2c36844cfefb97feb16ee0ae16f03b1a3dd0f29084e08c1804e04683228eeddcb7e899ac8de9080dabb436b9cfaa7849ade8cec3e2c9e2569d1cfdf6d553bca0cc3bce33393685527bf83652c0cf1cc9f8e92b130413fac20ca4c8d52fe18a025daabc9faa75e0b15760dcf5ae25d87875ad23565dbc705f140293d471254f6b42ef64d73b1eb2c9feef3c0836bc6e323a425f53abc482c3bf0d87af103159ec8e944c8028401eab44f8408583b0084015691dd84651671dbb90118d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5831deffbb860a8b8a61feb9a56b32ea88c840cca849231ff63218438baacba2d869ae8c82ceda4c840b7ade4c54163a88bf03d6d4bfa16ecdc3e3035134272a0a1736fca3cd77cab8be8e7422ad08ee64d32f1c5db2bac4b3b5b20524a529dba11524437e2fcf84c8401eab44da041aed78504a8f7cd2c8a47080b48e3818649929a82a92e47c593268dd3ff8a788401eab44ea025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5d80e49dbc6f6272f92948075f099052215916bf4de4b20f04132ab76e06b367a20a638124754fcb83e2f7d3e7ef7f7064f1f286d6e784755f447feabfc5e18e132701a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800ab2110aaf11f908aca0e2ad1bb270035fc33be7fc17b2013212009c67d23c4f9dc3bac786556514d9c4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949f8ccdafcc39f3c7d6ebf637c9151673cbc36b88a0737846183f791474fb7ad30d3f3f7735af4a0fd26a71cdbc183850257ce4ba80a01865e4b9cc291244c26629a56ffe5c0c3a86a422b9477b9e56636a13283ab3aca056088018f37773ed36357fd4d0aad8d523499f31cb21bd6b719101b8ea1cfc3eb9010042e6aa0c0562542a0059a2d796bf4ea2e72f6c890a4300621f3801a4ee2810109e05bb225000d607903a16ba325f03a2ae584a18040e624020a27592b429f38a5d4044e02755082fc353623fbf34c4f42c95890905746a04ef3c1100c5a50ba944a8fa38ca1280ef48490e90216a1c690c4820d316f2842844018419641406d39f4be06c034a0c1985ba3471187cc88d06b454a5016c150c197554e0011454241b90047a3239e838427e58c43e8e090869120890e9809e8f30aa12ab6d0d2848492516424c0548c4072240871b065280e3c0a7003929a0d5091149328265a12018f5ca250a14c1884b3092c7261053142152840088a0255a98223813aaa31052028401eab45084084fe2c683941fb784651671deb906add98301020c846765746889676f312e31392e3133856c696e75780000b19df4a2150bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c816295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a61dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d25685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d35870f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba772b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a51733fda7714a05960b7536330be4dbb135bef0ed6b0245c33bc556cfeb013cd3643b30dbdef6df61a0be3ba00cae104b3c587083852e28f8911689c7033f7021a8a1774c98b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d78869485b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de7b4dd66d7c2c7e57f628210187192fb89d4b99dd4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cdcc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a419d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce739e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d21e9ae3261a475a27bb1028f140bc2a7c843318afd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5bef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0f8b5831deffbb86087568bd60dc7dfb4172eb13641307639ee36e21369683d5f3703df105cba9fee241d10140d5d9075d89e7835eced7f2b16059f0570b3e33274a47e2b02504e906c7571b771b9645c6a929461b638b37135013cf80a40eede3613d6d005710dc2f84c8401eab44ea025d5dc6c7dcf1bf968de16eace6951e0089b2d116a9c6bbabec5e137bb6bfa5d8401eab44fa0e2ad1bb270035fc33be7fc17b2013212009c67d23c4f9dc3bac786556514d9c480debc35c33e3ea7a2879f41210c97f3270d878f131346db393bcb4f4ead70c3267814b40f985dc38c168506bcd868a0a4d5ee10d1fc3e4728f560e17e9cb06ef701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080120510cde8aa0f1a951df90e92f90211a048451379e031bcd60626af8421403d4d18b5b7bf8a64ccdd0fbcaa2171ac9597a0075d0ab91dda5f4dfaa0760c7acbedff68dcb5d158ecf4870296913b1b48ef6ca01659e308b7e29c43fd58db3ec01364edda041b830246df857ea1d0d9eeb8f5cda0c24b58adf81ee009c2510cd2e7c8dfca18413ca6470334ae656eaa416ac75139a004791497b2e3477a697ac00283ecb3a28eb9ad5b15478c271ca99fbe099c96cda019aba8266cb3affd6370a22094c23a724d19cb49606ba1f0deb1354b9d092fc9a0fa577e66c35f4e187a80293754a0ae304077932803520e574991d857841fd54ea00ee17ba839b4ef42b262244177074c64edf6573a900ee451356a1c53568e1697a0d6d3dfb4177f94f2a739fb25a9712bbc89104e99ddd1ccf174d70db5be6715bfa071a15ffb6f707e540655f7886249d74d0c278c5b6fd80f4c47169640d6d2b361a049ce6c2bc1872fbeec7d97de5545da2198b4f4a495c9fccd9d0fae26f55515cca02ddec8926f407b71c6addb27f2bfc99bc305c4cecd9f5b6b66c045b38b8bc538a01741ca8ef2f749f36002f6b77482e940b5a51c257b1332755f2ca4143911d3a7a005b8ee2ca4f1b73115c504b4571b9b2b02ea06813031989de6d275d27e5eebdaa0e471e10a98dfae9f331dcf52b2643d9bc0adcb723d958c16532f62a17583bc37a0e45b9f17b1a2d6da4cf2fa4d58e399b1c7a162819771602a428caabd0134e26780f90211a0c0793f10053ed2c41cfb1e7959fa9d7cced9aace666965cf7a573a459439471ea09a6c4d6061f23eed1a8e11acee27347d1b0419625211034df67a1889b0239a2fa0600b1a06017a4b6b4debdb47344fbe80ea84df61faad75d734e07d8d714cde6aa0b6725f8d33af74ba12cdf08e6fc58ae20704dd4882492dc281a251cd146a6f87a01dce17052d2f6e61d73506ae9a91844a19c58e7683b33915f6af567ebd2c38a8a0b845167d248fa7e47bb7d1ad2b57628c4d2123a23272111bf54da04ee2a74510a0fcb34c796b651b5a4020c097d8511341b5f5bb48e401e070f6a7d12256ffe2cfa077c1e22ffc4e2fbec0d5d43037257aa08c114ef60eb899aa9fe3b0941252833fa01408e6e82662d4f962f88429d3bb45e5d01a2c617c8d1d1fb75ea5059ea04e37a04eea53224ef719e89d96f6e28f0b30b134534cb1cbff564b794ddd51965d9c3ea0541a5041cbfd4498517b4a9eb780f9878cc1ee5c963411e8622dd1b9504b30cea0773b1f6d7b178250d1964040cefd0281d82f40c4a6536fcef01c26828b035c57a09c98f548a2978982ce49095f1c746570304e5d982c3b3f1b653b19ded79fb154a0a3ae58c75b4ae0e1c5ef01578828bbdcae8767456104d892053f7fbf76a2b9c9a05fe5f8e1652162490cc8fffa38f82f00b63fc86e38ccbb35481641aba0fa64bfa06f8b991df607ceaef21247f8535531cc0c12a04eaea11d08113da652e81de75c80f90211a0f896dd0a7a1c8218701f4c361a84fd6a07f4880118f4c63b4e2014dd9c9e1496a05889af7518058d3f8f1df7be08264cd6f53c67d5e6f5e3ce6e2a2962b6e03dafa010ff519911bf19bc43b28a0b9ed9fef5cc43f104c4892b5ee3f67865a4f537bfa083b07d2e20449a5605d58d88ad161d46153be60a52ce1353688cd2b877f983a9a0a350620df8df255fcb99d7d45da85158540f1fbc9525c68cd33431713b2a0752a00420b5733e9d4fba3b1ef4c9b7ee33dbe2d40818f66d4afc185d999d7022d376a0c7f8aa54645d635d425af7ec5c5412857d3b0c7901375c9b3dd0641c43b466bba0c5fa441716971965985dbb1c0f9c3cf5a519a2fa714524c167c31fee28506bc4a07d8da77127e270a9d5ee89f6f31f624229ae2753a5fa72d5616d5d27d056cd65a09aea1aa1c9363eacdc7e514c732a8b5f72d84d07547a07cad1c5ae357f10e437a095373e654bdec2ce20fbaaac26cf003eecad3d51b70151708d17122f3cdee26aa085830dc2d405e64c9ed8c427c2c2e98370f58873f3db7dba81d5125beb02da51a0b6a3a8b3abe15006dc8e25dde51f7aa30d958d0736d3baf1e0201276ffe6b7c7a0d883732a9e24b91ef30c4a066e31799d010d818d0c657af2e1b875c4aed8f6a1a06b92e79407e8c59592197ffdb77cfb0b8253a2f30febc4d6fd3247deb2cff568a0a74976f3c1568094513dc978e2a75f7aa05b4ca23271f312c6ff8d6b9e16fd0580f90211a039a1af4570c801d62fdfe4674f02510e117eae6330facc959df997fa8e4d6c0da0969897f77040974812fdc243499998d5a2f808b010e3e743fff5bb1cf06701b7a072a62f95c81d3849bc02102bcb66b5be775ad3b68cae7967451e6a13c48b6c43a0b76215fccceed3ae9731ccda9fedc68c32d509f70d88f78625d90a45999dae47a0b432a588f41a59491ec16126330cbe15a7e6aa261e05dda3d613dfee571cb9e0a03e55e7223adcd5dc7ba7a187a0443ce8110cb34ef616883fc3a33cf2cd06947ea0e62b04415ce8e7a5e17bddb2ab421a54c1095137c60127066ea495e56dcd26f6a010c1d3ed8e096233c3fa24d0e6604b2272497f25c388bf55cf1f2fbede09c424a020915f443baa11cfe88623086f95a4fec54633d2dd4788b4fe5aacb54e433be4a0d604d6e74ad8121336fa09e9672eee5239e757e03a0a7e006596479497832c0ba02a1bdf5679c646407f898eecb449053dd3f1b5ad7d104dee3d8d01674bafa747a07e4527336a6fe45d71c98c0274515d11279e5d8c0d21bee7c63e5ee1f23426e1a045f3cafdbd08257bee895fc3f4cd8c7db2dc04a430b8e33bed28e2d117010837a0fb219648890e649741ec78e85f4550de81839cc5a4ece0b98f868ae5ad92458aa0b2d85e9be8807bae98dfe9520d739703aa23eab1fe6764196844d4afad2a819ba00c1369efa246a68459c9465394abf698221c2f6c62c2c159ab5e89e7c16d2bae80f90211a011ff0a2d404fd7ed97509ebaa806f2a5ba09c5cde5ff596903c4313783487509a014931c578b05f5948939281aa31d2bc8b05b01c6932c45bf7a70972a430575c2a0d85789a4b9f2eec599bde9e5e9946fe9f7a613de910aebbd1bb681d718d422c8a092b17ad714173ec4787f0b3b9d2dfa96680861e093b5121441ffcde64183d074a0de881616657bd4c300116254ef39e2622f52faebe1b06b4fc9d3daed9dc76c06a07ce695737ab0d4bf9003a06ce83b11e75d81fbeb47c013b41f9c2e00a97cb87aa0dfe63771f833e98a5aeff54d9dd5a8dcfd89ca43c23644b18ec8e29ab8ccc287a0a327c817dc8a8ea3a5d3ca3cb55169777a1bfa30fe9f0df842eb3978dbd6737ba053683114bdaed7819b30ab8baec1fb9a2a96fee4dabc72f319cec9869da3b0b0a04d98297a896312d18da40240ed9a527f4c01c73edd3ea1f7c28338d1d863d97ca070451b5f2a402b497659eb18e648ac46f39c0068cc91436eb0b082b1d06dd63da066e866f800200512b0d3e534c547f4d2012429152cc9693bf1553cc22361627ba003fc4e648aafdadd7a9fa7cb534103f08dc699413ecda22bda46898bfb792429a0b46a167c66b50c74227d03a68971e124fdd011d6c90f5a08f6fe30ae34de603ca0a7ced66271235bc27b154f37bee6d9a1366cd253176c96de707d124fcc593c35a0f4f09b104a86cefc5c282d393b415e6c224eb8a463386448ebebfad9f9f53c9680f90211a05f93540f4317a4c6d8b73556a7ffdab6fcf0aa36af84b8c4bd2a3e7114e2da4ea05dd8c13b1b83485911f5e1185669f7d5559c260193a72e52597a3e80736c248ca03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa0a928e2ea8773ba69dde5344d69069b237667dbaaa69e86133d4e444e432799b1a0ebb2cbf0c3314ddf681f21a29fa17b320094684ba35e725bc36bbc407821cfa3a0762aeb8161d2b1b8a5ee51d1ede36f51cc2dad7e0c4d0ff097b89c831aff8c35a0957a8eaaac924688482d21a95b7a7f01889ab39a7a50d58efaaffa9e486ae071a046c10b0c15aa83973ea4b108f50bad2638941550fce7c9308c8b968abee271f8a08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca020630d0f41d1f38c61fc8d3fc6170f6f11fc52ade454930a3b5e4f4491b47467a04539a99793f29484fdbd39b606f27265499acb3c24461f48858655f07166f0dfa05fd40548cfae17d12e103db98572f22cdc8dd3ec670be570727a7ff68f6bce9fa032efe866f058f79ef06de75f682e10773576eb9fca3f950fda96ea9926784685a05c170d685d29417781f678b746174c7500e7c228b4bd71bcfe9f5421742a0b67a0c3fb71b77522f06c4a4e4cb7029e7faeb747b8e446460586ea0d5e9abae68cd9a03f2294bf8bea287c7afafde4b39aaa56716230ef425ece688f6a78fcadf5f49e80f9013180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a0a10cfa51ae290afebd64a5b530db7088fa0b02f22ce9b0838135b422b885dee5808080e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47022440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9122442a7cdd959bfe8d9487b2a43b33565295a698f7e200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab022443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a224470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba7224472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a5122447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e22448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d7886948522449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244b8f7166496996a7da21cf1f1b04d9b3e26a3d0778974616fe8ab950a3cded19b1d16ff49c97bf5af65154b3b097d5523eb213f3d35fc5c57e7276c7f2d83be87ebfdcdf92244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212244e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2244ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd02a440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2a442465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c8162a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a4435ebb5849518aff370ca25e19e1072cc1a9fabcaa7f3e2c0b4b16ad183c473bafe30a36e39fa4a143657e229cd23c77f8fbc8e4e4e241695dd3d248d1e51521eee6619142a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a44685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d3582a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44e9ae3261a475a27bb1028f140bc2a7c843318afd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832a44ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0").to_vec(); + any.extend(any2); let any: Any = any.try_into().unwrap(); let err = client .submit_misbehaviour(&ctx, client_id, any) .unwrap_err(); assert!( - format!("{:?}", err).contains("UnexpectedCoinbase: 31727008"), + format!("{:?}", err).contains("UnexpectedHeaderRelation: 32158798 32158799"), "{}", err ); diff --git a/light-client/src/client_state.rs b/light-client/src/client_state.rs index 80bec5b..dfc06bc 100644 --- a/light-client/src/client_state.rs +++ b/light-client/src/client_state.rs @@ -13,7 +13,7 @@ use crate::consensus_state::ConsensusState; use crate::errors::Error; use crate::header::Header; use crate::misbehaviour::Misbehaviour; -use crate::misc::{keccak_256_vec, new_height, Address, ChainId, Hash}; +use crate::misc::{new_height, Address, ChainId, Hash}; pub const PARLIA_CLIENT_STATE_TYPE_URL: &str = "/ibc.lightclients.parlia.v1.ClientState"; @@ -71,14 +71,13 @@ impl ClientState { &new_client_state.ibc_store_address, )?; - let new_validators = header.new_validators()?; let new_consensus_state = ConsensusState { state_root: account .storage_root .try_into() .map_err(Error::UnexpectedStorageRoot)?, timestamp: header.timestamp()?, - validators_hash: keccak_256_vec(&new_validators), + validators_hash: header.new_validators_hash(), }; Ok((new_client_state, new_consensus_state)) diff --git a/light-client/src/errors.rs b/light-client/src/errors.rs index 7fcbcc2..9f3830f 100644 --- a/light-client/src/errors.rs +++ b/light-client/src/errors.rs @@ -44,9 +44,8 @@ pub enum Error { UnexpectedValidatorsHashSize(Vec), // Header error - MissingParentTrustedValidators(BlockNumber), - MissingTargetTrustedValidators(BlockNumber), - MissingPreviousTargetTrustedValidators(BlockNumber), + MissingPreviousTrustedValidators(BlockNumber), + MissingCurrentTrustedValidators(BlockNumber), MissingTrustedValidatorsHeight, OutOfTrustingPeriod(Time, Time), HeaderFromFuture(Time, core::time::Duration, Time), @@ -56,8 +55,6 @@ pub enum Error { NegativeMaxClockDrift, UnexpectedTrustedHeight(BlockNumber, BlockNumber), EmptyHeader, - InsufficientHeaderToVerify(BlockNumber, usize, usize), - InsufficientHeaderToVerifyAcrossCheckpoint(BlockNumber, u64, usize, usize, usize), UnexpectedHeaderRevision(u64, u64), UnexpectedSignature(BlockNumber, signature::Error), MissingVanityInExtraData(BlockNumber, usize, usize), @@ -78,19 +75,20 @@ pub enum Error { UnexpectedHeaderRelation(BlockNumber, BlockNumber), ProofRLPError(rlp::DecoderError), InvalidProofFormatError(Vec), - InsufficientParentValidators(usize, usize), - InsufficientTargetValidators(usize, usize), - UnexpectedTargetValidatorsHash(Height, usize, Hash, Hash), - UnexpectedParentValidatorsHash(Height, usize, Hash, Hash), - UnexpectedPreviousTargetValidatorsHash(Height, usize, Hash, Hash), MissingValidatorInEpochBlock(BlockNumber), + UnexpectedPreviousValidatorsHash(Height, Hash, Hash), + UnexpectedCurrentValidatorsHash(Height, Hash, Hash), + InvalidVerifyingHeaderLength(BlockNumber, usize), // Vote attestation + TooManyHeaders(BlockNumber, usize), + UnexpectedVoteRelation(BlockNumber, usize, Option>), + UnexpectedSourceInGrandChild(BlockNumber, BlockNumber, Hash, Hash), UnexpectedVoteLength(usize), UnexpectedVoteAttestationExtraLength(usize), UnexpectedVoteAttestationRelation(BlockNumber, BlockNumber, Hash, Hash), UnexpectedBLSSignature(milagro_bls::AmclError), - UnexpectedBLSPubkey(milagro_bls::AmclError), + UnexpectedBLSPubkey(BlockNumber, milagro_bls::AmclError), FailedToVerifyBLSSignature(usize), InsufficientValidatorCount(usize, usize), UnexpectedVoteAddressCount(usize, usize), @@ -145,9 +143,6 @@ impl core::fmt::Display for Error { write!(f, "UnexpectedTrustedHeight: {} {}", e1, e2) } Error::EmptyHeader => write!(f, "EmptyHeader"), - Error::InsufficientHeaderToVerify(e1, e2, e3) => { - write!(f, "InsufficientHeaderToVerify: {} {} {}", e1, e2, e3) - } Error::UnexpectedHeaderRevision(e1, e2) => { write!(f, "UnexpectedHeaderRevision: {} {}", e1, e2) } @@ -161,28 +156,6 @@ impl core::fmt::Display for Error { Error::UnexpectedValidatorsHashSize(e) => { write!(f, "UnexpectedValidatorsHashSize: {:?}", e) } - Error::UnexpectedTargetValidatorsHash(e1, e2, e3, e4) => { - write!( - f, - "UnexpectedTargetValidatorsHash: {:?} {:?} {:?} {:?}", - e1, e2, e3, e4 - ) - } - Error::UnexpectedParentValidatorsHash(e1, e2, e3, e4) => { - write!( - f, - "UnexpectedParentValidatorsHash: {:?} {:?} {:?} {:?}", - e1, e2, e3, e4 - ) - } - Error::UnexpectedPreviousTargetValidatorsHash(e1, e2, e3, e4) => { - write!( - f, - "UnexpectedPreviousTargetValidatorsHash: {:?} {:?} {:?} {:?}", - e1, e2, e3, e4 - ) - } - Error::UnexpectedMixHash(e) => write!(f, "UnexpectedMixHash: {}", e), Error::UnexpectedUncleHash(e) => write!(f, "UnexpectedUncleHash: {}", e), Error::UnexpectedDifficulty(e1, e2) => write!(f, "UnexpectedDifficulty: {} {}", e1, e2), Error::UnexpectedNonce(e) => write!(f, "UnexpectedNonce: {}", e), @@ -210,31 +183,6 @@ impl core::fmt::Display for Error { Error::IllegalTimestamp(e1, e2) => write!(f, "IllegalTimestamp: {} {}", e1, e2), Error::UnexpectedHeader(e1, e3) => write!(f, "UnexpectedHeader: {} {:?}", e1, e3), Error::ProofRLPError(e) => write!(f, "ProofRLPError : {}", e), - Error::MissingParentTrustedValidators(e) => { - write!(f, "MissingParentTrustedValidators : {}", e) - } - Error::MissingTargetTrustedValidators(e) => { - write!(f, "MissingTargetTrustedValidators : {}", e) - } - Error::MissingPreviousTargetTrustedValidators(e) => { - write!(f, "MissingPreviousTargetTrustedValidators : {}", e) - } - Error::MissingTrustedValidatorsHeight => { - write!(f, "MissingTrustedValidatorsHeight") - } - Error::InsufficientParentValidators(e1, e2) => { - write!(f, "InsufficientParentValidators : {} {}", e1, e2) - } - Error::InsufficientTargetValidators(e1, e2) => { - write!(f, "InsufficientTargetValidators : {} {}", e1, e2) - } - Error::InsufficientHeaderToVerifyAcrossCheckpoint(e1, e2, e3, e4, e5) => { - write!( - f, - "InsufficientHeaderToVerifyAcrossCheckpoint : {} {} {} {} {}", - e1, e2, e3, e4, e5 - ) - } Error::MissingHeader1 => write!(f, "MissingHeader1"), Error::MissingHeader2 => write!(f, "MissingHeader2"), Error::UnexpectedClientId(e1) => write!(f, "UnexpectedClientId : {}", e1), @@ -286,8 +234,8 @@ impl core::fmt::Display for Error { Error::UnexpectedBLSSignatureLength(e1) => { write!(f, "UnexpectedBLSSignatureLength : {:?}", e1) } - Error::UnexpectedBLSPubkey(e1) => { - write!(f, "UnexpectedBLSPubkey : {:?}", e1) + Error::UnexpectedBLSPubkey(e1, e2) => { + write!(f, "UnexpectedBLSPubkey : {:?} {:?}", e1, e2) } Error::MissingValidatorInEpochBlock(e1) => { write!(f, "MissingValidatorInEpochBlock : {:?}", e1) @@ -295,6 +243,48 @@ impl core::fmt::Display for Error { Error::UnexpectedValidatorHeight(e1) => { write!(f, "UnexpectedValidatorHeight : {:?}", e1) } + Error::MissingPreviousTrustedValidators(e1) => { + write!(f, "MissingPreviousTrustedValidators : {:?}", e1) + } + Error::MissingCurrentTrustedValidators(e1) => { + write!(f, "MissingCurrentTrustedValidators : {:?}", e1) + } + Error::MissingTrustedValidatorsHeight => { + write!(f, "MissingTrustedValidatorsHeight") + } + Error::UnexpectedMixHash(e1) => { + write!(f, "UnexpectedMixHash : {:?}", e1) + } + Error::UnexpectedPreviousValidatorsHash(e1, e2, e3) => { + write!( + f, + "UnexpectedPreviousValidatorsHash : {:?} {:?} {:?}", + e1, e2, e3 + ) + } + Error::UnexpectedCurrentValidatorsHash(e1, e2, e3) => { + write!( + f, + "UnexpectedCurrentValidatorsHash : {:?} {:?} {:?}", + e1, e2, e3 + ) + } + Error::UnexpectedSourceInGrandChild(e1, e2, e3, e4) => { + write!( + f, + "UnexpectedSourceInGrandChild : {} {} {:?} {:?}", + e1, e2, e3, e4 + ) + } + Error::InvalidVerifyingHeaderLength(e1, e2) => { + write!(f, "InvalidVerifyingHeaderLength : {} {}", e1, e2) + } + Error::TooManyHeaders(e1, e2) => { + write!(f, "TooManyHeaders : {} {}", e1, e2) + } + Error::UnexpectedVoteRelation(e1, e2, e3) => { + write!(f, "UnexpectedVoteRelation : {} {} {:?}", e1, e2, e3) + } } } } diff --git a/light-client/src/header/eth_header.rs b/light-client/src/header/eth_header.rs index c568d3a..c4d940a 100644 --- a/light-client/src/header/eth_header.rs +++ b/light-client/src/header/eth_header.rs @@ -178,11 +178,7 @@ impl ETHHeader { Ok(signer) } - /// https://github.com/bnb-chain/bsc/blob/7a19cd27b61b342d24a1584efc7fa00de4a5b4f5/consensus/parlia/parlia.go#L416 - pub fn verify_vote_attestation( - &self, - parent: ÐHeader, - ) -> Result<(VoteAttestation, VoteAttestation), Error> { + pub fn verify_target_attestation(&self, parent: ÐHeader) -> Result { let target_vote_attestation = self.get_vote_attestation()?; let target_data = &target_vote_attestation.data; @@ -195,21 +191,28 @@ impl ETHHeader { parent.hash, )); } + Ok(target_vote_attestation) + } + + /// https://github.com/bnb-chain/bsc/blob/7a19cd27b61b342d24a1584efc7fa00de4a5b4f5/consensus/parlia/parlia.go#L416 + pub fn verify_vote_attestation(&self, parent: ÐHeader) -> Result { + let vote_attestation = self.verify_target_attestation(parent)?; + let vote_data = &vote_attestation.data; // The source block should be the highest justified block. let parent_vote_attestation = parent.get_vote_attestation()?; let parent_data = &parent_vote_attestation.data; - if target_data.source_number != parent_data.target_number - || target_data.source_hash != parent_data.target_hash + if vote_data.source_number != parent_data.target_number + || vote_data.source_hash != parent_data.target_hash { return Err(Error::UnexpectedVoteAttestationRelation( - target_data.source_number, + vote_data.source_number, parent_data.target_number, - target_data.source_hash, + vote_data.source_hash, parent_data.target_hash, )); } - Ok((target_vote_attestation, parent_vote_attestation)) + Ok(vote_attestation) } pub fn get_vote_attestation(&self) -> Result { diff --git a/light-client/src/header/eth_headers.rs b/light-client/src/header/eth_headers.rs new file mode 100644 index 0000000..12f65b0 --- /dev/null +++ b/light-client/src/header/eth_headers.rs @@ -0,0 +1,323 @@ +use alloc::vec::Vec; + +use parlia_ibc_proto::ibc::lightclients::parlia::v1::EthHeader; + +use crate::errors::Error; + +use crate::misc::{ChainId, Validators}; + +use super::eth_header::ETHHeader; +use super::BLOCKS_PER_EPOCH; + +#[derive(Clone, Debug, PartialEq)] +pub struct ETHHeaders { + pub target: ETHHeader, + pub all: Vec, +} + +impl ETHHeaders { + pub fn verify( + &self, + chain_id: &ChainId, + current_validators: &Validators, + previous_validators: &Validators, + ) -> Result<(), Error> { + // Ensure all the headers are successfully chained. + for (i, header) in self.all.iter().enumerate() { + if i < self.all.len() - 1 { + let child = &self.all[i + 1]; + child.verify_cascading_fields(header)?; + } + } + + // Ensure valid seals + let epoch = self.target.number / BLOCKS_PER_EPOCH; + let checkpoint = epoch * BLOCKS_PER_EPOCH + checkpoint(previous_validators); + for h in self.all.iter() { + if h.number >= checkpoint { + h.verify_seal(current_validators, chain_id)?; + } else { + h.verify_seal(previous_validators, chain_id)?; + } + } + + // Ensure target is finalized + let headers_for_finalize = self.verify_finalized()?; + + // Ensure BLS signature is collect + // At the just checkpoint BLS signature uses previous validator set. + for h in headers_for_finalize { + let vote = h.get_vote_attestation()?; + if h.number > checkpoint { + vote.verify(h.number, current_validators)?; + } else { + vote.verify(h.number, previous_validators)?; + } + } + Ok(()) + } + + fn verify_finalized(&self) -> Result, Error> { + if self.all.len() < 3 { + return Err(Error::InvalidVerifyingHeaderLength( + self.target.number, + self.all.len(), + )); + } + let mut last_error: Option = None; + let headers = &self.all[..self.all.len() - 2]; + for (i, _header) in headers.iter().enumerate() { + let header = &self.all[i]; + let child = &self.all[i + 1]; + let grand_child = &self.all[i + 2]; + match verify_finalized(header, child, grand_child) { + Err(e) => last_error = Some(e), + Ok(()) => { + if i + 2 != self.all.len() - 1 { + return Err(Error::TooManyHeaders(self.target.number, self.all.len())); + } + return Ok(vec![child, grand_child]); + } + } + } + Err(Error::UnexpectedVoteRelation( + self.target.number, + self.all.len(), + last_error.map(alloc::boxed::Box::new), + )) + } +} + +impl TryFrom> for ETHHeaders { + type Error = Error; + + fn try_from(value: Vec) -> Result { + let mut new_headers: Vec = Vec::with_capacity(value.len()); + for (i, header) in value.into_iter().enumerate() { + new_headers.push( + header + .try_into() + .map_err(|e| Error::UnexpectedHeader(i, alloc::boxed::Box::new(e)))?, + ); + } + let target = match new_headers.first() { + Some(v) => v, + None => return Err(Error::EmptyHeader), + }; + + Ok(ETHHeaders { + target: target.clone(), + all: new_headers, + }) + } +} + +fn verify_finalized( + header: ÐHeader, + child: ÐHeader, + grand_child: ÐHeader, +) -> Result<(), Error> { + child.verify_target_attestation(header)?; + let grand_child_vote = grand_child.verify_vote_attestation(child)?; + if grand_child_vote.data.source_number != header.number + || grand_child_vote.data.source_hash != header.hash + { + return Err(Error::UnexpectedSourceInGrandChild( + header.number, + grand_child_vote.data.source_number, + header.hash, + grand_child_vote.data.source_hash, + )); + } + Ok(()) +} + +/// for example when the validator count is 21 the checkpoint is 211, 411, 611 ... +/// https://github.com/bnb-chain/bsc/blob/48aaee69e9cb50fc2cedf1398ae4b98b099697db/consensus/parlia/parlia.go#L607 +/// https://github.com/bnb-chain/bsc/blob/48aaee69e9cb50fc2cedf1398ae4b98b099697db/consensus/parlia/snapshot.go#L191 +fn checkpoint(validators: &Validators) -> u64 { + let validator_size = validators.len() as u64; + validator_size / 2 + 1 +} + +#[cfg(test)] +mod test { + use crate::errors::Error; + use crate::header::eth_headers::ETHHeaders; + use crate::header::testdata::*; + use crate::header::Header; + use hex_literal::hex; + use light_client::types::Any; + + #[test] + fn test_success_verify_before_checkpoint() { + let headers = create_before_checkpoint_headers(); + let p_val = validators_in_31297000(); + headers.verify(&mainnet(), &vec![], &p_val).unwrap(); + } + + #[test] + fn test_success_verify_across_checkpoint() { + let headers = create_across_checkpoint_headers(); + let c_val = header_31297200().get_validator_bytes().unwrap(); + let p_val = validators_in_31297000(); + headers.verify(&mainnet(), &c_val, &p_val).unwrap(); + } + + #[test] + fn test_success_verify_after_checkpoint() { + let headers = create_after_checkpoint_headers(); + let c_val = header_31297200().get_validator_bytes().unwrap(); + headers.verify(&mainnet(), &c_val, &vec![]).unwrap(); + } + + #[test] + fn test_error_verify_before_checkpoint() { + let header = create_before_checkpoint_headers(); + + let mainnet = &mainnet(); + let _result = header.verify(mainnet, &vec![], &vec![]); + + // first block uses previous broken validator set + let mut previous_validator_set = validators_in_31297000(); + for v in previous_validator_set.iter_mut() { + v.remove(0); + } + let result = header.verify(mainnet, &vec![], &previous_validator_set); + match result.unwrap_err() { + Error::MissingSignerInValidator(number, _) => { + assert_eq!(number, header.target.number) + } + e => unreachable!("{:?}", e), + } + } + + #[test] + fn test_error_verify_across_checkpoint() { + let mut new_validator_set = header_31297200().get_validator_bytes().unwrap(); + let previous_validator_set = validators_in_31297000(); + + let mainnet = &mainnet(); + + // insufficient header for after checkpoint + let mut header = create_across_checkpoint_headers(); + header.all.pop(); + let _result = header.verify(mainnet, &new_validator_set, &previous_validator_set); + + // last block uses new empty validator set + let header = create_across_checkpoint_headers(); + for (i, v) in new_validator_set.iter_mut().enumerate() { + v[0] = i as u8; + } + let result = header.verify(mainnet, &new_validator_set, &previous_validator_set); + match result.unwrap_err() { + Error::MissingSignerInValidator(number, _) => { + //25428811 uses next validator + assert_eq!(number, header.all[header.all.len() - 2].number) + } + e => unreachable!("{:?}", e), + } + } + + #[test] + fn test_error_verify_non_continuous_header() { + let mut headers = create_after_checkpoint_headers(); + headers.all[1] = headers.all[0].clone(); + let c_val = header_31297200().get_validator_bytes().unwrap(); + let result = headers.verify(&mainnet(), &c_val, &vec![]); + match result.unwrap_err() { + Error::UnexpectedHeaderRelation(e1, e2) => { + assert_eq!(e1, headers.target.number); + assert_eq!(e2, headers.target.number); + } + e => unreachable!("{:?}", e), + } + } + + #[test] + fn test_error_verify_too_many_headers() { + let mut headers = create_after_checkpoint_headers(); + headers.all.push(header_31297214()); + let c_val = header_31297200().get_validator_bytes().unwrap(); + let result = headers.verify(&mainnet(), &c_val, &vec![]); + match result.unwrap_err() { + Error::TooManyHeaders(e1, e2) => { + assert_eq!(e1, headers.target.number, "block error"); + assert_eq!(e2, headers.all.len(), "header size"); + } + e => unreachable!("{:?}", e), + } + } + + #[test] + fn test_error_verify_invalid_header_size() { + let mut headers = create_after_checkpoint_headers(); + headers.all.pop(); + let c_val = header_31297200().get_validator_bytes().unwrap(); + let result = headers.verify(&mainnet(), &c_val, &vec![]); + match result.unwrap_err() { + Error::InvalidVerifyingHeaderLength(e1, e2) => { + assert_eq!(e1, headers.target.number, "block error"); + assert_eq!(e2, headers.all.len(), "header size"); + } + e => unreachable!("{:?}", e), + } + } + + #[test] + fn test_success_verify_finalized_including_not_finalized_block() { + let header= hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212961e0a9e060a9b06f90318a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd549a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d1d6bf74282782b0b3eb1413c901d6ecf02e8e28a0c2081e9bb02adf2b65cf9b3f83b71142e4a963584516174fa671c75e3c9b82f0a071f511f91544d703b0a8a74ef6b93df3d261d961b15f5abb688a115a164f59aba0a93cf4b9598e6c8ff24b4aea19f8a64291de129c57118291fee8c4b16de22fe5b90100462586c2f1cfbc9f58faae6f8ff10b2b6a5e6acb0d3077c87e9b05031ab93d1e8f62b32a766618ad9af4b9a1629f42008273c409768e35be70154b2721e87ef585d19504837158efa1b705d99333122ea79c48b387729b7e491f8154d55c5f180e6d01668a76152594e3183ccae8490d8e8e92500e0f5c2ad6b0e415f45ac72f95fab24672835de1c48e0a9f38923ec496ae5dd5fb62043cfd7bc0c8f0c5c3f1670ef7d1d7fc2b907ffe63ced34467b8fbf2300dba03b63a57722ff07ae56961f52d1a32862a09ef3698d1b93bc636286a56b3cadb8b22998372f4c28cd1e72c7ab0f0ab0db8c6aa8105556c1a3481c6fc66ac24d5ae775fba850d343a210feb028401e6aa4184084fe2c684014933a184650a4afbb90118d88301020b846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831dffffb8609865f38b886fdf9133435031ff4e3af35f0f7dcd165bed2f80f523864cdcaacd102a5d538972060573218a8cbd201d9418fde9d217990d8faf5c5c382618820fe24cf490f1010d92a66114d3d5305e953ef00268448068d5fb4638a94c4269a2f84c8401e6aa3fa0cba1480655a9172eb8fc0a0ea9cd5a285b9fcea8489bde764a134c52a8cc0ff98401e6aa40a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd54980a72fc8f10e414df8a61ea1d4d2f3362b2fa0c8c7c444848769e6d67bdbcce4de2683fdae80bcd5a90a8f92d76b7ae426f11d51a7f1d785fefe1cbf451f67186401a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9a060a9706f90314a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f306a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e9ae3261a475a27bb1028f140bc2a7c843318afda0c2081e9bb02adf2b65cf9b3f83b71142e4a963584516174fa671c75e3c9b82f0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028401e6aa4284085832a78084650a4affb90118d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831dffffb860b02f4314b40616294282cb1f66df8eb23b1c26395b214e78ecd75a9646e0fd008b5f9bae4b24647db4f4b4a92ca0aee4032f3a8917546bfc7c078624ab1b0be6bf87972f4d9815f4f96ad00ba291308ee5c5f6c63243e9518ab6c1f42ce34470f84c8401e6aa40a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd5498401e6aa41a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f30680ec8e7cec4b6c25fa8b22c40e9ecae359c542137ed189c711f5cd7616f4619f331f3eb09268047aaf47af3b83786ee4471c31779848627720f48a7bf5ca50f14601a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800ae6040ae304f90260a0cadbcaaebd901c23537425e903b40a054d6cca192f0f01ecf3d45d9afce4cef3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da054d3ce938c69efbd57808ae22c9030bfa64ebfe6b7f16d5574b1fada5c336d96a0ba3499b3199bc9606a46f865d4abc0cfa9e1be68940ba8a91eb0de4e02d660f5a04278f75943cad9584a22440799ef5f5db6618e33bed532b709b859bb44e0d02fb901006eb746324da2c67a4c1a4a70aeed04073c9d207629cda74bd61604bf345053d797915346c4e531f9033b2df9067732f89d89f3e90b6ae92122c64c020964e7de5facd5784b66c76ac979829d886e8779f9b1f4b5e5efd954c956a916bb1d5f71937998aa33863da5ace9aa48432959190bfee853e57f55beeae4c6b8efcc0ff092f7f1f73afcd1daf3dcbb7c3f82fab45bacbc95366ad9fc6d495e5968e65c346248d49a759b29086e28a57f6af62769dfac85aba6ddf3013783b02ad9d872e8afa60d631a9f0c838298a5955222d611e3d1b79eb8a872beaa37fa5a9a00e50dabd0ca073bc1ff981bf906c0fda18164ae868587e9b802cdf7e26fae9a811f0b028401e6aa438408583b00840105fdbe84650a4b02b861d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a239e14e61ceb442e61edd782ed2e011994aca0236541d845851453ed45e1c950b3672dcc21546bd65e746c468b17a3722b7c529d64d9c3a4b41136ab03e48147e01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9e060a9b06f90318a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d90a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ee226379db83cffc681495730c11fdde79ba4c0ca0921e5a9881b361b462e86c18d8170303f37f3576c4298f951b164a3a0ffa7950a04a318f22b6185bdebef3900d7c65bcceed28c6906605406b54bd9eb07cb6a266a07a8d59ef980eed078ac8f192425c1fffbf5210a9c92a2065c40639f6421c2367b90100cae58a5a44a877dfab933564fb46b73ec4c3d9c7f068cd492e7b13a3d43cca90ce095bebe264c59a13537dd3575e47c5a87922ba687d73fbdf4cf75c5c7fae998edcc9956b64445fc973aacd815ef67bbc3ce25deb67e19207fff0d98cc0cd558a0ec9eb2bb7bee5b4e736041f80bdcb0862fbf2e9afff5e3ce0959b8fa1cfb795fe04f69cbfecdde7a927c01fe87cc89cad2e277b31e63a5619f6ffac97cb631f4ba69ce7fea3f16e3c2b15fb8b2462cbf6ef9b62b3e77173fb306f19eb12fbe2ecdedfb32acbcf3efa25d9f79838b2b76b25cec051447eab71740e862feb2fd214e4db5568ceb4a791b6bec6c1a972726641bce9fe4f68e46edf15df75e652028401e6aa448408583b00840107e57384650a4b05b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5831dffffb860a4cc53efef08386da2bcdf2ccd02f5772899f7e1f3b0252b21bf309dd6f96034ee6570316f1767c75acdd7f6691589051341d1cdf1f118c5c47c505a2e48a47da6e7d26c3107799b8cf767cff1382115896c6b74f0df094690ee36d0fcecf95ef84c8401e6aa41a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f3068401e6aa43a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d908093e10e56b7f84c8f756b3bd5422d93053db5f5a55dee436bae6d8066674e131f4f430278fc3cb1f4d9f3dd0c85410694b92887718d431d8ddf25524ece35d03501a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a04eedf58a08358d43f0d37410f1c301efcc3dd738eff0b07bb4f82c83f30a0cc2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ef0274e31810c9df02f98fafde0f841f4e66a1cda04773baafa2984559c063e6b1f50e3019baae941124e89d5d7bc3f009e484a3d0a0c350e76080e62e8e4f45c1d424daec63750b940344655e81f56f0c65f1e7ab40a0cfd21dbf9df8503fb97bcd511aa04483116eb7afd0d4702532d1ff0b8e8b849eb90100002e022444181418d2d2414984070420434880e00f19494c8452044a5a7001298681544650c412916e119ca3241220808c0110050418214674422800002620a06440c08029440f8f296082ac8214002db995a0c59de7580a06168014c01036205a8ca0628e8205000458ea6110210d480a002ce0809e0410430084100d4c6420390a20a40479e91a14982410089018c4902ca40d601091081181105024a110a007904082087e211261d6008c42ceb44942602191022801165326a8aa1f8f28f8e0262c92228732026080028c8812d2057a10b884800048b10c13545b9e20f6340ab485c910af5a940909064e044f41446c6b8581653051e81603b101fc498c0b028401e6aa458408583b008385259f84650a4b08b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5831dffffb86088dd96fd990be352a39175463f3902ec9f4f036ed7cd8ab3ce3f4cc70dfc8230a1a1f856e28cbc84a4ed1f95431f63cd0464f1c2f061593bfaf3eae388264d02420af41cfc0e01525f438bc3cf11b9c5a988aa6bb9c82098d567b339709ac676f84c8401e6aa43a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d908401e6aa44a04eedf58a08358d43f0d37410f1c301efcc3dd738eff0b07bb4f82c83f30a0cc2801962735bca49e800156401aa4bbe2e32d58f36cc22ce3cfd8da23ca72e10eb2f44fa1c1a1840959059d86e6f1b936457795534d45c8a554c3060e9dd39ec108001a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801200221400000000000000000000000000000000000000002a140000000000000000000000000000000000000000").to_vec(); + let any: Any = header.try_into().unwrap(); + let header = Header::try_from(any).unwrap(); + header.headers.verify_finalized().unwrap(); + } + + #[test] + fn test_error_verify_finalized_no_finalized_header() { + let header= hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212961e0a9e060a9b06f90318a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd549a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d1d6bf74282782b0b3eb1413c901d6ecf02e8e28a0c2081e9bb02adf2b65cf9b3f83b71142e4a963584516174fa671c75e3c9b82f0a071f511f91544d703b0a8a74ef6b93df3d261d961b15f5abb688a115a164f59aba0a93cf4b9598e6c8ff24b4aea19f8a64291de129c57118291fee8c4b16de22fe5b90100462586c2f1cfbc9f58faae6f8ff10b2b6a5e6acb0d3077c87e9b05031ab93d1e8f62b32a766618ad9af4b9a1629f42008273c409768e35be70154b2721e87ef585d19504837158efa1b705d99333122ea79c48b387729b7e491f8154d55c5f180e6d01668a76152594e3183ccae8490d8e8e92500e0f5c2ad6b0e415f45ac72f95fab24672835de1c48e0a9f38923ec496ae5dd5fb62043cfd7bc0c8f0c5c3f1670ef7d1d7fc2b907ffe63ced34467b8fbf2300dba03b63a57722ff07ae56961f52d1a32862a09ef3698d1b93bc636286a56b3cadb8b22998372f4c28cd1e72c7ab0f0ab0db8c6aa8105556c1a3481c6fc66ac24d5ae775fba850d343a210feb028401e6aa4184084fe2c684014933a184650a4afbb90118d88301020b846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831dffffb8609865f38b886fdf9133435031ff4e3af35f0f7dcd165bed2f80f523864cdcaacd102a5d538972060573218a8cbd201d9418fde9d217990d8faf5c5c382618820fe24cf490f1010d92a66114d3d5305e953ef00268448068d5fb4638a94c4269a2f84c8401e6aa3fa0cba1480655a9172eb8fc0a0ea9cd5a285b9fcea8489bde764a134c52a8cc0ff98401e6aa40a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd54980a72fc8f10e414df8a61ea1d4d2f3362b2fa0c8c7c444848769e6d67bdbcce4de2683fdae80bcd5a90a8f92d76b7ae426f11d51a7f1d785fefe1cbf451f67186401a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9a060a9706f90314a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f306a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e9ae3261a475a27bb1028f140bc2a7c843318afda0c2081e9bb02adf2b65cf9b3f83b71142e4a963584516174fa671c75e3c9b82f0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028401e6aa4284085832a78084650a4affb90118d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831dffffb860b02f4314b40616294282cb1f66df8eb23b1c26395b214e78ecd75a9646e0fd008b5f9bae4b24647db4f4b4a92ca0aee4032f3a8917546bfc7c078624ab1b0be6bf87972f4d9815f4f96ad00ba291308ee5c5f6c63243e9518ab6c1f42ce34470f84c8401e6aa40a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd5498401e6aa41a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f30680ec8e7cec4b6c25fa8b22c40e9ecae359c542137ed189c711f5cd7616f4619f331f3eb09268047aaf47af3b83786ee4471c31779848627720f48a7bf5ca50f14601a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800ae6040ae304f90260a0cadbcaaebd901c23537425e903b40a054d6cca192f0f01ecf3d45d9afce4cef3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da054d3ce938c69efbd57808ae22c9030bfa64ebfe6b7f16d5574b1fada5c336d96a0ba3499b3199bc9606a46f865d4abc0cfa9e1be68940ba8a91eb0de4e02d660f5a04278f75943cad9584a22440799ef5f5db6618e33bed532b709b859bb44e0d02fb901006eb746324da2c67a4c1a4a70aeed04073c9d207629cda74bd61604bf345053d797915346c4e531f9033b2df9067732f89d89f3e90b6ae92122c64c020964e7de5facd5784b66c76ac979829d886e8779f9b1f4b5e5efd954c956a916bb1d5f71937998aa33863da5ace9aa48432959190bfee853e57f55beeae4c6b8efcc0ff092f7f1f73afcd1daf3dcbb7c3f82fab45bacbc95366ad9fc6d495e5968e65c346248d49a759b29086e28a57f6af62769dfac85aba6ddf3013783b02ad9d872e8afa60d631a9f0c838298a5955222d611e3d1b79eb8a872beaa37fa5a9a00e50dabd0ca073bc1ff981bf906c0fda18164ae868587e9b802cdf7e26fae9a811f0b028401e6aa438408583b00840105fdbe84650a4b02b861d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a239e14e61ceb442e61edd782ed2e011994aca0236541d845851453ed45e1c950b3672dcc21546bd65e746c468b17a3722b7c529d64d9c3a4b41136ab03e48147e01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9e060a9b06f90318a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d90a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ee226379db83cffc681495730c11fdde79ba4c0ca0921e5a9881b361b462e86c18d8170303f37f3576c4298f951b164a3a0ffa7950a04a318f22b6185bdebef3900d7c65bcceed28c6906605406b54bd9eb07cb6a266a07a8d59ef980eed078ac8f192425c1fffbf5210a9c92a2065c40639f6421c2367b90100cae58a5a44a877dfab933564fb46b73ec4c3d9c7f068cd492e7b13a3d43cca90ce095bebe264c59a13537dd3575e47c5a87922ba687d73fbdf4cf75c5c7fae998edcc9956b64445fc973aacd815ef67bbc3ce25deb67e19207fff0d98cc0cd558a0ec9eb2bb7bee5b4e736041f80bdcb0862fbf2e9afff5e3ce0959b8fa1cfb795fe04f69cbfecdde7a927c01fe87cc89cad2e277b31e63a5619f6ffac97cb631f4ba69ce7fea3f16e3c2b15fb8b2462cbf6ef9b62b3e77173fb306f19eb12fbe2ecdedfb32acbcf3efa25d9f79838b2b76b25cec051447eab71740e862feb2fd214e4db5568ceb4a791b6bec6c1a972726641bce9fe4f68e46edf15df75e652028401e6aa448408583b00840107e57384650a4b05b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5831dffffb860a4cc53efef08386da2bcdf2ccd02f5772899f7e1f3b0252b21bf309dd6f96034ee6570316f1767c75acdd7f6691589051341d1cdf1f118c5c47c505a2e48a47da6e7d26c3107799b8cf767cff1382115896c6b74f0df094690ee36d0fcecf95ef84c8401e6aa41a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f3068401e6aa43a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d908093e10e56b7f84c8f756b3bd5422d93053db5f5a55dee436bae6d8066674e131f4f430278fc3cb1f4d9f3dd0c85410694b92887718d431d8ddf25524ece35d03501a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a04eedf58a08358d43f0d37410f1c301efcc3dd738eff0b07bb4f82c83f30a0cc2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ef0274e31810c9df02f98fafde0f841f4e66a1cda04773baafa2984559c063e6b1f50e3019baae941124e89d5d7bc3f009e484a3d0a0c350e76080e62e8e4f45c1d424daec63750b940344655e81f56f0c65f1e7ab40a0cfd21dbf9df8503fb97bcd511aa04483116eb7afd0d4702532d1ff0b8e8b849eb90100002e022444181418d2d2414984070420434880e00f19494c8452044a5a7001298681544650c412916e119ca3241220808c0110050418214674422800002620a06440c08029440f8f296082ac8214002db995a0c59de7580a06168014c01036205a8ca0628e8205000458ea6110210d480a002ce0809e0410430084100d4c6420390a20a40479e91a14982410089018c4902ca40d601091081181105024a110a007904082087e211261d6008c42ceb44942602191022801165326a8aa1f8f28f8e0262c92228732026080028c8812d2057a10b884800048b10c13545b9e20f6340ab485c910af5a940909064e044f41446c6b8581653051e81603b101fc498c0b028401e6aa458408583b008385259f84650a4b08b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5831dffffb86088dd96fd990be352a39175463f3902ec9f4f036ed7cd8ab3ce3f4cc70dfc8230a1a1f856e28cbc84a4ed1f95431f63cd0464f1c2f061593bfaf3eae388264d02420af41cfc0e01525f438bc3cf11b9c5a988aa6bb9c82098d567b339709ac676f84c8401e6aa43a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d908401e6aa44a04eedf58a08358d43f0d37410f1c301efcc3dd738eff0b07bb4f82c83f30a0cc2801962735bca49e800156401aa4bbe2e32d58f36cc22ce3cfd8da23ca72e10eb2f44fa1c1a1840959059d86e6f1b936457795534d45c8a554c3060e9dd39ec108001a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801200221400000000000000000000000000000000000000002a140000000000000000000000000000000000000000").to_vec(); + let any: Any = header.try_into().unwrap(); + let mut header = Header::try_from(any).unwrap(); + header.headers.all.pop(); + let result = header.headers.verify_finalized(); + match result.unwrap_err() { + Error::UnexpectedVoteRelation(e1, e2, err) => { + assert_eq!(e1, header.headers.target.number, "block error"); + assert_eq!(e2, header.headers.all.len(), "header size"); + assert!(format!("{:?}", &err.unwrap()).contains("UnexpectedVoteLength")); + } + e => unreachable!("{:?}", e), + } + } + + fn create_before_checkpoint_headers() -> ETHHeaders { + let v = vec![header_31297208(), header_31297209(), header_31297210()]; + ETHHeaders { + target: v[0].clone(), + all: v, + } + } + + fn create_across_checkpoint_headers() -> ETHHeaders { + let v = vec![ + header_31297210(), + header_31297211(), // checkpoint + header_31297212(), + ]; + ETHHeaders { + target: v[0].clone(), + all: v, + } + } + + fn create_after_checkpoint_headers() -> ETHHeaders { + let v = vec![ + header_31297211(), // checkpoint + header_31297212(), + header_31297213(), + ]; + ETHHeaders { + target: v[0].clone(), + all: v, + } + } +} diff --git a/light-client/src/header/mod.rs b/light-client/src/header/mod.rs index 38c8b9c..2c2133a 100644 --- a/light-client/src/header/mod.rs +++ b/light-client/src/header/mod.rs @@ -7,9 +7,10 @@ use parlia_ibc_proto::google::protobuf::Any as IBCAny; use parlia_ibc_proto::ibc::lightclients::parlia::v1::Header as RawHeader; use crate::commitment::decode_eip1184_rlp_proof; -use crate::header::eth_header::ETHHeader; + +use crate::header::eth_headers::ETHHeaders; use crate::header::validator_set::ValidatorSet; -use crate::misc::{new_height, new_timestamp, ChainId, Hash, Validators}; +use crate::misc::{keccak_256_vec, new_height, new_timestamp, ChainId, Hash}; use super::errors::Error; @@ -20,31 +21,33 @@ pub const PARLIA_HEADER_TYPE_URL: &str = "/ibc.lightclients.parlia.v1.Header"; // inner header is module private pub mod constant; mod eth_header; +mod eth_headers; pub(crate) mod validator_set; mod vote_attestation; #[derive(Clone, Debug, PartialEq)] pub struct Header { account_proof: Vec, - target: ETHHeader, - parent: ETHHeader, + headers: ETHHeaders, trusted_height: Height, - parent_validators: ValidatorSet, - target_validators: ValidatorSet, - previous_target_validators: ValidatorSet, + previous_validators: ValidatorSet, + current_validators: ValidatorSet, } impl Header { pub fn height(&self) -> Height { - new_height(self.trusted_height.revision_number(), self.target.number) + new_height( + self.trusted_height.revision_number(), + self.headers.target.number, + ) } - pub fn parent_height(&self) -> Height { - new_height(self.trusted_height.revision_number(), self.parent.number) + pub fn is_target_epoch(&self) -> bool { + self.headers.target.is_epoch() } pub fn timestamp(&self) -> Result { - new_timestamp(self.target.timestamp) + new_timestamp(self.headers.target.timestamp) } pub fn account_proof(&self) -> Result>, Error> { @@ -56,47 +59,53 @@ impl Header { } pub fn state_root(&self) -> &Hash { - &self.target.root + &self.headers.target.root } - pub fn new_validators(&self) -> Result { - if !self.target.is_epoch() { - return Ok(vec![]); - } - self.target + pub fn new_validators_hash(&self) -> Hash { + let validator = self + .headers + .target .get_validator_bytes() - .ok_or_else(|| Error::MissingValidatorInEpochBlock(self.target.number)) + .unwrap_or_default(); + keccak_256_vec(&validator) } - pub fn parent_validators(&self) -> &ValidatorSet { - &self.parent_validators - } - - pub fn previous_target_validators(&self) -> &ValidatorSet { - &self.previous_target_validators + pub fn previous_epoch_validators(&self) -> (Height, Hash) { + let height = &self.height().revision_height(); + let mut epoch_count = height / BLOCKS_PER_EPOCH; + if epoch_count > 0 { + epoch_count -= 1; + } + ( + Height::new( + self.height().revision_number(), + epoch_count * BLOCKS_PER_EPOCH, + ), + self.previous_validators.hash, + ) } - pub fn target_validators(&self) -> &ValidatorSet { - &self.target_validators + pub fn current_epoch_validators(&self) -> (Height, Hash) { + let height = &self.height().revision_height(); + let epoch_count = height / BLOCKS_PER_EPOCH; + let epoch_block = epoch_count * BLOCKS_PER_EPOCH; + ( + Height::new(self.height().revision_number(), epoch_block), + self.current_validators.hash, + ) } pub fn verify(&self, chain_id: &ChainId) -> Result<(), Error> { - self.target.verify_cascading_fields(&self.parent)?; - let (target_vote_attestation, parent_vote_attestation) = - self.target.verify_vote_attestation(&self.parent)?; - target_vote_attestation.verify(&self.target_validators.validators)?; - parent_vote_attestation.verify(&self.parent_validators.validators)?; - - self.target - .verify_seal(&self.target_validators.validators, chain_id)?; - self.parent - .verify_seal(&self.parent_validators.validators, chain_id)?; - - Ok(()) + self.headers.verify( + chain_id, + &self.current_validators.validators, + &self.previous_validators.validators, + ) } pub fn block_hash(&self) -> &Hash { - &self.target.hash + &self.headers.target.hash } } @@ -113,43 +122,45 @@ impl TryFrom for Header { trusted_height.revision_height, ); - let target = ETHHeader::try_from(value.target.ok_or(Error::EmptyHeader)?)?; - let parent = ETHHeader::try_from(value.parent.ok_or(Error::EmptyHeader)?)?; + // All the header revision must be same as the revision of trusted_height. + let headers = ETHHeaders::try_from(value.headers.clone())?; - // Ensure target height is greater than or equals to trusted height. - let trusted_header_height = trusted_height.revision_height(); - if target.number <= trusted_header_height { + if headers.target.number <= trusted_height.revision_height() { return Err(Error::UnexpectedTrustedHeight( - target.number, - trusted_header_height, + headers.target.number, + trusted_height.revision_height(), )); } - let parent_validators: ValidatorSet = value.parent_validators.clone().try_into()?; - if parent_validators.validators.is_empty() { - return Err(Error::MissingParentTrustedValidators(target.number)); + let previous_validators: ValidatorSet = value.previous_validators.into(); + if previous_validators.validators.is_empty() { + return Err(Error::MissingPreviousTrustedValidators( + headers.target.number, + )); } // Epoch header contains validator set - let target_validators: ValidatorSet = value.target_validators.clone().try_into()?; - if target_validators.validators.is_empty() { - return Err(Error::MissingTargetTrustedValidators(target.number)); - } - - let previous_target_validators: ValidatorSet = - value.previous_target_validators.clone().try_into()?; - if previous_target_validators.validators.is_empty() { - return Err(Error::MissingPreviousTargetTrustedValidators(target.number)); + let current_validators: ValidatorSet = if headers.target.is_epoch() { + headers + .target + .get_validator_bytes() + .ok_or_else(|| Error::MissingValidatorInEpochBlock(headers.target.number))? + .into() + } else { + value.current_validators.into() + }; + if current_validators.validators.is_empty() { + return Err(Error::MissingCurrentTrustedValidators( + headers.target.number, + )); } Ok(Self { account_proof: value.account_proof, - target, - parent, + headers, trusted_height, - parent_validators, - target_validators, - previous_target_validators, + previous_validators, + current_validators, }) } } diff --git a/light-client/src/header/testdata.rs b/light-client/src/header/testdata.rs index c170eab..a29e948 100644 --- a/light-client/src/header/testdata.rs +++ b/light-client/src/header/testdata.rs @@ -34,8 +34,445 @@ pub fn validators_in_31297000() -> Validators { ] } +pub fn header_31297221() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ec5&boolean=false + //https://bscscan.com/block/31297221 + ETHHeader { + parent_hash: hex!("da01d8fede81f2840ea4bd2d5586d4303f68c73becf0a23d1d6dddd4890bd274").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("ea0a6e3c511bbd10f4519ece37dc24887e11b55d").into(), + root: hex!("97528e3167d013309f8585c8db78f4af02b0acbcf92e6b3aac530f9972b18ded"), + tx_hash: hex!("ed65d042cdbf107e3803eb2aaa1932b1ae28ab8b2fc4df9bafb9217b390aa9c9").into(), + receipt_hash: hex!("b8394040a65867ce80c2f4fd34d3bba3095b80ff9ccaea1e58669ca564a1e103").into(), + bloom: hex!("91a876410d0c7012c91502d6845200a6d208a629cdcc06a0053861b2b9760ba2c8293640420712c5329374810216e098cfeba05d250267e0d8421025952c6a30242ee00309c60244e5338ccbca3104be2518206551e6580b0c5d81b0c8a33c05e02cb13e7b22c3cb248d041493691c51087c8acb1b0bb68e884ec552e443b4041e0b07914679c2eb02f4240458036fae4aa6fe9dd421313b75513b74aa505c30067648177ea9d9c2332d5deebe9f38d046eac9840301613312c0252a7813aaf8ee39440e3088e446cc5d0a9e1ca2fb00a0c8b1421d1dc03611ba406a2a34e5fd16399c1d89dec60741b05462e1110945781a845e7db1796c9bca3e909b61205d").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8ec5", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("aa7b54", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0d4", 16).unwrap(), + extra_data: hex!("d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830ddfffb860b4de956fe39e1e7e6b535f75054f2efea8ac185ac2b76384c749cc45f7decfea9999b9b3b41e5666e36408069cdd06870e266fe868b9128ce0a0aecf4ecc6b0e42d10c5e646e9571a862dee7112e88f39ddc476b67be9cf32ccb337d3496f901f84c8401dd8ec3a035be0876c21a5a5726193d1adb8ce9ebb6eb95757407cafb9106a57f0d3d12228401dd8ec4a0da01d8fede81f2840ea4bd2d5586d4303f68c73becf0a23d1d6dddd4890bd27480939d982a7958bf5912c1105da4673d035df33b685ad798e6f589ada1b40f63fa27edbbcea731e17928a54c07847a70d7e262a0bc41e68e5fcda124a37f4340b301").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("0b89f31647758aaffb46d3a71f2bcee82816fd1a8c25dbddc774bd14524ae379"), + } +} + +pub fn header_31297220() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ec4&boolean=false + //https://bscscan.com/block/31297220 + ETHHeader { + parent_hash: hex!("35be0876c21a5a5726193d1adb8ce9ebb6eb95757407cafb9106a57f0d3d1222").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("d93dbfb27e027f5e9e6da52b9e1c413ce35adc11").into(), + root: hex!("1283c0ddaf635ba45c04c7dcd3ee83370027d55fee45e9bd2a8f121074808ece"), + tx_hash: hex!("62c9236c31a88ecf2d5ecb4666f06b78fad90bc6cde486714c92ac123b26e56b").into(), + receipt_hash: hex!("babb28a01a3e0fe3657bd296123c54e8e6368588e943ab3b966d97effdcc1ae2").into(), + bloom: hex!("dd6dd27f6ff5373d2ef7e4edba7714d6f3daf37bd7d8bfffba5fd73b32befff7ffc75fcbfbb955cfeab33ff77d1fd0b7fbd3d1fc05f5f02f7faf3efff3ed7afcffcffbf65d52ad3c9b75cedcb8d672fafdb1ffbf52f7af38e2fce0bffa6b0e3f5ffd7dfeaf4fcd630acd8ffc917b3dbf0ca36c63784d76b65eead7b9f6ef1fbf5aafff6e2e5fba9ff4ffbd57eeebdcbe76f67db77c36bdc86dabb3d3bccbdead97e726e3ebbefbf6effef7efcffebec3f7afcfef4ebaf9b5f7eaf77e6f5bebebe5e7f59ea35efbf7f6ea5d2fc36ffdeeadffb5eec3ba5e3dbbd774cef627f77ff1bafa3dbdf3d9de2735e7c685a723b6fc3e27fb767d7179bf2ffadfb9b9d8fb").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8ec4", 16).unwrap(), + gas_limit: u64::from_str_radix("85832a7", 16).unwrap(), + gas_used: u64::from_str_radix("142a9ef", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0d1", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5830ddfffb860a4332ba47e6728f4b0e52e490cf4bd3cc4fc742c12bb8a8e5912095c71d9c845f5ddc5fdd4128dbed0e1bcaf4da8236b05ded0aa4a4c81f4a4fb2250f790fe1b21edb1aed0bc7bb7d4a78b26c6dd9af3b65a2bacb5b44e4a7b1dc3284e9d7d6bf84c8401dd8ec2a00f0fc4bae073bbeae37d8ff5395c95480fe5a9149bad4f0cd4f5e8e32d18b32e8401dd8ec3a035be0876c21a5a5726193d1adb8ce9ebb6eb95757407cafb9106a57f0d3d1222805bd7bc1a83768b5c7a505eed50eca8fdddd8a583a46d37f80a2d714be9f8ca2b04b0ba1398956512d18b30e3a56755245df898b98f8d5f6131eb7527f7dc65b101").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("da01d8fede81f2840ea4bd2d5586d4303f68c73becf0a23d1d6dddd4890bd274"), + } +} + +pub fn header_31297219() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ec3&boolean=false + //https://bscscan.com/block/31297219 + ETHHeader { + parent_hash: hex!("0f0fc4bae073bbeae37d8ff5395c95480fe5a9149bad4f0cd4f5e8e32d18b32e").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("d1d6bf74282782b0b3eb1413c901d6ecf02e8e28").into(), + root: hex!("a6923c4f9bce5b7cc15a16d85222ce2618aa0f12bca0fa6b703d9aa5aa412648"), + tx_hash: hex!("57dc9bdab942a85992bf2bb645594c35d9aa1df083fee8207df409886d313d6d").into(), + receipt_hash: hex!("3bfa2879642e0273e765670993bff0ec2f22e589317782599cc6b79453441096").into(), + bloom: hex!("eea73ff54e3fd7191d7f53f49ca3c29eb5b9688d0fafc2d33e7ee12d3a35cc69ef7ebd97cfc31b177a6b73ccda3622f8f9b6d95b59976d306e3ecc5f7431eed49e5cd9f70ff7cd29df7de1ebfd3bae347bbd98a770559ede746e6f93c9fb4e23eb3db0a53e57bf4eb77d7c36d3f37944cd99ddd55bb79f7e1d57f5b7ee1b6eeaf987c3a4da37134c5fa5be1fd2107bce442ea68f7c34fc9f6beba6df46fb78e63fd7323f57c723718edfddce9bd9fd425a978f65a7bed42fff41f666aefb58f76dd3ff561332ffaeb7fac28d55e99b7cf1f7b1a768b7a8bcc13e7ce715f4affed53eb4e4b1c177bd5f5d2de36bf39bd6b8d6976e5dec7cccb4f4fd932a677ecd").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8ec3", 16).unwrap(), + gas_limit: u64::from_str_radix("84fe2c6", 16).unwrap(), + gas_used: u64::from_str_radix("f43a7c", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0ce", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b58305dfffb860b7ab6f15df58e54befa47c75d64d32161823c59edf5bade334b55623eceb68b45752b058206ab7805f277362b7df153601ff6c28a4359f22a74b39304f929af5ca3192f58af57955bd33002402c6824834448ac33fb34d702d2e0d08d2bdcb8cf84c8401dd8ec1a0a493bd047c4c05912239fccde0dbd49730ec916afaabff66abd2e4d8bb351a938401dd8ec2a00f0fc4bae073bbeae37d8ff5395c95480fe5a9149bad4f0cd4f5e8e32d18b32e80515ed762f28c37e88f3d4f21bb33aa5fbd548f3bd168a4b4eeba9ed4c128f79f16886350f86283a571bd58d56cbe2ede5500d4261f8536677c4f24fd5542db0a00").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("35be0876c21a5a5726193d1adb8ce9ebb6eb95757407cafb9106a57f0d3d1222"), + } +} + +pub fn header_31297218() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ec2&boolean=false + //https://bscscan.com/block/31297218 + ETHHeader { + parent_hash: hex!("a493bd047c4c05912239fccde0dbd49730ec916afaabff66abd2e4d8bb351a93").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("cc8e6d00c17eb431350c6c50d8b8f05176b90b11").into(), + root: hex!("b111fd4d787edd2a9a54e9e76aabac9bedf7213ddcf44b9960f334c9303b0256"), + tx_hash: hex!("c81295cf7fdfa201ef13477519a25fd0749c8085acc05f59386291fb87fac10b").into(), + receipt_hash: hex!("6024c6edc9ef851420121f565972736a182e40a2c5603c40de6afa8c1848b83b").into(), + bloom: hex!("66a0839004a3501048881050821442000900040000814969480300289840012088035a00108000010a8810000142020081618811240001212020801000201a0404140848034000200106100898884434249023000244010020441200808006000a0b20201a0200182402005810002a401800c80c007e36260000401083c8041c0020c39684308058138424001c0010002824a40524a0100810081440184028a0a2d8180110814006022c40083b1001004000a010400200043001192823100044932045028012804600700820a92612402820010000040838011451d20800a4250838080102003100032184089002111440200b0426a050480010300000011001").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8ec2", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("35a2f2", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0cb", 16).unwrap(), + extra_data: hex!("d98301020a846765746889676f312e31392e3131856c696e75780000b19df4a2f8b58305dfffb860afc7a23949201ffc50f92c39cb6a3a42f960edd1cafc424b852f511da8dbc052c0bb0222baa6b3a560cfe41a5a7b95c709c11e05b6471366ddb49ba73d0a547b085851d45b51dfbff2cc71f2ca93ff0d6402ecf1c534f240e4b67dfec13efc38f84c8401dd8ec0a03f20b11009e964211f4ef2e316ddf214066d6e0603b6fa2a283b14133c0aeb1b8401dd8ec1a0a493bd047c4c05912239fccde0dbd49730ec916afaabff66abd2e4d8bb351a9380740b7c6a2a1f2f5083f10dc247ed6e6223edd986368179556bd9dd3d78949149357dd8ed2793a0c701d6b7df744261439b71ef4cd2ef9b189afcc2f8105745ac01").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("0f0fc4bae073bbeae37d8ff5395c95480fe5a9149bad4f0cd4f5e8e32d18b32e"), + } +} + +pub fn header_31297217() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ec1&boolean=false + //https://bscscan.com/block/31297217 + ETHHeader { + parent_hash: hex!("3f20b11009e964211f4ef2e316ddf214066d6e0603b6fa2a283b14133c0aeb1b").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("35ebb5849518aff370ca25e19e1072cc1a9fabca").into(), + root: hex!("158af1b358e1ab7c08fd65a742d3e36c372859047aa6d1f8b47f8c6ca1a21d13"), + tx_hash: hex!("2e308aa7adf3de39000a56dfd3596435e357304504b9ecb1401492dcc101cf88").into(), + receipt_hash: hex!("698a86c1d0922df0705634891cbc82347d693ecd9e6ec0201ac9b9ffb4006cca").into(), + bloom: hex!("14244b5f06401457d30562ee82512903900dd1291845c7203f3f49517c14a7b08eeb1643764ed0295a328daf585e442a87c0dc3eef1ab1195200248805275b88847ad90a0f564c1a133a621dd3ed006af41494d545467e5bb5bc80f9b4492d36ce2c12a7aa064353340d18a5c11659c04904a952bb45fd06a344ee50cb4db65090eaa19787bd929d10bf6608d508b19b24651ec5f916309b31b68cf88841c8becf098432529e06423a2e83edae3fb40226ea99652ac09398fa626db2f116c4c8a47057b20a81292e13d0ee6674a0d92221d50e6a8126ea1d835fdbdab2b8fc2e9cb0ced009a6e37d29d5a842f5018932486c87294162fae82017883c5e6960c4").into(), + difficulty: 1, + number: u64::from_str_radix("1dd8ec1", 16).unwrap(), + gas_limit: u64::from_str_radix("8582a4f", 16).unwrap(), + gas_used: u64::from_str_radix("d5aba3", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0c8", 16).unwrap(), + extra_data: hex!("d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b58305dfffb860887daa937dc51ef1bdc88a3f2e52f51ccc297a3439741cf23e3bc635ecca60413c070e136840b09112b15158b54887801215cd8e3354c552e03587b922c8aa3c444c55336eaefafbf88708863869316136f0a68e45d62c243eb5976dffe41656f84c8401dd8ebfa0d1cbcb756aa78425abb3fd8eb10e814c67b8cf6e7750458b8c597388bd8682928401dd8ec0a03f20b11009e964211f4ef2e316ddf214066d6e0603b6fa2a283b14133c0aeb1b80b2c9b0fdb99e7bf632bdb2ab30550cff337b15c9163fddc47c9cc20b9582c71343857e79a7dae2b38715d8cbecf111a2d1cfcfbad8f4b65abd6b67ad2eb97bb900").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("a493bd047c4c05912239fccde0dbd49730ec916afaabff66abd2e4d8bb351a93"), + } +} + +pub fn header_31297216() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ec0&boolean=false + //https://bscscan.com/block/31297216 + ETHHeader { + parent_hash: hex!("d1cbcb756aa78425abb3fd8eb10e814c67b8cf6e7750458b8c597388bd868292").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("b4dd66d7c2c7e57f628210187192fb89d4b99dd4").into(), + root: hex!("57ede97b62b05af1187766de108267b2f27537ed9edd1a9f7889529db4cca965"), + tx_hash: hex!("93775f7dad7f0678386501fd9419fbff9e902707687c7baa4c73478a74c4e839").into(), + receipt_hash: hex!("0e3fb454aa5489134df6457875bfde27c8eb43f092cf84cffb1f007d8acbe1fe").into(), + bloom: hex!("882cc625e0381010c60011c584004440a00b1121012c82100038612a16088082af04b07e28049011662125b1020680b08300148849480620d8262c280a640a081d7485d2514625203328e09802204128703622a52054820e002d0000c8148445c20908222a1605012229022681101ae2081010175041848624510818de623640110a2901466d5882229d258e1921042a8924158511203a8800c8c0508980102092050022078d1402270638cd3f0a1640cc058d0108128189308365a020c224d8242c1ce290c361864190899b1a0012542500061006104094031347462a02e424281808521004114021881c484c0041295950e26951e09448a002419000413b06").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8ec0", 16).unwrap(), + gas_limit: u64::from_str_radix("84fda76", 16).unwrap(), + gas_used: u64::from_str_radix("847ded", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0c4", 16).unwrap(), + extra_data: hex!("d98301020a846765746889676f312e31392e3131856c696e75780000b19df4a2f8b5830ddfffb860b01dbdb421b9fb5b1f71f196b5e1a8979b353ebfb25bf1a0ef31cc692139df7918b4d2db38211f91ee023bbdf78ac50b00d1497f7d90e42adb7826b21c129d5c706219f37d9216b27be379a4f2854149fa744ef734e8558070c5e8c4fd794c5df84c8401dd8ebea017148d821da270f09540075131924b934bc0352dd71d8b8f60274f39d73231dd8401dd8ebfa0d1cbcb756aa78425abb3fd8eb10e814c67b8cf6e7750458b8c597388bd868292808cc4af67170aaa12f7d2c44f6bec754eadaad71cf12df86ad87667fb2a9579940c3a579e4b5bb1c63c02b488429d683c9e3599b0583f0e4015e98d674f58281f00").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("3f20b11009e964211f4ef2e316ddf214066d6e0603b6fa2a283b14133c0aeb1b"), + } +} + +pub fn header_31297215() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ebf&boolean=false + //https://bscscan.com/block/31297215 + ETHHeader { + parent_hash: hex!("17148d821da270f09540075131924b934bc0352dd71d8b8f60274f39d73231dd").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("b218c5d6af1f979ac42bc68d98a5a0d796c6ab01").into(), + root: hex!("a6e3d060b775a05eaa251583fb248df682fa839bd575d254eb4330d6c92f0356"), + tx_hash: hex!("4a81457bed752a8611a3fcf1409e6bfc34c8006651f64e6fdb5530a113d8972c").into(), + receipt_hash: hex!("a8539e4e87b5ce8ee15a3f9c52113062de8883c1ea062255959e3f3f5350ec00").into(), + bloom: hex!("1177e6c48819553fcb1800dcc612126e24206a13cd4d054bea0a07b81f00a03e8e43f8c2c280905102227a9355da28c18e1c000a071c61a140352328113d228007d640114bd00c69db01a449c835706ca8dcab8040744802234e841088042eb42a9d23365e262a370c0d001693eafc4348a6a440294fdf23010ac910944b6df8888ec3142b5440dc30aa5500a894fc9bf0b646857e6838de318cd1c300929c20828da412533ae674b610cb1e6f85e54008a4d7d0878286a57469a3b57752a2e7b38f14828276a80e30ab1c48f23650e0b41447e5c14f0417819e7d87833cefab519990032ef8e7274125026a8163152c278085a9d078c67c23b87d00da15f00b").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8ebf", 16).unwrap(), + gas_limit: u64::from_str_radix("84792e5", 16).unwrap(), + gas_used: u64::from_str_radix("aac551", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0c1", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5830ddfffb860b9b1a84b0ce0243a5b8592ffc6562f1f9f6e95197a1ca1ea17eb300b4f101382aff91466a179e5b9ad4fa3423f6ed40f14edef5a8addd5590754049e9828001b3aa9e355abd098b01b059781512654f9dce636865e6dd98c9c41066e09f64af2f84c8401dd8ebda0e5ec815463a14fc0a652302d302e93c2a06280d115782a183f5378692e8638288401dd8ebea017148d821da270f09540075131924b934bc0352dd71d8b8f60274f39d73231dd80615eb294cc6f3c9f5a307dca23199a3844bf63b9078c41d457d7732a7956189a4b68c910d5ed0eb7fe4e7432061ab9ca6bccc150099a5ad554112aa34494cc6801").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("d1cbcb756aa78425abb3fd8eb10e814c67b8cf6e7750458b8c597388bd868292"), + } +} + +pub fn header_31297214() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ebe&boolean=false + //https://bscscan.com/block/31297214 + ETHHeader { + parent_hash: hex!("e5ec815463a14fc0a652302d302e93c2a06280d115782a183f5378692e863828").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("a6f79b60359f141df90a0c745125b131caaffd12").into(), + root: hex!("46c90c2a67cf640eaf1c7e9b627bf137df627a4aa602c7c42cad02e6b3aa61ae"), + tx_hash: hex!("348bee6e3ed5a24936ef58c39a5656f7390ccf15023f76c902385bb37b88ae73").into(), + receipt_hash: hex!("5c64f76cfd4aae1954bc309191547a6bc7a3fc3811867a9d0501d4c49e37f7d7").into(), + bloom: hex!("30a757670ff6b7b08a55e045b7df00da267969e3bea749623a324fbb1fde51d39c565fc3c881c27d7e945e09565a63e3c39c4cd9643a24855c28269ae0f0e0e1f67db0e995680de41f71155b8a7ca0a9e89e9cac436d8189d56790628f81640d2fdf596efaaa124fbe2bb75a232bbda10ae0ca31349b7f643302c97a8cd106e7944d79ae139d6bf0bdcd5fda4cee1b8bcde6a5917911f1a8bc7198d4c4fa0cf98adaf037da23ab21b64edbceabef154056af8de4499885a157a261a0218261ae78983ed32186ec7e7692dc3b761271a22853094b0d35a8b78d30570a46a1e528923c9ce10182f1061b1d6ca3e20ba15067e6aff726fd7a4aabbc3e883c754dd0").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8ebe", 16).unwrap(), + gas_limit: u64::from_str_radix("84fe2c6", 16).unwrap(), + gas_used: u64::from_str_radix("a0a9fc", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0be", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5830ddfffb860b6b6980dabc6fb7a8e6563155150083f04f73a6a2ea6532eea4bb56ed5ac2178e20c27d0d4dac3e8852cc79c87de3c1d174a26ad0ef211e4e948881ef0c5dbe49cdb3919997e42f79f126ccc0fa879eb750db937033427666fbf8dc5f29e0b81f84c8401dd8ebca0c74fda0e42d712edb445971bc504af27873c62f5f8dc7392f0e04a07026cff188401dd8ebda0e5ec815463a14fc0a652302d302e93c2a06280d115782a183f5378692e8638288098360d498a03e2a7f8452086e83fe23b3fabbd623ddd30369811af6f592b54c520675d0e73882204d5b97bf391fab38af5ee0d58cd1b2f60869a370e3c4c5c5600").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("17148d821da270f09540075131924b934bc0352dd71d8b8f60274f39d73231dd"), + } +} + +pub fn header_31297213() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ebd&boolean=false + //https://bscscan.com/block/31297213 + ETHHeader { + parent_hash: hex!("c74fda0e42d712edb445971bc504af27873c62f5f8dc7392f0e04a07026cff18").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("8b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73").into(), + root: hex!("d7dc8b11d03723bc786b44fbd36ef47ef34471e1b7020f6d60a9239d44a5e4c8"), + tx_hash: hex!("90d350b4228b27f146ba9917abb86c867b6846ee277f38daa2fe908cdc8450f2").into(), + receipt_hash: hex!("23f67e6e9fa18049ca3a8d2984d1ccaa6d020b9d6ed37e72bdbbe6c81ff0f5fc").into(), + bloom: hex!("ad6ed6550e5cb77aa96db8f5eeabeed6f08bd2cf97cc48f8a3fa63eb5e89895aff4c1953f649d52773a33ae7f75ffe82dfd28ed945bd782f237fee1f9c6c6b9c8e54d4fe2d534c3b95f9ee8d8e1c22bf63b4e9a6d0e7ecd8effe51da8a2d2e31cbbf2a7e7b3fac29b4cd3d16dfdafbdd7acfacd3baadf58b7e47879ff04acecfcecf7da7e67589c9b6bf77901c875b1d5a769ec77e68fe9f755931cc907794e99a4c27e37bf6b7526f6eb65edb9f7ec2c0e6ada9438bd5ef3feb25a37df6b9f5a8ef7dd398430b6712f85f66b3741aeffde7d763c45b4ebcadbff5f6f23ce776f1fdfefb37f4d53fdb2537da5fe5cb77bee77ff59b3c7dfdfde3ff9c78e94ade").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8ebd", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("12d7505", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0bb", 16).unwrap(), + extra_data: hex!("d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5830ddfffb860a7977214b4091a4d9b36b958bae429233d1c122d2c691f4cd9f34768b72b1cc391a23d5d7752d06177d6f870e32ff3f41553ac2e4e16c44adb75bf0f78894bed963b77213057866a75954538741a296446cff7d19c68123c8b710252bdf52c73f84c8401dd8ebba096014f0baf3bd1f8096f66e7ee026238ac2e2d199c00e2bf2cc5c0183ab47c4b8401dd8ebca0c74fda0e42d712edb445971bc504af27873c62f5f8dc7392f0e04a07026cff188021b063740fb3c1e3a639e7a4ce20a7b58abcc5718a1c8e78677eb75f1e4f86a514fbc225bbb3229f7b8dbc26de24eedf456f1184bd67418582270fe25dccc09b00").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("e5ec815463a14fc0a652302d302e93c2a06280d115782a183f5378692e863828"), + } +} + +pub fn header_31297212() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ebc&boolean=false + //https://bscscan.com/block/31297212 + ETHHeader { + parent_hash: hex!("96014f0baf3bd1f8096f66e7ee026238ac2e2d199c00e2bf2cc5c0183ab47c4b").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("ee226379db83cffc681495730c11fdde79ba4c0c").into(), + root: hex!("375f3881abfe517cfef67f6fa4e4e6a6cdd55f59daba5bf549e42cf0f0bae4b9"), + tx_hash: hex!("cad310793c8d7a169ebb1f0bf1499829af25ff43a96620bcf8e4eaad746d09eb").into(), + receipt_hash: hex!("5f33ebd5da8fc4a50aad629c197df5ad9fa11b386856d7eca9e7198c3fbd8cfe").into(), + bloom: hex!("0020630015319710008002d788aa0006e509288314201202106a2105bd045316ea6050784001b60422282e8a0107c10081543311500c20b101900009d0e000900547848a555c0828250153880440a031b4134cc90c61cf08082c0a0084100660480a24343e6609090665c81083080873a884d47a860fce524101281480ca08988448aac0204003d7069a042320028080016e852d713a640c118059400d921c692a008826018046102200d24402a006204a0294040a0484e3d1a025f04b8187640122d507809022020004884157327008ac08030680202612451c44e30605a52d651050452804662b411c06a0016203a020040c2419284448a06155088081610d").into(), + difficulty: 1, + number: u64::from_str_radix("1dd8ebc", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("8dafa1", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0b8", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5830ddfffb860a3fc89fc965524cbda1745ddb014024d04182e9da19f4f508c998b2f5236d553b042dea0f061262eea3fc046799555890b7c054721eed6d48bb2e1e20e520fff107617d2002090b781d866daa35943464bfc575abacdc000ac019a642565e108f84c8401dd8ebaa0ae86b11151a6e6bc2ee0b782bc806d02049f9c50c7187ab0e398b4faf504ba188401dd8ebba096014f0baf3bd1f8096f66e7ee026238ac2e2d199c00e2bf2cc5c0183ab47c4b808e9209f39c07332b1163d586ee07e35d16ba59dfd8484e9980cc7b128c55f86374eee7f035aa2bddbc8d6a3bc7707014e6884c2f95692ee683dd3e4440feae8300").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("c74fda0e42d712edb445971bc504af27873c62f5f8dc7392f0e04a07026cff18"), + } +} + +pub fn header_31297211() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8ebb&boolean=false + //https://bscscan.com/block/31297211 + ETHHeader { + parent_hash: hex!("ae86b11151a6e6bc2ee0b782bc806d02049f9c50c7187ab0e398b4faf504ba18").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("be807dddb074639cd9fa61b47676c064fc50d62c").into(), + root: hex!("25a1b664bacf9cd2c46f9eaa16ea6b21b0eb9e186a99ef0895746e00527d2c85"), + tx_hash: hex!("8bd39094bd4ec2b55e87eafaac3c1c34a523fc68581789ed64fc7ee81f1c3a6c").into(), + receipt_hash: hex!("868924fa9b72d69921a4822b4c248bc6912d1e0b07f95733bfd4cb19f9711740").into(), + bloom: hex!("0226d26210015a9200800bc4841410020000c000010ca902200001a0041020108a81f06042001012e030290002580185ce5090181182000c201b0400146c404c6b630011b9420050211881e9022510e82170e80209e40d18040e081c82820695422d0ca20e072249310c0804212038220c00800911235600004784b88048310000184da443149c840894a50e003301c8052624c1ec0100ca440600c8810854ad0212c002761c2222b124760c0e09240245380908578808004528916d5002a0b40824160318060b16308298c0403bf96420c30264000940376b7a4042221ce130903aa02810504100091114c2010859040890f22600204242a042011019110b43").into(), + difficulty: 1, + number: u64::from_str_radix("1dd8ebb", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("6da01d", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0b5", 16).unwrap(), + extra_data: hex!("d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830aefffb860b2cd9aa09d1b6e9812ab9f8135e8f1d4cb19aec1caad116b5f3e9e2c9f8b8c6491b0440640fbaa8e560c933d34726e090fc5b2958f86ccd547b9edb5b1e7a628e8176bf3eaab5126e4eee4876c1f8fac77ab421906cb31cbdbdd3aee7ca2647cf84c8401dd8eb9a0cb51a23528c482caed2ead54edafc305f0b9ee8b6bd579a266433e28e857d09a8401dd8ebaa0ae86b11151a6e6bc2ee0b782bc806d02049f9c50c7187ab0e398b4faf504ba18802db553b0ae5d2fd84035d0054004e044ac57424d7b3e10a696c914b563c1c65c702608d9eca7410647cdab23741cedb277efd52d151f0db53e88d8e7f21ac70100").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("96014f0baf3bd1f8096f66e7ee026238ac2e2d199c00e2bf2cc5c0183ab47c4b"), + } +} + +pub fn header_31297210() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eba&boolean=false + //https://bscscan.com/block/31297210 + ETHHeader { + parent_hash: hex!("cb51a23528c482caed2ead54edafc305f0b9ee8b6bd579a266433e28e857d09a").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("7ae2f5b9e386cd1b50a4550696d957cb4900f03a").into(), + root: hex!("5d69f7ab2b1c76fbdbe2cf91ed2b2d515ab9e4e614f12377a29bd7cd16536481"), + tx_hash: hex!("d3d9091b8812a471b890629fc2dc64dbc5756c054e50b77dc41f9c59c35428f5").into(), + receipt_hash: hex!("6522a3bf645304f5698c92f770c022b735b08c97113cc2384c888d8a1bb5ed15").into(), + bloom: hex!("10a0926ca4b13410082800458641a0861014400700804248c4444dd012403411cf4090a044069000da2434209216d8c85b87e818010a622020000000c07002592452cc6e9341952ab1320789a82659bb333e812007400a902647003d818002e9206c233c0a428028241b008209428b69080048511452ef8f8002409457d801008c8aa1940238010ad0e115200c14188c79f6a687a88294a9ab0082400a1b04bd421ac060568303e4400a49440e043910a690840068608024408a49e01280138420093f4608a02986d0d012bd380210a2a0506242480480d53350c9820280a000503cb80c00403b91253914a0e90205c04560a6188a08626000133d4017c83491").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8eba", 16).unwrap(), + gas_limit: u64::from_str_radix("85832a7", 16).unwrap(), + gas_used: u64::from_str_radix("6bf9c2", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0b2", 16).unwrap(), + extra_data: hex!("d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830aefffb860b81cf27049e5890b663de5dc314505ab868cfceb20ec851a3e537af30569f8c49f591367b8c5174e459a56a0d9e85fde0d1866d9e03c7d07474020208077c83fd57067f8eb2c4b0522492dfc7d49ab5a769b54649f7e3832304778500d0b9b4ef84c8401dd8eb8a077545edd1aa19c89e81b0a1360ab862aab49c6193a18a52ec22f5922c56a17b68401dd8eb9a0cb51a23528c482caed2ead54edafc305f0b9ee8b6bd579a266433e28e857d09a80d23e1ee55dadb773514c3c830f784738af31c5d200e7ce02c026d31bd4b6a8b00420627f3ea649ae451250d8dc9afa1f420640f24165a6cde33cb9402f58688b00").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("ae86b11151a6e6bc2ee0b782bc806d02049f9c50c7187ab0e398b4faf504ba18"), + } +} + +pub fn header_31297209() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb9&boolean=false + //https://bscscan.com/block/31297209 + ETHHeader { + parent_hash: hex!("77545edd1aa19c89e81b0a1360ab862aab49c6193a18a52ec22f5922c56a17b6").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("72b61c6014342d914470ec7ac2975be345796c2b").into(), + root: hex!("64b13ec7180a8d694195c275043ce997f75a544e0a19947beae10e6e994061c1"), + tx_hash: hex!("cc20a7302764361da8a1b5068c523de3f56be6c71d6f83cb27ba9c648029a6cf").into(), + receipt_hash: hex!("c6aa644b38dd0efd1238ff89a1f07dc346c4a231d5a8fe1df2eadb30ea1386d6").into(), + bloom: hex!("8aedd6798fb8f77c58254df5a5c035cb9246ca6b34b5d641e63251ebe88cb5d1badedf4fe8e1c9a9bf20ee3e65da52e0ef246de10628e671dfaee71295e622a254e3ea4b2f4c04c507f004d8da28042f21b67555c26d835ab68cd11995a532d94addecf6fa4f7245886d05ab6101e9aa7921b64ea0ef57a40d30acf7eb4f1e465cc9402f0c575b0f95f82454361f7b992bee9e97f96e82e82b2b20e83aca7de5862f9861fead7740edcd3fee5fce681e47a118f565a0795c7be6ed26e15e43da38775f4a7596196ef920a80a6172f2a2eb1f21d904f5ee170955548e0832e63d9279acfa822763113b197a576600cbf0c98c1cf9767c61f2ebaf9ed8985d799a").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8eb9", 16).unwrap(), + gas_limit: u64::from_str_radix("84fe2c6", 16).unwrap(), + gas_used: u64::from_str_radix("d94391", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0af", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5830aefffb86083d57dd73e56f4c2e0bff865baf921a537e93264fada64e29bb5a1d40bd30536aa019783c89a15462630cbfef1bad4ea083249423996a0214a1c982441f857c45cd3fc5c056d8404a317784274aa46b52187ecbe892cdd8f56bbceb2a0962faef84c8401dd8eb7a00d16a0ad7ea094c72adfd206bfc939627a0d254bed38ebb4ef940f3cb82a68b08401dd8eb8a077545edd1aa19c89e81b0a1360ab862aab49c6193a18a52ec22f5922c56a17b6802ac5addce6b711b4030e8e2a8c7cd96d5c750821a70fb38a69547718d1dfbaf770e51cce4dc3e090c45c2082d2d457e517fabcc180172276132f637597a0affc00").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("cb51a23528c482caed2ead54edafc305f0b9ee8b6bd579a266433e28e857d09a"), + } +} + +pub fn header_31297208() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb8&boolean=false + //https://bscscan.com/block/31297208 + ETHHeader { + parent_hash: hex!("0d16a0ad7ea094c72adfd206bfc939627a0d254bed38ebb4ef940f3cb82a68b0").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("70f657164e5b75689b64b7fd1fa275f334f28e18").into(), + root: hex!("7aa465914e03589dcd98842483bd1a94539fa2512f4c3d60d28f34c247a51010"), + tx_hash: hex!("050d6a35f73760b00e23acc15f81e59ba332afad6346454d86e45a18801fb9e2").into(), + receipt_hash: hex!("d0dbc4ad668f41a42680484f7dfe4c6a2426387a9288d15211e307bdc06c4042").into(), + bloom: hex!("85b697030202101080019845e620d0122020e60102a040b20538cf5105800012a9049801e0829014439463084218000d5112900c4612ad0004072002013009c20460901885000081099801891030807a6034020201580e06a00cb15880030ed5a44d34682b260028c22b101c618b0c403c0428408e0194043220a4398049168220ad138e0b121a20108035000818035de0263dcd386331e92500005c102ac824a70a4433da24e2012c03af0f9e466e00c5c885c0b2a00cc9200059e8404070c8f80c34264240082696c88cb04188b06eb0600020100020142f5042031882ea2c7510858003002310211da44291282320080c0e2a0ce03c60280cc82408688c02").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8eb8", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("723c7f", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0ac", 16).unwrap(), + extra_data: hex!("d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830aefffb86081325d65523a881b1ca4bf500f9f030d2fcfa3fdb0e8a65fd8d5bad40a2f727de043a37875368cbd7e9e3573789b3fad0ea31c0f29521c4eef1a1bf63cfd4570b21493de83b47bbba1cb7b5eda6c120291a053a2463029fc8fe0fc55c798c638f84c8401dd8eb6a04edb537f71dc11604b10251c74ec65f9f5d8b7b49823a4e6b3fa635043ab066a8401dd8eb7a00d16a0ad7ea094c72adfd206bfc939627a0d254bed38ebb4ef940f3cb82a68b080faf6d5df96b30eb3f7670e25e8ca826f74d8ba9dcedbdcff2650478271b7cb1c35c7335fcfc5e3469a4e24204573d05bd5979c5d3371d762cd8951a06d31cf9601").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("77545edd1aa19c89e81b0a1360ab862aab49c6193a18a52ec22f5922c56a17b6"), + } +} + +pub fn header_31297207() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb7&boolean=false + //https://bscscan.com/block/31297207 + ETHHeader { + parent_hash: hex!("4edb537f71dc11604b10251c74ec65f9f5d8b7b49823a4e6b3fa635043ab066a").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("61dd481a114a2e761c554b641742c973867899d3").into(), + root: hex!("53470cabcceb59cb1791c5671c730349effe4cb1e905e59a669a992bbc0108a3"), + tx_hash: hex!("744ae570d1a8a93909fb7103ebcd6fe954e022b672b5cb9be489432c488c1ff7").into(), + receipt_hash: hex!("f169c9a2f0b634c358d264f7a07b9394f4ba0835dee24ae20af9a41f535eee4b").into(), + bloom: hex!("22200260065295f9805a3140ec14002bd420c70084001e84a22a050291381010c2021140408010000631242a001e3010a2a4c00c1418a5210306289863a422f01c41962081408c008bb200a8a00839b8221016a101628002602c1840a0300e218a4c002a1a035c012e534064d4080f3b8b50ac35005b5e02c901a812a00040514881390412f0f8d0009445770ac2448e563615036910001829c000c18ac24c280382a0306380cb13c280c6070fc4940860a0dc4100c9a02378208460611002e06806150624101847105208070031b760248332c7c2140254859050c30c00ec04119094078d21c18003079442a14001240c00202a28a8ec48010704009c214120").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8eb7", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("683daa", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0a9", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5830aefffb8608968a3375fc9df9fe293c2b1b932f2c6c373c16c6a8ad803653c4b2e37d36954ae620e82ca7ddf800afcf43d2152ae0f03c242b5afb6917cdd19076363647ae7b62841d196f0c75084ceb616db03de5f57e06a83e743a7c4f7d3ba9ca73614a8f84c8401dd8eb5a0194822ef17f86aa711f97387a2fed416227806f12a957715630f25a0a06042818401dd8eb6a04edb537f71dc11604b10251c74ec65f9f5d8b7b49823a4e6b3fa635043ab066a806bb80e19c89b75c476fdd6d654c9391e3699257bff38af792b757842bfeae34f5e2af403ee3017fd6d774509b782b80dec4a343f47048b788e8868e80d778a6200").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("0d16a0ad7ea094c72adfd206bfc939627a0d254bed38ebb4ef940f3cb82a68b0"), + } +} + +pub fn header_31297206() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb6&boolean=false + //https://bscscan.com/block/31297206 + ETHHeader { + parent_hash: hex!("194822ef17f86aa711f97387a2fed416227806f12a957715630f25a0a0604281").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("3f349bbafec1551819b8be1efea2fc46ca749aa1").into(), + root: hex!("bbc943551df90ecb01b15f521ccbd5780063c41f6273689690415206d6683a25"), + tx_hash: hex!("20bfdae2117df689c699d7b0402bf4878740879fad11350afdf53cc8b7b96b5a").into(), + receipt_hash: hex!("1a40aa2cd1b1e174f8ad0ae1e3f7a9918c6da6297238ffbaa9db907a44b96b6b").into(), + bloom: hex!("1ea0e6d21a3ebf7e894421e68e1475dfc39bc6d28728cb0a322ba16f5a9459128e66116753377025dd23beaa295e2a98c7512c89510c21356d946e983d2f36b87446c66ec3482f288358c668c35449ed6cb2bda772e68b0ae0c5a856d5c38e35cb0d3d268ac7dd012a5f5974257a6deba8c974db8f4f7e270a2b9e58e8e9d39549c8b18626a871996a86a61518c03fcd147564556d74169d399a95dd18da7ca15210288a43e587d5f61e5fcf9ba51556cfb6c5c10d72d2a534364f212f5123e57827950bd790bc4e70d8baeb49303265b967176a950839762f1ad4d2c90de6fdd55ca249bb37d93fc9959eca99030fa03137df6502ab54d5d9323bd2dea1c6df").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8eb6", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("f96c44", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0a6", 16).unwrap(), + extra_data: hex!("d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5830aefffb860a0138da8d8d9e4f6f61bab7567e04099cf03ada629e8190af22cd4ef64a03f6c429065f576709c7b72cefe9645f4dd9f0ddbfa22e3510b0d4e9a97441d2d00ca1807a072d34cc6551a97c48db9b188de7911f5ec56a061015641787e47fa0917f84c8401dd8eb4a055ac85646e4961091af47efe4cb44edc27446ee7b843e9ca88bd2410cabbd0bc8401dd8eb5a0194822ef17f86aa711f97387a2fed416227806f12a957715630f25a0a060428180f032d9041437495d44595befbb88540d3e87e4a6407fabc164295aa399d967090d860b2500045f33a37a7292d8d9314a0703a075d8e6de54656d16c5d3a64afc01").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("4edb537f71dc11604b10251c74ec65f9f5d8b7b49823a4e6b3fa635043ab066a"), + } +} + +pub fn header_31297205() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb5&boolean=false + //https://bscscan.com/block/31297205 + ETHHeader { + parent_hash: hex!("55ac85646e4961091af47efe4cb44edc27446ee7b843e9ca88bd2410cabbd0bc").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("2d4c407bbe49438ed859fe965b140dcf1aab71a9").into(), + root: hex!("0fcf463d8fb2dbff492b65e6f79af26d23e80c288aa7724019aa4cda75652061"), + tx_hash: hex!("1820a50d43fdc3cd2117af385955c896959555b3573590af364c6f8185646a74").into(), + receipt_hash: hex!("f498551fbc5c1298f3ed791a80b76750c6679c21b289a0c56bf3bb0c82491e37").into(), + bloom: hex!("20600602072a1118041000448416040501408082118b09015098050311c641088e00f900202410400100364f171642a483260e38042000082126480200243226240094c8994016a08d30b4c9c280a4a02810b420004e8813a42c0850810000e1cbab30273a261029886d080303492d184814124096c93c141021ac188852063d888a81250648e0919080371602795b08042644056b04009821c03944a0315ce01252611032b2010a2502dc9e0e800000a01001090700118130b60123e45020c8c858048a2642804e00a0886162229808e08801e285402855091ac4420021f5be0c18909084a6812a0190044ab003c982880494bf2031f0d839402481492101da").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8eb5", 16).unwrap(), + gas_limit: u64::from_str_radix("8583b00", 16).unwrap(), + gas_used: u64::from_str_radix("5f1ae3", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0a3", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e31392e38856c696e7578000000b19df4a2f8b5830aefffb860a8b4e7e5f158135b806ad8d725138c902ebce597c98f0205d3b2072b3ac06f1712103a9ba0e6b0da115364a28048d2ee0380cd09eecc422408390e716ef372c1cb6a4795898d0b3136019f53df637ab55aa73afd35b0c1da54a9762be654b472f84c8401dd8eb3a013901357854d7c35878d6ff9a24714e0c21f1beb95e0b55667b915d2d74c729e8401dd8eb4a055ac85646e4961091af47efe4cb44edc27446ee7b843e9ca88bd2410cabbd0bc804f894a2e6797eef8cb87e611a4d04c9d9d382a3025d0f21233992143acfdfd451598f85f09da424e6f1051aa4e3ead85b21a769d177c86d264799f13a4883bfc01").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("194822ef17f86aa711f97387a2fed416227806f12a957715630f25a0a0604281"), + } +} + +pub fn header_31297204() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb4&boolean=false + //https://bscscan.com/block/31297204 + ETHHeader { + parent_hash: hex!("13901357854d7c35878d6ff9a24714e0c21f1beb95e0b55667b915d2d74c729e").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("295e26495cef6f69dfa69911d9d8e4f3bbadb89b").into(), + root: hex!("74f96bbe3fdcb97aa80f9865f150a32bd3640761feb026457b8ccf9c81a4d0b3"), + tx_hash: hex!("704032ce0e736aa129323696270ba0c4f4c226770d5a5769b477f20028c69528").into(), + receipt_hash: hex!("85796e78bcf8868383deb17f5794af1ab2a02920410faeb25dcdce0a2114d49f").into(), + bloom: hex!("9feff27efd2db7ffcf7b7a47cdacbe47305ddb6377342ccf63fae53f2861af5e9ea43fd9ecc15ddf1bbefee2cf7e5b0daee7599ef32f7fd3749eeddf6f7cbe9bacdecd9bf95d893fa17ee69f9aa794eaea9287fd53f6aba29fef91678af61e79cf7cbee3ffae8e87956fdf6bffdbadfd9c8ab27dadfb5dcf7267cdfd8fdb8febddefa87757ddbce536cfef151c57efdb97fe7cb77bf3fcdff9fe91dfbcffdcff9f033ad3737b378eb607af6c1fef94d4fc2aea7e9b7acd9df3e963e47ffb55f8eb3b35e31c7cadff7dfa0e6e71fa9bb1e5d7f6eecd29fa35ff57fddef394f9e9bdf3ed7b15e577cb7fbd16ff217a23a6fe76863bf3f35b692b0256b4b9634c5e").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8eb4", 16).unwrap(), + gas_limit: u64::from_str_radix("85832a7", 16).unwrap(), + gas_used: u64::from_str_radix("1ab0be2", 16).unwrap(), + timestamp: u64::from_str_radix("64eee0a0", 16).unwrap(), + extra_data: hex!("d883010209846765746888676f312e32302e36856c696e7578000000b19df4a2f8b5830aefffb860a37f1a0dc4fbaffca02601db7fa52727bfc120101001a10a628b33340ae2437e34bab00c59ee3b77041899328ff816e0011b7f664c9837756fa64c824802ddcc15405628f667d07c6120161e68ef8c6ab2a5b03faf109f53254d9f65747781e4f84c8401dd8eb2a094fd52d22bffdadbdb22f6d8f5ff8843d7bb47cc4ed34170168862437d830c798401dd8eb3a013901357854d7c35878d6ff9a24714e0c21f1beb95e0b55667b915d2d74c729e8096c7d1f1f9dd8df490346a9b3e2f9cc92ee320217cc08dd253159cd50e3029052d9de5c19162eec1be3458eb7cb31e97dc9b656d80e92c681558beec028045da00").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("55ac85646e4961091af47efe4cb44edc27446ee7b843e9ca88bd2410cabbd0bc"), + } +} + +pub fn header_31297203() -> ETHHeader { + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb3&boolean=false + //https://bscscan.com/block/31297203 + ETHHeader { + parent_hash: hex!("94fd52d22bffdadbdb22f6d8f5ff8843d7bb47cc4ed34170168862437d830c79").into(), + uncle_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + coinbase: hex!("0bac492386862ad3df4b666bc096b0505bb694da").into(), + root: hex!("a5c326c2677e2d80a74326c1fe409c492f062679664307411e769aee4439b68c"), + tx_hash: hex!("7c506aa939b812971d33f7382e444605b41e4d3c457bca15de3d18a9f9402a69").into(), + receipt_hash: hex!("9db976f1d7b56eec4ef92e0e8e38eafc9141f0359931b7265f59088a37adca9d").into(), + bloom: hex!("4e6ccf91b23a34dacee649efb31f6c7fc6397cc97b6db5d4527ac96c345d4390af6b74c9fbde9f372fee7d6040be274efd351c57268efb67fba605bb9d6b4b9ce6e9edda9b56288381755d3dcaa164bcadbc5334fff2a9bf89bfd521e3e09c4d82bfa1ba7b2f7bd5221da9f1f361ff79db4505473aae0fd6d37ddc51b1672d84339ee90445e57bfb3f96e43798fa2fefbc2d2fe779d29cd92fe40ad3e6da47e5bb0f6afbf7ffe7beeec66fce26efd6dad63f41b953bfd9e5f6b4ef68f4df74697093d70eba27bb7b33da8eefcd9f7e2bf6d783af65dbcf173976de52e20dfd3717faee6fae56fd9f2d9737d69bd3bb66e1732f8af6f446fd7a26d81c6b69efdf").into(), + difficulty: 2, + number: u64::from_str_radix("1dd8eb3", 16).unwrap(), + gas_limit: u64::from_str_radix("84fe2c6", 16).unwrap(), + gas_used: u64::from_str_radix("ee1aa1", 16).unwrap(), + timestamp: u64::from_str_radix("64eee09d", 16).unwrap(), + extra_data: hex!("d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5830aefffb860a70735caccfcae04b5262d8f2fddfdde93b01c2b9c05319abb844c5512c30ef105491ebae1898c217ee585b5895159e40068f1f80f52a8d302cad34503cbe3a9d765708388e75c15b3adf8a27697b5afdeaa93d60c4e2668dd15244eb39115d4f84c8401dd8eb1a08398b4664eb55beadbbbb8ec08dbacd78322cb3274dcd8bb53999be2b784cd928401dd8eb2a094fd52d22bffdadbdb22f6d8f5ff8843d7bb47cc4ed34170168862437d830c79809b4e20566a9f785f109a5821474cdabf036fd19e217405b8de50e2deb9896dac59c62c8e39c32e3b48e5e37d335c528bc72ca86f0142959b37cb6a9fe97d76e601").into(), + mix_digest: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + nonce: hex!("0000000000000000").into(), + hash: hex!("13901357854d7c35878d6ff9a24714e0c21f1beb95e0b55667b915d2d74c729e"), + } +} + pub fn header_31297202() -> ETHHeader { - //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb2 + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb2&boolean=false //https://bscscan.com/block/31297202 ETHHeader { parent_hash: hex!("8398b4664eb55beadbbbb8ec08dbacd78322cb3274dcd8bb53999be2b784cd92").into(), @@ -58,7 +495,7 @@ pub fn header_31297202() -> ETHHeader { } pub fn header_31297201() -> ETHHeader { - //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb1 + //https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag=0x1dd8eb1&boolean=false //https://bscscan.com/block/31297201 ETHHeader { parent_hash: hex!("e3439a5ce7e27a9755611e2aed8533ae2b0108ced5610f88d69fc97fd54e832d").into(), diff --git a/light-client/src/header/validator_set.rs b/light-client/src/header/validator_set.rs index d656e3e..73867b6 100644 --- a/light-client/src/header/validator_set.rs +++ b/light-client/src/header/validator_set.rs @@ -1,4 +1,3 @@ -use crate::errors::Error; use alloc::vec::Vec; use crate::misc::{keccak_256_vec, Hash, Validators}; @@ -9,13 +8,12 @@ pub struct ValidatorSet { pub hash: Hash, } -impl TryFrom>> for ValidatorSet { - type Error = Error; - fn try_from(value: Vec>) -> Result { +impl From>> for ValidatorSet { + fn from(value: Vec>) -> Self { let hash = keccak_256_vec(&value); - Ok(Self { + Self { validators: value as Validators, hash, - }) + } } } diff --git a/light-client/src/header/vote_attestation.rs b/light-client/src/header/vote_attestation.rs index 5fbcd84..86cfae3 100644 --- a/light-client/src/header/vote_attestation.rs +++ b/light-client/src/header/vote_attestation.rs @@ -44,7 +44,7 @@ pub struct VoteAttestation { } impl VoteAttestation { - pub fn verify(&self, validators: &Validators) -> Result<(), Error> { + pub fn verify(&self, number: BlockNumber, validators: &Validators) -> Result<(), Error> { if self.vote_address_set.count() > validators.len() { return Err(Error::UnexpectedVoteAddressCount( self.vote_address_set.count(), @@ -57,8 +57,8 @@ impl VoteAttestation { continue; } let bls_pub_key_bytes = &val[val.len() - BLS_PUBKEY_LENGTH..]; - let bls_pub_key = - PublicKey::from_bytes(bls_pub_key_bytes).map_err(Error::UnexpectedBLSPubkey)?; + let bls_pub_key = PublicKey::from_bytes(bls_pub_key_bytes) + .map_err(|e| Error::UnexpectedBLSPubkey(number, e))?; voted_addr.push(bls_pub_key); } @@ -165,7 +165,11 @@ mod test { header_31297202(), ]; for block in blocks.iter() { - if let Err(e) = block.get_vote_attestation().unwrap().verify(&validators) { + if let Err(e) = block + .get_vote_attestation() + .unwrap() + .verify(block.number, &validators) + { unreachable!("{} {:?}", block.number, e); } } @@ -247,7 +251,7 @@ mod test { validators.extend(validators.clone()); let header = header_31297199(); let vote = header.get_vote_attestation().unwrap(); - let err = vote.verify(&validators).unwrap_err(); + let err = vote.verify(header.number, &validators).unwrap_err(); match err { Error::InsufficientValidatorCount(actual, required) => { assert_eq!(actual, 17); diff --git a/light-client/tests/ibc-parlia-relay b/light-client/tests/ibc-parlia-relay index e9c03ea..edba073 160000 --- a/light-client/tests/ibc-parlia-relay +++ b/light-client/tests/ibc-parlia-relay @@ -1 +1 @@ -Subproject commit e9c03ea6c440f787c17e58307fb7d5013b6ae7e2 +Subproject commit edba0734df82fedc811600b32f6f3d79d9aa839d diff --git a/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto b/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto index 91872d6..c9b31aa 100644 --- a/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto +++ b/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto @@ -26,13 +26,11 @@ message ETHHeader { } message Header { - ETHHeader target = 1; - ETHHeader parent = 2; - ibc.core.client.v1.Height trusted_height = 3; - bytes account_proof = 4; - repeated bytes parent_validators = 5; - repeated bytes target_validators = 6; - repeated bytes previous_target_validators = 7; + repeated ETHHeader headers = 1; + ibc.core.client.v1.Height trusted_height = 2; + bytes account_proof = 3; + repeated bytes current_validators = 4; + repeated bytes previous_validators = 5; } message ConsensusState { diff --git a/proto/src/prost/ibc.lightclients.parlia.v1.rs b/proto/src/prost/ibc.lightclients.parlia.v1.rs index 2ebb2f4..9a612e2 100644 --- a/proto/src/prost/ibc.lightclients.parlia.v1.rs +++ b/proto/src/prost/ibc.lightclients.parlia.v1.rs @@ -31,24 +31,18 @@ pub struct EthHeader { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Header { - #[prost(message, optional, tag = "1")] - pub target: ::core::option::Option, + #[prost(message, repeated, tag = "1")] + pub headers: ::prost::alloc::vec::Vec, #[prost(message, optional, tag = "2")] - pub parent: ::core::option::Option, - #[prost(message, optional, tag = "3")] pub trusted_height: ::core::option::Option< super::super::super::core::client::v1::Height, >, - #[prost(bytes = "vec", tag = "4")] + #[prost(bytes = "vec", tag = "3")] pub account_proof: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", repeated, tag = "4")] + pub current_validators: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, #[prost(bytes = "vec", repeated, tag = "5")] - pub parent_validators: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, - #[prost(bytes = "vec", repeated, tag = "6")] - pub target_validators: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, - #[prost(bytes = "vec", repeated, tag = "7")] - pub previous_target_validators: ::prost::alloc::vec::Vec< - ::prost::alloc::vec::Vec, - >, + pub previous_validators: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)]