diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index aafae80c..622143e8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,7 +15,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: actions/cache@v2 + - uses: actions/cache@v4 with: path: | ~/.cargo/registry @@ -47,23 +47,5 @@ jobs: command: test args: --release --features=dev --manifest-path light-client/Cargo.toml --lib test::dev_test_min env: - MINIMUM_TIMESTAMP_SUPPORTED: 1731495592 + MINIMUM_TIMESTAMP_SUPPORTED: 110 MINIMUM_HEIGHT_SUPPORTED: 100 - - uses: actions-rs/cargo@v1 - name: unit-test-dev-test-pascal - with: - command: test - args: --release --features=dev --manifest-path light-client/Cargo.toml --lib test::dev_test_after_pascal - env: - MINIMUM_TIMESTAMP_SUPPORTED: 1 - MINIMUM_HEIGHT_SUPPORTED: 1 - PASCAL_TIMESTAMP: 1 - - uses: actions-rs/cargo@v1 - name: unit-test-dev-test-pascal - with: - command: test - args: --release --features=dev --manifest-path light-client/Cargo.toml --lib test::dev_test_before_pascal - env: - MINIMUM_TIMESTAMP_SUPPORTED: 1 - MINIMUM_HEIGHT_SUPPORTED: 1 - PASCAL_TIMESTAMP: 1800000000 \ No newline at end of file diff --git a/README.md b/README.md index c2537dc1..a86fad0c 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ NOTE: This project is currently under heavy development. Features may change or break. ## Supported Versions -- [lcp v0.2.9](https://github.com/datachainlab/lcp/releases/tag/v0.2.9) -- [BSC v1.4.13](https://github.com/bnb-chain/bsc/releases/tag/v1.4.13) +- [lcp v0.2.12](https://github.com/datachainlab/lcp/releases/tag/v0.2.12) +- [BSC v1.5.5](https://github.com/bnb-chain/bsc/releases/tag/v1.5.5) ## Documents @@ -19,20 +19,11 @@ NOTE: This project is currently under heavy development. Features may change or Environment variables can be used to change settings. Each configuration must be determined at build time, not at run time. -### Blocks per epoch -You can change the blocks per epoch for localnet. -This is available in dev feature only. - -```sh -BSC_BLOCKS_PER_EPOCH=20 cargo build --features=dev -``` - ### Build Parameters Parameters can be specified to check for acceptable headers at build time. -| Name | Description | -| --- |-------------------------------------------------------------------------------------------------------------------------------------------------| -| `MINIMUM_TIMESTAMP_SUPPORTED` | Timestamp of the lowest header this light client will accept | -| `MINIMUM_HEIGHT_SUPPORTED` | Height of the lowest header this light client will accept | -| `PASCAL_TIMESTAMP` | Timestamp of the first Pascal Hardfork header, used to check the header structure after Pascal Hardfork; if 0 is specified, no check is made. | \ No newline at end of file +| Name | Description | +| --- |------------------------------------------------------------------------------------------------------------------------------| +| `MINIMUM_TIMESTAMP_SUPPORTED` | Timestamp(millisecond) of the lowest header this light client will accept. All the ForkSpec must be greater than or equal to this value. | +| `MINIMUM_HEIGHT_SUPPORTED` | Height of the lowest header this light client will accept. All the ForkSpec must be greater than or equal to this value. | diff --git a/light-client/build.rs b/light-client/build.rs index 212916c6..f6dc6609 100644 --- a/light-client/build.rs +++ b/light-client/build.rs @@ -1,34 +1,19 @@ fn main() { - #[cfg(feature = "dev")] - { - use std::io::Write; - let mut file = std::fs::File::create("src/header/constant.rs").unwrap(); - let blocks_per_epoch = - std::env::var("BSC_BLOCKS_PER_EPOCH").unwrap_or_else(|_| "200".to_string()); - writeln!( - file, - "pub const BLOCKS_PER_EPOCH: u64 = {};", - blocks_per_epoch, - ) - .unwrap(); - } + use std::io::Write; + let mut file = std::fs::File::create("src/header/constant.rs").unwrap(); + let mut values: Vec = vec![]; + let minimum_time_stamp_supported = + std::env::var("MINIMUM_TIMESTAMP_SUPPORTED").unwrap_or_else(|_| "0".to_string()); + values.push(format!( + "pub const MINIMUM_TIMESTAMP_SUPPORTED: u64 = {};", + minimum_time_stamp_supported + )); + let minimum_height_supported = + std::env::var("MINIMUM_HEIGHT_SUPPORTED").unwrap_or_else(|_| "0".to_string()); + values.push(format!( + "pub const MINIMUM_HEIGHT_SUPPORTED: u64 = {};", + minimum_height_supported + )); - { - use std::io::Write; - let mut file = std::fs::File::create("src/header/hardfork.rs").unwrap(); - let minimum_time_stamp_supported = - std::env::var("MINIMUM_TIMESTAMP_SUPPORTED").unwrap_or_else(|_| "0".to_string()); - let minimum_height_supported = - std::env::var("MINIMUM_HEIGHT_SUPPORTED").unwrap_or_else(|_| "0".to_string()); - let pascal_timestamp = - std::env::var("PASCAL_TIMESTAMP").unwrap_or_else(|_| "0".to_string()); - writeln!( - file, - "pub const MINIMUM_TIMESTAMP_SUPPORTED: u64 = {};\npub const MINIMUM_HEIGHT_SUPPORTED: u64 = {};\npub const PASCAL_TIMESTAMP: u64 = {};", - minimum_time_stamp_supported, - minimum_height_supported, - pascal_timestamp - ) - .unwrap(); - } + writeln!(file, "{}", values.join("\n")).unwrap(); } diff --git a/light-client/src/client.rs b/light-client/src/client.rs index 515af090..8958a59b 100644 --- a/light-client/src/client.rs +++ b/light-client/src/client.rs @@ -1,6 +1,11 @@ +use crate::client_state::ClientState; +use crate::consensus_state::ConsensusState; +use crate::errors::{ClientError, Error}; +use crate::header::Header; +use crate::message::ClientMessage; +use crate::misbehaviour::Misbehaviour; use alloc::string::{String, ToString}; use alloc::vec::Vec; - use light_client::commitments::{ EmittedState, MisbehaviourProxyMessage, PrevState, TrustingPeriodContext, UpdateStateProxyMessage, VerifyMembershipProxyMessage, @@ -11,18 +16,15 @@ use light_client::{ CreateClientResult, Error as LightClientError, HostClientReader, LightClient, MisbehaviourData, UpdateClientResult, UpdateStateData, VerifyMembershipResult, VerifyNonMembershipResult, }; +use parlia_ibc_proto::ibc::lightclients::parlia::v1::ProveState; use patricia_merkle_trie::keccak::keccak_256; -use crate::client_state::ClientState; use crate::commitment::{ - calculate_ibc_commitment_storage_key, decode_eip1184_rlp_proof, verify_proof, + calculate_ibc_commitment_storage_key, decode_eip1184_rlp_proof, resolve_account, verify_proof, }; -use crate::consensus_state::ConsensusState; -use crate::errors::{ClientError, Error}; -use crate::header::hardfork::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED}; -use crate::header::Header; -use crate::message::ClientMessage; -use crate::misbehaviour::Misbehaviour; +use crate::fork_spec::{verify_sorted_asc, HeightOrTimestamp}; +use crate::header::constant::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED}; +use prost::Message; #[derive(Default)] pub struct ParliaLightClient; @@ -148,6 +150,8 @@ impl LightClient for ParliaLightClient { } } +const NANO_TO_MILLIS: u128 = 1_000_000; + struct InnerLightClient; impl InnerLightClient { @@ -164,11 +168,13 @@ impl InnerLightClient { let height = client_state.latest_height; let timestamp = consensus_state.timestamp; + let milli_timestamp = (timestamp.as_unix_timestamp_nanos() / NANO_TO_MILLIS) as u64; #[allow(clippy::absurd_extreme_comparisons)] - if timestamp.as_unix_timestamp_secs() < MINIMUM_TIMESTAMP_SUPPORTED { + if milli_timestamp < MINIMUM_TIMESTAMP_SUPPORTED { return Err(Error::UnsupportedMinimumTimestamp(timestamp)); } + #[allow(clippy::absurd_extreme_comparisons)] if height.revision_height() < MINIMUM_HEIGHT_SUPPORTED { return Err(Error::UnsupportedMinimumHeight(height)); @@ -177,6 +183,30 @@ impl InnerLightClient { return Err(Error::UnexpectedRevisionHeight(height.revision_height())); } + if client_state.fork_specs.is_empty() { + return Err(Error::EmptyForkSpec); + } + + verify_sorted_asc(&client_state.fork_specs)?; + + let first = client_state.fork_specs.first().unwrap(); + match first.height_or_timestamp { + HeightOrTimestamp::Height(height) => + { + #[allow(clippy::absurd_extreme_comparisons)] + if height < MINIMUM_HEIGHT_SUPPORTED { + return Err(Error::UnsupportedMinimumHeightForkSpec(height)); + } + } + HeightOrTimestamp::Time(time) => + { + #[allow(clippy::absurd_extreme_comparisons)] + if time < MINIMUM_TIMESTAMP_SUPPORTED { + return Err(Error::UnsupportedMinimumTimestampForkSpec(time)); + } + } + } + Ok(CreateClientResult { height, message: UpdateStateProxyMessage { @@ -343,13 +373,14 @@ impl InnerLightClient { return Err(Error::ClientFrozen(client_id)); } + let mut misbehaviour = misbehaviour; let trusted_consensus_state1 = ConsensusState::try_from(any_consensus_state1)?; let trusted_consensus_state2 = ConsensusState::try_from(any_consensus_state2)?; let new_client_state = client_state.check_misbehaviour_and_update_state( ctx.host_timestamp(), &trusted_consensus_state1, &trusted_consensus_state2, - &misbehaviour, + &mut misbehaviour, )?; let prev_state = self.make_prev_states( @@ -389,8 +420,10 @@ impl InnerLightClient { path: &str, value: Option>, proof_height: &Height, - storage_proof_rlp: Vec, + proof: Vec, ) -> Result { + let prove_state = ProveState::decode(&*proof).map_err(Error::ProtoDecodeError)?; + let client_state = ClientState::try_from(ctx.client_state(&client_id).map_err(Error::LCPError)?)?; if client_state.frozen { @@ -408,8 +441,21 @@ impl InnerLightClient { ctx.consensus_state(&client_id, &proof_height) .map_err(Error::LCPError)?, )?; - let storage_root = consensus_state.state_root; - let storage_proof = decode_eip1184_rlp_proof(&storage_proof_rlp)?; + + // verify account + let account = resolve_account( + &consensus_state.state_root, + &decode_eip1184_rlp_proof(&prove_state.account_proof)?, + &client_state.ibc_store_address, + ) + .map_err(|e| Error::VerifyAccountError(alloc::boxed::Box::new(e)))?; + + // verify storage + let storage_root = account + .storage_root + .try_into() + .map_err(Error::UnexpectedStorageRoot)?; + let storage_proof = decode_eip1184_rlp_proof(&prove_state.commitment_proof)?; verify_proof( &storage_root, &storage_proof, @@ -474,13 +520,14 @@ mod test { use rstest::rstest; use time::macros::datetime; - use crate::client::ParliaLightClient; + use crate::client::{ParliaLightClient, NANO_TO_MILLIS}; use crate::client_state::ClientState; use crate::consensus_state::ConsensusState; - use crate::fixture::{localnet, Network}; + use crate::fixture::{fork_spec_after_lorentz, fork_spec_after_pascal, localnet, Network}; use crate::header::Header; + use crate::fork_spec::HeightOrTimestamp; use crate::misbehaviour::Misbehaviour; use crate::misc::{new_height, Address, ChainId, Hash}; use alloc::boxed::Box; @@ -497,6 +544,7 @@ mod test { max_clock_drift: core::time::Duration::new(1, 0), latest_height: Default::default(), frozen: false, + fork_specs: vec![fork_spec_after_pascal(), fork_spec_after_lorentz()], } } } @@ -567,10 +615,10 @@ mod test { } } - #[test] - fn test_success_create_client() { - let client_state = hex!("0a272f6962632e6c69676874636c69656e74732e7061726c69612e76312e436c69656e745374617465124d08381214151f3951fa218cac426edfe078fa9e5c6dcea5001a2000000000000000000000000000000000000000000000000000000000000000002205109b9ea90f2a040880a305320410c0843d").to_vec(); - let consensus_state = hex!("0a2a2f6962632e6c69676874636c69656e74732e7061726c69612e76312e436f6e73656e7375735374617465126c0a2056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42110de82d5a8061a209c59cf0b5717cb6e2bd8620b7f3481605c8abcd45636bdf45c86db06338f0c5e22207a1dede35f5c835fecdc768324928cd0d9d9161e8529e1ba1e60451f3a9d088a").to_vec(); + #[rstest] + #[case::localnet(localnet())] + fn test_success_create_client(#[case] hp: Box) { + let (client_state, consensus_state, height, timestamp) = hp.success_create_client(); let client = ParliaLightClient; let mock_consensus_state = BTreeMap::new(); let ctx = MockClientReader { @@ -582,16 +630,19 @@ mod test { let result = client .create_client(&ctx, any_client_state.clone(), any_consensus_state.clone()) .unwrap(); - assert_eq!(result.height.revision_height(), 32132891); + assert_eq!(result.height.revision_height(), height); match result.message { ProxyMessage::UpdateState(data) => { assert_eq!(data.post_height, result.height); let cs = ConsensusState::try_from(any_consensus_state).unwrap(); - assert_eq!(data.timestamp.as_unix_timestamp_secs(), 1695891806); assert_eq!( - data.timestamp.as_unix_timestamp_secs(), - cs.timestamp.as_unix_timestamp_secs() + (data.timestamp.as_unix_timestamp_nanos() / NANO_TO_MILLIS) as u64, + timestamp + ); + assert_eq!( + data.timestamp.as_unix_timestamp_nanos() / NANO_TO_MILLIS, + cs.timestamp.as_unix_timestamp_nanos() / NANO_TO_MILLIS ); assert_eq!(data.emitted_states[0].0, result.height); assert_eq!(data.emitted_states[0].1, any_client_state); @@ -602,25 +653,39 @@ mod test { _ => unreachable!("invalid commitment"), } } - #[test] - fn test_error_create_client() { - let client_state = hex!("0a272f6962632e6c69676874636c69656e74732e7061726c69612e76312e436c69656e745374617465124d08381214151f3951fa218cac426edfe078fa9e5c6dcea5001a2000000000000000000000000000000000000000000000000000000000000000002205109b9ea90f2a040880a305320410c0843d").to_vec(); - let consensus_state = hex!("0a2a2f6962632e6c69676874636c69656e74732e7061726c69612e76312e436f6e73656e7375735374617465126c0a2056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42110de82d5a8061a209c59cf0b5717cb6e2bd8620b7f3481605c8abcd45636bdf45c86db06338f0c5e22207a1dede35f5c835fecdc768324928cd0d9d9161e8529e1ba1e60451f3a9d088a").to_vec(); - let client = ParliaLightClient; - let mock_consensus_state = BTreeMap::new(); - let ctx = MockClientReader { - client_state: None, - consensus_state: mock_consensus_state, + + #[rstest] + #[case::localnet(localnet())] + fn test_error_create_client(#[case] hp: Box) { + let runner = |func: Box ClientState>| { + let (client_state, consensus_state, _, _) = hp.success_create_client(); + let client = ParliaLightClient; + let mock_consensus_state = BTreeMap::new(); + let ctx = MockClientReader { + client_state: None, + consensus_state: mock_consensus_state, + }; + let any_client_state: Any = client_state.try_into().unwrap(); + let mut client_state = ClientState::try_from(any_client_state.clone()).unwrap(); + client_state = func(client_state); + let any_client_state: Any = client_state.try_into().unwrap(); + let any_consensus_state: Any = consensus_state.try_into().unwrap(); + client + .create_client(&ctx, any_client_state.clone(), any_consensus_state.clone()) + .unwrap_err() }; - let mut any_client_state: Any = client_state.try_into().unwrap(); - let mut client_state = ClientState::try_from(any_client_state.clone()).unwrap(); - client_state.latest_height = Height::new(0, 0); - any_client_state = client_state.try_into().unwrap(); - let any_consensus_state: Any = consensus_state.try_into().unwrap(); - let result = client - .create_client(&ctx, any_client_state.clone(), any_consensus_state.clone()) - .unwrap_err(); + + let result = runner(Box::new(|mut client_state| { + client_state.latest_height = Height::new(0, 0); + client_state + })); assert_err(result, "UnexpectedRevisionHeight"); + + let result = runner(Box::new(|mut client_state| { + client_state.fork_specs = vec![]; + client_state + })); + assert_err(result, "EmptyForkSpec"); } #[rstest] @@ -634,7 +699,6 @@ mod test { input.trusted_previous_validators_hash, input.new_current_validators_hash, input.new_previous_validators_hash, - input.expected_storage_root, hp.ibc_store_address(), hp.network(), ) @@ -653,7 +717,6 @@ mod test { input.trusted_previous_validators_hash, new_current_validators_hash, new_previous_validators_hash, - input.expected_storage_root, hp.ibc_store_address(), hp.network(), ) @@ -667,7 +730,6 @@ mod test { trusted_previous_validator_hash: Hash, new_current_validator_hash: Hash, new_previous_validator_hash: Hash, - expected_storage_root: Hash, ibc_store_address: Address, chain_id: ChainId, ) { @@ -703,7 +765,7 @@ mod test { ConsensusState::try_from(data.new_any_consensus_state).unwrap(); assert_eq!(data.height, header.height()); assert_eq!(new_client_state.latest_height, header.height()); - assert_eq!(new_consensus_state.state_root, expected_storage_root); + assert_eq!(new_consensus_state.state_root, header.state_root().clone()); assert_eq!(new_consensus_state.timestamp, header.timestamp().unwrap()); assert_eq!( new_consensus_state.current_validators_hash, @@ -740,6 +802,90 @@ mod test { }; } + #[rstest] + #[case::localnet(localnet())] + fn test_error_update_state_non_epoch_boundary_epochs_is_timestamp( + #[case] hp: Box, + ) { + let input = hp.success_update_client_non_epoch_input(); + let any: Any = input.header.try_into().unwrap(); + let header = Header::try_from(any.clone()).unwrap(); + + let client = ParliaLightClient; + let client_id = ClientId::new(&client.client_type(), 1).unwrap(); + let mut mock_consensus_state = BTreeMap::new(); + let trusted_cs = ConsensusState { + current_validators_hash: input.trusted_current_validators_hash, + previous_validators_hash: input.trusted_previous_validators_hash, + ..Default::default() + }; + mock_consensus_state.insert(Height::new(0, input.trusted_height), trusted_cs.clone()); + + // Set fork spec is boundary timestamp + let mut boundary_fs = fork_spec_after_lorentz(); + boundary_fs.height_or_timestamp = + HeightOrTimestamp::Time(header.eth_header().target.milli_timestamp()); + let cs = ClientState { + chain_id: hp.network(), + ibc_store_address: hp.ibc_store_address(), + latest_height: Height::new(0, input.trusted_height), + fork_specs: vec![fork_spec_after_pascal(), boundary_fs], + ..Default::default() + }; + let ctx = MockClientReader { + client_state: Some(cs.clone()), + consensus_state: mock_consensus_state, + }; + let err = client.update_client(&ctx, client_id, any).unwrap_err(); + assert_err(err, "MissingForkHeightInBoundaryCalculation"); + } + + #[rstest] + #[case::localnet(localnet())] + fn test_success_update_state_non_epoch_update_fork_height(#[case] hp: Box) { + let input = hp.success_update_client_non_epoch_input(); + let any: Any = input.header.try_into().unwrap(); + let header = Header::try_from(any.clone()).unwrap(); + + let client = ParliaLightClient; + let client_id = ClientId::new(&client.client_type(), 1).unwrap(); + let mut mock_consensus_state = BTreeMap::new(); + let trusted_cs = ConsensusState { + current_validators_hash: input.trusted_current_validators_hash, + previous_validators_hash: input.trusted_previous_validators_hash, + ..Default::default() + }; + mock_consensus_state.insert(Height::new(0, input.trusted_height), trusted_cs.clone()); + + // Set fork spec boundary timestamp is all[1] + let mut boundary_fs = fork_spec_after_lorentz(); + boundary_fs.height_or_timestamp = + HeightOrTimestamp::Time(header.eth_header().all[1].milli_timestamp()); + let cs = ClientState { + chain_id: hp.network(), + ibc_store_address: hp.ibc_store_address(), + latest_height: Height::new(0, input.trusted_height), + fork_specs: vec![fork_spec_after_pascal(), boundary_fs], + ..Default::default() + }; + let ctx = MockClientReader { + client_state: Some(cs.clone()), + consensus_state: mock_consensus_state, + }; + let result = client.update_client(&ctx, client_id, any).unwrap(); + let data = match result { + UpdateClientResult::UpdateState(data) => data, + _ => unreachable!("invalid client result"), + }; + let new_client_state = ClientState::try_from(data.new_any_client_state).unwrap(); + + // update fork height + assert_eq!( + new_client_state.fork_specs[1].height_or_timestamp, + HeightOrTimestamp::Height(header.eth_header().all[1].number) + ); + } + #[rstest] #[case::localnet(localnet())] fn test_success_update_state_continuous(#[case] hp: Box) { @@ -889,7 +1035,7 @@ mod test { assert_err( err, &format!( - "UnexpectedTrustedHeight: {}", + "UnexpectedTrustedEpoch: {}", trusted_height.revision_height() ), ); @@ -897,9 +1043,9 @@ mod test { #[test] fn test_success_verify_membership() { - let proof_height = new_height(0, 232); - let proof = hex!("f902ccf90211a06868e3a43071c06084145e2546b14ab7b49b4a073213228fd2fe5b9ad6978723a032238795ce6d015be83c499b744c7108308321b5c52b424bdfe851819470572ca0db54777eae7ba641adeb842ebae3b86206443a817af6211162cb7b8f54685722a094b114ebfe63288bd344dc06b50a25982f93b38ae7deb1c4f0085a80b76692fda087385f44c834ce1d100176adb7dabf314d3d3799e83cecbdbae8bf0047bbeb8da0afa75930fdc8b5bbcc7de9653a126bbd5e7480ba180117ac8f6448ac620fe881a0c9970b5bcfc0a37c601a907ab40e0d73fe4a19b00564ebfaa2962bc4659937e8a07c6b19783013eefd4b7362ea987dda4509b7a6f6b9fa765f4be79817023c9fefa0c928ae51650933cbdc43721f48a8d96b1ff49326b6afc59fe4441a6ab4ec6391a0c60665890ed3028fb4cc13ffe5b37f9eaf93886aa0920ea7aab00e5f36a58cb9a0341de64564e1cde279f15a152a41fc07b955ed8fb331e8fbb70b6ada2f4533c1a0eb2cfd02210dd040808b05b9fcb94d99fb459a04cbaae816a87b30224962b82fa0dbd758e0c3164e578837b817584efafc5582fa3ad872bc59ba20a0ff29d84438a0ad31c527b35a0c5a0f50c15bcba55b473de5ced9ab8c22736bc71ca7ff5f9e4fa03d448120e46b82861ae5eccd3a72e3c12f8cd350b466dc27586a1d6d58791212a08a70cfd0b8005d9c457f0d83b1a7b29244963fadf71fb1ce35764fe7141bc90080f8718080808080a0ce42aec576e424376d1bfec5089611170bedc488327075ec1c37905b2eb04a7b80808080a0e8c783a5d1417b9c3c59e642b630d1fb818a3ca870068c33a8d3b3114d1a31278080a05868dd463ca96a009a6bbf76fe9a9d904ca04e30b83a3759619f191367ce5b26808080f843a0203fc42ddf6c1b5bb218ce24e14c40af9e0eb127a5d76050d37d7369e2fc4a47a1a038841326d6f11b905566840b11a81201594ec536da63c44f38c1681ddad3eee4"); - let state_root = hex!("4050c398b206f467b6d88cfd3d877a11f65701c37aabaa48d77466a63dfda9b7"); + let proof_height = new_height(0, 738); + let proof = hex!("0af505f902f2f90211a04f83ce967cc6c1a2529ccf2b54bb3be0822b7743744741920404fbda8e5bdb3aa0db8637d650a3f84e9866766025b2bb9a5a0e82140f3ac1d332f115fec1e3b0bda04cf087ca4528dc62a099390d1e88599fe43e360e2646f2067fa69774d22bb9d5a02fa8fb4f045ffee58682f7f7d1632a4b55512473503d73c265a97c621130ee8ba06e6b444bd057494f76216f671296fc77f71f989757f6286e308fc729a831c2daa08833397e80b9bf4db549c07e23998e023fd913b9efe4fe7579683f0688feaf02a09a256ea18698ff3c4769827a5c5535dd9f41d46fc8a534e7b51f8528491f621fa00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea0509d388bca267ead3cdeb2fb1da55193163896375582b79fced7df03cd42434aa0332fbd17735f4ee7db0b843666e1a9f5d3548badb90f4d16dca9e3f5a2f8665aa0b41e8d7ccbd1ec75dd4a330448c1ff914edd77397f847ceedfcb572ac7167b6aa02fe37b63b375e12fb0fdcc08811c4d4a2bb26a7c6e41bd7d908cbebe5a4b1178a0552ad5d23c543dd80f4d67a07ff4a37ebb9aafdd4642896cb473a1ad1b8600efa0d1d0d41dc046765964df5525c60b570da17d0ef87c7149260d72964bf7e280eaa0961b764de3cab4ab392b16c5144b545559450aa049b0575404432d040e8e1073a09acb2dbadb531e821eb8550792af7ab2c2e28e6407684d1ccf16c617e9f2e75980f871808080808080a05ebb69a6e5bc89b334b1cad75c8d55200c99c57898fb169e5c8546bb28b1f0208080a07d9dea58356b953bf7a7c795839d9dd16308c53d9eb944220ccd450abb8cc32a8080a0be86509add424551c0bb5c3cec1dd284c32757f219f0734656cd6513042f581280808080f869a02012683435c076b898a6cac1c03e41900e379104fefd4219d99f7908cb59cfb3b846f8440180a06ea5e7725bac4fdcc9462d77ec416efd003279f73a17a704ff07761638dd75a3a032494e8a0290ede55debb28d7a770918ee5249905e686dbfb522511502e6d1f512ef04f9026cf901d1a0162127af53c48811cc74cdf24e010964baeaec592221807055543c1be14c201ba031799f0839c6730a89f62d19f3a8c2f90648dfca3985861d989df03f7e6ea9a6a0f937a5894d7e171d02a2d836277767bbd69ae8b1864c52895a88d5d122b4ecaea05941e53568bf1fd6afed7ec75461710e0d67b8bbb72d3624acbad5ca353e4442a00dbc39c9b9ecaf901a5cacd446681d1b84276c0616bb2a142be9496f313382f880a061ec1614e1bd375100556e845545603fd281acb6615ced8af3196edef144a5aba0e46989a7771a48d24f9eedbee7b4efb32dd14f999e9b93b2399b4e0e7b6258c4a04585530cd9a77cfc46ffe70b4504dee31d8ad7bfa39ff5d8211ffbdb01c40defa0a777235f4b048421956fee718662f9308b4abfd1fb6b9922c67b2be6e623a37da032de982ffbb84f0a299cb7a3754690719719a79a03ef28b5bc1a476d16fff68ea042bd726cdc87e10a4ba8b83bebe34cf3bfa2729197b2cf5aa7de952efad3e1a4a065e3229e20dfd0b22ab4e93675f6a0b31d68a9639ebbe89348153658d046b300a0fb5fdb08b2ad9c2fd5cb6c7f9a2fe5aa7d809091e7075203dbda9c45c3bd634fa0f0342ad7c7a1501268fc9c0b31780b591caa57bf1754768896ddc35d80a270338080f85180a045a7754fcde5049be7c870b19247aad336ffcd4e10203b5e8f64039de5e4126880a09b7d0212148d0c50bd45d674a078f75ba616cdb1eef88e78947f1b442fa69ee680808080808080808080808080f843a020dc93aa2071d8fee619b0413af2f932685da696e8852d2c3c8dd087a6f0ffa6a1a038841326d6f11b905566840b11a81201594ec536da63c44f38c1681ddad3eee4"); + let state_root = hex!("b12f849b462b42954754ba3826ac6a97fb4f88ed820811a06640dd2edbc755ae"); let value = hex!("0a0b78782d7061726c69612d3012230a0131120d4f524445525f4f524445524544120f4f524445525f554e4f524445524544180322220a0b78782d7061726c69612d30120c636f6e6e656374696f6e2d301a050a03696263").to_vec(); let path = "connections/connection-0"; let result = do_test_verify_membership( @@ -920,9 +1066,9 @@ mod test { #[test] fn test_error_verify_membership() { - let proof_height = new_height(0, 232); - let proof = hex!("f902ccf90211a06868e3a43071c06084145e2546b14ab7b49b4a073213228fd2fe5b9ad6978723a032238795ce6d015be83c499b744c7108308321b5c52b424bdfe851819470572ca0db54777eae7ba641adeb842ebae3b86206443a817af6211162cb7b8f54685722a094b114ebfe63288bd344dc06b50a25982f93b38ae7deb1c4f0085a80b76692fda087385f44c834ce1d100176adb7dabf314d3d3799e83cecbdbae8bf0047bbeb8da0afa75930fdc8b5bbcc7de9653a126bbd5e7480ba180117ac8f6448ac620fe881a0c9970b5bcfc0a37c601a907ab40e0d73fe4a19b00564ebfaa2962bc4659937e8a07c6b19783013eefd4b7362ea987dda4509b7a6f6b9fa765f4be79817023c9fefa0c928ae51650933cbdc43721f48a8d96b1ff49326b6afc59fe4441a6ab4ec6391a0c60665890ed3028fb4cc13ffe5b37f9eaf93886aa0920ea7aab00e5f36a58cb9a0341de64564e1cde279f15a152a41fc07b955ed8fb331e8fbb70b6ada2f4533c1a0eb2cfd02210dd040808b05b9fcb94d99fb459a04cbaae816a87b30224962b82fa0dbd758e0c3164e578837b817584efafc5582fa3ad872bc59ba20a0ff29d84438a0ad31c527b35a0c5a0f50c15bcba55b473de5ced9ab8c22736bc71ca7ff5f9e4fa03d448120e46b82861ae5eccd3a72e3c12f8cd350b466dc27586a1d6d58791212a08a70cfd0b8005d9c457f0d83b1a7b29244963fadf71fb1ce35764fe7141bc90080f8718080808080a0ce42aec576e424376d1bfec5089611170bedc488327075ec1c37905b2eb04a7b80808080a0e8c783a5d1417b9c3c59e642b630d1fb818a3ca870068c33a8d3b3114d1a31278080a05868dd463ca96a009a6bbf76fe9a9d904ca04e30b83a3759619f191367ce5b26808080f843a0203fc42ddf6c1b5bb218ce24e14c40af9e0eb127a5d76050d37d7369e2fc4a47a1a038841326d6f11b905566840b11a81201594ec536da63c44f38c1681ddad3eee4"); - let state_root = hex!("4050c398b206f467b6d88cfd3d877a11f65701c37aabaa48d77466a63dfda9b7"); + let proof_height = new_height(0, 738); + let proof = hex!("0af505f902f2f90211a04f83ce967cc6c1a2529ccf2b54bb3be0822b7743744741920404fbda8e5bdb3aa06471fc474647b4776b34d1230c491cfd980bf33122f5956eff4eeefdf400431fa04cf087ca4528dc62a099390d1e88599fe43e360e2646f2067fa69774d22bb9d5a02824f5075c1fb398bab7ea258ee18a360b9639a1a31c6c604b13a492ca16394ea06e6b444bd057494f76216f671296fc77f71f989757f6286e308fc729a831c2daa099bf4775a4d089d01c6ffec506dfbb1eb64a13502604fa7477699b29e22b8b5ea03da8f11404097583100dd1eb02f762ccf0091ca84d6b118c644bf9cf900b7caaa00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea0509d388bca267ead3cdeb2fb1da55193163896375582b79fced7df03cd42434aa0332fbd17735f4ee7db0b843666e1a9f5d3548badb90f4d16dca9e3f5a2f8665aa0b41e8d7ccbd1ec75dd4a330448c1ff914edd77397f847ceedfcb572ac7167b6aa02fe37b63b375e12fb0fdcc08811c4d4a2bb26a7c6e41bd7d908cbebe5a4b1178a0552ad5d23c543dd80f4d67a07ff4a37ebb9aafdd4642896cb473a1ad1b8600efa0d1d0d41dc046765964df5525c60b570da17d0ef87c7149260d72964bf7e280eaa0961b764de3cab4ab392b16c5144b545559450aa049b0575404432d040e8e1073a09acb2dbadb531e821eb8550792af7ab2c2e28e6407684d1ccf16c617e9f2e75980f871808080808080a05ebb69a6e5bc89b334b1cad75c8d55200c99c57898fb169e5c8546bb28b1f0208080a07d9dea58356b953bf7a7c795839d9dd16308c53d9eb944220ccd450abb8cc32a8080a0be86509add424551c0bb5c3cec1dd284c32757f219f0734656cd6513042f581280808080f869a02012683435c076b898a6cac1c03e41900e379104fefd4219d99f7908cb59cfb3b846f8440180a06ea5e7725bac4fdcc9462d77ec416efd003279f73a17a704ff07761638dd75a3a032494e8a0290ede55debb28d7a770918ee5249905e686dbfb522511502e6d1f512ef04f9026cf901d1a0162127af53c48811cc74cdf24e010964baeaec592221807055543c1be14c201ba031799f0839c6730a89f62d19f3a8c2f90648dfca3985861d989df03f7e6ea9a6a0f937a5894d7e171d02a2d836277767bbd69ae8b1864c52895a88d5d122b4ecaea05941e53568bf1fd6afed7ec75461710e0d67b8bbb72d3624acbad5ca353e4442a00dbc39c9b9ecaf901a5cacd446681d1b84276c0616bb2a142be9496f313382f880a061ec1614e1bd375100556e845545603fd281acb6615ced8af3196edef144a5aba0e46989a7771a48d24f9eedbee7b4efb32dd14f999e9b93b2399b4e0e7b6258c4a04585530cd9a77cfc46ffe70b4504dee31d8ad7bfa39ff5d8211ffbdb01c40defa0a777235f4b048421956fee718662f9308b4abfd1fb6b9922c67b2be6e623a37da032de982ffbb84f0a299cb7a3754690719719a79a03ef28b5bc1a476d16fff68ea042bd726cdc87e10a4ba8b83bebe34cf3bfa2729197b2cf5aa7de952efad3e1a4a065e3229e20dfd0b22ab4e93675f6a0b31d68a9639ebbe89348153658d046b300a0fb5fdb08b2ad9c2fd5cb6c7f9a2fe5aa7d809091e7075203dbda9c45c3bd634fa0f0342ad7c7a1501268fc9c0b31780b591caa57bf1754768896ddc35d80a270338080f85180a045a7754fcde5049be7c870b19247aad336ffcd4e10203b5e8f64039de5e4126880a09b7d0212148d0c50bd45d674a078f75ba616cdb1eef88e78947f1b442fa69ee680808080808080808080808080f843a020dc93aa2071d8fee619b0413af2f932685da696e8852d2c3c8dd087a6f0ffa6a1a038841326d6f11b905566840b11a81201594ec536da63c44f38c1681ddad3eee4"); + let state_root = hex!("8617db342e8a02bf863ef25096db1ec2b5d665df743e789828ba626c88d41cf3"); let value = hex!("0a0b78782d7061726c69612d3012230a0131120d4f524445525f4f524445524544120f4f524445525f554e4f524445524544180322220a0b78782d7061726c69612d30120c636f6e6e656374696f6e2d301a050a03696263").to_vec(); let path = "connections/connection-0"; @@ -990,6 +1136,10 @@ mod test { let ctx = MockClientReader { client_state: Some(ClientState { latest_height, + ibc_store_address: hex!("aa43d337145E8930d01cb4E60Abf6595C692921E"), + ibc_commitments_slot: hex!( + "1ee222554989dda120e26ecacf756fe1235cd8d726706b57517715dde4f0c900" + ), frozen, ..Default::default() }), @@ -1013,7 +1163,7 @@ mod test { // Detect misbehaviour // Use blocks of two local nets with the same ChainID(=9999) and validator set. - let any = hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212ad3b0a0b78782d7061726c69612d3112c11c0ad5060ad206f9034fa0df813ab13cd8fa64526bab2d574bd83199f358cf875b5a7ca34c55cc59fb7841a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0347db7085bed92889205f4566fdeb71b36981b2662282e5b49f74f146e1b2920a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282022d8402625a00808466a21174b90111d98301040c846765746889676f312e32312e3132856c696e7578000060b2e37bf8ae03b860b42b097ae5430552430062d80b2015710882c0520cf58dc6b987d0aa042840525bab13a5098af712b844bccf36b2ccb009fa3796f7088dec9a5dfcc0db6e4ab502fcca21d59598bd4f7504415662ec094b6ba1555c7faa0389468e45e11e8655f84882022ba0fe631870634a3823f363cdb9c6bd572b1a3ecaa9daeb98a784610a1cd1107e4882022ca0df813ab13cd8fa64526bab2d574bd83199f358cf875b5a7ca34c55cc59fb78418008487b8053f33e79d8758655252a23e25ce9f3440557d0ed67c80700633730674c5c682fa86414f136befd54de6023cbbb74bc48edc438ad136bc34f520b264100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa09e0419600f424df6786dbbdef3f774c0a3d9a9785c8e3aec85ec4d95a2a526ada01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0347db7085bed92889205f4566fdeb71b36981b2662282e5b49f74f146e1b2920a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282022e8402625a00808466a21177b90111d98301040c846765746889676f312e32312e3132856c696e7578000060b2e37bf8ae03b86099480987f69ba68b91ea25863b7cc7881fa57156c57f04b9a1ce33fa6766522d1ddafbb4b0ebd913bedee575cf18790f163d68c5d8fc5d389206ec1baf04b7daf1b17c9b5e688f29e71bfc5c40c5327dd6a36a7fd6e043305f6fe01da6fc77bff84882022ca0df813ab13cd8fa64526bab2d574bd83199f358cf875b5a7ca34c55cc59fb784182022da09e0419600f424df6786dbbdef3f774c0a3d9a9785c8e3aec85ec4d95a2a526ad80aab31b654039b4edef9af34f1bfbff4999aafd9c007bb3925378e865a8fde7d9693646834fc0323d375029594e363a4d96d49d0d5bc1dd6d98ed87d13fcfc4a700a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0d71391dfe369c3f939c86aa6c3a25649a5ce9c298549e075981d65dc3278fadda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0347db7085bed92889205f4566fdeb71b36981b2662282e5b49f74f146e1b2920a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282022f8402625a00808466a2117ab90111d98301040c846765746889676f312e32312e3132856c696e7578000060b2e37bf8ae03b860acd5509943efb944b23870db31f09b536731993d75078450bedefa5df77ea416d2d54be798d452d4562b57571fcf3ec00596cb4516d86b82a52081275c9ff9a35aed899b63791acbff7000f3c907c9d9f61e386c8c0de5ea79d67fd49c5675abf84882022da09e0419600f424df6786dbbdef3f774c0a3d9a9785c8e3aec85ec4d95a2a526ad82022ea0d71391dfe369c3f939c86aa6c3a25649a5ce9c298549e075981d65dc3278fadd8076a78528fffc86138b8155eaf036c0ccced82091d1cd7be5e7445d9d44b512907766334023ba1ac6b5376b39619e7198467598e549b284dcd065b4088ee0be0600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310ac041a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0cb21354718f7d012561dacf2274405cdd9bccd532afe18206bd26bf60e96c853a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a09e8d71308bd38616ac52a39498cee9fcf29c440d9aacfedfc7143772c77ce54480a0a74e307420bf9966d5db9a83ce48edc32c7a8e43328c6373de6875cefa04ad7aa004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0d4182165b298d7b52b0f2064d19ab8bdad2b3955fa5b3d85c00673beb97e124480f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a03f47312ca98ac1f6ae9db9752c2a33529723b64e654d87f7847cee0382edfb55a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e56592b50b17b5348f1aebe4c50d87c59b55223abe57c9c3df76cb4a96211bb393aacd440bac5f71ea3fc481abff6270142d2244a7876ea32e7a748c697d01345145485561305b24aed19f6cbeb659e104b4657c2e41822087506cb58b037aba5599314c2c4bea0ef4d3cbbc449b24abf396cfd71ac07af42a448fdaaa7e6631e438625ca25c857a3727ea28e56592b50b17b5348f1aebe4c50d87c59b55223abe57c9c3df76cb4a96211bb393aacd440bac5f71ea3fc481abff6270142d2a44d9a13701eafb76870cb220843b8c6476824bfa1595bd9f541fdb277d2bdd5ff223f95eb83f8d2b465c1bac3cf2d0bc551ad01a9037a4af083d66eff89b34200745db92cc300538061ad91e0ad5060ad206f9034fa0aeef6b8a15e0109c9838875b033b5c54d21c356cb5ddf395eb109b9b29ae694fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a03e5bfca057d64cd5c54c82f5e213f8e7993411a5a490c0b93358f6def507e8d4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282022d8402625a00808466a2116eb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb86082b910df7cee75733375fb7716c34b14c1ce27f283c2d87ea0e2b2a0de42d18bdd724766b3a73d5daaa25befaa814df815605e8881819d421c8703100b7a93d1a22c89693625b4370d4d87b85ed676661ce65d46ef0c5c8325696892abf0d5d5f84882022ba03986751eb813b176c13e29485332e635df862b515516501e87113f50b655d80c82022ca0aeef6b8a15e0109c9838875b033b5c54d21c356cb5ddf395eb109b9b29ae694f80af43c5cc71b487cbe16b6771635dc751cbd6231274a3bbf87ae8b38c3319e5f54eb4e0a8186070727a19eb749b2e70068b7c505b1ed8b0dd7d6a595e2bf5db3601a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa04a9481f17c19c739ab1961ffdba488b234d37254da0ec7e95d8cf5d4ad54893ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a03e5bfca057d64cd5c54c82f5e213f8e7993411a5a490c0b93358f6def507e8d4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282022e8402625a00808466a21171b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a41a9347a1766d7b59a6f4eb4434f89a5ff5e52df18b90baf4588374a65b578fdf85c4c605b325468883f22a49ce28bf1194955ae44b6de878a8def6b4c36cd5bb669be37d4a31bb7b48e45c7e0fe0d8fd43e86ba60871b6e1b7c731498d0df4f84882022ca0aeef6b8a15e0109c9838875b033b5c54d21c356cb5ddf395eb109b9b29ae694f82022da04a9481f17c19c739ab1961ffdba488b234d37254da0ec7e95d8cf5d4ad54893b80292058b3eeab2626c29d676db526a6a0d8b739a59f9d7971e5fd3e96192321e4759aa81a6bfdd5a211e3dca1d29f20fc5feffdb3261fb2afdd2fd9b4f9607fb201a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa04a6b366f150065827cf5954904fdca9da5073531b4aa5462e86636feb61890aca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a03e5bfca057d64cd5c54c82f5e213f8e7993411a5a490c0b93358f6def507e8d4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282022f8402625a00808466a21174b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a440c540974a6217ff340cbe742520fce50a18f18553f4816fdb43d9a74092ebb237ce4cce2a10f0e6d7b6ec58cf53990b91b8d2279eec1391748eab3a605cf1d900fa267dfc21cc8ebf35cb138c10287d49b3a4c1c5d18bd7727f74fa64e46ef84882022da04a9481f17c19c739ab1961ffdba488b234d37254da0ec7e95d8cf5d4ad54893b82022ea04a6b366f150065827cf5954904fdca9da5073531b4aa5462e86636feb61890ac806014de9b2c697f9b78ac9c86cdcc45bd19b3388569814a24bcbbe570a47561fd713af78490598f2d211f13cf1a5ed4bf299c1c1df8c677bd018b695c9f8339bf01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310ab041a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0d1c5c078d5c2983649e8200a84d8fef4d4c1ca8a06ed8f7be21f82c23a910edaa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a0f9858d51200cb595d4f158c848af32e29fa61db4ddea7cde4006a7cbc306ef5880a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a0a4aa3b0d5510f907876be1bff95c5867b088e8464e4ae75e45d016c5ac21c0faa00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62244b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32a44e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc130083808").to_vec(); + let any = hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212c6300a0b78782d7061726c69612d31128c170af6060af306f90370a0bcf423276bee4dbb0205f395d5f73dab513d7cb3e79a634f969df347537f3cc9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0df3605ab1ded1b02408bad8ac4d1391abea1cccfd90d0f332951f294375d0b8fa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202c78402625a00808467d00ec1b90111d883010505846765746888676f312e32332e37856c696e75780000004d2622aaf8ae03b86080ede2b1f76367a7a1e2d9671f6c3954ce7143a5b2c74b56a998d41cff1dd4432ec7ac4d9c12af18b78efaa8ab609e8d19a7f90cf1a568346eff5d8909555a9c18ba98f3dead20f850878d34c4dc5f491a0fef1b49799bc2d4fcaf8ef9c28b02f8488202c5a0dae075ce24140e7d270976767ffdd1c09774dbba5a020d9c8ae428f2bfdb73718202c6a0bcf423276bee4dbb0205f395d5f73dab513d7cb3e79a634f969df347537f3cc9800c31980d8fe3ab00b710e2403a13b808aed6ebfd899385d09e4bf8be64997dd62bbec57bb4624ce6c123880636713340c31c04fbe907e554397b64e573cffa2100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0af95ffe55ab4f551c803abcd747079fac133cbbb9e241ac8e64aa3ebbfbb68f4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04f8e7b8d1e6b3a9c3586a06c8c1b6d3551d604b7ae0b3bdfe416f863eddc7354a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202c88402625a00808467d00ec4b90111d883010505846765746888676f312e32332e37856c696e75780000004d2622aaf8ae03b8609120dc5ff1026be3223eabf3f5f2ec184d8edd6b5bdfd7849faa545f6180c62fa4c98f15704df073cdacddefaaff4fb20cfc6ae3dbba48519c4bb6b63a8f844ca9df18c90a98e66d9d0be15a53d6bac23853c355241a865abe06b39fb5033743f8488202c6a0bcf423276bee4dbb0205f395d5f73dab513d7cb3e79a634f969df347537f3cc98202c7a0af95ffe55ab4f551c803abcd747079fac133cbbb9e241ac8e64aa3ebbfbb68f480536f03148a0f51e1320140145cad7f5d9abaee94cad967f856bbb54dcf905c9039c1ef36d50a279cae95a351c1338ce5f07faf7f3db083b5b9161bff9e10f28f01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0a46c2663376b09f02207da096c42dee09822a3975db771c4d1e1332737d1bcd3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0abbb6e40d3d188bc7b4203a9905c5a910f789801b5f6a1803e76165f3edf3405a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202c98402625a00808467d00ec7b90111d883010505846765746888676f312e32332e37856c696e75780000004d2622aaf8ae03b860a95c96c9095eae79fcd12d81fd298cd048b46eec0019ac39f35331b2b9c19b68f29e231e3cb9f9761ac5fa8875d6cbd60a10ae994087ea0b876181b0c0571173503000b626db0041d1ddadfc5bc8a645b8d199508137df1fd14264c16e8a5286f8488202c7a0af95ffe55ab4f551c803abcd747079fac133cbbb9e241ac8e64aa3ebbfbb68f48202c8a0a46c2663376b09f02207da096c42dee09822a3975db771c4d1e1332737d1bcd380684d242a478031c74aa937c29cbe388f8103ada3d95cc6a539ead39fe16fd82731e8d0c53516a7f488cfc1b438498042994ca54d05b37b0103330726d96724b300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310c6051a44a7876ea32e7a748c697d01345145485561305b24a485dbaadce4a8c2a53776a976aba7eb234f626cdabdef4f5bc107f959d7670b8b16977cd6ed75deaada04a5b735f8b21a44d9a13701eafb76870cb220843b8c6476824bfa1599b98f72c9afc9aeb469dae26bd849e3ced8ec8888e6ec16f8f7c9eeda8f9f620b4aeb01ffa4d022167b23fb4c3fc66c22448fdaaa7e6631e438625ca25c857a3727ea28e565b3578eaae8fa56b45ca90f5620afe437f7b41fd8c4f8e2428cf83be168dd93288a8d26406a850de67b1ff6ddf9bfdb692244a7876ea32e7a748c697d01345145485561305b24a485dbaadce4a8c2a53776a976aba7eb234f626cdabdef4f5bc107f959d7670b8b16977cd6ed75deaada04a5b735f8b2280430081aa7190af9060af606f90373a00dc20b49a0b4f16f36f4131ed92d3724c48443e83a3d09c4963c9b008402534ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a00725a2f9efc4850fe004341f398c3c17040f8ff8a84f747fb729bdc50259af89a05d74a9f8937eb042045ad57c519824df058a77e550c7ef9b531afda823c20863a0ecaaa68cb6eda61c2c6ee5f366f1d13cb5d2986fb18d22989d880db8645cadceb9010000000000000000000000004000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002010000000000000000000000000010000080020000200000000000000000000080000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000002008400000020000000000000000000000000000000000000000000000000000000000000000000000000000000000080000104002000000000000000000000000010000040000010000008000000000004000000000000000028202c78402625a008306ed738467d00eb8b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb86084128e77dacaf3c448d5847ff3eaab289ba436c999b3d21d38b2c38c1174554cded80770419dab4f3dbc25b13d183c2513c94432f4b1614e0d80ee272980f34a2eb25b9f638e1622a400e65bcf1f2e8afcd121cf9d670ed5d123245622ba90bef8488202c5a04ae0ada31ecd1b5d875c91aa0a58b2ae6b49667741cf8fd58443ece5a85fb6948202c6a00dc20b49a0b4f16f36f4131ed92d3724c48443e83a3d09c4963c9b008402534b805bd310e4c1f45a2b7977d54cad5cc616d613f313b811eb94e3140aa748b7e4251b0fb8a5e3d836b01ebfb33d4de5753b1277b8be02fef476bdb7fb297e0bcb3100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0b8bcb3864d490b5d75b889999f923decd62bccb032c39f577861ed5916fc779fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0a58f35b982fb99d7cecefae42654267108a4ea87cf8130998120834984f95945a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202c88402625a00808467d00ebbb90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b96bd8ba80bcea4e018b959c3eebc688fe3b27a1ff1e5b03248fb5edf64c6b5285aa344f83d54a9459a286ddc267959e187dda37761e4e3cf72dddb3f1c946b72d93a9523bc45d1e027de549d24aa9a16caea89ab2357b583d0b44e021c95380f8488202c6a00dc20b49a0b4f16f36f4131ed92d3724c48443e83a3d09c4963c9b008402534b8202c7a0b8bcb3864d490b5d75b889999f923decd62bccb032c39f577861ed5916fc779f8079f0dc578581fa2b2e270353cbf3ca150676a27d0aa31a6b270d8fea1fa2ef56314c07f1aa7d8ca1e4448c37b7f8cca695fe271717634e88369b807f660a762100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0bbdf9cc08305a46cdbe0740b15338c87674b62906cc0e4c8c9033813fe46b5d0a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0d9f03ddb3371cd8ce245ea85e499cb763ecb68071adecc6c3c74f75136cb9e6da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202c98402625a00808467d00ebeb90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860a5224150f6a842a965128cb719c859faf5d080acfda9b33e97788fb2e079cf602f2b24a7619851317dddbd8d8f931fea0886287914952c4654e012802519451dbe0f275e0813a201e62cbd5d7e71581f6a7117d2a67d4b7829a9b3f73ef7b4def8488202c7a0b8bcb3864d490b5d75b889999f923decd62bccb032c39f577861ed5916fc779f8202c8a0bbdf9cc08305a46cdbe0740b15338c87674b62906cc0e4c8c9033813fe46b5d080dd912614993f9ee58208ed05889671e284c0f46904e7c16c8c81b023b16567c835a0b21f6e3b12c9d776b3ac0c53ab0631961919e26053112f2aa6e0074d0bb200a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310c5051a44a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb1a44b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81721a44d9a13701eafb76870cb220843b8c6476824bfa15933e9ee732cad53fcaab7a262f923a6c5a2f19033136dd925786b0890af8e44573f71695bc10fc25168ae1b41e5c92331a44e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b169845c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a486822448fdaaa7e6631e438625ca25c857a3727ea28e5659952928ee3ab47ef980231cd0ed75ebcce668b23ec23d21c7fc4ac91ceb2dc605973bd4914e6ae4d29db2d349441cb772244a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb2244b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81722244e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b169845c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a486828093007").to_vec(); let any: Any = any.try_into().unwrap(); let misbehaviour = Misbehaviour::try_from(any.clone()).unwrap(); let mut mock_consensus_state = BTreeMap::new(); @@ -1034,7 +1184,10 @@ mod test { }, ); let ctx = MockClientReader { - client_state: Some(ClientState::default()), + client_state: Some(ClientState { + fork_specs: vec![fork_spec_after_pascal(), fork_spec_after_lorentz()], + ..Default::default() + }), consensus_state: mock_consensus_state, }; @@ -1078,38 +1231,39 @@ mod test { let client_id = ClientId::new(client.client_type().as_str(), 1).unwrap(); // fail: exactly same block - let mut any= hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212cf370a0b78782d7061726c69612d3112de1b0ab4060ab106f9032ea0c3ca2cd851054700e22f8313521399aacfcc225541cde7dfeca894f9b57d7c22a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0d269e8b47a345f3a77343f46943f78480a96ff82a8466963fb4a29c0e2b66091a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820c1c8402625a0080846699bcdab90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b86086dcdfb683f4965de8062063dd843775eeb55a1271b317a6d65ef7aadabb1e10a9327c9face4c69c331b914f3b24aeb4010b30d4c4a7007c67d7de812e9c7cca598c9b3b1e94679e90aeb94b790b19dce6bee8662126eecdb3b539efee6468b7f848820c1aa049430f5e612a0b37a9bab1b1c5003f02f3586a4e2ea9e84d8de511f879f30561820c1ba0c3ca2cd851054700e22f8313521399aacfcc225541cde7dfeca894f9b57d7c22803135a7c114e967442e0bc0996b3b083aae7638e142b3a145b8d966267fecb84141fcf58023341e1aeaf333bfe4d91349db198c157947780f46b1d476a892c25900a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea02c07474042f3b317665fe4a233454a1ec921770d6429dd3eb0a23e812429d595a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0d269e8b47a345f3a77343f46943f78480a96ff82a8466963fb4a29c0e2b66091a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820c1d8402625a0080846699bcddb90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860a410689613510c2087d762d49d42acb83f84b136e417e0567c8fbd693fd25cb36f794ae231b79101b94d700457f511120b7b2c8c0294c33b2d9728fa5d0a81a9c02901e28c3df1c840e7a4f7f6b5f150c3d7276b84a5f05d57a582ac6659692ff848820c1ba0c3ca2cd851054700e22f8313521399aacfcc225541cde7dfeca894f9b57d7c22820c1ca02c07474042f3b317665fe4a233454a1ec921770d6429dd3eb0a23e812429d59580dfca46ba06e40ca0191deacc05e2185acbfb04ca3ce23355f2b3d1be19667d096f33e5174260e4e5be857a49307dcf824f1b7e353c3be3e7bb4202c5bf4ae32b00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea0c0e82c0cda470def9ae9b03f55755b9cf0af015ae255bbb90a7969296918514aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0d269e8b47a345f3a77343f46943f78480a96ff82a8466963fb4a29c0e2b66091a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820c1e8402625a0080846699bce0b90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860856d586a1618c0da1e906937b0a4c2596598a2d34e5cbf62063fc52ca9e5078fc962443b3a53166fabf69548b8d885ec08260a0d01293a3e61ba14d82e976f477f6ab2db2a8ae7c641cca0077c1770f472e7306ab43f8fecf762a95bc45ca1a5f848820c1ca02c07474042f3b317665fe4a233454a1ec921770d6429dd3eb0a23e812429d595820c1da0c0e82c0cda470def9ae9b03f55755b9cf0af015ae255bbb90a7969296918514a802a8efd919b1fe8bd679c8db7976de46350cfe3c2bdf67ec67e95c2f1c02909736bbb1bcdd798058072adc2e3cea6a16d519d1630e121539b8ccd77b1a7f84a1c00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180801203109b181a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0d8a8f0aaba741477e7d0c15b6a1759b3d842e346b35afd14219ecdd18188718ea0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a0bd63cc1cadd9ef7ffd41bb496484bff7c6ddbc3b29cf1a8b82d1f8f12bc6347680a0a74e307420bf9966d5db9a83ce48edc32c7a8e43328c6373de6875cefa04ad7aa0e502f113ade32bee3770b5a0117fa799c8812e5ab5a239e3878660c59c3537fda00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0d4182165b298d7b52b0f2064d19ab8bdad2b3955fa5b3d85c00673beb97e124480f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a03f47312ca98ac1f6ae9db9752c2a33529723b64e654d87f7847cee0382edfb55a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512f2244a7876ea32e7a748c697d01345145485561305b24903201f874819815e1a3f183c4addc814b71ec0e573e07f79ee9082926d82dd1711d6c45a9cc8841916d8563c2f80baa2a448fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512f2a44d9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be").to_vec(); - let any2= hex!("7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab99300138011ade1b0ab4060ab106f9032ea0c3ca2cd851054700e22f8313521399aacfcc225541cde7dfeca894f9b57d7c22a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0d269e8b47a345f3a77343f46943f78480a96ff82a8466963fb4a29c0e2b66091a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820c1c8402625a0080846699bcdab90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b86086dcdfb683f4965de8062063dd843775eeb55a1271b317a6d65ef7aadabb1e10a9327c9face4c69c331b914f3b24aeb4010b30d4c4a7007c67d7de812e9c7cca598c9b3b1e94679e90aeb94b790b19dce6bee8662126eecdb3b539efee6468b7f848820c1aa049430f5e612a0b37a9bab1b1c5003f02f3586a4e2ea9e84d8de511f879f30561820c1ba0c3ca2cd851054700e22f8313521399aacfcc225541cde7dfeca894f9b57d7c22803135a7c114e967442e0bc0996b3b083aae7638e142b3a145b8d966267fecb84141fcf58023341e1aeaf333bfe4d91349db198c157947780f46b1d476a892c25900a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea02c07474042f3b317665fe4a233454a1ec921770d6429dd3eb0a23e812429d595a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0d269e8b47a345f3a77343f46943f78480a96ff82a8466963fb4a29c0e2b66091a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820c1d8402625a0080846699bcddb90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860a410689613510c2087d762d49d42acb83f84b136e417e0567c8fbd693fd25cb36f794ae231b79101b94d700457f511120b7b2c8c0294c33b2d9728fa5d0a81a9c02901e28c3df1c840e7a4f7f6b5f150c3d7276b84a5f05d57a582ac6659692ff848820c1ba0c3ca2cd851054700e22f8313521399aacfcc225541cde7dfeca894f9b57d7c22820c1ca02c07474042f3b317665fe4a233454a1ec921770d6429dd3eb0a23e812429d59580dfca46ba06e40ca0191deacc05e2185acbfb04ca3ce23355f2b3d1be19667d096f33e5174260e4e5be857a49307dcf824f1b7e353c3be3e7bb4202c5bf4ae32b00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea0c0e82c0cda470def9ae9b03f55755b9cf0af015ae255bbb90a7969296918514aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0d269e8b47a345f3a77343f46943f78480a96ff82a8466963fb4a29c0e2b66091a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820c1e8402625a0080846699bce0b90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860856d586a1618c0da1e906937b0a4c2596598a2d34e5cbf62063fc52ca9e5078fc962443b3a53166fabf69548b8d885ec08260a0d01293a3e61ba14d82e976f477f6ab2db2a8ae7c641cca0077c1770f472e7306ab43f8fecf762a95bc45ca1a5f848820c1ca02c07474042f3b317665fe4a233454a1ec921770d6429dd3eb0a23e812429d595820c1da0c0e82c0cda470def9ae9b03f55755b9cf0af015ae255bbb90a7969296918514a802a8efd919b1fe8bd679c8db7976de46350cfe3c2bdf67ec67e95c2f1c02909736bbb1bcdd798058072adc2e3cea6a16d519d1630e121539b8ccd77b1a7f84a1c00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180801203109b181a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0d8a8f0aaba741477e7d0c15b6a1759b3d842e346b35afd14219ecdd18188718ea0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a0bd63cc1cadd9ef7ffd41bb496484bff7c6ddbc3b29cf1a8b82d1f8f12bc6347680a0a74e307420bf9966d5db9a83ce48edc32c7a8e43328c6373de6875cefa04ad7aa0e502f113ade32bee3770b5a0117fa799c8812e5ab5a239e3878660c59c3537fda00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0d4182165b298d7b52b0f2064d19ab8bdad2b3955fa5b3d85c00673beb97e124480f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a03f47312ca98ac1f6ae9db9752c2a33529723b64e654d87f7847cee0382edfb55a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512f2244a7876ea32e7a748c697d01345145485561305b24903201f874819815e1a3f183c4addc814b71ec0e573e07f79ee9082926d82dd1711d6c45a9cc8841916d8563c2f80baa2a448fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512f2a44d9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab9930013801").to_vec(); + let mut any= hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212db320a0b78782d7061726c69612d3112a4190af6060af306f90370a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0f213a434eee1a6f27d9891a7c29c76641ffa43f4cef91a264824477eaea8300fa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202da8402625a00808467d00ef1b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b9cc1c4d529d31592a873c3cb3afd6bac1766302f424652c3fbedcbec2da7a7f99249f88dd1a13a1b22059c8b393540d187fb2628c89bda549a7010a2488533d6b3cf9bad7142f9ea61eff699dddf5a4e6423b4aecabf8dc499c923f2cdfbfa9f8488202d8a0b0e9d1ddd59db45429b1ae9d4c01812e7bdbe7a8822d32855617844f10ed5b748202d9a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3b804721ffbf07fc83f2f1cc3773881b3f7868b707198e84d42ac1bacf40039a8bb13009d78f96ff8e8d1552ae3583d001101aefcba4d6a827527fdce1b7e91afb0401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a67a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada094de24b42126f642e0497a72d77d0c583fb9c6230f7a6dba7e54efa97e13c627a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202db8402625a00808467d00ef4b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b50822e55669b92492ecc5a42229fe7c03e0d0116a0449e3d2897fc32e134e0a601a9a49c13fd8eea94162858a83229d086639a1cef8ea3a3210937ea0aec4f140d9ccae24ed535c9ddb75024d4d58133c0483e352bd634af301da84f98bb154f8488202d9a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3b8202daa0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a6780b6bdc9a4de82e5d16cb1868bea7a98df85879e37ff283cc4f5ed0604b58cbbdc60faa7b6dc3fb519c35ffe8a2b2cd34da95f65087c905345bae6ef8d319c5d3e01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a06c2e2a3f0dc9f7bbc40ec103c97b49ec079c88c00abf3cdd966922c557cc319ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0305c4387cd456db6642b98fb5a615619af15a1c900f612501c20793f24e91257a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202dc8402625a00808467d00ef7b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb8608871ce67969e2b836797cae67245c47e43d848aa91671b27bdf17c64a1b8567a2a8726d677cb7058e503aa5308f296a51574f47028fe8246d07a1c8c1ed49bfaacecdb0d0e93b97da8cc8e067022e2f89636aa38f7d22f4944e1b6c3158145b9f8488202daa0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a678202dba06c2e2a3f0dc9f7bbc40ec103c97b49ec079c88c00abf3cdd966922c557cc319e80869fda554f1f7821370f876ff60b3f4cab712df1a46f53cabea77f19e16a98af26f85c7cfb4cb482b1851ebc25e8e1482e70840c77075e7636a165caad92756600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310d9051a44a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb1a44b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81721a44d9a13701eafb76870cb220843b8c6476824bfa15933e9ee732cad53fcaab7a262f923a6c5a2f19033136dd925786b0890af8e44573f71695bc10fc25168ae1b41e5c92331a44e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b169845c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a486822448fdaaa7e6631e438625ca25c857a3727ea28e5659952928ee3ab47ef980231cd0ed75ebcce668b23ec23d21c7fc4ac91ceb2dc605973bd4914e6ae4d29db2d349441cb772244a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb2244b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81722244e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b16984").to_vec(); + let any2= hex!("5c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a4868280930071aa4190af6060af306f90370a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0f213a434eee1a6f27d9891a7c29c76641ffa43f4cef91a264824477eaea8300fa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202da8402625a00808467d00ef1b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b9cc1c4d529d31592a873c3cb3afd6bac1766302f424652c3fbedcbec2da7a7f99249f88dd1a13a1b22059c8b393540d187fb2628c89bda549a7010a2488533d6b3cf9bad7142f9ea61eff699dddf5a4e6423b4aecabf8dc499c923f2cdfbfa9f8488202d8a0b0e9d1ddd59db45429b1ae9d4c01812e7bdbe7a8822d32855617844f10ed5b748202d9a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3b804721ffbf07fc83f2f1cc3773881b3f7868b707198e84d42ac1bacf40039a8bb13009d78f96ff8e8d1552ae3583d001101aefcba4d6a827527fdce1b7e91afb0401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a67a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada094de24b42126f642e0497a72d77d0c583fb9c6230f7a6dba7e54efa97e13c627a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202db8402625a00808467d00ef4b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b50822e55669b92492ecc5a42229fe7c03e0d0116a0449e3d2897fc32e134e0a601a9a49c13fd8eea94162858a83229d086639a1cef8ea3a3210937ea0aec4f140d9ccae24ed535c9ddb75024d4d58133c0483e352bd634af301da84f98bb154f8488202d9a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3b8202daa0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a6780b6bdc9a4de82e5d16cb1868bea7a98df85879e37ff283cc4f5ed0604b58cbbdc60faa7b6dc3fb519c35ffe8a2b2cd34da95f65087c905345bae6ef8d319c5d3e01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a06c2e2a3f0dc9f7bbc40ec103c97b49ec079c88c00abf3cdd966922c557cc319ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0305c4387cd456db6642b98fb5a615619af15a1c900f612501c20793f24e91257a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202dc8402625a00808467d00ef7b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb8608871ce67969e2b836797cae67245c47e43d848aa91671b27bdf17c64a1b8567a2a8726d677cb7058e503aa5308f296a51574f47028fe8246d07a1c8c1ed49bfaacecdb0d0e93b97da8cc8e067022e2f89636aa38f7d22f4944e1b6c3158145b9f8488202daa0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a678202dba06c2e2a3f0dc9f7bbc40ec103c97b49ec079c88c00abf3cdd966922c557cc319e80869fda554f1f7821370f876ff60b3f4cab712df1a46f53cabea77f19e16a98af26f85c7cfb4cb482b1851ebc25e8e1482e70840c77075e7636a165caad92756600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310d9051a44a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb1a44b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81721a44d9a13701eafb76870cb220843b8c6476824bfa15933e9ee732cad53fcaab7a262f923a6c5a2f19033136dd925786b0890af8e44573f71695bc10fc25168ae1b41e5c92331a44e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b169845c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a486822448fdaaa7e6631e438625ca25c857a3727ea28e5659952928ee3ab47ef980231cd0ed75ebcce668b23ec23d21c7fc4ac91ceb2dc605973bd4914e6ae4d29db2d349441cb772244a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb2244b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81722244e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b169845c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a486828093007").to_vec(); any.extend(any2); let any: Any = any.try_into().unwrap(); // check if misbehaviour let err = client .update_client(&ctx, client_id.clone(), any) .unwrap_err(); - assert_err(err, "UnexpectedSameBlockHash : 0-3100"); + assert_err(err, "UnexpectedSameBlockHash : 0-730"); // fail: invalid block let mut mock_consensus_state = BTreeMap::new(); let trusted_cs = ConsensusState { current_validators_hash: hex!( - "5b514a7e8083146842c425a71aec83368ef4628442999a6d340d623ffb360c67" + "3d54d2721533c6c4f6b16867838d8e5b536f99733560b4de6b7231ca8755fcfc" ), previous_validators_hash: hex!( - "399334b2051da932262b42f25e5e59724c08df5c88d13c9d6bf5c51c33233aab" + "6c7878638fcd4ff99c05131c23b62dec729ef854d129b6deb38af8268dc9478b" ), ..Default::default() }; - mock_consensus_state.insert(Height::new(0, 3354), trusted_cs); + mock_consensus_state.insert(Height::new(0, 729), trusted_cs); let ctx = MockClientReader { client_state: Some(ClientState { chain_id: ChainId::new(9999), + fork_specs: vec![fork_spec_after_pascal(), fork_spec_after_lorentz()], ..Default::default() }), consensus_state: mock_consensus_state.clone(), }; - let mut any = hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212cf370a0b78782d7061726c69612d3112de1b0ab4060ab106f9032ea0268b5cdf7f6414cb54b00626c619892e5f3b693d568d546ff76198667f9e487ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0225560657909c76bbd1111cfa8a11f7ade19c80a315f013a920031ce76562e3ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820d1b8402625a0080846699bfd7b90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860b0b171c0b05dca088e0a163582339da1076da795a317c65f77441585d1446fda6692ce27df7b2b01ef2d419c2f8eb2f50b4e2f5856d9fb438f073c3e0aea72930333a6775d59096ce7560320504bb9bb4b17725edc5221491a3ac0bf64ec1f7ff848820d19a0e73c8182c6ff44e893b468600184209f9ffc5017be041533385658b98ee5675a820d1aa0268b5cdf7f6414cb54b00626c619892e5f3b693d568d546ff76198667f9e487b80649d4b1ea49d34532d24281cff713c1a1ffa9ad10ceaae118d02b19ec8a57bb4137e8ec449a3798de7cbec3a22d43d1377c84f045550e73e7100bb377df2753f01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea018b177b16b907b473a20b82a7c61d76f505a1f740c540e950f93c4210319a33ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0225560657909c76bbd1111cfa8a11f7ade19c80a315f013a920031ce76562e3ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820d1c8402625a0080846699bfdab90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b86083fcfb7f3c9d99995d330e6b953282f6c349af68cd4c523e1d635aa51ec49a2db651d824974ab9e7cf254e7e1b7e15cb0611ceb6adda365b8ee54d04c222b7f64dcacf94b4eb61671653396e1fe8840737444731d6c8d144d553a757e2327825f848820d1aa0268b5cdf7f6414cb54b00626c619892e5f3b693d568d546ff76198667f9e487b820d1ba018b177b16b907b473a20b82a7c61d76f505a1f740c540e950f93c4210319a33b80ddc0dfa730aa9a6de6089c20d1728803b04b4d7872a2b01c90e7cad663379a8a3f8676574fb5341ec662c890cae04fed92eaed9689c3b0c5421ea85fc3e42b5801a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea0220755141e26b1c68c8f887b41172aa93e3267f9f0ae7b49cfd1c7002558bcb4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0225560657909c76bbd1111cfa8a11f7ade19c80a315f013a920031ce76562e3ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820d1d8402625a0080846699bfddb90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860af867e0589e50a2571bfdec447fae755aade11b113b67c7928ef8bd3225a6aa29a0e29b7ab24d4952ebcbfd320258a41071e5875b547f4265c7eeb45ab4989294328db719d94157619bca873e451c3709447ecb0fa349df1084da580bb46a425f848820d1ba018b177b16b907b473a20b82a7c61d76f505a1f740c540e950f93c4210319a33b820d1ca0220755141e26b1c68c8f887b41172aa93e3267f9f0ae7b49cfd1c7002558bcb4804613f2a8116641990a7d1ce90f946e079891aa1d7904c01e078df492f1ef4dff120465d060478da7542c7cd65621d68d47c35e20482385ca5af9d58329eeac1e00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180801203109a1a1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0eec2a9e5f0342238c9790975e393915d8ef68ade66edfeb220210a2b13a89464a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a08851197273e914fa4bdd7b07c2fec3f243a63d2298ed39c2b0a78c4f7da9ddd880a0a74e307420bf9966d5db9a83ce48edc32c7a8e43328c6373de6875cefa04ad7aa0e502f113ade32bee3770b5a0117fa799c8812e5ab5a239e3878660c59c3537fda00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0d4182165b298d7b52b0f2064d19ab8bdad2b3955fa5b3d85c00673beb97e124480f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a03f47312ca98ac1f6ae9db9752c2a33529723b64e654d87f7847cee0382edfb55a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24903201f874819815e1a3f183c4addc814b71ec0e573e07f79ee9082926d82dd1711d6c45a9cc8841916d8563c2f80baa2244d9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab992a448fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512f2a44a7876ea32e7a748c697d01345145485561305b24903201f874819815e1a3f183c4addc814b71ec0e573e07").to_vec(); - let any2 = hex!("f79ee9082926d82dd1711d6c45a9cc8841916d8563c2f80baa300138011ade1b0ab4060ab106f9032ea0268b5cdf7f6414cb54b00626c619892e5f3b693d568d546ff76198667f9e487ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820d1b8402625a0080846699bfd7b90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860b0b171c0b05dca088e0a163582339da1076da795a317c65f77441585d1446fda6692ce27df7b2b01ef2d419c2f8eb2f50b4e2f5856d9fb438f073c3e0aea72930333a6775d59096ce7560320504bb9bb4b17725edc5221491a3ac0bf64ec1f7ff848820d19a0e73c8182c6ff44e893b468600184209f9ffc5017be041533385658b98ee5675a820d1aa0268b5cdf7f6414cb54b00626c619892e5f3b693d568d546ff76198667f9e487b80649d4b1ea49d34532d24281cff713c1a1ffa9ad10ceaae118d02b19ec8a57bb4137e8ec449a3798de7cbec3a22d43d1377c84f045550e73e7100bb377df2753f01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea018b177b16b907b473a20b82a7c61d76f505a1f740c540e950f93c4210319a33ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0225560657909c76bbd1111cfa8a11f7ade19c80a315f013a920031ce76562e3ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820d1c8402625a0080846699bfdab90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b86083fcfb7f3c9d99995d330e6b953282f6c349af68cd4c523e1d635aa51ec49a2db651d824974ab9e7cf254e7e1b7e15cb0611ceb6adda365b8ee54d04c222b7f64dcacf94b4eb61671653396e1fe8840737444731d6c8d144d553a757e2327825f848820d1aa0268b5cdf7f6414cb54b00626c619892e5f3b693d568d546ff76198667f9e487b820d1ba018b177b16b907b473a20b82a7c61d76f505a1f740c540e950f93c4210319a33b80ddc0dfa730aa9a6de6089c20d1728803b04b4d7872a2b01c90e7cad663379a8a3f8676574fb5341ec662c890cae04fed92eaed9689c3b0c5421ea85fc3e42b5801a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea0220755141e26b1c68c8f887b41172aa93e3267f9f0ae7b49cfd1c7002558bcb4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0225560657909c76bbd1111cfa8a11f7ade19c80a315f013a920031ce76562e3ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002820d1d8402625a0080846699bfddb90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860af867e0589e50a2571bfdec447fae755aade11b113b67c7928ef8bd3225a6aa29a0e29b7ab24d4952ebcbfd320258a41071e5875b547f4265c7eeb45ab4989294328db719d94157619bca873e451c3709447ecb0fa349df1084da580bb46a425f848820d1ba018b177b16b907b473a20b82a7c61d76f505a1f740c540e950f93c4210319a33b820d1ca0220755141e26b1c68c8f887b41172aa93e3267f9f0ae7b49cfd1c7002558bcb4804613f2a8116641990a7d1ce90f946e079891aa1d7904c01e078df492f1ef4dff120465d060478da7542c7cd65621d68d47c35e20482385ca5af9d58329eeac1e00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180801203109a1a1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0eec2a9e5f0342238c9790975e393915d8ef68ade66edfeb220210a2b13a89464a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a08851197273e914fa4bdd7b07c2fec3f243a63d2298ed39c2b0a78c4f7da9ddd880a0a74e307420bf9966d5db9a83ce48edc32c7a8e43328c6373de6875cefa04ad7aa0e502f113ade32bee3770b5a0117fa799c8812e5ab5a239e3878660c59c3537fda00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0d4182165b298d7b52b0f2064d19ab8bdad2b3955fa5b3d85c00673beb97e124480f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a03f47312ca98ac1f6ae9db9752c2a33529723b64e654d87f7847cee0382edfb55a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24903201f874819815e1a3f183c4addc814b71ec0e573e07f79ee9082926d82dd1711d6c45a9cc8841916d8563c2f80baa2244d9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab992a448fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512f2a44a7876ea32e7a748c697d01345145485561305b24903201f874819815e1a3f183c4addc814b71ec0e573e07f79ee9082926d82dd1711d6c45a9cc8841916d8563c2f80baa30013801").to_vec(); + let mut any= hex!("0a282f6962632e6c69676874636c69656e74732e7061726c69612e76312e4d69736265686176696f757212db320a0b78782d7061726c69612d3112a4190af6060af306f90370a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0f213a434eee1a6f27d9891a7c29c76641ffa43f4cef91a264824477eaea8300fa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202da8402625a00808467d00ef1b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b9cc1c4d529d31592a873c3cb3afd6bac1766302f424652c3fbedcbec2da7a7f99249f88dd1a13a1b22059c8b393540d187fb2628c89bda549a7010a2488533d6b3cf9bad7142f9ea61eff699dddf5a4e6423b4aecabf8dc499c923f2cdfbfa9f8488202d8a0b0e9d1ddd59db45429b1ae9d4c01812e7bdbe7a8822d32855617844f10ed5b748202d9a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3b804721ffbf07fc83f2f1cc3773881b3f7868b707198e84d42ac1bacf40039a8bb13009d78f96ff8e8d1552ae3583d001101aefcba4d6a827527fdce1b7e91afb0401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a67a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada094de24b42126f642e0497a72d77d0c583fb9c6230f7a6dba7e54efa97e13c627a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202db8402625a00808467d00ef4b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b50822e55669b92492ecc5a42229fe7c03e0d0116a0449e3d2897fc32e134e0a601a9a49c13fd8eea94162858a83229d086639a1cef8ea3a3210937ea0aec4f140d9ccae24ed535c9ddb75024d4d58133c0483e352bd634af301da84f98bb154f8488202d9a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3b8202daa0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a6780b6bdc9a4de82e5d16cb1868bea7a98df85879e37ff283cc4f5ed0604b58cbbdc60faa7b6dc3fb519c35ffe8a2b2cd34da95f65087c905345bae6ef8d319c5d3e01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a06c2e2a3f0dc9f7bbc40ec103c97b49ec079c88c00abf3cdd966922c557cc319ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0305c4387cd456db6642b98fb5a615619af15a1c900f612501c20793f24e91257a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202dc8402625a00808467d00ef7b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb8608871ce67969e2b836797cae67245c47e43d848aa91671b27bdf17c64a1b8567a2a8726d677cb7058e503aa5308f296a51574f47028fe8246d07a1c8c1ed49bfaacecdb0d0e93b97da8cc8e067022e2f89636aa38f7d22f4944e1b6c3158145b9f8488202daa0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a678202dba06c2e2a3f0dc9f7bbc40ec103c97b49ec079c88c00abf3cdd966922c557cc319e80869fda554f1f7821370f876ff60b3f4cab712df1a46f53cabea77f19e16a98af26f85c7cfb4cb482b1851ebc25e8e1482e70840c77075e7636a165caad92756600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310d9051a44a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb1a44b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81721a44d9a13701eafb76870cb220843b8c6476824bfa15933e9ee732cad53fcaab7a262f923a6c5a2f19033136dd925786b0890af8e44573f71695bc10fc25168ae1b41e5c92331a44e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b169845c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a486822448fdaaa7e6631e438625ca25c857a3727ea28e5659952928ee3ab47ef980231cd0ed75ebcce668b23ec23d21c7fc4ac91ceb2dc605973bd4914e6ae4d29db2d349441cb772244a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb2244b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81722244e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b16984").to_vec(); + let any2= hex!("5c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a4868280930071aa4190af6060af306f90370a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202da8402625a00808467d00ef1b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b9cc1c4d529d31592a873c3cb3afd6bac1766302f424652c3fbedcbec2da7a7f99249f88dd1a13a1b22059c8b393540d187fb2628c89bda549a7010a2488533d6b3cf9bad7142f9ea61eff699dddf5a4e6423b4aecabf8dc499c923f2cdfbfa9f8488202d8a0b0e9d1ddd59db45429b1ae9d4c01812e7bdbe7a8822d32855617844f10ed5b748202d9a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3b804721ffbf07fc83f2f1cc3773881b3f7868b707198e84d42ac1bacf40039a8bb13009d78f96ff8e8d1552ae3583d001101aefcba4d6a827527fdce1b7e91afb0401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a67a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada094de24b42126f642e0497a72d77d0c583fb9c6230f7a6dba7e54efa97e13c627a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202db8402625a00808467d00ef4b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb860b50822e55669b92492ecc5a42229fe7c03e0d0116a0449e3d2897fc32e134e0a601a9a49c13fd8eea94162858a83229d086639a1cef8ea3a3210937ea0aec4f140d9ccae24ed535c9ddb75024d4d58133c0483e352bd634af301da84f98bb154f8488202d9a06bb5eb76f326c67c7715cc402296353a74907abdcc384f551c1427dea1cb6e3b8202daa0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a6780b6bdc9a4de82e5d16cb1868bea7a98df85879e37ff283cc4f5ed0604b58cbbdc60faa7b6dc3fb519c35ffe8a2b2cd34da95f65087c905345bae6ef8d319c5d3e01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a06c2e2a3f0dc9f7bbc40ec103c97b49ec079c88c00abf3cdd966922c557cc319ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0305c4387cd456db6642b98fb5a615619af15a1c900f612501c20793f24e91257a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028202dc8402625a00808467d00ef7b90111d883010505846765746888676f312e32332e37856c696e7578000000ff037d50f8ae0fb8608871ce67969e2b836797cae67245c47e43d848aa91671b27bdf17c64a1b8567a2a8726d677cb7058e503aa5308f296a51574f47028fe8246d07a1c8c1ed49bfaacecdb0d0e93b97da8cc8e067022e2f89636aa38f7d22f4944e1b6c3158145b9f8488202daa0ee5f12de6366bb1488fa849c748b51e53a32d7daab6499ce8ab0d23cad617a678202dba06c2e2a3f0dc9f7bbc40ec103c97b49ec079c88c00abf3cdd966922c557cc319e80869fda554f1f7821370f876ff60b3f4cab712df1a46f53cabea77f19e16a98af26f85c7cfb4cb482b1851ebc25e8e1482e70840c77075e7636a165caad92756600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310d9051a44a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb1a44b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81721a44d9a13701eafb76870cb220843b8c6476824bfa15933e9ee732cad53fcaab7a262f923a6c5a2f19033136dd925786b0890af8e44573f71695bc10fc25168ae1b41e5c92331a44e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b169845c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a486822448fdaaa7e6631e438625ca25c857a3727ea28e5659952928ee3ab47ef980231cd0ed75ebcce668b23ec23d21c7fc4ac91ceb2dc605973bd4914e6ae4d29db2d349441cb772244a7876ea32e7a748c697d01345145485561305b24a5d7d2e39dd93e5df8bb135ce476c313de541f8029f742c84cce3ab86ce1f56006167491c71c10856b89a9cc07a5b9cb2244b2e42bc54d19116d2348ac83461e2e0915d508ad92becd1a47f6eaec1583ebdd4990b518666e0cee67961b5cfb24bf538d7ea370bed973f07824cd5c31a1a091fbee81722244e04db2de85453e0936b441c339a26d10cfa71b50a498f4680dc9f07facc7e1bceafed4dc1efe3a32b169845c4b8f96da8de788ddaeb513ee0a898e1410b3791e2a4a486828093007").to_vec(); any.extend(any2); let any: Any = any.try_into().unwrap(); // check if misbehaviour @@ -1117,7 +1271,7 @@ mod test { let err = client .update_client(&ctx, client_id.clone(), any.clone()) .unwrap_err(); - assert_err(err, "UnexpectedHeaderRelation: 3355 3356"); + assert_err(err, "UnexpectedHeaderRelation: 730 731"); // fail: client state is frozen let ctx = MockClientReader { @@ -1157,67 +1311,95 @@ mod test { #[cfg(feature = "dev")] mod dev_test_min { - use crate::client::test::MockClientReader; + use crate::client::test::{assert_err, MockClientReader}; use crate::client::ParliaLightClient; use crate::client_state::ClientState; use crate::consensus_state::ConsensusState; - use crate::header::hardfork::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED}; + use crate::fixture::{localnet, Network}; + use crate::fork_spec::{ForkSpec, HeightOrTimestamp}; + use crate::header::constant::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED}; use crate::misc::{new_height, new_timestamp}; - use hex_literal::hex; use light_client::{types::Any, LightClient}; + use rstest::rstest; use std::collections::BTreeMap; - - #[test] - fn test_supported_timestamp() { - let client_state = hex!("0a272f6962632e6c69676874636c69656e74732e7061726c69612e76312e436c69656e745374617465124d08381214151f3951fa218cac426edfe078fa9e5c6dcea5001a2000000000000000000000000000000000000000000000000000000000000000002205109b9ea90f2a040880a305320410c0843d").to_vec(); - let consensus_state = hex!("0a2a2f6962632e6c69676874636c69656e74732e7061726c69612e76312e436f6e73656e7375735374617465126c0a2056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42110de82d5a8061a209c59cf0b5717cb6e2bd8620b7f3481605c8abcd45636bdf45c86db06338f0c5e22207a1dede35f5c835fecdc768324928cd0d9d9161e8529e1ba1e60451f3a9d088a").to_vec(); - let client = ParliaLightClient::default(); - let mock_consensus_state = BTreeMap::new(); - let ctx = MockClientReader { - client_state: None, - consensus_state: mock_consensus_state, - }; - let any_client_state: Any = client_state.try_into().unwrap(); - let any_consensus_state: Any = consensus_state.try_into().unwrap(); - let err = client - .create_client(&ctx, any_client_state.clone(), any_consensus_state.clone()) - .unwrap_err(); - assert!( - format!("{:?}", err).contains("UnsupportedMinimumTimestamp"), - "{}", - err - ); - } - - #[test] - fn test_supported_height() { - let client_state = hex!("0a272f6962632e6c69676874636c69656e74732e7061726c69612e76312e436c69656e745374617465124d08381214151f3951fa218cac426edfe078fa9e5c6dcea5001a2000000000000000000000000000000000000000000000000000000000000000002205109b9ea90f2a040880a305320410c0843d").to_vec(); - let consensus_state = hex!("0a2a2f6962632e6c69676874636c69656e74732e7061726c69612e76312e436f6e73656e7375735374617465126c0a2056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42110de82d5a8061a209c59cf0b5717cb6e2bd8620b7f3481605c8abcd45636bdf45c86db06338f0c5e22207a1dede35f5c835fecdc768324928cd0d9d9161e8529e1ba1e60451f3a9d088a").to_vec(); - let client = ParliaLightClient::default(); - let mock_consensus_state = BTreeMap::new(); - let ctx = MockClientReader { - client_state: None, - consensus_state: mock_consensus_state, + use std::prelude::rust_2015::Box; + + #[rstest] + #[case::localnet(localnet())] + fn test_supported_value(#[case] hp: Box) { + let runner = |func: Box< + dyn FnOnce(ClientState, ConsensusState) -> (ClientState, ConsensusState), + >| { + let (client_state, consensus_state, _, _) = hp.success_create_client(); + let client = ParliaLightClient; + let mock_consensus_state = BTreeMap::new(); + let ctx = MockClientReader { + client_state: None, + consensus_state: mock_consensus_state, + }; + let any_client_state: Any = client_state.try_into().unwrap(); + let any_consensus_state: Any = consensus_state.try_into().unwrap(); + let mut client_state = ClientState::try_from(any_client_state.clone()).unwrap(); + let mut consensus_state = + ConsensusState::try_from(any_consensus_state.clone()).unwrap(); + (client_state, consensus_state) = func(client_state, consensus_state); + let any_client_state: Any = client_state.try_into().unwrap(); + let any_consensus_state: Any = consensus_state.try_into().unwrap(); + client.create_client(&ctx, any_client_state.clone(), any_consensus_state.clone()) }; - let any_client_state: Any = client_state.try_into().unwrap(); - let any_consensus_state: Any = consensus_state.try_into().unwrap(); - - let mut client_state: ClientState = any_client_state.try_into().unwrap(); - client_state.latest_height = new_height(0, MINIMUM_HEIGHT_SUPPORTED - 1); - let mut consensus_state: ConsensusState = any_consensus_state.try_into().unwrap(); - consensus_state.timestamp = new_timestamp(MINIMUM_TIMESTAMP_SUPPORTED).unwrap(); - - let any_client_state: Any = client_state.try_into().unwrap(); - let any_consensus_state: Any = consensus_state.try_into().unwrap(); - let err = client - .create_client(&ctx, any_client_state.clone(), any_consensus_state.clone()) - .unwrap_err(); - assert!( - format!("{:?}", err).contains("UnsupportedMinimumHeight"), - "{}", - err - ); + let result = runner(Box::new(|client_state, mut cons_state| { + cons_state.timestamp = new_timestamp(MINIMUM_TIMESTAMP_SUPPORTED - 1).unwrap(); + (client_state, cons_state) + })); + assert_err(result.unwrap_err(), "UnsupportedMinimumTimestamp"); + + let result = runner(Box::new(|mut client_state, mut cons_state| { + cons_state.timestamp = new_timestamp(MINIMUM_TIMESTAMP_SUPPORTED).unwrap(); + client_state.latest_height = new_height(0, MINIMUM_HEIGHT_SUPPORTED - 1); + (client_state, cons_state) + })); + assert_err(result.unwrap_err(), "UnsupportedMinimumHeight"); + + let result = runner(Box::new(|mut client_state, mut cons_state| { + cons_state.timestamp = new_timestamp(MINIMUM_TIMESTAMP_SUPPORTED).unwrap(); + client_state.latest_height = new_height(0, MINIMUM_HEIGHT_SUPPORTED); + client_state.fork_specs = vec![ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(MINIMUM_HEIGHT_SUPPORTED - 1), + additional_header_item_count: 0, + epoch_length: 200, + max_turn_length: 9, + }]; + (client_state, cons_state) + })); + assert_err(result.unwrap_err(), "UnsupportedMinimumHeightFork"); + + let result = runner(Box::new(|mut client_state, mut cons_state| { + cons_state.timestamp = new_timestamp(MINIMUM_TIMESTAMP_SUPPORTED).unwrap(); + client_state.latest_height = new_height(0, MINIMUM_HEIGHT_SUPPORTED); + client_state.fork_specs = vec![ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(MINIMUM_TIMESTAMP_SUPPORTED - 1), + additional_header_item_count: 0, + epoch_length: 200, + max_turn_length: 9, + }]; + (client_state, cons_state) + })); + assert_err(result.unwrap_err(), "UnsupportedMinimumTimestampFork"); + + // success + runner(Box::new(|mut client_state, mut cons_state| { + cons_state.timestamp = new_timestamp(MINIMUM_TIMESTAMP_SUPPORTED).unwrap(); + client_state.latest_height = new_height(0, MINIMUM_HEIGHT_SUPPORTED); + client_state.fork_specs = vec![ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(MINIMUM_TIMESTAMP_SUPPORTED), + additional_header_item_count: 0, + epoch_length: 200, + max_turn_length: 9, + }]; + (client_state, cons_state) + })) + .unwrap(); } } } diff --git a/light-client/src/client_state.rs b/light-client/src/client_state.rs index ac1ba332..f776edad 100644 --- a/light-client/src/client_state.rs +++ b/light-client/src/client_state.rs @@ -8,10 +8,9 @@ use prost::Message as _; use parlia_ibc_proto::google::protobuf::Any as IBCAny; use parlia_ibc_proto::ibc::lightclients::parlia::v1::ClientState as RawClientState; -use crate::commitment::resolve_account; use crate::consensus_state::ConsensusState; use crate::errors::Error; -use crate::header::hardfork::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED}; +use crate::fork_spec::{ForkSpec, HeightOrTimestamp}; use crate::header::Header; use crate::misbehaviour::Misbehaviour; use crate::misc::{new_height, Address, ChainId, Hash}; @@ -34,6 +33,9 @@ pub struct ClientState { /// State pub latest_height: Height, pub frozen: bool, + + /// fork specs + pub fork_specs: Vec, } impl ClientState { @@ -42,6 +44,7 @@ impl ClientState { pub fn canonicalize(mut self) -> Self { self.latest_height = new_height(self.chain_id.version(), 0); self.frozen = false; + self.fork_specs = vec![]; self } @@ -54,29 +57,32 @@ impl ClientState { &self, now: Time, trusted_consensus_state: &ConsensusState, - header: Header, + mut header: Header, ) -> Result<(ClientState, ConsensusState), Error> { // Ensure header is valid - self.check_header(now, trusted_consensus_state, &header)?; - + self.check_header(now, trusted_consensus_state, &mut header)?; let mut new_client_state = self.clone(); + + // Update fork specs if timestamp + for fs in &mut new_client_state.fork_specs.iter_mut() { + if let HeightOrTimestamp::Time(ts) = fs.height_or_timestamp { + // second must be forks spec timestamp + if header.eth_header().all.len() >= 2 { + let h = &header.eth_header().all[1]; + if ts <= h.milli_timestamp() { + fs.height_or_timestamp = HeightOrTimestamp::Height(h.number) + } + } + } + } + let header_height = header.height(); if new_client_state.latest_height < header_height { new_client_state.latest_height = header_height; } - // Ensure world state is valid - let account = resolve_account( - header.state_root(), - &header.account_proof()?, - &new_client_state.ibc_store_address, - )?; - let new_consensus_state = ConsensusState { - state_root: account - .storage_root - .try_into() - .map_err(Error::UnexpectedStorageRoot)?, + state_root: *header.state_root(), timestamp: header.timestamp()?, current_validators_hash: header.current_epoch_validators_hash(), previous_validators_hash: header.previous_epoch_validators_hash(), @@ -90,26 +96,21 @@ impl ClientState { now: Time, h1_trusted_cs: &ConsensusState, h2_trusted_cs: &ConsensusState, - misbehaviour: &Misbehaviour, + misbehaviour: &mut Misbehaviour, ) -> Result { - self.check_header(now, h1_trusted_cs, &misbehaviour.header_1)?; - self.check_header(now, h2_trusted_cs, &misbehaviour.header_2)?; + self.check_header(now, h1_trusted_cs, &mut misbehaviour.header_1)?; + self.check_header(now, h2_trusted_cs, &mut misbehaviour.header_2)?; Ok(self.clone().freeze()) } - fn check_header(&self, now: Time, cs: &ConsensusState, header: &Header) -> Result<(), Error> { - // Ensure header has supported timestamp - let ts = header.timestamp()?; - - #[allow(clippy::absurd_extreme_comparisons)] - if ts.as_unix_timestamp_secs() < MINIMUM_TIMESTAMP_SUPPORTED { - return Err(Error::UnsupportedMinimumTimestamp(ts)); - } - #[allow(clippy::absurd_extreme_comparisons)] - if header.height().revision_height() < MINIMUM_HEIGHT_SUPPORTED { - return Err(Error::UnsupportedMinimumHeight(header.height())); - } + fn check_header( + &self, + now: Time, + cs: &ConsensusState, + header: &mut Header, + ) -> Result<(), Error> { // Ensure last consensus state is within the trusting period + let ts = header.timestamp()?; validate_within_trusting_period( now, self.trusting_period, @@ -127,6 +128,9 @@ impl ClientState { )); } + // Ensure satisfying fork specs + header.assign_fork_spec(&self.fork_specs)?; + // Ensure header is valid header.verify(&self.chain_id, cs) } @@ -207,6 +211,12 @@ impl TryFrom for ClientState { let frozen = value.frozen; + let mut fork_specs = Vec::with_capacity(value.fork_specs.len()); + for fs in value.fork_specs { + let fork_spec = ForkSpec::try_from(fs)?; + fork_specs.push(fork_spec) + } + Ok(Self { chain_id, ibc_store_address, @@ -215,12 +225,14 @@ impl TryFrom for ClientState { trusting_period, max_clock_drift, frozen, + fork_specs, }) } } impl From for RawClientState { fn from(value: ClientState) -> Self { + let fork_specs = value.fork_specs.into_iter().map(|fs| fs.into()).collect(); Self { chain_id: value.chain_id.id(), ibc_store_address: value.ibc_store_address.to_vec(), @@ -232,6 +244,7 @@ impl From for RawClientState { trusting_period: Some(value.trusting_period.into()), max_clock_drift: Some(value.max_clock_drift.into()), frozen: value.frozen.to_owned(), + fork_specs, } } } @@ -296,14 +309,25 @@ mod test { use crate::header::eth_header::ETHHeader; use crate::header::eth_headers::ETHHeaders; + use crate::fork_spec::{ForkSpec, HeightOrTimestamp}; use crate::header::Header; use crate::misc::{new_timestamp, ChainId}; use alloc::boxed::Box; + use parlia_ibc_proto::ibc::lightclients::parlia::v1::ForkSpec as RawForkSpec; use parlia_ibc_proto::ibc::lightclients::parlia::v1::Header as RawHeader; use parlia_ibc_proto::ibc::lightclients::parlia::v1::{ ClientState as RawClientState, EthHeader, }; + fn after_pascal() -> ForkSpec { + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(0), + additional_header_item_count: 1, // requestsHash + epoch_length: 200, + max_turn_length: 9, + } + } + #[rstest] #[case::localnet(localnet())] fn test_error_check_header_and_update_state(#[case] hp: Box) { @@ -315,18 +339,18 @@ mod test { max_clock_drift: Default::default(), latest_height: Default::default(), frozen: false, + fork_specs: vec![after_pascal()], }; // fail: check_header let h = &hp.epoch_header(); let cons_state = ConsensusState { state_root: [0u8; 32], - timestamp: new_timestamp(h.timestamp).unwrap(), + timestamp: new_timestamp(h.milli_timestamp()).unwrap(), current_validators_hash: hp.previous_epoch_header().epoch.unwrap().hash(), previous_validators_hash: hp.previous_epoch_header().epoch.unwrap().hash(), }; let header = Header::new( - vec![1], ETHHeaders { target: hp.epoch_header(), all: vec![], @@ -338,7 +362,7 @@ mod test { hp.previous_epoch_header().epoch.unwrap(), hp.epoch_header().epoch.unwrap(), ); - let now = new_timestamp(h.timestamp + 1).unwrap(); + let now = new_timestamp(h.milli_timestamp() + 1).unwrap(); let err = cs .check_header_and_update_state(now, &cons_state, header.clone()) .unwrap_err(); @@ -349,34 +373,6 @@ mod test { } err => unreachable!("{:?}", err), } - - // fail: resolve_account - let header = Header::new( - vec![1], - ETHHeaders { - target: hp.epoch_header(), - all: vec![ - hp.epoch_header(), - hp.epoch_header_plus_1(), - hp.epoch_header_plus_2(), - ], - }, - Height { - revision_number: 0, - revision_height: h.number - 1, - }, - hp.previous_epoch_header().epoch.unwrap(), - hp.epoch_header().epoch.unwrap(), - ); - let err = cs - .check_header_and_update_state(now, &cons_state, header) - .unwrap_err(); - match err { - Error::InvalidProofFormatError(value) => { - assert_eq!(value, vec![1]); - } - err => unreachable!("{:?}", err), - } } #[rstest] @@ -390,7 +386,6 @@ mod test { let raw = RawHeader { headers: vec![EthHeader { header: h_rlp }], trusted_height: Some(trusted_height), - account_proof: vec![], current_validators: if h.is_epoch() { h.epoch.clone().unwrap().validators().clone() } else { @@ -411,6 +406,7 @@ mod test { max_clock_drift: Default::default(), latest_height: Default::default(), frozen: false, + fork_specs: vec![after_pascal()], }; let mut cons_state = ConsensusState { state_root: [0u8; 32], @@ -421,10 +417,10 @@ mod test { // fail: validate_trusting_period let h = hp.epoch_header(); - let now = new_timestamp(h.timestamp - 1).unwrap(); - cons_state.timestamp = new_timestamp(h.timestamp).unwrap(); - let header = header_fn(0, &h, hp.epoch_header_rlp()); - let err = cs.check_header(now, &cons_state, &header).unwrap_err(); + let now = new_timestamp(h.milli_timestamp() - 1).unwrap(); + cons_state.timestamp = new_timestamp(h.milli_timestamp()).unwrap(); + let mut header = header_fn(0, &h, hp.epoch_header_rlp()); + let err = cs.check_header(now, &cons_state, &mut header).unwrap_err(); match err { Error::HeaderFromFuture(_, _, _) => {} err => unreachable!("{:?}", err), @@ -432,10 +428,10 @@ mod test { // fail: revision check let h = hp.epoch_header(); - let now = new_timestamp(h.timestamp + 1).unwrap(); - cons_state.timestamp = new_timestamp(h.timestamp).unwrap(); - let header = header_fn(1, &h, hp.epoch_header_rlp()); - let err = cs.check_header(now, &cons_state, &header).unwrap_err(); + let now = new_timestamp(h.milli_timestamp() + 1).unwrap(); + cons_state.timestamp = new_timestamp(h.milli_timestamp()).unwrap(); + let mut header = header_fn(1, &h, hp.epoch_header_rlp()); + let err = cs.check_header(now, &cons_state, &mut header).unwrap_err(); match err { Error::UnexpectedHeaderRevision(n1, n2) => { assert_eq!(cs.chain_id.version(), n1); @@ -446,12 +442,12 @@ mod test { // fail: verify_validator_set let h = hp.epoch_header(); - let header = header_fn(0, &h, hp.epoch_header_rlp()); - let err = cs.check_header(now, &cons_state, &header).unwrap_err(); + let mut header = header_fn(0, &h, hp.epoch_header_rlp()); + let err = cs.check_header(now, &cons_state, &mut header).unwrap_err(); match err { - Error::UnexpectedUntrustedValidatorsHashInEpoch(h1, h2, _, _) => { + Error::UnexpectedUntrustedValidatorsHashInEpoch(h1, h2, _, _, _) => { assert_eq!(h1.revision_height(), h.number - 1); - assert_eq!(h2.revision_height(), h.number); + assert_eq!(h2, h.number); } err => unreachable!("{:?}", err), } @@ -459,8 +455,8 @@ mod test { // fail: header.verify let h = hp.epoch_header(); cons_state.current_validators_hash = Epoch::new(vec![h.coinbase.clone()].into(), 1).hash(); - let header = header_fn(0, &h, hp.epoch_header_rlp()); - let err = cs.check_header(now, &cons_state, &header).unwrap_err(); + let mut header = header_fn(0, &h, hp.epoch_header_rlp()); + let err = cs.check_header(now, &cons_state, &mut header).unwrap_err(); match err { Error::UnexpectedCoinbase(number) => { assert_eq!(number, h.number); @@ -471,22 +467,22 @@ mod test { #[test] fn test_success_try_from_any() { - let cs = hex!("0a272f6962632e6c69676874636c69656e74732e7061726c69612e76312e436c69656e745374617465124d08381214151f3951fa218cac426edfe078fa9e5c6dcea5001a200000000000000000000000000000000000000000000000000000000000000000220510af9da90f2a040880a305320410c0843d").to_vec(); + let cs = hex!("0a272f6962632e6c69676874636c69656e74732e7061726c69612e76312e436c69656e7453746174651253088f4e1214aa43d337145e8930d01cb4e60abf6595c692921e1a201ee222554989dda120e26ecacf756fe1235cd8d726706b57517715dde4f0c900220410dffb012a040880a305320410c0843d420410001815").to_vec(); let cs: Any = cs.try_into().unwrap(); let cs: ClientState = cs.try_into().unwrap(); assert_eq!(0, cs.latest_height.revision_number()); - assert_eq!(32132783, cs.latest_height.revision_height()); - assert_eq!(56, cs.chain_id.id()); + assert_eq!(32223, cs.latest_height.revision_height()); + assert_eq!(9999, cs.chain_id.id()); assert_eq!(0, cs.chain_id.version()); assert_eq!(86400, cs.trusting_period.as_secs()); assert_eq!(1, cs.max_clock_drift.as_millis()); assert_eq!( - hex!("151f3951FA218cac426edFe078fA9e5C6dceA500"), + hex!("aa43d337145E8930d01cb4E60Abf6595C692921E"), cs.ibc_store_address ); assert_eq!( - hex!("0000000000000000000000000000000000000000000000000000000000000000"), + hex!("1ee222554989dda120e26ecacf756fe1235cd8d726706b57517715dde4f0c900"), cs.ibc_commitments_slot ); } @@ -501,6 +497,7 @@ mod test { trusting_period: None, max_clock_drift: None, frozen: false, + fork_specs: vec![RawForkSpec::from(after_pascal())], }; let err = ClientState::try_from(cs.clone()).unwrap_err(); match err { @@ -705,69 +702,4 @@ mod test { panic!("expected error"); } } - #[cfg(feature = "dev")] - mod dev_test_min { - use crate::client_state::ClientState; - use crate::consensus_state::ConsensusState; - use crate::errors::Error; - use crate::fixture::localnet; - use crate::header::eth_headers::ETHHeaders; - use crate::header::hardfork::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED}; - use crate::header::Header; - use crate::misc::new_timestamp; - use parlia_ibc_proto::ibc::core::client::v1::Height; - - #[test] - fn test_supported_timestamp() { - let header = Header::new( - vec![1], - ETHHeaders { - target: localnet().previous_epoch_header(), - all: vec![], - }, - Height::default(), - localnet().previous_epoch_header().epoch.unwrap(), - localnet().epoch_header().epoch.unwrap(), - ); - let cs = ClientState::default(); - let cons_state = ConsensusState::default(); - let err = cs - .check_header(new_timestamp(0).unwrap(), &cons_state, &header) - .unwrap_err(); - match err { - Error::UnsupportedMinimumTimestamp(e1) => { - assert_eq!(e1, header.timestamp().unwrap()); - } - err => unreachable!("{:?}", err), - } - } - - #[test] - fn test_supported_height() { - let mut header = Header::new( - vec![1], - ETHHeaders { - target: localnet().previous_epoch_header(), - all: vec![], - }, - Height::default(), - localnet().previous_epoch_header().epoch.unwrap(), - localnet().epoch_header().epoch.unwrap(), - ); - header.eth_header_mut().target.timestamp = MINIMUM_TIMESTAMP_SUPPORTED; - header.eth_header_mut().target.number = MINIMUM_HEIGHT_SUPPORTED - 1; - - let cs = ClientState::default(); - let cons_state = ConsensusState::default(); - let err = cs - .check_header(new_timestamp(0).unwrap(), &cons_state, &header) - .unwrap_err(); - match err { - Error::UnsupportedMinimumHeight(e1) => { - assert_eq!(e1, header.height()); - } - err => unreachable!("{:?}", err), - } - } - } } diff --git a/light-client/src/consensus_state.rs b/light-client/src/consensus_state.rs index 63ba7214..66eadb1d 100644 --- a/light-client/src/consensus_state.rs +++ b/light-client/src/consensus_state.rs @@ -61,7 +61,7 @@ impl From for RawConsensusState { fn from(value: ConsensusState) -> Self { Self { state_root: value.state_root.to_vec(), - timestamp: value.timestamp.as_unix_timestamp_secs(), + timestamp: (value.timestamp.as_unix_timestamp_nanos() / 1_000_000) as u64, current_validators_hash: value.current_validators_hash.into(), previous_validators_hash: value.previous_validators_hash.into(), } @@ -123,21 +123,24 @@ mod test { #[test] fn test_success_try_from_any() { - let cs = hex!("0a2a2f6962632e6c69676874636c69656e74732e7061726c69612e76312e436f6e73656e7375735374617465126c0a2056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42110de82d5a8061a209c59cf0b5717cb6e2bd8620b7f3481605c8abcd45636bdf45c86db06338f0c5e22207a1dede35f5c835fecdc768324928cd0d9d9161e8529e1ba1e60451f3a9d088a").to_vec(); + let cs = hex!("0a2a2f6962632e6c69676874636c69656e74732e7061726c69612e76312e436f6e73656e7375735374617465126d0a20e0cecaaf108b444908180c46807c7891991377cc43669273e779c5c0c5cbd77c10c88db8afd6321a204e013ddc6238ab26c478ce824c78b5938efa2d4e5eb73e9c9a3172ffca99c7ee22203acf3e01a40afb77b433f11eb9a311cbc5326957d5d3e9e9428439d17b76ead0").to_vec(); let cs: Any = cs.try_into().unwrap(); let cs: ConsensusState = cs.try_into().unwrap(); assert_eq!( - hex!("9c59cf0b5717cb6e2bd8620b7f3481605c8abcd45636bdf45c86db06338f0c5e"), + hex!("4e013ddc6238ab26c478ce824c78b5938efa2d4e5eb73e9c9a3172ffca99c7ee"), cs.current_validators_hash ); assert_eq!( - hex!("7a1dede35f5c835fecdc768324928cd0d9d9161e8529e1ba1e60451f3a9d088a"), + hex!("3acf3e01a40afb77b433f11eb9a311cbc5326957d5d3e9e9428439d17b76ead0"), cs.previous_validators_hash ); - assert_eq!(1695891806, cs.timestamp.as_unix_timestamp_secs()); assert_eq!( - hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), + 1741171853000, + cs.timestamp.as_unix_timestamp_nanos() / 1_000_000 + ); + assert_eq!( + hex!("e0cecaaf108b444908180c46807c7891991377cc43669273e779c5c0c5cbd77c"), cs.state_root ); } diff --git a/light-client/src/errors.rs b/light-client/src/errors.rs index 6e1531c6..eecf2793 100644 --- a/light-client/src/errors.rs +++ b/light-client/src/errors.rs @@ -2,13 +2,13 @@ use alloc::string::String; use alloc::vec::Vec; use core::fmt::Formatter; +use crate::fork_spec::ForkSpec; +use crate::misc::{Address, BlockNumber, Hash}; use k256::ecdsa::signature; use light_client::commitments::{CommitmentPrefix, Error as CommitmentError}; use light_client::types::{Any, ClientId, Height, Time, TimeError}; use trie_db::TrieError; -use crate::misc::{Address, BlockNumber, Hash}; - type BoxedTrieError = alloc::boxed::Box>; #[derive(Debug)] @@ -25,6 +25,7 @@ pub enum Error { UnknownMisbehaviourType(String), UnexpectedClientType(String), LCPCommitmentError(CommitmentError), + VerifyAccountError(alloc::boxed::Box), // ClientState error MissingLatestHeight, @@ -33,6 +34,11 @@ pub enum Error { ClientFrozen(ClientId), UnexpectedProofHeight(Height, Height), UnexpectedRevisionHeight(u64), + EmptyForkSpec, + UnsupportedMinimumTimestampForkSpec(u64), + UnsupportedMinimumHeightForkSpec(u64), + UnsupportedMinimumTimestamp(Time), + UnsupportedMinimumHeight(Height), // ConsensusState error AccountNotFound(Address), @@ -51,8 +57,6 @@ pub enum Error { UnexpectedValidatorsHashSize(Vec), // Header error - UnsupportedMinimumTimestamp(Time), - UnsupportedMinimumHeight(Height), MissingPreviousValidators(BlockNumber), MissingCurrentValidators(BlockNumber), OutOfTrustingPeriod(Time, Time), @@ -60,6 +64,7 @@ pub enum Error { MissingTrustedHeight, MissingTrustingPeriod, NegativeMaxClockDrift, + UnexpectedTrustedEpoch(BlockNumber, BlockNumber, BlockNumber, BlockNumber), UnexpectedTrustedHeight(BlockNumber, BlockNumber), EmptyHeader, UnexpectedHeaderRevision(u64, u64), @@ -67,7 +72,7 @@ pub enum Error { UnexpectedSignature(BlockNumber, signature::Error), MissingVanityInExtraData(BlockNumber, usize, usize), MissingSignatureInExtraData(BlockNumber, usize, usize), - UnexpectedMixHash(BlockNumber), + UnexpectedMixHash(BlockNumber, Vec), UnexpectedUncleHash(BlockNumber), UnexpectedDifficulty(BlockNumber, u64), UnexpectedNonce(BlockNumber), @@ -84,8 +89,8 @@ pub enum Error { MissingTurnLengthInEpochBlock(BlockNumber), MissingEpochInfoInEpochBlock(BlockNumber), MissingNextValidatorSet(BlockNumber), - UnexpectedPreviousValidatorsHash(Height, Height, Hash, Hash), - UnexpectedCurrentValidatorsHash(Height, Height, Hash, Hash), + UnexpectedPreviousValidatorsHash(Height, BlockNumber, Hash, Hash, BlockNumber), + UnexpectedCurrentValidatorsHash(Height, BlockNumber, Hash, Hash, BlockNumber), InvalidVerifyingHeaderLength(BlockNumber, usize), InsufficientHonestValidator(Hash, usize, usize), MissingValidatorToVerifySeal(BlockNumber), @@ -95,12 +100,17 @@ pub enum Error { MissingTrustedCurrentValidators(BlockNumber), UnexpectedDifficultyInTurn(BlockNumber, u64, usize), UnexpectedDifficultyNoTurn(BlockNumber, u64, usize), - UnexpectedUntrustedValidatorsHashInEpoch(Height, Height, Hash, Hash), - UnexpectedCurrentValidatorsHashInEpoch(Height, Height, Hash, Hash), + UnexpectedUntrustedValidatorsHashInEpoch(Height, BlockNumber, Hash, Hash, BlockNumber), + UnexpectedCurrentValidatorsHashInEpoch(Height, BlockNumber, Hash, Hash), UnexpectedUntrustedValidators(BlockNumber, BlockNumber), MissingRequestsHash(BlockNumber), UnexpectedRequestsHash(BlockNumber, Vec), UnexpectedHeaderRLP(BlockNumber), + MissingForkSpec(BlockNumber, u64), + MissingForkSpecByHeight(BlockNumber), + UnexpectedHeaderItemCount(BlockNumber, usize, u64), + MissingEpochInfo(BlockNumber), + UnexpectedEpochInfo(BlockNumber, BlockNumber), // Vote attestation UnexpectedTooManyHeadersToFinalize(BlockNumber, usize), @@ -119,6 +129,19 @@ pub enum Error { UnexpectedTurnLength(u8), UnexpectedExtraDataLength(usize), + // Fork Spec + MissingTimestampOrHeightInForkSpec, + UnexpectedForkSpecTimestampOrder(u64, u64), + UnexpectedForkSpecHeightOrder(u64, u64), + MissingForkHeightIntPreviousEpochCalculation(u64, ForkSpec), + MissingForkHeightInBoundaryCalculation(ForkSpec), + MissingBoundaryEpochs(BlockNumber), + MissingPreviousForkSpec(ForkSpec), + UnexpectedCurrentEpochInCalculatingNextEpoch(BlockNumber, BlockNumber, BlockNumber), + UnexpectedMissingForkSpecInCurrentEpochCalculation(BlockNumber, alloc::boxed::Box), + UnexpectedMissingForkSpecInPreviousEpochCalculation(BlockNumber, alloc::boxed::Box), + UnexpectedPreviousEpochInCalculatingNextEpoch(BlockNumber, BlockNumber, BlockNumber), + // Misbehaviour MissingHeader1, MissingHeader2, @@ -163,8 +186,15 @@ impl core::fmt::Display for Error { write!(f, "HeaderFromFuture: {} {:?} {}", e1, e2, e3) } Error::MissingTrustedHeight => write!(f, "MissingTrustedHeight"), + Error::UnexpectedTrustedEpoch(e1, e2, e3, e4) => { + write!( + f, + "UnexpectedTrustedEpoch: {} {} header_epoch={} trusted_epoch={}", + e1, e2, e3, e4 + ) + } Error::UnexpectedTrustedHeight(e1, e2) => { - write!(f, "UnexpectedTrustedHeight: {} {}", e1, e2) + write!(f, "UnexpectedTrustedHeight: {} {} ", e1, e2) } Error::EmptyHeader => write!(f, "EmptyHeader"), Error::UnexpectedHeaderRevision(e1, e2) => { @@ -286,21 +316,21 @@ impl core::fmt::Display for Error { Error::MissingCurrentValidators(e1) => { write!(f, "MissingCurrentValidators : {:?}", e1) } - Error::UnexpectedMixHash(e1) => { - write!(f, "UnexpectedMixHash : {:?}", e1) + Error::UnexpectedMixHash(e1, e2) => { + write!(f, "UnexpectedMixHash : {:?} {:?}", e1, e2) } - Error::UnexpectedPreviousValidatorsHash(e1, e2, e3, e4) => { + Error::UnexpectedPreviousValidatorsHash(e1, e2, e3, e4, e5) => { write!( f, - "UnexpectedPreviousValidatorsHash : {:?} {:?} {:?} {:?}", - e1, e2, e3, e4 + "UnexpectedPreviousValidatorsHash : {:?} {:?} {:?} {:?} trusted_epoch={}", + e1, e2, e3, e4, e5 ) } - Error::UnexpectedCurrentValidatorsHash(e1, e2, e3, e4) => { + Error::UnexpectedCurrentValidatorsHash(e1, e2, e3, e4, e5) => { write!( f, - "UnexpectedCurrentValidatorsHash : {:?} {:?} {:?} {:?}", - e1, e2, e3, e4 + "UnexpectedCurrentValidatorsHash : {:?} {:?} {:?} {:?} trusted_epoch={}", + e1, e2, e3, e4, e5 ) } Error::UnexpectedSourceInGrandChild(e1, e2, e3, e4) => { @@ -361,11 +391,11 @@ impl core::fmt::Display for Error { Error::UnexpectedExtraDataLength(e1) => { write!(f, "UnexpectedExtraDataLength: {}", e1) } - Error::UnexpectedUntrustedValidatorsHashInEpoch(e1, e2, e3, e4) => { + Error::UnexpectedUntrustedValidatorsHashInEpoch(e1, e2, e3, e4, e5) => { write!( f, - "UnexpectedUntrustedValidatorsHashInEpoch : {:?} {:?} {:?} {:?}", - e1, e2, e3, e4 + "UnexpectedUntrustedValidatorsHashInEpoch : {:?} {:?} {:?} {:?} trusted_epoch={}", + e1, e2, e3, e4, e5 ) } Error::UnexpectedCurrentValidatorsHashInEpoch(e1, e2, e3, e4) => { @@ -396,6 +426,86 @@ impl core::fmt::Display for Error { Error::UnexpectedHeaderRLP(e1) => { write!(f, "UnexpectedHeaderRLP : {}", e1) } + Error::MissingForkSpec(e1, e2) => { + write!(f, "MissingForkSpec : {} {}", e1, e2) + } + Error::UnexpectedHeaderItemCount(e1, e2, e3) => { + write!(f, "UnexpectedHeaderItemCount : {} {} {}", e1, e2, e3) + } + Error::MissingTimestampOrHeightInForkSpec => { + write!(f, "MissingTimestampOrHeightInForkSpec") + } + Error::UnexpectedForkSpecTimestampOrder(e1, e2) => { + write!(f, "UnexpectedForkSpecTimestampOrder : {} {}", e1, e2) + } + Error::UnexpectedForkSpecHeightOrder(e1, e2) => { + write!(f, "UnexpectedForkSpecHeightOrder : {} {}", e1, e2) + } + Error::EmptyForkSpec => { + write!(f, "EmptyForkSpec") + } + Error::UnsupportedMinimumTimestampForkSpec(e1) => { + write!(f, "UnsupportedMinimumTimestampForkSpec : {}", e1) + } + Error::UnsupportedMinimumHeightForkSpec(e1) => { + write!(f, "UnsupportedMinimumHeightForkSpec : {}", e1) + } + Error::VerifyAccountError(e1) => { + write!(f, "VerifyAccountError : {}", e1) + } + Error::MissingForkSpecByHeight(e1) => { + write!(f, "MissingForkSpecByHeight : {}", e1) + } + Error::MissingForkHeightIntPreviousEpochCalculation(e1, e2) => { + write!( + f, + "MissingForkHeightIntPreviousEpochCalculation : {} {:?}", + e1, e2 + ) + } + Error::MissingForkHeightInBoundaryCalculation(e1) => { + write!(f, "MissingForkHeightInBoundaryCalculation : {:?}", e1) + } + Error::MissingBoundaryEpochs(e1) => { + write!(f, "MissingBoundaryEpochs : {}", e1) + } + Error::MissingPreviousForkSpec(e1) => { + write!(f, "MissingPreviousForkSpec : {:?}", e1) + } + Error::UnexpectedCurrentEpochInCalculatingNextEpoch(e1, e2, e3) => { + write!( + f, + "UnexpectedCurrentEpochInCalculatingNextEpoch : {} {} {}", + e1, e2, e3 + ) + } + Error::UnexpectedMissingForkSpecInCurrentEpochCalculation(e1, e2) => { + write!( + f, + "UnexpectedMissingForkSpecInCurrentEpochCalculation : {} {:?} ", + e1, e2 + ) + } + Error::UnexpectedMissingForkSpecInPreviousEpochCalculation(e1, e2) => { + write!( + f, + "UnexpectedMissingForkSpecInPreviousEpochCalculation : {} {:?} ", + e1, e2 + ) + } + Error::UnexpectedPreviousEpochInCalculatingNextEpoch(e1, e2, e3) => { + write!( + f, + "UnexpectedPreviousEpochInCalculatingNextEpoch : {} {} {} ", + e1, e2, e3, + ) + } + Error::MissingEpochInfo(e1) => { + write!(f, "MissingEpochInfo : {} ", e1) + } + Error::UnexpectedEpochInfo(e1, e2) => { + write!(f, "UnexpectedEpochInfo : {} {}", e1, e2) + } } } } @@ -453,7 +563,7 @@ impl core::fmt::Display for ClientError { ), ClientError::UpdateClient{cause, client_id, message} => write!( f, - "CreateClient: cause={}\nclient_id={:?}\nmessage={:?}", + "UpdateClient: cause={}\nclient_id={:?}\nmessage={:?}", cause, client_id, message ), ClientError::VerifyMembership { diff --git a/light-client/src/fixture/localnet.rs b/light-client/src/fixture/localnet.rs index 9ba16647..98cf34e7 100644 --- a/light-client/src/fixture/localnet.rs +++ b/light-client/src/fixture/localnet.rs @@ -1,9 +1,8 @@ use hex_literal::hex; -use std::prelude::rust_2015::Vec; - use crate::header::eth_header::ETHHeader; use crate::header::eth_headers::ETHHeaders; +use std::prelude::rust_2015::Vec; use crate::fixture::{decode_header, Network, UpdateClientEpochInput, UpdateClientNonEpochInput}; use crate::misc::{Address, ChainId}; @@ -16,29 +15,29 @@ impl Network for Localnet { } fn ibc_store_address(&self) -> Address { - hex!("2F5703804E29F4252FA9405B8D357220d11b3bd9") + hex!("aa43d337145E8930d01cb4E60Abf6595C692921E") } fn previous_epoch_header(&self) -> ETHHeader { - // height 200 - decode_header(hex!("f90391a0844dee9abff97d261ae0049fe38246ac10aba49f2b8618f28f7c2d19e62eccf9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0ecf1aa30fa754576ac4abc3cf2a61d1babd41c7e5515855efd857b2d3f37866ba00f0ea7d212c4aaca329b03f5e9ed9c69d3641eb5e03a4edb69b61e6f9d8d51efa0c3372a1f332fc4245e1a9fdcb62580fc6dae741087a8029560f19216dd3d58b9b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000281c88402625a00826c7484669a6a91b90173d98301040b846765746889676f312e32312e3132856c696e7578000020155b72048fdaaa7e6631e438625ca25c857a3727ea28e565b94a73be71b4a5703b4d0b36e4f65d52615b668b385efc047f7f385ace378981fa3750a0bc16ca6f8217be599bcfa274b2e42bc54d19116d2348ac83461e2e0915d508ad921ebe99c27c8fdbd30aecdbe86f95aee2e06995f83ebeb327924669629f193ffd3257315c79ed5a4867ec53b502b5e6d9a13701eafb76870cb220843b8c6476824bfa158c66a3f3d2fba1d440da8edc79b59ed9a3a43db62bd7659f7d4e25073f9241dba560600b23e26c30d48ea0395eeeb4ede04db2de85453e0936b441c339a26d10cfa71b50a50dd5edefbafd33740101d074b6d58b56a787a7644ddfff77d0c00f9e62cc58c931e671afc564f3f6e255cc6fc8a567015cbc63c3d778cef5e8dbfdaf1fd8f758a764f2667aad2d3775954e4ac23e726226b66f0a94631bd0b6d937b22955d73eed65a31a6f535662f51cc7547143f6f201a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080").to_vec()) + // height 500 + decode_header(hex!("f90482a05e0415a04370b022b7a003e86fdd29e13e8781435867230cc6e5ff45e1924cbea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0bae6330554017c1046039ecbd12d5e62956bf2af0bc371415b4778d5b33a085fa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201f48402625a00808467d7b8bbb90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926901f8ae0fb860a7c69dd2e73ffb364f69c37bded01a0b6a4ed65dbc6d8f86bf4e96f1372273d6b91e7e4e74976067acf10aab91ce53c508376fbd5d29c3a9387b6ffca3d190a8e375d1c3bf55cb104738c99bc8882afb20b8dc6b3c02a7d9c40fa0ed02937ad6f8488201f2a0074b91607b4a91e13eef4df4ad575ec25da52100a0d56a481803dd41143c90838201f3a05e0415a04370b022b7a003e86fdd29e13e8781435867230cc6e5ff45e1924cbe8031443f1f703eae6925ce1036aa58458d8d7673ef4d0f40a7ea18a0ef91f1a07c62ffe6be3e7db067ec696db0d9e6be5c50ffe4482f05b79f9c55a7b4ca5d58ca01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec()) } fn epoch_header_rlp(&self) -> Vec { - // height 400 - hex!("f90442a04ec3c90370deeeab62de72108470bccac75d1abe118a778f01afa7a99c976a5da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa0015ebe4a5d6cd56f0bf97db1d21746f59ab5cbecf216e34753920d815403ada2a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201908402625a008229a884669a6ce9b90223d98301040b846765746889676f312e32312e3132856c696e7578000020155b72048fdaaa7e6631e438625ca25c857a3727ea28e565b94a73be71b4a5703b4d0b36e4f65d52615b668b385efc047f7f385ace378981fa3750a0bc16ca6f8217be599bcfa274a7876ea32e7a748c697d01345145485561305b248cd0ede772633b8baea9958f9b602db36d78934d948244a13c2d66e998f987783276e9aee6facbff50b0d63574406b51b2e42bc54d19116d2348ac83461e2e0915d508ad921ebe99c27c8fdbd30aecdbe86f95aee2e06995f83ebeb327924669629f193ffd3257315c79ed5a4867ec53b502b5e6e04db2de85453e0936b441c339a26d10cfa71b50a50dd5edefbafd33740101d074b6d58b56a787a7644ddfff77d0c00f9e62cc58c931e671afc564f3f6e255cc6fc8a56701f8ae0fb8608b6dc552b410a6fa44fa31643850bcb314f1d4edb32c0c79ee3efef5397691f3685d80057d77510a00e77a39e8b2497419053c3b81a8901e85590a20a0a2dad529c82f6c175ec3ebca8a9112415aa94718af673c16c0e90e327e27709666e499f84882018ea0709f88597f05218c198818991cf5598c9280db30d5bfe899da9b7a8c963bff6c82018fa04ec3c90370deeeab62de72108470bccac75d1abe118a778f01afa7a99c976a5d8012518315e9c22a4a648f4d26efcf57f877a26498de6d53fe7a267e8d5ef01482009817fc9de90ca8008ef1f420aa606ddc0c56a975bace3906601fd5cde657d600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080").to_vec() + // height 1000 + hex!("f90484a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a04c35879f76cd366249e5810ce3ff0a4be2f4e1a995e004fa207bcbece6b43bf2a0e0781acd204a300b1a607656df80d8a3ab2684fb6fa9e83d4087aa9e9157330ca03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e88402625a008229a88467d7bba9b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926906f8ae0fb86099f5bd42d7a4e11f283b9daa22fe1f7ae89e5260b61722ec3f57dc2b18a669e0040e42a6f81d114732c00609d4648b0d0fec3a07fb300cf49a7cf6116abb217b13a63ee6330663349e8a316c42dc04f16131445a331365d2b32bcb4d5b546c25f8488203e6a0302d35ff53c930401473e5650e8169f18f1156d0127cd1bd1a3e65fe365c5efc8203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a80a240096b876248068d454519a30d241182b95497f8a66d6d179495e9fd6d9427096f4c35eb87299f195d8fd4731d162a2c8ab445dd0ea56989288b2825c640c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec() } fn epoch_header_plus_1_rlp(&self) -> Vec { - hex!("f9032ea0e256fac4dd62cc71eaefd8d6c24ae5209c0e48f5c0b62bcced06dfa838c2ad31a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201918402625a008084669a6cecb90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb8609338bf42b6ef715e9c887e1b285e706355c2a993cd227497b447f8aad4b7fa44d18cd895862e1a2b961b78656d620f9c015e777cf9bcb6c50e1db2783818bd91f647f6879f8bd199f266f1166f9241f00f955fb5210e7e89e7678680900d1cc1f84882018fa04ec3c90370deeeab62de72108470bccac75d1abe118a778f01afa7a99c976a5d820190a0e256fac4dd62cc71eaefd8d6c24ae5209c0e48f5c0b62bcced06dfa838c2ad3180d6c559fceda3795918a2fdd34cb4f77608c8095b67091aadcef5d5c4efe09fc0477a1977c0037f19244240648637c3c5ec9fe22f1db4899a022575bec96cfccf01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080").to_vec() + hex!("f90370a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04ff32807d3701bcff50e1213fdce58ce988fb64c9e1cc269874a3d970ef7d1e8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e98402625a00808467d7bbaab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860a51854c31fb60a02ba70c07eeb467be677b9548c828607f99dfd0edc80a9b25be05670b86485dd71d8fb8e19d7458a9103d942ea6b84070ed47adcd3a3f284385fc538a5f692289c3abc25372e461a54ef23100718aedf80224a1e4fe26671d3f8488203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a8203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c80313317225cc094c83c097e6a830295a3e3a6df48baadc709927d7d2bc643d9ef4d474ff4442565ef2c0bf90644095ee4d3a9934650d1b989f9d82ba9d664e57100a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec() } fn epoch_header_plus_2(&self) -> ETHHeader { - decode_header(hex!("f9032ea0669cf9fc3b3d480d7a8de1cc051e1d95fa24be8870aa93bb5bfc03f1d592db46a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201928402625a008084669a6cefb90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb8608d465cf004274c6caaddd041116c93f12cba458536d23efc6148134af357a685c7b84b1d3de59eb61b2756e7b99a99de00a6158245e16d23dd10602ef719836ce41862c567745727a145df4bde737415e8ffbec5056d4653b02fe1ddc8f21069f848820190a0e256fac4dd62cc71eaefd8d6c24ae5209c0e48f5c0b62bcced06dfa838c2ad31820191a0669cf9fc3b3d480d7a8de1cc051e1d95fa24be8870aa93bb5bfc03f1d592db468083bec325b33996ad2fc35e146d7e8fd215177b1423378d3b07cb73293d5384733488a981b64ae03cbcf44af281cfbd57431addbd8432042c49fb4c78d5573f0d01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080").to_vec()) + decode_header(hex!("f90370a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a08c694a1f89eafbe7d2a2e08e4e64f855159fe234cb26637edf6a166429d4f338a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ea8402625a00808467d7bbacb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86094e9755690770485712c5b0f060b43d2bd542c3712146d8542053d4f42d05bf253ed5ee05efb85862f2faf4b6c25279e1735110b78af88000b4c90462ff318fc195be0b1a7a0d4e41943ec288aafab6eb3c5ebc31dd2a0ce428cceebf20553aef8488203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c8203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8020c2f74f57683c3ca4405ad21e3fdf74c30624571bbcf7b88cf27d4b12631ac9069c6fa8ff35fac1662e9bc89dc040cec541fd36aee8c8058c299bafc0ed5d1700a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec()) } fn epoch_header_plus_3(&self) -> ETHHeader { - decode_header(hex!("f9032ea0705444384ac2acf605c4ca8353e5070f37cc0976597dfdfc74413e278725eee7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201938402625a008084669a6cf2b90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb860a6e88879bc7f8ff4ee90ba0776b414b97ffcb0a2bc4f9484075ea121e00b7ce27e21c0fbf76f34746b232e76a37cfc220011efbd7863237e75eb2830748736e9092847a283401bf6793e94d00619764884d012609cf5bace403e93b66f60c3bcf848820191a0669cf9fc3b3d480d7a8de1cc051e1d95fa24be8870aa93bb5bfc03f1d592db46820192a0705444384ac2acf605c4ca8353e5070f37cc0976597dfdfc74413e278725eee780f5171f7fc98ba3118543b55677128c397b07085a29dcd71c989c7f0eb602308342cf64470f85ebe31ebdda4244e7992b82ff2026ac461d0f2997332ccb99255201a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080").to_vec()) + decode_header(hex!("f90370a04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd24a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0167484b0a23d96c53238b8e02465ce28353b86bde23a4c76079c206ef68c9646a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203eb8402625a00808467d7bbadb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860acaa8373b727de717178de93621351e285bc9803b59af041bcf6125421adb461838a18c251c2fe3e747b4081010e429411a750ddc02871238102ac2df09bcb6085b48d9061f23dda19b5084c1b6b8cbdf816f29643413a0b616ba24a3b00145bf8488203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd24805444abf4fc554f34fd1f7e8e768ffa50740d4cbe373175fa115bc3b674d4d2322496a207e5d5bf5224071a161d9194db4b9c4e628e3214c3f4c35bf194998b0c00a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec()) } fn headers_before_checkpoint(&self) -> ETHHeaders { @@ -51,100 +50,93 @@ impl Network for Localnet { } fn headers_across_checkpoint(&self) -> ETHHeaders { - let h404 = decode_header(hex!("f9032ea096cb50332bbf713e73255ff60f9bd09d8fd1c6aaa77e238877391578648ef27ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201948402625a008084669a6cf5b90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb8609172e0bc45c783421222512ab2f9dd881f7416db9f0577699ee5fdd35c43655df184674ff0567f9a3e014778305f93c902b1d5c7389c8ef5733fcf458d6fa8fb7db16b0355fa5fa20d707d7e6d481ed52d59dc4da52a483100742e3b5a720b21f848820192a0705444384ac2acf605c4ca8353e5070f37cc0976597dfdfc74413e278725eee7820193a096cb50332bbf713e73255ff60f9bd09d8fd1c6aaa77e238877391578648ef27e8007b6d31837799df1d74bc66a1b12b5e4c485adac4b869b2b87160800c65418e3061d0ccf55b52c0ab7a50832c51f8d5d74aa2de7c481b9f87e83d9a73334009301a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080").to_vec()); - vec![self.epoch_header_plus_2(), self.epoch_header_plus_3(), h404].into() + let checkpoint_plus_1 = decode_header(hex!("f90370a06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a06d13a0cc728f1d2c3dbf74e1e3ec93bf5f5e05419259290c6af477dfec4c5946a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ec8402625a00808467d7bbafb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86098cf37a5fdc36301d6d4ccf22f89c1403a577f4c5e25f3fd795f80ef9de4ae2c5ae1f7b7e4e8ba75334c2ffa0e6b1c0f002bfc3e46e11b2491fa85da11b3abd89e58934c0cf1f889e2a833ca25635a3c9dc4cdf322949c20cd2ea016cd29209ef8488203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd248203eba06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28b80e539311c1e5557ee877b0fa621406d29858639e72427f363a562402cbc7b8e21573b84267a99bba57e0924b2536c9d42ec2cb1b8fee98cb9ce7b5418b887495900a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec()); + vec![ + self.epoch_header_plus_2(), + self.epoch_header_plus_3(), + checkpoint_plus_1, + ] + .into() } fn headers_after_checkpoint(&self) -> ETHHeaders { - let h404 = decode_header(hex!("f9032ea096cb50332bbf713e73255ff60f9bd09d8fd1c6aaa77e238877391578648ef27ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201948402625a008084669a6cf5b90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb8609172e0bc45c783421222512ab2f9dd881f7416db9f0577699ee5fdd35c43655df184674ff0567f9a3e014778305f93c902b1d5c7389c8ef5733fcf458d6fa8fb7db16b0355fa5fa20d707d7e6d481ed52d59dc4da52a483100742e3b5a720b21f848820192a0705444384ac2acf605c4ca8353e5070f37cc0976597dfdfc74413e278725eee7820193a096cb50332bbf713e73255ff60f9bd09d8fd1c6aaa77e238877391578648ef27e8007b6d31837799df1d74bc66a1b12b5e4c485adac4b869b2b87160800c65418e3061d0ccf55b52c0ab7a50832c51f8d5d74aa2de7c481b9f87e83d9a73334009301a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080").to_vec()); - let h405 = decode_header(hex!("f9032ea03a48eae03d25e5b740a93befd16e8e4f9926727075d0a986c3448e69aa8acc62a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201958402625a008084669a6cf8b90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb860aa33cabb6ecd6b5fd88cd0cf67fb9b7e9a87cd46699f6dc1c065a309494bcba543371190cd53d3f614f78e08bebd98360f8463999bc2a14ff20c1a771755745340e5728a58f48ff14530ab2616f5e020022ef47393fd041024c258faed646498f848820193a096cb50332bbf713e73255ff60f9bd09d8fd1c6aaa77e238877391578648ef27e820194a03a48eae03d25e5b740a93befd16e8e4f9926727075d0a986c3448e69aa8acc6280f8561d89c6a41e9eb05325d0c1087dc6f13efd20c591a4c4fa774a27156c2a30388b570eeac528d7521832243a8164043366dd1e94e030d966473462d7c5605a01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080").to_vec()); - vec![self.epoch_header_plus_3(), h404, h405].into() + let checkpoint_plus_1 = decode_header(hex!("f90370a06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a06d13a0cc728f1d2c3dbf74e1e3ec93bf5f5e05419259290c6af477dfec4c5946a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ec8402625a00808467d7bbafb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86098cf37a5fdc36301d6d4ccf22f89c1403a577f4c5e25f3fd795f80ef9de4ae2c5ae1f7b7e4e8ba75334c2ffa0e6b1c0f002bfc3e46e11b2491fa85da11b3abd89e58934c0cf1f889e2a833ca25635a3c9dc4cdf322949c20cd2ea016cd29209ef8488203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd248203eba06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28b80e539311c1e5557ee877b0fa621406d29858639e72427f363a562402cbc7b8e21573b84267a99bba57e0924b2536c9d42ec2cb1b8fee98cb9ce7b5418b887495900a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec()); + let checkpoint_plus_2 = decode_header(hex!("f90370a0ad2e1c5034a4cbbe79457ddf448057510e268fddb10e99daf81564b86414773aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a097d5fe33ae946428c4be77c59ae8a545705646ef31fe8b2a54c5b7134f798169a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ed8402625a00808467d7bbb0b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860b547590857fa914223f8af00a02c80c179f90d31ef69e7bf6e2d9a222fe9acdc518136b552ddac94f85fefe2ad5eb0e306a2c90b0506d274bf8853909a0503d360fe5f1e8271bed925d2e57870ab03799dec8d79d183df90775d7e4d9b62a5d2f8488203eba06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28b8203eca0ad2e1c5034a4cbbe79457ddf448057510e268fddb10e99daf81564b86414773a8091195aca7d09fd725ab73adab646c3f2eec45cbc8d77d36b15bd67bfbaa2f8112f9800f6361f91bac66e2b0d359eeefab41cf3cdfe1a547bf77655e93ca8810101a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec()); + vec![ + self.epoch_header_plus_3(), + checkpoint_plus_1, + checkpoint_plus_2, + ] + .into() } fn success_update_client_non_epoch_input(&self) -> UpdateClientNonEpochInput { UpdateClientNonEpochInput { - header: hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212de1b0ab4060ab106f9032ea04788023231ff806fc9c20db23fce4c06c3b70d9038168334ec3e2095840ce534a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a044a1ff3b091f2f544a4d42c0772da7a8c26265f177d0472730efa0719c157d35a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201f68402625a00808466992e3bb90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860a5847b013e471a925b8122c9c748725825aef5d215d1ccee2b83af041eba4cf9ee211aed07fdeac7b4c2f7b85070208505e6849508cb950b2678fd27d40fb8e8a8656c050dd44f6ec33c226f108d15c6cab19080cfffbea81cdc7b1a09bc0463f8488201f4a0b4dfd14d8766b8fa4e64335fbcb53e56699c8948cb032d0bb628fc166a9321318201f5a04788023231ff806fc9c20db23fce4c06c3b70d9038168334ec3e2095840ce53480462103279b25cbd0540468881b0b90266b9ade0a60d6a93bba8a7ae4aff1d15477df78046011f78aeebf21fe63204b5e2b9b1aa8c7e26234482902addbb62a4001a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea0b1270c4b2a24c6bce1d07ec610c294d4b729b0c9c02d585e33018420bd6d8f5aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a044a1ff3b091f2f544a4d42c0772da7a8c26265f177d0472730efa0719c157d35a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201f78402625a00808466992e3eb90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b86099624ac24cb33ea9d08bbc36916d4850fabbeea8f97d320a0493c574e4ec19f443070972f6c1737e0ca5269bdb11f16507096f009f7c1298d1ea37e22d2c0565cd5ae718284f80f5704228d6bc4d36ea63d7cd9a6077b15bf8e0c973c0b54f98f8488201f5a04788023231ff806fc9c20db23fce4c06c3b70d9038168334ec3e2095840ce5348201f6a0b1270c4b2a24c6bce1d07ec610c294d4b729b0c9c02d585e33018420bd6d8f5a80f3a3f4f618fa7a483fcc7f00b52e43e90085d5371c62a34f9a7150ad13921d805762782747f63307bee2a73980fc19c19af853800c7805fec26a3e405ea2b77500a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea0be1699ee1c35954f180299bc9579d59ff6d57e5205cdc35c570d83d9e647d6d1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a044a1ff3b091f2f544a4d42c0772da7a8c26265f177d0472730efa0719c157d35a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201f88402625a00808466992e41b90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860af4473d99c25cbf6cce8b3b305ec3dbccff96d7c6007f123dbbcbda8286428a69da7f9145ced0f2275b11daf1b7ad1e514938274bc4f960d25026f23c2f2f8a5d8cd3d32d87b4c66062988a657dbb5cd625bb256f328e8a4a81d92f0a2389fd1f8488201f6a0b1270c4b2a24c6bce1d07ec610c294d4b729b0c9c02d585e33018420bd6d8f5a8201f7a0be1699ee1c35954f180299bc9579d59ff6d57e5205cdc35c570d83d9e647d6d18083abf2596f14299f17a96f652981b52bb794315aee435f3e277a031b4955f4866c5179198606ef2c2f691d3352d1d6daaf2a995e75212fb413f520604e7e412001a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080120310f5031a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea02da84052a06a138dc625b9f6b0020fa250e7b1862a9ff3db6516a7e32ff33698a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a0c4514d3d96fbd80ddd21b28182a517e555c417cd7683f805860098cd28a49a4380a0a74e307420bf9966d5db9a83ce48edc32c7a8e43328c6373de6875cefa04ad7aa056f4d573349c475d8d0dd015ee77c80ccc34d5742c2a7f2c266480b61f24a050a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0d4182165b298d7b52b0f2064d19ab8bdad2b3955fa5b3d85c00673beb97e124480f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a03f47312ca98ac1f6ae9db9752c2a33529723b64e654d87f7847cee0382edfb55a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512f2244d9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab992a44a7876ea32e7a748c697d01345145485561305b24903201f874819815e1a3f183c4addc814b71ec0e573e07f79ee9082926d82dd1711d6c45a9cc8841916d8563c2f80baa2a44d9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab9930013801").to_vec(), - trusted_height: 501, - trusted_current_validators_hash: hex!("92f25eb8500cae7c8548a61c6a03f4fc99690589b472b55e4c8ce25d0ce0f4d5"), - trusted_previous_validators_hash: hex!("5b514a7e8083146842c425a71aec83368ef4628442999a6d340d623ffb360c67"), - expected_storage_root: hex!("e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9") + header: hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212a4190af6060af306f90370a0630369520fa89700c2a3cbd2c6a49ce28e12c0582fae0e5892467d59ecdb9442a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0013b50447062263409b25586a7c0e2fa49bba4357c01d48caed402c0badddca3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282072c8402625a00808467d7c08fb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86099017aac5e8a295871b47614d78ea770a16462e8d7f1a35ca1787dc4a25eb21ea6c8f3c6efc726d6cb516e6bd1ab0fa10c4b7598cd5121973de41d2a1c0196f7bd442a9973e2d07d5105de750257847079a218af5595d150b40352b5cdcad173f84882072aa0c53a98ca6da5d9922f30a3af6fee23414fb633745fe866b78f61710b1ecd2f9782072ba0630369520fa89700c2a3cbd2c6a49ce28e12c0582fae0e5892467d59ecdb9442805d1c50096a51fbb3ea1a41536bbd1961c0bac25ef3a3fc624486b13bf6ba80b511e810f1c62b5638d449e116263b22903468b63d87549657fdac35cd49cd374200a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a09551e2927b3ee96206c6665dc987c92054842e2ab76270314b2c941b54c907f8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a016174282240ea081c186475fcb31841b3f43d0b47ae9d5cf24efeec517b514f0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282072d8402625a00808467d7c090b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860b813aaf35c2d21fcffdcaff25ecaed489a1c7949d16ed9f93ceb321d75c1264d34a6d4b306173cdc828a145f2b661fa30d8749615796e7c508b9fc5767eed847aa44793fcadf0b68016557ab885d45e928c49b8e6226be1150631f79cdfa1534f84882072ba0630369520fa89700c2a3cbd2c6a49ce28e12c0582fae0e5892467d59ecdb944282072ca09551e2927b3ee96206c6665dc987c92054842e2ab76270314b2c941b54c907f880705c080f39e4d03b4ac363a112216a404a6fcb01059350b7be810925078d831b131db2c6b739b4bbf21b800cce45327329628c25c757751367a229ab4bffde3401a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0294e78344d1eb6f24577bf449737275aac58aaf4960a4241ac0576e3499605a6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04d88b7fcbac04e723c32e90d4c981e425ae9a37f3340ac80896ccfc76acd7a84a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282072e8402625a00808467d7c092b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860ad530f84ab9d1aba997ff2dfee86cc8c1a911ccf3aaaec0221f3fe91db8737175de8c2b845b8d4546f323c8062c7efa119f57b105741468d99fbd83a606cebe16325bc732e3cbd8f628645b8dabba9bdafed811cbae32176ebb37e6dc63b45d6f84882072ca09551e2927b3ee96206c6665dc987c92054842e2ab76270314b2c941b54c907f882072da0294e78344d1eb6f24577bf449737275aac58aaf4960a4241ac0576e3499605a6809eb3ea3bb7a0bb30868e30e51129123c47813963e0140cfb0deaaaaeb0aeb69c0a18b1e57b15e26e42b734da16a8e489d400f5eeb5902b319557f9c44e0f120901a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310ab0e1a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006").to_vec(), + trusted_height: 1835, + trusted_current_validators_hash: hex!("9996aee43ef62a1232e6159ffd71f92238c710a4f4e588530418a23a8532a2b8"), + trusted_previous_validators_hash: hex!("dde714db60662eec8ebd26f0ed43b77d164961c2613f2a0e5bde3be50aa4ca4d"), } } fn success_update_client_epoch_input(&self) -> UpdateClientEpochInput { UpdateClientEpochInput { - header: hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ea1c0ac0070abd07f903baa0163d00e3a755c1dfba94d3a87b82ae4fbd31ac3400233606ab0c6084552ea907a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0b0bb21f48df0039e57c69d0157fe2346579dcfd4686d4c460f1e6b0a21a9c65aa028255bd26759d78c76dfc514a6c56ba3ca09b796f8b4ed29746cd5d1708e6392a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208988402625a008229a8846699a2e2b9019bd98301040b846765746889676f312e32312e3132856c696e75780000ffcc693e028fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512fd9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab9901f8ae03b8608c09a24f288f99a33d8f460676c20755d1ae4882aae146f8a7b70686f9da8fa483f9936492cec930d2e12e9dbde55d2b159e8489494b25033af825a7e9de9098e113314cbfb7e9116894e7acbe2d9997725c1dadfa1c87797f31adfe029e1268f848820896a0e94953cae18522809f395677c9d50f385c164df2bd08c6785ef73caabaab1ea6820897a0163d00e3a755c1dfba94d3a87b82ae4fbd31ac3400233606ab0c6084552ea907807a36b8b2b13a4f21512e1a4f47e9886adf4ede9107c86e34fe91c7001d5a60743af22d47507720ff67c07936b318094bbb033acc97c25c2fd996823556b3702401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea0159bd78c921d172005fa4812b7bd17818128531fcc94d79d4c5dc2eac89e8d24a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0b0bb21f48df0039e57c69d0157fe2346579dcfd4686d4c460f1e6b0a21a9c65aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208998402625a0080846699a2e5b90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b8608a925326ca08415ac1c64130b3686da771563220c5f8e9086ba2d7f3988e3e1a99e5e92d741c4ae6ed8d670fdd0dd2f91852b62894209617212d0adc83c678281b07ad1a61bc219daae50352b47a040e4b863295eec93a0ffe1039f9430fd552f848820897a0163d00e3a755c1dfba94d3a87b82ae4fbd31ac3400233606ab0c6084552ea907820898a0159bd78c921d172005fa4812b7bd17818128531fcc94d79d4c5dc2eac89e8d24808d29c8af8a9703ddae74256526b88cc9e23453db7b802efbb5e13879a0a9ba1a39431d64b66992d3d95bddfdb5d810038e423e2b63a513dd1d56d860d06af67f01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800ab4060ab106f9032ea019f886a89182b225d6d5f9fde2585225c7345a0dfec2d696d2883b2d457efff9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0b0bb21f48df0039e57c69d0157fe2346579dcfd4686d4c460f1e6b0a21a9c65aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282089a8402625a0080846699a2e8b90111d98301040b846765746889676f312e32312e3132856c696e75780000ffcc693ef8ae03b860823f591b2f21bfbbc4ffed752a4763e48f998303580842aba1dbefc47e5559cc9888c41b4821a5f1708671de14c9025c031ec1bc30f62f07ab90fc8579556af7827de63e06d63945b1f134f8b7a1f59e7ece7fb08a902d137a19f0aa31757e71f848820898a0159bd78c921d172005fa4812b7bd17818128531fcc94d79d4c5dc2eac89e8d24820899a019f886a89182b225d6d5f9fde2585225c7345a0dfec2d696d2883b2d457efff9802dc6bbe4016c470f6013d0862e7f72c88166d10968d27eb42dc0857718c3393a3b925acd3352a6581b027a59999b83aad3008317c6f6b0b6fc0e448a4b0b5cbb00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421808012031097111a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0e7dfe8f84f2275550989049850d05064cc8b01fb231136d5a5d4c93d3a35e207a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a05bd37b72fde8c8da4861cd3d3af70e498c5d49dd4d929f608ab3a34693fb394580a0a74e307420bf9966d5db9a83ce48edc32c7a8e43328c6373de6875cefa04ad7aa0a1be3efcd793a73f9c65da939fd72689098a7407794678fc846a0724d1bcd76ca00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0d4182165b298d7b52b0f2064d19ab8bdad2b3955fa5b3d85c00673beb97e124480f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a03f47312ca98ac1f6ae9db9752c2a33529723b64e654d87f7847cee0382edfb55a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e56593428ee663799df81ea82bc8445a7d93c891ef324b5f4438eb766bcf75fc405fb79d3f618fcdd17f107b374368ef512f2244d9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab992a44a7876ea32e7a748c697d01345145485561305b24903201f874819815e1a3f183c4addc814b71ec0e573e07f79ee9082926d82dd1711d6c45a9cc8841916d8563c2f80baa2a44d9a13701eafb76870cb220843b8c6476824bfa15a82968379b116362f75bdb7cc4be8ca0ceea7c0f2e74be7c8f289cda6dcbc5edbb26400e1306c2de06f52a9a583dab9930013801").to_vec(), - trusted_height: 2199, - trusted_current_validators_hash: hex!("5b514a7e8083146842c425a71aec83368ef4628442999a6d340d623ffb360c67"), - trusted_previous_validators_hash: hex!("399334b2051da932262b42f25e5e59724c08df5c88d13c9d6bf5c51c33233aab"), - new_current_validators_hash: hex!("92f25eb8500cae7c8548a61c6a03f4fc99690589b472b55e4c8ce25d0ce0f4d5"), - new_previous_validators_hash: hex!("5b514a7e8083146842c425a71aec83368ef4628442999a6d340d623ffb360c67"), - expected_storage_root: hex!("e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9") + header: hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b61b0a88090a8509f90482a09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a769a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0a4ef99b2f92fcf112f19fc275bcae30fc1a37b61070d1c05e7d8e46b8e808f42a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dc8402625a00808467d7be97b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926908f8ae0fb860abd36729a99a7a3e957e01525874db2cf2e4f35a9e1800ab422fe0cf03babfcbfee210ce61808e31c906c1a28301103b14eb7094777ee60d7373fb13be17ddeb1eb79930a6212f10947fed157b1acb4612e51c13ccebfe688f1819809112cd10f8488205daa03ca8f28ad9e7b92ba1e308f93ec7af270c2742d911d01812739a48e4ed98beb08205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a76980b62e41161cf2b31ac78ac9c93625f74601bffee172c3beb72ac0085d6f5f5a771005d058923a2babd7bac693258b3fee81aa36b027028923fbae2fb2a5a781c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a075dbbe77d365565f739f0f9725ed1fb83ae08d31bdfcbe83844341f8b6ebec76a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dd8402625a00808467d7be98b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb8609820e8c6b0271e4692c24207bf2f48a17c5c9f358169162ceddae29889de416d01812d65e7697f12856ef19d6bc83d4b137ce93bd937bfe2cbef141bd50c5849d3e07a25518cc7b4fb310e509c99efbb74f44d91f1749f21623c4002f3a849e5f8488205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a7698205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8092908f87a47fd452b13a53d775fa2fd4ac267318c50dd72103d81a499f1b4171324513520f29a6c0e13515cd2e92e15338e84a7cf53f5061d10acdf1293349d301a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0f3550e781e783369df120040a4abf7bd9dd5f8f39f0f8544fdffdedf43531c87a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205de8402625a00808467d7be9ab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86082a95e5c91809809e030a6846650011a287162783c98bf7bb389118d1c0990de451e74e88dc4abf9fef0d86680352ec210c9c26fd418ec0ff16a626980ee41dfb10e4021069e4111392f31abfdcdfecaa4e639508afed5884f3359779b22ff9df8488205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8205dda0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8804896f2df88ff6ff7e2f5284c2f5a98c94460c28a9adb701dfe388af57498c42d7f469cde54341978f0cbcf941e7e09f5a8682f0b016865cd0957aa0e64a933cf00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310db0b1a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006").to_vec(), + trusted_height: 1499, + trusted_current_validators_hash: hex!("dde714db60662eec8ebd26f0ed43b77d164961c2613f2a0e5bde3be50aa4ca4d"), + trusted_previous_validators_hash: hex!("cb71cc9e4b6529c3aa23c4e9f7d3ffba50640e993eb83734bb9a618b0b2e4bd5"), + new_current_validators_hash: hex!("9996aee43ef62a1232e6159ffd71f92238c710a4f4e588530418a23a8532a2b8"), + new_previous_validators_hash: hex!("dde714db60662eec8ebd26f0ed43b77d164961c2613f2a0e5bde3be50aa4ca4d"), } } + fn error_update_client_non_neighboring_epoch_input(&self) -> Vec { - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a0947b3bea434254e61a3cb8db3730b1f72f41387c5cafa6b70e442fb395febf1ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0eb1d5bc6a9a390ac95eb3615129897e262958bf00049496ac246dbffa21cbcf4a0635e768d28c61dab2839060edf8f2eeb96b39f7d83c210292a6d535f8792ef9da03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028206408402625a008229a88466a222f7b90223d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2f04a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b6b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be3d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b3e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc109f8ae0fb860b0c4bfc658efc671dde996a36671539bac5b825b9cbe12605170bea0962f2076ac1fa677363bdf6b402d2bacb97b6cda0c8d4cbf078bcae5f3fa944a3a2c201e646c312dabb42fb511a0cc7f7ccd65ec8acd463451ad7d2966087bac9e49a075f84882063ea0d6eb0fd288eb7e595da1a30d123e291811d08a56481fbe9adea04f213e3ef2a482063fa0947b3bea434254e61a3cb8db3730b1f72f41387c5cafa6b70e442fb395febf1c808f56a07ca2497220c99fe729399e4affdc82b979356fc32312090ae8bab6c1fa7125fcaceeaed814d8b3fba2c7e870ddac117994c046246a19c59bcfbf1ef65901a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0a2d72a8ec56486c9a6f050753741172c6d48a0a9a0ceee3e4bd3bc8211c42919a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0eb1d5bc6a9a390ac95eb3615129897e262958bf00049496ac246dbffa21cbcf4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028206418402625a00808466a222fab90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608efb50f56bef7c6c09e58a679088e25ffc317b2e7adcb8c2395626a2d00d1f0cf14864344d22d5b33ca0610631f834be179f775ec3247a72f1755f4e4f4974dfc6a1f404d6600a7f83186cb1bec99c66b4752e1c34b692ed3eeb3bb745ddf790f84882063fa0947b3bea434254e61a3cb8db3730b1f72f41387c5cafa6b70e442fb395febf1c820640a0a2d72a8ec56486c9a6f050753741172c6d48a0a9a0ceee3e4bd3bc8211c42919809a1200e4dace2a075f92d8467b3f71b68e5293f0f66fa123e349f1484d77bf727211932b96e56cace0fc0e5951b23419ef84d631e19ddde29a1feeb55a09a36300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0cc5f461c78150e7d776c24dfa8254ecd200e32d4125135bf2470eebce1ca142ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0eb1d5bc6a9a390ac95eb3615129897e262958bf00049496ac246dbffa21cbcf4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028206428402625a00808466a222fdb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860afca419465fac47a8f81e12fb48c91d204851ab257108b5822167eed706bc340d6dc934cf637744fbc13953289fbd19f12413b627fcec373ffa2bae301da2794b1067476093941dd20872c626181b3f64677a0686cbc9cbfd26948d363892267f848820640a0a2d72a8ec56486c9a6f050753741172c6d48a0a9a0ceee3e4bd3bc8211c42919820641a0cc5f461c78150e7d776c24dfa8254ecd200e32d4125135bf2470eebce1ca142e809c5c7082946f7344a1a6db2f6cbd2f8e088324661ef121fac78e2d0bf1377ef62902ec5b5daf49f536cad596bd48b79e4a4052f8b86228146805436a26a348b601a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310b0091a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0318b931f2fd109463dc35529a34c309be2f69ec517b3350d35d17d9eb9ed2051a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a09b42d04e00dcd19346ce2f08c108f85727fca76f6dc57e30da5d76ce8f531c9280a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0b3638fba61f44f70d5b5727baaf03c779ab269dff4a5bf83c15266f4b5380cffa00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62244b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32a44e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc130093801").to_vec() + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b61b0a88090a8509f90482a09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a769a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0a4ef99b2f92fcf112f19fc275bcae30fc1a37b61070d1c05e7d8e46b8e808f42a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dc8402625a00808467d7be97b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926908f8ae0fb860abd36729a99a7a3e957e01525874db2cf2e4f35a9e1800ab422fe0cf03babfcbfee210ce61808e31c906c1a28301103b14eb7094777ee60d7373fb13be17ddeb1eb79930a6212f10947fed157b1acb4612e51c13ccebfe688f1819809112cd10f8488205daa03ca8f28ad9e7b92ba1e308f93ec7af270c2742d911d01812739a48e4ed98beb08205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a76980b62e41161cf2b31ac78ac9c93625f74601bffee172c3beb72ac0085d6f5f5a771005d058923a2babd7bac693258b3fee81aa36b027028923fbae2fb2a5a781c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a075dbbe77d365565f739f0f9725ed1fb83ae08d31bdfcbe83844341f8b6ebec76a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dd8402625a00808467d7be98b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb8609820e8c6b0271e4692c24207bf2f48a17c5c9f358169162ceddae29889de416d01812d65e7697f12856ef19d6bc83d4b137ce93bd937bfe2cbef141bd50c5849d3e07a25518cc7b4fb310e509c99efbb74f44d91f1749f21623c4002f3a849e5f8488205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a7698205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8092908f87a47fd452b13a53d775fa2fd4ac267318c50dd72103d81a499f1b4171324513520f29a6c0e13515cd2e92e15338e84a7cf53f5061d10acdf1293349d301a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0f3550e781e783369df120040a4abf7bd9dd5f8f39f0f8544fdffdedf43531c87a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205de8402625a00808467d7be9ab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86082a95e5c91809809e030a6846650011a287162783c98bf7bb389118d1c0990de451e74e88dc4abf9fef0d86680352ec210c9c26fd418ec0ff16a626980ee41dfb10e4021069e4111392f31abfdcdfecaa4e639508afed5884f3359779b22ff9df8488205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8205dda0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8804896f2df88ff6ff7e2f5284c2f5a98c94460c28a9adb701dfe388af57498c42d7f469cde54341978f0cbcf941e7e09f5a8682f0b016865cd0957aa0e64a933cf00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310f4031a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006").to_vec() } fn success_update_client_continuous_input(&self) -> Vec>> { vec![ - // checkpoint 4424 turnLength 8 target 0-4424 - vec![ - //4400 - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafabaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a09f0bb93d54df1fcbfd84d4173496de9cff0f403319bbbaf15791ccde774b73d8a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211308402625a008229a884669fb2e3b90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8048fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6ca7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833309f8ae0fb860834538868d2c79371ead2f10fc7229fd3b3aaf1d7d8607fd7e1d2efba7df1008c105fdab4ad8029f86cfde1e3aa7dd24194fcf07502bb6c281fc3cbc08ad8cb467de57cbfd1bb93fabe72f77ece8f991a2b7a4d7fb301d54547c6cb4b612d06ff84882112ea042dfe9761fb9a677b088a868f237a171d511bea581f643844a1c98267902391882112fa0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafaba80321f35c8454a2691a2efff6894cae6277ea06390978294fe0d10fe03f432fd07440d802ca0858a2d6138230b37d1a9148a3d76fbe8492854e637c9aad7494e3401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211318402625a008084669fb2e6b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b6de9ffe941751cd11463bbd4bde69d3bc2b79868f669f9e2c4c327f036e6d558b013469a91670607dd88d63dc50b95d00719e118a17e5b72418b6ae4bef7aebbcdaa44b79f8c0677ac32c71312d84db44e6e9216bd84fb97c7d0701a4a03431f84882112fa0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafaba821130a09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1f80e5619874ecb4463f8d86981d939ddb4d0eaa151c6080c7067788e06699789d0a415e921b8824e8adc7907e5bbccec9373b22c7fe8a48527e9348aa957871b63300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0e3aa9bc64f82ccd7e70ec415d73263d9da9f3bb44b78bed500033379df9be8aaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211328402625a008084669fb2e9b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb86095a056c77bdeb59da26e665d69e75cc5667cd43df693a55f20f5f248483a3ce10cdd996b29c7fd6ba3f9e31cb4ac089c0b5bc13e77d83f17096d88f280b8d47ffd8b58b66bd760d0ccd4d26e0c2a7bb3ec168a06a815cfbdde9a2e18c32ac74ef848821130a09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1f821131a0e3aa9bc64f82ccd7e70ec415d73263d9da9f3bb44b78bed500033379df9be8aa80c04c6f70fa142c7486f7bed7e29a247f1203d58c7481c9aefef1193e6404112e32486f8d4dc8c7c558ae0b1bf860f6e05d425b7726ba7a4e2dac6e3e3eb83d3d00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310e8201a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea065b83aa9b59125f9b090432f556c6ff947b5708eb11ca5ea26342392860be00aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a01a41c640130c53b3c90b1b5c691ed467218cee97aade5aac9306e72865851e27a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330093808").to_vec(), - //4424 - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa07e83f283edaaa3f96ed0ea6eff394a8f33426be9f40cdf92ee1244c34773d578a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211488402625a008084669fb32bb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b6ed50c4b59a9e54e8e082fa735665d629f10488d2138f1e454b765ea16eca7571dbd7826e2b570b2905594f899fa2561977420047c4d053343146ed88df4ff667b9aa59679c3285dcccfa809647eb8ed2164b50f8e576fdc8f088cba74b6e98f848821146a08597c8d93294088beb70b3ec55ca00455f21c3c869f29a53a5a016f0ddc70490821147a07e83f283edaaa3f96ed0ea6eff394a8f33426be9f40cdf92ee1244c34773d578806c1bd063cda5cde68b7cdefa344815da1933ecd7212bfc3230cb37bc51d824156c969bfce6319e650e5adc96a133dc2759274b24bf5da3530648934500fe676b00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa06dc8edd393bb42e10868aa75eb0b4d891aec1c52940129e5ae1701b20f0922f4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211498402625a008084669fb32eb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb8609181bd632b988883a8d359e589409e6930dc2526a3143bc4406c976d4946edc6a894648cd2aa4113fd6c91cb519bf3e10e17fbbca9102de604bcaa013e2d0709320530bef0b2002dd451cc8166a5b626224cf94abaa9d906ec474bd48a79beb7f848821147a07e83f283edaaa3f96ed0ea6eff394a8f33426be9f40cdf92ee1244c34773d578821148a06dc8edd393bb42e10868aa75eb0b4d891aec1c52940129e5ae1701b20f0922f480119ad821963837eaf154d653c8c35215e3cf8a7c48154b1ea6e85b9efadf3f301e60c91b19b77d8600e7297e6a6b9ef9433e7b890e06e03fc2c084d0c0c79d9f00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0298fc95dada993aa42f306441bd8d5c7631a08cb5d8358659445a4691f26a14da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282114a8402625a008084669fb331b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a11e6d8a9c037cada3344abb538da2d287ec129993e50e6fba2dae713071344075a255b9872edf6471a72733f5602d740f7a9e81adcf41451146f80197a3e09a5c88d80f2010284396cb0aa4e4022cf8a66f9d8cb015cc0d15ddfbf4b38e57ddf848821148a06dc8edd393bb42e10868aa75eb0b4d891aec1c52940129e5ae1701b20f0922f4821149a0298fc95dada993aa42f306441bd8d5c7631a08cb5d8358659445a4691f26a14d80de1e991caa78f9d4b979c96d3a74ec7c6f34343ba466294780a7f475a616b4930bedaffe245caaf1c87a505b3d7d8f492f786bf4e884823b0ab94e46e4baadf400a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310b0221a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea065b83aa9b59125f9b090432f556c6ff947b5708eb11ca5ea26342392860be00aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a01a41c640130c53b3c90b1b5c691ed467218cee97aade5aac9306e72865851e27a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330093808").to_vec(), - ], - // 4423 + // checkpoint 1003 turnLength 1 target 0-1000 vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafabaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a09f0bb93d54df1fcbfd84d4173496de9cff0f403319bbbaf15791ccde774b73d8a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211308402625a008229a884669fb2e3b90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8048fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6ca7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833309f8ae0fb860834538868d2c79371ead2f10fc7229fd3b3aaf1d7d8607fd7e1d2efba7df1008c105fdab4ad8029f86cfde1e3aa7dd24194fcf07502bb6c281fc3cbc08ad8cb467de57cbfd1bb93fabe72f77ece8f991a2b7a4d7fb301d54547c6cb4b612d06ff84882112ea042dfe9761fb9a677b088a868f237a171d511bea581f643844a1c98267902391882112fa0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafaba80321f35c8454a2691a2efff6894cae6277ea06390978294fe0d10fe03f432fd07440d802ca0858a2d6138230b37d1a9148a3d76fbe8492854e637c9aad7494e3401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211318402625a008084669fb2e6b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b6de9ffe941751cd11463bbd4bde69d3bc2b79868f669f9e2c4c327f036e6d558b013469a91670607dd88d63dc50b95d00719e118a17e5b72418b6ae4bef7aebbcdaa44b79f8c0677ac32c71312d84db44e6e9216bd84fb97c7d0701a4a03431f84882112fa0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafaba821130a09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1f80e5619874ecb4463f8d86981d939ddb4d0eaa151c6080c7067788e06699789d0a415e921b8824e8adc7907e5bbccec9373b22c7fe8a48527e9348aa957871b63300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0e3aa9bc64f82ccd7e70ec415d73263d9da9f3bb44b78bed500033379df9be8aaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211328402625a008084669fb2e9b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb86095a056c77bdeb59da26e665d69e75cc5667cd43df693a55f20f5f248483a3ce10cdd996b29c7fd6ba3f9e31cb4ac089c0b5bc13e77d83f17096d88f280b8d47ffd8b58b66bd760d0ccd4d26e0c2a7bb3ec168a06a815cfbdde9a2e18c32ac74ef848821130a09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1f821131a0e3aa9bc64f82ccd7e70ec415d73263d9da9f3bb44b78bed500033379df9be8aa80c04c6f70fa142c7486f7bed7e29a247f1203d58c7481c9aefef1193e6404112e32486f8d4dc8c7c558ae0b1bf860f6e05d425b7726ba7a4e2dac6e3e3eb83d3d00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310e8201a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea065b83aa9b59125f9b090432f556c6ff947b5708eb11ca5ea26342392860be00aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a01a41c640130c53b3c90b1b5c691ed467218cee97aade5aac9306e72865851e27a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330093808").to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa08597c8d93294088beb70b3ec55ca00455f21c3c869f29a53a5a016f0ddc70490a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211478402625a008084669fb328b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860af92c5293ca4336704b31966a2d411532a7c9696f188dfce265be71340b5c8e3a3b34fa8d2684ea3a7f568e4d00ebd3613d00969b3b5ee28e218059dd9daa317232407168621b9ff0c29b10826b9e147d1e6581ef82eeffcaa2efc978d7bad64f848821145a0e322fe7afcc860264a85976dad2a256409bb3638003903326e3e5158ad95e83f821146a08597c8d93294088beb70b3ec55ca00455f21c3c869f29a53a5a016f0ddc70490808dc71db6edb508340d681faca3a54624171b62e4ed4639f3b1f67f954b87861c7686519390f671e919cb3f60fd1516ebefa7fea912ced5d6275e6797a3ccac1f00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa07e83f283edaaa3f96ed0ea6eff394a8f33426be9f40cdf92ee1244c34773d578a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211488402625a008084669fb32bb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b6ed50c4b59a9e54e8e082fa735665d629f10488d2138f1e454b765ea16eca7571dbd7826e2b570b2905594f899fa2561977420047c4d053343146ed88df4ff667b9aa59679c3285dcccfa809647eb8ed2164b50f8e576fdc8f088cba74b6e98f848821146a08597c8d93294088beb70b3ec55ca00455f21c3c869f29a53a5a016f0ddc70490821147a07e83f283edaaa3f96ed0ea6eff394a8f33426be9f40cdf92ee1244c34773d578806c1bd063cda5cde68b7cdefa344815da1933ecd7212bfc3230cb37bc51d824156c969bfce6319e650e5adc96a133dc2759274b24bf5da3530648934500fe676b00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa06dc8edd393bb42e10868aa75eb0b4d891aec1c52940129e5ae1701b20f0922f4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211498402625a008084669fb32eb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb8609181bd632b988883a8d359e589409e6930dc2526a3143bc4406c976d4946edc6a894648cd2aa4113fd6c91cb519bf3e10e17fbbca9102de604bcaa013e2d0709320530bef0b2002dd451cc8166a5b626224cf94abaa9d906ec474bd48a79beb7f848821147a07e83f283edaaa3f96ed0ea6eff394a8f33426be9f40cdf92ee1244c34773d578821148a06dc8edd393bb42e10868aa75eb0b4d891aec1c52940129e5ae1701b20f0922f480119ad821963837eaf154d653c8c35215e3cf8a7c48154b1ea6e85b9efadf3f301e60c91b19b77d8600e7297e6a6b9ef9433e7b890e06e03fc2c084d0c0c79d9f00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310b0221a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea065b83aa9b59125f9b090432f556c6ff947b5708eb11ca5ea26342392860be00aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a01a41c640130c53b3c90b1b5c691ed467218cee97aade5aac9306e72865851e27a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330093808").to_vec(), + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b81b0a8a090a8709f90484a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a04c35879f76cd366249e5810ce3ff0a4be2f4e1a995e004fa207bcbece6b43bf2a0e0781acd204a300b1a607656df80d8a3ab2684fb6fa9e83d4087aa9e9157330ca03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e88402625a008229a88467d7bba9b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926906f8ae0fb86099f5bd42d7a4e11f283b9daa22fe1f7ae89e5260b61722ec3f57dc2b18a669e0040e42a6f81d114732c00609d4648b0d0fec3a07fb300cf49a7cf6116abb217b13a63ee6330663349e8a316c42dc04f16131445a331365d2b32bcb4d5b546c25f8488203e6a0302d35ff53c930401473e5650e8169f18f1156d0127cd1bd1a3e65fe365c5efc8203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a80a240096b876248068d454519a30d241182b95497f8a66d6d179495e9fd6d9427096f4c35eb87299f195d8fd4731d162a2c8ab445dd0ea56989288b2825c640c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04ff32807d3701bcff50e1213fdce58ce988fb64c9e1cc269874a3d970ef7d1e8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e98402625a00808467d7bbaab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860a51854c31fb60a02ba70c07eeb467be677b9548c828607f99dfd0edc80a9b25be05670b86485dd71d8fb8e19d7458a9103d942ea6b84070ed47adcd3a3f284385fc538a5f692289c3abc25372e461a54ef23100718aedf80224a1e4fe26671d3f8488203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a8203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c80313317225cc094c83c097e6a830295a3e3a6df48baadc709927d7d2bc643d9ef4d474ff4442565ef2c0bf90644095ee4d3a9934650d1b989f9d82ba9d664e57100a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a08c694a1f89eafbe7d2a2e08e4e64f855159fe234cb26637edf6a166429d4f338a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ea8402625a00808467d7bbacb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86094e9755690770485712c5b0f060b43d2bd542c3712146d8542053d4f42d05bf253ed5ee05efb85862f2faf4b6c25279e1735110b78af88000b4c90462ff318fc195be0b1a7a0d4e41943ec288aafab6eb3c5ebc31dd2a0ce428cceebf20553aef8488203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c8203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8020c2f74f57683c3ca4405ad21e3fdf74c30624571bbcf7b88cf27d4b12631ac9069c6fa8ff35fac1662e9bc89dc040cec541fd36aee8c8058c299bafc0ed5d1700a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310f4031a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928063001") .to_vec(), + // 1004 + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212a4190af6060af306f90370a06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a06d13a0cc728f1d2c3dbf74e1e3ec93bf5f5e05419259290c6af477dfec4c5946a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ec8402625a00808467d7bbafb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86098cf37a5fdc36301d6d4ccf22f89c1403a577f4c5e25f3fd795f80ef9de4ae2c5ae1f7b7e4e8ba75334c2ffa0e6b1c0f002bfc3e46e11b2491fa85da11b3abd89e58934c0cf1f889e2a833ca25635a3c9dc4cdf322949c20cd2ea016cd29209ef8488203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd248203eba06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28b80e539311c1e5557ee877b0fa621406d29858639e72427f363a562402cbc7b8e21573b84267a99bba57e0924b2536c9d42ec2cb1b8fee98cb9ce7b5418b887495900a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0ad2e1c5034a4cbbe79457ddf448057510e268fddb10e99daf81564b86414773aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a097d5fe33ae946428c4be77c59ae8a545705646ef31fe8b2a54c5b7134f798169a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ed8402625a00808467d7bbb0b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860b547590857fa914223f8af00a02c80c179f90d31ef69e7bf6e2d9a222fe9acdc518136b552ddac94f85fefe2ad5eb0e306a2c90b0506d274bf8853909a0503d360fe5f1e8271bed925d2e57870ab03799dec8d79d183df90775d7e4d9b62a5d2f8488203eba06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28b8203eca0ad2e1c5034a4cbbe79457ddf448057510e268fddb10e99daf81564b86414773a8091195aca7d09fd725ab73adab646c3f2eec45cbc8d77d36b15bd67bfbaa2f8112f9800f6361f91bac66e2b0d359eeefab41cf3cdfe1a547bf77655e93ca8810101a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a073cdb17445b49b04b50268a391497d313bb97439e87714491cb3a79b69f9e0eaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0719726575d202c3ba768567e4ffb1a04fc595e95a514fb4147c7aca97b21848ba056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ee8402625a00808467d7bbb2b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860b6972fcec62512cad033a6d64131ccff94b0324cc0cf22f7bc4a4dbd9952883152a2814f64c2ba4e2e00d4486feff304088cb0d05d42ae1337b45db63f78f5d467671178a4777dbe305844c0a4315538c17dc15f472e174f328b0c74d19dc2f6f8488203eca0ad2e1c5034a4cbbe79457ddf448057510e268fddb10e99daf81564b86414773a8203eda073cdb17445b49b04b50268a391497d313bb97439e87714491cb3a79b69f9e0ea80c3dd1fae70cdeb72ce198f34f408e38b834af85a8a684f8a2e0b94b79ae0c31715261183253f86260b93091a609ed23cb3d2f09bb3e19ad603fc7beaf1b3514900a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310e8071a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928063001").to_vec() ], - // checkpoint 4627 turnLength 9 target 0-4700 vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de59a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a092fe9b87aac5e3e9d963a9176e28d4c71086d2c13b46ded73e0467a61f7a0fd7a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211f88402625a008229a884669fb53bb90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e804a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d2e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833304f8ae0fb860954dd9a7e6559e3f6f55f9ba10aaf0baac053ece467f77d6d42d204b629b5048d683376d02ce17945955458a8f30a9a601bf555c0283ff99075cc422edcc8ec964f161e6fd897999177c98dd733e8dfb6dc8085ca2b20af98022024c19abdc92f8488211f6a059332f01fb2eb9930f0e9fb5845396fc1815b2d1c4b59d02bf294601c8520e7c8211f7a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de598071fda5fa2587d87bf54660696cadbc7ebdf31a245474525de5136c1ff874095a62294fd1b2ea25e84c3e402a7a3a23831f2629761ad7e2007b9d32f02346466c00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211f98402625a008084669fb53eb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b98cdf6910246b1d63a21a58aaefd83776297f08ebd6226b34be9fe73aac50a2ee3aa920b67059563f60e94d1635ccb4146dce79aac8aa1b82541ab8624e86babd01e54c2205dbbfafe5e57be36a8c5c96b844db0f39fb2acc1914c5d838fa5bf8488211f7a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de598211f8a07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da4809ecf963edc51a77ac5a0a64d83e63c63289a2623cedc97e5a8c458f2fa54900677d1176db4c6911dedf7fd1c7e5f72c521c71d3c820adff16fd085dcaea6f60c01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa04efcea74c9f84fc35eb27c58b3b01263e2abe62131f720e24d1d2726abb9d777a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211fa8402625a008084669fb541b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a5e737e760e4d3b6e4966678f49264cd84af64a21abfac165be7664ca2d8f604fc6b1dcf015c29c7a69ac381c3f3679c11328ac212b8be7348304cfc1dd821a7fa24f9a0c211d2bfeccc26fd2d352d72afb467cad2d974b0b3181437ccd4204bf8488211f8a07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da48211f9a04efcea74c9f84fc35eb27c58b3b01263e2abe62131f720e24d1d2726abb9d77780ef69344959bf3a0cce0732ebb0a871676c381e77264b9eef8875c9bea16ea07812d4f290a701b4ba256800a7219f6413b27b367ebbb23686ac044a5f44af63c400a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310b0221a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0ded0ae13e1f14e98e291b7bc725f590e0208cd8aee5029e86999268a01dfa95aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330043809") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa04405b2852348288eb937f08cf2d4bbf9eb3b93e0cc37abf5a2d66480e72b3f93a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212138402625a008084669fb58cb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860ac1a9ed39be5ee71e4b04d6685b84a6c8af9bd23cc2490c4a922ae7f9adaafbbd0b33a7ec7af34c439a74b8019fd837014791bd9cad48d4bdf969ef1aadc93c9b2b466845711e6c45f1c0a1625cdc262d9da55861bddb43b8f378560147bddc6f848821211a0c7eb18f17075bce2c6433c7067473a8aed41832321610cd4203ac2458767000b821212a04405b2852348288eb937f08cf2d4bbf9eb3b93e0cc37abf5a2d66480e72b3f93800003aa6dca4260b052409e2c2f21878d34bcab41aaf0fdca1b22b1ce22f0d2da56ccce3bc9b18fae5aa5df4a69f5b3078d2db98094dfef7a8724ebda8151425600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa08a0f8318b4ebf3563cdebccbc1c5c9dc1631507e20b25ee82838b4200e7866dca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212148402625a008084669fb58fb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a1c7de98d980f1f5a1c7809a50b9f7b5edb0b0a2c5021a66375cc76b7fb018516521a8e66e871e343d2c7f767c5ee320146dacde02ff88061077445b32f03c0b2b80a0b4b57add85a90574490bc78a588fc5fced38340c9bff33e724eb8add09f848821212a04405b2852348288eb937f08cf2d4bbf9eb3b93e0cc37abf5a2d66480e72b3f93821213a08a0f8318b4ebf3563cdebccbc1c5c9dc1631507e20b25ee82838b4200e7866dc808b54d4dd3dd7b680aff75622bf8e37c28ad9c1b1ebee259dc6059c2eeece574330af8f57dd8d6fcb180e4561f8fd178390d0cdeda778716f3bb0af65826ca9af01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa09249902fceede184ab056d38dbf0c5a7ef63efea6d806f9c4a4252858986eb0aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212158402625a008084669fb592b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb86084b35063aa88712f15fecae44da0a94be292fbe0de1485357e4963d14536b4fd2068d58a65ef742bd8a6b21815c5b21304a518012f244d711157e18d45393d5b4eb414cde52929938890c912d362f894ec71df7bb1e29f0c5e3d6eb9976f1004f848821213a08a0f8318b4ebf3563cdebccbc1c5c9dc1631507e20b25ee82838b4200e7866dc821214a09249902fceede184ab056d38dbf0c5a7ef63efea6d806f9c4a4252858986eb0a808d9ab2b91f65aa6ead079f8b544dde4fa466d3586714e5da17f8f671599c5a5717b18d1811d6a3bfe5ccb1f6567b95cdc099a0f7d315a98e3199a268e5b5d53e00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310f8231a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0ded0ae13e1f14e98e291b7bc725f590e0208cd8aee5029e86999268a01dfa95aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330043809").to_vec() + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b81b0a8a090a8709f90484a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a04c35879f76cd366249e5810ce3ff0a4be2f4e1a995e004fa207bcbece6b43bf2a0e0781acd204a300b1a607656df80d8a3ab2684fb6fa9e83d4087aa9e9157330ca03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e88402625a008229a88467d7bba9b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926906f8ae0fb86099f5bd42d7a4e11f283b9daa22fe1f7ae89e5260b61722ec3f57dc2b18a669e0040e42a6f81d114732c00609d4648b0d0fec3a07fb300cf49a7cf6116abb217b13a63ee6330663349e8a316c42dc04f16131445a331365d2b32bcb4d5b546c25f8488203e6a0302d35ff53c930401473e5650e8169f18f1156d0127cd1bd1a3e65fe365c5efc8203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a80a240096b876248068d454519a30d241182b95497f8a66d6d179495e9fd6d9427096f4c35eb87299f195d8fd4731d162a2c8ab445dd0ea56989288b2825c640c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04ff32807d3701bcff50e1213fdce58ce988fb64c9e1cc269874a3d970ef7d1e8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e98402625a00808467d7bbaab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860a51854c31fb60a02ba70c07eeb467be677b9548c828607f99dfd0edc80a9b25be05670b86485dd71d8fb8e19d7458a9103d942ea6b84070ed47adcd3a3f284385fc538a5f692289c3abc25372e461a54ef23100718aedf80224a1e4fe26671d3f8488203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a8203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c80313317225cc094c83c097e6a830295a3e3a6df48baadc709927d7d2bc643d9ef4d474ff4442565ef2c0bf90644095ee4d3a9934650d1b989f9d82ba9d664e57100a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a08c694a1f89eafbe7d2a2e08e4e64f855159fe234cb26637edf6a166429d4f338a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ea8402625a00808467d7bbacb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86094e9755690770485712c5b0f060b43d2bd542c3712146d8542053d4f42d05bf253ed5ee05efb85862f2faf4b6c25279e1735110b78af88000b4c90462ff318fc195be0b1a7a0d4e41943ec288aafab6eb3c5ebc31dd2a0ce428cceebf20553aef8488203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c8203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8020c2f74f57683c3ca4405ad21e3fdf74c30624571bbcf7b88cf27d4b12631ac9069c6fa8ff35fac1662e9bc89dc040cec541fd36aee8c8058c299bafc0ed5d1700a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310f4031a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928063001") .to_vec(), + // 1003 + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212a4190af6060af306f90370a04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd24a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0167484b0a23d96c53238b8e02465ce28353b86bde23a4c76079c206ef68c9646a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203eb8402625a00808467d7bbadb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860acaa8373b727de717178de93621351e285bc9803b59af041bcf6125421adb461838a18c251c2fe3e747b4081010e429411a750ddc02871238102ac2df09bcb6085b48d9061f23dda19b5084c1b6b8cbdf816f29643413a0b616ba24a3b00145bf8488203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd24805444abf4fc554f34fd1f7e8e768ffa50740d4cbe373175fa115bc3b674d4d2322496a207e5d5bf5224071a161d9194db4b9c4e628e3214c3f4c35bf194998b0c00a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a06d13a0cc728f1d2c3dbf74e1e3ec93bf5f5e05419259290c6af477dfec4c5946a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ec8402625a00808467d7bbafb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86098cf37a5fdc36301d6d4ccf22f89c1403a577f4c5e25f3fd795f80ef9de4ae2c5ae1f7b7e4e8ba75334c2ffa0e6b1c0f002bfc3e46e11b2491fa85da11b3abd89e58934c0cf1f889e2a833ca25635a3c9dc4cdf322949c20cd2ea016cd29209ef8488203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd248203eba06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28b80e539311c1e5557ee877b0fa621406d29858639e72427f363a562402cbc7b8e21573b84267a99bba57e0924b2536c9d42ec2cb1b8fee98cb9ce7b5418b887495900a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0ad2e1c5034a4cbbe79457ddf448057510e268fddb10e99daf81564b86414773aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a097d5fe33ae946428c4be77c59ae8a545705646ef31fe8b2a54c5b7134f798169a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ed8402625a00808467d7bbb0b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860b547590857fa914223f8af00a02c80c179f90d31ef69e7bf6e2d9a222fe9acdc518136b552ddac94f85fefe2ad5eb0e306a2c90b0506d274bf8853909a0503d360fe5f1e8271bed925d2e57870ab03799dec8d79d183df90775d7e4d9b62a5d2f8488203eba06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28b8203eca0ad2e1c5034a4cbbe79457ddf448057510e268fddb10e99daf81564b86414773a8091195aca7d09fd725ab73adab646c3f2eec45cbc8d77d36b15bd67bfbaa2f8112f9800f6361f91bac66e2b0d359eeefab41cf3cdfe1a547bf77655e93ca8810101a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310e8071a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928063001").to_vec() ], - // 4626 vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de59a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a092fe9b87aac5e3e9d963a9176e28d4c71086d2c13b46ded73e0467a61f7a0fd7a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211f88402625a008229a884669fb53bb90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e804a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d2e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833304f8ae0fb860954dd9a7e6559e3f6f55f9ba10aaf0baac053ece467f77d6d42d204b629b5048d683376d02ce17945955458a8f30a9a601bf555c0283ff99075cc422edcc8ec964f161e6fd897999177c98dd733e8dfb6dc8085ca2b20af98022024c19abdc92f8488211f6a059332f01fb2eb9930f0e9fb5845396fc1815b2d1c4b59d02bf294601c8520e7c8211f7a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de598071fda5fa2587d87bf54660696cadbc7ebdf31a245474525de5136c1ff874095a62294fd1b2ea25e84c3e402a7a3a23831f2629761ad7e2007b9d32f02346466c00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211f98402625a008084669fb53eb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b98cdf6910246b1d63a21a58aaefd83776297f08ebd6226b34be9fe73aac50a2ee3aa920b67059563f60e94d1635ccb4146dce79aac8aa1b82541ab8624e86babd01e54c2205dbbfafe5e57be36a8c5c96b844db0f39fb2acc1914c5d838fa5bf8488211f7a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de598211f8a07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da4809ecf963edc51a77ac5a0a64d83e63c63289a2623cedc97e5a8c458f2fa54900677d1176db4c6911dedf7fd1c7e5f72c521c71d3c820adff16fd085dcaea6f60c01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa04efcea74c9f84fc35eb27c58b3b01263e2abe62131f720e24d1d2726abb9d777a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211fa8402625a008084669fb541b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a5e737e760e4d3b6e4966678f49264cd84af64a21abfac165be7664ca2d8f604fc6b1dcf015c29c7a69ac381c3f3679c11328ac212b8be7348304cfc1dd821a7fa24f9a0c211d2bfeccc26fd2d352d72afb467cad2d974b0b3181437ccd4204bf8488211f8a07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da48211f9a04efcea74c9f84fc35eb27c58b3b01263e2abe62131f720e24d1d2726abb9d77780ef69344959bf3a0cce0732ebb0a871676c381e77264b9eef8875c9bea16ea07812d4f290a701b4ba256800a7219f6413b27b367ebbb23686ac044a5f44af63c400a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310b0221a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0ded0ae13e1f14e98e291b7bc725f590e0208cd8aee5029e86999268a01dfa95aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330043809") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa0c7eb18f17075bce2c6433c7067473a8aed41832321610cd4203ac2458767000ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212128402625a008084669fb589b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb86081f087223adcf0e52ec559804997c76b928c922d2b18303a53d5eb2d4aacc0c51c77b5cd3e549da81a1e59a0b00084c600b3a1479cc06c825b3c7483413f14c27b5e858233352b744b4366c64df4e2df2965b5bab6229b64aef58fbf16ea2547f848821210a007ae96eb397a1c4786191ed1666e2037a1cb789b7966d546174ff5c51a26cdea821211a0c7eb18f17075bce2c6433c7067473a8aed41832321610cd4203ac2458767000b800db71cfcf5f3efea5deb8887bc3b1490ac7eb950c9bdf0eb8fa866aa90b90ba54c85a0ff8a86247a2c4ecbaa5a6d7ec62f75fbd09bfbbc37f1b42f95c6c3e9d401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa04405b2852348288eb937f08cf2d4bbf9eb3b93e0cc37abf5a2d66480e72b3f93a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212138402625a008084669fb58cb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860ac1a9ed39be5ee71e4b04d6685b84a6c8af9bd23cc2490c4a922ae7f9adaafbbd0b33a7ec7af34c439a74b8019fd837014791bd9cad48d4bdf969ef1aadc93c9b2b466845711e6c45f1c0a1625cdc262d9da55861bddb43b8f378560147bddc6f848821211a0c7eb18f17075bce2c6433c7067473a8aed41832321610cd4203ac2458767000b821212a04405b2852348288eb937f08cf2d4bbf9eb3b93e0cc37abf5a2d66480e72b3f93800003aa6dca4260b052409e2c2f21878d34bcab41aaf0fdca1b22b1ce22f0d2da56ccce3bc9b18fae5aa5df4a69f5b3078d2db98094dfef7a8724ebda8151425600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa08a0f8318b4ebf3563cdebccbc1c5c9dc1631507e20b25ee82838b4200e7866dca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212148402625a008084669fb58fb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a1c7de98d980f1f5a1c7809a50b9f7b5edb0b0a2c5021a66375cc76b7fb018516521a8e66e871e343d2c7f767c5ee320146dacde02ff88061077445b32f03c0b2b80a0b4b57add85a90574490bc78a588fc5fced38340c9bff33e724eb8add09f848821212a04405b2852348288eb937f08cf2d4bbf9eb3b93e0cc37abf5a2d66480e72b3f93821213a08a0f8318b4ebf3563cdebccbc1c5c9dc1631507e20b25ee82838b4200e7866dc808b54d4dd3dd7b680aff75622bf8e37c28ad9c1b1ebee259dc6059c2eeece574330af8f57dd8d6fcb180e4561f8fd178390d0cdeda778716f3bb0af65826ca9af01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310f8231a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0ded0ae13e1f14e98e291b7bc725f590e0208cd8aee5029e86999268a01dfa95aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330043809").to_vec() + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b81b0a8a090a8709f90484a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a04c35879f76cd366249e5810ce3ff0a4be2f4e1a995e004fa207bcbece6b43bf2a0e0781acd204a300b1a607656df80d8a3ab2684fb6fa9e83d4087aa9e9157330ca03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e88402625a008229a88467d7bba9b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926906f8ae0fb86099f5bd42d7a4e11f283b9daa22fe1f7ae89e5260b61722ec3f57dc2b18a669e0040e42a6f81d114732c00609d4648b0d0fec3a07fb300cf49a7cf6116abb217b13a63ee6330663349e8a316c42dc04f16131445a331365d2b32bcb4d5b546c25f8488203e6a0302d35ff53c930401473e5650e8169f18f1156d0127cd1bd1a3e65fe365c5efc8203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a80a240096b876248068d454519a30d241182b95497f8a66d6d179495e9fd6d9427096f4c35eb87299f195d8fd4731d162a2c8ab445dd0ea56989288b2825c640c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04ff32807d3701bcff50e1213fdce58ce988fb64c9e1cc269874a3d970ef7d1e8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e98402625a00808467d7bbaab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860a51854c31fb60a02ba70c07eeb467be677b9548c828607f99dfd0edc80a9b25be05670b86485dd71d8fb8e19d7458a9103d942ea6b84070ed47adcd3a3f284385fc538a5f692289c3abc25372e461a54ef23100718aedf80224a1e4fe26671d3f8488203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a8203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c80313317225cc094c83c097e6a830295a3e3a6df48baadc709927d7d2bc643d9ef4d474ff4442565ef2c0bf90644095ee4d3a9934650d1b989f9d82ba9d664e57100a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a08c694a1f89eafbe7d2a2e08e4e64f855159fe234cb26637edf6a166429d4f338a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ea8402625a00808467d7bbacb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86094e9755690770485712c5b0f060b43d2bd542c3712146d8542053d4f42d05bf253ed5ee05efb85862f2faf4b6c25279e1735110b78af88000b4c90462ff318fc195be0b1a7a0d4e41943ec288aafab6eb3c5ebc31dd2a0ce428cceebf20553aef8488203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c8203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8020c2f74f57683c3ca4405ad21e3fdf74c30624571bbcf7b88cf27d4b12631ac9069c6fa8ff35fac1662e9bc89dc040cec541fd36aee8c8058c299bafc0ed5d1700a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310f4031a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928063001") .to_vec(), + // 1002 + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212a4190af6060af306f90370a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a08c694a1f89eafbe7d2a2e08e4e64f855159fe234cb26637edf6a166429d4f338a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ea8402625a00808467d7bbacb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86094e9755690770485712c5b0f060b43d2bd542c3712146d8542053d4f42d05bf253ed5ee05efb85862f2faf4b6c25279e1735110b78af88000b4c90462ff318fc195be0b1a7a0d4e41943ec288aafab6eb3c5ebc31dd2a0ce428cceebf20553aef8488203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c8203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8020c2f74f57683c3ca4405ad21e3fdf74c30624571bbcf7b88cf27d4b12631ac9069c6fa8ff35fac1662e9bc89dc040cec541fd36aee8c8058c299bafc0ed5d1700a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd24a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0167484b0a23d96c53238b8e02465ce28353b86bde23a4c76079c206ef68c9646a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203eb8402625a00808467d7bbadb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860acaa8373b727de717178de93621351e285bc9803b59af041bcf6125421adb461838a18c251c2fe3e747b4081010e429411a750ddc02871238102ac2df09bcb6085b48d9061f23dda19b5084c1b6b8cbdf816f29643413a0b616ba24a3b00145bf8488203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd24805444abf4fc554f34fd1f7e8e768ffa50740d4cbe373175fa115bc3b674d4d2322496a207e5d5bf5224071a161d9194db4b9c4e628e3214c3f4c35bf194998b0c00a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a06d13a0cc728f1d2c3dbf74e1e3ec93bf5f5e05419259290c6af477dfec4c5946a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ec8402625a00808467d7bbafb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86098cf37a5fdc36301d6d4ccf22f89c1403a577f4c5e25f3fd795f80ef9de4ae2c5ae1f7b7e4e8ba75334c2ffa0e6b1c0f002bfc3e46e11b2491fa85da11b3abd89e58934c0cf1f889e2a833ca25635a3c9dc4cdf322949c20cd2ea016cd29209ef8488203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd248203eba06d0feaa8875bcdf85d71f2d5831b354eaddc2bca24005f732c348def8a23b28b80e539311c1e5557ee877b0fa621406d29858639e72427f363a562402cbc7b8e21573b84267a99bba57e0924b2536c9d42ec2cb1b8fee98cb9ce7b5418b887495900a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310e8071a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928063001").to_vec() ], - // 4628 - vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de59a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a092fe9b87aac5e3e9d963a9176e28d4c71086d2c13b46ded73e0467a61f7a0fd7a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211f88402625a008229a884669fb53bb90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e804a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d2e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833304f8ae0fb860954dd9a7e6559e3f6f55f9ba10aaf0baac053ece467f77d6d42d204b629b5048d683376d02ce17945955458a8f30a9a601bf555c0283ff99075cc422edcc8ec964f161e6fd897999177c98dd733e8dfb6dc8085ca2b20af98022024c19abdc92f8488211f6a059332f01fb2eb9930f0e9fb5845396fc1815b2d1c4b59d02bf294601c8520e7c8211f7a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de598071fda5fa2587d87bf54660696cadbc7ebdf31a245474525de5136c1ff874095a62294fd1b2ea25e84c3e402a7a3a23831f2629761ad7e2007b9d32f02346466c00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211f98402625a008084669fb53eb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b98cdf6910246b1d63a21a58aaefd83776297f08ebd6226b34be9fe73aac50a2ee3aa920b67059563f60e94d1635ccb4146dce79aac8aa1b82541ab8624e86babd01e54c2205dbbfafe5e57be36a8c5c96b844db0f39fb2acc1914c5d838fa5bf8488211f7a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de598211f8a07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da4809ecf963edc51a77ac5a0a64d83e63c63289a2623cedc97e5a8c458f2fa54900677d1176db4c6911dedf7fd1c7e5f72c521c71d3c820adff16fd085dcaea6f60c01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa04efcea74c9f84fc35eb27c58b3b01263e2abe62131f720e24d1d2726abb9d777a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211fa8402625a008084669fb541b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a5e737e760e4d3b6e4966678f49264cd84af64a21abfac165be7664ca2d8f604fc6b1dcf015c29c7a69ac381c3f3679c11328ac212b8be7348304cfc1dd821a7fa24f9a0c211d2bfeccc26fd2d352d72afb467cad2d974b0b3181437ccd4204bf8488211f8a07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da48211f9a04efcea74c9f84fc35eb27c58b3b01263e2abe62131f720e24d1d2726abb9d77780ef69344959bf3a0cce0732ebb0a871676c381e77264b9eef8875c9bea16ea07812d4f290a701b4ba256800a7219f6413b27b367ebbb23686ac044a5f44af63c400a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310b0221a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0ded0ae13e1f14e98e291b7bc725f590e0208cd8aee5029e86999268a01dfa95aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330043809") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa08a0f8318b4ebf3563cdebccbc1c5c9dc1631507e20b25ee82838b4200e7866dca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212148402625a008084669fb58fb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a1c7de98d980f1f5a1c7809a50b9f7b5edb0b0a2c5021a66375cc76b7fb018516521a8e66e871e343d2c7f767c5ee320146dacde02ff88061077445b32f03c0b2b80a0b4b57add85a90574490bc78a588fc5fced38340c9bff33e724eb8add09f848821212a04405b2852348288eb937f08cf2d4bbf9eb3b93e0cc37abf5a2d66480e72b3f93821213a08a0f8318b4ebf3563cdebccbc1c5c9dc1631507e20b25ee82838b4200e7866dc808b54d4dd3dd7b680aff75622bf8e37c28ad9c1b1ebee259dc6059c2eeece574330af8f57dd8d6fcb180e4561f8fd178390d0cdeda778716f3bb0af65826ca9af01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa09249902fceede184ab056d38dbf0c5a7ef63efea6d806f9c4a4252858986eb0aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212158402625a008084669fb592b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb86084b35063aa88712f15fecae44da0a94be292fbe0de1485357e4963d14536b4fd2068d58a65ef742bd8a6b21815c5b21304a518012f244d711157e18d45393d5b4eb414cde52929938890c912d362f894ec71df7bb1e29f0c5e3d6eb9976f1004f848821213a08a0f8318b4ebf3563cdebccbc1c5c9dc1631507e20b25ee82838b4200e7866dc821214a09249902fceede184ab056d38dbf0c5a7ef63efea6d806f9c4a4252858986eb0a808d9ab2b91f65aa6ead079f8b544dde4fa466d3586714e5da17f8f671599c5a5717b18d1811d6a3bfe5ccb1f6567b95cdc099a0f7d315a98e3199a268e5b5d53e00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0914c3fa83e1f679338195c58ea19dfab85f1e37ddb8bdb6e98a4f0a7a621575ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212168402625a008084669fb595b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a82b11ac3a16da80fe96338070479d843581fc96b1ec7e674034ff16b326f672b7276e0572d09778cbab20274751280e082f56b84a2fa69a3d4effeaa434e24bb91b2deac65ba30d81e269bdcd58681cece65fb43efdabf39feb8577d98a3979f848821214a09249902fceede184ab056d38dbf0c5a7ef63efea6d806f9c4a4252858986eb0a821215a0914c3fa83e1f679338195c58ea19dfab85f1e37ddb8bdb6e98a4f0a7a621575e805347706cb6777f5cce4f9970d4106b540bd37feb0ebc269cbcae2cabe2eede766cf8c829182db84d31f928ba050a38305a665985a950a83604c2e3a857ee74f801a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310f8231a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0ded0ae13e1f14e98e291b7bc725f590e0208cd8aee5029e86999268a01dfa95aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330043809").to_vec() - ], - // 4799 - vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de59a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a092fe9b87aac5e3e9d963a9176e28d4c71086d2c13b46ded73e0467a61f7a0fd7a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211f88402625a008229a884669fb53bb90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e804a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d2e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833304f8ae0fb860954dd9a7e6559e3f6f55f9ba10aaf0baac053ece467f77d6d42d204b629b5048d683376d02ce17945955458a8f30a9a601bf555c0283ff99075cc422edcc8ec964f161e6fd897999177c98dd733e8dfb6dc8085ca2b20af98022024c19abdc92f8488211f6a059332f01fb2eb9930f0e9fb5845396fc1815b2d1c4b59d02bf294601c8520e7c8211f7a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de598071fda5fa2587d87bf54660696cadbc7ebdf31a245474525de5136c1ff874095a62294fd1b2ea25e84c3e402a7a3a23831f2629761ad7e2007b9d32f02346466c00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211f98402625a008084669fb53eb90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b98cdf6910246b1d63a21a58aaefd83776297f08ebd6226b34be9fe73aac50a2ee3aa920b67059563f60e94d1635ccb4146dce79aac8aa1b82541ab8624e86babd01e54c2205dbbfafe5e57be36a8c5c96b844db0f39fb2acc1914c5d838fa5bf8488211f7a00f2f3784c6d60d1be2666840114c0b20da860de6af0c718087cd4d1248c4de598211f8a07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da4809ecf963edc51a77ac5a0a64d83e63c63289a2623cedc97e5a8c458f2fa54900677d1176db4c6911dedf7fd1c7e5f72c521c71d3c820adff16fd085dcaea6f60c01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa04efcea74c9f84fc35eb27c58b3b01263e2abe62131f720e24d1d2726abb9d777a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211fa8402625a008084669fb541b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a5e737e760e4d3b6e4966678f49264cd84af64a21abfac165be7664ca2d8f604fc6b1dcf015c29c7a69ac381c3f3679c11328ac212b8be7348304cfc1dd821a7fa24f9a0c211d2bfeccc26fd2d352d72afb467cad2d974b0b3181437ccd4204bf8488211f8a07629a6e123fa3e2e2ea74419dda8270bd54d31fdc33f51bcebc845d86c462da48211f9a04efcea74c9f84fc35eb27c58b3b01263e2abe62131f720e24d1d2726abb9d77780ef69344959bf3a0cce0732ebb0a871676c381e77264b9eef8875c9bea16ea07812d4f290a701b4ba256800a7219f6413b27b367ebbb23686ac044a5f44af63c400a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310b0221a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0ded0ae13e1f14e98e291b7bc725f590e0208cd8aee5029e86999268a01dfa95aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330043809") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ad5060ad206f9034fa09087686190c6eae842761bf3b6c0299e4573536cdf4a277e930ef5f1488cb88fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a056225dbe337930eae2e5053ccbde08ae2b963fafa0682f472b32189a8789c3b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212bf8402625a008084669fb790b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b0f4fb9a9c9970ba0b13b21c6605cd72939c2dd5c87b39aca58c85dbbc15a41496bab85a11306d082dd978e35055794105086b2eefd3cced77558a41c7475bb401baf50c87e1d5fb07a93a2d046add70bbe045de27ccad5be3e8e142febab17cf8488212bda03cdba57c5f1e6130e71dfccc752694035c8e9bbbfbb4bffc6fbacfa653a217dc8212bea09087686190c6eae842761bf3b6c0299e4573536cdf4a277e930ef5f1488cb88f803e96ae1c69b70b960305eccc4b09f9a8776698f26e4f0087820a1e0a9084e38a2f6aa9ba3617e610755529339dcafcde4abc6e3987ba76ca2fbadd5423353ac201a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ae9080ae608f90463a00cd675d1a4f59cea079078246ed698a21e8873ac3454dab0c6bc71ec74433dd0a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a005c8bb760447e318fc3c964a6a047a38074a8a8acd630f13e9cb6290f6c917cea0ba5df750e02baac2fe6eed41dccdda6ddd9ccbbcdbab113bcd20ce86955fbe70a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212c08402625a008229a884669fb793b90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8048fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6ca7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d206f8ae0fb860ad71337b4162caed9ffc51756eae682706a96abbc333e5f27767873bd3ff16b0a03b259db94947c8f1057d2dcc4caabf06847e9b5bccd843f040615d120008f1aa1833d22cac07e325b5d913a30e18248b77ca20cb942816d48c4c3e4d099fecf8488212bea09087686190c6eae842761bf3b6c0299e4573536cdf4a277e930ef5f1488cb88f8212bfa00cd675d1a4f59cea079078246ed698a21e8873ac3454dab0c6bc71ec74433dd080ca647eb84f4f9e06dbb5f17ce0bb252adf3fde1b61093c9db6b013f6eec88ebe2e41043bc19762ee36174b91d0383950cbadc8a51106cbc3d1ba5d874208ef9601a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0d78e550d546599d0e5d25a6280d42634285eeed5b68f25692b5ee8bfde9528a2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a005c8bb760447e318fc3c964a6a047a38074a8a8acd630f13e9cb6290f6c917cea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028212c18402625a008084669fb796b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860a60bfe671bd13c252b237b4222a361b19d89cfd5c58b6be3330a73b24b6d352afcbbf2cf300eeba1fe49fea61f76a21a03665f94ad81ec9bd474c937f4f143bc38f822843c41b61bd3ecd4844781bf8073ea0411cafaa9f77a421eeb4c0964a9f8488212bfa00cd675d1a4f59cea079078246ed698a21e8873ac3454dab0c6bc71ec74433dd08212c0a0d78e550d546599d0e5d25a6280d42634285eeed5b68f25692b5ee8bfde9528a280dfc0cd3dc16a57fe25955fb0df9304379e816659a89562c52a8a54e7534857f63f792f101cc37fae501197a4d7c59e9130fa65b790f35ea4b154ab75a9abd78b01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310f8231a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0ded0ae13e1f14e98e291b7bc725f590e0208cd8aee5029e86999268a01dfa95aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a03dc9ef066e7332efc09e4f620aab588d5465c1ed3b813c912928f1ffa44503a6a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba82244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330043809").to_vec() - ], - // checkpoint 2009 turnLength 3 target 0-2009 - vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a052c7f905de108f036db9b2315750c84d6c815f34b57595f27b8b4b849c7d7b4fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da05b4725d6a87fc261b989d40320187202c0a03ad275b6d3948bf6dcfca79386b1a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d08402625a008229a88466a227a7b90223d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2f048fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ffa7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b6d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b3e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc105f8ae0fb860946bd01663fe1ca7e95450b9199fa5253ccaad23be73d52793df5f453cb20de1ff51ab6186d39fbee1c63ce1b7581b550a740a785d66e71a586085f0c32ea8abca557bd7d39269b863e6d6cc94d316e53e221470adfea1fe00606ed0ae517232f8488207cea0e52d65a5e0d00748aa43600e083afd974407ce2054e7822a2f9c8a730f37316d8207cfa052c7f905de108f036db9b2315750c84d6c815f34b57595f27b8b4b849c7d7b4f80bb983b9893f0543f575bf6a348da8cc0d7ee769012d44b5bf0f2de1439fab0987ce564285e70ad18d66580082f14da2193a879e16efda9e0ff0524211a85533d00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0a9e00a112aeb3e91b86e95511018df2047cd9984ace5c86f085b77d55e3486dda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d18402625a00808466a227aab90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608c4d41718a421559d4c91b9285ffd53c001c528f2696f387802a508c427ef96d731e73b81c0e5679c887d51ba794ad8e0332a29b05d21f4a436b11a274cae8335ebd066d8ff7244a3902e583f4a3a4fe347805f42d9cf272db93c12eb19597baf8488207cfa052c7f905de108f036db9b2315750c84d6c815f34b57595f27b8b4b849c7d7b4f8207d0a0a9e00a112aeb3e91b86e95511018df2047cd9984ace5c86f085b77d55e3486dd800d29d848de30c1a0ad08ffd9ecdd67403f152fc8f1786617775e2db93ec3d5073c5d1f74725f091f39f09109341d05b0db02df59b2f5d7b825451b1b9c61a48501a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa01caa266e53b23711a9a0845389294f5e4a445697737e820dea91d743e62eca5da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d28402625a00808466a227adb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a76b14b8487cef51b8ee943af2386c8ef6fa60a56b375957d200c9b429f65a7206e85bd9965f63dd3f696bf722b1624e0c554ea89d453e56ccc528a050adad08143bd761ca80b7e9c172aa9c4d58b5e21ebd0e2c83f6ce0502855528d7acd7e4f8488207d0a0a9e00a112aeb3e91b86e95511018df2047cd9984ace5c86f085b77d55e3486dd8207d1a01caa266e53b23711a9a0845389294f5e4a445697737e820dea91d743e62eca5d80669abb81f040cc64c11e2bf33901138b269f0b720fa09d6ff00dc4628dbed8c75e6a1e41a90cf1d57fa472cbeb656168a3c6b800d8244324c072f6e3f30468e300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310880e1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea067ecb9b82d40265c310eaf00763b0fed54dfdf689ae4945f705b329f2b42b3dba0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a0c5efde1c8c860b17515432d64ac679d48902bea9421ecdc4e4156068c61fafb180a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b330053803") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa0f79e25ed6285179d4d82ea454695d38ba361acf43ea26f3fc5a8451016cb253fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d98402625a00808466a227c2b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860b93767a1a8005d8b3a0874bfc7808c59f3bc1b8444778307cb7d09bb3f8c43b32b5117df9c65ae4843d54fdbf40d382d1896574b3ad8a8f6acefb85686be61ce695c50e85232e3dc46a470e96e15f0a44282d41afd36ee9d6fe6ff6336f0f8eef8488207d7a0d79ba847026ce12a6ea07610d3eba41085267b91591e43dbdbb1d760a6ccc1bc8207d8a0f79e25ed6285179d4d82ea454695d38ba361acf43ea26f3fc5a8451016cb253f800477cca1964dd1bd73f4eb278d349cd6562a8106fbcbb541116770ea44cc605f4aeda07ba3389b0ffbf0e27d018c326d5a7871ef70490ba9c26afb8e6d60f5be01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0ef048929be37be72886019d6d983ea0296a0271243e09291fe2f84309b030a1ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207da8402625a00808466a227c5b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb86086872e2c9a12298026a3bf5c4575de14e383f741a5a46101c3892b2fd90a84ba775a11d5c03e2050884c3345ef7cfc4514e06f138c30bd7c54eeb1a7cd2b8ff4652701ed4b6051b681794fe4800efcbecd768d8de9f28df1eb04811e002b5240f8488207d8a0f79e25ed6285179d4d82ea454695d38ba361acf43ea26f3fc5a8451016cb253f8207d9a0ef048929be37be72886019d6d983ea0296a0271243e09291fe2f84309b030a1c801e2f5d814381948bc333a97e399a32b88d4b50a0419ef62931e983b5c501a9d267f56fb47de7c64cee7352326071167857213c8d3caa9987bef03e432c4b953a00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0bab45689cabc3dfe931b2b2b647ec15e80258192c1eea52a205563bce1b39139a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207db8402625a00808466a227c8b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a15832c489e5010025858454cfcf8de1d8625eb1a4a499efbed42e968a6f65439ae14f3b3b47101c085525ea25ef303a06717103df3a0913be834d8548570427acb6c4e5dffacdcbe323a006f609410c102ddcd053611833cae51b80dc524a60f8488207d9a0ef048929be37be72886019d6d983ea0296a0271243e09291fe2f84309b030a1c8207daa0bab45689cabc3dfe931b2b2b647ec15e80258192c1eea52a205563bce1b3913980c15c4f11222b5db54721e5826c8dd0842631845408609dc6ebede765c6fa4b557ecc12f574622012886811d864b86b1b620833334af52e1d773c40f49381ef0200a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310d00f1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea067ecb9b82d40265c310eaf00763b0fed54dfdf689ae4945f705b329f2b42b3dba0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a0c5efde1c8c860b17515432d64ac679d48902bea9421ecdc4e4156068c61fafb180a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b330053803").to_vec() - ], - // 2008 - vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a052c7f905de108f036db9b2315750c84d6c815f34b57595f27b8b4b849c7d7b4fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da05b4725d6a87fc261b989d40320187202c0a03ad275b6d3948bf6dcfca79386b1a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d08402625a008229a88466a227a7b90223d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2f048fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ffa7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b6d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b3e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc105f8ae0fb860946bd01663fe1ca7e95450b9199fa5253ccaad23be73d52793df5f453cb20de1ff51ab6186d39fbee1c63ce1b7581b550a740a785d66e71a586085f0c32ea8abca557bd7d39269b863e6d6cc94d316e53e221470adfea1fe00606ed0ae517232f8488207cea0e52d65a5e0d00748aa43600e083afd974407ce2054e7822a2f9c8a730f37316d8207cfa052c7f905de108f036db9b2315750c84d6c815f34b57595f27b8b4b849c7d7b4f80bb983b9893f0543f575bf6a348da8cc0d7ee769012d44b5bf0f2de1439fab0987ce564285e70ad18d66580082f14da2193a879e16efda9e0ff0524211a85533d00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0a9e00a112aeb3e91b86e95511018df2047cd9984ace5c86f085b77d55e3486dda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d18402625a00808466a227aab90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608c4d41718a421559d4c91b9285ffd53c001c528f2696f387802a508c427ef96d731e73b81c0e5679c887d51ba794ad8e0332a29b05d21f4a436b11a274cae8335ebd066d8ff7244a3902e583f4a3a4fe347805f42d9cf272db93c12eb19597baf8488207cfa052c7f905de108f036db9b2315750c84d6c815f34b57595f27b8b4b849c7d7b4f8207d0a0a9e00a112aeb3e91b86e95511018df2047cd9984ace5c86f085b77d55e3486dd800d29d848de30c1a0ad08ffd9ecdd67403f152fc8f1786617775e2db93ec3d5073c5d1f74725f091f39f09109341d05b0db02df59b2f5d7b825451b1b9c61a48501a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa01caa266e53b23711a9a0845389294f5e4a445697737e820dea91d743e62eca5da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d28402625a00808466a227adb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a76b14b8487cef51b8ee943af2386c8ef6fa60a56b375957d200c9b429f65a7206e85bd9965f63dd3f696bf722b1624e0c554ea89d453e56ccc528a050adad08143bd761ca80b7e9c172aa9c4d58b5e21ebd0e2c83f6ce0502855528d7acd7e4f8488207d0a0a9e00a112aeb3e91b86e95511018df2047cd9984ace5c86f085b77d55e3486dd8207d1a01caa266e53b23711a9a0845389294f5e4a445697737e820dea91d743e62eca5d80669abb81f040cc64c11e2bf33901138b269f0b720fa09d6ff00dc4628dbed8c75e6a1e41a90cf1d57fa472cbeb656168a3c6b800d8244324c072f6e3f30468e300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310880e1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea067ecb9b82d40265c310eaf00763b0fed54dfdf689ae4945f705b329f2b42b3dba0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a0c5efde1c8c860b17515432d64ac679d48902bea9421ecdc4e4156068c61fafb180a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b330053803") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa06160e6e45530a49dace82ba1afbd5dcf48935b0d2090cccd9bf47c44845f38e7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d78402625a00808466a227bcb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860893ded20ad4b9b5a1c1daee9dfee2737bff4b7cdceec843f770b71ab84eedddecfcc6caf6725e5416d69a44f433ed22814fb9e1119c52bc93ea90e6b98c836f6572ccdbce53a88ffe7efb7c41ed4a3738230587aa4d0a21570246929c612ab4cf8488207d5a073df87c23945fc6a74d8a01b98e951e97717b79518aeb760e443b99b1549f8fc8207d6a06160e6e45530a49dace82ba1afbd5dcf48935b0d2090cccd9bf47c44845f38e7805d589b186fa54113764c5538bc8313392eb38d8abb5af2b1c5e7996e518d91ef39963c53497c0bd54db8224a2d60bd12a4a1d225108972c3be767dbdc120535101a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0d79ba847026ce12a6ea07610d3eba41085267b91591e43dbdbb1d760a6ccc1bca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d88402625a00808466a227bfb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608b07302849be12f3e300e814465d8c2e56dc5724c1c077959ea910216addab2350cb5049826d99ae43052b23411a1c4b0e62f8683599781474841c690ee79c922665e3bde99c1d226b19c3aa98b36aa368a90616205cb0eedbd7ca534518e650f8488207d6a06160e6e45530a49dace82ba1afbd5dcf48935b0d2090cccd9bf47c44845f38e78207d7a0d79ba847026ce12a6ea07610d3eba41085267b91591e43dbdbb1d760a6ccc1bc80f7c8bf9ff3e2623dbce227b9ab7c6168151a45d3bac0e4e7a8f56c8521b5ecfe7271dcc6f956c435e7b77a6d3fc5a1b03c8d99230b3aeef32e62025a511941e400a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0f79e25ed6285179d4d82ea454695d38ba361acf43ea26f3fc5a8451016cb253fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a0759cb1ebd68321866dc7681de12480917ad2d8995c3b6608b2c9c4a103fc519da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207d98402625a00808466a227c2b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860b93767a1a8005d8b3a0874bfc7808c59f3bc1b8444778307cb7d09bb3f8c43b32b5117df9c65ae4843d54fdbf40d382d1896574b3ad8a8f6acefb85686be61ce695c50e85232e3dc46a470e96e15f0a44282d41afd36ee9d6fe6ff6336f0f8eef8488207d7a0d79ba847026ce12a6ea07610d3eba41085267b91591e43dbdbb1d760a6ccc1bc8207d8a0f79e25ed6285179d4d82ea454695d38ba361acf43ea26f3fc5a8451016cb253f800477cca1964dd1bd73f4eb278d349cd6562a8106fbcbb541116770ea44cc605f4aeda07ba3389b0ffbf0e27d018c326d5a7871ef70490ba9c26afb8e6d60f5be01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310d00f1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea067ecb9b82d40265c310eaf00763b0fed54dfdf689ae4945f705b329f2b42b3dba0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a0c5efde1c8c860b17515432d64ac679d48902bea9421ecdc4e4156068c61fafb180a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b330053803").to_vec() - ], - //checkpoint 2215 turnLength 5 target 0-2215 + + // checkpoint 1518 turnLength target 0-1500 vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca00bf9dee767e66678856f4c62a62515f54a39ebd7cb57ccb04ed25a22eff7065ba03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208988402625a008229a88466a229ffb90223d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2f048fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ffb2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be3d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b3e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc108f8ae0fb860a41bc57efe7ace714408c524070ad0e41bd17cb44f1367c23d64507edd2f94a804b86ad9f326e5fd7ff2646a77811d4013be08d719f6f24a81bf8ffae796c2c8238c79574ae05967517a1d194d27ae6f410c991e06d6431b490cc1826a9faa51f848820896a031f2ac651e45ab653e7a49287e7ca9754bea2e8e8dc87ea8062a6d43e4c9033f820897a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011807a5af307aee11ef5106ca8d8a1a8596e48dc2ffcc3d0797e6ad57cbe8da519a8224042fdabede179427ba5021fa621d46b0cb8fcf285ee78cb0ba18dc7e325e701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208998402625a00808466a22a02b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860ad4541e9b8a1c3d0def1a3f2d6d353c1d18f8c3d84822e29b413d5fa1fb77ee303add7c1441f7ac6a60e13f0b649483b105859b56e224feb6133a246fa60338e146d5747265994759964d4101d57914d4f3f00c380ff9b91dcb676851917880ff848820897a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011820898a0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0800e69a592db1d57d38c94298eff1ba8209e2a4b7b45b0c05b4d23c894b1c3d9285d446ee4d885a42a33b101c4ac7307f70b8173d5c89a67bafe8795ac3203449200a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0b1d096fbb6737a689f80e8e2f48811add6d9d6ec5cc631cb04a9a8dae0a562b4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282089a8402625a00808466a22a05b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a1f04d66e852eae33aeaf6a2b1a08b223f61e8a765894f9cdfbc6ac8aa0c04314df54fd0b98e14d2081c66fc5c49e162086853717104f1b5296adbba0b75643b00587131a47060e9e588ae216887576f41b6ea2e586615116bb46f6c40be812bf848820898a0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0820899a0b1d096fbb6737a689f80e8e2f48811add6d9d6ec5cc631cb04a9a8dae0a562b480c2efdccaf70cac8ec2926f52473dd4c3b23004bbde1cb1f61ddcfa06deae348d3aa81b0237708debe61dadf589e79d9520f2011e8f8812cdfd1a60af3f4d8b6e01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310d00f1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0273c6048b21e7d25636156a707b0be6ba081bcf7381f9b5019580f5aa70369e2a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a033ff9ba3990e4af75e9e1a6beb627bfc13f4bb7a788fb8ce61c8e90abacfcc5080a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32a44e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc130083805") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa04c83b66c9d766a11c5302ddf195e489be135a96d289a447b8f472cb38487d658a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208a78402625a00808466a22a2cb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608ff2f806af499b5704af0c43fd553e955d27ae7622090f38f4c8b3438f55341051badb02abb1c8ed74d18b5bed72de25127d60e3b4d0ca99b22354b8bca2357fafcb0755eb0d61e97fc7575a5ba27de548cd0017e8177df9c3f4db36e4db39b5f8488208a5a010b36eeee610eb8fd862ea3fd1a9fef0b60829ec6a8a9217f757f4595b9799968208a6a04c83b66c9d766a11c5302ddf195e489be135a96d289a447b8f472cb38487d658808db6c72c9f2d8eae719dd920ce14aad7c968fa58d14199554914bc1ee873a5c30d6bf530adcfc1bafe3d19248c9f4a0bdb728b309e6bab205749f1d0c4c0730c00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa01c0c14576d895ac5ee059ca87003dd354b0135ef20381f0864e3635212473bdea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208a88402625a00808466a22a2fb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608eb82ca384a2783e7b3eac15e62cede677ed7ffe7b65192682862888f53a41bd9e9668c67f8183dfe3492c4fe5ca706616262c999610710a5ddd126223edd5aca5dd88731df16503796931a56aabb1a747c23302f44fa504766bab674f756fbef8488208a6a04c83b66c9d766a11c5302ddf195e489be135a96d289a447b8f472cb38487d6588208a7a01c0c14576d895ac5ee059ca87003dd354b0135ef20381f0864e3635212473bde80282132396ca0067e53784fa76f1e54a5062d709d986ad67b3fc1af55c36e19cd5f34d00fbc8e28bd6efe75afd696f7476cd59dcef7f85e7d7e8d64441af3aa2c01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa07f472cd0045d5751fb839285cd34d38944031d12ca79f5cdb95fc803fe314780a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208a98402625a00808466a22a32b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608bdab2df74f889d68d125ea0bb536413fab26e9e251a0b44c8b4097943ae811ce9384fdad4e6f81880717fa57d31bac715ee8e18e39d5204b332ee90d384ccb92b593bcff2256a2f013623e2c69ef8e8e04218de33b33ef1a725731e2a25ab49f8488208a7a01c0c14576d895ac5ee059ca87003dd354b0135ef20381f0864e3635212473bde8208a8a07f472cd0045d5751fb839285cd34d38944031d12ca79f5cdb95fc803fe31478080521712094a69465ab786abee685ba960e6dc814b3a9ddd7168ddf3a8b209f57720f23cf2e5cd2b3ff2f01887cad5b3fa63dce7f937bbabef5ebe8339aca3f3f300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a0000000000000000000000000000000000000000000000000000000000000000012031098111a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0273c6048b21e7d25636156a707b0be6ba081bcf7381f9b5019580f5aa70369e2a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a033ff9ba3990e4af75e9e1a6beb627bfc13f4bb7a788fb8ce61c8e90abacfcc5080a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32a44e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc130083805").to_vec() + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b61b0a88090a8509f90482a09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a769a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0a4ef99b2f92fcf112f19fc275bcae30fc1a37b61070d1c05e7d8e46b8e808f42a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dc8402625a00808467d7be97b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926908f8ae0fb860abd36729a99a7a3e957e01525874db2cf2e4f35a9e1800ab422fe0cf03babfcbfee210ce61808e31c906c1a28301103b14eb7094777ee60d7373fb13be17ddeb1eb79930a6212f10947fed157b1acb4612e51c13ccebfe688f1819809112cd10f8488205daa03ca8f28ad9e7b92ba1e308f93ec7af270c2742d911d01812739a48e4ed98beb08205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a76980b62e41161cf2b31ac78ac9c93625f74601bffee172c3beb72ac0085d6f5f5a771005d058923a2babd7bac693258b3fee81aa36b027028923fbae2fb2a5a781c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a075dbbe77d365565f739f0f9725ed1fb83ae08d31bdfcbe83844341f8b6ebec76a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dd8402625a00808467d7be98b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb8609820e8c6b0271e4692c24207bf2f48a17c5c9f358169162ceddae29889de416d01812d65e7697f12856ef19d6bc83d4b137ce93bd937bfe2cbef141bd50c5849d3e07a25518cc7b4fb310e509c99efbb74f44d91f1749f21623c4002f3a849e5f8488205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a7698205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8092908f87a47fd452b13a53d775fa2fd4ac267318c50dd72103d81a499f1b4171324513520f29a6c0e13515cd2e92e15338e84a7cf53f5061d10acdf1293349d301a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0f3550e781e783369df120040a4abf7bd9dd5f8f39f0f8544fdffdedf43531c87a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205de8402625a00808467d7be9ab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86082a95e5c91809809e030a6846650011a287162783c98bf7bb389118d1c0990de451e74e88dc4abf9fef0d86680352ec210c9c26fd418ec0ff16a626980ee41dfb10e4021069e4111392f31abfdcdfecaa4e639508afed5884f3359779b22ff9df8488205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8205dda0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8804896f2df88ff6ff7e2f5284c2f5a98c94460c28a9adb701dfe388af57498c42d7f469cde54341978f0cbcf941e7e09f5a8682f0b016865cd0957aa0e64a933cf00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310e8071a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006") .to_vec(), + // 1518 + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212a4190af6060af306f90370a02916367e18c4d4f1436adb637e2f1ae896ebc22a400e805f11e93baed4d7d524a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a018f3387c16e846e7b551b4fb9aae1536fadbacde50aa67d5703e549bda258831a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205ee8402625a00808467d7beb2b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb8608095142b303c85215d5ffdf7fda5e82404cbc75c35d58127ee0552c3c4c9a2084cb7fb6fa4caf569aaafa929dd61fc5c1611e1eed348aafb01e1558df5e8f0978ef2b599d1337ac912eff652fce1d43aa155e416807d1b00ddb3959551537cfff8488205eca07dc2cb5e5f172f6f0882f52d83dabe4b539ae6148ddfc31e7f82d31bd4743fa68205eda02916367e18c4d4f1436adb637e2f1ae896ebc22a400e805f11e93baed4d7d52480206172e60d7cd0aacf740232c10f25a5e7d0edf2b620b9cb0dcf09729292f914450155f8e62169332d0aa1600352900010227f5200727470720d58aa8bb1e1c701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a050037868973ee5d65f44deae06246396b70234c5413db3fe2de0c47649a11650a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04173d3f3052577ce2f8abc5ab57fcd5494942c47fb2dd9e30bc1890acdb60f57a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205ef8402625a00808467d7beb3b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860b7421eac082dca08278ef8521c8f28cfe24a5f75c4cd856c3f8b1804fcc19c927db59030222c1a96bdc376b479edad2c15cbab9aee9255cbe5fabe2e7c065d817c773af64d801a26b3350d5a7d48587c78029ec6a227acd25f957f3b5fcb65e5f8488205eda02916367e18c4d4f1436adb637e2f1ae896ebc22a400e805f11e93baed4d7d5248205eea050037868973ee5d65f44deae06246396b70234c5413db3fe2de0c47649a11650809388ee7618d63d443f8cdc18558c70bc1e8af93f8f9383822d82a356f4c36e5845f489433ac610c515fb361c22d7c38988f2d1572de152d0fed41709f9a2fd9001a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0b07401491399c50cc54c6b6d6b6d84270a5c7d046e083b8f49881edd77a39e14a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0a85d162b8996ab27e9e284726ee8348ad1d298c38e57af5e23d092d8f5526c10a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205f08402625a00808467d7beb5b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860aaab4caf01a26863c632753a765bef6b06dfd772a8c87bf81e10d2dd55ccd8af7c2798697fd3c253146f896185f0a52200d330ccad7ea82ed72a4da6682c144431e770c8ed8b719855dc01c4ea650043483e1d9bac928b8ff53f8abf945339e3f8488205eea050037868973ee5d65f44deae06246396b70234c5413db3fe2de0c47649a116508205efa0b07401491399c50cc54c6b6d6b6d84270a5c7d046e083b8f49881edd77a39e1480bdeca409bd5a9eb693a52a980f02a9f213cc3cb4c2f49eb45fe6eca4d1792b2317010aee8ce875fe06e1c6316cd5872ce48b88d90b466c42d5a280dcb9e6e03d00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310dc0b1a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006").to_vec() ], - //2214 vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca00bf9dee767e66678856f4c62a62515f54a39ebd7cb57ccb04ed25a22eff7065ba03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208988402625a008229a88466a229ffb90223d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2f048fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ffb2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be3d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b3e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc108f8ae0fb860a41bc57efe7ace714408c524070ad0e41bd17cb44f1367c23d64507edd2f94a804b86ad9f326e5fd7ff2646a77811d4013be08d719f6f24a81bf8ffae796c2c8238c79574ae05967517a1d194d27ae6f410c991e06d6431b490cc1826a9faa51f848820896a031f2ac651e45ab653e7a49287e7ca9754bea2e8e8dc87ea8062a6d43e4c9033f820897a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011807a5af307aee11ef5106ca8d8a1a8596e48dc2ffcc3d0797e6ad57cbe8da519a8224042fdabede179427ba5021fa621d46b0cb8fcf285ee78cb0ba18dc7e325e701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208998402625a00808466a22a02b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860ad4541e9b8a1c3d0def1a3f2d6d353c1d18f8c3d84822e29b413d5fa1fb77ee303add7c1441f7ac6a60e13f0b649483b105859b56e224feb6133a246fa60338e146d5747265994759964d4101d57914d4f3f00c380ff9b91dcb676851917880ff848820897a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011820898a0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0800e69a592db1d57d38c94298eff1ba8209e2a4b7b45b0c05b4d23c894b1c3d9285d446ee4d885a42a33b101c4ac7307f70b8173d5c89a67bafe8795ac3203449200a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0b1d096fbb6737a689f80e8e2f48811add6d9d6ec5cc631cb04a9a8dae0a562b4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282089a8402625a00808466a22a05b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a1f04d66e852eae33aeaf6a2b1a08b223f61e8a765894f9cdfbc6ac8aa0c04314df54fd0b98e14d2081c66fc5c49e162086853717104f1b5296adbba0b75643b00587131a47060e9e588ae216887576f41b6ea2e586615116bb46f6c40be812bf848820898a0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0820899a0b1d096fbb6737a689f80e8e2f48811add6d9d6ec5cc631cb04a9a8dae0a562b480c2efdccaf70cac8ec2926f52473dd4c3b23004bbde1cb1f61ddcfa06deae348d3aa81b0237708debe61dadf589e79d9520f2011e8f8812cdfd1a60af3f4d8b6e01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310d00f1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0273c6048b21e7d25636156a707b0be6ba081bcf7381f9b5019580f5aa70369e2a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a033ff9ba3990e4af75e9e1a6beb627bfc13f4bb7a788fb8ce61c8e90abacfcc5080a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32a44e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc130083805") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa010b36eeee610eb8fd862ea3fd1a9fef0b60829ec6a8a9217f757f4595b979996a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208a68402625a00808466a22a29b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a679406d91eb9bc53857d50bfc12077371071b1473cfe4ede4016745fbdaf827a42ba7771b88e76e48b5ed027d9ef4f3126386b84dfd011f66506ea063b6b9f6e961e8d4cac5beafa34b5692b0aa45c80bfef8abe5ecb1be81434b55caa26a09f8488208a4a0860594f9818bfca1851dfd23d0a567e39ba5fc4631dac97a4d2d1f99d0420d0b8208a5a010b36eeee610eb8fd862ea3fd1a9fef0b60829ec6a8a9217f757f4595b97999680d54103bebc9a230cc3f1034869ea17dadc3af3be04031eacceff13864e33ec927514d121e198968d2cf5776aac920f3b771a762662b56a387f0844f6a426172000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa04c83b66c9d766a11c5302ddf195e489be135a96d289a447b8f472cb38487d658a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208a78402625a00808466a22a2cb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608ff2f806af499b5704af0c43fd553e955d27ae7622090f38f4c8b3438f55341051badb02abb1c8ed74d18b5bed72de25127d60e3b4d0ca99b22354b8bca2357fafcb0755eb0d61e97fc7575a5ba27de548cd0017e8177df9c3f4db36e4db39b5f8488208a5a010b36eeee610eb8fd862ea3fd1a9fef0b60829ec6a8a9217f757f4595b9799968208a6a04c83b66c9d766a11c5302ddf195e489be135a96d289a447b8f472cb38487d658808db6c72c9f2d8eae719dd920ce14aad7c968fa58d14199554914bc1ee873a5c30d6bf530adcfc1bafe3d19248c9f4a0bdb728b309e6bab205749f1d0c4c0730c00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa01c0c14576d895ac5ee059ca87003dd354b0135ef20381f0864e3635212473bdea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208a88402625a00808466a22a2fb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608eb82ca384a2783e7b3eac15e62cede677ed7ffe7b65192682862888f53a41bd9e9668c67f8183dfe3492c4fe5ca706616262c999610710a5ddd126223edd5aca5dd88731df16503796931a56aabb1a747c23302f44fa504766bab674f756fbef8488208a6a04c83b66c9d766a11c5302ddf195e489be135a96d289a447b8f472cb38487d6588208a7a01c0c14576d895ac5ee059ca87003dd354b0135ef20381f0864e3635212473bde80282132396ca0067e53784fa76f1e54a5062d709d986ad67b3fc1af55c36e19cd5f34d00fbc8e28bd6efe75afd696f7476cd59dcef7f85e7d7e8d64441af3aa2c01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a0000000000000000000000000000000000000000000000000000000000000000012031098111a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0273c6048b21e7d25636156a707b0be6ba081bcf7381f9b5019580f5aa70369e2a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a033ff9ba3990e4af75e9e1a6beb627bfc13f4bb7a788fb8ce61c8e90abacfcc5080a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32a44e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc130083805").to_vec() + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b61b0a88090a8509f90482a09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a769a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0a4ef99b2f92fcf112f19fc275bcae30fc1a37b61070d1c05e7d8e46b8e808f42a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dc8402625a00808467d7be97b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926908f8ae0fb860abd36729a99a7a3e957e01525874db2cf2e4f35a9e1800ab422fe0cf03babfcbfee210ce61808e31c906c1a28301103b14eb7094777ee60d7373fb13be17ddeb1eb79930a6212f10947fed157b1acb4612e51c13ccebfe688f1819809112cd10f8488205daa03ca8f28ad9e7b92ba1e308f93ec7af270c2742d911d01812739a48e4ed98beb08205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a76980b62e41161cf2b31ac78ac9c93625f74601bffee172c3beb72ac0085d6f5f5a771005d058923a2babd7bac693258b3fee81aa36b027028923fbae2fb2a5a781c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a075dbbe77d365565f739f0f9725ed1fb83ae08d31bdfcbe83844341f8b6ebec76a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dd8402625a00808467d7be98b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb8609820e8c6b0271e4692c24207bf2f48a17c5c9f358169162ceddae29889de416d01812d65e7697f12856ef19d6bc83d4b137ce93bd937bfe2cbef141bd50c5849d3e07a25518cc7b4fb310e509c99efbb74f44d91f1749f21623c4002f3a849e5f8488205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a7698205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8092908f87a47fd452b13a53d775fa2fd4ac267318c50dd72103d81a499f1b4171324513520f29a6c0e13515cd2e92e15338e84a7cf53f5061d10acdf1293349d301a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0f3550e781e783369df120040a4abf7bd9dd5f8f39f0f8544fdffdedf43531c87a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205de8402625a00808467d7be9ab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86082a95e5c91809809e030a6846650011a287162783c98bf7bb389118d1c0990de451e74e88dc4abf9fef0d86680352ec210c9c26fd418ec0ff16a626980ee41dfb10e4021069e4111392f31abfdcdfecaa4e639508afed5884f3359779b22ff9df8488205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8205dda0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8804896f2df88ff6ff7e2f5284c2f5a98c94460c28a9adb701dfe388af57498c42d7f469cde54341978f0cbcf941e7e09f5a8682f0b016865cd0957aa0e64a933cf00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310e8071a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006") .to_vec(), + // 1517 + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212a4190af6060af306f90370a07dc2cb5e5f172f6f0882f52d83dabe4b539ae6148ddfc31e7f82d31bd4743fa6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a09e287ce14222986335f3738dc3eaae3b28d9acd494e253579a09ccd50c6cb2cda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205ed8402625a00808467d7beb0b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86095bcb337da231a21fb86a80ae3ce5f51426bb2634909d62b8cfd39d9863118c83ae25b5605a8a49e59071fdf7632d49b137208ac04485a493cbcb2d8d8ba9bab9a7a89e80ee26a564cceb1128da50183b45c63517dd9e0f8158d63b9911ebc7ef8488205eba090f25cd8d97e5742121b30df2bceddd428d1964ca36010295bb7c99bd010f0bf8205eca07dc2cb5e5f172f6f0882f52d83dabe4b539ae6148ddfc31e7f82d31bd4743fa680151c5291b6c0646c7820bb9ed7c2c22baf1ec47a29b4b7533d4c622206b3be4c1f2c7a6dc8749066a6081a56199333262c3b01705afc60739ec359b7d4108e0e00a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a02916367e18c4d4f1436adb637e2f1ae896ebc22a400e805f11e93baed4d7d524a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a018f3387c16e846e7b551b4fb9aae1536fadbacde50aa67d5703e549bda258831a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205ee8402625a00808467d7beb2b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb8608095142b303c85215d5ffdf7fda5e82404cbc75c35d58127ee0552c3c4c9a2084cb7fb6fa4caf569aaafa929dd61fc5c1611e1eed348aafb01e1558df5e8f0978ef2b599d1337ac912eff652fce1d43aa155e416807d1b00ddb3959551537cfff8488205eca07dc2cb5e5f172f6f0882f52d83dabe4b539ae6148ddfc31e7f82d31bd4743fa68205eda02916367e18c4d4f1436adb637e2f1ae896ebc22a400e805f11e93baed4d7d52480206172e60d7cd0aacf740232c10f25a5e7d0edf2b620b9cb0dcf09729292f914450155f8e62169332d0aa1600352900010227f5200727470720d58aa8bb1e1c701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a050037868973ee5d65f44deae06246396b70234c5413db3fe2de0c47649a11650a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04173d3f3052577ce2f8abc5ab57fcd5494942c47fb2dd9e30bc1890acdb60f57a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205ef8402625a00808467d7beb3b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860b7421eac082dca08278ef8521c8f28cfe24a5f75c4cd856c3f8b1804fcc19c927db59030222c1a96bdc376b479edad2c15cbab9aee9255cbe5fabe2e7c065d817c773af64d801a26b3350d5a7d48587c78029ec6a227acd25f957f3b5fcb65e5f8488205eda02916367e18c4d4f1436adb637e2f1ae896ebc22a400e805f11e93baed4d7d5248205eea050037868973ee5d65f44deae06246396b70234c5413db3fe2de0c47649a11650809388ee7618d63d443f8cdc18558c70bc1e8af93f8f9383822d82a356f4c36e5845f489433ac610c515fb361c22d7c38988f2d1572de152d0fed41709f9a2fd9001a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310dc0b1a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006").to_vec() ], - //2216 vec![ - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca00bf9dee767e66678856f4c62a62515f54a39ebd7cb57ccb04ed25a22eff7065ba03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208988402625a008229a88466a229ffb90223d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2f048fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ffb2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be3d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b3e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc108f8ae0fb860a41bc57efe7ace714408c524070ad0e41bd17cb44f1367c23d64507edd2f94a804b86ad9f326e5fd7ff2646a77811d4013be08d719f6f24a81bf8ffae796c2c8238c79574ae05967517a1d194d27ae6f410c991e06d6431b490cc1826a9faa51f848820896a031f2ac651e45ab653e7a49287e7ca9754bea2e8e8dc87ea8062a6d43e4c9033f820897a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011807a5af307aee11ef5106ca8d8a1a8596e48dc2ffcc3d0797e6ad57cbe8da519a8224042fdabede179427ba5021fa621d46b0cb8fcf285ee78cb0ba18dc7e325e701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208998402625a00808466a22a02b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860ad4541e9b8a1c3d0def1a3f2d6d353c1d18f8c3d84822e29b413d5fa1fb77ee303add7c1441f7ac6a60e13f0b649483b105859b56e224feb6133a246fa60338e146d5747265994759964d4101d57914d4f3f00c380ff9b91dcb676851917880ff848820897a0c13597cb89679cf0b6f2ba3e0ae0781e5ec72c8f839c11083d6704d765137011820898a0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0800e69a592db1d57d38c94298eff1ba8209e2a4b7b45b0c05b4d23c894b1c3d9285d446ee4d885a42a33b101c4ac7307f70b8173d5c89a67bafe8795ac3203449200a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0b1d096fbb6737a689f80e8e2f48811add6d9d6ec5cc631cb04a9a8dae0a562b4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282089a8402625a00808466a22a05b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb860a1f04d66e852eae33aeaf6a2b1a08b223f61e8a765894f9cdfbc6ac8aa0c04314df54fd0b98e14d2081c66fc5c49e162086853717104f1b5296adbba0b75643b00587131a47060e9e588ae216887576f41b6ea2e586615116bb46f6c40be812bf848820898a0ac8875032a5bec1f6b3d2e91c9f082e6a8ecbd326126a1a3bc6ecb14c3a4c1d0820899a0b1d096fbb6737a689f80e8e2f48811add6d9d6ec5cc631cb04a9a8dae0a562b480c2efdccaf70cac8ec2926f52473dd4c3b23004bbde1cb1f61ddcfa06deae348d3aa81b0237708debe61dadf589e79d9520f2011e8f8812cdfd1a60af3f4d8b6e01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310d00f1a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0273c6048b21e7d25636156a707b0be6ba081bcf7381f9b5019580f5aa70369e2a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a033ff9ba3990e4af75e9e1a6beb627bfc13f4bb7a788fb8ce61c8e90abacfcc5080a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32a44e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc130083805") .to_vec(), - hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d91e0ad5060ad206f9034fa01c0c14576d895ac5ee059ca87003dd354b0135ef20381f0864e3635212473bdea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208a88402625a00808466a22a2fb90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608eb82ca384a2783e7b3eac15e62cede677ed7ffe7b65192682862888f53a41bd9e9668c67f8183dfe3492c4fe5ca706616262c999610710a5ddd126223edd5aca5dd88731df16503796931a56aabb1a747c23302f44fa504766bab674f756fbef8488208a6a04c83b66c9d766a11c5302ddf195e489be135a96d289a447b8f472cb38487d6588208a7a01c0c14576d895ac5ee059ca87003dd354b0135ef20381f0864e3635212473bde80282132396ca0067e53784fa76f1e54a5062d709d986ad67b3fc1af55c36e19cd5f34d00fbc8e28bd6efe75afd696f7476cd59dcef7f85e7d7e8d64441af3aa2c01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa07f472cd0045d5751fb839285cd34d38944031d12ca79f5cdb95fc803fe314780a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208a98402625a00808466a22a32b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608bdab2df74f889d68d125ea0bb536413fab26e9e251a0b44c8b4097943ae811ce9384fdad4e6f81880717fa57d31bac715ee8e18e39d5204b332ee90d384ccb92b593bcff2256a2f013623e2c69ef8e8e04218de33b33ef1a725731e2a25ab49f8488208a7a01c0c14576d895ac5ee059ca87003dd354b0135ef20381f0864e3635212473bde8208a8a07f472cd0045d5751fb839285cd34d38944031d12ca79f5cdb95fc803fe31478080521712094a69465ab786abee685ba960e6dc814b3a9ddd7168ddf3a8b209f57720f23cf2e5cd2b3ff2f01887cad5b3fa63dce7f937bbabef5ebe8339aca3f3f300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0208333d00c93f838c88a8774b75d999cd8f21f93a4389154a9ff169649c1fd04a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada02c7aa1d61f17c0020c7ed842efa5d227285f8399e151111a12ba247772d0c8eca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028208aa8402625a00808466a22a35b90111d98301040c846765746889676f312e32312e3132856c696e75780000e0299c2ff8ae0fb8608fed9056be3ee0ee5ad5535eb48716ee25b94fdf9cd27b1a113833e99eb0bcf5cb5ae0e4b7d981c19e051e0a54fed48605bd2abaf4b015cf97b7d5d52009ba6cdc8e5fd3bd1db9d5e9b4e2ba79eb51dfd1e630ea47d6d32e12cc038a96615c25f8488208a8a07f472cd0045d5751fb839285cd34d38944031d12ca79f5cdb95fc803fe3147808208a9a0208333d00c93f838c88a8774b75d999cd8f21f93a4389154a9ff169649c1fd0480368b6310d8c27fa2ead40a3e06977f4caa64bd6386db3c84ac5aec106c3d06b6155cc690eb7c12f3f9c5166393d216c208c98f4c25f7184bc215a58e2a0c226300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a0000000000000000000000000000000000000000000000000000000000000000012031098111a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea0273c6048b21e7d25636156a707b0be6ba081bcf7381f9b5019580f5aa70369e2a0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a033ff9ba3990e4af75e9e1a6beb627bfc13f4bb7a788fb8ce61c8e90abacfcc5080a0ad34ceb1c793eb6ab9036cecf8c0a1239b9edba58f94890173098a17d9b7693ba0f34dd8753d794952d0235df0a1d2b415d55ef60c393c5a197281bfc8a5bdf681a00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa076094ead9021f5472bb12b03aeb521e09d71029dfa5dac90afa7cb44cbdfc5bd80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a0579a97aa89dbeb98396792baa31c4a7ea8e2f41da084140f07bb4bd655b72dd5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2244b2e42bc54d19116d2348ac83461e2e0915d508adaf6af61cafa835c72fe6e9feb717dd4ddf95424e29b6384bd27c0d6c9c616d15cf7fdf0f2f9fc1a4fa9197251b196be32244d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32244e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc12a448fdaaa7e6631e438625ca25c857a3727ea28e565a8c9cbefc0c78b71cdf18eeb8206601e665778faa6b4dd23740f8dd8eeb0c7bcc8f49a1c900396aee02d1639ab7897ff2a44a7876ea32e7a748c697d01345145485561305b24b3f0af694696c1b453b1174a1ea8c1135c247eb168864c9731254bc2f28077f99fe195b477ee699d79f40468aa30c2b62a44d9a13701eafb76870cb220843b8c6476824bfa15b822666ed599d40aa3bc13feb3ca5d5bc9d3ebe23d3460078c755a5ddbd85a0a58a217860fb0ea675b708a82b288f4b32a44e04db2de85453e0936b441c339a26d10cfa71b50996157a84dd67ec797a9ea61e4023c01d5bb28cce995c4c8329900b7b96e5402c02696f6f7b62972af4ee81f3f58afc130083805").to_vec() + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b61b0a88090a8509f90482a09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a769a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0a4ef99b2f92fcf112f19fc275bcae30fc1a37b61070d1c05e7d8e46b8e808f42a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dc8402625a00808467d7be97b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926908f8ae0fb860abd36729a99a7a3e957e01525874db2cf2e4f35a9e1800ab422fe0cf03babfcbfee210ce61808e31c906c1a28301103b14eb7094777ee60d7373fb13be17ddeb1eb79930a6212f10947fed157b1acb4612e51c13ccebfe688f1819809112cd10f8488205daa03ca8f28ad9e7b92ba1e308f93ec7af270c2742d911d01812739a48e4ed98beb08205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a76980b62e41161cf2b31ac78ac9c93625f74601bffee172c3beb72ac0085d6f5f5a771005d058923a2babd7bac693258b3fee81aa36b027028923fbae2fb2a5a781c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a075dbbe77d365565f739f0f9725ed1fb83ae08d31bdfcbe83844341f8b6ebec76a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205dd8402625a00808467d7be98b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb8609820e8c6b0271e4692c24207bf2f48a17c5c9f358169162ceddae29889de416d01812d65e7697f12856ef19d6bc83d4b137ce93bd937bfe2cbef141bd50c5849d3e07a25518cc7b4fb310e509c99efbb74f44d91f1749f21623c4002f3a849e5f8488205dba09e934ca2c1ee21a9d742ec3b54cdd6e9439c6d5487db4958c798282429b2a7698205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8092908f87a47fd452b13a53d775fa2fd4ac267318c50dd72103d81a499f1b4171324513520f29a6c0e13515cd2e92e15338e84a7cf53f5061d10acdf1293349d301a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0f3550e781e783369df120040a4abf7bd9dd5f8f39f0f8544fdffdedf43531c87a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205de8402625a00808467d7be9ab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86082a95e5c91809809e030a6846650011a287162783c98bf7bb389118d1c0990de451e74e88dc4abf9fef0d86680352ec210c9c26fd418ec0ff16a626980ee41dfb10e4021069e4111392f31abfdcdfecaa4e639508afed5884f3359779b22ff9df8488205dca035958f2be113f6d0ae356b704aae8b7a8987e7f4118a6dbb5d4a14e2db8e32fe8205dda0dd8211ffdbce72465cb42d03b61a37c2a4f208f3c20a3263d59e4adfe9455dc8804896f2df88ff6ff7e2f5284c2f5a98c94460c28a9adb701dfe388af57498c42d7f469cde54341978f0cbcf941e7e09f5a8682f0b016865cd0957aa0e64a933cf00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310e8071a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006") .to_vec(), + // 1519 + hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212a4190af6060af306f90370a050037868973ee5d65f44deae06246396b70234c5413db3fe2de0c47649a11650a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04173d3f3052577ce2f8abc5ab57fcd5494942c47fb2dd9e30bc1890acdb60f57a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205ef8402625a00808467d7beb3b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860b7421eac082dca08278ef8521c8f28cfe24a5f75c4cd856c3f8b1804fcc19c927db59030222c1a96bdc376b479edad2c15cbab9aee9255cbe5fabe2e7c065d817c773af64d801a26b3350d5a7d48587c78029ec6a227acd25f957f3b5fcb65e5f8488205eda02916367e18c4d4f1436adb637e2f1ae896ebc22a400e805f11e93baed4d7d5248205eea050037868973ee5d65f44deae06246396b70234c5413db3fe2de0c47649a11650809388ee7618d63d443f8cdc18558c70bc1e8af93f8f9383822d82a356f4c36e5845f489433ac610c515fb361c22d7c38988f2d1572de152d0fed41709f9a2fd9001a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a0b07401491399c50cc54c6b6d6b6d84270a5c7d046e083b8f49881edd77a39e14a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0a85d162b8996ab27e9e284726ee8348ad1d298c38e57af5e23d092d8f5526c10a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205f08402625a00808467d7beb5b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860aaab4caf01a26863c632753a765bef6b06dfd772a8c87bf81e10d2dd55ccd8af7c2798697fd3c253146f896185f0a52200d330ccad7ea82ed72a4da6682c144431e770c8ed8b719855dc01c4ea650043483e1d9bac928b8ff53f8abf945339e3f8488205eea050037868973ee5d65f44deae06246396b70234c5413db3fe2de0c47649a116508205efa0b07401491399c50cc54c6b6d6b6d84270a5c7d046e083b8f49881edd77a39e1480bdeca409bd5a9eb693a52a980f02a9f213cc3cb4c2f49eb45fe6eca4d1792b2317010aee8ce875fe06e1c6316cd5872ce48b88d90b466c42d5a280dcb9e6e03d00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550af6060af306f90370a05eee627a59727ad6bc3e1d350fbbc4db4ee2217a9c98806d6ea7b694683bac2ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0433813ae12bc4282b81a4caec4c34e28c173a91b03bb0d73ea00f109e4961ff3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028205f18402625a00808467d7beb6b90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb8609595f1e7959f53b0c5462a2ae5a3c475542c78f4171b1920d8bb59d13ca9582d0e2391f306c73f3ac46b165bb153fabd0178c3dc3fd13117fe420bc1ee87cf42b4b221fab100372567d2efd786ea5e977b85928f61c5e01cb854c756c2b221fdf8488205efa0b07401491399c50cc54c6b6d6b6d84270a5c7d046e083b8f49881edd77a39e148205f0a05eee627a59727ad6bc3e1d350fbbc4db4ee2217a9c98806d6ea7b694683bac2e803dab34d63120928d1a77ac2619bcea075759e8a3116af81b468b3a95bdb5e3a23376229c1e739e866719285d18756cbb03d9589991b7ae5bb5ae9bcb71d2256e00a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855120310dc0b1a448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71981a44a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa081a44d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e91a44e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926922448fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb71982244a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa082244d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e92244e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926928083006").to_vec() ], + + ] } + + fn success_create_client(&self) -> (Vec, Vec, u64, u64) { + let client_state = hex!("0a272f6962632e6c69676874636c69656e74732e7061726c69612e76312e436c69656e7453746174651253088f4e1214aa43d337145e8930d01cb4e60abf6595c692921e1a201ee222554989dda120e26ecacf756fe1235cd8d726706b57517715dde4f0c900220410dbfc012a040880a305320410c0843d420410001815").to_vec(); + let consensus_state = hex!("0a2a2f6962632e6c69676874636c69656e74732e7061726c69612e76312e436f6e73656e7375735374617465126d0a20e0cecaaf108b444908180c46807c7891991377cc43669273e779c5c0c5cbd77c10c88db8afd6321a204e013ddc6238ab26c478ce824c78b5938efa2d4e5eb73e9c9a3172ffca99c7ee22203acf3e01a40afb77b433f11eb9a311cbc5326957d5d3e9e9428439d17b76ead0").to_vec(); + (client_state, consensus_state, 32347, 1741171853000) + } } diff --git a/light-client/src/fixture/mod.rs b/light-client/src/fixture/mod.rs index 733b6a33..cf814bfc 100644 --- a/light-client/src/fixture/mod.rs +++ b/light-client/src/fixture/mod.rs @@ -5,6 +5,7 @@ use crate::misc::{Address, ChainId, Hash, Validators}; use alloc::boxed::Box; use alloc::vec::Vec; +use crate::fork_spec::{ForkSpec, HeightOrTimestamp}; use parlia_ibc_proto::ibc::lightclients::parlia::v1::EthHeader; pub mod localnet; @@ -37,6 +38,7 @@ pub trait Network { fn success_update_client_epoch_input(&self) -> UpdateClientEpochInput; fn success_update_client_continuous_input(&self) -> Vec>>; fn error_update_client_non_neighboring_epoch_input(&self) -> Vec; + fn success_create_client(&self) -> (Vec, Vec, u64, u64); } pub struct UpdateClientNonEpochInput { @@ -44,7 +46,6 @@ pub struct UpdateClientNonEpochInput { pub trusted_height: u64, pub trusted_current_validators_hash: Hash, pub trusted_previous_validators_hash: Hash, - pub expected_storage_root: Hash, } pub struct UpdateClientEpochInput { @@ -54,7 +55,6 @@ pub struct UpdateClientEpochInput { pub trusted_previous_validators_hash: Hash, pub new_current_validators_hash: Hash, pub new_previous_validators_hash: Hash, - pub expected_storage_root: Hash, } pub fn localnet() -> Box { @@ -62,7 +62,36 @@ pub fn localnet() -> Box { } pub fn decode_header(rlp_header: Vec) -> ETHHeader { - EthHeader { header: rlp_header }.try_into().unwrap() + let mut header: ETHHeader = EthHeader { header: rlp_header }.try_into().unwrap(); + header + .set_boundary_epochs(&[fork_spec_after_pascal(), fork_spec_after_lorentz()]) + .unwrap(); + header } -// TODO Modify testnet / mainnet after each HF released +pub fn fork_spec_after_pascal() -> ForkSpec { + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(0), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 64, + } +} + +pub fn fork_spec_after_lorentz() -> ForkSpec { + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(1), + additional_header_item_count: 1, + epoch_length: 500, + max_turn_length: 64, + } +} + +pub fn fork_spec_after_maxwell() -> ForkSpec { + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(2), + additional_header_item_count: 1, + epoch_length: 1000, + max_turn_length: 64, + } +} diff --git a/light-client/src/fork_spec.rs b/light-client/src/fork_spec.rs new file mode 100644 index 00000000..c59db316 --- /dev/null +++ b/light-client/src/fork_spec.rs @@ -0,0 +1,749 @@ +use crate::errors::Error; +use crate::misc::BlockNumber; +use parlia_ibc_proto::ibc::lightclients::parlia::v1::fork_spec::HeightOrTimestamp as RawHeightOrTimestamp; +use parlia_ibc_proto::ibc::lightclients::parlia::v1::ForkSpec as RawForkSpec; + +#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] +pub enum HeightOrTimestamp { + Height(u64), + Time(u64), +} + +#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ForkSpec { + pub height_or_timestamp: HeightOrTimestamp, + /// Items count after parent_beacon_root + pub additional_header_item_count: u64, + /// Block count in epoch + pub epoch_length: u64, + /// Max turn length + pub max_turn_length: u64, +} + +impl ForkSpec { + /// Boundary epochs are block heights that indicate the epochs before and after the HF. + /// + /// Calculates the boundary epochs based on the current and previous fork specifications. + /// This function determines the boundary epochs by comparing the current fork specification + /// with the previous fork specification. It calculates the previous last epoch, the current + /// first epoch, and any intermediate epochs between them. + /// + /// first = previous last epoch + /// last = current first epoch + /// + /// eg) height = 1501 + /// first = 1400 + /// mid = [1600, 1800] + /// last = 2000 + /// + /// in Lorentz HF + /// eg) height = 1600 + /// first = 1600 + /// mid = [1800] + /// last = 2000 + /// + /// eg) height = 1601 + /// first = 1600 + /// mid = [1800] + /// last = 2000 + /// + /// eg) height = 1800 + /// first = 1800 + /// mid = [] + /// last = 2000 + /// + /// eg) height = 2000 + /// first = 2000 + /// mid = [] + /// last = 2000 + pub fn boundary_epochs(&self, prev_fork_spec: &ForkSpec) -> Result { + if let HeightOrTimestamp::Height(height) = self.height_or_timestamp { + let prev_last = height - (height % prev_fork_spec.epoch_length); + let current_first = (height..).find(|&h| h % self.epoch_length == 0).unwrap(); + let mut intermediates = vec![]; + + // starts 0, 200, 400...epoch_length + if prev_last == 0 { + const DEFAULT_EPOCH_LENGTH: u64 = 200; + let additive: u64 = if prev_fork_spec.epoch_length > DEFAULT_EPOCH_LENGTH { + DEFAULT_EPOCH_LENGTH + } else { + prev_fork_spec.epoch_length + }; + let mut mid = prev_last + additive; + while mid < prev_fork_spec.epoch_length { + intermediates.push(mid); + mid += additive; + } + } + let mut mid = prev_last + prev_fork_spec.epoch_length; + while mid < current_first { + intermediates.push(mid); + mid += prev_fork_spec.epoch_length; + } + return Ok(BoundaryEpochs { + previous_fork_spec: prev_fork_spec.clone(), + current_fork_spec: self.clone(), + current_first, + prev_last, + intermediates, + }); + } + Err(Error::MissingForkHeightInBoundaryCalculation(self.clone())) + } +} + +#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BoundaryEpochs { + previous_fork_spec: ForkSpec, + current_fork_spec: ForkSpec, + prev_last: BlockNumber, + current_first: BlockNumber, + intermediates: alloc::vec::Vec, +} + +impl BoundaryEpochs { + pub fn current_fork_spec(&self) -> &ForkSpec { + &self.current_fork_spec + } + + /// Calculates the current epoch block number based on the given block number. + /// + /// This function determines the current epoch block number by considering the given block number + /// and the intermediate epochs. It handles various cases such as the first epoch, intermediate epochs, + /// and epochs after the hard fork. + /// + pub fn current_epoch_block_number(&self, number: BlockNumber) -> BlockNumber { + if number >= self.current_first { + return number - (number % self.current_fork_spec.epoch_length); + } + for mid in self.intermediates.iter().rev() { + if number >= *mid { + return *mid; + } + } + number - (number % self.previous_fork_spec.epoch_length) + } + + /// Calculates the previous epoch block number based on the current epoch block number. + /// + /// This function determines the previous epoch block number by considering the current epoch block number + /// and the intermediate epochs. It handles various cases such as the first epoch, intermediate epochs, + /// and epochs after the hard fork. + pub fn previous_epoch_block_number( + &self, + current_epoch_block_number: BlockNumber, + ) -> BlockNumber { + if current_epoch_block_number == 0 { + return 0; + } + // first or under + if current_epoch_block_number <= self.prev_last { + return current_epoch_block_number - self.previous_fork_spec.epoch_length; + } + + // Hit mids eppchs + for (i, mid) in self.intermediates.iter().enumerate() { + if current_epoch_block_number == *mid { + if i == 0 { + return self.prev_last; + } else { + return self.intermediates[i - 1]; + } + } + } + + // is just current HF first + if current_epoch_block_number == self.current_first { + if self.intermediates.is_empty() { + return self.prev_last; + } + return *self.intermediates.last().unwrap(); + } + + // After HF + current_epoch_block_number - self.current_fork_spec.epoch_length + } +} + +impl TryFrom for ForkSpec { + type Error = Error; + + fn try_from(value: RawForkSpec) -> Result { + let height_or_timestamp = value + .height_or_timestamp + .ok_or(Error::MissingTimestampOrHeightInForkSpec)?; + + Ok(Self { + height_or_timestamp: match height_or_timestamp { + RawHeightOrTimestamp::Height(height) => HeightOrTimestamp::Height(height), + RawHeightOrTimestamp::Timestamp(timestamp) => HeightOrTimestamp::Time(timestamp), + }, + additional_header_item_count: value.additional_header_item_count, + epoch_length: value.epoch_length, + max_turn_length: value.max_turn_length, + }) + } +} + +impl From for RawForkSpec { + fn from(value: ForkSpec) -> Self { + Self { + height_or_timestamp: match value.height_or_timestamp { + HeightOrTimestamp::Height(height) => Some(RawHeightOrTimestamp::Height(height)), + HeightOrTimestamp::Time(timestamp) => { + Some(RawHeightOrTimestamp::Timestamp(timestamp)) + } + }, + additional_header_item_count: value.additional_header_item_count, + epoch_length: value.epoch_length, + max_turn_length: value.max_turn_length, + } + } +} + +pub fn find_target_fork_spec( + fork_specs: &[ForkSpec], + current_height: BlockNumber, + current_timestamp: u64, +) -> Result<&ForkSpec, Error> { + // find from last to first + fork_specs + .iter() + .rev() + .find(|spec| match spec.height_or_timestamp { + HeightOrTimestamp::Height(height) => height <= current_height, + HeightOrTimestamp::Time(timestamp) => timestamp <= current_timestamp, + }) + .ok_or(Error::MissingForkSpec(current_height, current_timestamp)) +} + +/// Retrieves the boundary epochs for the given `ForkSpec`. +/// +/// This function finds the boundary epochs for the specified `current_spec` by comparing it +/// with the previous fork specifications in the provided list. It returns the boundary epochs +/// if the `current_spec` is found in the list. +pub fn get_boundary_epochs( + current_spec: &ForkSpec, + fork_specs: &[ForkSpec], +) -> Result { + // find from last to first + for (i, spec) in fork_specs.iter().enumerate() { + if spec == current_spec { + if i == 0 { + return spec.boundary_epochs(spec); + } + return spec.boundary_epochs(&fork_specs[i - 1]); + } + } + Err(Error::MissingPreviousForkSpec(current_spec.clone())) +} + +/// Verifies that the given list of `ForkSpec` is sorted in ascending order. +/// +/// HEIGHT should be sorted by HEIGHT and TIMESTAMP should be sorted by TIMESTAMP. +/// As an operational constraint, ForkSpec should be submitted in HF order +pub fn verify_sorted_asc(fork_specs: &[ForkSpec]) -> Result<(), Error> { + let mut last_height: Option = None; + let mut last_timestamp: Option = None; + for spec in fork_specs { + match &spec.height_or_timestamp { + HeightOrTimestamp::Height(height) => { + if let Some(last_height) = &last_height { + if height <= last_height { + return Err(Error::UnexpectedForkSpecHeightOrder(*last_height, *height)); + } + } + last_height = Some(*height); + } + HeightOrTimestamp::Time(timestamp) => { + if let Some(last_timestamp) = &last_timestamp { + if timestamp <= last_timestamp { + return Err(Error::UnexpectedForkSpecTimestampOrder( + *last_timestamp, + *timestamp, + )); + } + } + last_timestamp = Some(*timestamp); + } + } + } + Ok(()) +} + +#[cfg(test)] +mod test { + use crate::errors::Error; + use crate::fixture::{ + fork_spec_after_lorentz, fork_spec_after_maxwell, fork_spec_after_pascal, + }; + use crate::fork_spec::{ + find_target_fork_spec, get_boundary_epochs, verify_sorted_asc, ForkSpec, HeightOrTimestamp, + }; + + #[test] + fn test_success_find_target_spec_height_only() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(20), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = find_target_fork_spec(specs, 10, 0).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Height(10)); + let v = find_target_fork_spec(specs, 11, 0).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Height(10)); + let v = find_target_fork_spec(specs, 19, 0).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Height(10)); + let v = find_target_fork_spec(specs, 20, 0).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Height(20)); + } + + #[test] + fn test_success_find_target_spec_timestamp_only() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(20), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = find_target_fork_spec(specs, 0, 10).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Time(10)); + let v = find_target_fork_spec(specs, 0, 11).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Time(10)); + let v = find_target_fork_spec(specs, 0, 19).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Time(10)); + let v = find_target_fork_spec(specs, 0, 20).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Time(20)); + } + + #[test] + fn test_success_find_target_spec_timestamp_and_height() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(10), + additional_header_item_count: 20, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + // After value is primary + let v = find_target_fork_spec(specs, 10, 10).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Time(10)); + let v = find_target_fork_spec(specs, 11, 11).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Time(10)); + let v = find_target_fork_spec(specs, 10, 19).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Time(10)); + let v = find_target_fork_spec(specs, 20, 20).unwrap(); + assert_eq!(v.height_or_timestamp, HeightOrTimestamp::Time(10)); + } + + #[test] + fn test_error_find_target_spec_height_only() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(20), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = find_target_fork_spec(specs, 9, 0).unwrap_err(); + match v { + Error::MissingForkSpec(e1, e0) => { + assert_eq!(e1, 9); + assert_eq!(e0, 0); + } + _ => unreachable!("unexpected error"), + } + } + + #[test] + fn test_error_find_target_spec_timestamp_only() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(20), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = find_target_fork_spec(specs, 0, 9).unwrap_err(); + match v { + Error::MissingForkSpec(e1, e0) => { + assert_eq!(e1, 0); + assert_eq!(e0, 9); + } + _ => unreachable!("unexpected error"), + } + } + + #[test] + fn test_error_find_target_spec_timestamp_and_height() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(10), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = find_target_fork_spec(specs, 9, 9).unwrap_err(); + match v { + Error::MissingForkSpec(e1, e0) => { + assert_eq!(e1, 9); + assert_eq!(e0, 9); + } + _ => unreachable!("unexpected error"), + } + } + + #[test] + fn test_success_verify_sorted_asc_height() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(11), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + verify_sorted_asc(specs).unwrap(); + } + + #[test] + fn test_success_verify_sorted_asc_time() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(11), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + verify_sorted_asc(specs).unwrap(); + } + + #[test] + fn test_error_verify_sorted_asc_height() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = verify_sorted_asc(specs).unwrap_err(); + match v { + Error::UnexpectedForkSpecHeightOrder(e1, e0) => { + assert_eq!(e1, 10); + assert_eq!(e0, 10); + } + _ => unreachable!("unexpected error"), + } + + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(11), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = verify_sorted_asc(specs).unwrap_err(); + match v { + Error::UnexpectedForkSpecHeightOrder(e1, e0) => { + assert_eq!(e1, 11); + assert_eq!(e0, 10); + } + _ => unreachable!("unexpected error"), + } + } + + #[test] + fn test_error_verify_sorted_asc_time() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(10), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = verify_sorted_asc(specs).unwrap_err(); + match v { + Error::UnexpectedForkSpecTimestampOrder(e1, e0) => { + assert_eq!(e1, 10); + assert_eq!(e0, 10); + } + _ => unreachable!("unexpected error"), + } + + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(11), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(10), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = verify_sorted_asc(specs).unwrap_err(); + match v { + Error::UnexpectedForkSpecTimestampOrder(e1, e0) => { + assert_eq!(e1, 11); + assert_eq!(e0, 10); + } + _ => unreachable!("unexpected error"), + } + } + + #[test] + fn test_error_boundary_epochs_lorentz_pascal() { + let current = ForkSpec { + height_or_timestamp: HeightOrTimestamp::Time(0), + additional_header_item_count: 1, + epoch_length: 500, + max_turn_length: 64, + }; + match current + .boundary_epochs(&fork_spec_after_pascal()) + .unwrap_err() + { + Error::MissingForkHeightInBoundaryCalculation(e1) => { + assert_eq!(current, e1); + } + _ => unreachable!("unexpected error"), + } + } + + #[test] + fn test_success_boundary_epochs() { + let mut f1 = fork_spec_after_lorentz().clone(); + f1.height_or_timestamp = HeightOrTimestamp::Height(1501); + let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap(); + assert_eq!(be.prev_last, 1400); + assert_eq!(be.intermediates, vec![1600, 1800]); + assert_eq!(be.current_first, 2000); + + f1.height_or_timestamp = HeightOrTimestamp::Height(1600); + let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap(); + assert_eq!(be.prev_last, 1600); + assert_eq!(be.intermediates, vec![1800]); + assert_eq!(be.current_first, 2000); + + f1.height_or_timestamp = HeightOrTimestamp::Height(1601); + let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap(); + assert_eq!(be.prev_last, 1600); + assert_eq!(be.intermediates, vec![1800]); + assert_eq!(be.current_first, 2000); + + f1.height_or_timestamp = HeightOrTimestamp::Height(1800); + let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap(); + assert_eq!(be.prev_last, 1800); + assert_eq!(be.intermediates, vec![]); + assert_eq!(be.current_first, 2000); + + f1.height_or_timestamp = HeightOrTimestamp::Height(2000); + let be = f1.boundary_epochs(&fork_spec_after_pascal()).unwrap(); + assert_eq!(be.prev_last, 2000); + assert_eq!(be.intermediates, vec![]); + assert_eq!(be.current_first, 2000); + } + + #[test] + fn test_success_boundary_epochs_lorentz_pascal() { + let be = fork_spec_after_lorentz() + .boundary_epochs(&fork_spec_after_pascal()) + .unwrap(); + assert_eq!(be.prev_last, 0); + assert_eq!(be.intermediates[0], 200); + assert_eq!(be.intermediates[1], 400); + assert_eq!(be.current_first, 500); + assert_eq!(be.current_epoch_block_number(199), 0); + assert_eq!(be.current_epoch_block_number(200), 200); + assert_eq!(be.current_epoch_block_number(399), 200); + assert_eq!(be.current_epoch_block_number(400), 400); + assert_eq!(be.current_epoch_block_number(499), 400); + assert_eq!(be.current_epoch_block_number(500), 500); + assert_eq!(be.current_epoch_block_number(501), 500); + assert_eq!(be.current_epoch_block_number(999), 500); + assert_eq!(be.current_epoch_block_number(1000), 1000); + assert_eq!(be.current_epoch_block_number(1001), 1000); + assert_eq!(be.current_epoch_block_number(1499), 1000); + assert_eq!(be.current_epoch_block_number(1500), 1500); + assert_eq!(be.current_epoch_block_number(1501), 1500); + + assert_eq!(be.previous_epoch_block_number(0), 0); + assert_eq!(be.previous_epoch_block_number(200), 0); + assert_eq!(be.previous_epoch_block_number(400), 200); + assert_eq!(be.previous_epoch_block_number(500), 400); + assert_eq!(be.previous_epoch_block_number(1000), 500); + assert_eq!(be.previous_epoch_block_number(1500), 1000); + } + + #[test] + fn test_success_boundary_epochs_maxwell_lorentz() { + let be = fork_spec_after_maxwell() + .boundary_epochs(&fork_spec_after_lorentz()) + .unwrap(); + assert_eq!(be.prev_last, 0); + assert_eq!(be.intermediates[0], 200); + assert_eq!(be.intermediates[1], 400); + assert_eq!(be.intermediates[2], 500); + assert_eq!(be.current_first, 1000); + assert_eq!(be.current_epoch_block_number(199), 0); + assert_eq!(be.current_epoch_block_number(200), 200); + assert_eq!(be.current_epoch_block_number(399), 200); + assert_eq!(be.current_epoch_block_number(400), 400); + assert_eq!(be.current_epoch_block_number(499), 400); + assert_eq!(be.current_epoch_block_number(500), 500); + assert_eq!(be.current_epoch_block_number(501), 500); + assert_eq!(be.current_epoch_block_number(999), 500); + assert_eq!(be.current_epoch_block_number(1000), 1000); + assert_eq!(be.current_epoch_block_number(1001), 1000); + assert_eq!(be.current_epoch_block_number(1499), 1000); + assert_eq!(be.current_epoch_block_number(1500), 1000); + assert_eq!(be.current_epoch_block_number(1501), 1000); + assert_eq!(be.current_epoch_block_number(1999), 1000); + assert_eq!(be.current_epoch_block_number(2000), 2000); + assert_eq!(be.current_epoch_block_number(2001), 2000); + assert_eq!(be.current_epoch_block_number(2999), 2000); + assert_eq!(be.current_epoch_block_number(3000), 3000); + + assert_eq!(be.previous_epoch_block_number(0), 0); + assert_eq!(be.previous_epoch_block_number(200), 0); + assert_eq!(be.previous_epoch_block_number(400), 200); + assert_eq!(be.previous_epoch_block_number(500), 400); + assert_eq!(be.previous_epoch_block_number(1000), 500); + assert_eq!(be.previous_epoch_block_number(2000), 1000); + assert_eq!(be.previous_epoch_block_number(3000), 2000); + } + + #[test] + fn test_error_get_boundary_epochs() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(20), + additional_header_item_count: 2, + epoch_length: 200, + max_turn_length: 9, + }, + ]; + let v = get_boundary_epochs(&fork_spec_after_pascal(), specs).unwrap_err(); + match v { + Error::MissingPreviousForkSpec(f) => { + assert_eq!(f, fork_spec_after_pascal()); + } + _ => unreachable!("unexpected error {}", v), + } + } + + #[test] + fn test_success_get_boundary_epochs() { + let specs = &[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(10), + additional_header_item_count: 1, + epoch_length: 200, + max_turn_length: 9, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(20), + additional_header_item_count: 2, + epoch_length: 500, + max_turn_length: 9, + }, + ]; + let v = get_boundary_epochs(&specs[1], specs).unwrap(); + assert_eq!(v.current_fork_spec, specs[1]); + assert_eq!(v.previous_fork_spec, specs[0]); + + let v = get_boundary_epochs(&specs[0], specs).unwrap(); + assert_eq!(v.current_fork_spec, specs[0]); + assert_eq!(v.previous_fork_spec, specs[0]); + } +} diff --git a/light-client/src/header/constant.rs b/light-client/src/header/constant.rs index 27095f52..2b2db298 100644 --- a/light-client/src/header/constant.rs +++ b/light-client/src/header/constant.rs @@ -1 +1,2 @@ -pub const BLOCKS_PER_EPOCH: u64 = 200; +pub const MINIMUM_TIMESTAMP_SUPPORTED: u64 = 0; +pub const MINIMUM_HEIGHT_SUPPORTED: u64 = 0; diff --git a/light-client/src/header/eth_header.rs b/light-client/src/header/eth_header.rs index 2cd1b8a5..f58cf439 100644 --- a/light-client/src/header/eth_header.rs +++ b/light-client/src/header/eth_header.rs @@ -1,22 +1,21 @@ use alloc::vec::Vec; - use elliptic_curve::sec1::ToEncodedPoint; use hex_literal::hex; use k256::ecdsa::{RecoveryId, Signature, VerifyingKey}; - use patricia_merkle_trie::keccak::keccak_256; +use primitive_types::U256; use rlp::{Rlp, RlpStream}; use parlia_ibc_proto::ibc::lightclients::parlia::v1::EthHeader as RawETHHeader; use crate::errors::Error; +use crate::fork_spec::{ + find_target_fork_spec, get_boundary_epochs, BoundaryEpochs, ForkSpec, HeightOrTimestamp, +}; use crate::header::epoch::Epoch; -use crate::header::hardfork::PASCAL_TIMESTAMP; use crate::header::vote_attestation::VoteAttestation; use crate::misc::{Address, BlockNumber, ChainId, Hash, RlpIterator, Validators}; -use super::BLOCKS_PER_EPOCH; - const DIFFICULTY_INTURN: u64 = 2; const DIFFICULTY_NOTURN: u64 = 1; @@ -38,31 +37,33 @@ const EMPTY_HASH: Hash = hex!("0000000000000000000000000000000000000000000000000 #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] pub struct ETHHeader { - pub parent_hash: Vec, - pub uncle_hash: Vec, + parent_hash: Vec, + uncle_hash: Vec, pub coinbase: Vec, pub root: Hash, - pub tx_hash: Vec, - pub receipt_hash: Vec, - pub bloom: Vec, - pub difficulty: u64, + tx_hash: Vec, + receipt_hash: Vec, + bloom: Vec, + difficulty: u64, pub number: BlockNumber, - pub gas_limit: u64, - pub gas_used: u64, - pub timestamp: u64, + gas_limit: u64, + gas_used: u64, + timestamp: u64, pub extra_data: Vec, - pub mix_digest: Vec, - pub nonce: Vec, - pub base_fee_per_gas: Option, - pub withdrawals_hash: Option>, - pub blob_gas_used: Option, - pub excess_blob_gas: Option, - pub parent_beacon_root: Option>, - pub requests_hash: Option>, + mix_digest: Vec, + nonce: Vec, + base_fee_per_gas: Option, + withdrawals_hash: Option>, + blob_gas_used: Option, + excess_blob_gas: Option, + parent_beacon_root: Option>, + additional_items: Vec>, // calculated by RawETHHeader pub hash: Hash, pub epoch: Option, + + boundary_epochs: Option, } impl ETHHeader { @@ -135,9 +136,8 @@ impl ETHHeader { } stream.append(parent_beacon_root); - // https://github.com/bnb-chain/bsc/blob/e2f2111a85fecabb4782099338aca21bf58bde09/core/types/block.go#L776 - if let Some(value) = &self.requests_hash { - stream.append(value); + for item in &self.additional_items { + stream.append_raw(item, 1); } } } @@ -159,15 +159,15 @@ impl ETHHeader { if parent.number != self.number - 1 || parent.hash != self.parent_hash.as_slice() - || parent.timestamp >= self.timestamp + || parent.milli_timestamp() >= self.milli_timestamp() { return Err(Error::UnexpectedHeaderRelation( parent.number, self.number, parent.hash, self.parent_hash.clone(), - parent.timestamp, - self.timestamp, + parent.milli_timestamp(), + self.milli_timestamp(), )); } @@ -290,7 +290,7 @@ impl ETHHeader { if self.extra_data.len() <= EXTRA_VANITY + EXTRA_SEAL { return Err(Error::UnexpectedVoteLength(self.extra_data.len())); } - let attestation_bytes = if self.number % BLOCKS_PER_EPOCH != 0 { + let attestation_bytes = if !self.is_epoch() { &self.extra_data[EXTRA_VANITY..self.extra_data.len() - EXTRA_SEAL] } else { let num = self.extra_data[EXTRA_VANITY] as usize; @@ -309,7 +309,65 @@ impl ETHHeader { } pub fn is_epoch(&self) -> bool { - self.number % BLOCKS_PER_EPOCH == 0 + self.epoch.is_some() + } + + pub fn current_epoch_block_number(&self) -> Result { + Ok(self + .boundary_epochs + .as_ref() + .ok_or(Error::MissingBoundaryEpochs(self.number))? + .current_epoch_block_number(self.number)) + } + + pub fn previous_epoch_block_number(&self) -> Result { + let boundary = self + .boundary_epochs + .as_ref() + .ok_or(Error::MissingBoundaryEpochs(self.number))?; + let current_epoch_block_number = boundary.current_epoch_block_number(self.number); + Ok(boundary.previous_epoch_block_number(current_epoch_block_number)) + } + + pub fn verify_fork_rule(&self, fork_specs: &[ForkSpec]) -> Result<(), Error> { + let fork_spec = find_target_fork_spec(fork_specs, self.number, self.milli_timestamp())?; + + // Ensure header item count is collect + if fork_spec.additional_header_item_count != self.additional_items.len() as u64 { + return Err(Error::UnexpectedHeaderItemCount( + self.number, + self.additional_items.len(), + fork_spec.additional_header_item_count, + )); + } + + if let Some(epoch) = &self.epoch { + validate_turn_length(epoch.turn_length(), fork_spec.max_turn_length as u8)?; + } + + Ok(()) + } + + pub fn set_boundary_epochs(&mut self, fork_specs: &[ForkSpec]) -> Result<(), Error> { + let fs = find_target_fork_spec(fork_specs, self.number, self.milli_timestamp())?; + match fs.height_or_timestamp { + HeightOrTimestamp::Height(_) => { + self.boundary_epochs = Some(get_boundary_epochs(fs, fork_specs)?); + Ok(()) + } + HeightOrTimestamp::Time(_) => { + Err(Error::MissingForkHeightInBoundaryCalculation(fs.clone())) + } + } + } + + // https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-520.md#411-millisecond-representation-in-block-header + pub fn milli_timestamp(&self) -> u64 { + let mut milliseconds: u64 = 0; + if self.mix_digest != EMPTY_HASH { + milliseconds = U256::from_big_endian(&self.mix_digest).low_u64(); + } + self.timestamp * 1000 + milliseconds } } @@ -324,7 +382,6 @@ pub fn get_validator_bytes_and_turn_length(extra_data: &[u8]) -> Result<(Validat let start = EXTRA_VANITY + VALIDATOR_NUM_SIZE; let end = start + num * VALIDATOR_BYTES_LENGTH; let turn_length = extra_data[end]; - validate_turn_length(turn_length)?; Ok(( extra_data[start..end] .chunks(VALIDATOR_BYTES_LENGTH) @@ -334,8 +391,8 @@ pub fn get_validator_bytes_and_turn_length(extra_data: &[u8]) -> Result<(Validat )) } -pub fn validate_turn_length(turn_length: u8) -> Result<(), Error> { - if !(turn_length == 1 || (3..=9).contains(&turn_length)) { +pub fn validate_turn_length(turn_length: u8, max: u8) -> Result<(), Error> { + if !(turn_length == 1 || (3..=max).contains(&turn_length)) { return Err(Error::UnexpectedTurnLength(turn_length)); } Ok(()) @@ -371,7 +428,6 @@ impl TryFrom for ETHHeader { let blob_gas_used: Option = rlp.try_next_as_val().map(Some).unwrap_or(None); let excess_blob_gas: Option = rlp.try_next_as_val().map(Some).unwrap_or(None); let parent_beacon_root: Option> = rlp.try_next_as_val().map(Some).unwrap_or(None); - let requests_hash: Option> = rlp.try_next_as_val().map(Some).unwrap_or(None); // Check that the extra-data contains the vanity, validators and signature let extra_size = extra_data.len(); @@ -391,8 +447,8 @@ impl TryFrom for ETHHeader { } // Ensure that the mix digest is zero as we don't have fork protection currently - if mix_digest != EMPTY_HASH { - return Err(Error::UnexpectedMixHash(number)); + if mix_digest.len() != 32 { + return Err(Error::UnexpectedMixHash(number, mix_digest)); } // Ensure that the block doesn't contain any uncles which are meaningless in PoA if uncle_hash != EMPTY_UNCLE_HASH { @@ -410,29 +466,16 @@ impl TryFrom for ETHHeader { } let hash: Hash = keccak_256(value.header.as_slice()); - let epoch = if number % BLOCKS_PER_EPOCH == 0 { - let (validators, turn_length) = get_validator_bytes_and_turn_length(&extra_data)?; - Some(Epoch::new(validators.into(), turn_length)) - } else { - None + let epoch = match get_validator_bytes_and_turn_length(&extra_data) { + Err(_) => None, + Ok((validators, turn_length)) => Some(Epoch::new(validators.into(), turn_length)), }; - #[allow(clippy::absurd_extreme_comparisons)] - if PASCAL_TIMESTAMP > 0 { - if timestamp >= PASCAL_TIMESTAMP { - if requests_hash.is_none() { - return Err(Error::MissingRequestsHash(number)); - } - // Ensure no more header element. - if rlp.try_next().is_ok() { - return Err(Error::UnexpectedHeaderRLP(number)); - } - } else if timestamp < PASCAL_TIMESTAMP && requests_hash.is_some() { - return Err(Error::UnexpectedRequestsHash( - number, - requests_hash.unwrap(), - )); - } + // Extra items for seal hash + let mut additional_items = vec![]; + while let Ok(value) = rlp.try_next() { + let item = value.as_raw(); + additional_items.push(item.to_vec()); } Ok(Self { @@ -456,9 +499,10 @@ impl TryFrom for ETHHeader { withdrawals_hash, blob_gas_used, parent_beacon_root, - requests_hash, + additional_items, hash, epoch, + boundary_epochs: None, }) } } @@ -474,11 +518,12 @@ pub(crate) mod test { use rlp::RlpStream; use rstest::*; - use crate::fixture::{decode_header, localnet, Network}; + use crate::fixture::{localnet, Network}; use crate::header::epoch::Epoch; + use crate::fork_spec::{ForkSpec, HeightOrTimestamp}; use alloc::boxed::Box; - use hex_literal::hex; + use parlia_ibc_proto::ibc::lightclients::parlia::v1::EthHeader as RawETHHeader; fn to_raw(header: ÐHeader) -> RawETHHeader { @@ -547,8 +592,9 @@ pub(crate) mod test { let raw = to_raw(&header); let err = ETHHeader::try_from(raw).unwrap_err(); match err { - Error::UnexpectedMixHash(number) => { + Error::UnexpectedMixHash(number, mix_hash) => { assert_eq!(number, header.number); + assert_eq!(mix_hash, header.mix_digest); } err => unreachable!("{:?}", err), }; @@ -694,8 +740,8 @@ pub(crate) mod test { assert_eq!(block.number, child_no); assert_eq!(parent.hash, parent_hash); assert_eq!(block.parent_hash, child_parent_hash); - assert_eq!(parent.timestamp, parent_ts); - assert_eq!(block.timestamp, child_ts); + assert_eq!(parent.milli_timestamp(), parent_ts); + assert_eq!(block.milli_timestamp(), child_ts); } err => unreachable!("{:?}", err), } @@ -820,88 +866,137 @@ pub(crate) mod test { err => unreachable!("{:?}", err), } } - #[test] - fn test_success_bep466_header() { - let header = hex!("f90370a04a99d244666a287d9aaa1a81aa5bba573f156865369023eaa53a4ba8bb303ad1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0d0a25a7c6b93d5d2e8f7e2075d2886fa62840f31c127b880b7cd503e2d364163a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282071b8402625a008084678f4827b90111d883010503846765746888676f312e32332e35856c696e75780000002f5b9772f8ae0fb860959e5c417ecd8a5e5ddabd85485cf2cc4433f26beea076d77bbc6f461e4129881b8772bdae5fdd6ca927b571662ac5750d4abeca4f44a4406ab3254e0d98e6ee92b5b6396122853b45db2d18d24fb79e8397e253ca10a2a03b3b18e5961173b5f848820719a0e5ef3de482ecc3de5aea0efb17457d7edc5b1a39fc97c29cc5780b4665c9ca2082071aa04a99d244666a287d9aaa1a81aa5bba573f156865369023eaa53a4ba8bb303ad180aba9a203cbc9ac6e2eabbc44b15f7c526ec5f9d570a0addc005d5958d8415f760794e65762057ff9956dce68034d30cca6d9cc2ac3eb35f699d47c74931c470a01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec(); - let header = decode_header(header); - let chain_id = localnet().network(); - let prev_epoch = hex!("f90484a0cdbf04705a1f6ed4989217c1e89f4c0ab22b3122df2f48c09e2fef3d0aa4b5b4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada08b3fad7b45691957d1bf905d2601a14e12d48d1da89205d22b4eb582af803e3da0629579638c8423e2836b6ad04eed7a7dcda123a3f4b6d2ab488121fac9df6c10a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028207088402625a008229a884678f47eeb90223d883010503846765746888676f312e32332e35856c696e75780000002f5b9772048fdaaa7e6631e438625ca25c857a3727ea28e565b5ad484c80ff8ed9a2aff68923f36e8975c377abd0c62a8a66ac0d2519b3eb4c14951312006c9e8b3829dc68cab6bcf0a7876ea32e7a748c697d01345145485561305b24958ec28bac0db09ee3e6cfc1769fd72b493a6c44118598abb600bec65e66aafd23acd46e0d1e0bda9d8101dbbdbf369fd9a13701eafb76870cb220843b8c6476824bfa15ad21d1bf47e3df7d8d99b105a24ebca95a84b035e6af22880b9eaf1d6a4a233920a57ecf09f8a6b89d7f5ca3cfe6484fe04db2de85453e0936b441c339a26d10cfa71b50b611e87c256a23edc8b7e55558abe1a7ff94262bacb53d600e657270ee6af9172c5a31c24498a162147dd7e1bfdcef9107f8ae0fb860a70e55ed7260c28c69880ca12370872c2059f0540ca88c1cb7a6ba772ed6e7f62a5e11c31e117ea483a4c6b46cf213681092f5273512ad15e030f52c3485838801a5ae99ece187028adbf6f543b34bd4a48199dc9b58ea47b16d06049a370a65f848820706a0ab18ec6cce429c9918cb4f354ffda5c0119871589de4829c9871ee7eddbce0ed820707a0cdbf04705a1f6ed4989217c1e89f4c0ab22b3122df2f48c09e2fef3d0aa4b5b48099019414f8ca7f80176785458468355225878402b80bbe64de4de083cbd909163b1c8dd0564e07516e6bbd0ec64381847f8f3d94d75992fd04243b538ba9348d01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec(); - let prev_epoch = decode_header(prev_epoch); + #[rstest] + #[case::localnet(localnet())] + fn test_success_verify_fork_rule(#[case] hp: Box) { + let mut header = hp.epoch_header(); + header.additional_items = vec![vec![1], vec![2]]; + header + .verify_fork_rule(&[ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: 64, + }]) + .unwrap(); header - .verify_seal(&prev_epoch.epoch.unwrap(), &chain_id) + .verify_fork_rule(&[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number - 1), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: 64, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: 64, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number + 1), + additional_header_item_count: header.additional_items.len() as u64 + 1, + epoch_length: 500, + max_turn_length: 64, + }, + ]) .unwrap(); - assert!(&header.requests_hash.is_some()); - assert_eq!(32, header.requests_hash.unwrap().len()); - } - - #[cfg(feature = "dev")] - mod dev_test_after_pascal { - use crate::errors::Error; - use crate::fixture::{decode_header, localnet}; - use crate::header::eth_header::ETHHeader; - use hex_literal::hex; - use parlia_ibc_proto::ibc::lightclients::parlia::v1::EthHeader; - - #[test] - fn test_error_missing_request_hash() { - // timestamp = 1721396460 - let raw_header = localnet().epoch_header_plus_1_rlp(); - let raw_header = EthHeader { header: raw_header }; - let result = ETHHeader::try_from(raw_header).unwrap_err(); - match result { - Error::MissingRequestsHash(_) => {} - _ => unreachable!(), - } - } + } - #[test] - fn test_error_invalid_header_rlp_length() { - let mut header = hex!("f90370a04a99d244666a287d9aaa1a81aa5bba573f156865369023eaa53a4ba8bb303ad1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0d0a25a7c6b93d5d2e8f7e2075d2886fa62840f31c127b880b7cd503e2d364163a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282071b8402625a008084678f4827b90111d883010503846765746888676f312e32332e35856c696e75780000002f5b9772f8ae0fb860959e5c417ecd8a5e5ddabd85485cf2cc4433f26beea076d77bbc6f461e4129881b8772bdae5fdd6ca927b571662ac5750d4abeca4f44a4406ab3254e0d98e6ee92b5b6396122853b45db2d18d24fb79e8397e253ca10a2a03b3b18e5961173b5f848820719a0e5ef3de482ecc3de5aea0efb17457d7edc5b1a39fc97c29cc5780b4665c9ca2082071aa04a99d244666a287d9aaa1a81aa5bba573f156865369023eaa53a4ba8bb303ad180aba9a203cbc9ac6e2eabbc44b15f7c526ec5f9d570a0addc005d5958d8415f760794e65762057ff9956dce68034d30cca6d9cc2ac3eb35f699d47c74931c470a01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec(); - // add unnecessary data - header.push(0x80); - let raw_header = EthHeader { header }; - let result = ETHHeader::try_from(raw_header).unwrap_err(); - match result { - Error::UnexpectedHeaderRLP(_) => {} - _ => unreachable!(), - } - } + #[rstest] + #[case::localnet(localnet())] + fn test_error_verify_fork_rule_item_count(#[case] hp: Box) { + let mut header = hp.epoch_header(); + header.additional_items = vec![vec![1]]; + let err = header + .verify_fork_rule(&[ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number), + additional_header_item_count: header.additional_items.len() as u64 - 1, + epoch_length: 500, + max_turn_length: 64, + }]) + .unwrap_err(); + match err { + Error::UnexpectedHeaderItemCount(_, _, _) => {} + _ => unreachable!("invalid error {:?}", err), + } + + let err = header + .verify_fork_rule(&[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number - 1), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: 64, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number), + additional_header_item_count: header.additional_items.len() as u64 - 1, + epoch_length: 500, + max_turn_length: 64, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number + 1), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: 64, + }, + ]) + .unwrap_err(); - #[test] - fn test_success_after_bep466() { - // timestamp=1737443367 - let header = hex!("f90370a04a99d244666a287d9aaa1a81aa5bba573f156865369023eaa53a4ba8bb303ad1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0d0a25a7c6b93d5d2e8f7e2075d2886fa62840f31c127b880b7cd503e2d364163a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282071b8402625a008084678f4827b90111d883010503846765746888676f312e32332e35856c696e75780000002f5b9772f8ae0fb860959e5c417ecd8a5e5ddabd85485cf2cc4433f26beea076d77bbc6f461e4129881b8772bdae5fdd6ca927b571662ac5750d4abeca4f44a4406ab3254e0d98e6ee92b5b6396122853b45db2d18d24fb79e8397e253ca10a2a03b3b18e5961173b5f848820719a0e5ef3de482ecc3de5aea0efb17457d7edc5b1a39fc97c29cc5780b4665c9ca2082071aa04a99d244666a287d9aaa1a81aa5bba573f156865369023eaa53a4ba8bb303ad180aba9a203cbc9ac6e2eabbc44b15f7c526ec5f9d570a0addc005d5958d8415f760794e65762057ff9956dce68034d30cca6d9cc2ac3eb35f699d47c74931c470a01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec(); - decode_header(header); + match err { + Error::UnexpectedHeaderItemCount(_, _, _) => {} + _ => unreachable!("invalid error {:?}", err), } } - #[cfg(feature = "dev")] - mod dev_test_before_pascal { - use crate::errors::Error; - use crate::fixture::{decode_header, localnet}; - use crate::header::eth_header::ETHHeader; - use hex_literal::hex; - use parlia_ibc_proto::ibc::lightclients::parlia::v1::EthHeader; - - #[test] - fn test_error_request_hash() { - // timestamp=1737443367 - let header = hex!("f90370a04a99d244666a287d9aaa1a81aa5bba573f156865369023eaa53a4ba8bb303ad1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0d0a25a7c6b93d5d2e8f7e2075d2886fa62840f31c127b880b7cd503e2d364163a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282071b8402625a008084678f4827b90111d883010503846765746888676f312e32332e35856c696e75780000002f5b9772f8ae0fb860959e5c417ecd8a5e5ddabd85485cf2cc4433f26beea076d77bbc6f461e4129881b8772bdae5fdd6ca927b571662ac5750d4abeca4f44a4406ab3254e0d98e6ee92b5b6396122853b45db2d18d24fb79e8397e253ca10a2a03b3b18e5961173b5f848820719a0e5ef3de482ecc3de5aea0efb17457d7edc5b1a39fc97c29cc5780b4665c9ca2082071aa04a99d244666a287d9aaa1a81aa5bba573f156865369023eaa53a4ba8bb303ad180aba9a203cbc9ac6e2eabbc44b15f7c526ec5f9d570a0addc005d5958d8415f760794e65762057ff9956dce68034d30cca6d9cc2ac3eb35f699d47c74931c470a01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").to_vec(); - let raw_header = EthHeader { header }; - let result = ETHHeader::try_from(raw_header).unwrap_err(); - match result { - Error::UnexpectedRequestsHash(_, _) => {} - _ => unreachable!(), - } - } + #[rstest] + #[case::localnet(localnet())] + fn test_error_verify_fork_rule_turn_length(#[case] hp: Box) { + let mut header = hp.epoch_header(); + let turn_length = header.epoch.as_ref().unwrap().turn_length() as u64; + header.additional_items = vec![vec![1]]; + let err = header + .verify_fork_rule(&[ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: turn_length - 1, + }]) + .unwrap_err(); + match err { + Error::UnexpectedTurnLength(_) => {} + _ => unreachable!("invalid error {:?}", err), + } + + let err = header + .verify_fork_rule(&[ + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number - 1), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: turn_length, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: turn_length - 1, + }, + ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(header.number + 1), + additional_header_item_count: header.additional_items.len() as u64, + epoch_length: 500, + max_turn_length: turn_length, + }, + ]) + .unwrap_err(); - #[test] - fn test_success_before_bep466() { - // timestamp=1721396460 - let raw_header = localnet().epoch_header_plus_1_rlp(); - decode_header(raw_header); + match err { + Error::UnexpectedTurnLength(_) => {} + _ => unreachable!("invalid error {:?}", err), } } } diff --git a/light-client/src/header/eth_headers.rs b/light-client/src/header/eth_headers.rs index 62816477..7eb94686 100644 --- a/light-client/src/header/eth_headers.rs +++ b/light-client/src/header/eth_headers.rs @@ -2,14 +2,12 @@ use alloc::vec::Vec; use parlia_ibc_proto::ibc::lightclients::parlia::v1::EthHeader; use crate::errors::Error; -use crate::errors::Error::MissingEpochInfoInEpochBlock; use crate::header::epoch::EitherEpoch::{Trusted, Untrusted}; use crate::header::epoch::{EitherEpoch, Epoch, TrustedEpoch}; use crate::misc::{BlockNumber, ChainId, Validators}; use super::eth_header::ETHHeader; -use super::BLOCKS_PER_EPOCH; #[derive(Clone, Debug, PartialEq)] pub struct ETHHeaders { @@ -34,10 +32,11 @@ impl ETHHeaders { previous_epoch: &TrustedEpoch, ) -> Result<(), Error> { // Ensure the header after the next or next checkpoint must not exist. - let epoch = self.target.number / BLOCKS_PER_EPOCH; - let checkpoint = epoch * BLOCKS_PER_EPOCH + previous_epoch.checkpoint(); - let next_checkpoint = (epoch + 1) * BLOCKS_PER_EPOCH + current_epoch.checkpoint(); - let n_val = self.verify_header_size(epoch, checkpoint, next_checkpoint, current_epoch)?; + let current_epoch_block_number = self.target.current_epoch_block_number()?; + let checkpoint = current_epoch_block_number + previous_epoch.checkpoint(); + + let next_epoch_info = + self.verify_header_size(checkpoint, current_epoch, current_epoch_block_number)?; // Ensure all the headers are successfully chained. self.verify_cascading_fields()?; @@ -45,8 +44,10 @@ impl ETHHeaders { // Ensure valid seals let p_val = previous_epoch.validators(); for h in self.all.iter() { - if h.number >= next_checkpoint { - h.verify_seal(unwrap_n_val(h.number, &n_val)?, chain_id)?; + if next_epoch_info.is_some() + && h.number >= next_epoch_info.as_ref().unwrap().next_checkpoint + { + h.verify_seal(&next_epoch_info.as_ref().unwrap().next_epoch, chain_id)?; } else if h.number >= checkpoint { h.verify_seal(current_epoch.epoch(), chain_id)?; } else { @@ -62,8 +63,13 @@ impl ETHHeaders { let mut last_voters: Validators = Vec::new(); for h in &[child, grand_child] { let vote = h.get_vote_attestation()?; - last_voters = if h.number > next_checkpoint { - vote.verify(h.number, unwrap_n_val(h.number, &n_val)?.validators())? + last_voters = if next_epoch_info.is_some() + && h.number > next_epoch_info.as_ref().unwrap().next_checkpoint + { + vote.verify( + h.number, + next_epoch_info.as_ref().unwrap().next_epoch.validators(), + )? } else if h.number > checkpoint { vote.verify(h.number, current_epoch.epoch().validators())? } else { @@ -75,7 +81,7 @@ impl ETHHeaders { verify_voters( &last_voters, grand_child, - next_checkpoint, + next_epoch_info.map(|e| e.next_checkpoint), checkpoint, current_epoch, previous_epoch, @@ -140,57 +146,154 @@ impl ETHHeaders { /// checkpoint range and ensures that they meet the size requirements for the current and next epochs. fn verify_header_size( &self, - epoch: u64, - checkpoint: u64, - next_checkpoint: u64, + current_checkpoint: u64, current_epoch: &EitherEpoch, - ) -> Result, Error> { - let hs: Vec<ÐHeader> = self.all.iter().filter(|h| h.number >= checkpoint).collect(); + current_epoch_block_number: BlockNumber, + ) -> Result, Error> { + let after_checkpoint: Vec<ÐHeader> = self + .all + .iter() + .filter(|h| h.number >= current_checkpoint) + .collect(); + match current_epoch { // ex) t=200 then 200 <= h < 411 (at least 1 honest c_val(200)' can be in p_val) Untrusted(_) => { // Ensure headers are before the next_checkpoint - if hs.iter().any(|h| h.number >= next_checkpoint) { - return Err(Error::UnexpectedNextCheckpointHeader( - self.target.number, - next_checkpoint, - )); + let next_epoch_info = find_next_epoch( + &after_checkpoint, + current_epoch.checkpoint(), + current_epoch_block_number, + )?; + if let Some(next_epoch_info) = next_epoch_info.as_ref() { + if after_checkpoint + .iter() + .any(|h| h.number >= next_epoch_info.next_checkpoint) + { + return Err(Error::UnexpectedNextCheckpointHeader( + self.target.number, + next_epoch_info.next_checkpoint, + )); + } } - Ok(None) + Ok(next_epoch_info) } // ex) t=201 then 201 <= h < 611 (at least 1 honest n_val(400) can be in c_val(200)) Trusted(_) => { // Get next_epoch if epoch after checkpoint ex) 400 - let next_epoch = match hs.iter().find(|h| h.is_epoch()) { - Some(h) => h - .epoch - .as_ref() - .ok_or_else(|| MissingEpochInfoInEpochBlock(h.number))?, - None => return Ok(None), + let next_epoch_info = find_next_epoch( + &after_checkpoint, + current_epoch.checkpoint(), + current_epoch_block_number, + )?; + let next_epoch_info = match next_epoch_info.as_ref() { + None => return Ok(next_epoch_info), + Some(v) => v, }; // Finish if no headers over next checkpoint were found - let hs: Vec<&ÐHeader> = - hs.iter().filter(|h| h.number >= next_checkpoint).collect(); - if hs.is_empty() { - return Ok(None); + let after_next_checkpoint: Vec<ÐHeader> = after_checkpoint + .into_iter() + .filter(|h| h.number >= next_epoch_info.next_checkpoint) + .collect(); + if after_next_checkpoint.is_empty() { + return Ok(Some(next_epoch_info.clone())); } - let next_next_checkpoint = (epoch + 2) * BLOCKS_PER_EPOCH + next_epoch.checkpoint(); - // Ensure headers are before the next_next_checkpoint - if hs.iter().any(|h| h.number >= next_next_checkpoint) { - return Err(Error::UnexpectedNextNextCheckpointHeader( - self.target.number, - next_next_checkpoint, - )); + let next_next_epoch_info = find_next_epoch( + &after_next_checkpoint, + next_epoch_info.next_epoch.checkpoint(), + next_epoch_info.next_epoch_block_number, + )?; + if let Some(next_next_epoch_info) = next_next_epoch_info { + if after_next_checkpoint + .iter() + .any(|h| h.number >= next_next_epoch_info.next_checkpoint) + { + return Err(Error::UnexpectedNextNextCheckpointHeader( + self.target.number, + next_next_epoch_info.next_checkpoint, + )); + } } - Ok(Some(next_epoch)) + Ok(Some(next_epoch_info.clone())) } } } } +#[derive(Clone, Debug, PartialEq)] +struct NextEpochInfo { + next_epoch: Epoch, + next_checkpoint: BlockNumber, + next_epoch_block_number: BlockNumber, +} + +impl NextEpochInfo { + fn new( + next_epoch: Epoch, + next_checkpoint: BlockNumber, + next_epoch_block_number: BlockNumber, + ) -> Self { + NextEpochInfo { + next_epoch, + next_checkpoint, + next_epoch_block_number, + } + } +} + +/// Finds the next epoch information based on the given headers. +/// +/// This function iterates through the provided headers to find the next epoch information. +/// It checks if the current epoch block number matches the header number and retrieves the next epoch details. +fn find_next_epoch( + hs: &[ÐHeader], + height_to_checkpoint: u64, + expected_prev_epoch_number: BlockNumber, +) -> Result, Error> { + for h in hs.iter() { + let self_current_epoch_number = h.current_epoch_block_number().map_err(|e| { + Error::UnexpectedMissingForkSpecInCurrentEpochCalculation( + h.number, + alloc::boxed::Box::new(e), + ) + })?; + if self_current_epoch_number == h.number { + return if let Some(next_epoch) = &h.epoch { + let self_previous_epoch_number = h.previous_epoch_block_number().map_err(|e| { + Error::UnexpectedMissingForkSpecInPreviousEpochCalculation( + h.number, + alloc::boxed::Box::new(e), + ) + })?; + if self_previous_epoch_number != expected_prev_epoch_number { + return Err(Error::UnexpectedPreviousEpochInCalculatingNextEpoch( + h.number, + self_previous_epoch_number, + expected_prev_epoch_number, + )); + } + let next_checkpoint = h.number + height_to_checkpoint; + Ok(Some(NextEpochInfo::new( + next_epoch.clone(), + next_checkpoint, + self_current_epoch_number, + ))) + } else { + Err(Error::MissingEpochInfo(h.number)) + }; + } else if h.is_epoch() { + return Err(Error::UnexpectedEpochInfo( + h.number, + self_current_epoch_number, + )); + } + } + Ok(None) +} + impl TryFrom> for ETHHeaders { type Error = Error; @@ -235,25 +338,21 @@ fn verify_finalized( Ok(()) } -fn unwrap_n_val<'a>(n: BlockNumber, n_val: &'a Option<&'a Epoch>) -> Result<&'a Epoch, Error> { - n_val.ok_or_else(|| Error::MissingNextValidatorSet(n)) -} - fn verify_voters( voters: &Validators, h: ÐHeader, - next_checkpoint: BlockNumber, + next_checkpoint: Option, checkpoint: BlockNumber, current_epoch: &EitherEpoch, previous_epoch: &TrustedEpoch, ) -> Result<(), Error> { - if h.number > next_checkpoint { + if next_checkpoint.is_some() && h.number > next_checkpoint.unwrap() { match current_epoch { Trusted(e) => e.verify_untrusted_voters(voters)?, _ => { return Err(Error::UnexpectedUntrustedValidators( h.number, - next_checkpoint, + next_checkpoint.unwrap(), )) } } @@ -269,16 +368,16 @@ fn verify_voters( mod test { use crate::errors::Error; - use crate::header::constant::BLOCKS_PER_EPOCH; use crate::header::eth_header::{get_validator_bytes_and_turn_length, ETHHeader}; use crate::header::eth_headers::{verify_voters, ETHHeaders}; use crate::fixture::*; use crate::header::epoch::{EitherEpoch, Epoch, TrustedEpoch, UntrustedEpoch}; - use crate::header::Header; + use crate::misc::Validators; use hex_literal::hex; - use light_client::types::Any; + + use crate::fork_spec::{ForkSpec, HeightOrTimestamp}; use rstest::rstest; use std::prelude::rust_2015::{Box, Vec}; use std::vec; @@ -445,10 +544,18 @@ mod test { #[test] fn test_success_verify_finalized_including_not_finalized_block() { - let header= hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafabaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a09f0bb93d54df1fcbfd84d4173496de9cff0f403319bbbaf15791ccde774b73d8a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211308402625a008229a884669fb2e3b90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8048fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6ca7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833309f8ae0fb860834538868d2c79371ead2f10fc7229fd3b3aaf1d7d8607fd7e1d2efba7df1008c105fdab4ad8029f86cfde1e3aa7dd24194fcf07502bb6c281fc3cbc08ad8cb467de57cbfd1bb93fabe72f77ece8f991a2b7a4d7fb301d54547c6cb4b612d06ff84882112ea042dfe9761fb9a677b088a868f237a171d511bea581f643844a1c98267902391882112fa0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafaba80321f35c8454a2691a2efff6894cae6277ea06390978294fe0d10fe03f432fd07440d802ca0858a2d6138230b37d1a9148a3d76fbe8492854e637c9aad7494e3401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211318402625a008084669fb2e6b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b6de9ffe941751cd11463bbd4bde69d3bc2b79868f669f9e2c4c327f036e6d558b013469a91670607dd88d63dc50b95d00719e118a17e5b72418b6ae4bef7aebbcdaa44b79f8c0677ac32c71312d84db44e6e9216bd84fb97c7d0701a4a03431f84882112fa0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafaba821130a09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1f80e5619874ecb4463f8d86981d939ddb4d0eaa151c6080c7067788e06699789d0a415e921b8824e8adc7907e5bbccec9373b22c7fe8a48527e9348aa957871b63300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0e3aa9bc64f82ccd7e70ec415d73263d9da9f3bb44b78bed500033379df9be8aaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211328402625a008084669fb2e9b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb86095a056c77bdeb59da26e665d69e75cc5667cd43df693a55f20f5f248483a3ce10cdd996b29c7fd6ba3f9e31cb4ac089c0b5bc13e77d83f17096d88f280b8d47ffd8b58b66bd760d0ccd4d26e0c2a7bb3ec168a06a815cfbdde9a2e18c32ac74ef848821130a09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1f821131a0e3aa9bc64f82ccd7e70ec415d73263d9da9f3bb44b78bed500033379df9be8aa80c04c6f70fa142c7486f7bed7e29a247f1203d58c7481c9aefef1193e6404112e32486f8d4dc8c7c558ae0b1bf860f6e05d425b7726ba7a4e2dac6e3e3eb83d3d00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310e8201a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea065b83aa9b59125f9b090432f556c6ff947b5708eb11ca5ea26342392860be00aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a01a41c640130c53b3c90b1b5c691ed467218cee97aade5aac9306e72865851e27a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330093808").to_vec(); - let any: Any = header.try_into().unwrap(); - let header = Header::try_from(any).unwrap(); - header.headers.verify_finalized().unwrap(); + let mut target_1 = localnet().epoch_header_plus_1(); + target_1.extra_data = vec![]; + let headers = ETHHeaders { + target: localnet().epoch_header(), + all: vec![ + localnet().epoch_header(), + target_1, + localnet().epoch_header_plus_2(), + localnet().epoch_header_plus_3(), + ], + }; + headers.verify_finalized().unwrap(); } #[test] @@ -465,7 +572,7 @@ mod test { verify_voters( &vec![vec![1]], &h, - 411, + Some(411), 211, &EitherEpoch::Trusted(TrustedEpoch::new(&c_epoch)), &pt_epoch, @@ -477,7 +584,7 @@ mod test { verify_voters( &vec![vec![1]], &h, - 411, + Some(411), 211, &EitherEpoch::Untrusted(UntrustedEpoch::new(&c_epoch)), &pt_epoch, @@ -489,7 +596,7 @@ mod test { verify_voters( &vec![vec![1]], &h, - 411, + Some(411), 211, &EitherEpoch::Untrusted(UntrustedEpoch::new(&c_epoch)), &pt_epoch, @@ -511,7 +618,7 @@ mod test { verify_voters( &vec![vec![1]], &h, - 411, + Some(411), 211, &EitherEpoch::Untrusted(UntrustedEpoch::new(&c_epoch)), &pt_epoch, @@ -520,7 +627,7 @@ mod test { verify_voters( &vec![vec![0]], &h, - 411, + Some(411), 211, &EitherEpoch::Trusted(TrustedEpoch::new(&c_epoch)), &pt_epoch, @@ -532,7 +639,7 @@ mod test { verify_voters( &vec![vec![0]], &h, - 411, + Some(411), 211, &EitherEpoch::Untrusted(UntrustedEpoch::new(&c_epoch)), &pt_epoch, @@ -542,15 +649,24 @@ mod test { #[test] fn test_error_verify_finalized_no_finalized_header() { - let header= hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212ed200ae9080ae608f90463a0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafabaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a09f0bb93d54df1fcbfd84d4173496de9cff0f403319bbbaf15791ccde774b73d8a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211308402625a008229a884669fb2e3b90223d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8048fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6ca7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98cb2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833309f8ae0fb860834538868d2c79371ead2f10fc7229fd3b3aaf1d7d8607fd7e1d2efba7df1008c105fdab4ad8029f86cfde1e3aa7dd24194fcf07502bb6c281fc3cbc08ad8cb467de57cbfd1bb93fabe72f77ece8f991a2b7a4d7fb301d54547c6cb4b612d06ff84882112ea042dfe9761fb9a677b088a868f237a171d511bea581f643844a1c98267902391882112fa0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafaba80321f35c8454a2691a2efff6894cae6277ea06390978294fe0d10fe03f432fd07440d802ca0858a2d6138230b37d1a9148a3d76fbe8492854e637c9aad7494e3401a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211318402625a008084669fb2e6b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb860b6de9ffe941751cd11463bbd4bde69d3bc2b79868f669f9e2c4c327f036e6d558b013469a91670607dd88d63dc50b95d00719e118a17e5b72418b6ae4bef7aebbcdaa44b79f8c0677ac32c71312d84db44e6e9216bd84fb97c7d0701a4a03431f84882112fa0794978ac680964fb5ada43366fa4d33a490c93ec6893304ddee68a59f2cafaba821130a09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1f80e5619874ecb4463f8d86981d939ddb4d0eaa151c6080c7067788e06699789d0a415e921b8824e8adc7907e5bbccec9373b22c7fe8a48527e9348aa957871b63300a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a000000000000000000000000000000000000000000000000000000000000000000ad5060ad206f9034fa0e3aa9bc64f82ccd7e70ec415d73263d9da9f3bb44b78bed500033379df9be8aaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a0558eacf75665a00d1eef186ffc4f79985db5e5fcb1aa24892df5d600ae869313a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028211328402625a008084669fb2e9b90111d98301040c846765746889676f312e32312e3132856c696e75780000d24ec9e8f8ae0fb86095a056c77bdeb59da26e665d69e75cc5667cd43df693a55f20f5f248483a3ce10cdd996b29c7fd6ba3f9e31cb4ac089c0b5bc13e77d83f17096d88f280b8d47ffd8b58b66bd760d0ccd4d26e0c2a7bb3ec168a06a815cfbdde9a2e18c32ac74ef848821130a09696424e13500cdc742b049c6459c0bc4cb357eab5d9fb48a2e79787c8897a1f821131a0e3aa9bc64f82ccd7e70ec415d73263d9da9f3bb44b78bed500033379df9be8aa80c04c6f70fa142c7486f7bed7e29a247f1203d58c7481c9aefef1193e6404112e32486f8d4dc8c7c558ae0b1bf860f6e05d425b7726ba7a4e2dac6e3e3eb83d3d00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000120310e8201a9506f90312f901f1a094e7dcd05ddcc3923085b451330f3aa5ce5a628d6685506d99cb09b3aef0e11ea065b83aa9b59125f9b090432f556c6ff947b5708eb11ca5ea26342392860be00aa0b116ef7733a93eed23f018027c116e60436a228a9f9173bb9b0c40eb71216da6a064c0a17f12a753c3fc032723866ac267ad8b7e05e7aa2e75bb680175d936617580a01a41c640130c53b3c90b1b5c691ed467218cee97aade5aac9306e72865851e27a004371241b9d6f35e1f361f2109d19a9192a9c0c749b2bd15fcb131a1a6ce5e3ba00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea070c0f30031f40c8017dbfc2ef008e6a3aae2e3105a654e0c5439b6104752882ea08f81903ec8515875682785142e1f92bdeaf65fccd5d0cf78b1ff2905a07e5883a03052420ba2d24a04d3f830584d3dbd6907b6d82bab84ddd806d03470e2c9d51ca06fb1a1498c2c8f93944a4f672ff4e982480ad181c835c0d8078159c517c7977aa013a426820f7b7249edc97cc5c002e653ac84b437f3ac12ac940c3d4b09e09827a09fbc54eac488b27315b09a1afa8d12f168e4c4cb5aea2d9a6ab5e7266da2f7e8a077c5e5cd5bd518bc509ee5e71790f1e42e492e23875b097e565cff8e809e7c8aa0a1575ef06513a19d2a28390e83958d2a3ffe166b530255b0fb5559d33409914d80f8b18080a0dc77b6ae50b675036e77b31973c79ec60c28c0d2c57b03ad99c2acfff2f0cd4e80a063a8a6161448a60a47ddbafa00899bed224e9f80072b35a1dbc64a82e85cd9b5a05e0f116451aaa1baab3f3abff2793c8318050eeed6bf62d464d343a11d86eb2880808080808080a0abbb1987d09a71106f586030d1ab913bae0008e2a7dec0d08f2d60cd30fb2ac8a096c706907bfc6472dd88315cb8e21ee6f60a661cd8050065e2ba387023ee96858080f869a020b1e2b1f9852058ee0aaadca3c963f77f6483a1a51c644d79386bcada360583b846f8440180a0e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9a0b3d632130dcb5cb583b47ec0623e59ca3703e6e2564f144272b597f3e3511ba822448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2244a7876ea32e7a748c697d01345145485561305b24b6c305acd27ad7aff76367fd3a1dfe8da19afba969c8464f37a29e60923c3a85cfacbdef18daa782d5724f13d415f98c2244b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442244e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f83332a448fdaaa7e6631e438625ca25c857a3727ea28e565b876532dd999985816f1df35a5d6359177f1d49bfb3c20e25d6760197246ad0b6b8efb77ad316a0f31360c3733cabd6c2a44b2e42bc54d19116d2348ac83461e2e0915d508ad976963272de9af796035a7c68771d03c92709aa174ce1e8723cb6d7d1f6d960790e83c59e1f9867721e6302520a30a442a44d9a13701eafb76870cb220843b8c6476824bfa15b9ebdc1d1a70721d7f9c57622e0a5d1175df1e09672ab1e8909bf9a9433592107024bd8a3ad47fbbdca199ede96c50d22a44e04db2de85453e0936b441c339a26d10cfa71b50b359d8b4d1e5fd24f5a99712ed2e5a8f7180621828a1ae567b86ff60792ff27f2fd62d410aa8b9b858316495867f833330093808").to_vec(); - let any: Any = header.try_into().unwrap(); - let mut header = Header::try_from(any).unwrap(); - header.headers.all[1].extra_data = vec![]; - let result = header.headers.verify_finalized(); + let mut target_1 = localnet().epoch_header_plus_1(); + target_1.extra_data = vec![]; + let mut target_2 = localnet().epoch_header(); + target_2.extra_data = vec![]; + let headers = ETHHeaders { + target: localnet().epoch_header(), + all: vec![ + localnet().epoch_header(), + target_1, + target_2, + localnet().epoch_header_plus_3(), + ], + }; + let result = 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_eq!(e1, headers.target.number, "block error"); + assert_eq!(e2, headers.all.len(), "header size"); assert!(format!("{:?}", &err.unwrap()).contains("UnexpectedVoteLength")); } e => unreachable!("{:?}", e), @@ -637,8 +753,9 @@ mod test { c_val: &EitherEpoch, p_val: &TrustedEpoch, include_limit: bool| { - let epoch = headers.target.number / BLOCKS_PER_EPOCH; - let next_epoch_checkpoint = (epoch + 1) * BLOCKS_PER_EPOCH + c_val.checkpoint(); + let next_epoch_checkpoint = headers.target.current_epoch_block_number().unwrap() + + fork_spec_after_lorentz().epoch_length + + c_val.checkpoint(); loop { let last = headers.all.last().unwrap(); let drift = u64::from(!include_limit); @@ -647,6 +764,15 @@ mod test { } let mut next = last.clone(); next.number = last.number + 1; + + // dummy validator set + if next.number % fork_spec_after_lorentz().epoch_length == 0 { + next.extra_data = hp.epoch_header().extra_data; + let (v, t) = get_validator_bytes_and_turn_length(&next.extra_data).unwrap(); + next.epoch = Some(Epoch::new(v.into(), t)); + } else { + next.epoch = None + } headers.all.push(next); } let result = headers.verify(&hp.network(), c_val, p_val).unwrap_err(); @@ -691,8 +817,10 @@ mod test { n_val_header: ETHHeader, include_limit: bool| { let n_val = n_val_header.epoch.clone().unwrap(); - let epoch = headers.target.number / BLOCKS_PER_EPOCH; - let next_next_epoch_checkpoint = (epoch + 2) * BLOCKS_PER_EPOCH + n_val.checkpoint(); + let next_next_epoch_checkpoint = headers.target.current_epoch_block_number().unwrap() + + fork_spec_after_lorentz().epoch_length + + fork_spec_after_lorentz().epoch_length + + n_val.checkpoint(); loop { let last = headers.all.last().unwrap(); let drift = u64::from(!include_limit); @@ -701,13 +829,15 @@ mod test { } let mut next = last.clone(); next.number = last.number + 1; - if next.is_epoch() { - // set n_val + if next.number % fork_spec_after_lorentz().epoch_length == 0 { + // set validator set next.extra_data = n_val_header.extra_data.clone(); - let (validators, turn_length) = - get_validator_bytes_and_turn_length(&next.extra_data).unwrap(); - next.epoch = Some(Epoch::new(validators.into(), turn_length)); + let (v, t) = get_validator_bytes_and_turn_length(&next.extra_data).unwrap(); + next.epoch = Some(Epoch::new(v.into(), t)); + } else { + next.epoch = None } + headers.all.push(next); } let result = headers.verify(&hp.network(), c_val, p_val).unwrap_err(); @@ -748,6 +878,131 @@ mod test { f(headers, &c_val, &p_val, n_val_header, false); } + #[rstest] + #[case::localnet(localnet())] + fn test_error_verify_header_size_missing_epoch_info(#[case] hp: Box) { + let previous_epoch = hp.previous_epoch_header().epoch.unwrap(); + let mut headers = hp.headers_after_checkpoint(); + + // No epoch info in next epoch + for _i in 0..1000 { + let mut header = headers.all.last().unwrap().clone(); + header.number += 1; + header.epoch = None; + headers.all.push(header); + } + + let epoch = &hp.epoch_header().epoch.unwrap(); + let epoch = TrustedEpoch::new(epoch); + let epoch = EitherEpoch::Trusted(epoch); + + let current_epoch_block_number = headers.target.current_epoch_block_number().unwrap(); + let checkpoint = current_epoch_block_number + previous_epoch.checkpoint(); + + let err = headers + .verify_header_size(checkpoint, &epoch, current_epoch_block_number) + .unwrap_err(); + match err { + Error::MissingEpochInfo(e1) => { + assert_eq!(e1, current_epoch_block_number + 500); + } + _ => unreachable!("err {:?}", err), + } + } + + #[rstest] + #[case::localnet(localnet())] + fn test_error_verify_header_size_unexpected_prev_epoch(#[case] hp: Box) { + let previous_epoch = hp.previous_epoch_header().epoch.unwrap(); + let mut headers = hp.headers_after_checkpoint(); + + // Set invalid fork spec + let invalid_prev_fork_spec = ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(1499), + epoch_length: 10, + additional_header_item_count: 1, + max_turn_length: 64, + }; + + let invalid_current_fork_spec = ForkSpec { + height_or_timestamp: HeightOrTimestamp::Height(1500), + epoch_length: 500, + additional_header_item_count: 1, + max_turn_length: 64, + }; + for _i in 0..1000 { + let mut header = headers.all.last().unwrap().clone(); + header.number += 1; + if header.number == 1500 { + header.epoch = hp.epoch_header().epoch; + header + .set_boundary_epochs(&[ + invalid_prev_fork_spec.clone(), + invalid_current_fork_spec.clone(), + ]) + .unwrap(); + } else { + header.epoch = None; + } + headers.all.push(header); + } + + let epoch = &hp.epoch_header().epoch.unwrap(); + let epoch = TrustedEpoch::new(epoch); + let epoch = EitherEpoch::Trusted(epoch); + + let current_epoch_block_number = headers.target.current_epoch_block_number().unwrap(); + let checkpoint = current_epoch_block_number + previous_epoch.checkpoint(); + + let err = headers + .verify_header_size(checkpoint, &epoch, current_epoch_block_number) + .unwrap_err(); + match err { + Error::UnexpectedPreviousEpochInCalculatingNextEpoch(e1, e2, e3) => { + assert_eq!(e1, 1500); + assert_eq!(e2, 1500 - invalid_prev_fork_spec.epoch_length); + assert_eq!(e3, 1500 - invalid_current_fork_spec.epoch_length); + } + _ => unreachable!("err {:?}", err), + } + } + + #[rstest] + #[case::localnet(localnet())] + fn test_error_verify_header_size_invalid_number(#[case] hp: Box) { + let previous_epoch = hp.previous_epoch_header().epoch.unwrap(); + let mut headers = hp.headers_after_checkpoint(); + + // Epoch info in non epoch + for _i in 0..1000 { + let mut header = headers.all.last().unwrap().clone(); + header.number += 1; + header.epoch = hp.epoch_header().epoch; + headers.all.push(header); + } + + let epoch = &hp.epoch_header().epoch.unwrap(); + let epoch = TrustedEpoch::new(epoch); + let epoch = EitherEpoch::Trusted(epoch); + + let current_epoch_block_number = headers.target.current_epoch_block_number().unwrap(); + let checkpoint = current_epoch_block_number + previous_epoch.checkpoint(); + + let err = headers + .verify_header_size(checkpoint, &epoch, current_epoch_block_number) + .unwrap_err(); + match err { + Error::UnexpectedEpochInfo(e1, e2) => { + assert_eq!( + e1, + hp.headers_after_checkpoint().all.last().unwrap().number + 1 + ); + assert_eq!(e2, current_epoch_block_number); + } + _ => unreachable!("err {:?}", err), + } + } + impl From> for ETHHeaders { fn from(value: Vec) -> Self { Self { diff --git a/light-client/src/header/hardfork.rs b/light-client/src/header/hardfork.rs deleted file mode 100644 index bae22b97..00000000 --- a/light-client/src/header/hardfork.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub const MINIMUM_TIMESTAMP_SUPPORTED: u64 = 0; -pub const MINIMUM_HEIGHT_SUPPORTED: u64 = 0; -pub const PASCAL_TIMESTAMP: u64 = 0; diff --git a/light-client/src/header/mod.rs b/light-client/src/header/mod.rs index 534f949a..60e984e9 100644 --- a/light-client/src/header/mod.rs +++ b/light-client/src/header/mod.rs @@ -1,24 +1,19 @@ -use alloc::vec::Vec; - use light_client::types::{Any, Height, Time}; use prost::Message as _; 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::consensus_state::ConsensusState; - +use crate::fork_spec::{find_target_fork_spec, get_boundary_epochs, ForkSpec, HeightOrTimestamp}; use crate::header::epoch::{EitherEpoch, Epoch, TrustedEpoch, UntrustedEpoch}; -use crate::header::eth_header::{validate_turn_length, ETHHeader}; +use crate::header::eth_header::ETHHeader; use crate::header::eth_headers::ETHHeaders; use crate::misc::{new_height, new_timestamp, ChainId, Hash}; use super::errors::Error; -use self::constant::BLOCKS_PER_EPOCH; - pub const PARLIA_HEADER_TYPE_URL: &str = "/ibc.lightclients.parlia.v1.Header"; // inner header is module private @@ -29,18 +24,22 @@ pub mod validator_set; pub mod vote_attestation; pub mod epoch; -pub mod hardfork; #[derive(Clone, Debug, PartialEq)] pub struct Header { - account_proof: Vec, headers: ETHHeaders, trusted_height: Height, previous_epoch: Epoch, current_epoch: Epoch, + + fork_specs: alloc::vec::Vec, } impl Header { + pub(crate) fn eth_header(&self) -> ÐHeaders { + &self.headers + } + pub fn height(&self) -> Height { new_height( self.trusted_height.revision_number(), @@ -49,11 +48,7 @@ impl Header { } pub fn timestamp(&self) -> Result { - new_timestamp(self.headers.target.timestamp) - } - - pub fn account_proof(&self) -> Result>, Error> { - decode_eip1184_rlp_proof(&self.account_proof) + new_timestamp(self.headers.target.milli_timestamp()) } pub fn trusted_height(&self) -> Height { @@ -76,6 +71,41 @@ impl Header { &self.headers.target.hash } + /// Finds the next epoch information based on the given headers. + /// + /// This function iterates through the provided headers to find the next epoch information. + /// It checks if the current epoch block number matches the header number and retrieves the next epoch details. + pub fn assign_fork_spec(&mut self, fork_specs: &[ForkSpec]) -> Result<(), Error> { + let mut fork_specs = fork_specs.to_vec(); + for header in &mut self.headers.all { + header.verify_fork_rule(&fork_specs)?; + } + // Ensure HF height is required for target without seeking next headers + self.headers.target.set_boundary_epochs(&fork_specs)?; + + // Try to set HF height + if !fork_specs.is_empty() { + let last_index = fork_specs.len() - 1; + let last = &mut fork_specs[last_index]; + if let HeightOrTimestamp::Time(time) = last.height_or_timestamp { + for header in &mut self.headers.all { + if header.milli_timestamp() >= time { + last.height_or_timestamp = HeightOrTimestamp::Height(header.number); + break; + } + } + } + } + + // Set boundary epoch to verify header size. + for header in &mut self.headers.all { + header.set_boundary_epochs(&fork_specs)? + } + + self.fork_specs = fork_specs; + Ok(()) + } + pub fn verify( &self, chain_id: &ChainId, @@ -84,10 +114,10 @@ impl Header { let (c_val, p_val) = verify_epoch( consensus_state, &self.headers.target, - self.height(), self.trusted_height, &self.previous_epoch, &self.current_epoch, + &self.fork_specs, )?; self.headers.verify(chain_id, &c_val, &p_val) } @@ -102,29 +132,37 @@ impl Header { fn verify_epoch<'a>( consensus_state: &ConsensusState, target: ÐHeader, - height: Height, trusted_height: Height, previous_epoch: &'a Epoch, current_epoch: &'a Epoch, + fork_specs: &[ForkSpec], ) -> Result<(EitherEpoch<'a>, TrustedEpoch<'a>), Error> { let is_epoch = target.is_epoch(); - let header_epoch = height.revision_height() / BLOCKS_PER_EPOCH; - let trusted_epoch = trusted_height.revision_height() / BLOCKS_PER_EPOCH; + + let trusted_time = (consensus_state.timestamp.as_unix_timestamp_nanos() / 1_000_000) as u64; + let trusted_fs = + find_target_fork_spec(fork_specs, trusted_height.revision_height(), trusted_time)?; + let trusted_epoch = get_boundary_epochs(trusted_fs, fork_specs)? + .current_epoch_block_number(trusted_height.revision_height()); if is_epoch { - if header_epoch != trusted_epoch + 1 { - return Err(Error::UnexpectedTrustedHeight( + let header_previous_epoch = target.previous_epoch_block_number()?; + if header_previous_epoch != trusted_epoch { + return Err(Error::UnexpectedTrustedEpoch( trusted_height.revision_height(), - height.revision_height(), + target.number, + header_previous_epoch, + trusted_epoch, )); } let previous_trusted = previous_epoch.hash() == consensus_state.current_validators_hash; if !previous_trusted { return Err(Error::UnexpectedUntrustedValidatorsHashInEpoch( trusted_height, - height, + target.number, previous_epoch.hash(), consensus_state.current_validators_hash, + trusted_epoch, )); } @@ -135,7 +173,7 @@ fn verify_epoch<'a>( if epoch_info.hash() != current_epoch.hash() { return Err(Error::UnexpectedCurrentValidatorsHashInEpoch( trusted_height, - height, + target.number, epoch_info.hash(), current_epoch.hash(), )); @@ -146,28 +184,33 @@ fn verify_epoch<'a>( TrustedEpoch::new(previous_epoch), )) } else { + let header_epoch = target.current_epoch_block_number()?; if header_epoch != trusted_epoch { - return Err(Error::UnexpectedTrustedHeight( + return Err(Error::UnexpectedTrustedEpoch( trusted_height.revision_height(), - height.revision_height(), + target.number, + header_epoch, + trusted_epoch, )); } let previous_trusted = previous_epoch.hash() == consensus_state.previous_validators_hash; if !previous_trusted { return Err(Error::UnexpectedPreviousValidatorsHash( trusted_height, - height, + target.number, previous_epoch.hash(), consensus_state.previous_validators_hash, + trusted_epoch, )); } let current_trusted = current_epoch.hash() == consensus_state.current_validators_hash; if !current_trusted { return Err(Error::UnexpectedCurrentValidatorsHash( trusted_height, - height, + target.number, current_epoch.hash(), consensus_state.current_validators_hash, + trusted_epoch, )); } Ok(( @@ -203,28 +246,17 @@ impl TryFrom for Header { if value.previous_validators.is_empty() { return Err(Error::MissingPreviousValidators(headers.target.number)); } - validate_turn_length(value.previous_turn_length as u8)?; // Epoch header contains validator set - let current_epoch = if headers.target.is_epoch() { - headers - .target - .epoch - .clone() - .ok_or_else(|| Error::MissingEpochInfoInEpochBlock(headers.target.number))? - } else { - Epoch::new( - value.current_validators.into(), - value.current_turn_length as u8, - ) - }; + let current_epoch = headers.target.clone().epoch.unwrap_or(Epoch::new( + value.current_validators.into(), + value.current_turn_length as u8, + )); if current_epoch.validators().is_empty() { return Err(Error::MissingCurrentValidators(headers.target.number)); } - validate_turn_length(value.current_turn_length as u8)?; Ok(Self { - account_proof: value.account_proof, headers, trusted_height, previous_epoch: Epoch::new( @@ -232,6 +264,7 @@ impl TryFrom for Header { value.previous_turn_length as u8, ), current_epoch, + fork_specs: vec![], }) } } @@ -268,31 +301,20 @@ pub(crate) mod test { use crate::header::{verify_epoch, Header}; use crate::misc::{new_height, Hash, Validators}; use alloc::boxed::Box; - use alloc::vec::Vec; - use hex_literal::hex; - use light_client::types::{Any, Height as LCPHeight, Time}; + + use light_client::types::{Height as LCPHeight, Time}; use parlia_ibc_proto::ibc::core::client::v1::Height; use parlia_ibc_proto::ibc::lightclients::parlia::v1::{EthHeader, Header as RawHeader}; use rstest::rstest; impl Header { - pub(crate) fn eth_header(&self) -> ÐHeaders { - &self.headers - } - - pub(crate) fn eth_header_mut(&mut self) -> &mut ETHHeaders { - &mut self.headers - } - pub(crate) fn new( - account_proof: Vec, headers: ETHHeaders, trusted_height: Height, previous_epoch: Epoch, current_epoch: Epoch, ) -> Self { Self { - account_proof, headers, trusted_height: LCPHeight::new( trusted_height.revision_number, @@ -300,9 +322,11 @@ pub(crate) mod test { ), previous_epoch, current_epoch, + fork_specs: vec![fork_spec_after_pascal(), fork_spec_after_lorentz()], } } } + const BLOCKS_PER_EPOCH: u64 = 500; #[rstest] #[case::localnet(localnet())] @@ -313,7 +337,6 @@ pub(crate) mod test { header: hp.epoch_header_plus_1_rlp(), }], trusted_height: None, - account_proof: vec![], current_validators: vec![h.coinbase.clone()], previous_validators: vec![h.coinbase.clone()], current_turn_length: 1, @@ -339,7 +362,6 @@ pub(crate) mod test { header: hp.epoch_header_plus_1_rlp(), }], trusted_height: Some(trusted_height.clone()), - account_proof: vec![], current_validators: vec![h.coinbase.clone()], previous_validators: vec![h.coinbase.clone()], current_turn_length: 1, @@ -368,7 +390,6 @@ pub(crate) mod test { header: hp.epoch_header_plus_1_rlp(), }], trusted_height: Some(trusted_height), - account_proof: vec![], current_validators: vec![h.coinbase.clone()], previous_validators: vec![], current_turn_length: 1, @@ -396,7 +417,6 @@ pub(crate) mod test { header: hp.epoch_header_plus_1_rlp(), }], trusted_height: Some(trusted_height), - account_proof: vec![], current_validators: vec![], previous_validators: vec![h.coinbase.clone()], current_turn_length: 1, @@ -424,13 +444,17 @@ pub(crate) mod test { header: hp.epoch_header_rlp(), }], trusted_height: Some(trusted_height.clone()), - account_proof: vec![], current_validators: hp.epoch_header().epoch.unwrap().validators().clone(), previous_validators: hp.previous_validators(), current_turn_length: 1, previous_turn_length: 1, }; - let result = Header::try_from(raw.clone()).unwrap(); + let mut result = Header::try_from(raw.clone()).unwrap(); + result + .headers + .target + .set_boundary_epochs(&[fork_spec_after_pascal(), fork_spec_after_lorentz()]) + .unwrap(); assert_eq!(result.headers.target, *h); assert_eq!( result.trusted_height.revision_height(), @@ -462,17 +486,17 @@ pub(crate) mod test { }; // epoch - let height = new_height(0, 400); - let trusted_height = new_height(0, 201); + let header = hp.epoch_header(); + let trusted_height = new_height(0, header.number - 1); let current_epoch = &hp.epoch_header().epoch.unwrap(); let previous_epoch = &Epoch::new(to_validator_set([1u8; 32]), 1); let (c_val, _) = verify_epoch( &cs, &hp.epoch_header(), - height, trusted_height, previous_epoch, current_epoch, + &[fork_spec_after_pascal(), fork_spec_after_lorentz()], ) .unwrap(); match c_val { @@ -487,17 +511,17 @@ pub(crate) mod test { current_validators_hash: Epoch::new(to_validator_set([1u8; 32]), 1).hash(), previous_validators_hash: Epoch::new(to_validator_set([2u8; 32]), 1).hash(), }; - let height = new_height(0, 599); - let trusted_height = new_height(0, 400); + let header = hp.epoch_header_plus_1(); + let trusted_height = new_height(0, hp.epoch_header().number); let current_epoch = &Epoch::new(to_validator_set([1u8; 32]), 1); let previous_epoch = &Epoch::new(to_validator_set([2u8; 32]), 1); let (c_val, _p_val) = verify_epoch( &cs, - &hp.epoch_header_plus_1(), - height, + &header, trusted_height, previous_epoch, current_epoch, + &[fork_spec_after_pascal(), fork_spec_after_lorentz()], ) .unwrap(); match c_val { @@ -518,104 +542,103 @@ pub(crate) mod test { previous_validators_hash: Epoch::new(to_validator_set([2u8; 32]), 1).hash(), }; - let height = new_height(0, 400); - let trusted_height = new_height(0, 199); + let trusted_height = new_height(0, BLOCKS_PER_EPOCH - 1); let current_epoch = &Epoch::new(to_validator_set([1u8; 32]), 1); let previous_epoch = &Epoch::new(to_validator_set([2u8; 32]), 1); let err = verify_epoch( &cs, &hp.epoch_header(), - height, trusted_height, previous_epoch, current_epoch, + &[fork_spec_after_pascal(), fork_spec_after_lorentz()], ) .unwrap_err(); match err { - Error::UnexpectedTrustedHeight(t, h) => { + Error::UnexpectedTrustedEpoch(t, _, _, _) => { assert_eq!(t, trusted_height.revision_height()); - assert_eq!(h, height.revision_height()); } _ => unreachable!("err {:?}", err), } - let trusted_height = new_height(0, 200); + let trusted_height = + new_height(0, hp.epoch_header().previous_epoch_block_number().unwrap()); let err = verify_epoch( &cs, &hp.epoch_header(), - height, trusted_height, previous_epoch, current_epoch, + &[fork_spec_after_pascal(), fork_spec_after_lorentz()], ) .unwrap_err(); match err { - Error::UnexpectedUntrustedValidatorsHashInEpoch(t, h, hash, cons_hash) => { + Error::UnexpectedUntrustedValidatorsHashInEpoch(t, _, hash, cons_hash, _) => { assert_eq!(t, trusted_height); - assert_eq!(h, height); assert_eq!(hash, previous_epoch.hash()); assert_eq!(cons_hash, cs.current_validators_hash); } _ => unreachable!("err {:?}", err), } - let height = new_height(0, 401); - let trusted_height = new_height(0, 200); + let trusted_height = new_height(0, BLOCKS_PER_EPOCH); let err = verify_epoch( &cs, &hp.epoch_header_plus_1(), - height, trusted_height, previous_epoch, current_epoch, + &[fork_spec_after_pascal(), fork_spec_after_lorentz()], ) .unwrap_err(); match err { - Error::UnexpectedTrustedHeight(t, h) => { + Error::UnexpectedTrustedEpoch(t, _, _, _) => { assert_eq!(t, trusted_height.revision_height()); - assert_eq!(h, height.revision_height()); } _ => unreachable!("err {:?}", err), } - let trusted_height = new_height(0, 400); + let trusted_height = new_height( + 0, + hp.epoch_header_plus_1() + .current_epoch_block_number() + .unwrap(), + ); let current_epoch = &Epoch::new(to_validator_set([1u8; 32]), 1); let previous_epoch = &Epoch::new(to_validator_set([3u8; 32]), 1); let err = verify_epoch( &cs, &hp.epoch_header_plus_1(), - height, trusted_height, previous_epoch, current_epoch, + &[fork_spec_after_pascal(), fork_spec_after_lorentz()], ) .unwrap_err(); match err { - Error::UnexpectedPreviousValidatorsHash(t, h, hash, cons_hash) => { + Error::UnexpectedPreviousValidatorsHash(t, _, hash, cons_hash, _) => { assert_eq!(t, trusted_height); - assert_eq!(h, height); assert_eq!(hash, previous_epoch.hash()); assert_eq!(cons_hash, cs.previous_validators_hash); } _ => unreachable!("err {:?}", err), } - let trusted_height = new_height(0, 400); + let trusted_height = new_height(0, hp.epoch_header().current_epoch_block_number().unwrap()); let current_epoch = &Epoch::new(to_validator_set([3u8; 32]), 1); let previous_epoch = &Epoch::new(to_validator_set([2u8; 32]), 1); let err = verify_epoch( &cs, &hp.epoch_header_plus_1(), - height, trusted_height, previous_epoch, current_epoch, + &[fork_spec_after_pascal(), fork_spec_after_lorentz()], ) .unwrap_err(); match err { - Error::UnexpectedCurrentValidatorsHash(t, h, hash, cons_hash) => { + Error::UnexpectedCurrentValidatorsHash(t, _, hash, cons_hash, _) => { assert_eq!(t, trusted_height); - assert_eq!(h, height); assert_eq!(hash, current_epoch.hash()); assert_eq!(cons_hash, cs.current_validators_hash); } @@ -628,40 +651,26 @@ pub(crate) mod test { current_validators_hash: Epoch::new(to_validator_set([4u8; 32]), 1).hash(), previous_validators_hash: Epoch::new(to_validator_set([2u8; 32]), 1).hash(), }; - let height = new_height(0, 400); - let trusted_height = new_height(0, 399); + let trusted_height = + new_height(0, hp.epoch_header().previous_epoch_block_number().unwrap()); let current_epoch = &Epoch::new(to_validator_set([1u8; 32]), 1); let previous_epoch = &Epoch::new(to_validator_set([4u8; 32]), 1); let err = verify_epoch( &cs, &hp.epoch_header(), - height, trusted_height, previous_epoch, current_epoch, + &[fork_spec_after_pascal(), fork_spec_after_lorentz()], ) .unwrap_err(); match err { - Error::UnexpectedCurrentValidatorsHashInEpoch(t, h, header_hash, request_hash) => { + Error::UnexpectedCurrentValidatorsHashInEpoch(t, _, header_hash, request_hash) => { assert_eq!(t, trusted_height); - assert_eq!(h, height); assert_eq!(header_hash, hp.epoch_header().epoch.unwrap().hash()); assert_eq!(request_hash, current_epoch.hash()); } _ => unreachable!("err {:?}", err), } } - - #[test] - fn test_error_try_from_invalid_turn_length() { - let header= hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212961e0a9e060a9b06f90318a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd549a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d1d6bf74282782b0b3eb1413c901d6ecf02e8e28a0c2081e9bb02adf2b65cf9b3f83b71142e4a963584516174fa671c75e3c9b82f0a071f511f91544d703b0a8a74ef6b93df3d261d961b15f5abb688a115a164f59aba0a93cf4b9598e6c8ff24b4aea19f8a64291de129c57118291fee8c4b16de22fe5b90100462586c2f1cfbc9f58faae6f8ff10b2b6a5e6acb0d3077c87e9b05031ab93d1e8f62b32a766618ad9af4b9a1629f42008273c409768e35be70154b2721e87ef585d19504837158efa1b705d99333122ea79c48b387729b7e491f8154d55c5f180e6d01668a76152594e3183ccae8490d8e8e92500e0f5c2ad6b0e415f45ac72f95fab24672835de1c48e0a9f38923ec496ae5dd5fb62043cfd7bc0c8f0c5c3f1670ef7d1d7fc2b907ffe63ced34467b8fbf2300dba03b63a57722ff07ae56961f52d1a32862a09ef3698d1b93bc636286a56b3cadb8b22998372f4c28cd1e72c7ab0f0ab0db8c6aa8105556c1a3481c6fc66ac24d5ae775fba850d343a210feb028401e6aa4184084fe2c684014933a184650a4afbb90118d88301020b846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831dffffb8609865f38b886fdf9133435031ff4e3af35f0f7dcd165bed2f80f523864cdcaacd102a5d538972060573218a8cbd201d9418fde9d217990d8faf5c5c382618820fe24cf490f1010d92a66114d3d5305e953ef00268448068d5fb4638a94c4269a2f84c8401e6aa3fa0cba1480655a9172eb8fc0a0ea9cd5a285b9fcea8489bde764a134c52a8cc0ff98401e6aa40a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd54980a72fc8f10e414df8a61ea1d4d2f3362b2fa0c8c7c444848769e6d67bdbcce4de2683fdae80bcd5a90a8f92d76b7ae426f11d51a7f1d785fefe1cbf451f67186401a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9a060a9706f90314a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f306a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e9ae3261a475a27bb1028f140bc2a7c843318afda0c2081e9bb02adf2b65cf9b3f83b71142e4a963584516174fa671c75e3c9b82f0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028401e6aa4284085832a78084650a4affb90118d88301020a846765746888676f312e32302e35856c696e7578000000b19df4a2f8b5831dffffb860b02f4314b40616294282cb1f66df8eb23b1c26395b214e78ecd75a9646e0fd008b5f9bae4b24647db4f4b4a92ca0aee4032f3a8917546bfc7c078624ab1b0be6bf87972f4d9815f4f96ad00ba291308ee5c5f6c63243e9518ab6c1f42ce34470f84c8401e6aa40a0793f4896c559772686c55bc1140baa291e62ef268061713080c9d02193ecd5498401e6aa41a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f30680ec8e7cec4b6c25fa8b22c40e9ecae359c542137ed189c711f5cd7616f4619f331f3eb09268047aaf47af3b83786ee4471c31779848627720f48a7bf5ca50f14601a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800ae6040ae304f90260a0cadbcaaebd901c23537425e903b40a054d6cca192f0f01ecf3d45d9afce4cef3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ea0a6e3c511bbd10f4519ece37dc24887e11b55da054d3ce938c69efbd57808ae22c9030bfa64ebfe6b7f16d5574b1fada5c336d96a0ba3499b3199bc9606a46f865d4abc0cfa9e1be68940ba8a91eb0de4e02d660f5a04278f75943cad9584a22440799ef5f5db6618e33bed532b709b859bb44e0d02fb901006eb746324da2c67a4c1a4a70aeed04073c9d207629cda74bd61604bf345053d797915346c4e531f9033b2df9067732f89d89f3e90b6ae92122c64c020964e7de5facd5784b66c76ac979829d886e8779f9b1f4b5e5efd954c956a916bb1d5f71937998aa33863da5ace9aa48432959190bfee853e57f55beeae4c6b8efcc0ff092f7f1f73afcd1daf3dcbb7c3f82fab45bacbc95366ad9fc6d495e5968e65c346248d49a759b29086e28a57f6af62769dfac85aba6ddf3013783b02ad9d872e8afa60d631a9f0c838298a5955222d611e3d1b79eb8a872beaa37fa5a9a00e50dabd0ca073bc1ff981bf906c0fda18164ae868587e9b802cdf7e26fae9a811f0b028401e6aa438408583b00840105fdbe84650a4b02b861d88301020b846765746888676f312e31392e38856c696e7578000000b19df4a239e14e61ceb442e61edd782ed2e011994aca0236541d845851453ed45e1c950b3672dcc21546bd65e746c468b17a3722b7c529d64d9c3a4b41136ab03e48147e01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9e060a9b06f90318a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d90a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ee226379db83cffc681495730c11fdde79ba4c0ca0921e5a9881b361b462e86c18d8170303f37f3576c4298f951b164a3a0ffa7950a04a318f22b6185bdebef3900d7c65bcceed28c6906605406b54bd9eb07cb6a266a07a8d59ef980eed078ac8f192425c1fffbf5210a9c92a2065c40639f6421c2367b90100cae58a5a44a877dfab933564fb46b73ec4c3d9c7f068cd492e7b13a3d43cca90ce095bebe264c59a13537dd3575e47c5a87922ba687d73fbdf4cf75c5c7fae998edcc9956b64445fc973aacd815ef67bbc3ce25deb67e19207fff0d98cc0cd558a0ec9eb2bb7bee5b4e736041f80bdcb0862fbf2e9afff5e3ce0959b8fa1cfb795fe04f69cbfecdde7a927c01fe87cc89cad2e277b31e63a5619f6ffac97cb631f4ba69ce7fea3f16e3c2b15fb8b2462cbf6ef9b62b3e77173fb306f19eb12fbe2ecdedfb32acbcf3efa25d9f79838b2b76b25cec051447eab71740e862feb2fd214e4db5568ceb4a791b6bec6c1a972726641bce9fe4f68e46edf15df75e652028401e6aa448408583b00840107e57384650a4b05b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5831dffffb860a4cc53efef08386da2bcdf2ccd02f5772899f7e1f3b0252b21bf309dd6f96034ee6570316f1767c75acdd7f6691589051341d1cdf1f118c5c47c505a2e48a47da6e7d26c3107799b8cf767cff1382115896c6b74f0df094690ee36d0fcecf95ef84c8401e6aa41a094904149695c8adb89cd6f020cb278275a2fd4483cfc10d7d3dab8121f69f3068401e6aa43a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d908093e10e56b7f84c8f756b3bd5422d93053db5f5a55dee436bae6d8066674e131f4f430278fc3cb1f4d9f3dd0c85410694b92887718d431d8ddf25524ece35d03501a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a04eedf58a08358d43f0d37410f1c301efcc3dd738eff0b07bb4f82c83f30a0cc2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ef0274e31810c9df02f98fafde0f841f4e66a1cda04773baafa2984559c063e6b1f50e3019baae941124e89d5d7bc3f009e484a3d0a0c350e76080e62e8e4f45c1d424daec63750b940344655e81f56f0c65f1e7ab40a0cfd21dbf9df8503fb97bcd511aa04483116eb7afd0d4702532d1ff0b8e8b849eb90100002e022444181418d2d2414984070420434880e00f19494c8452044a5a7001298681544650c412916e119ca3241220808c0110050418214674422800002620a06440c08029440f8f296082ac8214002db995a0c59de7580a06168014c01036205a8ca0628e8205000458ea6110210d480a002ce0809e0410430084100d4c6420390a20a40479e91a14982410089018c4902ca40d601091081181105024a110a007904082087e211261d6008c42ceb44942602191022801165326a8aa1f8f28f8e0262c92228732026080028c8812d2057a10b884800048b10c13545b9e20f6340ab485c910af5a940909064e044f41446c6b8581653051e81603b101fc498c0b028401e6aa458408583b008385259f84650a4b08b90118d88301020a846765746888676f312e32302e34856c696e7578000000b19df4a2f8b5831dffffb86088dd96fd990be352a39175463f3902ec9f4f036ed7cd8ab3ce3f4cc70dfc8230a1a1f856e28cbc84a4ed1f95431f63cd0464f1c2f061593bfaf3eae388264d02420af41cfc0e01525f438bc3cf11b9c5a988aa6bb9c82098d567b339709ac676f84c8401e6aa43a0cc482c7a97c2c547a7e1483c14e65bb6087ca7257c15ff673f946298c57e7d908401e6aa44a04eedf58a08358d43f0d37410f1c301efcc3dd738eff0b07bb4f82c83f30a0cc2801962735bca49e800156401aa4bbe2e32d58f36cc22ce3cfd8da23ca72e10eb2f44fa1c1a1840959059d86e6f1b936457795534d45c8a554c3060e9dd39ec108001a00000000000000000000000000000000000000000000000000000000000000000880000000000000000801200221400000000000000000000000000000000000000002a140000000000000000000000000000000000000000").to_vec(); - let any: Any = header.try_into().unwrap(); - let err = Header::try_from(any).unwrap_err(); - match err { - Error::UnexpectedTurnLength(turn_length) => { - assert_eq!(turn_length, 0) - } - _ => unreachable!("unexpected "), - } - } } diff --git a/light-client/src/header/vote_attestation.rs b/light-client/src/header/vote_attestation.rs index e6aa6fc3..40af4016 100644 --- a/light-client/src/header/vote_attestation.rs +++ b/light-client/src/header/vote_attestation.rs @@ -154,7 +154,7 @@ impl<'a> TryFrom> for VoteAttestation { mod test { use crate::errors::Error; use crate::fixture::*; - use crate::header::eth_header::{get_validator_bytes_and_turn_length, ETHHeader}; + use crate::header::eth_header::get_validator_bytes_and_turn_length; use crate::header::vote_attestation::{ VoteAddressBitSet, VoteAttestation, VoteData, BLS_SIGNATURE_LENGTH, MAX_ATTESTATION_EXTRA_LENGTH, @@ -221,31 +221,8 @@ mod test { #[test] fn test_error_no_vote_data() { - let header = ETHHeader { - parent_hash: vec![], - uncle_hash: vec![], - coinbase: vec![], - root: [0u8; 32], - tx_hash: vec![], - receipt_hash: vec![], - bloom: vec![], - difficulty: 0, - number: 43198800, - gas_limit: 0, - gas_used: 0, - timestamp: 0, - extra_data: hex!("d98301040d846765746889676f312e32312e3132856c696e757800000299d9bc0808265da01e1a65d62b903c7b34c08cb389bf3d9996f763f030b1adcfb369c5a5df4a18e1529baffe7feaec66db3dbd1bc06810f7f6f88b7be6645418a7e2a2a3f40514c215a13e315cbfb9398a26d77a299963bf034c28f8b0183ea044211f468630233d2533b73307979c78a9486b33bb4ee04ca31a65f3e86fba804db7fe293fa643e6b72bb3821a3d9d7a717d64e6088ac937d5aacdd3e20ca963979974cd8ff90cbf097023dc8c448245ceff671e965d57d82eaf9be91478cfa0f24d2993e0c5f43a6c5a4cd99850023040d3256eb0babe89f0ea54edaa398513136612f5a334b49d766ebe3eb9f6bdc163bd2c19aa7e8cee1667851ae0c1651f01c4cf7cf2cfcf8475bff3e99cab25b05631472d53387f3321fd69d1e030bb921230dfb188826affaa39ebf1c38b190851e4db0588a3e90142c5299041fb8a0db3bb9a1fa4bdf0dae84ca37ee12a6b8c26caab775f0e007b76d76ee8823de52a1a431884c2ca930c5e72bff3803af79641cf964cc001671017f0b680f93b7dde085b24bbc67b2a562a216f903ac878c5477641328172a353f1e493cf7f5f2cf1aec83bf0c74df566a41aa7ed65ea84ea99e3849ef31887c0f880a0feb92f356f58fbd023a82f5311fc87a5883a662e9ebbbefc90bf13aa533c2438a4113804bfd447b49cd040d20bc21e49ffea6487f5638e4346ad9fc6d1ec30e28016d3892b51a7898bd354cfe78643453fd3868410da412de7f2883180d0a2840111ad2e043fa403eb04cc3c0ed356ea54a6e7015490240681b002cb63e12f65c456cafca335c730b123553e70df5322013812429e0bc31508e1f1fbf0ab312e4aaade9e022150071a1f00").into(), - mix_digest: vec![], - nonce: vec![], - base_fee_per_gas: None, - withdrawals_hash: None, - blob_gas_used: None, - excess_blob_gas: None, - parent_beacon_root: None, - requests_hash: None, - hash: [0u8; 32], - epoch: None, - }; + let mut header = localnet().epoch_header(); + header.extra_data = hex!("d98301040d846765746889676f312e32312e3132856c696e757800000299d9bc0808265da01e1a65d62b903c7b34c08cb389bf3d9996f763f030b1adcfb369c5a5df4a18e1529baffe7feaec66db3dbd1bc06810f7f6f88b7be6645418a7e2a2a3f40514c215a13e315cbfb9398a26d77a299963bf034c28f8b0183ea044211f468630233d2533b73307979c78a9486b33bb4ee04ca31a65f3e86fba804db7fe293fa643e6b72bb3821a3d9d7a717d64e6088ac937d5aacdd3e20ca963979974cd8ff90cbf097023dc8c448245ceff671e965d57d82eaf9be91478cfa0f24d2993e0c5f43a6c5a4cd99850023040d3256eb0babe89f0ea54edaa398513136612f5a334b49d766ebe3eb9f6bdc163bd2c19aa7e8cee1667851ae0c1651f01c4cf7cf2cfcf8475bff3e99cab25b05631472d53387f3321fd69d1e030bb921230dfb188826affaa39ebf1c38b190851e4db0588a3e90142c5299041fb8a0db3bb9a1fa4bdf0dae84ca37ee12a6b8c26caab775f0e007b76d76ee8823de52a1a431884c2ca930c5e72bff3803af79641cf964cc001671017f0b680f93b7dde085b24bbc67b2a562a216f903ac878c5477641328172a353f1e493cf7f5f2cf1aec83bf0c74df566a41aa7ed65ea84ea99e3849ef31887c0f880a0feb92f356f58fbd023a82f5311fc87a5883a662e9ebbbefc90bf13aa533c2438a4113804bfd447b49cd040d20bc21e49ffea6487f5638e4346ad9fc6d1ec30e28016d3892b51a7898bd354cfe78643453fd3868410da412de7f2883180d0a2840111ad2e043fa403eb04cc3c0ed356ea54a6e7015490240681b002cb63e12f65c456cafca335c730b123553e70df5322013812429e0bc31508e1f1fbf0ab312e4aaade9e022150071a1f00").into(); let (val, turn) = get_validator_bytes_and_turn_length(&header.extra_data).unwrap(); assert_eq!(val.len(), 8); assert_eq!(turn, 4); diff --git a/light-client/src/lib.rs b/light-client/src/lib.rs index 22feedad..4bbda38f 100644 --- a/light-client/src/lib.rs +++ b/light-client/src/lib.rs @@ -13,6 +13,7 @@ pub mod consensus_state; pub mod errors; #[cfg(test)] mod fixture; +mod fork_spec; pub mod header; pub mod message; pub mod misbehaviour; diff --git a/light-client/src/misbehaviour.rs b/light-client/src/misbehaviour.rs index fb2e63c9..2f6678e5 100644 --- a/light-client/src/misbehaviour.rs +++ b/light-client/src/misbehaviour.rs @@ -85,7 +85,6 @@ mod test { RawHeader { headers: vec![EthHeader { header: h }], trusted_height: Some(Height::default()), - account_proof: vec![], current_validators: vec![coinbase.clone()], previous_validators: vec![coinbase], previous_turn_length: 1, diff --git a/light-client/src/misc.rs b/light-client/src/misc.rs index 5bfaf4be..c43e1400 100644 --- a/light-client/src/misc.rs +++ b/light-client/src/misc.rs @@ -90,11 +90,11 @@ pub fn new_height(revision_number: u64, height: BlockNumber) -> Height { Height::new(revision_number, height) } -pub fn new_timestamp(second: u64) -> Result { - let second = second as u128; - let nanos = second - .checked_mul(1_000_000_000) - .ok_or_else(|| Error::TimestampOverflowError(second))?; +pub fn new_timestamp(msec: u64) -> Result { + let msec = msec as u128; + let nanos = msec + .checked_mul(1_000_000) + .ok_or_else(|| Error::TimestampOverflowError(msec))?; Time::from_unix_timestamp_nanos(nanos).map_err(Error::TimeError) } diff --git a/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto b/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto index 5c703500..261f5c0f 100644 --- a/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto +++ b/proto/definitions/ibc/lightclients/parlia/v1/parlia.proto @@ -7,6 +7,18 @@ import "gogoproto/gogo.proto"; import "ibc/core/client/v1/client.proto"; import "google/protobuf/duration.proto"; +message ForkSpec { + oneof height_or_timestamp { + uint64 height = 1; + uint64 timestamp = 2; + } + // The number of headers prior to Pascal HF is set to 0. + // For example, the number of headers before Pascal HF is set to 1 because of the addition of the requestsHash. + uint64 additional_header_item_count = 3; + uint64 epoch_length = 4; + uint64 max_turn_length = 5; +} + message ClientState { uint64 chain_id = 1; @@ -19,6 +31,8 @@ message ClientState { google.protobuf.Duration max_clock_drift = 6 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; bool frozen = 7; + + repeated ForkSpec fork_specs = 8; } message ETHHeader { @@ -28,11 +42,10 @@ message ETHHeader { message Header { 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; - uint32 current_turn_length = 6; - uint32 previous_turn_length = 7; + repeated bytes current_validators = 3; + repeated bytes previous_validators = 4; + uint32 current_turn_length = 5; + uint32 previous_turn_length = 6; } message ConsensusState { @@ -46,4 +59,9 @@ message Misbehaviour { string client_id = 1; Header header_1 = 2; Header header_2 = 3; -} \ No newline at end of file +} + +message ProveState { + bytes account_proof = 1; + bytes commitment_proof = 2; +} diff --git a/proto/src/prost/ibc.lightclients.parlia.v1.rs b/proto/src/prost/ibc.lightclients.parlia.v1.rs index 5be56140..33fe1f1b 100644 --- a/proto/src/prost/ibc.lightclients.parlia.v1.rs +++ b/proto/src/prost/ibc.lightclients.parlia.v1.rs @@ -1,5 +1,30 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct ForkSpec { + /// The number of headers prior to Pascal HF is set to 0. + /// For example, the number of headers before Pascal HF is set to 1 because of the addition of the requestsHash. + #[prost(uint64, tag = "3")] + pub additional_header_item_count: u64, + #[prost(uint64, tag = "4")] + pub epoch_length: u64, + #[prost(uint64, tag = "5")] + pub max_turn_length: u64, + #[prost(oneof = "fork_spec::HeightOrTimestamp", tags = "1, 2")] + pub height_or_timestamp: ::core::option::Option, +} +/// Nested message and enum types in `ForkSpec`. +pub mod fork_spec { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum HeightOrTimestamp { + #[prost(uint64, tag = "1")] + Height(u64), + #[prost(uint64, tag = "2")] + Timestamp(u64), + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ClientState { #[prost(uint64, tag = "1")] pub chain_id: u64, @@ -21,6 +46,8 @@ pub struct ClientState { >, #[prost(bool, tag = "7")] pub frozen: bool, + #[prost(message, repeated, tag = "8")] + pub fork_specs: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -37,15 +64,13 @@ pub struct Header { pub trusted_height: ::core::option::Option< super::super::super::core::client::v1::Height, >, - #[prost(bytes = "vec", tag = "3")] - pub account_proof: ::prost::alloc::vec::Vec, - #[prost(bytes = "vec", repeated, tag = "4")] + #[prost(bytes = "vec", repeated, tag = "3")] pub current_validators: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, - #[prost(bytes = "vec", repeated, tag = "5")] + #[prost(bytes = "vec", repeated, tag = "4")] pub previous_validators: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, - #[prost(uint32, tag = "6")] + #[prost(uint32, tag = "5")] pub current_turn_length: u32, - #[prost(uint32, tag = "7")] + #[prost(uint32, tag = "6")] pub previous_turn_length: u32, } #[allow(clippy::derive_partial_eq_without_eq)] @@ -70,3 +95,11 @@ pub struct Misbehaviour { #[prost(message, optional, tag = "3")] pub header_2: ::core::option::Option
, } +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProveState { + #[prost(bytes = "vec", tag = "1")] + pub account_proof: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub commitment_proof: ::prost::alloc::vec::Vec, +}